blob: 6671f006f628201a917384303f8e01eb89ebbe65 [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001/*
2 This file is part of drd, a data race detector.
3
sewardj85642922008-01-14 11:54:56 +00004 Copyright (C) 2006-2008 Bart Van Assche
sewardjaf44c822007-11-25 14:01:38 +00005 bart.vanassche@gmail.com
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
26#include "pub_tool_basics.h" // Addr, SizeT
27#include "pub_tool_debuginfo.h" // VG_(get_objname)()
28#include "pub_tool_libcassert.h" // tl_assert()
29#include "pub_tool_libcbase.h" // VG_(memset)
30#include "pub_tool_libcprint.h" // VG_(printf)
31#include "pub_tool_machine.h" // VG_(get_IP)()
32#include "pub_tool_mallocfree.h" // VG_(malloc), VG_(free)
33#include "pub_drd_bitmap.h"
34#include "drd_bitmap.h"
35#include "drd_error.h"
36#include "drd_suppression.h"
37
38
bartf647d342008-03-24 19:12:12 +000039/* Forward declarations. */
sewardjaf44c822007-11-25 14:01:38 +000040
bartf647d342008-03-24 19:12:12 +000041struct bitmap2;
sewardjaf44c822007-11-25 14:01:38 +000042
43
bartf647d342008-03-24 19:12:12 +000044/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000045
46static void bm2_merge(struct bitmap2* const bm2l,
47 const struct bitmap2* const bm2r);
48
49
bartf647d342008-03-24 19:12:12 +000050/* Local constants. */
51
52static ULong s_bitmap_creation_count;
53
54
55/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000056
57struct bitmap* bm_new()
58{
bart33e56c92008-03-24 06:41:30 +000059 unsigned i;
bart3772a982008-03-15 08:11:03 +000060 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000061
bartf29205e2008-03-25 18:51:06 +000062 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
63 /* in drd_bitmap.h. */
bart3772a982008-03-15 08:11:03 +000064 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000065
bart3772a982008-03-15 08:11:03 +000066 bm = VG_(malloc)(sizeof(*bm));
67 tl_assert(bm);
bartf29205e2008-03-25 18:51:06 +000068 /* Cache initialization. a1 is initialized with a value that never can */
69 /* match any valid address: the upper ADDR0_BITS bits of a1 are always */
70 /* zero for a valid cache entry. */
bart33e56c92008-03-24 06:41:30 +000071 for (i = 0; i < N_CACHE_ELEM; i++)
72 {
bartf29205e2008-03-25 18:51:06 +000073 bm->cache[i].a1 = ~(UWord)1;
bart33e56c92008-03-24 06:41:30 +000074 bm->cache[i].bm2 = 0;
75 }
bartf647d342008-03-24 19:12:12 +000076 bm->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free));
sewardjaf44c822007-11-25 14:01:38 +000077
bart3772a982008-03-15 08:11:03 +000078 s_bitmap_creation_count++;
sewardjaf44c822007-11-25 14:01:38 +000079
bart3772a982008-03-15 08:11:03 +000080 return bm;
sewardjaf44c822007-11-25 14:01:38 +000081}
82
83void bm_delete(struct bitmap* const bm)
84{
bartf647d342008-03-24 19:12:12 +000085 struct bitmap2* bm2;
86 struct bitmap2ref* bm2ref;
87
bart3772a982008-03-15 08:11:03 +000088 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000089
90 VG_(OSetGen_ResetIter)(bm->oset);
91 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
92 {
93 bm2 = bm2ref->bm2;
94 tl_assert(bm2->refcnt >= 1);
95 if (--bm2->refcnt == 0)
96 {
97 VG_(free)(bm2);
98 }
99 }
100
bart3772a982008-03-15 08:11:03 +0000101 VG_(OSetGen_Destroy)(bm->oset);
102 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +0000103}
104
105/**
bart36556122008-03-13 19:24:30 +0000106 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000107 * bitmap bm.
108 */
barta79df6e2008-03-14 17:07:51 +0000109static
sewardjaf44c822007-11-25 14:01:38 +0000110void bm_access_range(struct bitmap* const bm,
bart9036dea2008-03-13 19:10:06 +0000111 const Addr a1, const Addr a2,
bart0268dfa2008-03-11 20:10:21 +0000112 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000113{
bart3772a982008-03-15 08:11:03 +0000114 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000115
bart3772a982008-03-15 08:11:03 +0000116 tl_assert(bm);
117 tl_assert(a1 < a2);
barta3f61092008-05-04 07:46:20 +0000118 /* The current implementation of bm_access_range does not work for the */
119 /* ADDR0_COUNT highest addresses in the address range. At least on Linux */
120 /* this is not a problem since the upper part of the address space is */
121 /* reserved for the kernel. */
122 tl_assert(a2 + ADDR0_COUNT > a2);
sewardjaf44c822007-11-25 14:01:38 +0000123
bart3772a982008-03-15 08:11:03 +0000124 for (b = a1; b < a2; b = b_next)
125 {
126 Addr b_start;
127 Addr b_end;
128 struct bitmap2* bm2;
129 SPLIT_ADDRESS(b);
bart36556122008-03-13 19:24:30 +0000130
bart3772a982008-03-15 08:11:03 +0000131 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
132 if (b_next > a2)
133 {
134 b_next = a2;
135 }
bart36556122008-03-13 19:24:30 +0000136
bartf647d342008-03-24 19:12:12 +0000137 bm2 = bm2_lookup_or_insert_exclusive(bm, b1);
bart3772a982008-03-15 08:11:03 +0000138 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000139
bart3772a982008-03-15 08:11:03 +0000140 if ((bm2->addr << ADDR0_BITS) < a1)
141 b_start = a1;
142 else
143 if ((bm2->addr << ADDR0_BITS) < a2)
144 b_start = (bm2->addr << ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000145 else
bart3772a982008-03-15 08:11:03 +0000146 break;
147 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000148
bart3772a982008-03-15 08:11:03 +0000149 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
150 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
151 else
152 b_end = a2;
153 tl_assert(a1 <= b_end && b_end <= a2);
154 tl_assert(b_start < b_end);
155 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000156
bart0008f5b2008-03-22 17:07:39 +0000157 if (access_type == eLoad)
bart3772a982008-03-15 08:11:03 +0000158 {
bart0008f5b2008-03-22 17:07:39 +0000159 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart36556122008-03-13 19:24:30 +0000160 {
bart3772a982008-03-15 08:11:03 +0000161 bm0_set(bm2->bm1.bm0_r, b0);
sewardjaf44c822007-11-25 14:01:38 +0000162 }
bart0008f5b2008-03-22 17:07:39 +0000163 }
164 else
165 {
166 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart3772a982008-03-15 08:11:03 +0000167 {
168 bm0_set(bm2->bm1.bm0_w, b0);
169 }
170 }
171 }
sewardjaf44c822007-11-25 14:01:38 +0000172}
173
barta79df6e2008-03-14 17:07:51 +0000174static inline
175void bm_access_aligned_load(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000176 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000177{
bart3772a982008-03-15 08:11:03 +0000178 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000179
bartf647d342008-03-24 19:12:12 +0000180 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000181 bm0_set_range(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000182}
183
184static inline
185void bm_access_aligned_store(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000186 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000187{
bart3772a982008-03-15 08:11:03 +0000188 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000189
bartf647d342008-03-24 19:12:12 +0000190 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000191 bm0_set_range(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000192}
193
bart36556122008-03-13 19:24:30 +0000194void bm_access_range_load(struct bitmap* const bm,
195 const Addr a1, const Addr a2)
196{
bart3772a982008-03-15 08:11:03 +0000197 bm_access_range(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000198}
199
barta79df6e2008-03-14 17:07:51 +0000200void bm_access_load_1(struct bitmap* const bm, const Addr a1)
201{
bartf8bc71d2008-03-15 11:42:34 +0000202 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000203}
204
205void bm_access_load_2(struct bitmap* const bm, const Addr a1)
206{
bart3772a982008-03-15 08:11:03 +0000207 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000208 bm_access_aligned_load(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000209 else
210 bm_access_range(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000211}
212
213void bm_access_load_4(struct bitmap* const bm, const Addr a1)
214{
bart3772a982008-03-15 08:11:03 +0000215 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000216 bm_access_aligned_load(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000217 else
218 bm_access_range(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000219}
220
221void bm_access_load_8(struct bitmap* const bm, const Addr a1)
222{
bart3772a982008-03-15 08:11:03 +0000223 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000224 bm_access_aligned_load(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000225 else if ((a1 & 3) == 0)
226 {
bartf8bc71d2008-03-15 11:42:34 +0000227 bm_access_aligned_load(bm, a1 + 0, 4);
228 bm_access_aligned_load(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000229 }
230 else
231 bm_access_range(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000232}
233
bartf5acbbc2008-05-10 08:22:20 +0000234void bm_access_range_store(struct bitmap* const bm,
235 const Addr a1, const Addr a2)
236{
237 bm_access_range(bm, a1, a2, eStore);
238}
239
barta79df6e2008-03-14 17:07:51 +0000240void bm_access_store_1(struct bitmap* const bm, const Addr a1)
241{
bartf8bc71d2008-03-15 11:42:34 +0000242 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000243}
244
245void bm_access_store_2(struct bitmap* const bm, const Addr a1)
246{
bart3772a982008-03-15 08:11:03 +0000247 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000248 bm_access_aligned_store(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000249 else
250 bm_access_range(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000251}
252
253void bm_access_store_4(struct bitmap* const bm, const Addr a1)
254{
bart3772a982008-03-15 08:11:03 +0000255 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000256 bm_access_aligned_store(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000257 else
258 bm_access_range(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000259}
260
261void bm_access_store_8(struct bitmap* const bm, const Addr a1)
262{
bart3772a982008-03-15 08:11:03 +0000263 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000264 bm_access_aligned_store(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000265 else if ((a1 & 3) == 0)
266 {
bartf8bc71d2008-03-15 11:42:34 +0000267 bm_access_aligned_store(bm, a1 + 0, 4);
268 bm_access_aligned_store(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000269 }
270 else
271 bm_access_range(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000272}
273
bart36556122008-03-13 19:24:30 +0000274Bool bm_has(const struct bitmap* const bm, const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000275 const BmAccessTypeT access_type)
276{
bart3772a982008-03-15 08:11:03 +0000277 Addr b;
278 for (b = a1; b < a2; b++)
279 {
280 if (! bm_has_1(bm, b, access_type))
281 {
282 return False;
283 }
284 }
285 return True;
sewardjaf44c822007-11-25 14:01:38 +0000286}
287
bartd4907072008-03-30 18:41:07 +0000288Bool bm_has_any_load(const struct bitmap* const bm,
289 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000290{
bartd4907072008-03-30 18:41:07 +0000291 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000292
bart3772a982008-03-15 08:11:03 +0000293 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000294
bartd4907072008-03-30 18:41:07 +0000295 for (b = a1; b < a2; b = b_next)
bart3772a982008-03-15 08:11:03 +0000296 {
bartd4907072008-03-30 18:41:07 +0000297 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
298
299 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
300 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000301 {
bartd4907072008-03-30 18:41:07 +0000302 b_next = a2;
303 }
304
305 if (bm2)
306 {
307 Addr b_start;
308 Addr b_end;
309 UWord b0;
310 const struct bitmap1* const p1 = &bm2->bm1;
311
312 if ((bm2->addr << ADDR0_BITS) < a1)
313 b_start = a1;
314 else
315 if ((bm2->addr << ADDR0_BITS) < a2)
316 b_start = (bm2->addr << ADDR0_BITS);
317 else
318 break;
319 tl_assert(a1 <= b_start && b_start <= a2);
320
321 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
322 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
323 else
324 b_end = a2;
325 tl_assert(a1 <= b_end && b_end <= a2);
326 tl_assert(b_start < b_end);
327 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
328
329 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
330 {
331 if (bm0_is_set(p1->bm0_r, b0))
332 {
333 return True;
334 }
335 }
bart3772a982008-03-15 08:11:03 +0000336 }
337 }
bartd4907072008-03-30 18:41:07 +0000338 return 0;
339}
340
341Bool bm_has_any_store(const struct bitmap* const bm,
342 const Addr a1, const Addr a2)
343{
344 Addr b, b_next;
345
346 tl_assert(bm);
347
348 for (b = a1; b < a2; b = b_next)
349 {
350 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
351
352 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
353 if (b_next > a2)
354 {
355 b_next = a2;
356 }
357
358 if (bm2)
359 {
360 Addr b_start;
361 Addr b_end;
362 UWord b0;
363 const struct bitmap1* const p1 = &bm2->bm1;
364
365 if ((bm2->addr << ADDR0_BITS) < a1)
366 b_start = a1;
367 else
368 if ((bm2->addr << ADDR0_BITS) < a2)
369 b_start = (bm2->addr << ADDR0_BITS);
370 else
371 break;
372 tl_assert(a1 <= b_start && b_start <= a2);
373
374 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
375 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
376 else
377 b_end = a2;
378 tl_assert(a1 <= b_end && b_end <= a2);
379 tl_assert(b_start < b_end);
380 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
381
382 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
383 {
384 if (bm0_is_set(p1->bm0_w, b0))
385 {
386 return True;
387 }
388 }
389 }
390 }
391 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000392}
393
bartc2c81db2008-05-10 11:19:10 +0000394/* Return True if there is a read access, write access or both */
395/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
396Bool bm_has_any_access(const struct bitmap* const bm,
397 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000398{
bart3772a982008-03-15 08:11:03 +0000399 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000400
bart3772a982008-03-15 08:11:03 +0000401 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000402
bart3772a982008-03-15 08:11:03 +0000403 for (b = a1; b < a2; b = b_next)
404 {
bartf647d342008-03-24 19:12:12 +0000405 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000406
bart3772a982008-03-15 08:11:03 +0000407 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
408 if (b_next > a2)
409 {
410 b_next = a2;
411 }
sewardjaf44c822007-11-25 14:01:38 +0000412
bart3772a982008-03-15 08:11:03 +0000413 if (bm2)
414 {
415 Addr b_start;
416 Addr b_end;
417 UWord b0;
418 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000419
bart3772a982008-03-15 08:11:03 +0000420 if ((bm2->addr << ADDR0_BITS) < a1)
421 b_start = a1;
422 else
423 if ((bm2->addr << ADDR0_BITS) < a2)
424 b_start = (bm2->addr << ADDR0_BITS);
425 else
426 break;
427 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000428
bart3772a982008-03-15 08:11:03 +0000429 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
430 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
431 else
432 b_end = a2;
433 tl_assert(a1 <= b_end && b_end <= a2);
434 tl_assert(b_start < b_end);
435 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000436
bart3772a982008-03-15 08:11:03 +0000437 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
438 {
bartc2c81db2008-05-10 11:19:10 +0000439 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
bart3772a982008-03-15 08:11:03 +0000440 {
bartc2c81db2008-05-10 11:19:10 +0000441 return True;
bart3772a982008-03-15 08:11:03 +0000442 }
sewardjaf44c822007-11-25 14:01:38 +0000443 }
bart3772a982008-03-15 08:11:03 +0000444 }
445 }
bartc2c81db2008-05-10 11:19:10 +0000446 return False;
sewardjaf44c822007-11-25 14:01:38 +0000447}
448
bartc2c81db2008-05-10 11:19:10 +0000449/** Report whether an access of type access_type at address a is recorded in
450 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000451 */
bartc2c81db2008-05-10 11:19:10 +0000452Bool bm_has_1(const struct bitmap* const bm,
453 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000454{
bartf647d342008-03-24 19:12:12 +0000455 const struct bitmap2* p2;
456 const struct bitmap1* p1;
457 const UWord* p0;
bart3772a982008-03-15 08:11:03 +0000458 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000459
bart3772a982008-03-15 08:11:03 +0000460 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000461
bart11d0b502008-03-22 16:44:03 +0000462 p2 = bm2_lookup(bm, a >> ADDR0_BITS);
bart3772a982008-03-15 08:11:03 +0000463 if (p2)
464 {
465 p1 = &p2->bm1;
466 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
bartc2c81db2008-05-10 11:19:10 +0000467 return bm0_is_set(p0, a0) ? True : False;
bart3772a982008-03-15 08:11:03 +0000468 }
bartc2c81db2008-05-10 11:19:10 +0000469 return False;
sewardjaf44c822007-11-25 14:01:38 +0000470}
471
sewardjaf44c822007-11-25 14:01:38 +0000472void bm_clear(const struct bitmap* const bm,
473 const Addr a1,
474 const Addr a2)
475{
bart3772a982008-03-15 08:11:03 +0000476 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000477
bart3772a982008-03-15 08:11:03 +0000478 tl_assert(bm);
479 tl_assert(a1);
480 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000481
bart3772a982008-03-15 08:11:03 +0000482 for (b = a1; b < a2; b = b_next)
483 {
bartf647d342008-03-24 19:12:12 +0000484 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000485
bart3772a982008-03-15 08:11:03 +0000486 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
487 if (b_next > a2)
488 {
489 b_next = a2;
490 }
491
492 if (p2)
493 {
494 Addr c = b;
bartf647d342008-03-24 19:12:12 +0000495 /* If the first address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000496 /* start on an UWord boundary, start clearing the first addresses. */
bart3772a982008-03-15 08:11:03 +0000497 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000498 {
bart3772a982008-03-15 08:11:03 +0000499 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
500 if (c_next > b_next)
501 c_next = b_next;
bart5955f332008-03-25 17:19:20 +0000502 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, c_next - c);
503 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, c_next - c);
bart3772a982008-03-15 08:11:03 +0000504 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000505 }
bartf647d342008-03-24 19:12:12 +0000506 /* If some UWords have to be cleared entirely, do this now. */
bart3772a982008-03-15 08:11:03 +0000507 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000508 {
bart3772a982008-03-15 08:11:03 +0000509 const Addr c_next = UWORD_MSB(b_next);
510 tl_assert(UWORD_LSB(c) == 0);
511 tl_assert(UWORD_LSB(c_next) == 0);
512 tl_assert(c_next <= b_next);
513 tl_assert(c <= c_next);
514 if (c_next > c)
515 {
516 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
517 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
518 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
519 c = c_next;
520 }
sewardjaf44c822007-11-25 14:01:38 +0000521 }
bartf647d342008-03-24 19:12:12 +0000522 /* If the last address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000523 /* fall on an UWord boundary, clear the last addresses. */
524 /* tl_assert(c <= b_next); */
525 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, b_next - c);
526 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, b_next - c);
bart3772a982008-03-15 08:11:03 +0000527 }
528 }
sewardjaf44c822007-11-25 14:01:38 +0000529}
sewardjaf44c822007-11-25 14:01:38 +0000530
bart9c4224c2008-03-29 14:40:08 +0000531/** Clear all references to loads in bitmap bm starting at address a1 and
532 * up to but not including address a2.
533 */
534void bm_clear_load(const struct bitmap* const bm,
535 const Addr a1, const Addr a2)
536{
537 Addr a;
538
539 for (a = a1; a < a2; a++)
540 {
541 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
542 if (p2)
543 {
544 bm0_clear(p2->bm1.bm0_r, a & ADDR0_MASK);
545 }
546 }
547}
548
549/** Clear all references to stores in bitmap bm starting at address a1 and
550 * up to but not including address a2.
551 */
552void bm_clear_store(const struct bitmap* const bm,
553 const Addr a1, const Addr a2)
554{
555 Addr a;
556
557 for (a = a1; a < a2; a++)
558 {
559 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
560 if (p2)
561 {
562 bm0_clear(p2->bm1.bm0_w, a & ADDR0_MASK);
563 }
564 }
565}
566
bart8bf2f8b2008-03-30 17:56:43 +0000567/** Clear bitmap bm starting at address a1 and up to but not including address
568 * a2. Return True if and only if any of the addresses was set before
569 * clearing.
570 */
571Bool bm_test_and_clear(const struct bitmap* const bm,
572 const Addr a1, const Addr a2)
573{
574 Bool result;
575
576 result = bm_has_any_access(bm, a1, a2) != 0;
577 bm_clear(bm, a1, a2);
578 return result;
579}
580
bart36556122008-03-13 19:24:30 +0000581Bool bm_has_conflict_with(const struct bitmap* const bm,
582 const Addr a1, const Addr a2,
583 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000584{
bart3772a982008-03-15 08:11:03 +0000585 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000586
bart3772a982008-03-15 08:11:03 +0000587 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000588
bart3772a982008-03-15 08:11:03 +0000589 for (b = a1; b < a2; b = b_next)
590 {
bartf647d342008-03-24 19:12:12 +0000591 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000592
bart3772a982008-03-15 08:11:03 +0000593 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
594 if (b_next > a2)
595 {
596 b_next = a2;
597 }
bart36556122008-03-13 19:24:30 +0000598
bart3772a982008-03-15 08:11:03 +0000599 if (bm2)
600 {
601 Addr b_start;
602 Addr b_end;
603 UWord b0;
604 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000605
bart3772a982008-03-15 08:11:03 +0000606 if ((bm2->addr << ADDR0_BITS) < a1)
607 b_start = a1;
608 else
609 if ((bm2->addr << ADDR0_BITS) < a2)
610 b_start = (bm2->addr << ADDR0_BITS);
611 else
612 break;
613 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000614
bart3772a982008-03-15 08:11:03 +0000615 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
616 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
617 else
618 b_end = a2;
619 tl_assert(a1 <= b_end && b_end <= a2);
620 tl_assert(b_start < b_end);
621 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000622
bart3772a982008-03-15 08:11:03 +0000623 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
624 {
625 if (access_type == eLoad)
626 {
627 if (bm0_is_set(p1->bm0_w, b0))
628 {
629 return True;
630 }
631 }
632 else
633 {
634 tl_assert(access_type == eStore);
635 if (bm0_is_set(p1->bm0_r, b0)
636 | bm0_is_set(p1->bm0_w, b0))
637 {
638 return True;
639 }
640 }
sewardjaf44c822007-11-25 14:01:38 +0000641 }
bart3772a982008-03-15 08:11:03 +0000642 }
643 }
644 return False;
sewardjaf44c822007-11-25 14:01:38 +0000645}
646
barta79df6e2008-03-14 17:07:51 +0000647static inline
648Bool bm_aligned_load_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000649 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000650{
bartf647d342008-03-24 19:12:12 +0000651 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000652
bart11d0b502008-03-22 16:44:03 +0000653 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000654
bartf8bc71d2008-03-15 11:42:34 +0000655 return (bm2 && bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size));
barta79df6e2008-03-14 17:07:51 +0000656}
657
658static inline
659Bool bm_aligned_store_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000660 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000661{
bartf647d342008-03-24 19:12:12 +0000662 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000663
bart11d0b502008-03-22 16:44:03 +0000664 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000665
bart3772a982008-03-15 08:11:03 +0000666 if (bm2)
667 {
bartf8bc71d2008-03-15 11:42:34 +0000668 if (bm0_is_any_set(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size)
669 | bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size))
bart3772a982008-03-15 08:11:03 +0000670 {
671 return True;
672 }
673 }
674 return False;
barta79df6e2008-03-14 17:07:51 +0000675}
676
bart36556122008-03-13 19:24:30 +0000677Bool bm_load_has_conflict_with(const struct bitmap* const bm,
678 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000679{
bart3772a982008-03-15 08:11:03 +0000680 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000681}
682
barta79df6e2008-03-14 17:07:51 +0000683Bool bm_load_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
684{
bartf8bc71d2008-03-15 11:42:34 +0000685 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000686}
687
688Bool bm_load_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
689{
bart3772a982008-03-15 08:11:03 +0000690 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000691 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000692 else
693 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000694}
695
696Bool bm_load_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
697{
bart3772a982008-03-15 08:11:03 +0000698 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000699 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000700 else
701 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000702}
703
704Bool bm_load_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
705{
bart3772a982008-03-15 08:11:03 +0000706 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000707 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000708 else
709 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000710}
711
712Bool bm_store_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
713{
bartf8bc71d2008-03-15 11:42:34 +0000714 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000715}
716
717Bool bm_store_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
718{
bart3772a982008-03-15 08:11:03 +0000719 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000720 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000721 else
722 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000723}
724
725Bool bm_store_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
726{
bart3772a982008-03-15 08:11:03 +0000727 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000728 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000729 else
730 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000731}
732
733Bool bm_store_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
734{
bart3772a982008-03-15 08:11:03 +0000735 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000736 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000737 else
738 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000739}
740
bart36556122008-03-13 19:24:30 +0000741Bool bm_store_has_conflict_with(const struct bitmap* const bm,
742 const Addr a1, const Addr a2)
743{
bart3772a982008-03-15 08:11:03 +0000744 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000745}
746
bartc2c81db2008-05-10 11:19:10 +0000747/** Return True if the two bitmaps *lhs and *rhs are identical, and false
bart7cd7d7f2008-04-14 16:10:01 +0000748 * if not.
749 */
barta3f61092008-05-04 07:46:20 +0000750Bool bm_equal(struct bitmap* const lhs, const struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000751{
752 struct bitmap2* bm2l;
753 struct bitmap2ref* bm2l_ref;
754 struct bitmap2* bm2r;
755 const struct bitmap2ref* bm2r_ref;
756
barta3f61092008-05-04 07:46:20 +0000757 /* It's not possible to have two independent iterators over the same OSet, */
758 /* so complain if lhs == rhs. */
759 tl_assert(lhs != rhs);
760
bart7cd7d7f2008-04-14 16:10:01 +0000761 VG_(OSetGen_ResetIter)(lhs->oset);
762 VG_(OSetGen_ResetIter)(rhs->oset);
763
764 for ( ; (bm2l_ref = VG_(OSetGen_Next)(lhs->oset)) != 0; )
765 {
bartf5acbbc2008-05-10 08:22:20 +0000766 while (bm2l_ref
767 && (bm2l = bm2l_ref->bm2)
768 && bm2l
769 && ! bm_has_any_access(lhs,
770 bm2l->addr << ADDR0_BITS,
771 (bm2l->addr + 1) << ADDR0_BITS))
772 {
773 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
774 }
775 if (bm2l_ref == 0)
776 break;
bart7cd7d7f2008-04-14 16:10:01 +0000777 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000778#if 0
779 VG_(message)(Vg_DebugMsg, "bm_equal: at 0x%lx", bm2l->addr << ADDR0_BITS);
780#endif
781
bart7cd7d7f2008-04-14 16:10:01 +0000782 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
783 if (bm2r_ref == 0)
barta3f61092008-05-04 07:46:20 +0000784 {
785#if 0
786 VG_(message)(Vg_DebugMsg, "bm_equal: no match found");
787#endif
bart7cd7d7f2008-04-14 16:10:01 +0000788 return False;
barta3f61092008-05-04 07:46:20 +0000789 }
bart7cd7d7f2008-04-14 16:10:01 +0000790 bm2r = bm2r_ref->bm2;
791 tl_assert(bm2r);
792 tl_assert(bm_has_any_access(rhs,
793 bm2r->addr << ADDR0_BITS,
794 (bm2r->addr + 1) << ADDR0_BITS));
barta3f61092008-05-04 07:46:20 +0000795
796 if (bm2l != bm2r
797 && (bm2l->addr != bm2r->addr
798 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
bart7cd7d7f2008-04-14 16:10:01 +0000799 {
barta3f61092008-05-04 07:46:20 +0000800#if 0
801 VG_(message)(Vg_DebugMsg, "bm_equal: rhs 0x%lx -- returning false",
802 bm2r->addr << ADDR0_BITS);
803#endif
bart7cd7d7f2008-04-14 16:10:01 +0000804 return False;
805 }
barta3f61092008-05-04 07:46:20 +0000806 }
807 bm2r = VG_(OSetGen_Next)(rhs->oset);
808 if (bm2r)
809 {
810 tl_assert(bm_has_any_access(rhs,
811 bm2r->addr << ADDR0_BITS,
812 (bm2r->addr + 1) << ADDR0_BITS));
813#if 0
814 VG_(message)(Vg_DebugMsg,
815 "bm_equal: remaining rhs 0x%lx -- returning false",
816 bm2r->addr << ADDR0_BITS);
817#endif
818 return False;
bart7cd7d7f2008-04-14 16:10:01 +0000819 }
820 return True;
821}
822
sewardjaf44c822007-11-25 14:01:38 +0000823void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
824{
bart3772a982008-03-15 08:11:03 +0000825 OSet* const tmp = bm1->oset;
826 bm1->oset = bm2->oset;
827 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000828}
829
bartf647d342008-03-24 19:12:12 +0000830/** Merge bitmaps *lhs and *rhs into *lhs. */
sewardjaf44c822007-11-25 14:01:38 +0000831void bm_merge2(struct bitmap* const lhs,
832 const struct bitmap* const rhs)
833{
bart3772a982008-03-15 08:11:03 +0000834 struct bitmap2* bm2l;
bartf647d342008-03-24 19:12:12 +0000835 struct bitmap2ref* bm2l_ref;
836 struct bitmap2* bm2r;
837 const struct bitmap2ref* bm2r_ref;
sewardjaf44c822007-11-25 14:01:38 +0000838
bart3772a982008-03-15 08:11:03 +0000839 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000840
bartf647d342008-03-24 19:12:12 +0000841 for ( ; (bm2r_ref = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000842 {
bartf647d342008-03-24 19:12:12 +0000843 bm2r = bm2r_ref->bm2;
844 bm2l_ref = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
845 if (bm2l_ref)
bart3772a982008-03-15 08:11:03 +0000846 {
bartf647d342008-03-24 19:12:12 +0000847 bm2l = bm2l_ref->bm2;
848 if (bm2l != bm2r)
849 {
850 if (bm2l->refcnt > 1)
851 bm2l = bm2_make_exclusive(lhs, bm2l_ref);
852 bm2_merge(bm2l, bm2r);
853 }
854 }
855 else
856 {
857 bm2_insert_addref(lhs, bm2r);
858 }
bart3772a982008-03-15 08:11:03 +0000859 }
sewardjaf44c822007-11-25 14:01:38 +0000860}
861
862/**
863 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
864 * @param lhs First bitmap.
865 * @param rhs Bitmap to be compared with lhs.
866 * @return !=0 if there are data races, == 0 if there are none.
867 */
868int bm_has_races(const struct bitmap* const lhs,
869 const struct bitmap* const rhs)
870{
bart3772a982008-03-15 08:11:03 +0000871 VG_(OSetGen_ResetIter)(lhs->oset);
872 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000873
bart3772a982008-03-15 08:11:03 +0000874 for (;;)
875 {
bartf647d342008-03-24 19:12:12 +0000876 const struct bitmap2ref* bm2l_ref;
877 const struct bitmap2ref* bm2r_ref;
878 const struct bitmap2* bm2l;
879 const struct bitmap2* bm2r;
bart3772a982008-03-15 08:11:03 +0000880 const struct bitmap1* bm1l;
881 const struct bitmap1* bm1r;
882 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000883
bartf647d342008-03-24 19:12:12 +0000884 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
885 bm2l = bm2l_ref->bm2;
886 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
887 bm2r = bm2r_ref->bm2;
bart3772a982008-03-15 08:11:03 +0000888 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
889 {
890 if (bm2l->addr < bm2r->addr)
bartf647d342008-03-24 19:12:12 +0000891 bm2l = (bm2l_ref = VG_(OSetGen_Next)(lhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000892 else
bartf647d342008-03-24 19:12:12 +0000893 bm2r = (bm2r_ref = VG_(OSetGen_Next)(rhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000894 }
895 if (bm2l == 0 || bm2r == 0)
896 break;
897
898 bm1l = &bm2l->bm1;
899 bm1r = &bm2r->bm1;
900
901 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
902 {
903 unsigned b;
904 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000905 {
barta3f61092008-05-04 07:46:20 +0000906 UWord const access_mask
bart3772a982008-03-15 08:11:03 +0000907 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
908 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
909 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
910 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
911 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
barta3f61092008-05-04 07:46:20 +0000912 if (HAS_RACE(access_mask) && ! drd_is_suppressed(a, a + 1))
bart3772a982008-03-15 08:11:03 +0000913 {
914 return 1;
915 }
sewardjaf44c822007-11-25 14:01:38 +0000916 }
bart3772a982008-03-15 08:11:03 +0000917 }
918 }
919 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000920}
921
sewardjaf44c822007-11-25 14:01:38 +0000922void bm_print(const struct bitmap* const bm)
923{
bart3772a982008-03-15 08:11:03 +0000924 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000925 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000926
bart3772a982008-03-15 08:11:03 +0000927 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000928
bartf647d342008-03-24 19:12:12 +0000929 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000930 {
bartf647d342008-03-24 19:12:12 +0000931 const struct bitmap1* bm1;
bart0008f5b2008-03-22 17:07:39 +0000932 unsigned b;
bartf647d342008-03-24 19:12:12 +0000933
934 bm2 = bm2ref->bm2;
935 bm1 = &bm2->bm1;
bart0008f5b2008-03-22 17:07:39 +0000936 for (b = 0; b < ADDR0_COUNT; b++)
bart3772a982008-03-15 08:11:03 +0000937 {
bart0008f5b2008-03-22 17:07:39 +0000938 const Addr a = (bm2->addr << ADDR0_BITS) | b;
939 const Bool r = bm0_is_set(bm1->bm0_r, b) != 0;
940 const Bool w = bm0_is_set(bm1->bm0_w, b) != 0;
941 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +0000942 {
bart0008f5b2008-03-22 17:07:39 +0000943 VG_(printf)("0x%08lx %c %c\n",
944 a,
945 w ? 'W' : ' ',
946 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +0000947 }
bart3772a982008-03-15 08:11:03 +0000948 }
949 }
sewardjaf44c822007-11-25 14:01:38 +0000950}
951
952ULong bm_get_bitmap_creation_count(void)
953{
bart3772a982008-03-15 08:11:03 +0000954 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000955}
956
bart588d90f2008-04-06 13:05:58 +0000957ULong bm_get_bitmap2_node_creation_count(void)
958{
959 return s_bitmap2_creation_count;
960}
961
sewardjaf44c822007-11-25 14:01:38 +0000962ULong bm_get_bitmap2_creation_count(void)
963{
bart3772a982008-03-15 08:11:03 +0000964 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000965}
966
bartf647d342008-03-24 19:12:12 +0000967/** Allocate and initialize a second level bitmap. */
968static struct bitmap2* bm2_new(const UWord a1)
969{
970 struct bitmap2* bm2;
971
972 bm2 = VG_(malloc)(sizeof(*bm2));
973 bm2->addr = a1;
974 bm2->refcnt = 1;
975
976 s_bitmap2_creation_count++;
977
978 return bm2;
979}
980
981/** Make a copy of a shared second level bitmap such that the copy can be
982 * modified.
983 *
984 * @param a1 client address shifted right by ADDR0_BITS.
985 * @param bm bitmap pointer.
986 */
987static
988struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
989 struct bitmap2ref* const bm2ref)
990{
991 UWord a1;
992 struct bitmap2* bm2;
993 struct bitmap2* bm2_copy;
994
995 tl_assert(bm);
996 tl_assert(bm2ref);
997 bm2 = bm2ref->bm2;
998 tl_assert(bm2);
999 tl_assert(bm2->refcnt > 1);
1000 bm2->refcnt--;
1001 tl_assert(bm2->refcnt >= 1);
1002 a1 = bm2->addr;
1003 bm2_copy = bm2_new(a1);
1004 tl_assert(bm2_copy);
1005 tl_assert(bm2_copy->addr == a1);
1006 tl_assert(bm2_copy->refcnt == 1);
1007 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1));
1008 bm2ref->bm2 = bm2_copy;
1009
1010 bm_update_cache(bm, a1, bm2_copy);
1011
1012 return bm2_copy;
1013}
1014
sewardjaf44c822007-11-25 14:01:38 +00001015static void bm2_merge(struct bitmap2* const bm2l,
1016 const struct bitmap2* const bm2r)
1017{
bart3772a982008-03-15 08:11:03 +00001018 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001019
bart33e56c92008-03-24 06:41:30 +00001020 tl_assert(bm2l);
1021 tl_assert(bm2r);
bart3772a982008-03-15 08:11:03 +00001022 tl_assert(bm2l->addr == bm2r->addr);
bartf647d342008-03-24 19:12:12 +00001023 tl_assert(bm2l->refcnt == 1);
sewardjaf44c822007-11-25 14:01:38 +00001024
bart3772a982008-03-15 08:11:03 +00001025 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1026 {
1027 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1028 }
1029 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1030 {
1031 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1032 }
sewardjaf44c822007-11-25 14:01:38 +00001033}