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: 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)
|
Author: sewardj
Date: 2008-03-29 14:08:12 +0000 (Sat, 29 Mar 2008)
New Revision: 7809
Log:
Framework level changes to support double (guest state) shadowing.
Modified:
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_initimg/initimg-linux.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_machine.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_scheduler/scheduler.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-amd64-linux.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-x86-linux.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-amd64-linux.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-x86-linux.c
branches/OTRACK_BY_INSTRUMENTATION/coregrind/pub_core_threadstate.h
branches/OTRACK_BY_INSTRUMENTATION/include/pub_tool_machine.h
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_initimg/initimg-linux.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_initimg/initimg-linux.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_initimg/initimg-linux.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -962,8 +962,9 @@
sane way. */
LibVEX_GuestX86_initialise(&arch->vex);
- /* Zero out the shadow area. */
- VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestX86State));
+ /* Zero out the shadow areas. */
+ VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
+ VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));
/* Put essential stuff into the new state. */
arch->vex.guest_ESP = iifii.initial_client_SP;
@@ -982,8 +983,9 @@
sane way. */
LibVEX_GuestAMD64_initialise(&arch->vex);
- /* Zero out the shadow area. */
- VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestAMD64State));
+ /* Zero out the shadow areas. */
+ VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State));
+ VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State));
/* Put essential stuff into the new state. */
arch->vex.guest_RSP = iifii.initial_client_SP;
@@ -996,8 +998,9 @@
sane way. */
LibVEX_GuestPPC32_initialise(&arch->vex);
- /* Zero out the shadow area. */
- VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC32State));
+ /* Zero out the shadow areas. */
+ VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State));
+ VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State));
/* Put essential stuff into the new state. */
arch->vex.guest_GPR1 = iifii.initial_client_SP;
@@ -1010,8 +1013,9 @@
sane way. */
LibVEX_GuestPPC64_initialise(&arch->vex);
- /* Zero out the shadow area. */
- VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC64State));
+ /* Zero out the shadow areas. */
+ VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State));
+ VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State));
/* Put essential stuff into the new state. */
arch->vex.guest_GPR1 = iifii.initial_client_SP;
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_machine.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_machine.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_machine.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -79,34 +79,44 @@
}
-void VG_(get_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size,
- UChar* area )
+void
+VG_(get_shadow_regs_area) ( ThreadId tid,
+ /*DST*/UChar* dst,
+ /*SRC*/Int shadowNo, OffT offset, SizeT size )
{
+ void* src;
ThreadState* tst;
-
+ vg_assert(shadowNo == 1 || shadowNo == 2);
vg_assert(VG_(is_valid_tid)(tid));
- tst = & VG_(threads)[tid];
-
// Bounds check
vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
vg_assert(offset + size <= sizeof(VexGuestArchState));
-
- VG_(memcpy)( area, (void*)(((Addr)&(tst->arch.vex_shadow)) + offset), size);
+ // Copy
+ tst = & VG_(threads)[tid];
+ src = shadowNo == 1
+ ? (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset)
+ : (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset);
+ VG_(memcpy)( dst, src, size);
}
-void VG_(set_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size,
- const UChar* area )
+void
+VG_(set_shadow_regs_area) ( ThreadId tid,
+ /*DST*/Int shadowNo, OffT offset, SizeT size,
+ /*SRC*/const UChar* src )
{
+ void* dst;
ThreadState* tst;
-
+ vg_assert(shadowNo == 1 || shadowNo == 2);
vg_assert(VG_(is_valid_tid)(tid));
- tst = & VG_(threads)[tid];
-
// Bounds check
vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
vg_assert(offset + size <= sizeof(VexGuestArchState));
-
- VG_(memcpy)( (void*)(((Addr)(&tst->arch.vex_shadow)) + offset), area, size);
+ // Copy
+ tst = & VG_(threads)[tid];
+ dst = shadowNo == 1
+ ? (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset)
+ : (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset);
+ VG_(memcpy)( dst, src, size);
}
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_scheduler/scheduler.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_scheduler/scheduler.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_scheduler/scheduler.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -530,33 +530,39 @@
/* Do various guest state alignment checks prior to running a thread.
Specifically, check that what we have matches Vex's guest state
layout requirements. */
-static void do_pre_run_checks ( volatile ThreadState* tst )
+static void do_pre_run_checks ( ThreadState* tst )
{
- Addr a_vex = (Addr) & tst->arch.vex;
- Addr a_vexsh = (Addr) & tst->arch.vex_shadow;
- Addr a_spill = (Addr) & tst->arch.vex_spill;
- UInt sz_vex = (UInt) sizeof tst->arch.vex;
- UInt sz_vexsh = (UInt) sizeof tst->arch.vex_shadow;
- UInt sz_spill = (UInt) sizeof tst->arch.vex_spill;
+ Addr a_vex = (Addr) & tst->arch.vex;
+ Addr a_vexsh1 = (Addr) & tst->arch.vex_shadow1;
+ Addr a_vexsh2 = (Addr) & tst->arch.vex_shadow2;
+ Addr a_spill = (Addr) & tst->arch.vex_spill;
+ UInt sz_vex = (UInt) sizeof tst->arch.vex;
+ UInt sz_vexsh1 = (UInt) sizeof tst->arch.vex_shadow1;
+ UInt sz_vexsh2 = (UInt) sizeof tst->arch.vex_shadow2;
+ UInt sz_spill = (UInt) sizeof tst->arch.vex_spill;
if (0)
VG_(printf)("%p %d %p %d %p %d\n",
- (void*)a_vex, sz_vex, (void*)a_vexsh, sz_vexsh,
+ (void*)a_vex, sz_vex, (void*)a_vexsh1, sz_vexsh1,
(void*)a_spill, sz_spill );
vg_assert(VG_IS_8_ALIGNED(sz_vex));
- vg_assert(VG_IS_8_ALIGNED(sz_vexsh));
+ vg_assert(VG_IS_8_ALIGNED(sz_vexsh1));
+ vg_assert(VG_IS_8_ALIGNED(sz_vexsh2));
vg_assert(VG_IS_16_ALIGNED(sz_spill));
vg_assert(VG_IS_4_ALIGNED(a_vex));
- vg_assert(VG_IS_4_ALIGNED(a_vexsh));
+ vg_assert(VG_IS_4_ALIGNED(a_vexsh1));
+ vg_assert(VG_IS_4_ALIGNED(a_vexsh2));
vg_assert(VG_IS_4_ALIGNED(a_spill));
- vg_assert(sz_vex == sz_vexsh);
- vg_assert(a_vex + sz_vex == a_vexsh);
+ vg_assert(sz_vex == sz_vexsh1);
+ vg_assert(sz_vex == sz_vexsh2);
+ vg_assert(a_vex + 1 * sz_vex == a_vexsh1);
+ vg_assert(a_vex + 2 * sz_vex == a_vexsh2);
vg_assert(sz_spill == LibVEX_N_SPILL_BYTES);
- vg_assert(a_vex + 2 * sz_vex == a_spill);
+ vg_assert(a_vex + 3 * sz_vex == a_spill);
# if defined(VGA_ppc32) || defined(VGA_ppc64)
/* ppc guest_state vector regs must be 16 byte aligned for
@@ -583,7 +589,7 @@
vg_assert(!VG_(is_exiting)(tid));
tst = VG_(get_ThreadState)(tid);
- do_pre_run_checks(tst);
+ do_pre_run_checks( (ThreadState*)tst );
/* end Paranoia */
trc = 0;
@@ -686,7 +692,7 @@
vg_assert(!VG_(is_exiting)(tid));
tst = VG_(get_ThreadState)(tid);
- do_pre_run_checks(tst);
+ do_pre_run_checks( (ThreadState*)tst );
/* end Paranoia */
# if defined(VGA_ppc32) || defined(VGA_ppc64)
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-amd64-linux.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-amd64-linux.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-amd64-linux.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -93,7 +93,8 @@
/* XXX This is wrong. Surely we should store the shadow values
into the shadow memory behind the actual values? */
- VexGuestAMD64State vex_shadow;
+ VexGuestAMD64State vex_shadow1;
+ VexGuestAMD64State vex_shadow2;
/* HACK ALERT */
VexGuestAMD64State vex;
@@ -422,7 +423,8 @@
{
frame->sigNo_private = sigNo;
frame->magicPI = 0x31415927;
- frame->vex_shadow = tst->arch.vex_shadow;
+ frame->vex_shadow1 = tst->arch.vex_shadow1;
+ frame->vex_shadow2 = tst->arch.vex_shadow2;
/* HACK ALERT */
frame->vex = tst->arch.vex;
/* end HACK ALERT */
@@ -541,13 +543,14 @@
*sigNo = VKI_SIGSEGV;
return False;
}
- tst->sig_mask = frame->mask;
- tst->tmp_sig_mask = frame->mask;
- tst->arch.vex_shadow = frame->vex_shadow;
+ tst->sig_mask = frame->mask;
+ tst->tmp_sig_mask = frame->mask;
+ tst->arch.vex_shadow1 = frame->vex_shadow1;
+ tst->arch.vex_shadow2 = frame->vex_shadow2;
/* HACK ALERT */
- tst->arch.vex = frame->vex;
+ tst->arch.vex = frame->vex;
/* end HACK ALERT */
- *sigNo = frame->sigNo_private;
+ *sigNo = frame->sigNo_private;
return True;
}
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-x86-linux.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-x86-linux.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_sigframe/sigframe-x86-linux.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -99,7 +99,8 @@
/* XXX This is wrong. Surely we should store the shadow values
into the shadow memory behind the actual values? */
- VexGuestX86State vex_shadow;
+ VexGuestX86State vex_shadow1;
+ VexGuestX86State vex_shadow2;
/* HACK ALERT */
VexGuestX86State vex;
@@ -443,7 +444,8 @@
{
frame->sigNo_private = sigNo;
frame->magicPI = 0x31415927;
- frame->vex_shadow = tst->arch.vex_shadow;
+ frame->vex_shadow1 = tst->arch.vex_shadow1;
+ frame->vex_shadow2 = tst->arch.vex_shadow2;
/* HACK ALERT */
frame->vex = tst->arch.vex;
/* end HACK ALERT */
@@ -622,13 +624,14 @@
*sigNo = VKI_SIGSEGV;
return False;
}
- tst->sig_mask = frame->mask;
- tst->tmp_sig_mask = frame->mask;
- tst->arch.vex_shadow = frame->vex_shadow;
+ tst->sig_mask = frame->mask;
+ tst->tmp_sig_mask = frame->mask;
+ tst->arch.vex_shadow1 = frame->vex_shadow1;
+ tst->arch.vex_shadow2 = frame->vex_shadow2;
/* HACK ALERT */
- tst->arch.vex = frame->vex;
+ tst->arch.vex = frame->vex;
/* end HACK ALERT */
- *sigNo = frame->sigNo_private;
+ *sigNo = frame->sigNo_private;
return True;
}
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-amd64-linux.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-amd64-linux.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-amd64-linux.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -322,7 +322,8 @@
{
/* We inherit our parent's guest state. */
child->vex = parent->vex;
- child->vex_shadow = parent->vex_shadow;
+ child->vex_shadow1 = parent->vex_shadow1;
+ child->vex_shadow2 = parent->vex_shadow2;
}
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-x86-linux.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-x86-linux.c 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/m_syswrap/syswrap-x86-linux.c 2008-03-29 14:08:12 UTC (rev 7809)
@@ -732,7 +732,8 @@
{
/* We inherit our parent's guest state. */
child->vex = parent->vex;
- child->vex_shadow = parent->vex_shadow;
+ child->vex_shadow1 = parent->vex_shadow1;
+ child->vex_shadow2 = parent->vex_shadow2;
/* We inherit our parent's LDT. */
if (parent->vex.guest_LDT == (HWord)NULL) {
Modified: branches/OTRACK_BY_INSTRUMENTATION/coregrind/pub_core_threadstate.h
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/coregrind/pub_core_threadstate.h 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/coregrind/pub_core_threadstate.h 2008-03-29 14:08:12 UTC (rev 7809)
@@ -96,8 +96,9 @@
/* Saved machine context. */
VexGuestArchState vex;
- /* Saved shadow context. */
- VexGuestArchState vex_shadow;
+ /* Saved shadow context (2 copies). */
+ VexGuestArchState vex_shadow1;
+ VexGuestArchState vex_shadow2;
/* Spill area. */
UChar vex_spill[LibVEX_N_SPILL_BYTES];
Modified: branches/OTRACK_BY_INSTRUMENTATION/include/pub_tool_machine.h
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/include/pub_tool_machine.h 2008-03-29 13:38:48 UTC (rev 7808)
+++ branches/OTRACK_BY_INSTRUMENTATION/include/pub_tool_machine.h 2008-03-29 14:08:12 UTC (rev 7809)
@@ -83,10 +83,14 @@
// For get/set, 'area' is where the asked-for shadow state will be copied
// into/from.
-extern void VG_(get_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset,
- SizeT size, UChar* area );
-extern void VG_(set_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset,
- SizeT size, const UChar* area );
+void
+VG_(get_shadow_regs_area) ( ThreadId tid,
+ /*DST*/UChar* dst,
+ /*SRC*/Int shadowNo, OffT offset, SizeT size );
+void
+VG_(set_shadow_regs_area) ( ThreadId tid,
+ /*DST*/Int shadowNo, OffT offset, SizeT size,
+ /*SRC*/const UChar* src );
// Apply a function 'f' to all the general purpose registers in all the
// current threads.
|
|
From: <sv...@va...> - 2008-03-29 14:02:57
|
Author: sewardj
Date: 2008-03-29 14:02:57 +0000 (Sat, 29 Mar 2008)
New Revision: 1815
Log:
Add a new primop, 32-bit unsigned max, as that is useful for
propogating origin tags. And it makes it easy to fold out unnecessary
instrumentation code.
Modified:
branches/OTRACK_BY_INSTRUMENTATION/priv/host-x86/isel.c
branches/OTRACK_BY_INSTRUMENTATION/priv/ir/irdefs.c
branches/OTRACK_BY_INSTRUMENTATION/priv/ir/iropt.c
branches/OTRACK_BY_INSTRUMENTATION/pub/libvex_ir.h
Modified: branches/OTRACK_BY_INSTRUMENTATION/priv/host-x86/isel.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/priv/host-x86/isel.c 2008-03-29 14:01:51 UTC (rev 1814)
+++ branches/OTRACK_BY_INSTRUMENTATION/priv/host-x86/isel.c 2008-03-29 14:02:57 UTC (rev 1815)
@@ -925,6 +925,16 @@
return dst;
}
+ if (e->Iex.Binop.op == Iop_Max32U) {
+ HReg src1 = iselIntExpr_R(env, e->Iex.Binop.arg1);
+ HReg dst = newVRegI(env);
+ HReg src2 = iselIntExpr_R(env, e->Iex.Binop.arg2);
+ addInstr(env, mk_iMOVsd_RR(src1,dst));
+ addInstr(env, X86Instr_Alu32R(Xalu_CMP, X86RMI_Reg(src2), dst));
+ addInstr(env, X86Instr_CMov32(Xcc_B, X86RM_Reg(src2), dst));
+ return dst;
+ }
+
/* Handle misc other ops. */
if (e->Iex.Binop.op == Iop_8HLto16) {
HReg hi8 = newVRegI(env);
Modified: branches/OTRACK_BY_INSTRUMENTATION/priv/ir/irdefs.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/priv/ir/irdefs.c 2008-03-29 14:01:51 UTC (rev 1814)
+++ branches/OTRACK_BY_INSTRUMENTATION/priv/ir/irdefs.c 2008-03-29 14:02:57 UTC (rev 1815)
@@ -210,6 +210,7 @@
case Iop_Left16: vex_printf("Left16"); return;
case Iop_Left32: vex_printf("Left32"); return;
case Iop_Left64: vex_printf("Left64"); return;
+ case Iop_Max32U: vex_printf("Max32U"); return;
case Iop_CmpORD32U: vex_printf("CmpORD32U"); return;
case Iop_CmpORD32S: vex_printf("CmpORD32S"); return;
@@ -1498,6 +1499,7 @@
case Iop_CmpORD32S:
case Iop_Add32: case Iop_Sub32: case Iop_Mul32:
case Iop_Or32: case Iop_And32: case Iop_Xor32:
+ case Iop_Max32U:
BINARY(Ity_I32,Ity_I32, Ity_I32);
case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
Modified: branches/OTRACK_BY_INSTRUMENTATION/priv/ir/iropt.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/priv/ir/iropt.c 2008-03-29 14:01:51 UTC (rev 1814)
+++ branches/OTRACK_BY_INSTRUMENTATION/priv/ir/iropt.c 2008-03-29 14:02:57 UTC (rev 1815)
@@ -1421,8 +1421,9 @@
e2 = e->Iex.Binop.arg1;
} else
- /* Or32/Add32(x,0) ==> x */
- if ((e->Iex.Binop.op == Iop_Add32 || e->Iex.Binop.op == Iop_Or32)
+ /* Or32/Add32/Max32U(x,0) ==> x */
+ if ((e->Iex.Binop.op == Iop_Add32
+ || e->Iex.Binop.op == Iop_Or32 || e->Iex.Binop.op == Iop_Max32U)
&& e->Iex.Binop.arg2->tag == Iex_Const
&& e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 == 0) {
e2 = e->Iex.Binop.arg1;
@@ -1500,8 +1501,8 @@
e2 = e->Iex.Binop.arg2;
} else
- /* Or32(0,x) ==> x */
- if (e->Iex.Binop.op == Iop_Or32
+ /* Or32/Max32U(0,x) ==> x */
+ if ((e->Iex.Binop.op == Iop_Or32 || e->Iex.Binop.op == Iop_Max32U)
&& e->Iex.Binop.arg1->tag == Iex_Const
&& e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 == 0) {
e2 = e->Iex.Binop.arg2;
Modified: branches/OTRACK_BY_INSTRUMENTATION/pub/libvex_ir.h
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/pub/libvex_ir.h 2008-03-29 14:01:51 UTC (rev 1814)
+++ branches/OTRACK_BY_INSTRUMENTATION/pub/libvex_ir.h 2008-03-29 14:02:57 UTC (rev 1815)
@@ -446,6 +446,7 @@
Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64,
Iop_CmpwNEZ32, Iop_CmpwNEZ64, /* all-0s -> all-Os; other -> all-1s */
Iop_Left8, Iop_Left16, Iop_Left32, Iop_Left64, /* \x -> x | -x */
+ Iop_Max32U, /* unsigned max */
/* PowerPC-style 3-way integer comparisons. Without them it is
difficult to simulate PPC efficiently.
|
|
From: <sv...@va...> - 2008-03-29 14:01:51
|
Author: sewardj
Date: 2008-03-29 14:01:51 +0000 (Sat, 29 Mar 2008)
New Revision: 1814
Log:
Add support for a second set of register shadows in vex.
Astonishingly this seems to be the only required change.
Modified:
branches/OTRACK_BY_INSTRUMENTATION/priv/host-generic/reg_alloc2.c
Modified: branches/OTRACK_BY_INSTRUMENTATION/priv/host-generic/reg_alloc2.c
===================================================================
--- branches/OTRACK_BY_INSTRUMENTATION/priv/host-generic/reg_alloc2.c 2008-03-29 12:58:42 UTC (rev 1813)
+++ branches/OTRACK_BY_INSTRUMENTATION/priv/host-generic/reg_alloc2.c 2008-03-29 14:01:51 UTC (rev 1814)
@@ -849,9 +849,9 @@
}
/* This reflects LibVEX's hard-wired knowledge of the baseBlock
- layout: the guest state, then an equal sized area following
- it for shadow state, and then the spill area. */
- vreg_lrs[j].spill_offset = toShort(guest_sizeB * 2 + k * 8);
+ layout: the guest state, then two equal sized areas following
+ it for two sets of shadow state, and then the spill area. */
+ vreg_lrs[j].spill_offset = toShort(guest_sizeB * 3 + k * 8);
/* if (j > max_ss_no) */
/* max_ss_no = j; */
|
|
From: <sv...@va...> - 2008-03-29 13:38:43
|
Author: sewardj Date: 2008-03-29 13:38:48 +0000 (Sat, 29 Mar 2008) New Revision: 7808 Log: Swizzle external. Modified: branches/OTRACK_BY_INSTRUMENTATION/ Property changes on: branches/OTRACK_BY_INSTRUMENTATION ___________________________________________________________________ Name: svn:externals - VEX svn://svn.valgrind.org/vex/trunk + VEX svn://svn.valgrind.org/vex/branches/OTRACK_BY_INSTRUMENTATION |
|
From: <sv...@va...> - 2008-03-29 13:34:52
|
Author: sewardj Date: 2008-03-29 13:34:57 +0000 (Sat, 29 Mar 2008) New Revision: 7807 Log: Make a copy of trunk r7806 for experimentation with instrumentation-based origin tracking (for Memcheck). Added: branches/OTRACK_BY_INSTRUMENTATION/ Copied: branches/OTRACK_BY_INSTRUMENTATION (from rev 7806, trunk) |
|
From: Julian S. <js...@ac...> - 2008-03-29 13:33:09
|
> 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. J |
|
From: <sv...@va...> - 2008-03-29 13:17:58
|
Author: bart
Date: 2008-03-29 13:18:02 +0000 (Sat, 29 Mar 2008)
New Revision: 7806
Log:
Changed meaning of the second argument of the start/stop suppression client requests from "end address" to "size in bytes".
Modified:
trunk/exp-drd/drd_clientreq.c
trunk/exp-drd/drd_clientreq.h
trunk/exp-drd/drd_pthread_intercepts.c
Modified: trunk/exp-drd/drd_clientreq.c
===================================================================
--- trunk/exp-drd/drd_clientreq.c 2008-03-29 13:13:33 UTC (rev 7805)
+++ trunk/exp-drd/drd_clientreq.c 2008-03-29 13:18:02 UTC (rev 7806)
@@ -94,11 +94,11 @@
break;
case VG_USERREQ__DRD_START_SUPPRESSION:
- drd_start_suppression(arg[1], arg[2], "client");
+ drd_start_suppression(arg[1], arg[1] + arg[2], "client");
break;
case VG_USERREQ__DRD_FINISH_SUPPRESSION:
- drd_finish_suppression(arg[1], arg[2]);
+ drd_finish_suppression(arg[1], arg[1] + arg[2]);
break;
case VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK:
Modified: trunk/exp-drd/drd_clientreq.h
===================================================================
--- trunk/exp-drd/drd_clientreq.h 2008-03-29 13:13:33 UTC (rev 7805)
+++ trunk/exp-drd/drd_clientreq.h 2008-03-29 13:18:02 UTC (rev 7806)
@@ -13,11 +13,11 @@
/* To tell the drd tool to suppress data race detection on the specified */
/* address range. */
VG_USERREQ__DRD_START_SUPPRESSION,
- /* args: start address, end address */
+ /* args: start address, size in bytes */
/* To tell the drd tool no longer to suppress data race detection on the */
/* specified address range. */
VG_USERREQ__DRD_FINISH_SUPPRESSION,
- /* args: start address, end address */
+ /* args: start address, size in bytes */
/* Ask drd to suppress data race reports on all currently allocated stack */
/* data of the current thread. */
VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK,
Modified: trunk/exp-drd/drd_pthread_intercepts.c
===================================================================
--- trunk/exp-drd/drd_pthread_intercepts.c 2008-03-29 13:13:33 UTC (rev 7805)
+++ trunk/exp-drd/drd_pthread_intercepts.c 2008-03-29 13:18:02 UTC (rev 7806)
@@ -125,7 +125,7 @@
{
int res;
VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
- p, (char*)p + size, 0, 0, 0);
+ p, size, 0, 0, 0);
}
static void vg_set_joinable(const pthread_t tid, const int joinable)
|
|
From: <sv...@va...> - 2008-03-29 13:13:29
|
Author: bart
Date: 2008-03-29 13:13:33 +0000 (Sat, 29 Mar 2008)
New Revision: 7805
Log:
Comment-only fix.
Modified:
trunk/exp-drd/drd_thread.h
Modified: trunk/exp-drd/drd_thread.h
===================================================================
--- trunk/exp-drd/drd_thread.h 2008-03-29 12:54:01 UTC (rev 7804)
+++ trunk/exp-drd/drd_thread.h 2008-03-29 13:13:33 UTC (rev 7805)
@@ -172,7 +172,10 @@
#endif
s_threadinfo[tid].stack_min = stack_min;
#if 0
- tl_assert(s_threadinfo[tid].stack_min < s_threadinfo[tid].stack_max);
+ /* This function can be called after the thread has been created but */
+ /* before drd_post_thread_create() has filled in stack_max. */
+ tl_assert(s_threadinfo[tid].stack_min < s_threadinfo[tid].stack_max
+ || s_threadinfo[tid].stack_max == 0);
#endif
if (UNLIKELY(stack_min < s_threadinfo[tid].stack_min_min))
{
|
|
From: Julian S. <js...@ac...> - 2008-03-29 13:12:09
|
> The peephole optimizer I described earlier. It does some coalescing and > removes redudant moves between virtual registers. On code instrumented with > memcheck it can reduce the number of reg-allocated instructions by up to > 12%. > > All the regression tests pass after applying these patches (except those > that didn't pass before applying the patches). 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 |
|
From: <sv...@va...> - 2008-03-29 12:58:39
|
Author: sewardj Date: 2008-03-29 12:58:42 +0000 (Sat, 29 Mar 2008) New Revision: 1813 Log: Make a copy of r1812 for experimentation with instrumentation-based origin tracking (as opposed to value-piggybacking-based origin tracking). Added: branches/OTRACK_BY_INSTRUMENTATION/ Copied: branches/OTRACK_BY_INSTRUMENTATION (from rev 1812, trunk) |
|
From: <sv...@va...> - 2008-03-29 12:54:01
|
Author: bart
Date: 2008-03-29 12:54:01 +0000 (Sat, 29 Mar 2008)
New Revision: 7804
Log:
Minor optimization: eliminated an if-statement.
Modified:
trunk/exp-drd/drd_thread.h
Modified: trunk/exp-drd/drd_thread.h
===================================================================
--- trunk/exp-drd/drd_thread.h 2008-03-29 11:03:38 UTC (rev 7803)
+++ trunk/exp-drd/drd_thread.h 2008-03-29 12:54:01 UTC (rev 7804)
@@ -170,16 +170,13 @@
#if 0
tl_assert(0 <= tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID);
#endif
- if (s_threadinfo[tid].stack_max)
- {
- s_threadinfo[tid].stack_min = stack_min;
+ s_threadinfo[tid].stack_min = stack_min;
#if 0
- tl_assert(s_threadinfo[tid].stack_min < s_threadinfo[tid].stack_max);
+ tl_assert(s_threadinfo[tid].stack_min < s_threadinfo[tid].stack_max);
#endif
- if (UNLIKELY(stack_min < s_threadinfo[tid].stack_min_min))
- {
- s_threadinfo[tid].stack_min_min = stack_min;
- }
+ if (UNLIKELY(stack_min < s_threadinfo[tid].stack_min_min))
+ {
+ s_threadinfo[tid].stack_min_min = stack_min;
}
}
|
|
From: Bart V. A. <bar...@gm...> - 2008-03-29 12:39:39
|
On Sat, Mar 29, 2008 at 12:26 AM, Julian Seward <js...@ac...> wrote: > > Konstantin wrote: > > > I'd like to collect ideas regarding the subject raised today in a > > separate thread: how to decipher Helgrind's reports about 'Possible > > data race'. > > That is an excellent question; unfortunately not easy to answer. > > Let me ask a related question. In a way it is chasing the problem > from the other end. Question is: In an ideal world (no constraints > on CPU time or memory), what information would make it easy to > find the root cause of race reports? What definitely helps is the stack traces (two or more) of all conflicting accesses and the allocation context of the address on which the conflict happened. This is sufficient for identifying the source code statements causing the conflict. Solving a data race properly can be more difficult. Sometimes basic knowledge of the software you are analyzing is sufficient, sometimes you need a deep understanding of the software. Adding more tracing always helps understanding complex cases. Bart. |
|
From: <sv...@va...> - 2008-03-29 11:03:34
|
Author: sewardj Date: 2008-03-29 11:03:38 +0000 (Sat, 29 Mar 2008) New Revision: 7803 Log: Add notes on how to hack on OOo without having excessive delays caused by either (1) having to reinstall having rebuilt, or (2) by having 'make' walk over the entire massive source tree to decide what to rebuild following a 1-line change. With help from Michael Meeks. Modified: branches/HGDEV/docs/internals/BIG_APP_NOTES.txt Modified: branches/HGDEV/docs/internals/BIG_APP_NOTES.txt =================================================================== --- branches/HGDEV/docs/internals/BIG_APP_NOTES.txt 2008-03-29 09:31:43 UTC (rev 7802) +++ branches/HGDEV/docs/internals/BIG_APP_NOTES.txt 2008-03-29 11:03:38 UTC (rev 7803) @@ -75,6 +75,8 @@ ./autogen.sh --with-distro=SUSE-10.2 --with-java=no --disable-gstreamer --disable-mono --with-max-jobs=2 --with-num-cpus=2 +# --with-alloc=system is used by default + ./download make @@ -97,3 +99,25 @@ cd ~/Tools/OOPlay/Inst01 valgrind -v ./program/soffice.bin + +# Hacking OOo + +# Use two shells, (C)ompile and (R)un. In (C): +# +cd build/ooh680-m12 +. ./LinuxX86Env.Set.sh +solenv/bin/linkoo ~/Tools/OOPlay/Inst01 +# +# This replaces all the .so's in the install tree with symlinks +# back into the build tree, so you can then re-run without +# having to endlessly reinstall. It also creates 'ooenv' in +# ~/Tools/OOPlay/Inst01/program, which needs to be sourced +# once before running. +# +# So having changed something in OOo, eg in svx/, do: +# +(cd svx && build) +# +# Meanwhile in the (R)un shell: +source ooenv # just once! +valgrind [args] ./soffice.bin |