blob: 031337e1ab9b3041c4849689e71cd79f0dc4242d [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
394/* Return a non-zero value if there is a read access, write access or both */
395/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
396UWord bm_has_any_access(const struct bitmap* const bm,
397 const Addr a1,
398 const Addr a2)
399{
bart3772a982008-03-15 08:11:03 +0000400 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000401
bart3772a982008-03-15 08:11:03 +0000402 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000403
bart3772a982008-03-15 08:11:03 +0000404 for (b = a1; b < a2; b = b_next)
405 {
bartf647d342008-03-24 19:12:12 +0000406 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000407
bart3772a982008-03-15 08:11:03 +0000408 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
409 if (b_next > a2)
410 {
411 b_next = a2;
412 }
sewardjaf44c822007-11-25 14:01:38 +0000413
bart3772a982008-03-15 08:11:03 +0000414 if (bm2)
415 {
416 Addr b_start;
417 Addr b_end;
418 UWord b0;
419 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000420
bart3772a982008-03-15 08:11:03 +0000421 if ((bm2->addr << ADDR0_BITS) < a1)
422 b_start = a1;
423 else
424 if ((bm2->addr << ADDR0_BITS) < a2)
425 b_start = (bm2->addr << ADDR0_BITS);
426 else
427 break;
428 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000429
bart3772a982008-03-15 08:11:03 +0000430 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
431 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
432 else
433 b_end = a2;
434 tl_assert(a1 <= b_end && b_end <= a2);
435 tl_assert(b_start < b_end);
436 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000437
bart3772a982008-03-15 08:11:03 +0000438 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
439 {
440 const UWord mask
441 = bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0);
442 if (mask)
443 {
444 return mask;
445 }
sewardjaf44c822007-11-25 14:01:38 +0000446 }
bart3772a982008-03-15 08:11:03 +0000447 }
448 }
449 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000450}
451
452/**
453 * Report whether an access of type access_type at address a is recorded in
454 * bitmap bm.
455 * @return != 0 means true, and == 0 means false
456 */
457UWord bm_has_1(const struct bitmap* const bm,
458 const Addr a,
459 const BmAccessTypeT access_type)
460{
bartf647d342008-03-24 19:12:12 +0000461 const struct bitmap2* p2;
462 const struct bitmap1* p1;
463 const UWord* p0;
bart3772a982008-03-15 08:11:03 +0000464 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000465
bart3772a982008-03-15 08:11:03 +0000466 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000467
bart11d0b502008-03-22 16:44:03 +0000468 p2 = bm2_lookup(bm, a >> ADDR0_BITS);
bart3772a982008-03-15 08:11:03 +0000469 if (p2)
470 {
471 p1 = &p2->bm1;
472 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
473 return bm0_is_set(p0, a0);
474 }
475 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000476}
477
sewardjaf44c822007-11-25 14:01:38 +0000478void bm_clear(const struct bitmap* const bm,
479 const Addr a1,
480 const Addr a2)
481{
bart3772a982008-03-15 08:11:03 +0000482 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000483
bart3772a982008-03-15 08:11:03 +0000484 tl_assert(bm);
485 tl_assert(a1);
486 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000487
bart3772a982008-03-15 08:11:03 +0000488 for (b = a1; b < a2; b = b_next)
489 {
bartf647d342008-03-24 19:12:12 +0000490 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000491
bart3772a982008-03-15 08:11:03 +0000492 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
493 if (b_next > a2)
494 {
495 b_next = a2;
496 }
497
498 if (p2)
499 {
500 Addr c = b;
bartf647d342008-03-24 19:12:12 +0000501 /* If the first address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000502 /* start on an UWord boundary, start clearing the first addresses. */
bart3772a982008-03-15 08:11:03 +0000503 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000504 {
bart3772a982008-03-15 08:11:03 +0000505 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
506 if (c_next > b_next)
507 c_next = b_next;
bart5955f332008-03-25 17:19:20 +0000508 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, c_next - c);
509 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, c_next - c);
bart3772a982008-03-15 08:11:03 +0000510 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000511 }
bartf647d342008-03-24 19:12:12 +0000512 /* If some UWords have to be cleared entirely, do this now. */
bart3772a982008-03-15 08:11:03 +0000513 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000514 {
bart3772a982008-03-15 08:11:03 +0000515 const Addr c_next = UWORD_MSB(b_next);
516 tl_assert(UWORD_LSB(c) == 0);
517 tl_assert(UWORD_LSB(c_next) == 0);
518 tl_assert(c_next <= b_next);
519 tl_assert(c <= c_next);
520 if (c_next > c)
521 {
522 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
523 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
524 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
525 c = c_next;
526 }
sewardjaf44c822007-11-25 14:01:38 +0000527 }
bartf647d342008-03-24 19:12:12 +0000528 /* If the last address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000529 /* fall on an UWord boundary, clear the last addresses. */
530 /* tl_assert(c <= b_next); */
531 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, b_next - c);
532 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, b_next - c);
bart3772a982008-03-15 08:11:03 +0000533 }
534 }
sewardjaf44c822007-11-25 14:01:38 +0000535}
sewardjaf44c822007-11-25 14:01:38 +0000536
bart9c4224c2008-03-29 14:40:08 +0000537/** Clear all references to loads in bitmap bm starting at address a1 and
538 * up to but not including address a2.
539 */
540void bm_clear_load(const struct bitmap* const bm,
541 const Addr a1, const Addr a2)
542{
543 Addr a;
544
545 for (a = a1; a < a2; a++)
546 {
547 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
548 if (p2)
549 {
550 bm0_clear(p2->bm1.bm0_r, a & ADDR0_MASK);
551 }
552 }
553}
554
555/** Clear all references to stores in bitmap bm starting at address a1 and
556 * up to but not including address a2.
557 */
558void bm_clear_store(const struct bitmap* const bm,
559 const Addr a1, const Addr a2)
560{
561 Addr a;
562
563 for (a = a1; a < a2; a++)
564 {
565 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
566 if (p2)
567 {
568 bm0_clear(p2->bm1.bm0_w, a & ADDR0_MASK);
569 }
570 }
571}
572
bart8bf2f8b2008-03-30 17:56:43 +0000573/** Clear bitmap bm starting at address a1 and up to but not including address
574 * a2. Return True if and only if any of the addresses was set before
575 * clearing.
576 */
577Bool bm_test_and_clear(const struct bitmap* const bm,
578 const Addr a1, const Addr a2)
579{
580 Bool result;
581
582 result = bm_has_any_access(bm, a1, a2) != 0;
583 bm_clear(bm, a1, a2);
584 return result;
585}
586
bart36556122008-03-13 19:24:30 +0000587Bool bm_has_conflict_with(const struct bitmap* const bm,
588 const Addr a1, const Addr a2,
589 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000590{
bart3772a982008-03-15 08:11:03 +0000591 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000592
bart3772a982008-03-15 08:11:03 +0000593 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000594
bart3772a982008-03-15 08:11:03 +0000595 for (b = a1; b < a2; b = b_next)
596 {
bartf647d342008-03-24 19:12:12 +0000597 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000598
bart3772a982008-03-15 08:11:03 +0000599 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
600 if (b_next > a2)
601 {
602 b_next = a2;
603 }
bart36556122008-03-13 19:24:30 +0000604
bart3772a982008-03-15 08:11:03 +0000605 if (bm2)
606 {
607 Addr b_start;
608 Addr b_end;
609 UWord b0;
610 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000611
bart3772a982008-03-15 08:11:03 +0000612 if ((bm2->addr << ADDR0_BITS) < a1)
613 b_start = a1;
614 else
615 if ((bm2->addr << ADDR0_BITS) < a2)
616 b_start = (bm2->addr << ADDR0_BITS);
617 else
618 break;
619 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000620
bart3772a982008-03-15 08:11:03 +0000621 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
622 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
623 else
624 b_end = a2;
625 tl_assert(a1 <= b_end && b_end <= a2);
626 tl_assert(b_start < b_end);
627 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000628
bart3772a982008-03-15 08:11:03 +0000629 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
630 {
631 if (access_type == eLoad)
632 {
633 if (bm0_is_set(p1->bm0_w, b0))
634 {
635 return True;
636 }
637 }
638 else
639 {
640 tl_assert(access_type == eStore);
641 if (bm0_is_set(p1->bm0_r, b0)
642 | bm0_is_set(p1->bm0_w, b0))
643 {
644 return True;
645 }
646 }
sewardjaf44c822007-11-25 14:01:38 +0000647 }
bart3772a982008-03-15 08:11:03 +0000648 }
649 }
650 return False;
sewardjaf44c822007-11-25 14:01:38 +0000651}
652
barta79df6e2008-03-14 17:07:51 +0000653static inline
654Bool bm_aligned_load_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000655 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000656{
bartf647d342008-03-24 19:12:12 +0000657 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000658
bart11d0b502008-03-22 16:44:03 +0000659 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000660
bartf8bc71d2008-03-15 11:42:34 +0000661 return (bm2 && bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size));
barta79df6e2008-03-14 17:07:51 +0000662}
663
664static inline
665Bool bm_aligned_store_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000666 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000667{
bartf647d342008-03-24 19:12:12 +0000668 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000669
bart11d0b502008-03-22 16:44:03 +0000670 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000671
bart3772a982008-03-15 08:11:03 +0000672 if (bm2)
673 {
bartf8bc71d2008-03-15 11:42:34 +0000674 if (bm0_is_any_set(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size)
675 | bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size))
bart3772a982008-03-15 08:11:03 +0000676 {
677 return True;
678 }
679 }
680 return False;
barta79df6e2008-03-14 17:07:51 +0000681}
682
bart36556122008-03-13 19:24:30 +0000683Bool bm_load_has_conflict_with(const struct bitmap* const bm,
684 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000685{
bart3772a982008-03-15 08:11:03 +0000686 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000687}
688
barta79df6e2008-03-14 17:07:51 +0000689Bool bm_load_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
690{
bartf8bc71d2008-03-15 11:42:34 +0000691 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000692}
693
694Bool bm_load_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
695{
bart3772a982008-03-15 08:11:03 +0000696 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000697 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000698 else
699 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000700}
701
702Bool bm_load_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
703{
bart3772a982008-03-15 08:11:03 +0000704 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000705 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000706 else
707 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000708}
709
710Bool bm_load_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
711{
bart3772a982008-03-15 08:11:03 +0000712 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000713 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000714 else
715 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000716}
717
718Bool bm_store_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
719{
bartf8bc71d2008-03-15 11:42:34 +0000720 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000721}
722
723Bool bm_store_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
724{
bart3772a982008-03-15 08:11:03 +0000725 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000726 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000727 else
728 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000729}
730
731Bool bm_store_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
732{
bart3772a982008-03-15 08:11:03 +0000733 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000734 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000735 else
736 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000737}
738
739Bool bm_store_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
740{
bart3772a982008-03-15 08:11:03 +0000741 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000742 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000743 else
744 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000745}
746
bart36556122008-03-13 19:24:30 +0000747Bool bm_store_has_conflict_with(const struct bitmap* const bm,
748 const Addr a1, const Addr a2)
749{
bart3772a982008-03-15 08:11:03 +0000750 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000751}
752
bart7cd7d7f2008-04-14 16:10:01 +0000753/** Return true if the two bitmaps *lhs and *rhs are identical, and false
754 * if not.
755 */
barta3f61092008-05-04 07:46:20 +0000756Bool bm_equal(struct bitmap* const lhs, const struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000757{
758 struct bitmap2* bm2l;
759 struct bitmap2ref* bm2l_ref;
760 struct bitmap2* bm2r;
761 const struct bitmap2ref* bm2r_ref;
762
barta3f61092008-05-04 07:46:20 +0000763 /* It's not possible to have two independent iterators over the same OSet, */
764 /* so complain if lhs == rhs. */
765 tl_assert(lhs != rhs);
766
bart7cd7d7f2008-04-14 16:10:01 +0000767 VG_(OSetGen_ResetIter)(lhs->oset);
768 VG_(OSetGen_ResetIter)(rhs->oset);
769
770 for ( ; (bm2l_ref = VG_(OSetGen_Next)(lhs->oset)) != 0; )
771 {
bartf5acbbc2008-05-10 08:22:20 +0000772 while (bm2l_ref
773 && (bm2l = bm2l_ref->bm2)
774 && bm2l
775 && ! bm_has_any_access(lhs,
776 bm2l->addr << ADDR0_BITS,
777 (bm2l->addr + 1) << ADDR0_BITS))
778 {
779 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
780 }
781 if (bm2l_ref == 0)
782 break;
bart7cd7d7f2008-04-14 16:10:01 +0000783 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000784#if 0
785 VG_(message)(Vg_DebugMsg, "bm_equal: at 0x%lx", bm2l->addr << ADDR0_BITS);
786#endif
787
bart7cd7d7f2008-04-14 16:10:01 +0000788 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
789 if (bm2r_ref == 0)
barta3f61092008-05-04 07:46:20 +0000790 {
791#if 0
792 VG_(message)(Vg_DebugMsg, "bm_equal: no match found");
793#endif
bart7cd7d7f2008-04-14 16:10:01 +0000794 return False;
barta3f61092008-05-04 07:46:20 +0000795 }
bart7cd7d7f2008-04-14 16:10:01 +0000796 bm2r = bm2r_ref->bm2;
797 tl_assert(bm2r);
798 tl_assert(bm_has_any_access(rhs,
799 bm2r->addr << ADDR0_BITS,
800 (bm2r->addr + 1) << ADDR0_BITS));
barta3f61092008-05-04 07:46:20 +0000801
802 if (bm2l != bm2r
803 && (bm2l->addr != bm2r->addr
804 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
bart7cd7d7f2008-04-14 16:10:01 +0000805 {
barta3f61092008-05-04 07:46:20 +0000806#if 0
807 VG_(message)(Vg_DebugMsg, "bm_equal: rhs 0x%lx -- returning false",
808 bm2r->addr << ADDR0_BITS);
809#endif
bart7cd7d7f2008-04-14 16:10:01 +0000810 return False;
811 }
barta3f61092008-05-04 07:46:20 +0000812 }
813 bm2r = VG_(OSetGen_Next)(rhs->oset);
814 if (bm2r)
815 {
816 tl_assert(bm_has_any_access(rhs,
817 bm2r->addr << ADDR0_BITS,
818 (bm2r->addr + 1) << ADDR0_BITS));
819#if 0
820 VG_(message)(Vg_DebugMsg,
821 "bm_equal: remaining rhs 0x%lx -- returning false",
822 bm2r->addr << ADDR0_BITS);
823#endif
824 return False;
bart7cd7d7f2008-04-14 16:10:01 +0000825 }
826 return True;
827}
828
sewardjaf44c822007-11-25 14:01:38 +0000829void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
830{
bart3772a982008-03-15 08:11:03 +0000831 OSet* const tmp = bm1->oset;
832 bm1->oset = bm2->oset;
833 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000834}
835
bartf647d342008-03-24 19:12:12 +0000836/** Merge bitmaps *lhs and *rhs into *lhs. */
sewardjaf44c822007-11-25 14:01:38 +0000837void bm_merge2(struct bitmap* const lhs,
838 const struct bitmap* const rhs)
839{
bart3772a982008-03-15 08:11:03 +0000840 struct bitmap2* bm2l;
bartf647d342008-03-24 19:12:12 +0000841 struct bitmap2ref* bm2l_ref;
842 struct bitmap2* bm2r;
843 const struct bitmap2ref* bm2r_ref;
sewardjaf44c822007-11-25 14:01:38 +0000844
bart3772a982008-03-15 08:11:03 +0000845 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000846
bartf647d342008-03-24 19:12:12 +0000847 for ( ; (bm2r_ref = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000848 {
bartf647d342008-03-24 19:12:12 +0000849 bm2r = bm2r_ref->bm2;
850 bm2l_ref = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
851 if (bm2l_ref)
bart3772a982008-03-15 08:11:03 +0000852 {
bartf647d342008-03-24 19:12:12 +0000853 bm2l = bm2l_ref->bm2;
854 if (bm2l != bm2r)
855 {
856 if (bm2l->refcnt > 1)
857 bm2l = bm2_make_exclusive(lhs, bm2l_ref);
858 bm2_merge(bm2l, bm2r);
859 }
860 }
861 else
862 {
863 bm2_insert_addref(lhs, bm2r);
864 }
bart3772a982008-03-15 08:11:03 +0000865 }
sewardjaf44c822007-11-25 14:01:38 +0000866}
867
868/**
869 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
870 * @param lhs First bitmap.
871 * @param rhs Bitmap to be compared with lhs.
872 * @return !=0 if there are data races, == 0 if there are none.
873 */
874int bm_has_races(const struct bitmap* const lhs,
875 const struct bitmap* const rhs)
876{
bart3772a982008-03-15 08:11:03 +0000877 VG_(OSetGen_ResetIter)(lhs->oset);
878 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000879
bart3772a982008-03-15 08:11:03 +0000880 for (;;)
881 {
bartf647d342008-03-24 19:12:12 +0000882 const struct bitmap2ref* bm2l_ref;
883 const struct bitmap2ref* bm2r_ref;
884 const struct bitmap2* bm2l;
885 const struct bitmap2* bm2r;
bart3772a982008-03-15 08:11:03 +0000886 const struct bitmap1* bm1l;
887 const struct bitmap1* bm1r;
888 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000889
bartf647d342008-03-24 19:12:12 +0000890 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
891 bm2l = bm2l_ref->bm2;
892 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
893 bm2r = bm2r_ref->bm2;
bart3772a982008-03-15 08:11:03 +0000894 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
895 {
896 if (bm2l->addr < bm2r->addr)
bartf647d342008-03-24 19:12:12 +0000897 bm2l = (bm2l_ref = VG_(OSetGen_Next)(lhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000898 else
bartf647d342008-03-24 19:12:12 +0000899 bm2r = (bm2r_ref = VG_(OSetGen_Next)(rhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000900 }
901 if (bm2l == 0 || bm2r == 0)
902 break;
903
904 bm1l = &bm2l->bm1;
905 bm1r = &bm2r->bm1;
906
907 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
908 {
909 unsigned b;
910 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000911 {
barta3f61092008-05-04 07:46:20 +0000912 UWord const access_mask
bart3772a982008-03-15 08:11:03 +0000913 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
914 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
915 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
916 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
917 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
barta3f61092008-05-04 07:46:20 +0000918 if (HAS_RACE(access_mask) && ! drd_is_suppressed(a, a + 1))
bart3772a982008-03-15 08:11:03 +0000919 {
920 return 1;
921 }
sewardjaf44c822007-11-25 14:01:38 +0000922 }
bart3772a982008-03-15 08:11:03 +0000923 }
924 }
925 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000926}
927
sewardjaf44c822007-11-25 14:01:38 +0000928void bm_print(const struct bitmap* const bm)
929{
bart3772a982008-03-15 08:11:03 +0000930 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000931 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000932
bart3772a982008-03-15 08:11:03 +0000933 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000934
bartf647d342008-03-24 19:12:12 +0000935 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000936 {
bartf647d342008-03-24 19:12:12 +0000937 const struct bitmap1* bm1;
bart0008f5b2008-03-22 17:07:39 +0000938 unsigned b;
bartf647d342008-03-24 19:12:12 +0000939
940 bm2 = bm2ref->bm2;
941 bm1 = &bm2->bm1;
bart0008f5b2008-03-22 17:07:39 +0000942 for (b = 0; b < ADDR0_COUNT; b++)
bart3772a982008-03-15 08:11:03 +0000943 {
bart0008f5b2008-03-22 17:07:39 +0000944 const Addr a = (bm2->addr << ADDR0_BITS) | b;
945 const Bool r = bm0_is_set(bm1->bm0_r, b) != 0;
946 const Bool w = bm0_is_set(bm1->bm0_w, b) != 0;
947 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +0000948 {
bart0008f5b2008-03-22 17:07:39 +0000949 VG_(printf)("0x%08lx %c %c\n",
950 a,
951 w ? 'W' : ' ',
952 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +0000953 }
bart3772a982008-03-15 08:11:03 +0000954 }
955 }
sewardjaf44c822007-11-25 14:01:38 +0000956}
957
958ULong bm_get_bitmap_creation_count(void)
959{
bart3772a982008-03-15 08:11:03 +0000960 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000961}
962
bart588d90f2008-04-06 13:05:58 +0000963ULong bm_get_bitmap2_node_creation_count(void)
964{
965 return s_bitmap2_creation_count;
966}
967
sewardjaf44c822007-11-25 14:01:38 +0000968ULong bm_get_bitmap2_creation_count(void)
969{
bart3772a982008-03-15 08:11:03 +0000970 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000971}
972
bartf647d342008-03-24 19:12:12 +0000973/** Allocate and initialize a second level bitmap. */
974static struct bitmap2* bm2_new(const UWord a1)
975{
976 struct bitmap2* bm2;
977
978 bm2 = VG_(malloc)(sizeof(*bm2));
979 bm2->addr = a1;
980 bm2->refcnt = 1;
981
982 s_bitmap2_creation_count++;
983
984 return bm2;
985}
986
987/** Make a copy of a shared second level bitmap such that the copy can be
988 * modified.
989 *
990 * @param a1 client address shifted right by ADDR0_BITS.
991 * @param bm bitmap pointer.
992 */
993static
994struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
995 struct bitmap2ref* const bm2ref)
996{
997 UWord a1;
998 struct bitmap2* bm2;
999 struct bitmap2* bm2_copy;
1000
1001 tl_assert(bm);
1002 tl_assert(bm2ref);
1003 bm2 = bm2ref->bm2;
1004 tl_assert(bm2);
1005 tl_assert(bm2->refcnt > 1);
1006 bm2->refcnt--;
1007 tl_assert(bm2->refcnt >= 1);
1008 a1 = bm2->addr;
1009 bm2_copy = bm2_new(a1);
1010 tl_assert(bm2_copy);
1011 tl_assert(bm2_copy->addr == a1);
1012 tl_assert(bm2_copy->refcnt == 1);
1013 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1));
1014 bm2ref->bm2 = bm2_copy;
1015
1016 bm_update_cache(bm, a1, bm2_copy);
1017
1018 return bm2_copy;
1019}
1020
sewardjaf44c822007-11-25 14:01:38 +00001021static void bm2_merge(struct bitmap2* const bm2l,
1022 const struct bitmap2* const bm2r)
1023{
bart3772a982008-03-15 08:11:03 +00001024 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001025
bart33e56c92008-03-24 06:41:30 +00001026 tl_assert(bm2l);
1027 tl_assert(bm2r);
bart3772a982008-03-15 08:11:03 +00001028 tl_assert(bm2l->addr == bm2r->addr);
bartf647d342008-03-24 19:12:12 +00001029 tl_assert(bm2l->refcnt == 1);
sewardjaf44c822007-11-25 14:01:38 +00001030
bart3772a982008-03-15 08:11:03 +00001031 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1032 {
1033 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1034 }
1035 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1036 {
1037 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1038 }
sewardjaf44c822007-11-25 14:01:38 +00001039}