You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
1
(21) |
|
2
(19) |
3
(33) |
4
(24) |
5
(18) |
6
(13) |
7
(22) |
8
(21) |
|
9
(38) |
10
(25) |
11
(20) |
12
(27) |
13
(43) |
14
(9) |
15
(19) |
|
16
(37) |
17
(19) |
18
(13) |
19
(11) |
20
(8) |
21
(11) |
22
(25) |
|
23
(21) |
24
(30) |
25
(18) |
26
(11) |
27
(10) |
28
(14) |
29
(40) |
|
30
(24) |
31
(14) |
|
|
|
|
|
|
From: <sv...@va...> - 2008-03-30 10:03:02
|
Author: bart
Date: 2008-03-30 11:03:04 +0100 (Sun, 30 Mar 2008)
New Revision: 7820
Log:
Even more expected output updates.
Modified:
trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3
Modified: trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3
===================================================================
--- trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3 2008-03-30 08:51:59 UTC (rev 7819)
+++ trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3 2008-03-30 10:03:04 UTC (rev 7820)
@@ -37,13 +37,13 @@
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_trylock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:116)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] pre_mutex_lock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_timedlock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:121)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] mutex_unlock invalid mutex 0x........ rc 0
The object at address 0x........ is not a mutex.
@@ -70,14 +70,10 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
-[1/1] mutex_unlock error checking mutex 0x........ rc 0
-
-Mutex not locked: mutex 0x........, recursion count 0, owner 0.
- at 0x........: pthread_cond_timedwait* (drd_pthread_intercepts.c:?)
- by 0x........: main (tc20_verifywrap.c:165)
+[1/1] mutex_unlock error checking mutex 0x........ rc 1
[1/1] cond_pre_wait 0x........
[1/1] cond_post_wait 0x........
-[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 1
---------------- pthread_rwlock_* ----------------
@@ -131,6 +127,9 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
[1/1] mutex_destroy error checking mutex 0x........
+
+Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
+ at 0x........: main (tc20_verifywrap.c:262)
[1/1] mutex_destroy invalid mutex 0x........
[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 0
[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
|
|
From: <sv...@va...> - 2008-03-30 08:51:55
|
Author: bart
Date: 2008-03-30 09:51:59 +0100 (Sun, 30 Mar 2008)
New Revision: 7819
Log:
More expected output updates.
Modified:
trunk/exp-drd/tests/tc20_verifywrap.stderr.exp-glibc2.3
trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b
Modified: trunk/exp-drd/tests/tc20_verifywrap.stderr.exp-glibc2.3
===================================================================
--- trunk/exp-drd/tests/tc20_verifywrap.stderr.exp-glibc2.3 2008-03-30 08:44:02 UTC (rev 7818)
+++ trunk/exp-drd/tests/tc20_verifywrap.stderr.exp-glibc2.3 2008-03-30 08:51:59 UTC (rev 7819)
@@ -53,10 +53,6 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
-Mutex not locked: mutex 0x........, recursion count 0, owner 0.
- at 0x........: pthread_cond_timedwait* (drd_pthread_intercepts.c:?)
- by 0x........: main (tc20_verifywrap.c:165)
-
---------------- pthread_rwlock_* ----------------
@@ -103,4 +99,7 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
+ at 0x........: main (tc20_verifywrap.c:262)
+
ERROR SUMMARY: 14 errors from 14 contexts (suppressed: 0 from 0)
Modified: trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b
===================================================================
--- trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b 2008-03-30 08:44:02 UTC (rev 7818)
+++ trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp-glibc2.3-b 2008-03-30 08:51:59 UTC (rev 7819)
@@ -37,13 +37,13 @@
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_trylock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:116)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] pre_mutex_lock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_timedlock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:121)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] mutex_unlock invalid mutex 0x........ rc 0
The object at address 0x........ is not a mutex.
@@ -70,14 +70,10 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
-[1/1] mutex_unlock error checking mutex 0x........ rc 0
-
-Mutex not locked: mutex 0x........, recursion count 0, owner 0.
- at 0x........: pthread_cond_timedwait* (drd_pthread_intercepts.c:?)
- by 0x........: main (tc20_verifywrap.c:165)
+[1/1] mutex_unlock error checking mutex 0x........ rc 1
[1/1] cond_pre_wait 0x........
[1/1] cond_post_wait 0x........
-[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 1
---------------- pthread_rwlock_* ----------------
@@ -131,6 +127,9 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
[1/1] mutex_destroy error checking mutex 0x........
+
+Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
+ at 0x........: main (tc20_verifywrap.c:262)
[1/1] mutex_destroy invalid mutex 0x........
[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 0
[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
|
|
From: <sv...@va...> - 2008-03-30 08:43:57
|
Author: bart
Date: 2008-03-30 09:44:02 +0100 (Sun, 30 Mar 2008)
New Revision: 7818
Log:
Updated expected output files.
Modified:
trunk/exp-drd/tests/tc20_verifywrap.stderr.exp
trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp
Modified: trunk/exp-drd/tests/tc20_verifywrap.stderr.exp
===================================================================
--- trunk/exp-drd/tests/tc20_verifywrap.stderr.exp 2008-03-30 08:41:59 UTC (rev 7817)
+++ trunk/exp-drd/tests/tc20_verifywrap.stderr.exp 2008-03-30 08:44:02 UTC (rev 7818)
@@ -54,10 +54,6 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
-Mutex not locked: mutex 0x........, recursion count 0, owner 0.
- at 0x........: pthread_cond_timedwait* (drd_pthread_intercepts.c:?)
- by 0x........: main (tc20_verifywrap.c:165)
-
---------------- pthread_rwlock_* ----------------
@@ -104,4 +100,7 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
+Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
+ at 0x........: main (tc20_verifywrap.c:262)
+
ERROR SUMMARY: 15 errors from 15 contexts (suppressed: 0 from 0)
Modified: trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp
===================================================================
--- trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp 2008-03-30 08:41:59 UTC (rev 7817)
+++ trunk/exp-drd/tests/tc20_verifywrap2.stderr.exp 2008-03-30 08:44:02 UTC (rev 7818)
@@ -34,19 +34,19 @@
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_lock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:108)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] pre_mutex_lock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_trylock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:116)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] pre_mutex_lock invalid mutex 0x........ rc 0 owner 0
The object at address 0x........ is not a mutex.
at 0x........: pthread_mutex_timedlock (drd_pthread_intercepts.c:?)
by 0x........: main (tc20_verifywrap.c:121)
-[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0 (locking failed)
[1/1] mutex_unlock invalid mutex 0x........ rc 0
The object at address 0x........ is not a mutex.
@@ -73,14 +73,10 @@
FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
-[1/1] mutex_unlock error checking mutex 0x........ rc 0
-
-Mutex not locked: mutex 0x........, recursion count 0, owner 0.
- at 0x........: pthread_cond_timedwait* (drd_pthread_intercepts.c:?)
- by 0x........: main (tc20_verifywrap.c:165)
+[1/1] mutex_unlock error checking mutex 0x........ rc 1
[1/1] cond_pre_wait 0x........
[1/1] cond_post_wait 0x........
-[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0
+[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 1
---------------- pthread_rwlock_* ----------------
@@ -134,6 +130,9 @@
Destroying locked rwlock: rwlock 0x.........
at 0x........: main (tc20_verifywrap.c:262)
[1/1] mutex_destroy error checking mutex 0x........
+
+Destroying locked mutex: mutex 0x........, recursion count 1, owner 1.
+ at 0x........: main (tc20_verifywrap.c:262)
[1/1] mutex_destroy invalid mutex 0x........
[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 0
[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
|
|
From: <sv...@va...> - 2008-03-30 08:41:56
|
Author: bart
Date: 2008-03-30 09:41:59 +0100 (Sun, 30 Mar 2008)
New Revision: 7817
Log:
Made mutex tracing output more verbose.
Modified:
trunk/exp-drd/drd_mutex.c
Modified: trunk/exp-drd/drd_mutex.c
===================================================================
--- trunk/exp-drd/drd_mutex.c 2008-03-30 08:40:49 UTC (rev 7816)
+++ trunk/exp-drd/drd_mutex.c 2008-03-30 08:41:59 UTC (rev 7817)
@@ -259,13 +259,14 @@
if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
- "[%d/%d] post_mutex_lock %s 0x%lx rc %d owner %d",
+ "[%d/%d] post_mutex_lock %s 0x%lx rc %d owner %d%s",
VG_(get_running_tid)(),
drd_tid,
p ? mutex_get_typename(p) : "(?)",
mutex,
p ? p->recursion_count : 0,
- p ? p->owner : VG_INVALID_THREADID);
+ p ? p->owner : VG_INVALID_THREADID,
+ took_lock ? "" : " (locking failed)");
}
if (! p || ! took_lock)
|
|
From: <sv...@va...> - 2008-03-30 08:40:46
|
Author: bart
Date: 2008-03-30 09:40:49 +0100 (Sun, 30 Mar 2008)
New Revision: 7816
Log:
Added DRD_IGNORE_VAR() and DRD_TRACE_VAR() macro's.
Modified:
trunk/exp-drd/drd_clientreq.h
Modified: trunk/exp-drd/drd_clientreq.h
===================================================================
--- trunk/exp-drd/drd_clientreq.h 2008-03-30 08:39:51 UTC (rev 7815)
+++ trunk/exp-drd/drd_clientreq.h 2008-03-30 08:40:49 UTC (rev 7816)
@@ -5,6 +5,10 @@
#include "valgrind.h" // VG_USERREQ_TOOL_BASE()
+#define DRD_IGNORE_VAR(x) { int res; VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION, &(x), sizeof(x), 0, 0, 0); }
+#define DRD_TRACE_VAR(x) { int res; VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_TRACE_ADDR, &(x), sizeof(x), 0, 0, 0); }
+
+
enum {
/* Ask the core the thread ID assigned by Valgrind. */
VG_USERREQ__GET_THREAD_SELF = VG_USERREQ_TOOL_BASE('D', 'R'),
@@ -155,7 +159,7 @@
VG_USERREQ__PRE_RWLOCK_UNLOCK,
/* args: Addr rwlock */
/* To notify the drd tool of a pthread_rwlock_unlock call. */
- VG_USERREQ__POST_RWLOCK_UNLOCK,
+ VG_USERREQ__POST_RWLOCK_UNLOCK
/* args: Addr rwlock, Bool unlocked */
};
@@ -166,13 +170,13 @@
mutex_type_recursive_mutex = 1,
mutex_type_errorcheck_mutex = 2,
mutex_type_default_mutex = 3,
- mutex_type_spinlock = 4,
+ mutex_type_spinlock = 4
} MutexT;
typedef enum
{
pthread_barrier = 1,
- gomp_barrier = 2,
+ gomp_barrier = 2
} BarrierT;
#endif // __DRD_CLIENTREQ_H
|
|
From: <sv...@va...> - 2008-03-30 08:39:50
|
Author: bart
Date: 2008-03-30 09:39:51 +0100 (Sun, 30 Mar 2008)
New Revision: 7815
Log:
Bug fix: DRD no longer complains that a mutex was not locked by the calling thread when unlocking a mutex after a call to pthread_cond_timedwait() that timed out.
Modified:
trunk/exp-drd/drd_pthread_intercepts.c
Modified: trunk/exp-drd/drd_pthread_intercepts.c
===================================================================
--- trunk/exp-drd/drd_pthread_intercepts.c 2008-03-29 14:42:59 UTC (rev 7814)
+++ trunk/exp-drd/drd_pthread_intercepts.c 2008-03-30 08:39:51 UTC (rev 7815)
@@ -459,7 +459,7 @@
cond, mutex, mutex_type(mutex), 0, 0);
CALL_FN_W_WW(ret, fn, cond, mutex);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
- cond, mutex, ret == 0, 0, 0);
+ cond, mutex, 1, 0, 0);
return ret;
}
@@ -477,7 +477,7 @@
cond, mutex, mutex_type(mutex), 0, 0);
CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT,
- cond, mutex, ret == 0, 0, 0);
+ cond, mutex, 1, 0, 0);
return ret;
}
|
|
From: Nicholas N. <nj...@cs...> - 2008-03-30 04:23:33
|
On Sat, 29 Mar 2008, Julian Seward wrote:
> Also, maybe use the test cases in perf/; at least bz2.c, fbench.c and
> ffbench.c ("make perf").
Also 'tinycc'.
Nick
|
|
From: Tom H. <th...@cy...> - 2008-03-30 04:16:33
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2008-03-30 03:15:07 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 330 tests, 76 stderr failures, 1 stdout failure, 29 post failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/lsframe1 (stderr) memcheck/tests/lsframe2 (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/noisy_child (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/varinfo1 (stderr) memcheck/tests/varinfo2 (stderr) memcheck/tests/varinfo3 (stderr) memcheck/tests/varinfo4 (stderr) memcheck/tests/varinfo5 (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/x86/bug152022 (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) massif/tests/alloc-fns-A (post) massif/tests/alloc-fns-B (post) massif/tests/basic (post) massif/tests/basic2 (post) massif/tests/big-alloc (post) massif/tests/culling1 (stderr) massif/tests/culling2 (stderr) massif/tests/custom_alloc (post) massif/tests/deep-A (post) massif/tests/deep-B (stderr) massif/tests/deep-B (post) massif/tests/deep-C (stderr) massif/tests/deep-C (post) massif/tests/deep-D (post) massif/tests/ignoring (post) massif/tests/insig (post) massif/tests/long-names (post) massif/tests/long-time (post) massif/tests/new-cpp (post) massif/tests/null (post) massif/tests/one (post) massif/tests/overloaded-new (post) massif/tests/peak (post) massif/tests/peak2 (stderr) massif/tests/peak2 (post) massif/tests/realloc (stderr) massif/tests/realloc (post) massif/tests/thresholds_0_0 (post) massif/tests/thresholds_0_10 (post) massif/tests/thresholds_10_0 (post) massif/tests/thresholds_10_10 (post) massif/tests/thresholds_5_0 (post) massif/tests/thresholds_5_10 (post) massif/tests/zero1 (post) massif/tests/zero2 (post) none/tests/blockfault (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/shell (stderr) none/tests/shell_valid1 (stderr) none/tests/shell_valid2 (stderr) none/tests/shell_valid3 (stderr) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/hg06_readshared (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc02_simple_tls (stderr) helgrind/tests/tc03_re_excl (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc07_hbl1 (stderr) helgrind/tests/tc08_hbl2 (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc11_XCHG (stderr) helgrind/tests/tc12_rwl_trivial (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) helgrind/tests/tc24_nonzero_sem (stderr) |
|
From: Tom H. <th...@cy...> - 2008-03-30 03:25:03
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2008-03-30 03:05:12 BST Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 413 tests, 7 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) exp-drd/tests/rwlock_race (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 413 tests, 6 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sun Mar 30 03:46:55 2008 --- new.short Sun Mar 30 04:25:03 2008 *************** *** 8,10 **** ! == 413 tests, 6 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) --- 8,10 ---- ! == 413 tests, 7 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) *************** *** 17,18 **** --- 17,19 ---- helgrind/tests/tc22_exit_w_lock (stderr) + exp-drd/tests/rwlock_race (stderr) |
|
From: Tom H. <th...@cy...> - 2008-03-30 02:57:37
|
Nightly build on aston ( x86_64, Fedora Core 5 ) started at 2008-03-30 03:20:08 BST Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 419 tests, 9 stderr failures, 1 stdout failure, 0 post failures == memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 419 tests, 9 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) exp-drd/tests/tc08_hbl2 (stdout) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sun Mar 30 03:41:20 2008 --- new.short Sun Mar 30 03:57:41 2008 *************** *** 8,10 **** ! == 419 tests, 9 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) --- 8,10 ---- ! == 419 tests, 9 stderr failures, 1 stdout failure, 0 post failures == memcheck/tests/malloc_free_fill (stderr) *************** *** 19,21 **** helgrind/tests/tc22_exit_w_lock (stderr) - exp-drd/tests/tc08_hbl2 (stdout) --- 19,20 ---- |
|
From: Tom H. <th...@cy...> - 2008-03-30 02:44:01
|
Nightly build on trojan ( x86_64, Fedora Core 6 ) started at 2008-03-30 03:25:03 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 417 tests, 8 stderr failures, 5 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/bug133694 (stdout) memcheck/tests/x86/bug133694 (stderr) memcheck/tests/x86/scalar (stderr) none/tests/cmdline1 (stdout) none/tests/cmdline2 (stdout) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) |
|
From: Tom H. <th...@cy...> - 2008-03-30 02:36:40
|
Nightly build on dellow ( x86_64, Fedora 8 ) started at 2008-03-30 03:10:03 BST Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 413 tests, 8 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 413 tests, 10 stderr failures, 3 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/pth_cvsimple (stdout) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sun Mar 30 03:22:23 2008 --- new.short Sun Mar 30 03:36:44 2008 *************** *** 8,10 **** ! == 413 tests, 10 stderr failures, 3 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) --- 8,10 ---- ! == 413 tests, 8 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/pointer-trace (stderr) *************** *** 16,22 **** none/tests/mremap2 (stdout) - none/tests/pth_cvsimple (stdout) - helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) - helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) --- 16,19 ---- |
|
From: Tom H. <th...@cy...> - 2008-03-30 02:18:11
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2008-03-30 03:00:05 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 419 tests, 31 stderr failures, 3 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/amd64/insn_ssse3 (stdout) none/tests/amd64/insn_ssse3 (stderr) none/tests/amd64/ssse3_misaligned (stderr) none/tests/blockfault (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/x86/insn_ssse3 (stdout) none/tests/x86/insn_ssse3 (stderr) none/tests/x86/ssse3_misaligned (stderr) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) |
|
From: Filipe C. <fi...@gm...> - 2008-03-29 20:28:50
|
On 29 Mar, 2008, at 19:02, Julian Seward wrote: > > I think (although not sure) that you can get a complete 32-bit only > build > if you build from clean, giving --enable-only32bit to ./configure. > > btw, if you give "--vg=" to perf/vg_perf multiple times, then it will > summarise all the results in one table, which makes them much easier > to > compare. (try "perl perf/vg_perf --help") > Thanks. Here's the stats from an amd64 server with one core that was idling: valgrind - original new-valgrind - with Nuno's regalloc patches optimized-valgrind - with those patches + optimization. filcab@escher ~/cvsw/valgrind $ cat ../perf-timings -- Running tests in perf ---------------------------------------------- -- bigcode1 -- bigcode1 new-valgrind:0.29s no: 7.5s (25.8x, -----) me:10.9s (37.6x, -----) bigcode1 optimized-valgrind:0.29s no: 7.6s (26.1x, -1.1%) me:11.1s (38.3x, -2.0%) bigcode1 valgrind :0.29s no: 7.5s (25.8x, 0.3%) me:10.9s (37.5x, 0.2%) -- bigcode2 -- bigcode2 new-valgrind:0.29s no:12.3s (42.3x, -----) me:21.1s (72.9x, -----) bigcode2 optimized-valgrind:0.29s no:12.4s (42.9x, -1.5%) me:21.9s (75.4x, -3.5%) bigcode2 valgrind :0.29s no:12.2s (42.1x, 0.4%) me:21.2s (73.0x, -0.2%) -- bz2 -- bz2 new-valgrind:1.02s no: 8.7s ( 8.6x, -----) me:18.7s (18.4x, -----) bz2 optimized-valgrind:1.02s no: 8.7s ( 8.5x, 0.7%) me:18.6s (18.2x, 1.0%) bz2 valgrind :1.02s no: 8.7s ( 8.5x, 0.3%) me:19.1s (18.7x, -2.0%) -- fbench -- fbench new-valgrind:0.57s no: 3.4s ( 6.0x, -----) me: 8.9s (15.7x, -----) fbench optimized-valgrind:0.57s no: 3.4s ( 6.0x, 0.0%) me: 9.0s (15.7x, -0.1%) fbench valgrind :0.57s no: 3.5s ( 6.1x, -0.9%) me: 9.0s (15.7x, -0.2%) -- ffbench -- ffbench new-valgrind:2.25s no: 3.5s ( 1.6x, -----) me: 8.2s ( 3.6x, -----) ffbench optimized-valgrind:2.25s no: 3.6s ( 1.6x, -0.8%) me: 8.2s ( 3.6x, -0.6%) ffbench valgrind :2.25s no: 3.5s ( 1.6x, 0.0%) me: 8.1s ( 3.6x, 0.1%) -- heap -- heap new-valgrind:0.24s no: 2.8s (11.5x, -----) me:16.4s (68.5x, -----) heap optimized-valgrind:0.24s no: 2.8s (11.7x, -1.1%) me:16.8s (70.0x, -2.3%) heap valgrind :0.24s no: 2.8s (11.7x, -1.1%) me:16.7s (69.8x, -1.9%) -- sarp -- sarp new-valgrind:0.11s no: 0.6s ( 5.0x, -----) me: 4.3s (39.2x, -----) sarp optimized-valgrind:0.11s no: 0.6s ( 5.2x, -3.6%) me: 4.3s (39.5x, -0.9%) sarp valgrind :0.11s no: 0.6s ( 5.1x, -1.8%) me: 4.3s (39.1x, 0.2%) -- tinycc -- tinycc new-valgrind:0.38s no: 5.3s (13.9x, -----) me:23.0s (60.6x, -----) tinycc optimized-valgrind:0.38s no: 5.3s (14.0x, -0.2%) me:23.2s (61.1x, -0.7%) tinycc valgrind :0.38s no: 5.3s (14.0x, -0.4%) me:23.1s (60.8x, -0.3%) -- Finished tests in perf ---------------------------------------------- == 8 programs, 48 timings ================= 475.29user 5.76system 8:01.96elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (1major+731739minor)pagefaults 0swaps I can't test it decently with firefox or something because right now I don't have physical access (well. maybe I could just kill firefox after some minutes). Also, tracing firefox is quite strange because there are some shell scripts in between and I have to search for the process firefox-bin afterward so I can get the stats. Is there a way to --trace- children=yes and then have the global stats? I think running "valgrind -v valgrind firefox" may be a bit of an overkill. - Filipe Cabecinhas |
|
From: Julian S. <js...@ac...> - 2008-03-29 19:06:41
|
> This is with a x86_64 machine with vmware. Is there a way to compile > the tests in 32-bit mode? Or must I do some hacking in the Makefiles? I think (although not sure) that you can get a complete 32-bit only build if you build from clean, giving --enable-only32bit to ./configure. btw, if you give "--vg=" to perf/vg_perf multiple times, then it will summarise all the results in one table, which makes them much easier to compare. (try "perl perf/vg_perf --help") The code expansion numbers (eg 300,800 -> 2,120,621; ratio 70:10) are important, though. At this level of tuning any speedup often gets lost in the measurement noise, and so these numbers are a much more reliable way to see if you managed to generate less code. What they mean is new 8,362 (300,800 -> 2,120,621; ratio 70:10) 8362 blocks translated 300800 bytes of original code in those blocks converted to 2120621 bytes by vex J |
|
From: Julian S. <js...@ac...> - 2008-03-29 18:58:32
|
> Yes, it's worth trying.
> [...]
> This will hardly be a complete solution though.
> Just an example from my last week's runs: I've run some test under
> Helgrind ~20 times.
> There were two reports that made me curious: one appeared in every run
> and another only appeared 2-3 times.
Yes. I agree it is not the ideal solution. But (obviously) the problem
is that to collect all this information for all memory locations is
impossibly expensive, so restricting it to cases where we have seen a
race is a good filtering heuristic. (maybe not good enough)
Even if it can be only a 90% solution, it is much better than what we
have right now. FWIW, on Friday I spent some time with HGDEV chasing
a race in the new OpenOffice 2.4, and .. it is very difficult to make
sense of the results. Basically I gave up. ("yes, ok, I agree, there
is a race here. but where did the access(es) from other threads happen?")
Although it is true, OOo is not exactly a simple or small program :-)
J
|
|
From: Filipe C. <fi...@gm...> - 2008-03-29 18:57:05
|
On 29 Mar, 2008, at 13:08, Julian Seward wrote: > > What about something really large, like konqueror, mozilla, OOo? > > Do you have some more comprehensive before/after numbers? > > * what are the before/after code expansion ratios for apps as a whole, > as shown by these lines (run with -v) ? > > --8732-- transtab: new 3,095 (68,098 -> 1,067,412; ratio 156:10) > > * what are the actual measured performance effects? Have you made > friends yet with 'make perf' ? > > J Also, the make perf suite: Old valgrind: -- Running tests in perf ---------------------------------------------- bigcode1 valgrind :0.23s no: 2.4s (10.6x, -----) me: 4.7s (20.3x, -----) bigcode2 valgrind :0.28s no: 6.3s (22.6x, -----) me:13.7s (49.0x, -----) bz2 valgrind :0.99s no: 2.4s ( 2.4x, -----) me:10.7s (10.8x, -----) fbench valgrind :0.56s no: 0.7s ( 1.3x, -----) me: 7.1s (12.7x, -----) ffbench valgrind :0.40s no: 0.9s ( 2.3x, -----) me: 5.2s (13.0x, -----) heap valgrind :0.28s no: 0.8s ( 2.7x, -----) me:15.7s (56.0x, -----) sarp valgrind :0.03s no: 0.2s ( 6.0x, -----) me: 3.6s (119.0x, -----) tinycc valgrind :0.31s no: 2.1s ( 6.7x, -----) me:19.2s (62.0x, -----) -- Finished tests in perf ---------------------------------------------- real 2m13.018s user 1m39.190s sys 0m32.710s Patched valgrind: -- Running tests in perf ---------------------------------------------- bigcode1 new-valgrind:0.24s no: 2.9s (12.2x, -----) me: 6.1s (25.4x, -----) bigcode2 new-valgrind:0.27s no: 7.8s (28.7x, -----) me:16.1s (59.6x, -----) bz2 new-valgrind:0.96s no: 4.8s ( 5.0x, -----) me:13.4s (14.0x, -----) fbench new-valgrind:0.57s no: 1.2s ( 2.0x, -----) me: 6.4s (11.3x, -----) ffbench new-valgrind:0.40s no: 0.9s ( 2.3x, -----) me: 5.2s (13.0x, -----) heap new-valgrind:0.27s no: 0.7s ( 2.7x, -----) me:14.5s (53.6x, -----) sarp new-valgrind:0.04s no: 0.2s ( 4.2x, -----) me: 3.6s (89.5x, -----) tinycc new-valgrind:0.31s no: 1.5s ( 4.9x, -----) me:17.9s (57.6x, -----) -- Finished tests in perf ---------------------------------------------- real 2m11.275s user 1m46.779s sys 0m23.545s This is with a x86_64 machine with vmware. Is there a way to compile the tests in 32-bit mode? Or must I do some hacking in the Makefiles? I'll revert the optimization patch so we could see if the problem is in the regalloc bugfixes or in the optimization. - Filipe Cabecinhas |
|
From: Julian S. <js...@ac...> - 2008-03-29 18:49:05
|
Hi,
> Before:
> --10356-- transtab: new 8,362 (300,800 -> 2,120,621; ratio
> 70:10)
> --14932-- transtab: new 8,359 (300,880 -> 2,119,507; ratio
> 70:10) [0 scs]
--tool=memcheck stresses the register allocator and spiller much more
than --tool=none, so it is a better test of any optimisations. I suggest
you try it.
Also, maybe use the test cases in perf/; at least bz2.c, fbench.c and
ffbench.c ("make perf"). These are conveniently provided for exactly
this kind of reason :-)
> FWIW: I'm running this on an intel mac with vmware fusion. I wasn't
> using the CPU outside vmware fusion (only mild web browsing) so the
> test shouldn't have been skewed too much.
Hmm, getting reliable timing numbers even on a real machine is hard
enough. On a VM is likely to be more difficult. (The VMM introduces
more sources of measurement "noise" ..)
J
|
|
From: Filipe C. <fi...@gm...> - 2008-03-29 17:45:52
|
On 29 Mar, 2008, at 13:08, Julian Seward wrote: > > What about something really large, like konqueror, mozilla, OOo? > > Do you have some more comprehensive before/after numbers? > > * what are the before/after code expansion ratios for apps as a whole, > as shown by these lines (run with -v) ? > > --8732-- transtab: new 3,095 (68,098 -> 1,067,412; ratio 156:10) > > * what are the actual measured performance effects? Have you made > friends yet with 'make perf' ? > I just tried the optimizations with openssl test and here are some numbers, tested with: time ./vg-in-place --tool=none -v openssl speed Before: ==10356== --10356-- translate: fast SP updates identified: 0 ( --%) --10356-- translate: generic_known SP updates identified: 0 ( --%) --10356-- translate: generic_unknown SP updates identified: 0 ( --%) --10356-- tt/tc: 32,633,199 tt lookups requiring 47,799,060 probes --10356-- tt/tc: 32,633,199 fast-cache updates, 2 flushes --10356-- transtab: new 8,362 (300,800 -> 2,120,621; ratio 70:10) [0 scs] --10356-- transtab: dumped 0 (0 -> ??) --10356-- transtab: discarded 0 (0 -> ??) --10356-- scheduler: 9,698,533,428 jumps (bb entries). --10356-- scheduler: 96,985/32,728,700 major/minor sched events. --10356-- sanity: 96986 cheap, 419 expensive checks. --10356-- exectx: 769 lists, 0 contexts (avg 0 per list) --10356-- exectx: 0 searches, 0 full compares (0 per 1000) --10356-- exectx: 0 cmp2, 0 cmp4, 0 cmpAll --10356-- errormgr: 0 supplist searches, 0 comparisons during search --10356-- errormgr: 0 errlist searches, 0 comparisons during search real 8m52.593s user 6m35.829s sys 2m13.512s After: ==14932== --14932-- translate: fast SP updates identified: 0 ( --%) --14932-- translate: generic_known SP updates identified: 0 ( --%) --14932-- translate: generic_unknown SP updates identified: 0 ( --%) --14932-- tt/tc: 34,848,394 tt lookups requiring 51,153,884 probes --14932-- tt/tc: 34,848,394 fast-cache updates, 2 flushes --14932-- transtab: new 8,359 (300,880 -> 2,119,507; ratio 70:10) [0 scs] --14932-- transtab: dumped 0 (0 -> ??) --14932-- transtab: discarded 0 (0 -> ??) --14932-- scheduler: 10,034,632,377 jumps (bb entries). --14932-- scheduler: 100,346/34,948,591 major/minor sched events. --14932-- sanity: 100347 cheap, 427 expensive checks. --14932-- exectx: 769 lists, 0 contexts (avg 0 per list) --14932-- exectx: 0 searches, 0 full compares (0 per 1000) --14932-- exectx: 0 cmp2, 0 cmp4, 0 cmpAll --14932-- errormgr: 0 supplist searches, 0 comparisons during search --14932-- errormgr: 0 errlist searches, 0 comparisons during search real 8m52.360s user 6m28.008s sys 2m22.093s There is only a marginal difference. I may try with memcheck if you want but it will just give up on error reporting about half-way due to getting 1000000 errors. I could also try mozilla, firefox, OOo or other programs like those but shouldn't the conditions be more or less similar? I couldn't figure out how to do a run with firefox that didn't implied human interaction, I'll look into that now. FWIW: I'm running this on an intel mac with vmware fusion. I wasn't using the CPU outside vmware fusion (only mild web browsing) so the test shouldn't have been skewed too much. - Filipe Cabecinhas |
|
From: Konstantin S. <kon...@gm...> - 2008-03-29 16:42:24
|
On Sat, Mar 29, 2008 at 4:28 PM, Julian Seward <js...@ac...> wrote:
>
> > First is easy if we know the address to trace (with --trace-addr)
> > before we start Helgrind. But we usually don't. :(
>
> Would this help?
>
> Once an address is marked as SHVAL_Race, start collecting more info
> about it. In particular, record stack traces for the next N (say 100)
> memory accesses to it, or maybe better a stack trace for the first access
> to it from each different thread. Or some variant of these.
>
> This doesn't help find the first access to an address in a race. But
> on the assumption that most races happen > 1 time (as reported in the
> Rodehoffer "Racetrack" paper) then this might be an easy way to find
> some other places where the address is accessed.
Yes, it's worth trying.
Maybe, something like this: once a race is detected and reported (i.e.
not a suppressed error), put the memory in SHVAL_New_Traced state.
And when handling all other accesses apply the same state machine, but
instead of states SHVAL_R and SHVAL_W, use SHVAL_{R,W}_Traced (and, of
course, print or collect the traces). If a race is detected again,
print a report saying that we have all the traces now.
Will do experiments next week.
This will hardly be a complete solution though.
Just an example from my last week's runs: I've run some test under
Helgrind ~20 times.
There were two reports that made me curious: one appeared in every run
and another only appeared 2-3 times.
I chased the first one with techniques described in my first message.
That race happens > 1 times.
But I still did not catch the second race and I suspect it happens
only once (it's in a destructor).
--kcc
--kcc
|
|
From: <sv...@va...> - 2008-03-29 14:42:55
|
Author: bart
Date: 2008-03-29 14:42:59 +0000 (Sat, 29 Mar 2008)
New Revision: 7814
Log:
Removed --trace-mem which traced all memory accesses. Added support for multiple --trace-address options. A range size can now be specified to the VG_USERREQ__DRD_START_TRACE_ADDR client request. Added VG_USERREQ__DRD_STOP_TRACE_ADDR client request.
Modified:
trunk/exp-drd/drd_clientreq.c
trunk/exp-drd/drd_clientreq.h
trunk/exp-drd/drd_main.c
trunk/exp-drd/drd_suppression.c
trunk/exp-drd/drd_suppression.h
trunk/exp-drd/drd_track.h
Modified: trunk/exp-drd/drd_clientreq.c
===================================================================
--- trunk/exp-drd/drd_clientreq.c 2008-03-29 14:40:08 UTC (rev 7813)
+++ trunk/exp-drd/drd_clientreq.c 2008-03-29 14:42:59 UTC (rev 7814)
@@ -109,10 +109,14 @@
thread_new_segment(PtThreadIdToDrdThreadId(arg[1]));
break;
- case VG_USERREQ__DRD_TRACE_ADDR:
- drd_trace_addr(arg[1]);
+ case VG_USERREQ__DRD_START_TRACE_ADDR:
+ drd_start_tracing_address_range(arg[1], arg[1] + arg[2]);
break;
+ case VG_USERREQ__DRD_STOP_TRACE_ADDR:
+ drd_stop_tracing_address_range(arg[1], arg[1] + arg[2]);
+ break;
+
case VG_USERREQ__SET_PTHREADID:
thread_set_pthreadid(drd_tid, arg[1]);
break;
Modified: trunk/exp-drd/drd_clientreq.h
===================================================================
--- trunk/exp-drd/drd_clientreq.h 2008-03-29 14:40:08 UTC (rev 7813)
+++ trunk/exp-drd/drd_clientreq.h 2008-03-29 14:42:59 UTC (rev 7814)
@@ -25,9 +25,12 @@
/* To ask the drd tool to start a new segment in the specified thread. */
VG_USERREQ__DRD_START_NEW_SEGMENT,
/* args: POSIX thread ID. */
- /* To ask the drd tool to trace all accesses to the specified address. */
- VG_USERREQ__DRD_TRACE_ADDR,
- /* args: Addr. */
+ /* To ask the drd tool to trace all accesses to the specified range. */
+ VG_USERREQ__DRD_START_TRACE_ADDR,
+ /* args: Addr, SizeT. */
+ /* To ask the drd tool to stop tracing accesses to the specified range. */
+ VG_USERREQ__DRD_STOP_TRACE_ADDR,
+ /* args: Addr, SizeT. */
/* Tell the core the pthread_t of the running thread */
VG_USERREQ__SET_PTHREADID,
Modified: trunk/exp-drd/drd_main.c
===================================================================
--- trunk/exp-drd/drd_main.c 2008-03-29 14:40:08 UTC (rev 7813)
+++ trunk/exp-drd/drd_main.c 2008-03-29 14:42:59 UTC (rev 7814)
@@ -63,8 +63,6 @@
static Bool drd_print_stats = False;
static Bool drd_trace_fork_join = False;
-static Bool drd_trace_mem = False;
-static Addr drd_trace_address = 0;
static Bool s_drd_var_info = False;
static Bool s_show_stack_usage = False;
@@ -99,7 +97,6 @@
else VG_BOOL_CLO(arg, "--trace-csw", trace_csw)
else VG_BOOL_CLO(arg, "--trace-danger-set", trace_danger_set)
else VG_BOOL_CLO(arg, "--trace-fork-join", drd_trace_fork_join)
- else VG_BOOL_CLO(arg, "--trace-mem", drd_trace_mem)
else VG_BOOL_CLO(arg, "--trace-mutex", trace_mutex)
else VG_BOOL_CLO(arg, "--trace-rwlock", trace_rwlock)
else VG_BOOL_CLO(arg, "--trace-segment", trace_segment)
@@ -116,7 +113,8 @@
set_show_conflicting_segments(show_confl_seg);
if (trace_address)
{
- drd_trace_address = VG_(strtoll16)(trace_address, 0);
+ const Addr addr = VG_(strtoll16)(trace_address, 0);
+ drd_start_tracing_address_range(addr, addr + 1);
}
if (trace_barrier != -1)
barrier_set_trace(trace_barrier);
@@ -221,7 +219,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, size))
{
drd_trace_mem_access(addr, size, eLoad);
}
@@ -240,7 +238,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 1))
{
drd_trace_mem_access(addr, 1, eLoad);
}
@@ -259,7 +257,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 2))
{
drd_trace_mem_access(addr, 2, eLoad);
}
@@ -278,7 +276,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 4))
{
drd_trace_mem_access(addr, 4, eLoad);
}
@@ -297,7 +295,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 8))
{
drd_trace_mem_access(addr, 8, eLoad);
}
@@ -323,7 +321,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, size))
{
drd_trace_mem_access(addr, size, eStore);
}
@@ -342,7 +340,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 1))
{
drd_trace_mem_access(addr, 1, eStore);
}
@@ -361,7 +359,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 2))
{
drd_trace_mem_access(addr, 2, eStore);
}
@@ -380,7 +378,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 4))
{
drd_trace_mem_access(addr, 4, eStore);
}
@@ -399,7 +397,7 @@
if (! running_thread_is_recording())
return;
- if (drd_trace_mem || (addr == drd_trace_address))
+ if (range_any_is_traced(addr, 8))
{
drd_trace_mem_access(addr, 8, eStore);
}
@@ -460,11 +458,9 @@
static void drd_start_using_mem(const Addr a1, const SizeT len)
{
- const Addr a2 = a1 + len;
+ tl_assert(a1 < a1 + len);
- tl_assert(a1 < a2);
-
- if (a1 <= drd_trace_address && drd_trace_address < a2)
+ if (range_any_is_traced(a1, len))
{
drd_trace_mem_access(a1, len, eStart);
}
@@ -476,7 +472,7 @@
tl_assert(a1 < a2);
- if (a1 <= drd_trace_address && drd_trace_address < a2)
+ if (range_any_is_traced(a1, len))
{
drd_trace_mem_access(a1, len, eEnd);
}
@@ -593,10 +589,6 @@
barrier_thread_delete(drd_joinee);
}
-void drd_trace_addr(const Addr addr)
-{
- drd_trace_address = addr;
-}
/* Called after a thread has performed its last memory access. */
static void drd_thread_finished(ThreadId vg_tid)
Modified: trunk/exp-drd/drd_suppression.c
===================================================================
--- trunk/exp-drd/drd_suppression.c 2008-03-29 14:40:08 UTC (rev 7813)
+++ trunk/exp-drd/drd_suppression.c 2008-03-29 14:42:59 UTC (rev 7814)
@@ -35,6 +35,7 @@
static struct bitmap* s_suppressed;
static Bool s_trace_suppression;
+Bool g_any_address_traced = False;
// Function definitions.
@@ -81,7 +82,7 @@
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 12);
tl_assert(False);
}
- bm_clear(s_suppressed, a1, a2);
+ bm_clear_store(s_suppressed, a1, a2);
}
/**
@@ -104,6 +105,33 @@
return bm_has_any(s_suppressed, a1, a2, eStore);
}
+void drd_start_tracing_address_range(const Addr a1, const Addr a2)
+{
+ tl_assert(a1 < a2);
+
+ bm_access_range_load(s_suppressed, a1, a2);
+ if (! g_any_address_traced)
+ {
+ g_any_address_traced = True;
+ }
+}
+
+void drd_stop_tracing_address_range(const Addr a1, const Addr a2)
+{
+ tl_assert(a1 < a2);
+
+ bm_clear_load(s_suppressed, a1, a2);
+ if (g_any_address_traced)
+ {
+ g_any_address_traced = bm_has_any(s_suppressed, 0, ~(Addr)0, eLoad);
+ }
+}
+
+Bool drd_is_any_traced(const Addr a1, const Addr a2)
+{
+ return bm_has_any(s_suppressed, a1, a2, eLoad);
+}
+
void drd_suppression_stop_using_mem(const Addr a1, const Addr a2)
{
if (s_trace_suppression)
Modified: trunk/exp-drd/drd_suppression.h
===================================================================
--- trunk/exp-drd/drd_suppression.h 2008-03-29 14:40:08 UTC (rev 7813)
+++ trunk/exp-drd/drd_suppression.h 2008-03-29 14:42:59 UTC (rev 7814)
@@ -4,6 +4,10 @@
#include "pub_tool_basics.h"
+
+extern Bool g_any_address_traced;
+
+
void suppression_set_trace(const Bool trace_suppression);
void drd_suppression_init(void);
void drd_start_suppression(const Addr a1, const Addr a2,
@@ -11,7 +15,17 @@
void drd_finish_suppression(const Addr a1, const Addr a2);
Bool drd_is_suppressed(const Addr a1, const Addr a2);
Bool drd_is_any_suppressed(const Addr a1, const Addr a2);
+void drd_start_tracing_address_range(const Addr a1, const Addr a2);
+void drd_stop_tracing_address_range(const Addr a1, const Addr a2);
+Bool drd_is_any_traced(const Addr a1, const Addr a2);
void drd_suppression_stop_using_mem(const Addr a1, const Addr a2);
+static __inline__
+int range_any_is_traced(const Addr addr, const SizeT size)
+{
+ return (g_any_address_traced && drd_is_any_traced(addr, addr + size));
+}
+
+
#endif // __PUB_CORE_DRD_H
Modified: trunk/exp-drd/drd_track.h
===================================================================
--- trunk/exp-drd/drd_track.h 2008-03-29 14:40:08 UTC (rev 7813)
+++ trunk/exp-drd/drd_track.h 2008-03-29 14:42:59 UTC (rev 7814)
@@ -25,8 +25,6 @@
void drd_post_thread_join(DrdThreadId joiner, DrdThreadId joinee);
-void drd_trace_addr(const Addr addr);
-
void drd_pre_mutex_init(Addr mutex, const MutexT mutex_type);
void drd_post_mutex_destroy(Addr mutex, const MutexT mutex_type);
void drd_pre_mutex_lock(const Addr mutex, const MutexT mutex_type,
|
|
From: <sv...@va...> - 2008-03-29 14:40:04
|
Author: bart
Date: 2008-03-29 14:40:08 +0000 (Sat, 29 Mar 2008)
New Revision: 7813
Log:
Added functions bm_clear_load() and bm_clear_store().
Modified:
trunk/exp-drd/drd_bitmap.c
trunk/exp-drd/pub_drd_bitmap.h
Modified: trunk/exp-drd/drd_bitmap.c
===================================================================
--- trunk/exp-drd/drd_bitmap.c 2008-03-29 14:24:26 UTC (rev 7812)
+++ trunk/exp-drd/drd_bitmap.c 2008-03-29 14:40:08 UTC (rev 7813)
@@ -441,6 +441,42 @@
}
}
+/** Clear all references to loads in bitmap bm starting at address a1 and
+ * up to but not including address a2.
+ */
+void bm_clear_load(const struct bitmap* const bm,
+ const Addr a1, const Addr a2)
+{
+ Addr a;
+
+ for (a = a1; a < a2; a++)
+ {
+ struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
+ if (p2)
+ {
+ bm0_clear(p2->bm1.bm0_r, a & ADDR0_MASK);
+ }
+ }
+}
+
+/** Clear all references to stores in bitmap bm starting at address a1 and
+ * up to but not including address a2.
+ */
+void bm_clear_store(const struct bitmap* const bm,
+ const Addr a1, const Addr a2)
+{
+ Addr a;
+
+ for (a = a1; a < a2; a++)
+ {
+ struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
+ if (p2)
+ {
+ bm0_clear(p2->bm1.bm0_w, a & ADDR0_MASK);
+ }
+ }
+}
+
Bool bm_has_conflict_with(const struct bitmap* const bm,
const Addr a1, const Addr a2,
const BmAccessTypeT access_type)
Modified: trunk/exp-drd/pub_drd_bitmap.h
===================================================================
--- trunk/exp-drd/pub_drd_bitmap.h 2008-03-29 14:24:26 UTC (rev 7812)
+++ trunk/exp-drd/pub_drd_bitmap.h 2008-03-29 14:40:08 UTC (rev 7813)
@@ -80,6 +80,10 @@
const Addr address, const BmAccessTypeT access_type);
void bm_clear(const struct bitmap* const bm,
const Addr a1, const Addr a2);
+void bm_clear_load(const struct bitmap* const bm,
+ const Addr a1, const Addr a2);
+void bm_clear_store(const struct bitmap* const bm,
+ const Addr a1, const Addr a2);
Bool bm_has_conflict_with(const struct bitmap* const bm,
const Addr a1, const Addr a2,
const BmAccessTypeT access_type);
|
|
From: <sv...@va...> - 2008-03-29 14:24:24
|
Author: sewardj
Date: 2008-03-29 14:24:26 +0000 (Sat, 29 Mar 2008)
New Revision: 7812
Log:
Increase stack size (needed for reading debuginfo off x86 OOo 2.4 build)
Modified:
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_debuginfo/readdwarf3.c
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_debuginfo/readdwarf3.c 2008-03-29 14:22:59 UTC (rev 7811)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_debuginfo/readdwarf3.c 2008-03-29 14:24:26 UTC (rev 7812)
@@ -1164,7 +1164,7 @@
}
TempVar;
-#define N_D3_VAR_STACK 24
+#define N_D3_VAR_STACK 48
typedef
struct {
|
|
From: <sv...@va...> - 2008-03-29 14:23:10
|
Author: sewardj
Date: 2008-03-29 14:22:59 +0000 (Sat, 29 Mar 2008)
New Revision: 7811
Log:
Generate instrumentation code to shadow most values with 32-bit origin
tags (referred to by the generic letter 'b' in the code, as opposed to
'v' for the definedness shadow values).
Improve debug tracing, so as to make it easy to see which code is for
V-bit (definedness) tracking and which for B-tag (origin) tracking.
The important functions are schemeS, which generates origin tracking
code for an IR statement, and schemeE, which generates an origin
expression for an IR expression.
The existing V-bits tracking code is almost completely unchanged.
The only change is that when generating a call to
MC_(helperc_value_check0_fail), schemeE is used to generate an origin
value to pass to the helper function. (Obviously, otherwise all of
this would be completely pointless).
This involves some nasty x86-specific hacks to do with guest state
layout, which will have to be cleaned up for real. See function
get_shadow_offset for the gruesome details.
Modified:
branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_translate.c
Modified: branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_translate.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_translate.c 2008-03-29 14:12:37 UTC (rev 7810)
+++ branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_translate.c 2008-03-29 14:22:59 UTC (rev 7811)
@@ -116,7 +116,7 @@
struct _MCEnv;
-static IRType shadowType ( IRType ty );
+static IRType shadowTypeV ( IRType ty );
static IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e );
@@ -130,6 +130,7 @@
/* MODIFIED: the superblock being constructed. IRStmts are
added. */
IRSB* bb;
+ Bool trace;
/* MODIFIED: a table [0 .. #temps_in_original_bb-1] which maps
original temps to their current their current shadow temp.
@@ -139,7 +140,8 @@
point original tmps are shadowed by integer tmps of the same
size, and Bit-typed original tmps are shadowed by the type
Ity_I8. See comment below. */
- IRTemp* tmpMap;
+ IRTemp* tmpMapV; /* V-bit tmp shadows */
+ IRTemp* tmpMapB; /* origin tracking tmp shadows */
Int n_originalTmps; /* for range checking */
/* MODIFIED: indicates whether "bogus" literals have so far been
@@ -183,15 +185,15 @@
/* Find the tmp currently shadowing the given original tmp. If none
so far exists, allocate one. */
-static IRTemp findShadowTmp ( MCEnv* mce, IRTemp orig )
+static IRTemp findShadowTmpV ( MCEnv* mce, IRTemp orig )
{
tl_assert(orig < mce->n_originalTmps);
- if (mce->tmpMap[orig] == IRTemp_INVALID) {
- mce->tmpMap[orig]
+ if (mce->tmpMapV[orig] == IRTemp_INVALID) {
+ mce->tmpMapV[orig]
= newIRTemp(mce->bb->tyenv,
- shadowType(mce->bb->tyenv->types[orig]));
+ shadowTypeV(mce->bb->tyenv->types[orig]));
}
- return mce->tmpMap[orig];
+ return mce->tmpMapV[orig];
}
/* Allocate a new shadow for the given original tmp. This means any
@@ -200,12 +202,12 @@
for undefinedness, but unfortunately IR's SSA property disallows
this. Instead we must abandon the old shadow, allocate a new one
and use that instead. */
-static void newShadowTmp ( MCEnv* mce, IRTemp orig )
+static void newShadowTmpV ( MCEnv* mce, IRTemp orig )
{
tl_assert(orig < mce->n_originalTmps);
- mce->tmpMap[orig]
+ mce->tmpMapV[orig]
= newIRTemp(mce->bb->tyenv,
- shadowType(mce->bb->tyenv->types[orig]));
+ shadowTypeV(mce->bb->tyenv->types[orig]));
}
@@ -265,7 +267,7 @@
given type. The only valid shadow types are Bit, I8, I16, I32,
I64, V128. */
-static IRType shadowType ( IRType ty )
+static IRType shadowTypeV ( IRType ty )
{
switch (ty) {
case Ity_I1:
@@ -278,7 +280,7 @@
case Ity_F64: return Ity_I64;
case Ity_V128: return Ity_V128;
default: ppIRType(ty);
- VG_(tool_panic)("memcheck:shadowType");
+ VG_(tool_panic)("memcheck:shadowTypeV");
}
}
@@ -301,14 +303,22 @@
/*--- Constructing IR fragments ---*/
/*------------------------------------------------------------*/
+/* add stmt to a bb */
+static inline void stmt ( HChar cat, MCEnv* mce, IRStmt* st ) {
+ if (mce->trace) {
+ VG_(printf)(" %c: ", cat);
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ }
+ addStmtToIRSB(mce->bb, st);
+}
+
/* assign value to tmp */
-#define assign(_bb,_tmp,_expr) \
- addStmtToIRSB((_bb), IRStmt_WrTmp((_tmp),(_expr)))
+static inline
+void assign ( HChar cat, MCEnv* mce, IRTemp tmp, IRExpr* expr ) {
+ stmt(cat, mce, IRStmt_WrTmp(tmp,expr));
+}
-/* add stmt to a bb */
-#define stmt(_bb,_stmt) \
- addStmtToIRSB((_bb), (_stmt))
-
/* build various kinds of expressions */
#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
#define unop(_op, _arg) IRExpr_Unop((_op),(_arg))
@@ -322,9 +332,9 @@
/* bind the given expression to a new temporary, and return the
temporary. This effectively converts an arbitrary expression into
an atom. */
-static IRAtom* assignNew ( MCEnv* mce, IRType ty, IRExpr* e ) {
+static IRAtom* assignNew ( HChar cat, MCEnv* mce, IRType ty, IRExpr* e ) {
IRTemp t = newIRTemp(mce->bb->tyenv, ty);
- assign(mce->bb, t, e);
+ assign(cat, mce, t, e);
return mkexpr(t);
}
@@ -338,31 +348,31 @@
static IRAtom* mkDifD8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I8, binop(Iop_And8, a1, a2));
+ return assignNew('V', mce, Ity_I8, binop(Iop_And8, a1, a2));
}
static IRAtom* mkDifD16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I16, binop(Iop_And16, a1, a2));
+ return assignNew('V', mce, Ity_I16, binop(Iop_And16, a1, a2));
}
static IRAtom* mkDifD32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I32, binop(Iop_And32, a1, a2));
+ return assignNew('V', mce, Ity_I32, binop(Iop_And32, a1, a2));
}
static IRAtom* mkDifD64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I64, binop(Iop_And64, a1, a2));
+ return assignNew('V', mce, Ity_I64, binop(Iop_And64, a1, a2));
}
static IRAtom* mkDifDV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_V128, binop(Iop_AndV128, a1, a2));
+ return assignNew('V', mce, Ity_V128, binop(Iop_AndV128, a1, a2));
}
/* --------- Undefined-if-either-undefined --------- */
@@ -370,31 +380,31 @@
static IRAtom* mkUifU8 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I8, binop(Iop_Or8, a1, a2));
+ return assignNew('V', mce, Ity_I8, binop(Iop_Or8, a1, a2));
}
static IRAtom* mkUifU16 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I16, binop(Iop_Or16, a1, a2));
+ return assignNew('V', mce, Ity_I16, binop(Iop_Or16, a1, a2));
}
static IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I32, binop(Iop_Or32, a1, a2));
+ return assignNew('V', mce, Ity_I32, binop(Iop_Or32, a1, a2));
}
static IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_I64, binop(Iop_Or64, a1, a2));
+ return assignNew('V', mce, Ity_I64, binop(Iop_Or64, a1, a2));
}
static IRAtom* mkUifUV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
- return assignNew(mce, Ity_V128, binop(Iop_OrV128, a1, a2));
+ return assignNew('V', mce, Ity_V128, binop(Iop_OrV128, a1, a2));
}
static IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) {
@@ -414,22 +424,22 @@
static IRAtom* mkLeft8 ( MCEnv* mce, IRAtom* a1 ) {
tl_assert(isShadowAtom(mce,a1));
- return assignNew(mce, Ity_I8, unop(Iop_Left8, a1));
+ return assignNew('V', mce, Ity_I8, unop(Iop_Left8, a1));
}
static IRAtom* mkLeft16 ( MCEnv* mce, IRAtom* a1 ) {
tl_assert(isShadowAtom(mce,a1));
- return assignNew(mce, Ity_I16, unop(Iop_Left16, a1));
+ return assignNew('V', mce, Ity_I16, unop(Iop_Left16, a1));
}
static IRAtom* mkLeft32 ( MCEnv* mce, IRAtom* a1 ) {
tl_assert(isShadowAtom(mce,a1));
- return assignNew(mce, Ity_I32, unop(Iop_Left32, a1));
+ return assignNew('V', mce, Ity_I32, unop(Iop_Left32, a1));
}
static IRAtom* mkLeft64 ( MCEnv* mce, IRAtom* a1 ) {
tl_assert(isShadowAtom(mce,a1));
- return assignNew(mce, Ity_I64, unop(Iop_Left64, a1));
+ return assignNew('V', mce, Ity_I64, unop(Iop_Left64, a1));
}
/* --------- 'Improvement' functions for AND/OR. --------- */
@@ -442,7 +452,7 @@
tl_assert(isOriginalAtom(mce, data));
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
- return assignNew(mce, Ity_I8, binop(Iop_Or8, data, vbits));
+ return assignNew('V', mce, Ity_I8, binop(Iop_Or8, data, vbits));
}
static IRAtom* mkImproveAND16 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
@@ -450,7 +460,7 @@
tl_assert(isOriginalAtom(mce, data));
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
- return assignNew(mce, Ity_I16, binop(Iop_Or16, data, vbits));
+ return assignNew('V', mce, Ity_I16, binop(Iop_Or16, data, vbits));
}
static IRAtom* mkImproveAND32 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
@@ -458,7 +468,7 @@
tl_assert(isOriginalAtom(mce, data));
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
- return assignNew(mce, Ity_I32, binop(Iop_Or32, data, vbits));
+ return assignNew('V', mce, Ity_I32, binop(Iop_Or32, data, vbits));
}
static IRAtom* mkImproveAND64 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
@@ -466,7 +476,7 @@
tl_assert(isOriginalAtom(mce, data));
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
- return assignNew(mce, Ity_I64, binop(Iop_Or64, data, vbits));
+ return assignNew('V', mce, Ity_I64, binop(Iop_Or64, data, vbits));
}
static IRAtom* mkImproveANDV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
@@ -474,7 +484,7 @@
tl_assert(isOriginalAtom(mce, data));
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
- return assignNew(mce, Ity_V128, binop(Iop_OrV128, data, vbits));
+ return assignNew('V', mce, Ity_V128, binop(Iop_OrV128, data, vbits));
}
/* ImproveOR(data, vbits) = ~data OR vbits. Defined (0) data 1s give
@@ -486,9 +496,9 @@
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
return assignNew(
- mce, Ity_I8,
+ 'V', mce, Ity_I8,
binop(Iop_Or8,
- assignNew(mce, Ity_I8, unop(Iop_Not8, data)),
+ assignNew('V', mce, Ity_I8, unop(Iop_Not8, data)),
vbits) );
}
@@ -498,9 +508,9 @@
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
return assignNew(
- mce, Ity_I16,
+ 'V', mce, Ity_I16,
binop(Iop_Or16,
- assignNew(mce, Ity_I16, unop(Iop_Not16, data)),
+ assignNew('V', mce, Ity_I16, unop(Iop_Not16, data)),
vbits) );
}
@@ -510,9 +520,9 @@
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
return assignNew(
- mce, Ity_I32,
+ 'V', mce, Ity_I32,
binop(Iop_Or32,
- assignNew(mce, Ity_I32, unop(Iop_Not32, data)),
+ assignNew('V', mce, Ity_I32, unop(Iop_Not32, data)),
vbits) );
}
@@ -522,9 +532,9 @@
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
return assignNew(
- mce, Ity_I64,
+ 'V', mce, Ity_I64,
binop(Iop_Or64,
- assignNew(mce, Ity_I64, unop(Iop_Not64, data)),
+ assignNew('V', mce, Ity_I64, unop(Iop_Not64, data)),
vbits) );
}
@@ -534,9 +544,9 @@
tl_assert(isShadowAtom(mce, vbits));
tl_assert(sameKindedAtoms(data, vbits));
return assignNew(
- mce, Ity_V128,
+ 'V', mce, Ity_V128,
binop(Iop_OrV128,
- assignNew(mce, Ity_V128, unop(Iop_NotV128, data)),
+ assignNew('V', mce, Ity_V128, unop(Iop_NotV128, data)),
vbits) );
}
@@ -553,14 +563,14 @@
/* Fast-track some common cases */
if (src_ty == Ity_I32 && dst_ty == Ity_I32)
- return assignNew(mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits));
+ return assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits));
if (src_ty == Ity_I64 && dst_ty == Ity_I64)
- return assignNew(mce, Ity_I64, unop(Iop_CmpwNEZ64, vbits));
+ return assignNew('V', mce, Ity_I64, unop(Iop_CmpwNEZ64, vbits));
if (src_ty == Ity_I32 && dst_ty == Ity_I64) {
- IRAtom* tmp = assignNew(mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits));
- return assignNew(mce, Ity_I64, binop(Iop_32HLto64, tmp, tmp));
+ IRAtom* tmp = assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits));
+ return assignNew('V', mce, Ity_I64, binop(Iop_32HLto64, tmp, tmp));
}
/* Else do it the slow way .. */
@@ -570,24 +580,24 @@
tmp1 = vbits;
break;
case Ity_I8:
- tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ8, vbits));
+ tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ8, vbits));
break;
case Ity_I16:
- tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ16, vbits));
+ tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ16, vbits));
break;
case Ity_I32:
- tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ32, vbits));
+ tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ32, vbits));
break;
case Ity_I64:
- tmp1 = assignNew(mce, Ity_I1, unop(Iop_CmpNEZ64, vbits));
+ tmp1 = assignNew('V', mce, Ity_I1, unop(Iop_CmpNEZ64, vbits));
break;
case Ity_I128: {
/* Gah. Chop it in half, OR the halves together, and compare
that with zero. */
- IRAtom* tmp2 = assignNew(mce, Ity_I64, unop(Iop_128HIto64, vbits));
- IRAtom* tmp3 = assignNew(mce, Ity_I64, unop(Iop_128to64, vbits));
- IRAtom* tmp4 = assignNew(mce, Ity_I64, binop(Iop_Or64, tmp2, tmp3));
- tmp1 = assignNew(mce, Ity_I1,
+ IRAtom* tmp2 = assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, vbits));
+ IRAtom* tmp3 = assignNew('V', mce, Ity_I64, unop(Iop_128to64, vbits));
+ IRAtom* tmp4 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp2, tmp3));
+ tmp1 = assignNew('V', mce, Ity_I1,
unop(Iop_CmpNEZ64, tmp4));
break;
}
@@ -601,20 +611,20 @@
case Ity_I1:
return tmp1;
case Ity_I8:
- return assignNew(mce, Ity_I8, unop(Iop_1Sto8, tmp1));
+ return assignNew('V', mce, Ity_I8, unop(Iop_1Sto8, tmp1));
case Ity_I16:
- return assignNew(mce, Ity_I16, unop(Iop_1Sto16, tmp1));
+ return assignNew('V', mce, Ity_I16, unop(Iop_1Sto16, tmp1));
case Ity_I32:
- return assignNew(mce, Ity_I32, unop(Iop_1Sto32, tmp1));
+ return assignNew('V', mce, Ity_I32, unop(Iop_1Sto32, tmp1));
case Ity_I64:
- return assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
+ return assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1));
case Ity_V128:
- tmp1 = assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
- tmp1 = assignNew(mce, Ity_V128, binop(Iop_64HLtoV128, tmp1, tmp1));
+ tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1));
+ tmp1 = assignNew('V', mce, Ity_V128, binop(Iop_64HLtoV128, tmp1, tmp1));
return tmp1;
case Ity_I128:
- tmp1 = assignNew(mce, Ity_I64, unop(Iop_1Sto64, tmp1));
- tmp1 = assignNew(mce, Ity_I128, binop(Iop_64HLto128, tmp1, tmp1));
+ tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_1Sto64, tmp1));
+ tmp1 = assignNew('V', mce, Ity_I128, binop(Iop_64HLto128, tmp1, tmp1));
return tmp1;
default:
ppIRType(dst_ty);
@@ -705,23 +715,25 @@
}
naive
- = mkPCastTo(mce,ty, assignNew(mce, ty, binop(opUIFU, vxx, vyy)));
+ = mkPCastTo(mce,ty,
+ assignNew('V', mce, ty, binop(opUIFU, vxx, vyy)));
vec
= assignNew(
- mce,ty,
+ 'V', mce,ty,
binop( opOR,
- assignNew(mce,ty, binop(opOR, vxx, vyy)),
+ assignNew('V', mce,ty, binop(opOR, vxx, vyy)),
assignNew(
- mce,ty,
+ 'V', mce,ty,
unop( opNOT,
- assignNew(mce,ty, binop(opXOR, xx, yy))))));
+ assignNew('V', mce,ty, binop(opXOR, xx, yy))))));
improvement_term
- = mkPCastTo( mce,ty, assignNew(mce,Ity_I1, binop(opCMP, vec, top)));
+ = mkPCastTo( mce,ty,
+ assignNew('V', mce,Ity_I1, binop(opCMP, vec, top)));
improved
- = assignNew( mce,ty, binop(opDIFD, naive, improvement_term) );
+ = assignNew( 'V', mce,ty, binop(opDIFD, naive, improvement_term) );
final_cast
= mkPCastTo( mce, Ity_I1, improved );
@@ -817,18 +829,18 @@
binop(
opOR,
assignNew(
- mce,ty,
+ 'V', mce,ty,
binop(
opAND,
mkPCastTo(mce,ty, xxhash),
threeLeft1
)),
assignNew(
- mce,ty,
+ 'V', mce,ty,
binop(
opSHL,
assignNew(
- mce,ty,
+ 'V', mce,ty,
binop(opSHR, xxhash, mkU8(width-1))),
mkU8(3)
))
@@ -851,6 +863,9 @@
/*--- Emit a test and complaint if something is undefined. ---*/
/*------------------------------------------------------------*/
+static IRAtom* schemeE ( MCEnv* mce, IRExpr* e ); /* fwds */
+
+
/* Set the annotations on a dirty helper to indicate that the stack
pointer and instruction pointers might be read. This is the
behaviour of all 'emit-a-complaint' style functions we might
@@ -884,6 +899,7 @@
Int sz;
IRDirty* di;
IRAtom* cond;
+ IRAtom* origin;
// Don't do V bit tests if we're not reporting undefined value errors.
if (!MC_(clo_undef_value_errors))
@@ -906,51 +922,54 @@
cond = mkPCastTo( mce, Ity_I1, vatom );
/* cond will be 0 if all defined, and 1 if any not defined. */
+ /* Get the origin info for the value we are about to check. */
+ origin = schemeE( mce, atom );
+
switch (sz) {
case 0:
- di = unsafeIRDirty_0_N(
- 0/*regparms*/,
+ di = unsafeIRDirty_0_N(
+ 1/*regparms*/,
"MC_(helperc_value_check0_fail)",
VG_(fnptr_to_fnentry)( &MC_(helperc_value_check0_fail) ),
- mkIRExprVec_0()
+ mkIRExprVec_1(origin)
);
break;
case 1:
- di = unsafeIRDirty_0_N(
- 0/*regparms*/,
+ di = unsafeIRDirty_0_N(
+ 1/*regparms*/,
"MC_(helperc_value_check1_fail)",
VG_(fnptr_to_fnentry)( &MC_(helperc_value_check1_fail) ),
- mkIRExprVec_0()
+ mkIRExprVec_1(origin)
);
break;
case 4:
- di = unsafeIRDirty_0_N(
- 0/*regparms*/,
+ di = unsafeIRDirty_0_N(
+ 1/*regparms*/,
"MC_(helperc_value_check4_fail)",
VG_(fnptr_to_fnentry)( &MC_(helperc_value_check4_fail) ),
- mkIRExprVec_0()
+ mkIRExprVec_1(origin)
);
break;
case 8:
- di = unsafeIRDirty_0_N(
- 0/*regparms*/,
+ di = unsafeIRDirty_0_N(
+ 1/*regparms*/,
"MC_(helperc_value_check8_fail)",
VG_(fnptr_to_fnentry)( &MC_(helperc_value_check8_fail) ),
- mkIRExprVec_0()
+ mkIRExprVec_1(origin)
);
break;
default:
- di = unsafeIRDirty_0_N(
- 1/*regparms*/,
+ di = unsafeIRDirty_0_N(
+ 2/*regparms*/,
"MC_(helperc_complain_undef)",
VG_(fnptr_to_fnentry)( &MC_(helperc_complain_undef) ),
- mkIRExprVec_1( mkIRExpr_HWord( sz ))
+ mkIRExprVec_2( mkIRExpr_HWord( sz ), origin )
);
break;
}
di->guard = cond;
setHelperAnns( mce, di );
- stmt( mce->bb, IRStmt_Dirty(di));
+ stmt( 'V', mce, IRStmt_Dirty(di));
/* Set the shadow tmp to be defined. First, update the
orig->shadow tmp mapping to reflect the fact that this shadow is
@@ -959,9 +978,9 @@
/* sameKindedAtoms ... */
if (vatom->tag == Iex_RdTmp) {
tl_assert(atom->tag == Iex_RdTmp);
- newShadowTmp(mce, atom->Iex.RdTmp.tmp);
- assign(mce->bb, findShadowTmp(mce, atom->Iex.RdTmp.tmp),
- definedOfType(ty));
+ newShadowTmpV(mce, atom->Iex.RdTmp.tmp);
+ assign('V', mce, findShadowTmpV(mce, atom->Iex.RdTmp.tmp),
+ definedOfType(ty));
}
}
@@ -1035,7 +1054,7 @@
/* complainIfUndefined(mce, atom); */
} else {
/* Do a plain shadow Put. */
- stmt( mce->bb, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) );
+ stmt( 'V', mce, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) );
}
}
@@ -1062,7 +1081,7 @@
vatom = expr2vbits( mce, atom );
tl_assert(sameKindedAtoms(atom, vatom));
ty = descr->elemTy;
- tyS = shadowType(ty);
+ tyS = shadowTypeV(ty);
arrSize = descr->nElems * sizeofIRType(ty);
tl_assert(ty != Ity_I1);
tl_assert(isOriginalAtom(mce,ix));
@@ -1077,7 +1096,7 @@
IRRegArray* new_descr
= mkIRRegArray( descr->base + mce->layout->total_sizeB,
tyS, descr->nElems);
- stmt( mce->bb, IRStmt_PutI( new_descr, ix, bias, vatom ));
+ stmt( 'V', mce, IRStmt_PutI( new_descr, ix, bias, vatom ));
}
}
@@ -1088,7 +1107,7 @@
static
IRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty )
{
- IRType tyS = shadowType(ty);
+ IRType tyS = shadowTypeV(ty);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* Always defined, return all zeroes of the relevant type */
@@ -1096,6 +1115,7 @@
} else {
/* return a cloned version of the Get that refers to the shadow
area. */
+ /* FIXME: this isn't an atom! */
return IRExpr_Get( offset + mce->layout->total_sizeB, tyS );
}
}
@@ -1109,7 +1129,7 @@
IRRegArray* descr, IRAtom* ix, Int bias )
{
IRType ty = descr->elemTy;
- IRType tyS = shadowType(ty);
+ IRType tyS = shadowTypeV(ty);
Int arrSize = descr->nElems * sizeofIRType(ty);
tl_assert(ty != Ity_I1);
tl_assert(isOriginalAtom(mce,ix));
@@ -1403,31 +1423,31 @@
}
// a_min = aa & ~qaa
- a_min = assignNew(mce,ty,
+ a_min = assignNew('V', mce,ty,
binop(opAND, aa,
- assignNew(mce,ty, unop(opNOT, qaa))));
+ assignNew('V', mce,ty, unop(opNOT, qaa))));
// b_min = bb & ~qbb
- b_min = assignNew(mce,ty,
+ b_min = assignNew('V', mce,ty,
binop(opAND, bb,
- assignNew(mce,ty, unop(opNOT, qbb))));
+ assignNew('V', mce,ty, unop(opNOT, qbb))));
// a_max = aa | qaa
- a_max = assignNew(mce,ty, binop(opOR, aa, qaa));
+ a_max = assignNew('V', mce,ty, binop(opOR, aa, qaa));
// b_max = bb | qbb
- b_max = assignNew(mce,ty, binop(opOR, bb, qbb));
+ b_max = assignNew('V', mce,ty, binop(opOR, bb, qbb));
if (add) {
// result = (qaa | qbb) | ((a_min + b_min) ^ (a_max + b_max))
return
- assignNew(mce,ty,
+ assignNew('V', mce,ty,
binop( opOR,
- assignNew(mce,ty, binop(opOR, qaa, qbb)),
- assignNew(mce,ty,
+ assignNew('V', mce,ty, binop(opOR, qaa, qbb)),
+ assignNew('V', mce,ty,
binop( opXOR,
- assignNew(mce,ty, binop(opADD, a_min, b_min)),
- assignNew(mce,ty, binop(opADD, a_max, b_max))
+ assignNew('V', mce,ty, binop(opADD, a_min, b_min)),
+ assignNew('V', mce,ty, binop(opADD, a_max, b_max))
)
)
)
@@ -1435,13 +1455,13 @@
} else {
// result = (qaa | qbb) | ((a_min - b_max) ^ (a_max + b_min))
return
- assignNew(mce,ty,
+ assignNew('V', mce,ty,
binop( opOR,
- assignNew(mce,ty, binop(opOR, qaa, qbb)),
- assignNew(mce,ty,
+ assignNew('V', mce,ty, binop(opOR, qaa, qbb)),
+ assignNew('V', mce,ty,
binop( opXOR,
- assignNew(mce,ty, binop(opSUB, a_min, b_max)),
- assignNew(mce,ty, binop(opSUB, a_max, b_min))
+ assignNew('V', mce,ty, binop(opSUB, a_min, b_max)),
+ assignNew('V', mce,ty, binop(opSUB, a_max, b_min))
)
)
)
@@ -1488,9 +1508,9 @@
tl_assert(sameKindedAtoms(qbb,bb));
return
assignNew(
- mce, ty,
+ 'V', mce, ty,
mkUifU( mce, ty,
- assignNew(mce, ty, binop(original_op, qaa, bb)),
+ assignNew('V', mce, ty, binop(original_op, qaa, bb)),
mkPCastTo(mce, ty, qbb)
)
);
@@ -1505,37 +1525,37 @@
static IRAtom* mkPCast8x16 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ8x16, at));
+ return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ8x16, at));
}
static IRAtom* mkPCast16x8 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ16x8, at));
+ return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ16x8, at));
}
static IRAtom* mkPCast32x4 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ32x4, at));
+ return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ32x4, at));
}
static IRAtom* mkPCast64x2 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_V128, unop(Iop_CmpNEZ64x2, at));
+ return assignNew('V', mce, Ity_V128, unop(Iop_CmpNEZ64x2, at));
}
static IRAtom* mkPCast32x2 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ32x2, at));
+ return assignNew('V', mce, Ity_I64, unop(Iop_CmpNEZ32x2, at));
}
static IRAtom* mkPCast16x4 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ16x4, at));
+ return assignNew('V', mce, Ity_I64, unop(Iop_CmpNEZ16x4, at));
}
static IRAtom* mkPCast8x8 ( MCEnv* mce, IRAtom* at )
{
- return assignNew(mce, Ity_I64, unop(Iop_CmpNEZ8x8, at));
+ return assignNew('V', mce, Ity_I64, unop(Iop_CmpNEZ8x8, at));
}
@@ -1582,7 +1602,7 @@
tl_assert(isShadowAtom(mce, vatomX));
tl_assert(isShadowAtom(mce, vatomY));
at = mkUifUV128(mce, vatomX, vatomY);
- at = assignNew(mce, Ity_V128, mkPCast32x4(mce, at));
+ at = assignNew('V', mce, Ity_V128, mkPCast32x4(mce, at));
return at;
}
@@ -1591,7 +1611,7 @@
{
IRAtom* at;
tl_assert(isShadowAtom(mce, vatomX));
- at = assignNew(mce, Ity_V128, mkPCast32x4(mce, vatomX));
+ at = assignNew('V', mce, Ity_V128, mkPCast32x4(mce, vatomX));
return at;
}
@@ -1602,9 +1622,9 @@
tl_assert(isShadowAtom(mce, vatomX));
tl_assert(isShadowAtom(mce, vatomY));
at = mkUifUV128(mce, vatomX, vatomY);
- at = assignNew(mce, Ity_I32, unop(Iop_V128to32, at));
+ at = assignNew('V', mce, Ity_I32, unop(Iop_V128to32, at));
at = mkPCastTo(mce, Ity_I32, at);
- at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
return at;
}
@@ -1613,9 +1633,9 @@
{
IRAtom* at;
tl_assert(isShadowAtom(mce, vatomX));
- at = assignNew(mce, Ity_I32, unop(Iop_V128to32, vatomX));
+ at = assignNew('V', mce, Ity_I32, unop(Iop_V128to32, vatomX));
at = mkPCastTo(mce, Ity_I32, at);
- at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo32, vatomX, at));
return at;
}
@@ -1628,7 +1648,7 @@
tl_assert(isShadowAtom(mce, vatomX));
tl_assert(isShadowAtom(mce, vatomY));
at = mkUifUV128(mce, vatomX, vatomY);
- at = assignNew(mce, Ity_V128, mkPCast64x2(mce, at));
+ at = assignNew('V', mce, Ity_V128, mkPCast64x2(mce, at));
return at;
}
@@ -1637,7 +1657,7 @@
{
IRAtom* at;
tl_assert(isShadowAtom(mce, vatomX));
- at = assignNew(mce, Ity_V128, mkPCast64x2(mce, vatomX));
+ at = assignNew('V', mce, Ity_V128, mkPCast64x2(mce, vatomX));
return at;
}
@@ -1648,9 +1668,9 @@
tl_assert(isShadowAtom(mce, vatomX));
tl_assert(isShadowAtom(mce, vatomY));
at = mkUifUV128(mce, vatomX, vatomY);
- at = assignNew(mce, Ity_I64, unop(Iop_V128to64, at));
+ at = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, at));
at = mkPCastTo(mce, Ity_I64, at);
- at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
return at;
}
@@ -1659,9 +1679,9 @@
{
IRAtom* at;
tl_assert(isShadowAtom(mce, vatomX));
- at = assignNew(mce, Ity_I64, unop(Iop_V128to64, vatomX));
+ at = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, vatomX));
at = mkPCastTo(mce, Ity_I64, at);
- at = assignNew(mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_SetV128lo64, vatomX, at));
return at;
}
@@ -1708,9 +1728,9 @@
}
tl_assert(isShadowAtom(mce,vatom1));
tl_assert(isShadowAtom(mce,vatom2));
- at1 = assignNew(mce, Ity_V128, pcast(mce, vatom1));
- at2 = assignNew(mce, Ity_V128, pcast(mce, vatom2));
- at3 = assignNew(mce, Ity_V128, binop(narrow_op, at1, at2));
+ at1 = assignNew('V', mce, Ity_V128, pcast(mce, vatom1));
+ at2 = assignNew('V', mce, Ity_V128, pcast(mce, vatom2));
+ at3 = assignNew('V', mce, Ity_V128, binop(narrow_op, at1, at2));
return at3;
}
@@ -1728,9 +1748,9 @@
}
tl_assert(isShadowAtom(mce,vatom1));
tl_assert(isShadowAtom(mce,vatom2));
- at1 = assignNew(mce, Ity_I64, pcast(mce, vatom1));
- at2 = assignNew(mce, Ity_I64, pcast(mce, vatom2));
- at3 = assignNew(mce, Ity_I64, binop(narrow_op, at1, at2));
+ at1 = assignNew('V', mce, Ity_I64, pcast(mce, vatom1));
+ at2 = assignNew('V', mce, Ity_I64, pcast(mce, vatom2));
+ at3 = assignNew('V', mce, Ity_I64, binop(narrow_op, at1, at2));
return at3;
}
@@ -1927,7 +1947,7 @@
case Iop_ShlN8x8:
/* Same scheme as with all other shifts. */
complainIfUndefined(mce, atom2);
- return assignNew(mce, Ity_I64, binop(op, vatom1, atom2));
+ return assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2));
case Iop_QNarrow32Sx2:
case Iop_QNarrow16Sx4:
@@ -1979,7 +1999,7 @@
case Iop_InterleaveHI8x8:
case Iop_CatOddLanes16x4:
case Iop_CatEvenLanes16x4:
- return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2));
+ return assignNew('V', mce, Ity_I64, binop(op, vatom1, vatom2));
/* Perm8x8: rearrange values in left arg using steering values
from right arg. So rearrange the vbits in the same way but
@@ -1987,7 +2007,7 @@
case Iop_Perm8x8:
return mkUifU64(
mce,
- assignNew(mce, Ity_I64, binop(op, vatom1, atom2)),
+ assignNew('V', mce, Ity_I64, binop(op, vatom1, atom2)),
mkPCast8x8(mce, vatom2)
);
@@ -2007,7 +2027,7 @@
this is wrong now, scalar shifts are done properly lazily.
Vector shifts should be fixed too. */
complainIfUndefined(mce, atom2);
- return assignNew(mce, Ity_V128, binop(op, vatom1, atom2));
+ return assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2));
/* V x V shifts/rotates are done using the standard lazy scheme. */
case Iop_Shl8x16:
@@ -2015,7 +2035,7 @@
case Iop_Sar8x16:
case Iop_Rol8x16:
return mkUifUV128(mce,
- assignNew(mce, Ity_V128, binop(op, vatom1, atom2)),
+ assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)),
mkPCast8x16(mce,vatom2)
);
@@ -2024,7 +2044,7 @@
case Iop_Sar16x8:
case Iop_Rol16x8:
return mkUifUV128(mce,
- assignNew(mce, Ity_V128, binop(op, vatom1, atom2)),
+ assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)),
mkPCast16x8(mce,vatom2)
);
@@ -2033,7 +2053,7 @@
case Iop_Sar32x4:
case Iop_Rol32x4:
return mkUifUV128(mce,
- assignNew(mce, Ity_V128, binop(op, vatom1, atom2)),
+ assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)),
mkPCast32x4(mce,vatom2)
);
@@ -2163,7 +2183,7 @@
case Iop_InterleaveHI32x4:
case Iop_InterleaveHI16x8:
case Iop_InterleaveHI8x16:
- return assignNew(mce, Ity_V128, binop(op, vatom1, vatom2));
+ return assignNew('V', mce, Ity_V128, binop(op, vatom1, vatom2));
/* Perm8x16: rearrange values in left arg using steering values
from right arg. So rearrange the vbits in the same way but
@@ -2171,7 +2191,7 @@
case Iop_Perm8x16:
return mkUifUV128(
mce,
- assignNew(mce, Ity_V128, binop(op, vatom1, atom2)),
+ assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2)),
mkPCast8x16(mce, vatom2)
);
@@ -2186,8 +2206,8 @@
case Iop_MullEven16Sx8: {
IRAtom* at;
at = binary16Ix8(mce,vatom1,vatom2);
- at = assignNew(mce, Ity_V128, binop(Iop_ShlN32x4, at, mkU8(16)));
- at = assignNew(mce, Ity_V128, binop(Iop_SarN32x4, at, mkU8(16)));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_ShlN32x4, at, mkU8(16)));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_SarN32x4, at, mkU8(16)));
return at;
}
@@ -2196,8 +2216,8 @@
case Iop_MullEven8Sx16: {
IRAtom* at;
at = binary8Ix16(mce,vatom1,vatom2);
- at = assignNew(mce, Ity_V128, binop(Iop_ShlN16x8, at, mkU8(8)));
- at = assignNew(mce, Ity_V128, binop(Iop_SarN16x8, at, mkU8(8)));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_ShlN16x8, at, mkU8(8)));
+ at = assignNew('V', mce, Ity_V128, binop(Iop_SarN16x8, at, mkU8(8)));
return at;
}
@@ -2207,8 +2227,8 @@
than a data steering operation. */
case Iop_Narrow32x4:
case Iop_Narrow16x8:
- return assignNew(mce, Ity_V128,
- binop(op, vatom1, vatom2));
+ return assignNew('V', mce, Ity_V128,
+ binop(op, vatom1, vatom2));
case Iop_ShrV128:
case Iop_ShlV128:
@@ -2216,12 +2236,12 @@
this is wrong now, scalar shifts are done properly lazily.
Vector shifts should be fixed too. */
complainIfUndefined(mce, atom2);
- return assignNew(mce, Ity_V128, binop(op, vatom1, atom2));
+ return assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2));
/* I128-bit data-steering */
case Iop_64HLto128:
- return assignNew(mce, Ity_I128, binop(op, vatom1, vatom2));
+ return assignNew('V', mce, Ity_I128, binop(op, vatom1, vatom2));
/* Scalar floating point */
@@ -2260,36 +2280,36 @@
return mkLazy2(mce, Ity_I128, vatom1, vatom2);
case Iop_16HLto32:
- return assignNew(mce, Ity_I32, binop(op, vatom1, vatom2));
+ return assignNew('V', mce, Ity_I32, binop(op, vatom1, vatom2));
case Iop_32HLto64:
- return assignNew(mce, Ity_I64, binop(op, vatom1, vatom2));
+ return assignNew('V', mce, Ity_I64, binop(op, vatom1, vatom2));
case Iop_MullS64:
case Iop_MullU64: {
IRAtom* vLo64 = mkLeft64(mce, mkUifU64(mce, vatom1,vatom2));
IRAtom* vHi64 = mkPCastTo(mce, Ity_I64, vLo64);
- return assignNew(mce, Ity_I128, binop(Iop_64HLto128, vHi64, vLo64));
+ return assignNew('V', mce, Ity_I128, binop(Iop_64HLto128, vHi64, vLo64));
}
case Iop_MullS32:
case Iop_MullU32: {
IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2));
IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32);
- return assignNew(mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32));
+ return assignNew('V', mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32));
}
case Iop_MullS16:
case Iop_MullU16: {
IRAtom* vLo16 = mkLeft16(mce, mkUifU16(mce, vatom1,vatom2));
IRAtom* vHi16 = mkPCastTo(mce, Ity_I16, vLo16);
- return assignNew(mce, Ity_I32, binop(Iop_16HLto32, vHi16, vLo16));
+ return assignNew('V', mce, Ity_I32, binop(Iop_16HLto32, vHi16, vLo16));
}
case Iop_MullS8:
case Iop_MullU8: {
IRAtom* vLo8 = mkLeft8(mce, mkUifU8(mce, vatom1,vatom2));
IRAtom* vHi8 = mkPCastTo(mce, Ity_I8, vLo8);
- return assignNew(mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8));
+ return assignNew('V', mce, Ity_I16, binop(Iop_8HLto16, vHi8, vLo8));
}
case Iop_DivS32:
@@ -2424,7 +2444,7 @@
do_And_Or:
return
assignNew(
- mce,
+ 'V', mce,
and_or_ty,
difd(mce, uifu(mce, vatom1, vatom2),
difd(mce, improve(mce, atom1, vatom1),
@@ -2484,7 +2504,7 @@
case Iop_Dup8x16:
case Iop_Dup16x8:
case Iop_Dup32x4:
- return assignNew(mce, Ity_V128, unop(op, vatom));
+ return assignNew('V', mce, Ity_V128, unop(op, vatom));
case Iop_F32toF64:
case Iop_I32toF64:
@@ -2511,7 +2531,7 @@
case Iop_V128HIto64:
case Iop_128HIto64:
case Iop_128to64:
- return assignNew(mce, Ity_I64, unop(op, vatom));
+ return assignNew('V', mce, Ity_I64, unop(op, vatom));
case Iop_64to32:
case Iop_64HIto32:
@@ -2522,27 +2542,27 @@
case Iop_16Sto32:
case Iop_8Sto32:
case Iop_V128to32:
- return assignNew(mce, Ity_I32, unop(op, vatom));
+ return assignNew('V', mce, Ity_I32, unop(op, vatom));
case Iop_8Sto16:
case Iop_8Uto16:
case Iop_32to16:
case Iop_32HIto16:
case Iop_64to16:
- return assignNew(mce, Ity_I16, unop(op, vatom));
+ return assignNew('V', mce, Ity_I16, unop(op, vatom));
case Iop_1Uto8:
case Iop_16to8:
case Iop_16HIto8:
case Iop_32to8:
case Iop_64to8:
- return assignNew(mce, Ity_I8, unop(op, vatom));
+ return assignNew('V', mce, Ity_I8, unop(op, vatom));
case Iop_32to1:
- return assignNew(mce, Ity_I1, unop(Iop_32to1, vatom));
+ return assignNew('V', mce, Ity_I1, unop(Iop_32to1, vatom));
case Iop_64to1:
- return assignNew(mce, Ity_I1, unop(Iop_64to1, vatom));
+ return assignNew('V', mce, Ity_I1, unop(Iop_64to1, vatom));
case Iop_ReinterpF64asI64:
case Iop_ReinterpI64asF64:
@@ -2583,7 +2603,7 @@
/* Now cook up a call to the relevant helper function, to read the
data V bits from shadow memory. */
- ty = shadowType(ty);
+ ty = shadowTypeV(ty);
if (end == Iend_LE) {
switch (ty) {
@@ -2631,7 +2651,7 @@
tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
- addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) );
+ addrAct = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBias) );
}
/* We need to have a place to park the V bits we're just about to
@@ -2642,7 +2662,7 @@
hname, VG_(fnptr_to_fnentry)( helper ),
mkIRExprVec_1( addrAct ));
setHelperAnns( mce, di );
- stmt( mce->bb, IRStmt_Dirty(di) );
+ stmt( 'V', mce, IRStmt_Dirty(di) );
return mkexpr(datavbits);
}
@@ -2655,7 +2675,7 @@
{
IRAtom *v64hi, *v64lo;
tl_assert(end == Iend_LE || end == Iend_BE);
- switch (shadowType(ty)) {
+ switch (shadowTypeV(ty)) {
case Ity_I8:
case Ity_I16:
case Ity_I32:
@@ -2669,7 +2689,7 @@
v64hi = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias);
v64lo = expr2vbits_Load_WRK(mce, end, Ity_I64, addr, bias+8);
}
- return assignNew( mce,
+ return assignNew( 'V', mce,
Ity_V128,
binop(Iop_64HLtoV128, v64hi, v64lo));
default:
@@ -2699,7 +2719,8 @@
ty = typeOfIRExpr(mce->bb->tyenv, vbits0);
return
- mkUifU(mce, ty, assignNew(mce, ty, IRExpr_Mux0X(cond, vbits0, vbitsX)),
+ mkUifU(mce, ty, assignNew('V', mce, ty,
+ IRExpr_Mux0X(cond, vbits0, vbitsX)),
mkPCastTo(mce, ty, vbitsC) );
}
@@ -2718,10 +2739,10 @@
e->Iex.GetI.ix, e->Iex.GetI.bias );
case Iex_RdTmp:
- return IRExpr_RdTmp( findShadowTmp(mce, e->Iex.RdTmp.tmp) );
+ return IRExpr_RdTmp( findShadowTmpV(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e)));
+ return definedOfType(shadowTypeV(typeOfIRExpr(mce->bb->tyenv, e)));
case Iex_Qop:
return expr2vbits_Qop(
@@ -2789,20 +2810,28 @@
if (tyH == Ity_I32) {
switch (ty) {
- case Ity_I32: return vatom;
- case Ity_I16: return assignNew(mce, tyH, unop(Iop_16Uto32, vatom));
- case Ity_I8: return assignNew(mce, tyH, unop(Iop_8Uto32, vatom));
- default: goto unhandled;
+ case Ity_I32:
+ return vatom;
+ case Ity_I16:
+ return assignNew('V', mce, tyH, unop(Iop_16Uto32, vatom));
+ case Ity_I8:
+ return assignNew('V', mce, tyH, unop(Iop_8Uto32, vatom));
+ default:
+ goto unhandled;
}
} else
if (tyH == Ity_I64) {
switch (ty) {
- case Ity_I32: return assignNew(mce, tyH, unop(Iop_32Uto64, vatom));
- case Ity_I16: return assignNew(mce, tyH, unop(Iop_32Uto64,
- assignNew(mce, Ity_I32, unop(Iop_16Uto32, vatom))));
- case Ity_I8: return assignNew(mce, tyH, unop(Iop_32Uto64,
- assignNew(mce, Ity_I32, unop(Iop_8Uto32, vatom))));
- default: goto unhandled;
+ case Ity_I32:
+ return assignNew('V', mce, tyH, unop(Iop_32Uto64, vatom));
+ case Ity_I16:
+ return assignNew('V', mce, tyH, unop(Iop_32Uto64,
+ assignNew('V', mce, Ity_I32, unop(Iop_16Uto32, vatom))));
+ case Ity_I8:
+ return assignNew('V', mce, tyH, unop(Iop_32Uto64,
+ assignNew('V', mce, Ity_I32, unop(Iop_8Uto32, vatom))));
+ default:
+ goto unhandled;
}
} else {
goto unhandled;
@@ -2930,16 +2959,16 @@
}
eBiasLo64 = tyAddr==Ity_I32 ? mkU32(bias+offLo64) : mkU64(bias+offLo64);
- addrLo64 = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasLo64) );
- vdataLo64 = assignNew(mce, Ity_I64, unop(Iop_V128to64, vdata));
+ addrLo64 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasLo64) );
+ vdataLo64 = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, vdata));
diLo64 = unsafeIRDirty_0_N(
1/*regparms*/,
hname, VG_(fnptr_to_fnentry)( helper ),
mkIRExprVec_2( addrLo64, vdataLo64 )
);
eBiasHi64 = tyAddr==Ity_I32 ? mkU32(bias+offHi64) : mkU64(bias+offHi64);
- addrHi64 = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasHi64) );
- vdataHi64 = assignNew(mce, Ity_I64, unop(Iop_V128HIto64, vdata));
+ addrHi64 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasHi64) );
+ vdataHi64 = assignNew('V', mce, Ity_I64, unop(Iop_V128HIto64, vdata));
diHi64 = unsafeIRDirty_0_N(
1/*regparms*/,
hname, VG_(fnptr_to_fnentry)( helper ),
@@ -2947,8 +2976,8 @@
);
setHelperAnns( mce, diLo64 );
setHelperAnns( mce, diHi64 );
- stmt( mce->bb, IRStmt_Dirty(diLo64) );
- stmt( mce->bb, IRStmt_Dirty(diHi64) );
+ stmt( 'V', mce, IRStmt_Dirty(diLo64) );
+ stmt( 'V', mce, IRStmt_Dirty(diHi64) );
} else {
@@ -2958,7 +2987,7 @@
addrAct = addr;
} else {
eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
- addrAct = assignNew(mce, tyAddr, binop(mkAdd, addr, eBias) );
+ addrAct = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBias));
}
if (ty == Ity_I64) {
@@ -2979,7 +3008,7 @@
);
}
setHelperAnns( mce, di );
- stmt( mce->bb, IRStmt_Dirty(di) );
+ stmt( 'V', mce, IRStmt_Dirty(di) );
}
}
@@ -3060,8 +3089,8 @@
/* update 'curr' with UifU of the state slice
gOff .. gOff+n-1 */
tySrc = szToITy( n );
- src = assignNew( mce, tySrc,
- shadow_GET(mce, gOff, tySrc ) );
+ src = assignNew( 'V', mce, tySrc,
+ shadow_GET(mce, gOff, tySrc ) );
here = mkPCastTo( mce, Ity_I32, src );
curr = mkUifU32(mce, here, curr);
gSz -= n;
@@ -3123,9 +3152,9 @@
/* Outputs: the destination temporary, if there is one. */
if (d->tmp != IRTemp_INVALID) {
- dst = findShadowTmp(mce, d->tmp);
+ dst = findShadowTmpV(mce, d->tmp);
tyDst = typeOfIRTemp(mce->bb->tyenv, d->tmp);
- assign( mce->bb, dst, mkPCastTo( mce, tyDst, curr) );
+ assign( 'V', mce, dst, mkPCastTo( mce, tyDst, curr) );
}
/* Outputs: guest state that we write or modify. */
@@ -3197,7 +3226,7 @@
VG_(fnptr_to_fnentry)( &MC_(helperc_MAKE_STACK_UNINIT) ),
mkIRExprVec_2( base, mkIRExpr_HWord( (UInt)len) )
);
- stmt( mce->bb, IRStmt_Dirty(di) );
+ stmt( 'V', mce, IRStmt_Dirty(di) );
}
@@ -3205,6 +3234,8 @@
/*--- Memcheck main ---*/
/*------------------------------------------------------------*/
+static void schemeS ( MCEnv* mce, IRStmt* st );
+
static Bool isBogusAtom ( IRAtom* at )
{
ULong n = 0;
@@ -3320,7 +3351,7 @@
VexGuestExtents* vge,
IRType gWordTy, IRType hWordTy )
{
- Bool verboze = False; //True;
+ Bool verboze = 0||False;
Bool bogus;
Int i, j, first_stmt;
IRStmt* st;
@@ -3346,13 +3377,17 @@
/* Set up the running environment. Only .bb is modified as we go
along. */
mce.bb = bb;
+ mce.trace = verboze;
mce.layout = layout;
mce.n_originalTmps = bb->tyenv->types_used;
mce.hWordTy = hWordTy;
mce.bogusLiterals = False;
- mce.tmpMap = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp));
- for (i = 0; i < mce.n_originalTmps; i++)
- mce.tmpMap[i] = IRTemp_INVALID;
+ mce.tmpMapV = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp));
+ mce.tmpMapB = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp));
+ for (i = 0; i < mce.n_originalTmps; i++) {
+ mce.tmpMapV[i] = IRTemp_INVALID;
+ mce.tmpMapB[i] = IRTemp_INVALID;
+ }
/* Make a preliminary inspection of the statements, to see if there
are any dodgy-looking literals. If there are, we generate
@@ -3392,7 +3427,7 @@
tl_assert(st);
tl_assert(isFlatIRStmt(st));
- addStmtToIRSB( bb, bb_in->stmts[i] );
+ stmt( 'C', &mce, bb_in->stmts[i] );
i++;
}
@@ -3416,12 +3451,12 @@
*/
for (j = 0; j < i; j++) {
if (bb_in->stmts[j]->tag == Ist_WrTmp) {
- /* findShadowTmp checks its arg is an original tmp;
+ /* findShadowTmpV checks its arg is an original tmp;
no need to assert that here. */
IRTemp tmp_o = bb_in->stmts[j]->Ist.WrTmp.tmp;
- IRTemp tmp_s = findShadowTmp(&mce, tmp_o);
+ IRTemp tmp_s = findShadowTmpV(&mce, tmp_o);
IRType ty_s = typeOfIRTemp(bb->tyenv, tmp_s);
- assign( bb, tmp_s, definedOfType( ty_s ) );
+ assign( 'V', &mce, tmp_s, definedOfType( ty_s ) );
if (0) {
VG_(printf)("create shadow tmp for preamble tmp [%d] ty ", j);
ppIRType( ty_s );
@@ -3443,17 +3478,20 @@
first_stmt = bb->stmts_used;
if (verboze) {
+ VG_(printf)("\n");
ppIRStmt(st);
- VG_(printf)("\n\n");
+ VG_(printf)("\n");
}
+ schemeS( &mce, st );
+
/* Generate instrumentation code for each stmt ... */
switch (st->tag) {
case Ist_WrTmp:
- assign( bb, findShadowTmp(&mce, st->Ist.WrTmp.tmp),
- expr2vbits( &mce, st->Ist.WrTmp.data) );
+ assign( 'V', &mce, findShadowTmpV(&mce, st->Ist.WrTmp.tmp),
+ expr2vbits( &mce, st->Ist.WrTmp.data) );
break;
case Ist_Put:
@@ -3503,7 +3541,7 @@
} /* switch (st->tag) */
- if (verboze) {
+ if (0 && verboze) {
for (j = first_stmt; j < bb->stmts_used; j++) {
VG_(printf)(" ");
ppIRStmt(bb->stmts[j]);
@@ -3513,7 +3551,7 @@
}
/* ... and finally copy the stmt itself to the output. */
- addStmtToIRSB(bb, st);
+ stmt('C', &mce, st);
}
@@ -3528,7 +3566,7 @@
complainIfUndefined( &mce, bb->next );
- if (verboze) {
+ if (0 && verboze) {
for (j = first_stmt; j < bb->stmts_used; j++) {
VG_(printf)(" ");
ppIRStmt(bb->stmts[j]);
@@ -3683,6 +3721,600 @@
}
+/*------------------------------------------------------------*/
+/*--- Origin tracking stuff ---*/
+/*------------------------------------------------------------*/
+
+static IRTemp findShadowTmpB ( MCEnv* mce, IRTemp orig )
+{
+ tl_assert(orig < mce->n_originalTmps);
+ if (mce->tmpMapB[orig] == IRTemp_INVALID) {
+ mce->tmpMapB[orig]
+ = newIRTemp(mce->bb->tyenv, Ity_I32);
+ }
+ return mce->tmpMapB[orig];
+}
+
+#include "libvex_guest_x86.h"
+
+static IRType get_reg_array_equiv_int_type ( IRRegArray* arr )
+{
+#if defined(VGA_x86)
+ /* Ignore the FP tag array - pointless to shadow, and in any case
+ the elements are too small */
+ if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
+ && arr->elemTy == Ity_I8 && arr->nElems == 8)
+ return Ity_INVALID;
+
+ /* The FP register array */
+ if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
+ && arr->elemTy == Ity_F64 && arr->nElems == 8)
+ return Ity_I64;
+
+ VG_(printf)("get_reg_array_equiv_int_type: unhandled: ");
+ ppIRRegArray(arr);
+ VG_(printf)("\n");
+ tl_assert(0);
+#else
+ tl_assert(0);
+#endif
+}
+
+static Int get_shadow_offset ( Int offset, Int szB )
+{
+#if defined(VGA_x86)
+ Bool do_adcb_h_hack = True;
+ Bool is124 = szB == 1 || szB == 2 || szB == 4;
+ if (offset == offsetof(VexGuestX86State,guest_EAX) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_ECX) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_EDX) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_EBX) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_ESP) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_EBP) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_ESI) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_EDI) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_CC_OP) && is124)
+ return -1; /* CC_OP is always defined */
+ if (offset == offsetof(VexGuestX86State,guest_CC_DEP1) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_CC_DEP2) && is124)
+ return offset;
+ if (offset == offsetof(VexGuestX86State,guest_CC_NDEP) && is124)
+ return -1; /* CC_NDEP is always defined -- this slot is used for %AH */
+ if (offset == offsetof(VexGuestX86State,guest_DFLAG) && is124)
+ return -1; /* DFLAG is always defined -- this slot is used for %CH */
+ if (offset == offsetof(VexGuestX86State,guest_EIP) && is124)
+ return -1; /* EIP is always defined -- this slot is used for %DH */
+ if (offset == offsetof(VexGuestX86State,guest_IDFLAG) && is124)
+ return -1; /* IDFLAG is always defined -- this slot is used for %BH */
+ if (offset == offsetof(VexGuestX86State,guest_ACFLAG) && is124)
+ return -1; /* ACFLAG is always defined */
+
+ // Treat %ah, %ch, %dh, %bh as independent registers. To do this
+ // requires finding 4 unused 32-bit slots in the second-shadow
+ // guest state. How about: CC_OP DFLAG IDFLAG ACFLAG since none of
+ // those are tracked.
+ tl_assert(sizeof( ((VexGuestX86State*)0)->guest_CC_OP ) == 4);
+ tl_assert(sizeof( ((VexGuestX86State*)0)->guest_DFLAG ) == 4);
+ tl_assert(sizeof( ((VexGuestX86State*)0)->guest_IDFLAG ) == 4);
+ tl_assert(sizeof( ((VexGuestX86State*)0)->guest_ACFLAG ) == 4);
+ if (offset == 1+ offsetof(VexGuestX86State,guest_EAX) && szB==1) {
+ if (do_adcb_h_hack)
+ return offsetof(VexGuestX86State,guest_CC_OP);
+ VG_(printf)("Approx: get_shadow_offset: %%AH\n");
+ return -1;
+ }
+ if (offset == 1+ offsetof(VexGuestX86State,guest_ECX) && szB==1) {
+ if (do_adcb_h_hack)
+ return offsetof(VexGuestX86State,guest_DFLAG);
+ VG_(printf)("Approx: get_shadow_offset: %%CH\n");
+ return -1;
+ }
+ if (offset == 1+ offsetof(VexGuestX86State,guest_EDX) && szB==1) {
+ if (do_adcb_h_hack)
+ return offsetof(VexGuestX86State,guest_IDFLAG);
+ VG_(printf)("Approx: get_shadow_offset: %%DH\n");
+ return -1;
+ }
+ if (offset == 1+ offsetof(VexGuestX86State,guest_EBX) && szB==1) {
+ if (do_adcb_h_hack)
+ return offsetof(VexGuestX86State,guest_ACFLAG);
+ VG_(printf)("Approx: get_shadow_offset: %%BH\n");
+ return -1;
+ }
+
+ // skip %gs and other segment related stuff
+ if (offset == offsetof(VexGuestX86State,guest_GS) && szB==2)
+ return -1;
+ if (offset == offsetof(VexGuestX86State,guest_LDT) && szB==4)
+ return -1;
+ if (offset == offsetof(VexGuestX86State,guest_GDT) && szB==4)
+ return -1;
+
+ // skip FP admin stuff
+ if (offset == offsetof(VexGuestX86State,guest_FTOP) && szB==4)
+ return -1;
+ if (offset == offsetof(VexGuestX86State,guest_FC3210) && szB==4)
+ return -1;
+ if (offset == offsetof(VexGuestX86State,guest_FPROUND) && szB==4)
+ return -1;
+ if (offset == offsetof(VexGuestX86State,guest_EMWARN) && szB==4)
+ return -1;
+
+ // skip MMX accesses to FP regs
+ if (offset >= offsetof(VexGuestX86State,guest_FPREG[0])
+ && offset <= offsetof(VexGuestX86State,guest_FPREG[7])
+ && szB==8)
+ return -1;
+
+ // ignore SSE for now
+ if (offset == offsetof(VexGuestX86State,guest_SSEROUND) && szB==4)
+ return -1;
+
+ VG_(printf)("get_shadow_offset(off=%d,sz=%d)\n", offset,szB);
+ tl_assert(0);
+#else
+ tl_assert(0);
+#endif
+}
+
+static IRAtom* gen_maxU32 ( MCEnv* mce, IRAtom* b1, IRAtom* b2 )
+{
+#if 0
+ IRAtom* b3 = assignNew( 'B', mce, Ity_I1, binop(Iop_CmpLT32U, b1, b2));
+ IRAtom* b4 = assignNew( 'B', mce, Ity_I8, unop(Iop_1Uto8, b3));
+ return assignNew( 'B', mce, Ity_I32, IRExpr_Mux0X(b4,b1,b2));
+#else
+ return assignNew( 'B', mce, Ity_I32, binop(Iop_Max32U, b1, b2) );
+#endif
+}
+static IRAtom* gen_load_b ( MCEnv* mce, Int szB,
+ IRAtom* baseaddr, Int offset )
+{
+ void* hFun;
+ HChar* hName;
+ IRTemp bTmp;
+ IRType aTy = typeOfIRExpr( mce->bb->tyenv, baseaddr );
+ IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
+ IRAtom* ea = baseaddr;
+ if (offset != 0) {
+ IRAtom* off = aTy == Ity_I32 ? mkU32( offset )
+ : mkU64( (Long)(Int)offset );
+ ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off));
+ }
+ bTmp = newIRTemp(mce->bb->tyenv, mce->hWordTy);
+
+ switch (szB) {
+ case 1: hFun = (void*)&MC_(helperc_b_load1);
+ hName = "MC_(helperc_b_load1)";
+ break;
+ case 2: hFun = (void*)&MC_(helperc_b_load2);
+ hName = "MC_(helperc_b_load2)";
+ break;
+ case 4: hFun = (void*)&MC_(helperc_b_load4);
+ hName = "MC_(helperc_b_load4)";
+ break;
+ case 8: hFun = (void*)&MC_(helperc_b_load8);
+ hName = "MC_(helperc_b_load8)";
+ break;
+ default:
+ tl_assert(0);
+ }
+ IRDirty* di
+ = unsafeIRDirty_1_N(
+ bTmp, 1/*regparms*/, hName, VG_(fnptr_to_fnentry)( hFun ),
+ mkIRExprVec_1( ea )
+ );
+ /* no need to mess with any annotations. This call accesses
+ neither guest state nor guest memory. */
+ stmt( 'B', mce, IRStmt_Dirty(di) );
+ if (mce->hWordTy == Ity_I64) {
+ assign( 'B', mce, bTmp, unop(Iop_64to32, mkexpr(bTmp)) );
+ }
+ return mkexpr(bTmp);
+}
+static void gen_store_b ( MCEnv* mce, Int szB,
+ IRAtom* baseaddr, Int offset, IRAtom* dataB )
+{
+ void* hFun;
+ HChar* hName;
+ IRType aTy = typeOfIRExpr( mce->bb->tyenv, baseaddr );
+ IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
+ IRAtom* ea = baseaddr;
+ if (offset != 0) {
+ IRAtom* off = aTy == Ity_I32 ? mkU32( offset )
+ : mkU64( (Long)(Int)offset );
+ ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off));
+ }
+ if (mce->hWordTy == Ity_I64)
+ dataB = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, dataB));
+
+ switch (szB) {
+ case 1: hFun = (void*)&MC_(helperc_b_store1);
+ hName = "MC_(helperc_b_store1)";
+ break;
+ case 2: hFun = (void*)&MC_(helperc_b_store2);
+ hName = "MC_(helperc_b_store2)";
+ break;
+ case 4: hFun = (void*)&MC_(helperc_b_store4);
+ hName = "MC_(helperc_b_store4)";
+ break;
+ case 8: hFun = (void*)&MC_(helperc_b_store8);
+ hName = "MC_(helperc_b_store8)";
+ break;
+ default:
+ tl_assert(0);
+ }
+ IRDirty* di
+ = unsafeIRDirty_0_N( 2/*regparms*/,
+ hName, VG_(fnptr_to...
[truncated message content] |
|
From: <sv...@va...> - 2008-03-29 14:12:42
|
Author: sewardj
Date: 2008-03-29 14:12:37 +0000 (Sat, 29 Mar 2008)
New Revision: 7810
Log:
Add the usual trappings of shadow memory:
* a fixed-size origin-tag cache (in lieu of full-scale shadow memory)
* helper functions called from generated code to read/write origin
shadow mem
* add functions to deal with address range setting on origin shadow
mem
Fix up error handling a bit, so as to show origins
Modified:
branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_include.h
branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_main.c
Modified: branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_include.h
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_include.h 2008-03-29 14:08:12 UTC (rev 7809)
+++ branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_include.h 2008-03-29 14:12:37 UTC (rev 7810)
@@ -297,11 +297,11 @@
/*------------------------------------------------------------*/
/* Functions defined in mc_main.c */
-extern VG_REGPARM(1) void MC_(helperc_complain_undef) ( HWord );
-extern void MC_(helperc_value_check8_fail) ( void );
-extern void MC_(helperc_value_check4_fail) ( void );
-extern void MC_(helperc_value_check1_fail) ( void );
-extern void MC_(helperc_value_check0_fail) ( void );
+extern VG_REGPARM(2) void MC_(helperc_complain_undef) ( HWord, UWord );
+extern VG_REGPARM(1) void MC_(helperc_value_check8_fail) ( UWord );
+extern VG_REGPARM(1) void MC_(helperc_value_check4_fail) ( UWord );
+extern VG_REGPARM(1) void MC_(helperc_value_check1_fail) ( UWord );
+extern VG_REGPARM(1) void MC_(helperc_value_check0_fail) ( UWord );
extern VG_REGPARM(1) void MC_(helperc_STOREV64be) ( Addr, ULong );
extern VG_REGPARM(1) void MC_(helperc_STOREV64le) ( Addr, ULong );
@@ -321,6 +321,15 @@
extern void MC_(helperc_MAKE_STACK_UNINIT) ( Addr base, UWord len );
+VG_REGPARM(2) void MC_(helperc_b_store1)( Addr a, UWord d32 );
+VG_REGPARM(2) void MC_(helperc_b_store2)( Addr a, UWord d32 );
+VG_REGPARM(2) void MC_(helperc_b_store4)( Addr a, UWord d32 );
+VG_REGPARM(2) void MC_(helperc_b_store8)( Addr a, UWord d32 );
+VG_REGPARM(1) UWord MC_(helperc_b_load1)( Addr a );
+VG_REGPARM(1) UWord MC_(helperc_b_load2)( Addr a );
+VG_REGPARM(1) UWord MC_(helperc_b_load4)( Addr a );
+VG_REGPARM(1) UWord MC_(helperc_b_load8)( Addr a );
+
/* Functions defined in mc_translate.c */
extern
IRSB* MC_(instrument) ( VgCallbackClosure* closure,
Modified: branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_main.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_main.c 2008-03-29 14:08:12 UTC (rev 7809)
+++ branches/OTRACK_BY_INSTRUMENTATION/memcheck/mc_main.c 2008-03-29 14:12:37 UTC (rev 7810)
@@ -55,7 +55,10 @@
#define DEBUG(fmt, args...) //VG_(printf)(fmt, ## args)
+static void ocache_sarp_Set_Origins ( Addr, UWord ); /* fwds */
+static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */
+
/*------------------------------------------------------------*/
/*--- Fast-case knobs ---*/
/*------------------------------------------------------------*/
@@ -1554,6 +1557,7 @@
PROF_EVENT(40, "MC_(make_mem_noaccess)");
DEBUG("MC_(make_mem_noaccess)(%p, %lu)\n", a, len);
set_address_range_perms ( a, len, VA_BITS16_NOACCESS, SM_DIST_NOACCESS );
+ ocache_sarp_Clear_Origins ( a, len );
}
void MC_(make_mem_undefined) ( Addr a, SizeT len )
@@ -1561,6 +1565,7 @@
PROF_EVENT(41, "MC_(make_mem_undefined)");
DEBUG("MC_(make_mem_undefined)(%p, %lu)\n", a, len);
set_address_range_perms ( a, len, VA_BITS16_UNDEFINED, SM_DIST_UNDEFINED );
+ ocache_sarp_Set_Origins ( a, len );
}
void MC_(make_mem_defined) ( Addr a, SizeT len )
@@ -1568,6 +1573,7 @@
PROF_EVENT(42, "MC_(make_mem_defined)");
DEBUG("MC_(make_mem_defined)(%p, %lu)\n", a, len);
set_address_range_perms ( a, len, VA_BITS16_DEFINED, SM_DIST_DEFINED );
+ ocache_sarp_Clear_Origins ( a, len );
}
/* For each byte in [a,a+len), if the byte is addressable, make it be
@@ -1672,6 +1678,147 @@
}
+/*------------------------------------------------------------*/
+/*--- Origin tracking stuff - cache basics ---*/
+/*------------------------------------------------------------*/
+
+static UWord stats__ocacheline_find = 0;
+static UWord stats__ocacheline_found_at_1 = 0;
+static UWord stats__ocacheline_found_at_N = 0;
+static UWord stats__ocacheline_misses = 0;
+
+
+/* Cache of 32-bit values, one every 32 bits of address space */
+
+#define OC_W32S_PER_LINE 4
+#define OC_LINES_PER_SET 2
+//#define OC_N_SETS (1<<18)
+#define OC_N_SETS (1<<19)
+//#define OC_N_SETS (1<<20)
+//#define OC_N_SETS (1<<22)
+
+typedef
+ struct {
+ Addr tag;
+ UInt w32[OC_W32S_PER_LINE];
+ UChar descr[OC_W32S_PER_LINE];
+ }
+ OCacheLine;
+
+#if 0
+static Bool isZeroLine ( OCacheLine* line ) {
+ UWord i;
+ for (i = 0; i < OC_W32S_PER_LINE; i++) {
+ if (line->w32[i] != 0)
+ return False;
+ }
+ return True;
+}
+#endif
+
+typedef
+ struct {
+ OCacheLine line[OC_LINES_PER_SET];
+ }
+ OCacheSet;
+
+typedef
+ struct {
+ OCacheSet set[OC_N_SETS];
+ }
+ OCache;
+
+static OCache ocache;
+static UWord ocache_event_ctr = 0;
+#define OC_MOVE_FORWARDS_EVERY 1024
+
+static void init_OCache ( void ) {
+ UWord line, set;
+ for (set = 0; set < OC_N_SETS; set++) {
+ for (line = 0; line < OC_LINES_PER_SET; line++) {
+ ocache.set[set].line[line].tag = 1/*invalid*/;
+ }
+ }
+}
+
+static void moveLineForwards ( OCacheSet* set, UWord lineno )
+{
+ OCacheLine tmp;
+ tl_assert(lineno >= 0 && lineno < OC_LINES_PER_SET);
+ if (lineno == 0)
+ return;
+ tmp = set->line[lineno-1];
+ set->line[lineno-1] = set->line[lineno];
+ set->line[lineno] = tmp;
+}
+
+static void zeroise_OCacheLine ( OCacheLine* line, Addr tag ) {
+ UWord i;
+ for (i = 0; i < OC_W32S_PER_LINE; i++) {
+ line->w32[i] = 0; /* NO ORIGIN */
+ line->descr[i] = 0; /* REALLY REALLY NO ORIGIN! */
+ }
+ line->tag = tag;
+}
+
+__attribute__((noinline))
+static OCacheLine* find_OCacheLine_SLOW ( Addr a )
+{
+ UWord line;
+ UWord setno = (a % (OC_W32S_PER_LINE * OC_N_SETS * 4))
+ / (OC_W32S_PER_LINE * 4);
+ UWord tag = a - (a % (OC_W32S_PER_LINE * 4));
+
+ tl_assert(setno >= 0 && setno < OC_N_SETS);
+ tl_assert(0 == (tag & (4 * OC_W32S_PER_LINE - 1)));
+
+ /* we already tried line == 0; skip therefore. */
+ for (line = 1; line < OC_LINES_PER_SET; line++) {
+ if (ocache.set[setno].line[line].tag == tag) {
+ if (line == 1)
+ stats__ocacheline_found_at_1++;
+ else
+ stats__ocacheline_found_at_N++;
+ if (0 == (ocache_event_ctr++ & OC_MOVE_FORWARDS_EVERY)) {
+ moveLineForwards( &ocache.set[setno], line );
+ line--;
+ }
+ return &ocache.set[setno].line[line];
+ }
+ }
+
+ /* A miss. Use the last slot. */
+ stats__ocacheline_misses++;
+ tl_assert(line == OC_LINES_PER_SET);
+ line--;
+ tl_assert(line > 0);
+
+ zeroise_OCacheLine( &ocache.set[setno].line[line], tag );
+ moveLineForwards( &ocache.set[setno], line );
+ line--;
+
+ return &ocache.set[setno].line[line];
+}
+
+inline
+static OCacheLine* find_OCacheLine ( Addr a )
+{
+ UWord setno = (a % (OC_W32S_PER_LINE * OC_N_SETS * 4))
+ / (OC_W32S_PER_LINE * 4);
+ UWord tag = a - (a % (OC_W32S_PER_LINE * 4));
+
+ stats__ocacheline_find++;
+ // tl_assert(setno >= 0 && setno < OC_N_SETS);
+ //tl_assert(0 == (tag & (4 * OC_W32S_PER_LINE - 1)));
+
+ if (LIKELY(ocache.set[setno].line[0].tag == tag)) {
+ return &ocache.set[setno].line[0];
+ }
+
+ return find_OCacheLine_SLOW( a );
+}
+
+
/* --- Fast case permission setters, for dealing with stacks. --- */
static INLINE
@@ -1694,6 +1841,16 @@
sm = get_secmap_for_writing_low(a);
sm_off = SM_OFF(a);
sm->vabits8[sm_off] = VA_BITS8_UNDEFINED;
+
+ //// BEGIN inlined, specialised version of MC_(helperc_b_store4)
+ //// Set the origins for a+0 .. a+3
+ { UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+ OCacheLine* line = find_OCacheLine( a );
+ line->descr[lineoff] = 0xF;
+ line->w32[lineoff] = a;
+ }
+ //// END inlined, specialised version of MC_(helperc_b_store4)
#endif
}
@@ -1718,6 +1875,15 @@
sm = get_secmap_for_writing_low(a);
sm_off = SM_OFF(a);
sm->vabits8[sm_off] = VA_BITS8_NOACCESS;
+
+ //// BEGIN inlined, specialised version of MC_(helperc_b_store4)
+ //// Set the origins for a+0 .. a+3. FIXME: is this necessary?
+ { UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+ OCacheLine* line = find_OCacheLine( a );
+ line->descr[lineoff] = 0;
+ }
+ //// END inlined, specialised version of MC_(helperc_b_store4)
#endif
}
@@ -1743,6 +1909,19 @@
sm = get_secmap_for_writing_low(a);
sm_off16 = SM_OFF_16(a);
((UShort*)(sm->vabits8))[sm_off16] = VA_BITS16_UNDEFINED;
+
+ //// BEGIN inlined, specialised version of MC_(helperc_b_store8)
+ //// Set the origins for a+0 .. a+7
+ { UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ tl_assert(lineoff >= 0
+ && lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/);
+ OCacheLine* line = find_OCacheLine( a );
+ line->descr[lineoff+0] = 0xF;
+ line->descr[lineoff+1] = 0xF;
+ line->w32[lineoff+0] = a+0;
+ line->w32[lineoff+1] = a+4;
+ }
+ //// END inlined, specialised version of MC_(helperc_b_store8)
#endif
}
@@ -1767,6 +1946,17 @@
sm = get_secmap_for_writing_low(a);
sm_off16 = SM_OFF_16(a);
((UShort*)(sm->vabits8))[sm_off16] = VA_BITS16_NOACCESS;
+
+ //// BEGIN inlined, specialised version of MC_(helperc_b_store8)
+ //// Clear the origins for a+0 .. a+7. FIXME: is this necessary?
+ { UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ tl_assert(lineoff >= 0
+ && lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/);
+ OCacheLine* line = find_OCacheLine( a );
+ line->descr[lineoff+0] = 0;
+ line->descr[lineoff+1] = 0;
+ }
+ //// END inlined, specialised version of MC_(helperc_b_store8)
#endif
}
@@ -2561,7 +2751,7 @@
UChar area[MAX_REG_WRITE_SIZE];
tl_assert(size <= MAX_REG_WRITE_SIZE);
VG_(memset)(area, V_BITS8_DEFINED, size);
- VG_(set_shadow_regs_area)( tid, offset, size, area );
+ VG_(set_shadow_regs_area)( tid, 1/*shadowNo*/,offset,size, area );
# undef MAX_REG_WRITE_SIZE
}
@@ -2586,7 +2776,7 @@
UChar area[16];
tl_assert(size <= 16);
- VG_(get_shadow_regs_area)( tid, offset, size, area );
+ VG_(get_shadow_regs_area)( tid, area, 1/*shadowNo*/,offset,size );
bad = False;
for (i = 0; i < size; i++) {
@@ -2715,10 +2905,14 @@
// - as a jump target
struct {
SizeT szB; // size of value in bytes
+ UInt origin; // origin tag
+ AddrInfo oai;
} Value;
// Use of an undefined value in a conditional branch or move.
struct {
+ UInt origin;
+ AddrInfo oai;
} Cond;
// Addressability error in core (signal-handling) operation.
@@ -2944,14 +3138,23 @@
case Err_Value:
mc_pp_msg("UninitValue", err,
- "Use of uninitialised value of size %d",
- extra->Err.Value.szB);
+ "Use of uninitialised value of size %d (origin 0x%x)",
+ extra->Err.Value.szB, extra->Err.Value.origin);
+ if (extra->Err.Value.origin) {
+ mc_pp_AddrInfo(extra->Err.Value.origin,
+ &extra->Err.Value.oai, False);
+ }
break;
case Err_Cond:
mc_pp_msg("UninitCondition", err,
"Conditional jump or move depends"
- " on uninitialised value(s)");
+ " on uninitialised value(s) (origin 0x%x)",
+ extra->Err.Cond.origin);
+ if (extra->Err.Cond.origin) {
+ mc_pp_AddrInfo(extra->Err.Cond.origin,
+ &extra->Err.Cond.oai, False);
+ }
break;
case Err_RegParam:
@@ -3165,18 +3368,23 @@
VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
}
-static void mc_record_value_error ( ThreadId tid, Int szB )
+static void mc_record_value_error ( ThreadId tid, Int szB, UInt origin )
{
MC_Error extra;
tl_assert(MC_(clo_undef_value_errors));
extra.Err.Value.szB = szB;
+ extra.Err.Value.origin = origin;
+ extra.Err.Value.oai.tag = Addr_Undescribed;
VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
}
-static void mc_record_cond_error ( ThreadId tid )
+static void mc_record_cond_error ( ThreadId tid, UInt origin )
{
+ MC_Error extra;
tl_assert(MC_(clo_undef_value_errors));
- VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, /*extra*/NULL);
+ extra.Err.Cond.origin = origin;
+ extra.Err.Cond.oai.tag = Addr_Undescribed;
+ VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
}
/* --- Called from non-generated code --- */
@@ -3478,8 +3686,8 @@
// These ones don't have addresses associated with them, and so don't
// need any updating.
case Err_CoreMem:
- case Err_Value:
- case Err_Cond:
+ //case Err_Value:
+ //case Err_Cond:
case Err_Overlap:
case Err_RegParam:
// For Err_Leaks the returned size does not matter -- they are always
@@ -3488,6 +3696,23 @@
case Err_Leak:
return sizeof(MC_Error);
+ case Err_Value:
+ tl_assert(sizeof(void*) == 4);
+ if (extra->Err.Value.origin != 0) {
+ describe_addr ( extra->Err.Value.origin, &extra->Err.Value.oai );
+ } else {
+ extra->Err.Value.oai.tag = Addr_Unknown;
+ }
+ return sizeof(MC_Error);
+ case Err_Cond:
+ tl_assert(sizeof(void*) == 4);
+ if (extra->Err.Cond.origin != 0) {
+ describe_addr ( extra->Err.Cond.origin, &extra->Err.Cond.oai );
+ } else {
+ extra->Err.Cond.oai.tag = Addr_Unknown;
+ }
+ return sizeof(MC_Error);
+
// These ones always involve a memory address.
case Err_Addr:
describe_addr ( VG_(get_error_address)(err),
@@ -4183,29 +4408,30 @@
/*--- Value-check failure handlers. ---*/
/*------------------------------------------------------------*/
-void MC_(helperc_value_check0_fail) ( void )
+VG_REGPARM(1) void MC_(helperc_value_check0_fail) ( UWord origin )
{
- mc_record_cond_error ( VG_(get_running_tid)() );
+ mc_record_cond_error ( VG_(get_running_tid)(), (UInt)origin );
}
-void MC_(helperc_value_check1_fail) ( void )
+VG_REGPARM(1) void MC_(helperc_value_check1_fail) ( UWord origin )
{
- mc_record_value_error ( VG_(get_running_tid)(), 1 );
+ mc_record_value_error ( VG_(get_running_tid)(), 1, (UInt)origin );
}
-void MC_(helperc_value_check4_fail) ( void )
+VG_REGPARM(1) void MC_(helperc_value_check4_fail) ( UWord origin )
{
- mc_record_value_error ( VG_(get_running_tid)(), 4 );
+ mc_record_value_error ( VG_(get_running_tid)(), 4, (UInt)origin );
}
-void MC_(helperc_value_check8_fail) ( void )
+VG_REGPARM(1) void MC_(helperc_value_check8_fail) ( UWord origin )
{
- mc_record_value_error ( VG_(get_running_tid)(), 8 );
+ mc_record_value_error ( VG_(get_running_tid)(), 8, (UInt)origin );
}
-VG_REGPARM(1) void MC_(helperc_complain_undef) ( HWord sz )
+VG_REGPARM(2)
+void MC_(helperc_complain_undef) ( HWord sz, UWord origin )
{
- mc_record_value_error ( VG_(get_running_tid)(), (Int)sz );
+ mc_record_value_error ( VG_(get_running_tid)(), (Int)sz, (UInt)origin );
}
@@ -4963,10 +5189,247 @@
#endif
+
/*------------------------------------------------------------*/
+/*--- Origin tracking stuff ---*/
+/*------------------------------------------------------------*/
+
+/*--------------------------------------------*/
+/*--- Origin tracking: load handlers ---*/
+/*--------------------------------------------*/
+
+__attribute__((noinline))
+static UInt merge_origins ( UInt or1, UInt or2 ) {
+ if (or1 == 0) return or2;
+ if (or2 == 0) return or1;
+ return or1 < or2 ? or1 : or2;
+}
+
+UWord VG_REGPARM(1) MC_(helperc_b_load1)( Addr a ) {
+
+ UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ UWord byteoff = a & 3; /* 0, 1, 2 or 3 */
+
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+
+ OCacheLine* line = find_OCacheLine( a );
+
+ UChar descr = line->descr[lineoff];
+ tl_assert(descr < 0x10);
+
+ if (0 == (descr & (1 << byteoff))) {
+ return 0;
+ } else {
+ return line->w32[lineoff];
+ }
+}
+
+UWord VG_REGPARM(1) MC_(helperc_b_load2)( Addr a ) {
+
+ if (UNLIKELY(a & 1)) {
+ /* Handle misaligned case, slowly. */
+ UInt oLo = (UInt)MC_(helperc_b_load1)( a + 0 );
+ UInt oHi = (UInt)MC_(helperc_b_load1)( a + 1 );
+ UInt oBoth = merge_origins(oLo, oHi);
+ return (UWord)oBoth;
+ }
+
+ UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ UWord byteoff = a & 3; /* 0 or 2 */
+
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+
+ OCacheLine* line = find_OCacheLine( a );
+
+ UChar descr = line->descr[lineoff];
+ tl_assert(descr < 0x10);
+
+ if (0 == (descr & (3 << byteoff))) {
+ return 0;
+ } else {
+ return line->w32[lineoff];
+ }
+}
+
+UWord VG_REGPARM(1) MC_(helperc_b_load4)( Addr a ) {
+
+ if (UNLIKELY(a & 3)) {
+ /* Handle misaligned case, slowly. */
+ UInt oLo = (UInt)MC_(helperc_b_load2)( a + 0 );
+ UInt oHi = (UInt)MC_(helperc_b_load2)( a + 2 );
+ UInt oBoth = merge_origins(oLo, oHi);
+ return (UWord)oBoth;
+ }
+
+ UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+
+ OCacheLine* line = find_OCacheLine( a );
+
+ UChar descr = line->descr[lineoff];
+ tl_assert(descr < 0x10);
+
+ if (0 == descr) {
+ return 0;
+ } else {
+ return line->w32[lineoff];
+ }
+}
+
+UWord VG_REGPARM(1) MC_(helperc_b_load8)( Addr a ) {
+ UInt oLo = (UInt)MC_(helperc_b_load4)( a + 0 );
+ UInt oHi = (UInt)MC_(helperc_b_load4)( a + 4 );
+ UInt oBoth = merge_origins(oLo, oHi);
+ return (UWord)oBoth;
+}
+
+/*--------------------------------------------*/
+/*--- Origin tracking: store handlers ---*/
+/*--------------------------------------------*/
+
+void VG_REGPARM(2) MC_(helperc_b_store1)( Addr a, UWord d32 ) {
+
+ UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ UWord byteoff = a & 3; /* 0, 1, 2 or 3 */
+
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+
+ OCacheLine* line = find_OCacheLine( a );
+
+ if (d32 == 0) {
+ line->descr[lineoff] &= ~(1 << byteoff);
+ } else {
+ line->descr[lineoff] |= (1 << byteoff);
+ line->w32[lineoff] = d32;
+ }
+}
+
+void VG_REGPARM(2) MC_(helperc_b_store2)( Addr a, UWord d32 ) {
+
+ if (UNLIKELY(a & 1)) {
+ /* Handle misaligned case, slowly. */
+ MC_(helperc_b_store1)( a + 0, d32 );
+ MC_(helperc_b_store1)( a + 1, d32 );
+ return;
+ }
+
+ UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ UWord byteoff = a & 3; /* 0 or 2 */
+
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+
+ OCacheLine* line = find_OCacheLine( a );
+
+ if (d32 == 0) {
+ line->descr[lineoff] &= ~(3 << byteoff);
+ } else {
+ line->descr[lineoff] |= (3 << byteoff);
+ line->w32[lineoff] = d32;
+ }
+}
+
+void VG_REGPARM(2) MC_(helperc_b_store4)( Addr a, UWord d32 ) {
+
+ if (UNLIKELY(a & 3)) {
+ /* Handle misaligned case, slowly. */
+ MC_(helperc_b_store2)( a + 0, d32 );
+ MC_(helperc_b_store2)( a + 2, d32 );
+ return;
+ }
+
+ UWord lineoff = (a % (OC_W32S_PER_LINE * 4)) / 4;
+ tl_assert(lineoff >= 0 && lineoff < OC_W32S_PER_LINE);
+
+ OCacheLine* line = find_OCacheLine( a );
+
+ if (d32 == 0) {
+ line->descr[lineoff] = 0;
+ } else {
+ line->descr[lineoff] = 0xF;
+ line->w32[lineoff] = d32;
+ }
+}
+
+void VG_REGPARM(2) MC_(helperc_b_store8)( Addr a, UWord d32 ) {
+ MC_(helperc_b_store4)( a + 0, d32 );
+ MC_(helperc_b_store4)( a + 4, d32 );
+}
+
+/*--------------------------------------------*/
+/*--- Origin tracking: sarp handlers ---*/
+/*--------------------------------------------*/
+
+// FIXME: reconsider what origin to store for the 1/2 cases
+__attribute__((noinline))
+static void ocache_sarp_Set_Origins ( Addr a, UWord len ) {
+ if ((a & 1) && len >= 1) {
+ MC_(helperc_b_store1)( a, a );
+ a++;
+ len--;
+ }
+ if ((a & 2) && len >= 2) {
+ MC_(helperc_b_store2)( a, a );
+ a += 2;
+ len -= 2;
+ }
+ if (len >= 4)
+ tl_assert(0 == (a & 3));
+ while (len >= 4) {
+ MC_(helperc_b_store4)( a, a );
+ a += 4;
+ len -= 4;
+ }
+ if (len >= 2) {
+ MC_(helperc_b_store2)( a, a );
+ a += 2;
+ len -= 2;
+ }
+ if (len >= 1) {
+ MC_(helperc_b_store1)( a, a );
+ a++;
+ len--;
+ }
+ tl_assert(len == 0);
+}
+
+__attribute__((noinline))
+static void ocache_sarp_Clear_Origins ( Addr a, UWord len ) {
+ if ((a & 1) && len >= 1) {
+ MC_(helperc_b_store1)( a, 0 );
+ a++;
+ len--;
+ }
+ if ((a & 2) && len >= 2) {
+ MC_(helperc_b_store2)( a, 0 );
+ a += 2;
+ len -= 2;
+ }
+ if (len >= 4)
+ tl_assert(0 == (a & 3));
+ while (len >= 4) {
+ MC_(helperc_b_store4)( a, 0 );
+ a += 4;
+ len -= 4;
+ }
+ if (len >= 2) {
+ MC_(helperc_b_store2)( a, 0 );
+ a += 2;
+ len -= 2;
+ }
+ if (len >= 1) {
+ MC_(helperc_b_store1)( a, 0 );
+ a++;
+ len--;
+ }
+ tl_assert(len == 0);
+}
+
+
+/*------------------------------------------------------------*/
/*--- Setup and finalisation ---*/
/*------------------------------------------------------------*/
+
static void mc_post_clo_init ( void )
{
/* If we've been asked to emit XML, mash around various other
@@ -5054,6 +5517,18 @@
VG_(message)(Vg_DebugMsg,
" memcheck: max shadow mem size: %dk, %dM",
max_shmem_szB / 1024, max_shmem_szB / (1024 * 1024));
+
+ VG_(message)(Vg_DebugMsg,
+ " ocache: %,12lu finds %,12lu misses",
+ stats__ocacheline_find,
+ stats__ocacheline_misses );
+ VG_(message)(Vg_DebugMsg,
+ " ocache: %,12lu at 0 %,12lu at 1 %,12lu at 2+",
+ stats__ocacheline_find - stats__ocacheline_misses
+ - stats__ocacheline_found_at_1
+ - stats__ocacheline_found_at_N,
+ stats__ocacheline_found_at_1,
+ stats__ocacheline_found_at_N );
}
if (0) {
@@ -5184,6 +5659,8 @@
// BYTES_PER_SEC_VBIT_NODE must be a power of two.
tl_assert(-1 != VG_(log2)(BYTES_PER_SEC_VBIT_NODE));
+
+ init_OCache();
}
VG_DETERMINE_INTERFACE_VERSION(mc_pre_clo_init)
|