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
(6) |
2
(4) |
3
(4) |
4
(4) |
|
5
(6) |
6
(9) |
7
(4) |
8
(15) |
9
(6) |
10
(6) |
11
(22) |
|
12
(12) |
13
(9) |
14
(4) |
15
(11) |
16
(8) |
17
(4) |
18
(6) |
|
19
(6) |
20
(15) |
21
(9) |
22
(9) |
23
(14) |
24
(7) |
25
(7) |
|
26
(8) |
27
(11) |
28
(4) |
29
(4) |
30
(12) |
31
(7) |
|
|
From: <sv...@va...> - 2008-10-08 23:03:14
|
Author: sewardj
Date: 2008-10-09 00:03:00 +0100 (Thu, 09 Oct 2008)
New Revision: 8652
Log:
Get rid of another layer of pointless function calls on the read/write
fast paths.
Modified:
branches/YARD/helgrind/hg_main.c
branches/YARD/helgrind/libhb.h
branches/YARD/helgrind/libhb_core.c
Modified: branches/YARD/helgrind/hg_main.c
===================================================================
--- branches/YARD/helgrind/hg_main.c 2008-10-08 21:55:49 UTC (rev 8651)
+++ branches/YARD/helgrind/hg_main.c 2008-10-08 23:03:00 UTC (rev 8652)
@@ -1054,13 +1054,13 @@
{
Thr* hbthr = thr->hbthr;
tl_assert(hbthr);
- libhb_read_N(hbthr, a, len);
+ LIBHB_READ_N(hbthr, a, len);
}
static void shadow_mem_write_range ( Thread* thr, Addr a, SizeT len ) {
Thr* hbthr = thr->hbthr;
tl_assert(hbthr);
- libhb_write_N(hbthr, a, len);
+ LIBHB_WRITE_N(hbthr, a, len);
}
static void shadow_mem_make_New ( Thread* thr, Addr a, SizeT len )
@@ -1731,70 +1731,70 @@
void evh__mem_help_read_1(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_read_1(hbthr, a);
+ LIBHB_READ_1(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_read_2(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_read_2(hbthr, a);
+ LIBHB_READ_2(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_read_4(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_read_4(hbthr, a);
+ LIBHB_READ_4(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_read_8(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_read_8(hbthr, a);
+ LIBHB_READ_8(hbthr, a);
}
static VG_REGPARM(2)
void evh__mem_help_read_N(Addr a, SizeT size) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_read_N(hbthr, a, size);
+ LIBHB_READ_N(hbthr, a, size);
}
static VG_REGPARM(1)
void evh__mem_help_write_1(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_write_1(hbthr, a);
+ LIBHB_WRITE_1(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_write_2(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_write_2(hbthr, a);
+ LIBHB_WRITE_2(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_write_4(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_write_4(hbthr, a);
+ LIBHB_WRITE_4(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_write_8(Addr a) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_write_8(hbthr, a);
+ LIBHB_WRITE_8(hbthr, a);
}
static VG_REGPARM(2)
void evh__mem_help_write_N(Addr a, SizeT size) {
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- libhb_write_N(hbthr, a, size);
+ LIBHB_WRITE_N(hbthr, a, size);
}
static void evh__bus_lock(void) {
Modified: branches/YARD/helgrind/libhb.h
===================================================================
--- branches/YARD/helgrind/libhb.h 2008-10-08 21:55:49 UTC (rev 8651)
+++ branches/YARD/helgrind/libhb.h 2008-10-08 23:03:00 UTC (rev 8652)
@@ -98,21 +98,35 @@
/* Has this SO ever been sent on? */
Bool libhb_so_everSent ( SO* so );
-/* Memory accesses (1/2/4/8 byte size). Returns True if this access
- resulted in a reportable race, in which case the details are placed
- in *ri. If False is returned, the contents of *ri are unspecified
- and should not be consulted. */
-void libhb_write_1 ( Thr* thr, Addr a );
-void libhb_write_2 ( Thr* thr, Addr a );
-void libhb_write_4 ( Thr* thr, Addr a );
-void libhb_write_8 ( Thr* thr, Addr a );
-void libhb_write_N ( Thr* thr, Addr a, SizeT szB );
-void libhb_read_1 ( Thr* thr, Addr a );
-void libhb_read_2 ( Thr* thr, Addr a );
-void libhb_read_4 ( Thr* thr, Addr a );
-void libhb_read_8 ( Thr* thr, Addr a );
-void libhb_read_N ( Thr* thr, Addr a, SizeT szB );
+/* Memory accesses (1/2/4/8 byte size). They report a race if one is
+ found. */
+#define LIBHB_WRITE_1(_thr,_a) zsm_apply8___msm_write((_thr),(_a))
+#define LIBHB_WRITE_2(_thr,_a) zsm_apply16___msm_write((_thr),(_a))
+#define LIBHB_WRITE_4(_thr,_a) zsm_apply32___msm_write((_thr),(_a))
+#define LIBHB_WRITE_8(_thr,_a) zsm_apply64___msm_write((_thr),(_a))
+#define LIBHB_WRITE_N(_thr,_a,_n) zsm_apply_range___msm_read((_thr),(_a),(_n))
+#define LIBHB_READ_1(_thr,_a) zsm_apply8___msm_read((_thr),(_a))
+#define LIBHB_READ_2(_thr,_a) zsm_apply16___msm_read((_thr),(_a))
+#define LIBHB_READ_4(_thr,_a) zsm_apply32___msm_read((_thr),(_a))
+#define LIBHB_READ_8(_thr,_a) zsm_apply64___msm_read((_thr),(_a))
+#define LIBHB_READ_N(_thr,_a,_n) zsm_apply_range___msm_read((_thr),(_a),(_n))
+
+void zsm_apply8___msm_write ( Thr* thr, Addr a );
+void zsm_apply16___msm_write ( Thr* thr, Addr a );
+void zsm_apply32___msm_write ( Thr* thr, Addr a );
+void zsm_apply64___msm_write ( Thr* thr, Addr a );
+void zsm_apply_range___msm_write ( Thr* thr,
+ Addr a, SizeT len );
+
+void zsm_apply8___msm_read ( Thr* thr, Addr a );
+void zsm_apply16___msm_read ( Thr* thr, Addr a );
+void zsm_apply32___msm_read ( Thr* thr, Addr a );
+void zsm_apply64___msm_read ( Thr* thr, Addr a );
+void zsm_apply_range___msm_read ( Thr* thr,
+ Addr a, SizeT len );
+
+
/* Set memory address ranges to new (freshly allocated), or noaccess
(no longer accessible). */
void libhb_range_new ( Thr*, Addr, SizeT );
Modified: branches/YARD/helgrind/libhb_core.c
===================================================================
--- branches/YARD/helgrind/libhb_core.c 2008-10-08 21:55:49 UTC (rev 8651)
+++ branches/YARD/helgrind/libhb_core.c 2008-10-08 23:03:00 UTC (rev 8652)
@@ -3228,7 +3228,6 @@
/*------------- ZSM accesses: 8 bit apply ------------- */
-static
void zsm_apply8___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3252,7 +3251,6 @@
cl->svals[cloff] = svNew;
}
-static
void zsm_apply8___msm_write ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3278,7 +3276,6 @@
/*------------- ZSM accesses: 16 bit apply ------------- */
-static
void zsm_apply16___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3312,7 +3309,6 @@
zsm_apply8___msm_read( thr, a + 1 );
}
-static
void zsm_apply16___msm_write ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3348,7 +3344,6 @@
/*------------- ZSM accesses: 32 bit apply ------------- */
-static
void zsm_apply32___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3381,7 +3376,6 @@
zsm_apply16___msm_read( thr, a + 2 );
}
-static
void zsm_apply32___msm_write ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3416,7 +3410,6 @@
/*------------- ZSM accesses: 64 bit apply ------------- */
-static
void zsm_apply64___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3443,7 +3436,6 @@
zsm_apply32___msm_read( thr, a + 4 );
}
-static
void zsm_apply64___msm_write ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3633,8 +3625,8 @@
/* ------------ Shadow memory range setting ops ------------ */
-static void zsm_apply_range___msm_read ( Thr* thr,
- Addr a, SizeT len )
+void zsm_apply_range___msm_read ( Thr* thr,
+ Addr a, SizeT len )
{
/* fast track a couple of common cases */
if (len == 4 && aligned32(a)) {
@@ -3712,8 +3704,8 @@
-static void zsm_apply_range___msm_write ( Thr* thr,
- Addr a, SizeT len )
+void zsm_apply_range___msm_write ( Thr* thr,
+ Addr a, SizeT len )
{
/* fast track a couple of common cases */
if (len == 4 && aligned32(a)) {
@@ -4376,58 +4368,6 @@
VG_(printf)("%s","\n");
}
-void libhb_read_1 ( Thr* thr, Addr a ) {
- if(TRACEME(a,1))trace(thr,a,1,"rd-before");
- zsm_apply8___msm_read ( thr, a );
- if(TRACEME(a,1))trace(thr,a,1,"rd-after ");
-}
-void libhb_read_2 ( Thr* thr, Addr a ) {
- if(TRACEME(a,2))trace(thr,a,2,"rd-before");
- zsm_apply16___msm_read ( thr, a );
- if(TRACEME(a,2))trace(thr,a,2,"rd-after ");
-}
-void libhb_read_4 ( Thr* thr, Addr a ) {
- if(TRACEME(a,4))trace(thr,a,4,"rd-before");
- zsm_apply32___msm_read ( thr, a );
- if(TRACEME(a,4))trace(thr,a,4,"rd-after ");
-}
-void libhb_read_8 ( Thr* thr, Addr a ) {
- if(TRACEME(a,8))trace(thr,a,8,"rd-before");
- zsm_apply64___msm_read ( thr, a );
- if(TRACEME(a,8))trace(thr,a,8,"rd-after ");
-}
-void libhb_read_N ( Thr* thr, Addr a, SizeT szB ) {
- if(TRACEME(a,szB))trace(thr,a,szB,"rd-before");
- zsm_apply_range___msm_read ( thr, a, szB );
- if(TRACEME(a,szB))trace(thr,a,szB,"rd-after ");
-}
-
-void libhb_write_1 ( Thr* thr, Addr a ) {
- if(TRACEME(a,1))trace(thr,a,1,"wr-before");
- zsm_apply8___msm_write ( thr, a );
- if(TRACEME(a,1))trace(thr,a,1,"wr-after ");
-}
-void libhb_write_2 ( Thr* thr, Addr a ) {
- if(TRACEME(a,2))trace(thr,a,2,"wr-before");
- zsm_apply16___msm_write ( thr, a );
- if(TRACEME(a,2))trace(thr,a,2,"wr-after ");
-}
-void libhb_write_4 ( Thr* thr, Addr a ) {
- if(TRACEME(a,4))trace(thr,a,4,"wr-before");
- zsm_apply32___msm_write ( thr, a );
- if(TRACEME(a,4))trace(thr,a,4,"wr-after ");
-}
-void libhb_write_8 ( Thr* thr, Addr a ) {
- if(TRACEME(a,8))trace(thr,a,8,"wr-before");
- zsm_apply64___msm_write ( thr, a );
- if(TRACEME(a,8))trace(thr,a,8,"wr-after ");
-}
-void libhb_write_N ( Thr* thr, Addr a, SizeT szB ) {
- if(TRACEME(a,szB))trace(thr,a,szB,"wr-before");
- zsm_apply_range___msm_write ( thr, a, szB );
- if(TRACEME(a,szB))trace(thr,a,szB,"wr-after ");
-}
-
void libhb_range_new ( Thr* thr, Addr a, SizeT szB )
{
SVal sv = SVal__mkC(thr->viW, thr->viW);
|
|
From: Sérgio D. J. <ser...@li...> - 2008-10-08 22:44:40
|
Hi Julian, On Wed, 2008-10-08 at 18:03 +0200, Julian Seward wrote: > > What should I specifically do to get Helgrind working with OpenMP? > > See the attached files. Note that they are for valgrind-3.3.1. Thank you. I've tried to locate those files (or at least the README) in the tar.bz2 package without success. Are they in some specific place, or only you developers have them? :-) > Note also, you really need to run this stuff on x86/amd64; on > ppc32/ppc64 you will get bad results, due to not-good support > for ppc atomic operations (lwarx/stwcx) in Helgrind 3.3.x. > ppc32/ppc64 support will be improved in Helgrind 3.4.x. Right, thanks for the warning. I'll try it first on x86 then, and probably I'll have more questions to ask after my initial tests with Helgrind and OpenMP. By the way, is there an IRC channel or something where I can get in touch with you, guys? I've tried #valgrind on Freenode, but apparently it's not even registered. Regards, -- Sérgio Durigan Júnior Linux on Power Toolchain - Software Engineer Linux Technology Center - LTC IBM Brazil |
|
From: <sv...@va...> - 2008-10-08 22:33:58
|
Author: sewardj
Date: 2008-10-08 22:55:49 +0100 (Wed, 08 Oct 2008)
New Revision: 8651
Log:
Get rid of some dead code and dead types.
Modified:
branches/YARD/helgrind/libhb.h
branches/YARD/helgrind/libhb_core.c
Modified: branches/YARD/helgrind/libhb.h
===================================================================
--- branches/YARD/helgrind/libhb.h 2008-10-08 15:59:59 UTC (rev 8650)
+++ branches/YARD/helgrind/libhb.h 2008-10-08 21:55:49 UTC (rev 8651)
@@ -41,20 +41,13 @@
/* struct _EC will be defined by user at some point. */
typedef struct _EC EC;
-/* Concrete to user: info on races. tidp and wherep are the previous
- (other) access in the race. */
-typedef
- struct { Thr* thr; struct EC_* where; Addr a; SizeT szB; Bool isW;
- Thr* thrp; struct EC_* wherep; }
- RaceInfo;
-
/* Initialise library; returns Thr* for root thread. 'shadow_alloc'
should never return NULL, instead it should simply not return if
they encounter an out-of-memory condition. */
Thr* libhb_init (
void (*get_stacktrace)( Thr*, Addr*, UWord ),
- struct EC_* (*stacktrace_to_EC)( Addr*, UWord ),
- struct EC_* (*get_EC)( Thr* )
+ struct _EC* (*stacktrace_to_EC)( Addr*, UWord ),
+ struct _EC* (*get_EC)( Thr* )
);
/* Shut down the library, and print stats (in fact that's _all_
Modified: branches/YARD/helgrind/libhb_core.c
===================================================================
--- branches/YARD/helgrind/libhb_core.c 2008-10-08 15:59:59 UTC (rev 8650)
+++ branches/YARD/helgrind/libhb_core.c 2008-10-08 21:55:49 UTC (rev 8651)
@@ -57,8 +57,8 @@
Globals needed by other parts of the library. These are set
once at startup and then never changed. */
static void (*main_get_stacktrace)( Thr*, Addr*, UWord ) = NULL;
-static struct EC_* (*main_stacktrace_to_EC)( Addr*, UWord ) = NULL;
-static struct EC_* (*main_get_EC)( Thr* ) = NULL;
+static struct _EC* (*main_stacktrace_to_EC)( Addr*, UWord ) = NULL;
+static struct _EC* (*main_get_EC)( Thr* ) = NULL;
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
@@ -109,11 +109,6 @@
*/
static void zsm_init ( void(*rcinc)(SVal), void(*rcdec)(SVal) );
-static void zsm_apply8 ( Addr, SVal(*)(SVal,void*), void* );
-static void zsm_apply16 ( Addr, SVal(*)(SVal,void*), void* );
-static void zsm_apply32 ( Addr, SVal(*)(SVal,void*), void* );
-static void zsm_apply64 ( Addr, SVal(*)(SVal,void*), void* );
-static void zsm_apply_range ( Addr, SizeT, SVal(*)(SVal,void*), void* );
static void zsm_set_range ( Addr, SizeT, SVal );
static SVal zsm_read8 ( Addr );
static void zsm_copy_range ( Addr, Addr, SizeT );
@@ -2812,7 +2807,7 @@
static
-Bool event_map_lookup ( /*OUT*/struct EC_** resEC,
+Bool event_map_lookup ( /*OUT*/struct _EC** resEC,
/*OUT*/Thr** resThr,
Thr* thr_acc, Addr a )
{
@@ -3054,19 +3049,6 @@
static ULong stats__msm_write = 0;
static ULong stats__msm_write_change = 0;
-typedef
- struct {
- /* IN - RO */
- Thr* acc_thr; /* thread making this access */
- Addr ea; /* address of access */
- /* OUT */
- Bool race; /* caller sets this to False beforehand */
- struct EC_* where; /* only filled in if .race == True */
- struct EC_* wherep;
- Thr* thrp;
- }
- MSMInfo;
-
__attribute__((noinline))
static void record_race_info ( Thr* acc_thr,
Addr acc_addr, SizeT szB, Bool isWrite,
@@ -3074,8 +3056,8 @@
{
Bool found;
Thr* thrp = NULL;
- struct EC_* where = NULL;
- struct EC_* wherep = NULL;
+ struct _EC* where = NULL;
+ struct _EC* wherep = NULL;
where = main_get_EC( acc_thr );
found = event_map_lookup( &wherep, &thrp, acc_thr, acc_addr );
if (found) {
@@ -3247,30 +3229,6 @@
/*------------- ZSM accesses: 8 bit apply ------------- */
static
-void zsm_apply8 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- stats__cline_read8s++;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 .. 7 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
-}
-
-static
void zsm_apply8___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3321,40 +3279,6 @@
/*------------- ZSM accesses: 16 bit apply ------------- */
static
-void zsm_apply16 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- stats__cline_read16s++;
- if (UNLIKELY(!aligned16(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
- if (valid_value_is_below_me_16(descr, toff)) {
- goto slowcase;
- } else {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
- }
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
- return;
- slowcase: /* misaligned, or must go further down the tree */
- stats__cline_16to8splits++;
- zsm_apply8( a + 0, fn, fn_opaque );
- zsm_apply8( a + 1, fn, fn_opaque );
-}
-
-static
void zsm_apply16___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3425,39 +3349,6 @@
/*------------- ZSM accesses: 32 bit apply ------------- */
static
-void zsm_apply32 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- if (UNLIKELY(!aligned32(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 or 4 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
- if (valid_value_is_above_me_32(descr, toff)) {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
- } else {
- goto slowcase;
- }
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
- return;
- slowcase: /* misaligned, or must go further down the tree */
- stats__cline_32to16splits++;
- zsm_apply16( a + 0, fn, fn_opaque );
- zsm_apply16( a + 2, fn, fn_opaque );
-}
-
-static
void zsm_apply32___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -3526,33 +3417,6 @@
/*------------- ZSM accesses: 64 bit apply ------------- */
static
-void zsm_apply64 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- stats__cline_read64s++;
- if (UNLIKELY(!aligned64(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0, unused */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & TREE_DESCR_64) )) {
- goto slowcase;
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
- return;
- slowcase: /* misaligned, or must go further down the tree */
- stats__cline_64to32splits++;
- zsm_apply32( a + 0, fn, fn_opaque );
- zsm_apply32( a + 4, fn, fn_opaque );
-}
-
-static
void zsm_apply64___msm_read ( Thr* thr, Addr a ) {
CacheLine* cl;
UWord cloff, tno, toff;
@@ -4199,8 +4063,8 @@
Thr* libhb_init (
void (*get_stacktrace)( Thr*, Addr*, UWord ),
- struct EC_* (*stacktrace_to_EC)( Addr*, UWord ),
- struct EC_* (*get_EC)( Thr* )
+ struct _EC* (*stacktrace_to_EC)( Addr*, UWord ),
+ struct _EC* (*get_EC)( Thr* )
)
{
Thr* thr;
@@ -4538,9 +4402,6 @@
if(TRACEME(a,szB))trace(thr,a,szB,"rd-after ");
}
-
-
-
void libhb_write_1 ( Thr* thr, Addr a ) {
if(TRACEME(a,1))trace(thr,a,1,"wr-before");
zsm_apply8___msm_write ( thr, a );
@@ -4567,14 +4428,6 @@
if(TRACEME(a,szB))trace(thr,a,szB,"wr-after ");
}
-
-
-
-
-
-
-
-
void libhb_range_new ( Thr* thr, Addr a, SizeT szB )
{
SVal sv = SVal__mkC(thr->viW, thr->viW);
|
|
From: Julian S. <js...@ac...> - 2008-10-08 16:15:06
|
> What should I specifically do to get Helgrind working with OpenMP? See the attached files. Note that they are for valgrind-3.3.1. Note also, you really need to run this stuff on x86/amd64; on ppc32/ppc64 you will get bad results, due to not-good support for ppc atomic operations (lwarx/stwcx) in Helgrind 3.3.x. ppc32/ppc64 support will be improved in Helgrind 3.4.x. J |
|
From: <sv...@va...> - 2008-10-08 16:00:09
|
Author: sewardj
Date: 2008-10-08 16:59:59 +0100 (Wed, 08 Oct 2008)
New Revision: 8650
Log:
Specialise {load,store}_{1,2,4,8,N} fast-case load/store handlers and
remove reading and writing of MSMInfo and RaceInfo structures. This
increases performance of simple non-threaded code by about 50%.
Modified:
branches/YARD/helgrind/hg_main.c
branches/YARD/helgrind/libhb.h
branches/YARD/helgrind/libhb_core.c
Modified: branches/YARD/helgrind/hg_main.c
===================================================================
--- branches/YARD/helgrind/hg_main.c 2008-10-06 06:36:59 UTC (rev 8649)
+++ branches/YARD/helgrind/hg_main.c 2008-10-08 15:59:59 UTC (rev 8650)
@@ -1052,25 +1052,15 @@
static void shadow_mem_read_range ( Thread* thr, Addr a, SizeT len )
{
- RaceInfo ri;
Thr* hbthr = thr->hbthr;
tl_assert(hbthr);
- if (libhb_read(&ri, hbthr, a, len)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_read_N(hbthr, a, len);
}
static void shadow_mem_write_range ( Thread* thr, Addr a, SizeT len ) {
- RaceInfo ri;
Thr* hbthr = thr->hbthr;
tl_assert(hbthr);
- if (libhb_write(&ri, hbthr, a, len)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_write_N(hbthr, a, len);
}
static void shadow_mem_make_New ( Thread* thr, Addr a, SizeT len )
@@ -1739,122 +1729,72 @@
static VG_REGPARM(1)
void evh__mem_help_read_1(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_read(&ri, hbthr, a, 1)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_read_1(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_read_2(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_read(&ri, hbthr, a, 2)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_read_2(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_read_4(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_read(&ri, hbthr, a, 4)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_read_4(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_read_8(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_read(&ri, hbthr, a, 8)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_read_8(hbthr, a);
}
static VG_REGPARM(2)
void evh__mem_help_read_N(Addr a, SizeT size) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_read(&ri, hbthr, a, size)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_read_N(hbthr, a, size);
}
static VG_REGPARM(1)
void evh__mem_help_write_1(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_write(&ri, hbthr, a, 1)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_write_1(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_write_2(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_write(&ri, hbthr, a, 2)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_write_2(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_write_4(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_write(&ri, hbthr, a, 4)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_write_4(hbthr, a);
}
static VG_REGPARM(1)
void evh__mem_help_write_8(Addr a) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_write(&ri, hbthr, a, 8)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_write_8(hbthr, a);
}
static VG_REGPARM(2)
void evh__mem_help_write_N(Addr a, SizeT size) {
- RaceInfo ri;
Thread* thr = get_current_Thread_in_C_C();
Thr* hbthr = thr->hbthr;
- if (libhb_write(&ri, hbthr, a, size)) {
- Thread* confthr = ri.thrp ? libhb_get_Thr_opaque( ri.thrp ) : NULL;
- HG_(record_error_Race)( thr, ri.a, ri.isW, ri.szB, NULL,
- (ExeContext*)ri.wherep, confthr );
- }
+ libhb_write_N(hbthr, a, size);
}
static void evh__bus_lock(void) {
Modified: branches/YARD/helgrind/libhb.h
===================================================================
--- branches/YARD/helgrind/libhb.h 2008-10-06 06:36:59 UTC (rev 8649)
+++ branches/YARD/helgrind/libhb.h 2008-10-08 15:59:59 UTC (rev 8650)
@@ -109,8 +109,16 @@
resulted in a reportable race, in which case the details are placed
in *ri. If False is returned, the contents of *ri are unspecified
and should not be consulted. */
-Bool libhb_write ( /*OUT*/RaceInfo* ri, Thr* thr, Addr a, SizeT szB );
-Bool libhb_read ( /*OUT*/RaceInfo* ri, Thr* thr, Addr a, SizeT szB );
+void libhb_write_1 ( Thr* thr, Addr a );
+void libhb_write_2 ( Thr* thr, Addr a );
+void libhb_write_4 ( Thr* thr, Addr a );
+void libhb_write_8 ( Thr* thr, Addr a );
+void libhb_write_N ( Thr* thr, Addr a, SizeT szB );
+void libhb_read_1 ( Thr* thr, Addr a );
+void libhb_read_2 ( Thr* thr, Addr a );
+void libhb_read_4 ( Thr* thr, Addr a );
+void libhb_read_8 ( Thr* thr, Addr a );
+void libhb_read_N ( Thr* thr, Addr a, SizeT szB );
/* Set memory address ranges to new (freshly allocated), or noaccess
(no longer accessible). */
Modified: branches/YARD/helgrind/libhb_core.c
===================================================================
--- branches/YARD/helgrind/libhb_core.c 2008-10-06 06:36:59 UTC (rev 8649)
+++ branches/YARD/helgrind/libhb_core.c 2008-10-08 15:59:59 UTC (rev 8650)
@@ -43,10 +43,12 @@
#include "pub_tool_threadstate.h"
#include "pub_tool_aspacemgr.h"
#include "pub_tool_execontext.h"
+#include "pub_tool_errormgr.h"
#include "hg_basics.h"
#include "hg_wordset.h"
#include "hg_lock_n_thread.h"
+#include "hg_errors.h"
#include "libhb.h"
@@ -1458,590 +1460,8 @@
}
}
-static
-void zsm_apply8 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- stats__cline_read8s++;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 .. 7 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
-}
+/* ------------ Cache management ------------ */
-static
-void zsm_apply16 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- stats__cline_read16s++;
- if (UNLIKELY(!aligned16(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
- if (valid_value_is_below_me_16(descr, toff)) {
- goto slowcase;
- } else {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
- }
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
- return;
- slowcase: /* misaligned, or must go further down the tree */
- stats__cline_16to8splits++;
- zsm_apply8( a + 0, fn, fn_opaque );
- zsm_apply8( a + 1, fn, fn_opaque );
-}
-
-__attribute__((noinline))
-static
-void zsm_apply32_SLOW ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- if (UNLIKELY(!aligned32(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 or 4 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
- if (valid_value_is_above_me_32(descr, toff)) {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
- } else {
- goto slowcase;
- }
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
- return;
- slowcase: /* misaligned, or must go further down the tree */
- stats__cline_32to16splits++;
- zsm_apply16( a + 0, fn, fn_opaque );
- zsm_apply16( a + 2, fn, fn_opaque );
-}
-
-static
-void zsm_apply32 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- UShort descr;
- stats__cline_read32s++;
- if (UNLIKELY(!aligned32(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 or 4 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) goto slowcase;
- { SVal* p = &cl->svals[cloff];
- SVal svOld = *p;
- SVal svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- *p = svNew;
- }
- return;
- slowcase: /* misaligned, or not at this level in the tree */
- zsm_apply32_SLOW( a, fn, fn_opaque );
-}
-
-static
-void zsm_apply64 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- SVal svOld, svNew;
- UShort descr;
- stats__cline_read64s++;
- if (UNLIKELY(!aligned64(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0, unused */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & TREE_DESCR_64) )) {
- goto slowcase;
- }
- svOld = cl->svals[cloff];
- svNew = fn( svOld, fn_opaque );
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
- return;
- slowcase: /* misaligned, or must go further down the tree */
- stats__cline_64to32splits++;
- zsm_apply32( a + 0, fn, fn_opaque );
- zsm_apply32( a + 4, fn, fn_opaque );
-}
-
-static
-void zsm_write8 ( Addr a, SVal svNew ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- UShort descr;
- stats__cline_set8s++;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 .. 7 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff] = svNew;
-}
-
-static
-void zsm_write16 ( Addr a, SVal svNew ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- UShort descr;
- stats__cline_set16s++;
- if (UNLIKELY(!aligned16(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
- if (valid_value_is_below_me_16(descr, toff)) {
- /* Writing at this level. Need to fix up 'descr'. */
- cl->descrs[tno] = pullup_descr_to_16(descr, toff);
- /* At this point, the tree does not match cl->descr[tno] any
- more. The assignments below will fix it up. */
- } else {
- /* We can't indiscriminately write on the w16 node as in the
- w64 case, as that might make the node inconsistent with
- its parent. So first, pull down to this level. */
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- }
- }
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff + 0] = svNew;
- cl->svals[cloff + 1] = SVal_INVALID;
- return;
- slowcase: /* misaligned */
- stats__cline_16to8splits++;
- zsm_write8( a + 0, svNew );
- zsm_write8( a + 1, svNew );
-}
-
-static
-void zsm_write32 ( Addr a, SVal svNew ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- UShort descr;
- stats__cline_set32s++;
- if (UNLIKELY(!aligned32(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 or 4 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
- if (valid_value_is_above_me_32(descr, toff)) {
- /* We can't indiscriminately write on the w32 node as in the
- w64 case, as that might make the node inconsistent with
- its parent. So first, pull down to this level. */
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
- if (SCE_CACHELINE)
- tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
- } else {
- /* Writing at this level. Need to fix up 'descr'. */
- cl->descrs[tno] = pullup_descr_to_32(descr, toff);
- /* At this point, the tree does not match cl->descr[tno] any
- more. The assignments below will fix it up. */
- }
- }
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff + 0] = svNew;
- cl->svals[cloff + 1] = SVal_INVALID;
- cl->svals[cloff + 2] = SVal_INVALID;
- cl->svals[cloff + 3] = SVal_INVALID;
- return;
- slowcase: /* misaligned */
- stats__cline_32to16splits++;
- zsm_write16( a + 0, svNew );
- zsm_write16( a + 2, svNew );
-}
-
-static
-void zsm_write64 ( Addr a, SVal svNew ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- stats__cline_set64s++;
- if (UNLIKELY(!aligned64(a))) goto slowcase;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 */
- cl->descrs[tno] = TREE_DESCR_64;
- tl_assert(svNew != SVal_INVALID);
- cl->svals[cloff + 0] = svNew;
- cl->svals[cloff + 1] = SVal_INVALID;
- cl->svals[cloff + 2] = SVal_INVALID;
- cl->svals[cloff + 3] = SVal_INVALID;
- cl->svals[cloff + 4] = SVal_INVALID;
- cl->svals[cloff + 5] = SVal_INVALID;
- cl->svals[cloff + 6] = SVal_INVALID;
- cl->svals[cloff + 7] = SVal_INVALID;
- return;
- slowcase: /* misaligned */
- stats__cline_64to32splits++;
- zsm_write32( a + 0, svNew );
- zsm_write32( a + 4, svNew );
-}
-
-static
-SVal zsm_read8 ( Addr a ) {
- CacheLine* cl;
- UWord cloff, tno, toff;
- UShort descr;
- stats__cline_get8s++;
- cl = get_cacheline(a);
- cloff = get_cacheline_offset(a);
- tno = get_treeno(a);
- toff = get_tree_offset(a); /* == 0 .. 7 */
- descr = cl->descrs[tno];
- if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
- SVal* tree = &cl->svals[tno << 3];
- cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
- }
- return cl->svals[cloff];
-}
-
-static void zsm_copy8 ( Addr src, Addr dst, Bool uu_normalise ) {
- SVal sv;
- stats__cline_copy8s++;
- sv = zsm_read8( src );
- zsm_write8( dst, sv );
-}
-
-/* ------------ Shadow memory range setting ops ------------ */
-
-/* Apply 'fn' to SVals in the given range. */
-
-static void zsm_apply_range ( Addr a, SizeT len,
- SVal(*fn)(SVal,void*), void* fn_opaque )
-{
- /* fast track a couple of common cases */
- if (len == 4 && aligned32(a)) {
- zsm_apply32( a, fn, fn_opaque );
- return;
- }
- if (len == 8 && aligned64(a)) {
- zsm_apply64( a, fn, fn_opaque );
- return;
- }
-
- /* be completely general (but as efficient as possible) */
- if (len == 0) return;
-
- if (!aligned16(a) && len >= 1) {
- zsm_apply8( a, fn, fn_opaque );
- a += 1;
- len -= 1;
- tl_assert(aligned16(a));
- }
- if (len == 0) return;
-
- if (!aligned32(a) && len >= 2) {
- zsm_apply16( a, fn, fn_opaque );
- a += 2;
- len -= 2;
- tl_assert(aligned32(a));
- }
- if (len == 0) return;
-
- if (!aligned64(a) && len >= 4) {
- zsm_apply32( a, fn, fn_opaque );
- a += 4;
- len -= 4;
- tl_assert(aligned64(a));
- }
- if (len == 0) return;
-
- if (len >= 8) {
- tl_assert(aligned64(a));
- while (len >= 8) {
- zsm_apply64( a, fn, fn_opaque );
- a += 8;
- len -= 8;
- }
- tl_assert(aligned64(a));
- }
- if (len == 0) return;
-
- if (len >= 4)
- tl_assert(aligned32(a));
- if (len >= 4) {
- zsm_apply32( a, fn, fn_opaque );
- a += 4;
- len -= 4;
- }
- if (len == 0) return;
-
- if (len >= 2)
- tl_assert(aligned16(a));
- if (len >= 2) {
- zsm_apply16( a, fn, fn_opaque );
- a += 2;
- len -= 2;
- }
- if (len == 0) return;
-
- if (len >= 1) {
- zsm_apply8( a, fn, fn_opaque );
- a += 1;
- len -= 1;
- }
- tl_assert(len == 0);
-}
-
-/* Block-copy states (needed for implementing realloc()). */
-
-static void zsm_copy_range ( Addr src, Addr dst, SizeT len )
-{
- SizeT i;
- if (len == 0)
- return;
-
- /* assert for non-overlappingness */
- tl_assert(src+len <= dst || dst+len <= src);
-
- /* To be simple, just copy byte by byte. But so as not to wreck
- performance for later accesses to dst[0 .. len-1], normalise
- destination lines as we finish with them, and also normalise the
- line containing the first and last address. */
- for (i = 0; i < len; i++) {
- Bool normalise
- = get_cacheline_offset( dst+i+1 ) == 0 /* last in line */
- || i == 0 /* first in range */
- || i == len-1; /* last in range */
- zsm_copy8( src+i, dst+i, normalise );
- }
-}
-
-
-/* For setting address ranges to a given value. Has considerable
- sophistication so as to avoid generating large numbers of pointless
- cache loads/writebacks for large ranges. */
-
-/* Do small ranges in-cache, in the obvious way. */
-static
-void zsm_set_range_SMALL ( Addr a, SizeT len, SVal svNew )
-{
- /* fast track a couple of common cases */
- if (len == 4 && aligned32(a)) {
- zsm_write32( a, svNew );
- return;
- }
- if (len == 8 && aligned64(a)) {
- zsm_write64( a, svNew );
- return;
- }
-
- /* be completely general (but as efficient as possible) */
- if (len == 0) return;
-
- if (!aligned16(a) && len >= 1) {
- zsm_write8( a, svNew );
- a += 1;
- len -= 1;
- tl_assert(aligned16(a));
- }
- if (len == 0) return;
-
- if (!aligned32(a) && len >= 2) {
- zsm_write16( a, svNew );
- a += 2;
- len -= 2;
- tl_assert(aligned32(a));
- }
- if (len == 0) return;
-
- if (!aligned64(a) && len >= 4) {
- zsm_write32( a, svNew );
- a += 4;
- len -= 4;
- tl_assert(aligned64(a));
- }
- if (len == 0) return;
-
- if (len >= 8) {
- tl_assert(aligned64(a));
- while (len >= 8) {
- zsm_write64( a, svNew );
- a += 8;
- len -= 8;
- }
- tl_assert(aligned64(a));
- }
- if (len == 0) return;
-
- if (len >= 4)
- tl_assert(aligned32(a));
- if (len >= 4) {
- zsm_write32( a, svNew );
- a += 4;
- len -= 4;
- }
- if (len == 0) return;
-
- if (len >= 2)
- tl_assert(aligned16(a));
- if (len >= 2) {
- zsm_write16( a, svNew );
- a += 2;
- len -= 2;
- }
- if (len == 0) return;
-
- if (len >= 1) {
- zsm_write8( a, svNew );
- a += 1;
- len -= 1;
- }
- tl_assert(len == 0);
-}
-
-
-/* If we're doing a small range, hand off to zsm_set_range_SMALL. But
- for larger ranges, try to operate directly on the out-of-cache
- representation, rather than dragging lines into the cache,
- overwriting them, and forcing them out. This turns out to be an
- important performance optimisation. */
-
-static void zsm_set_range ( Addr a, SizeT len, SVal svNew )
-{
- tl_assert(svNew != SVal_INVALID);
- stats__cache_make_New_arange += (ULong)len;
-
- if (0 && len > 500)
- VG_(printf)("make New ( %#lx, %ld )\n", a, len );
-
- if (0) {
- static UWord n_New_in_cache = 0;
- static UWord n_New_not_in_cache = 0;
- /* tag is 'a' with the in-line offset masked out,
- eg a[31]..a[4] 0000 */
- Addr tag = a & ~(N_LINE_ARANGE - 1);
- UWord wix = (a >> N_LINE_BITS) & (N_WAY_NENT - 1);
- if (LIKELY(tag == cache_shmem.tags0[wix])) {
- n_New_in_cache++;
- } else {
- n_New_not_in_cache++;
- }
- if (0 == ((n_New_in_cache + n_New_not_in_cache) % 100000))
- VG_(printf)("shadow_mem_make_New: IN %lu OUT %lu\n",
- n_New_in_cache, n_New_not_in_cache );
- }
-
- if (LIKELY(len < 2 * N_LINE_ARANGE)) {
- zsm_set_range_SMALL( a, len, svNew );
- } else {
- Addr before_start = a;
- Addr aligned_start = cacheline_ROUNDUP(a);
- Addr after_start = cacheline_ROUNDDN(a + len);
- UWord before_len = aligned_start - before_start;
- UWord aligned_len = after_start - aligned_start;
- UWord after_len = a + len - after_start;
- tl_assert(before_start <= aligned_start);
- tl_assert(aligned_start <= after_start);
- tl_assert(before_len < N_LINE_ARANGE);
- tl_assert(after_len < N_LINE_ARANGE);
- tl_assert(get_cacheline_offset(aligned_start) == 0);
- if (get_cacheline_offset(a) == 0) {
- tl_assert(before_len == 0);
- tl_assert(a == aligned_start);
- }
- if (get_cacheline_offset(a+len) == 0) {
- tl_assert(after_len == 0);
- tl_assert(after_start == a+len);
- }
- if (before_len > 0) {
- zsm_set_range_SMALL( before_start, before_len, svNew );
- }
- if (after_len > 0) {
- zsm_set_range_SMALL( after_start, after_len, svNew );
- }
- stats__cache_make_New_inZrep += (ULong)aligned_len;
-
- while (1) {
- Addr tag;
- UWord wix;
- if (aligned_start >= after_start)
- break;
- tl_assert(get_cacheline_offset(aligned_start) == 0);
- tag = aligned_start & ~(N_LINE_ARANGE - 1);
- wix = (aligned_start >> N_LINE_BITS) & (N_WAY_NENT - 1);
- if (tag == cache_shmem.tags0[wix]) {
- UWord i;
- for (i = 0; i < N_LINE_ARANGE / 8; i++)
- zsm_write64( aligned_start + i * 8, svNew );
- } else {
- UWord i;
- Word zix;
- SecMap* sm;
- LineZ* lineZ;
- /* This line is not in the cache. Do not force it in; instead
- modify it in-place. */
- /* find the Z line to write in and rcdec it or the
- associated F line. */
- find_Z_for_writing( &sm, &zix, tag );
- tl_assert(sm);
- tl_assert(zix >= 0 && zix < N_SECMAP_ZLINES);
- lineZ = &sm->linesZ[zix];
- lineZ->dict[0] = svNew;
- lineZ->dict[1] = lineZ->dict[2] = lineZ->dict[3] = SVal_INVALID;
- for (i = 0; i < N_LINE_ARANGE/4; i++)
- lineZ->ix2s[i] = 0; /* all refer to dict[0] */
- rcinc_LineZ(lineZ);
- }
- aligned_start += N_LINE_ARANGE;
- aligned_len -= N_LINE_ARANGE;
- }
- tl_assert(aligned_start == after_start);
- tl_assert(aligned_len == 0);
- }
-}
-
-
static void zsm_flush_cache ( void )
{
shmem__flush_and_invalidate_scache();
@@ -3300,7 +2720,7 @@
static UWord oldrefTreeN = 0; /* # elems in oldrefTree */
static UWord oldrefGenIncAt = 0; /* inc gen # when size hits this */
-static void event_map_bind ( Addr a, struct EC_* ecxx, Thr* thr )
+static void event_map_bind ( Addr a, Thr* thr )
{
OldRef key, *ref;
RCEC* here;
@@ -3647,25 +3067,32 @@
}
MSMInfo;
-static void record_race_info ( /*MOD*/MSMInfo* info, SVal svOld, SVal svNew )
+__attribute__((noinline))
+static void record_race_info ( Thr* acc_thr,
+ Addr acc_addr, SizeT szB, Bool isWrite,
+ SVal svOld, SVal svNew )
{
+ Bool found;
+ Thr* thrp = NULL;
+ struct EC_* where = NULL;
struct EC_* wherep = NULL;
- Thr* thrp = NULL;
- Bool found;
-
- info->where = main_get_EC( info->acc_thr );
-
- found = event_map_lookup( &wherep, &thrp, info->acc_thr, info->ea );
+ where = main_get_EC( acc_thr );
+ found = event_map_lookup( &wherep, &thrp, acc_thr, acc_addr );
if (found) {
- tl_assert(wherep);
- tl_assert(thrp);
- info->wherep = wherep;
- info->thrp = thrp;
+ tl_assert(wherep);
+ tl_assert(thrp);
+ tl_assert(thrp->opaque);
+ tl_assert(acc_thr->opaque);
+ HG_(record_error_Race)( acc_thr->opaque, acc_addr,
+ isWrite, szB, NULL/*mb_lastlock*/,
+ wherep, thrp->opaque );
} else {
- tl_assert(!wherep);
- tl_assert(!thrp);
- info->wherep = NULL;
- info->thrp = NULL;
+ tl_assert(!wherep);
+ tl_assert(!thrp);
+ tl_assert(acc_thr->opaque);
+ HG_(record_error_Race)( acc_thr->opaque, acc_addr,
+ isWrite, szB, NULL/*mb_lastlock*/,
+ NULL, NULL );
}
}
@@ -3677,9 +3104,13 @@
return False;
}
-/* Direct callback from lib_zsm. */
+
/* Compute new state following a read */
-static SVal msm_read ( SVal svOld, /*MOD*/MSMInfo* info )
+static inline SVal msm_read ( SVal svOld,
+ /* The following are only needed for
+ creating error reports. */
+ Thr* acc_thr,
+ Addr acc_addr, SizeT szB )
{
SVal svNew = SVal_INVALID;
stats__msm_read++;
@@ -3691,8 +3122,8 @@
if (SVal__isC(svOld)) {
POrd ord;
- VtsID tviR = info->acc_thr->viR;
- VtsID tviW = info->acc_thr->viW;
+ VtsID tviR = acc_thr->viR;
+ VtsID tviW = acc_thr->viW;
VtsID rmini = SVal__unC_Rmin(svOld);
VtsID wmini = SVal__unC_Wmin(svOld);
@@ -3706,10 +3137,8 @@
svNew = MSM_RACE2ERR
? SVal__mkE()
: SVal__mkC( rmini, VtsID__join2(wmini,tviR) );
- if (!info->race) {
- info->race = True;
- record_race_info( info, svOld, svNew );
- }
+ record_race_info( acc_thr, acc_addr, szB, False/*!isWrite*/,
+ svOld, svNew );
goto out;
}
}
@@ -3735,17 +3164,20 @@
tl_assert(svNew != SVal_INVALID);
if (svNew != svOld) {
if (MSM_CONFACC && SVal__isC(svOld) && SVal__isC(svNew)) {
- struct EC_* ec = NULL; //main_get_EC( info->acc_thr );
- event_map_bind( info->ea, ec, info->acc_thr );
+ event_map_bind( acc_addr, acc_thr );
stats__msm_read_change++;
}
}
return svNew;
}
-/* Direct callback from lib_zsm. */
+
/* Compute new state following a write */
-static SVal msm_write ( SVal svOld, /*MOD*/MSMInfo* info )
+static inline SVal msm_write ( SVal svOld,
+ /* The following are only needed for
+ creating error reports. */
+ Thr* acc_thr,
+ Addr acc_addr, SizeT szB )
{
SVal svNew = SVal_INVALID;
stats__msm_write++;
@@ -3757,7 +3189,7 @@
if (SVal__isC(svOld)) {
POrd ord;
- VtsID tviW = info->acc_thr->viW;
+ VtsID tviW = acc_thr->viW;
VtsID wmini = SVal__unC_Wmin(svOld);
ord = VtsID__getOrdering(wmini,tviW);
@@ -3771,10 +3203,8 @@
? SVal__mkE()
: SVal__mkC( VtsID__join2(rmini,tviW),
VtsID__join2(wmini,tviW) );
- if (!info->race) {
- info->race = True;
- record_race_info( info, svOld, svNew );
- }
+ record_race_info( acc_thr, acc_addr, szB, True/*isWrite*/,
+ svOld, svNew );
goto out;
}
}
@@ -3800,8 +3230,7 @@
tl_assert(svNew != SVal_INVALID);
if (svNew != svOld) {
if (MSM_CONFACC && SVal__isC(svOld) && SVal__isC(svNew)) {
- struct EC_* ec = NULL; //main_get_EC( info->acc_thr );
- event_map_bind( info->ea, ec, info->acc_thr );
+ event_map_bind( acc_addr, acc_thr );
stats__msm_write_change++;
}
}
@@ -3811,6 +3240,905 @@
/////////////////////////////////////////////////////////
// //
+// Apply core MSM to specific memory locations //
+// //
+/////////////////////////////////////////////////////////
+
+/*------------- ZSM accesses: 8 bit apply ------------- */
+
+static
+void zsm_apply8 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read8s++;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 .. 7 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = fn( svOld, fn_opaque );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+}
+
+static
+void zsm_apply8___msm_read ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read8s++;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 .. 7 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_read( svOld, thr,a,1 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+}
+
+static
+void zsm_apply8___msm_write ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read8s++;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 .. 7 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_write( svOld, thr,a,1 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+}
+
+/*------------- ZSM accesses: 16 bit apply ------------- */
+
+static
+void zsm_apply16 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read16s++;
+ if (UNLIKELY(!aligned16(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
+ if (valid_value_is_below_me_16(descr, toff)) {
+ goto slowcase;
+ } else {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
+ }
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = fn( svOld, fn_opaque );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_16to8splits++;
+ zsm_apply8( a + 0, fn, fn_opaque );
+ zsm_apply8( a + 1, fn, fn_opaque );
+}
+
+static
+void zsm_apply16___msm_read ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read16s++;
+ if (UNLIKELY(!aligned16(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
+ if (valid_value_is_below_me_16(descr, toff)) {
+ goto slowcase;
+ } else {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
+ }
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_read( svOld, thr,a,2 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_16to8splits++;
+ zsm_apply8___msm_read( thr, a + 0 );
+ zsm_apply8___msm_read( thr, a + 1 );
+}
+
+static
+void zsm_apply16___msm_write ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read16s++;
+ if (UNLIKELY(!aligned16(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
+ if (valid_value_is_below_me_16(descr, toff)) {
+ goto slowcase;
+ } else {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
+ }
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_write( svOld, thr,a,2 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_16to8splits++;
+ zsm_apply8___msm_write( thr, a + 0 );
+ zsm_apply8___msm_write( thr, a + 1 );
+}
+
+/*------------- ZSM accesses: 32 bit apply ------------- */
+
+static
+void zsm_apply32 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ if (UNLIKELY(!aligned32(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 or 4 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
+ if (valid_value_is_above_me_32(descr, toff)) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
+ } else {
+ goto slowcase;
+ }
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = fn( svOld, fn_opaque );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_32to16splits++;
+ zsm_apply16( a + 0, fn, fn_opaque );
+ zsm_apply16( a + 2, fn, fn_opaque );
+}
+
+static
+void zsm_apply32___msm_read ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ if (UNLIKELY(!aligned32(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 or 4 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
+ if (valid_value_is_above_me_32(descr, toff)) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
+ } else {
+ goto slowcase;
+ }
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_read( svOld, thr,a,4 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_32to16splits++;
+ zsm_apply16___msm_read( thr, a + 0 );
+ zsm_apply16___msm_read( thr, a + 2 );
+}
+
+static
+void zsm_apply32___msm_write ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ if (UNLIKELY(!aligned32(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 or 4 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
+ if (valid_value_is_above_me_32(descr, toff)) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
+ } else {
+ goto slowcase;
+ }
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_write( svOld, thr,a,4 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_32to16splits++;
+ zsm_apply16___msm_write( thr, a + 0 );
+ zsm_apply16___msm_write( thr, a + 2 );
+}
+
+/*------------- ZSM accesses: 64 bit apply ------------- */
+
+static
+void zsm_apply64 ( Addr a, SVal(*fn)(SVal,void*), void* fn_opaque ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read64s++;
+ if (UNLIKELY(!aligned64(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, unused */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & TREE_DESCR_64) )) {
+ goto slowcase;
+ }
+ svOld = cl->svals[cloff];
+ svNew = fn( svOld, fn_opaque );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_64to32splits++;
+ zsm_apply32( a + 0, fn, fn_opaque );
+ zsm_apply32( a + 4, fn, fn_opaque );
+}
+
+static
+void zsm_apply64___msm_read ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read64s++;
+ if (UNLIKELY(!aligned64(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, unused */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & TREE_DESCR_64) )) {
+ goto slowcase;
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_read( svOld, thr,a,8 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_64to32splits++;
+ zsm_apply32___msm_read( thr, a + 0 );
+ zsm_apply32___msm_read( thr, a + 4 );
+}
+
+static
+void zsm_apply64___msm_write ( Thr* thr, Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ SVal svOld, svNew;
+ UShort descr;
+ stats__cline_read64s++;
+ if (UNLIKELY(!aligned64(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, unused */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & TREE_DESCR_64) )) {
+ goto slowcase;
+ }
+ svOld = cl->svals[cloff];
+ svNew = msm_write( svOld, thr,a,8 );
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+ return;
+ slowcase: /* misaligned, or must go further down the tree */
+ stats__cline_64to32splits++;
+ zsm_apply32___msm_write( thr, a + 0 );
+ zsm_apply32___msm_write( thr, a + 4 );
+}
+
+/*--------------- ZSM accesses: 8 bit write --------------- */
+
+static
+void zsm_write8 ( Addr a, SVal svNew ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ UShort descr;
+ stats__cline_set8s++;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 .. 7 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff] = svNew;
+}
+
+/*--------------- ZSM accesses: 16 bit write --------------- */
+
+static
+void zsm_write16 ( Addr a, SVal svNew ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ UShort descr;
+ stats__cline_set16s++;
+ if (UNLIKELY(!aligned16(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0, 2, 4 or 6 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_16_0 << toff)) )) {
+ if (valid_value_is_below_me_16(descr, toff)) {
+ /* Writing at this level. Need to fix up 'descr'. */
+ cl->descrs[tno] = pullup_descr_to_16(descr, toff);
+ /* At this point, the tree does not match cl->descr[tno] any
+ more. The assignments below will fix it up. */
+ } else {
+ /* We can't indiscriminately write on the w16 node as in the
+ w64 case, as that might make the node inconsistent with
+ its parent. So first, pull down to this level. */
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_16(tree, toff, descr);
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ }
+ }
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff + 0] = svNew;
+ cl->svals[cloff + 1] = SVal_INVALID;
+ return;
+ slowcase: /* misaligned */
+ stats__cline_16to8splits++;
+ zsm_write8( a + 0, svNew );
+ zsm_write8( a + 1, svNew );
+}
+
+/*--------------- ZSM accesses: 32 bit write --------------- */
+
+static
+void zsm_write32 ( Addr a, SVal svNew ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ UShort descr;
+ stats__cline_set32s++;
+ if (UNLIKELY(!aligned32(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 or 4 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_32_0 << toff)) )) {
+ if (valid_value_is_above_me_32(descr, toff)) {
+ /* We can't indiscriminately write on the w32 node as in the
+ w64 case, as that might make the node inconsistent with
+ its parent. So first, pull down to this level. */
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_32(tree, toff, descr);
+ if (SCE_CACHELINE)
+ tl_assert(is_sane_CacheLine(cl)); /* EXPENSIVE */
+ } else {
+ /* Writing at this level. Need to fix up 'descr'. */
+ cl->descrs[tno] = pullup_descr_to_32(descr, toff);
+ /* At this point, the tree does not match cl->descr[tno] any
+ more. The assignments below will fix it up. */
+ }
+ }
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff + 0] = svNew;
+ cl->svals[cloff + 1] = SVal_INVALID;
+ cl->svals[cloff + 2] = SVal_INVALID;
+ cl->svals[cloff + 3] = SVal_INVALID;
+ return;
+ slowcase: /* misaligned */
+ stats__cline_32to16splits++;
+ zsm_write16( a + 0, svNew );
+ zsm_write16( a + 2, svNew );
+}
+
+/*--------------- ZSM accesses: 64 bit write --------------- */
+
+static
+void zsm_write64 ( Addr a, SVal svNew ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ stats__cline_set64s++;
+ if (UNLIKELY(!aligned64(a))) goto slowcase;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 */
+ cl->descrs[tno] = TREE_DESCR_64;
+ tl_assert(svNew != SVal_INVALID);
+ cl->svals[cloff + 0] = svNew;
+ cl->svals[cloff + 1] = SVal_INVALID;
+ cl->svals[cloff + 2] = SVal_INVALID;
+ cl->svals[cloff + 3] = SVal_INVALID;
+ cl->svals[cloff + 4] = SVal_INVALID;
+ cl->svals[cloff + 5] = SVal_INVALID;
+ cl->svals[cloff + 6] = SVal_INVALID;
+ cl->svals[cloff + 7] = SVal_INVALID;
+ return;
+ slowcase: /* misaligned */
+ stats__cline_64to32splits++;
+ zsm_write32( a + 0, svNew );
+ zsm_write32( a + 4, svNew );
+}
+
+/*------------- ZSM accesses: 8 bit read/copy ------------- */
+
+static
+SVal zsm_read8 ( Addr a ) {
+ CacheLine* cl;
+ UWord cloff, tno, toff;
+ UShort descr;
+ stats__cline_get8s++;
+ cl = get_cacheline(a);
+ cloff = get_cacheline_offset(a);
+ tno = get_treeno(a);
+ toff = get_tree_offset(a); /* == 0 .. 7 */
+ descr = cl->descrs[tno];
+ if (UNLIKELY( !(descr & (TREE_DESCR_8_0 << toff)) )) {
+ SVal* tree = &cl->svals[tno << 3];
+ cl->descrs[tno] = pulldown_to_8(tree, toff, descr);
+ }
+ return cl->svals[cloff];
+}
+
+static void zsm_copy8 ( Addr src, Addr dst, Bool uu_normalise ) {
+ SVal sv;
+ stats__cline_copy8s++;
+ sv = zsm_read8( src );
+ zsm_write8( dst, sv );
+}
+
+/* ------------ Shadow memory range setting ops ------------ */
+
+static void zsm_apply_range___msm_read ( Thr* thr,
+ Addr a, SizeT len )
+{
+ /* fast track a couple of common cases */
+ if (len == 4 && aligned32(a)) {
+ zsm_apply32___msm_read( thr, a );
+ return;
+ }
+ if (len == 8 && aligned64(a)) {
+ zsm_apply64___msm_read( thr, a );
+ return;
+ }
+
+ /* be completely general (but as efficient as possible) */
+ if (len == 0) return;
+
+ if (!aligned16(a) && len >= 1) {
+ zsm_apply8___msm_read( thr, a );
+ a += 1;
+ len -= 1;
+ tl_assert(aligned16(a));
+ }
+ if (len == 0) return;
+
+ if (!aligned32(a) && len >= 2) {
+ zsm_apply16___msm_read( thr, a );
+ a += 2;
+ len -= 2;
+ tl_assert(aligned32(a));
+ }
+ if (len == 0) return;
+
+ if (!aligned64(a) && len >= 4) {
+ zsm_apply32___msm_read( thr, a );
+ a += 4;
+ len -= 4;
+ tl_assert(aligned64(a));
+ }
+ if (len == 0) return;
+
+ if (len >= 8) {
+ tl_assert(aligned64(a));
+ while (len >= 8) {
+ zsm_apply64___msm_read( thr, a );
+ a += 8;
+ len -= 8;
+ }
+ tl_assert(aligned64(a));
+ }
+ if (len == 0) return;
+
+ if (len >= 4)
+ tl_assert(aligned32(a));
+ if (len >= 4) {
+ zsm_apply32___msm_read( thr, a );
+ a += 4;
+ len -= 4;
+ }
+ if (len == 0) return;
+
+ if (len >= 2)
+ tl_assert(aligned16(a));
+ if (len >= 2) {
+ zsm_apply16___msm_read( thr, a );
+ a += 2;
+ len -= 2;
+ }
+ if (len == 0) return;
+
+ if (len >= 1) {
+ zsm_apply8___msm_read( thr, a );
+ a += 1;
+ len -= 1;
+ }
+ tl_assert(len == 0);
+}
+
+
+
+static void zsm_apply_range___msm_write ( Thr* thr,
+ Addr a, SizeT len )
+{
+ /* fast track a couple of common cases */
+ if (len == 4 && aligned32(a)) {
+ zsm_apply32___msm_write( thr, a );
+ return;
+ }
+ if (len == 8 && aligned64(a)) {
+ zsm_apply64___msm_write( thr, a );
+ return;
+ }
+
+ /* be completely general (but as efficient as possible) */
+ if (len == 0) return;
+
+ if (!aligned16(a) && len >= 1) {
+ zsm_apply8___msm_write( thr, a );
+ a += 1;
+ len -= 1;
+ tl_assert(aligned16(a));
+ }
+ if (len == 0) return;
+
+ if (!aligned32(a) && len >= 2) {
+ zsm_apply16___msm_write( thr, a );
+ a += 2;
+ len -= 2;
+ tl_assert(aligned32(a));
+ }
+ if (len == 0) return;
+
+ if (!aligned64(a) && len >= 4) {
+ zsm_apply32___msm_write( thr, a );
+ a += 4;
+ len -= 4;
+ tl_assert(aligned64(a));
+ }
+ if (len == 0) return;
+
+ if (len >= 8) {
+ tl_assert(aligned64(a));
+ while (len >= 8) {
+ zsm_apply64___msm_write( thr, a );
+ a += 8;
+ len -= 8;
+ }
+ tl_assert(aligned64(a));
+ }
+ if (len == 0) return;
+
+ if (len >= 4)
+ tl_assert(aligned32(a));
+ if (len >= 4) {
+ zsm_apply32___msm_write( thr, a );
+ a += 4;
+ len -= 4;
+ }
+ if (len == 0) return;
+
+ if (len >= 2)
+ tl_assert(aligned16(a));
+ if (len >= 2) {
+ zsm_apply16___msm_write( thr, a );
+ a += 2;
+ len -= 2;
+ }
+ if (len == 0) return;
+
+ if (len >= 1) {
+ zsm_apply8___msm_write( thr, a );
+ a += 1;
+ len -= 1;
+ }
+ tl_assert(len == 0);
+}
+
+
+
+
+/* Block-copy states (needed for implementing realloc()). */
+
+static void zsm_copy_range ( Addr src, Addr dst, SizeT len )
+{
+ SizeT i;
+ if (len == 0)
+ return;
+
+ /* assert for non-overlappingness */
+ tl_assert(src+len <= dst || dst+len <= src);
+
+ /* To be simple, just copy byte by byte. But so as not to wreck
+ performance for later accesses to dst[0 .. len-1], normalise
+ destination lines as we finish with them, and also normalise the
+ line containing the first and last address. */
+ for (i = 0; i < len; i++) {
+ Bool normalise
+ = get_cacheline_offset( dst+i+1 ) == 0 /* last in line */
+ || i == 0 /* first in range */
+ || i == len-1; /* last in range */
+ zsm_copy8( src+i, dst+i, normalise );
+ }
+}
+
+
+/* For setting address ranges to a given value. Has considerable
+ sophistication so as to avoid generating large numbers of pointless
+ cache loads/writebacks for large ranges. */
+
+/* Do small ranges in-cache, in the obvious way. */
+static
+void zsm_set_range_SMALL ( Addr a, SizeT len, SVal svNew )
+{
+ /* fast track a couple of common cases */
+ if (len == 4 && aligned32(a)) {
+ zsm_write32( a, svNew );
+ return;
+ }
+ if (len == 8 && aligned64(a)) {
+ zsm_write64( a, svNew );
+ return;
+ }
+
+ /* be completely general (but as efficient as possible) */
+ if (len == 0) return;
+
+ if (!aligned16(a) && len >= 1) {
+ zsm_write8( a, svNew );
+ a += 1;
+ len -= 1;
+ tl_assert(aligned16(a));
+ }
+ if (len == 0) return;
+
+ if (!aligned32(a) && len >= 2) {
+ zsm_write16( a, svNew );
+ a += 2;
+ len -= 2;
+ tl_assert(aligned32(a));
+ }
+ if (len == 0) return;
+
+ if (!aligned64(a) && len >= 4) {
+ zsm_write32( a, svNew );
+ a += 4;
+ len -= 4;
+ tl_assert(aligned64(a));
+ }
+ if (len == 0) return;
+
+ if (len >= 8) {
+ tl_assert(aligned64(a));
+ while (len >= 8) {
+ zsm_write64( a, svNew );
+ a += 8;
+ len -= 8;
+ }
+ tl_assert(aligned64(a));
+ }
+ if (len == 0) return;
+
+ if (len >= 4)
+ tl_assert(aligned32(a));
+ if (len >= 4) {
+ zsm_write32( a, svNew );
+ a += 4;
+ len -= 4;
+ }
+ if (len == 0) return;
+
+ if (len >= 2)
+ tl_assert(aligned16(a));
+ if (len >= 2) {
+ zsm_write16( a, svNew );
+ a += 2;
+ len -= 2;
+ }
+ if (len == 0) return;
+
+ if (len >= 1) {
+ zsm_write8( a, svNew );
+ a += 1;
+ len -= 1;
+ }
+ tl_assert(len == 0);
+}
+
+
+/* If we're doing a small range, hand off to zsm_set_range_SMALL. But
+ for larger ranges, try to operate directly on the out-of-cache
+ representation, rather than dragging lines into the cache,
+ overwriting them, and forcing them out. This turns out to be an
+ important performance optimisation. */
+
+static void zsm_set_range ( Addr a, SizeT len, SVal svNew )
+{
+ tl_assert(svNew != SVal_INVALID);
+ stats__cache_make_New_arange += (ULong)len;
+
+ if (0 && len > 500)
+ VG_(printf)("make New ( %#lx, %ld )\n", a, len );
+
+ if (0) {
+ static UWord n_New_in_cache = 0;
+ static UWord n_New_not_in_cache = 0;
+ /* tag is 'a' with the in-line offset masked out,
+ eg a[31]..a[4] 0000 */
+ Addr tag = a & ~(N_LINE_ARANGE - 1);
+ UWord wix = (a >> N_LINE_BITS) & (N_WAY_NENT - 1);
+ if (LIKELY(tag == cache_shmem.tags0[wix])) {
+ n_New_in_cache++;
+ } else {
+ n_New_not_in_cache++;
+ }
+ if (0 == ((n_New_in_cache + n_New_not_in_cache) % 100000))
+ VG_(printf)("shadow_mem_make_New: IN %lu OUT %lu\n",
+ n_New_in_cache, n_New_not_in_cache );
+ }
+
+ if (LIKELY(len < 2 * N_LINE_ARANGE)) {
+ zsm_set_range_SMALL( a, len, svNew );
+ } else {
+ Addr before_start = a;
+ Addr aligned_start = cacheline_ROUNDUP(a);
+ Addr after_start = cacheline_ROUNDDN(a + len);
+ UWord before_len = aligned_start - before_start;
+ UWord aligned_len = after_start - aligned_start;
+ UWord after_len = a + len - after_start;
+ tl_assert(before_start <= aligned_start);
+ tl_assert(aligned_start <= after_start);
+ tl_assert(before_len < N_LINE_ARANGE);
+ tl_assert(after_len < N_LINE_ARANGE);
+ tl_assert(get_cacheline_offset(aligned_start) == 0);
+ if (get_cacheline_offset(a) == 0) {
+ tl_assert(before_len == 0);
+ tl_assert(a == aligned_start);
+ }
+ if (get_cacheline_offset(a+len) == 0) {
+ tl_assert(after_len == 0);
+ tl_assert(after_start == a+len);
+ }
+ if (before_len > 0) {
+ zsm_set_range_SMALL( before_start, before_len, svNew );
+ }
+ if (after_len > 0) {
+ zsm_set_range_SMALL( after_start, after_len, svNew );
+ }
+ stats__cache_make_New_inZrep += (ULong)aligned_len;
+
+ while (1) {
+ Addr tag;
+ UWord wix;
+ if (aligned_start >= after_start)
+ break;
+ tl_assert(get_cacheline_offset(aligned_start) == 0);
+ tag = aligned_start & ~(N_LINE_ARANGE - 1);
+ wix = (aligned_start >> N_LINE_BITS) & (N_WAY_NENT - 1);
+ if (tag == cache_shmem.tags0[wix]) {
+ UWord i;
+ for (i = 0; i < N_LINE_ARANGE / 8; i++)
+ zsm_write64( aligned_start + i * 8, svNew );
+ } else {
+ UWord i;
+ Word zix;
+ SecMap* sm;
+ LineZ* lineZ;
+ /* This line is not in the cache. Do not force it in; instead
+ modify it in-place. */
+ /* find the Z line to write in and rcdec it or the
+ associated F line. */
+ find_Z_for_writing( &sm, &zix, tag );
+ tl_assert(sm);
+ tl_assert(zix >= 0 && zix < N_SECMAP_ZLINES);
+ lineZ = &sm->linesZ[zix];
+ lineZ->dict[0] = svNew;
+ lineZ->dict[1] = lineZ->dict[2] = lineZ->dict[3] = SVal_INVALID;
+ for (i = 0; i < N_LINE_ARANGE/4; i++)
+ lineZ->ix2s[i] = 0; /* all refer to dict[0] */
+ rcinc_LineZ(lineZ);
+ }
+ aligned_start += N_LINE_ARANGE;
+ aligned_len -= N_LINE_ARANGE;
+ }
+ tl_assert(aligned_start == after_start);
+ tl_assert(aligned_len == 0);
+ }
+}
+
+
+/////////////////////////////////////////////////////////
+// //
// Synchronisation objects //
// //
/////////////////////////////////////////////////////////
@@ -4184,80 +4512,69 @@
VG_(printf)("%s","\n");
}
-Bool libhb_read ( /*OUT*/RaceInfo* ri, Thr* thr, Addr a, SizeT szB )
-{
- MSMInfo info;
- void* opaque = (void*)&info;
+void libhb_read_1 ( Thr* thr, Addr a ) {
+ if(TRACEME(a,1))trace(thr,a,1,"rd-before");
+ zsm_apply8___msm_read ( thr, a );
+ if(TRACEME(a,1))trace(thr,a,1,"rd-after ");
+}
+void libhb_read_2 ( Thr* thr, Addr a ) {
+ if(TRACEME(a,2))trace(thr,a,2,"rd-before");
+ zsm_apply16___msm_read ( thr, a );
+ if(TRACEME(a,2))trace(thr,a,2,"rd-after ");
+}
+void libhb_read_4 ( Thr* thr, Addr a ) {
+ if(TRACEME(a,4))trace(thr,a,4,"rd-before");
+ zsm_apply32___msm_read ( thr, a );
+ if(TRACEME(a,4))trace(thr,a,4,"rd-after ");
+}
+void libhb_read_8 ( Thr* thr, Addr a ) {
+ if(TRACEME(a,8))trace(thr,a,8,"rd-before");
+ zsm_apply64___msm_read ( thr, a );
+ if(TRACEME(a,8))trace(thr,a,8,"rd-after ");
+}
+void libhb_read_N ( Thr* thr, Addr a, SizeT szB ) {
if(TRACEME(a,szB))trace(thr,a,szB,"rd-before");
- info.acc_thr = thr;
- info.ea = a;
- info.race = False;
- switch (szB) {
- case 8:
- zsm_apply64( a, (SVal(*)(SVal,void*))msm_read, opaque );
- break;
- case 4:
- zsm_apply32( a, (SVal(*)(SVal,void*))msm_read, opaque );
- break;
- case 2:
- zsm_apply16( a, (SVal(*)(SVal,void*))msm_read, opaque );
- break;
- case 1:
- zsm_apply8 ( a, (SVal(*)(SVal,void*))msm_read, opaque );
- break;
- default:
- zsm_apply_range( a, szB, (SVal(*)(SVal,void*))msm_read, opaque );
- break;
- }
+ zsm_apply_range___msm_read ( thr, a, szB );
if(TRACEME(a,szB))trace(thr,a,szB,"rd-after ");
- if (!info.race) return False;
- ri->thr = thr;
- ri->where = info.where;
- ri->a = a;
- ri->szB = szB;
- ri->isW = False;
- ri->thrp = info.thrp;
- ri->wherep = info.wherep;
- r...
[truncated message content] |
|
From: Sérgio D. J. <ser...@li...> - 2008-10-08 15:07:20
|
Hello guys, I was reading the Valgrind's website and found something which interested us. The page is: http://valgrind.org/docs/manual/hg-manual.html (Which might be familiar to you, I think :-) ). By reading it, I saw that Valgrind and Helgrind do a very good work with multithreaded applications. Also, this particular bullet has called my attention: * Runtime support library for GNU OpenMP (part of GCC), at least GCC versions 4.2 and 4.3. With some minor effort of modifying the GNU OpenMP runtime support sources, it is possible to use Helgrind on GNU OpenMP compiled codes. Please contact the Valgrind authors for details. And that's the reason why I'm writing this e-mail. I have a couple of questions here, so I thought it'd a good idea to write one of to the developer's mailing-list and try to have them answered :-). Basically, my initial question is: What should I specifically do to get Helgrind working with OpenMP? What kind of modifications in the GNU OpenMP runtime support sources should I make? I'd be happy if you could answer that :-). Also, I've already mailed Jeremy (Helgrind author), but unfortunately he didn't answer yet. Thanks in advance, -- Sérgio Durigan Júnior Linux on Power Toolchain - Software Engineer Linux Technology Center - LTC IBM Brazil |
|
From: Julian S. <js...@ac...> - 2008-10-08 09:19:18
|
> VEX does not seem to guarantee that a constant is placed in > a defined operand position when the operator is commutative. True. > I was thinking of extending IRExpr_Binop to be aware of > commutative operators. What do you think of that approcach? Overall, I'd say that fine tuning the instruction selectors produces changes in performance which are so small as to often be almost unmeasurable. I did a round of isel tuning before the release of 3.2.0. For Memcheck running large programs it would be often in the region of a 1% change. Do you have evidence from a run with --profile-flags=10001100 that such bad cases are happening a lot? FWIW, if you are trying to speed up a tool, the most effective approach is to tune the tool itself. That tends to be where most of the time goes. Especially if the tool is managing large data structures and thereby causing a large amount of D1/L2 pollution compared to the original program. J |
|
From: Julian S. <js...@ac...> - 2008-10-08 09:01:16
|
You should study the Lackey tool, and even use it as a starting point
for your experiments. It shows how you can see all the memory accesses
in a program.
> VG_(track_pre_mem_read) (fb_pre_mem_read);
> VG_(track_pre_mem_write) (fb_pre_mem_write);
> VG_(track_post_mem_write) (fb_post_mem_write);
These only show some very specialised accesses, for system call handling
and signal handling mostly. You will not see the normal data accesses
like this. You need to write an instrumentation function.
> P.S. Also I tried to work with registers by VG_(track_pre_reg_read) and
> VG_(track_post_reg_write), but I also had only strange values on them...
Same problem as with track_{pre,post}_mem_{read,write}.
Even when you see all the memory accesses, there is the problem of
mapping them to source level variables.
Some accesses -- caller save register saves and restores in function
prologues and epilogues -- do not correspond to any specific variables,
and they do not correspond to user-written loads/stores. Others
-- register spills and reloads -- might correspond to a given variable,
but they do not correspond to any user-written loads/stores.
Heap block accesses, you can detect by intercepting all mallocs/frees
so you know the bounds of heap blocks.
For stack and global variables, you can detect accesses (for objects
compiled with -g) by writing a function similar to VG_(get_data_description).
At least in theory you could use VG_(get_data_description), but it can be
very slow and so it won't be practical like that. You would need to
reformat the data in some faster-to-access way.
J
|
|
From: Vadim A. <av...@gm...> - 2008-10-08 07:14:32
|
---------- Forwarded message ---------- From: Vadim Antonov <av...@gm...> Date: 2008/10/8 Subject: Re: [Valgrind-developers] how i can read variables' values with valgrind core? To: Bart Van Assche <bar...@gm...> I want to find variables' values during program's execution. I think, that variables names can't give me this information. 2008/10/8 Bart Van Assche <bar...@gm...> > On Wed, Oct 8, 2008 at 8:37 AM, Vadim Antonov <av...@gm...> wrote: > > > Maybe, you can give an advice, how to find real addresses? > > Why do you need the absolute addresses ? Do you know that Valgrind's > core can translate addresses into names if debug information is > present in an executable ? > > Bart. > -- Best regards, Antonov Vadim mailto: av...@gm... mobile: +79099933666 -- Best regards, Antonov Vadim mailto: av...@gm... mobile: +79099933666 |
|
From: Bart V. A. <bar...@gm...> - 2008-10-08 06:49:30
|
On Wed, Oct 8, 2008 at 8:37 AM, Vadim Antonov <av...@gm...> wrote: > Maybe, you can give an advice, how to find real addresses? Why do you need the absolute addresses ? Do you know that Valgrind's core can translate addresses into names if debug information is present in an executable ? Bart. |
|
From: Bart V. A. <bar...@gm...> - 2008-10-08 06:31:27
|
On Mon, Oct 6, 2008 at 6:56 PM, Vadim Antonov <av...@gm...> wrote: > But I can't understand, why it doesn't work. > Values, which are printed by these code aren't values of my program, which > i'm analyzing. Are you aware that Valgrind loads executables at another address than ld.so ? Bart. |
|
From: Tom H. <th...@cy...> - 2008-10-08 03:30:27
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2008-10-08 03:15:12 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 366 tests, 80 stderr failures, 2 stdout failures, 29 post failures == exp-ptrcheck/tests/bad_percentify (stderr) exp-ptrcheck/tests/base (stderr) exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/fp (stderr) exp-ptrcheck/tests/globalerr (stderr) exp-ptrcheck/tests/hackedbz2 (stderr) exp-ptrcheck/tests/hp_bounds (stderr) exp-ptrcheck/tests/hp_dangle (stderr) exp-ptrcheck/tests/justify (stderr) exp-ptrcheck/tests/partial_bad (stderr) exp-ptrcheck/tests/partial_good (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) exp-ptrcheck/tests/realloc (stderr) exp-ptrcheck/tests/stackerr (stderr) exp-ptrcheck/tests/strcpy (stderr) exp-ptrcheck/tests/supp (stderr) exp-ptrcheck/tests/tricky (stderr) exp-ptrcheck/tests/unaligned (stderr) exp-ptrcheck/tests/zero (stderr) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/hg06_readshared (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc02_simple_tls (stderr) helgrind/tests/tc03_re_excl (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc07_hbl1 (stderr) helgrind/tests/tc08_hbl2 (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc11_XCHG (stderr) helgrind/tests/tc12_rwl_trivial (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) helgrind/tests/tc24_nonzero_sem (stderr) massif/tests/alloc-fns-A (post) massif/tests/alloc-fns-B (post) massif/tests/basic (post) massif/tests/basic2 (post) massif/tests/big-alloc (post) massif/tests/culling1 (stderr) massif/tests/culling2 (stderr) massif/tests/custom_alloc (post) massif/tests/deep-A (post) massif/tests/deep-B (stderr) massif/tests/deep-B (post) massif/tests/deep-C (stderr) massif/tests/deep-C (post) massif/tests/deep-D (post) massif/tests/ignoring (post) massif/tests/insig (post) massif/tests/long-names (post) massif/tests/long-time (post) massif/tests/new-cpp (post) massif/tests/null (post) massif/tests/one (post) massif/tests/overloaded-new (post) massif/tests/peak (post) massif/tests/peak2 (stderr) massif/tests/peak2 (post) massif/tests/realloc (stderr) massif/tests/realloc (post) massif/tests/thresholds_0_0 (post) massif/tests/thresholds_0_10 (post) massif/tests/thresholds_10_0 (post) massif/tests/thresholds_10_10 (post) massif/tests/thresholds_5_0 (post) massif/tests/thresholds_5_10 (post) massif/tests/zero1 (post) massif/tests/zero2 (post) memcheck/tests/file_locking (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/origin1-yes (stderr) memcheck/tests/origin4-many (stderr) memcheck/tests/origin5-bz2 (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/varinfo1 (stderr) memcheck/tests/varinfo2 (stderr) memcheck/tests/varinfo3 (stderr) memcheck/tests/varinfo4 (stderr) memcheck/tests/varinfo5 (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/x86/bug152022 (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) none/tests/blockfault (stderr) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) none/tests/shell (stderr) none/tests/shell_valid1 (stderr) none/tests/shell_valid2 (stderr) none/tests/shell_valid3 (stderr) |
|
From: Tom H. <th...@cy...> - 2008-10-08 03:04:43
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2008-10-08 03:05:05 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 460 tests, 11 stderr failures, 3 stdout failures, 0 post failures == exp-ptrcheck/tests/base (stderr) exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2008-10-08 02:54:58
|
Nightly build on trojan ( x86_64, Fedora Core 6 ) started at 2008-10-08 03:25:06 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 464 tests, 13 stderr failures, 5 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/bug133694 (stdout) memcheck/tests/x86/bug133694 (stderr) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/cmdline1 (stdout) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2008-10-08 02:33:22
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2008-10-08 03:00:02 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 466 tests, 34 stderr failures, 4 stdout failures, 0 post failures == drd/tests/pth_cancel_locked (stderr) exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/hackedbz2 (stderr) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/origin5-bz2 (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/amd64/insn_ssse3 (stdout) none/tests/amd64/insn_ssse3 (stderr) none/tests/amd64/ssse3_misaligned (stderr) none/tests/blockfault (stderr) none/tests/cmdline2 (stdout) none/tests/fdleak_fcntl (stderr) none/tests/mremap2 (stdout) none/tests/x86/insn_ssse3 (stdout) none/tests/x86/insn_ssse3 (stderr) none/tests/x86/ssse3_misaligned (stderr) |