blob: c02bd49898028031322dba25370bf56a2da0ba80 [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 */
109void bm_access_range(struct bitmap* const bm,
bart9036dea2008-03-13 19:10:06 +0000110 const Addr a1, const Addr a2,
bart0268dfa2008-03-11 20:10:21 +0000111 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000112{
bart3772a982008-03-15 08:11:03 +0000113 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000114
bart3772a982008-03-15 08:11:03 +0000115 tl_assert(bm);
116 tl_assert(a1 < a2);
barta3f61092008-05-04 07:46:20 +0000117 /* The current implementation of bm_access_range does not work for the */
118 /* ADDR0_COUNT highest addresses in the address range. At least on Linux */
119 /* this is not a problem since the upper part of the address space is */
120 /* reserved for the kernel. */
121 tl_assert(a2 + ADDR0_COUNT > a2);
sewardjaf44c822007-11-25 14:01:38 +0000122
bart3772a982008-03-15 08:11:03 +0000123 for (b = a1; b < a2; b = b_next)
124 {
125 Addr b_start;
126 Addr b_end;
127 struct bitmap2* bm2;
128 SPLIT_ADDRESS(b);
bart36556122008-03-13 19:24:30 +0000129
bart3772a982008-03-15 08:11:03 +0000130 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
131 if (b_next > a2)
132 {
133 b_next = a2;
134 }
bart36556122008-03-13 19:24:30 +0000135
bartf647d342008-03-24 19:12:12 +0000136 bm2 = bm2_lookup_or_insert_exclusive(bm, b1);
bart3772a982008-03-15 08:11:03 +0000137 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000138
bart3772a982008-03-15 08:11:03 +0000139 if ((bm2->addr << ADDR0_BITS) < a1)
140 b_start = a1;
141 else
142 if ((bm2->addr << ADDR0_BITS) < a2)
143 b_start = (bm2->addr << ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000144 else
bart3772a982008-03-15 08:11:03 +0000145 break;
146 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000147
bart3772a982008-03-15 08:11:03 +0000148 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
149 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
150 else
151 b_end = a2;
152 tl_assert(a1 <= b_end && b_end <= a2);
153 tl_assert(b_start < b_end);
154 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000155
bart0008f5b2008-03-22 17:07:39 +0000156 if (access_type == eLoad)
bart3772a982008-03-15 08:11:03 +0000157 {
bart0008f5b2008-03-22 17:07:39 +0000158 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart36556122008-03-13 19:24:30 +0000159 {
bart3772a982008-03-15 08:11:03 +0000160 bm0_set(bm2->bm1.bm0_r, b0);
sewardjaf44c822007-11-25 14:01:38 +0000161 }
bart0008f5b2008-03-22 17:07:39 +0000162 }
163 else
164 {
165 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart3772a982008-03-15 08:11:03 +0000166 {
167 bm0_set(bm2->bm1.bm0_w, b0);
168 }
169 }
170 }
sewardjaf44c822007-11-25 14:01:38 +0000171}
172
bart36556122008-03-13 19:24:30 +0000173void bm_access_range_load(struct bitmap* const bm,
174 const Addr a1, const Addr a2)
175{
bart3772a982008-03-15 08:11:03 +0000176 bm_access_range(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000177}
178
barta79df6e2008-03-14 17:07:51 +0000179void bm_access_load_1(struct bitmap* const bm, const Addr a1)
180{
bartf8bc71d2008-03-15 11:42:34 +0000181 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000182}
183
184void bm_access_load_2(struct bitmap* const bm, const Addr a1)
185{
bart3772a982008-03-15 08:11:03 +0000186 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000187 bm_access_aligned_load(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000188 else
189 bm_access_range(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000190}
191
192void bm_access_load_4(struct bitmap* const bm, const Addr a1)
193{
bart3772a982008-03-15 08:11:03 +0000194 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000195 bm_access_aligned_load(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000196 else
197 bm_access_range(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000198}
199
200void bm_access_load_8(struct bitmap* const bm, const Addr a1)
201{
bart3772a982008-03-15 08:11:03 +0000202 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000203 bm_access_aligned_load(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000204 else if ((a1 & 3) == 0)
205 {
bartf8bc71d2008-03-15 11:42:34 +0000206 bm_access_aligned_load(bm, a1 + 0, 4);
207 bm_access_aligned_load(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000208 }
209 else
210 bm_access_range(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000211}
212
bartf5acbbc2008-05-10 08:22:20 +0000213void bm_access_range_store(struct bitmap* const bm,
214 const Addr a1, const Addr a2)
215{
216 bm_access_range(bm, a1, a2, eStore);
217}
218
barta79df6e2008-03-14 17:07:51 +0000219void bm_access_store_1(struct bitmap* const bm, const Addr a1)
220{
bartf8bc71d2008-03-15 11:42:34 +0000221 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000222}
223
224void bm_access_store_2(struct bitmap* const bm, const Addr a1)
225{
bart3772a982008-03-15 08:11:03 +0000226 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000227 bm_access_aligned_store(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000228 else
229 bm_access_range(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000230}
231
232void bm_access_store_4(struct bitmap* const bm, const Addr a1)
233{
bart3772a982008-03-15 08:11:03 +0000234 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000235 bm_access_aligned_store(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000236 else
237 bm_access_range(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000238}
239
240void bm_access_store_8(struct bitmap* const bm, const Addr a1)
241{
bart3772a982008-03-15 08:11:03 +0000242 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000243 bm_access_aligned_store(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000244 else if ((a1 & 3) == 0)
245 {
bartf8bc71d2008-03-15 11:42:34 +0000246 bm_access_aligned_store(bm, a1 + 0, 4);
247 bm_access_aligned_store(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000248 }
249 else
250 bm_access_range(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000251}
252
bart7e81a172008-06-09 19:50:51 +0000253Bool bm_has(struct bitmap* const bm, const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000254 const BmAccessTypeT access_type)
255{
bart3772a982008-03-15 08:11:03 +0000256 Addr b;
257 for (b = a1; b < a2; b++)
258 {
259 if (! bm_has_1(bm, b, access_type))
260 {
261 return False;
262 }
263 }
264 return True;
sewardjaf44c822007-11-25 14:01:38 +0000265}
266
bart7e81a172008-06-09 19:50:51 +0000267Bool bm_has_any_load(struct bitmap* const bm, const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000268{
bartd4907072008-03-30 18:41:07 +0000269 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000270
bart3772a982008-03-15 08:11:03 +0000271 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000272
bartd4907072008-03-30 18:41:07 +0000273 for (b = a1; b < a2; b = b_next)
bart3772a982008-03-15 08:11:03 +0000274 {
bartd4907072008-03-30 18:41:07 +0000275 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
276
277 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
278 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000279 {
bartd4907072008-03-30 18:41:07 +0000280 b_next = a2;
281 }
282
283 if (bm2)
284 {
285 Addr b_start;
286 Addr b_end;
287 UWord b0;
288 const struct bitmap1* const p1 = &bm2->bm1;
289
290 if ((bm2->addr << ADDR0_BITS) < a1)
291 b_start = a1;
292 else
293 if ((bm2->addr << ADDR0_BITS) < a2)
294 b_start = (bm2->addr << ADDR0_BITS);
295 else
296 break;
297 tl_assert(a1 <= b_start && b_start <= a2);
298
299 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
300 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
301 else
302 b_end = a2;
303 tl_assert(a1 <= b_end && b_end <= a2);
304 tl_assert(b_start < b_end);
305 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
306
307 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
308 {
309 if (bm0_is_set(p1->bm0_r, b0))
310 {
311 return True;
312 }
313 }
bart3772a982008-03-15 08:11:03 +0000314 }
315 }
bartd4907072008-03-30 18:41:07 +0000316 return 0;
317}
318
bart7e81a172008-06-09 19:50:51 +0000319Bool bm_has_any_store(struct bitmap* const bm,
bartd4907072008-03-30 18:41:07 +0000320 const Addr a1, const Addr a2)
321{
322 Addr b, b_next;
323
324 tl_assert(bm);
325
326 for (b = a1; b < a2; b = b_next)
327 {
328 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
329
330 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
331 if (b_next > a2)
332 {
333 b_next = a2;
334 }
335
336 if (bm2)
337 {
338 Addr b_start;
339 Addr b_end;
340 UWord b0;
341 const struct bitmap1* const p1 = &bm2->bm1;
342
343 if ((bm2->addr << ADDR0_BITS) < a1)
344 b_start = a1;
345 else
346 if ((bm2->addr << ADDR0_BITS) < a2)
347 b_start = (bm2->addr << ADDR0_BITS);
348 else
349 break;
350 tl_assert(a1 <= b_start && b_start <= a2);
351
352 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
353 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
354 else
355 b_end = a2;
356 tl_assert(a1 <= b_end && b_end <= a2);
357 tl_assert(b_start < b_end);
358 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
359
360 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
361 {
362 if (bm0_is_set(p1->bm0_w, b0))
363 {
364 return True;
365 }
366 }
367 }
368 }
369 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000370}
371
bartc2c81db2008-05-10 11:19:10 +0000372/* Return True if there is a read access, write access or both */
373/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
bart7e81a172008-06-09 19:50:51 +0000374Bool bm_has_any_access(struct bitmap* const bm,
bartc2c81db2008-05-10 11:19:10 +0000375 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000376{
bart3772a982008-03-15 08:11:03 +0000377 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000378
bart3772a982008-03-15 08:11:03 +0000379 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000380
bart3772a982008-03-15 08:11:03 +0000381 for (b = a1; b < a2; b = b_next)
382 {
bartf647d342008-03-24 19:12:12 +0000383 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000384
bart3772a982008-03-15 08:11:03 +0000385 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
386 if (b_next > a2)
387 {
388 b_next = a2;
389 }
sewardjaf44c822007-11-25 14:01:38 +0000390
bart3772a982008-03-15 08:11:03 +0000391 if (bm2)
392 {
393 Addr b_start;
394 Addr b_end;
395 UWord b0;
396 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000397
bart3772a982008-03-15 08:11:03 +0000398 if ((bm2->addr << ADDR0_BITS) < a1)
399 b_start = a1;
400 else
401 if ((bm2->addr << ADDR0_BITS) < a2)
402 b_start = (bm2->addr << ADDR0_BITS);
403 else
404 break;
405 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000406
bart3772a982008-03-15 08:11:03 +0000407 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
408 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
409 else
410 b_end = a2;
411 tl_assert(a1 <= b_end && b_end <= a2);
412 tl_assert(b_start < b_end);
413 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000414
bart3772a982008-03-15 08:11:03 +0000415 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
416 {
bartc2c81db2008-05-10 11:19:10 +0000417 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
bart3772a982008-03-15 08:11:03 +0000418 {
bartc2c81db2008-05-10 11:19:10 +0000419 return True;
bart3772a982008-03-15 08:11:03 +0000420 }
sewardjaf44c822007-11-25 14:01:38 +0000421 }
bart3772a982008-03-15 08:11:03 +0000422 }
423 }
bartc2c81db2008-05-10 11:19:10 +0000424 return False;
sewardjaf44c822007-11-25 14:01:38 +0000425}
426
bartc2c81db2008-05-10 11:19:10 +0000427/** Report whether an access of type access_type at address a is recorded in
428 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000429 */
bart7e81a172008-06-09 19:50:51 +0000430Bool bm_has_1(struct bitmap* const bm,
bartc2c81db2008-05-10 11:19:10 +0000431 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000432{
bartf647d342008-03-24 19:12:12 +0000433 const struct bitmap2* p2;
434 const struct bitmap1* p1;
435 const UWord* p0;
bart3772a982008-03-15 08:11:03 +0000436 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000437
bart3772a982008-03-15 08:11:03 +0000438 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000439
bart11d0b502008-03-22 16:44:03 +0000440 p2 = bm2_lookup(bm, a >> ADDR0_BITS);
bart3772a982008-03-15 08:11:03 +0000441 if (p2)
442 {
443 p1 = &p2->bm1;
444 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
bartc2c81db2008-05-10 11:19:10 +0000445 return bm0_is_set(p0, a0) ? True : False;
bart3772a982008-03-15 08:11:03 +0000446 }
bartc2c81db2008-05-10 11:19:10 +0000447 return False;
sewardjaf44c822007-11-25 14:01:38 +0000448}
449
bart7e81a172008-06-09 19:50:51 +0000450void bm_clear(struct bitmap* const bm,
sewardjaf44c822007-11-25 14:01:38 +0000451 const Addr a1,
452 const Addr a2)
453{
bart3772a982008-03-15 08:11:03 +0000454 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000455
bart3772a982008-03-15 08:11:03 +0000456 tl_assert(bm);
457 tl_assert(a1);
458 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000459
bart3772a982008-03-15 08:11:03 +0000460 for (b = a1; b < a2; b = b_next)
461 {
bartf647d342008-03-24 19:12:12 +0000462 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000463
bart3772a982008-03-15 08:11:03 +0000464 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
465 if (b_next > a2)
466 {
467 b_next = a2;
468 }
469
470 if (p2)
471 {
472 Addr c = b;
bartf647d342008-03-24 19:12:12 +0000473 /* If the first address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000474 /* start on an UWord boundary, start clearing the first addresses. */
bart3772a982008-03-15 08:11:03 +0000475 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000476 {
bart3772a982008-03-15 08:11:03 +0000477 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
478 if (c_next > b_next)
479 c_next = b_next;
bart5955f332008-03-25 17:19:20 +0000480 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, c_next - c);
481 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, c_next - c);
bart3772a982008-03-15 08:11:03 +0000482 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000483 }
bartf647d342008-03-24 19:12:12 +0000484 /* If some UWords have to be cleared entirely, do this now. */
bart3772a982008-03-15 08:11:03 +0000485 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000486 {
bart3772a982008-03-15 08:11:03 +0000487 const Addr c_next = UWORD_MSB(b_next);
488 tl_assert(UWORD_LSB(c) == 0);
489 tl_assert(UWORD_LSB(c_next) == 0);
490 tl_assert(c_next <= b_next);
491 tl_assert(c <= c_next);
492 if (c_next > c)
493 {
494 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
495 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
496 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
497 c = c_next;
498 }
sewardjaf44c822007-11-25 14:01:38 +0000499 }
bartf647d342008-03-24 19:12:12 +0000500 /* If the last address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000501 /* fall on an UWord boundary, clear the last addresses. */
502 /* tl_assert(c <= b_next); */
503 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, b_next - c);
504 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, b_next - c);
bart3772a982008-03-15 08:11:03 +0000505 }
506 }
sewardjaf44c822007-11-25 14:01:38 +0000507}
sewardjaf44c822007-11-25 14:01:38 +0000508
bart9c4224c2008-03-29 14:40:08 +0000509/** Clear all references to loads in bitmap bm starting at address a1 and
510 * up to but not including address a2.
511 */
bart7e81a172008-06-09 19:50:51 +0000512void bm_clear_load(struct bitmap* const bm,
bart9c4224c2008-03-29 14:40:08 +0000513 const Addr a1, const Addr a2)
514{
515 Addr a;
516
517 for (a = a1; a < a2; a++)
518 {
519 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
520 if (p2)
521 {
522 bm0_clear(p2->bm1.bm0_r, a & ADDR0_MASK);
523 }
524 }
525}
526
527/** Clear all references to stores in bitmap bm starting at address a1 and
528 * up to but not including address a2.
529 */
bart7e81a172008-06-09 19:50:51 +0000530void bm_clear_store(struct bitmap* const bm,
bart9c4224c2008-03-29 14:40:08 +0000531 const Addr a1, const Addr a2)
532{
533 Addr a;
534
535 for (a = a1; a < a2; a++)
536 {
537 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
538 if (p2)
539 {
540 bm0_clear(p2->bm1.bm0_w, a & ADDR0_MASK);
541 }
542 }
543}
544
bart8bf2f8b2008-03-30 17:56:43 +0000545/** Clear bitmap bm starting at address a1 and up to but not including address
546 * a2. Return True if and only if any of the addresses was set before
547 * clearing.
548 */
bart7e81a172008-06-09 19:50:51 +0000549Bool bm_test_and_clear(struct bitmap* const bm,
bart8bf2f8b2008-03-30 17:56:43 +0000550 const Addr a1, const Addr a2)
551{
552 Bool result;
553
554 result = bm_has_any_access(bm, a1, a2) != 0;
555 bm_clear(bm, a1, a2);
556 return result;
557}
558
bart7e81a172008-06-09 19:50:51 +0000559Bool bm_has_conflict_with(struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000560 const Addr a1, const Addr a2,
561 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000562{
bart3772a982008-03-15 08:11:03 +0000563 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000564
bart3772a982008-03-15 08:11:03 +0000565 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000566
bart3772a982008-03-15 08:11:03 +0000567 for (b = a1; b < a2; b = b_next)
568 {
bartf647d342008-03-24 19:12:12 +0000569 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000570
bart3772a982008-03-15 08:11:03 +0000571 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
572 if (b_next > a2)
573 {
574 b_next = a2;
575 }
bart36556122008-03-13 19:24:30 +0000576
bart3772a982008-03-15 08:11:03 +0000577 if (bm2)
578 {
579 Addr b_start;
580 Addr b_end;
581 UWord b0;
582 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000583
bart3772a982008-03-15 08:11:03 +0000584 if ((bm2->addr << ADDR0_BITS) < a1)
585 b_start = a1;
586 else
587 if ((bm2->addr << ADDR0_BITS) < a2)
588 b_start = (bm2->addr << ADDR0_BITS);
589 else
590 break;
591 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000592
bart3772a982008-03-15 08:11:03 +0000593 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
594 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
595 else
596 b_end = a2;
597 tl_assert(a1 <= b_end && b_end <= a2);
598 tl_assert(b_start < b_end);
599 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000600
bart3772a982008-03-15 08:11:03 +0000601 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
602 {
603 if (access_type == eLoad)
604 {
605 if (bm0_is_set(p1->bm0_w, b0))
606 {
607 return True;
608 }
609 }
610 else
611 {
612 tl_assert(access_type == eStore);
613 if (bm0_is_set(p1->bm0_r, b0)
614 | bm0_is_set(p1->bm0_w, b0))
615 {
616 return True;
617 }
618 }
sewardjaf44c822007-11-25 14:01:38 +0000619 }
bart3772a982008-03-15 08:11:03 +0000620 }
621 }
622 return False;
sewardjaf44c822007-11-25 14:01:38 +0000623}
624
bart7e81a172008-06-09 19:50:51 +0000625Bool bm_load_has_conflict_with(struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000626 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000627{
bart3772a982008-03-15 08:11:03 +0000628 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000629}
630
bart7e81a172008-06-09 19:50:51 +0000631Bool bm_load_1_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000632{
bartf8bc71d2008-03-15 11:42:34 +0000633 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000634}
635
bart7e81a172008-06-09 19:50:51 +0000636Bool bm_load_2_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000637{
bart3772a982008-03-15 08:11:03 +0000638 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000639 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000640 else
641 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000642}
643
bart7e81a172008-06-09 19:50:51 +0000644Bool bm_load_4_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000645{
bart3772a982008-03-15 08:11:03 +0000646 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000647 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000648 else
649 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000650}
651
bart7e81a172008-06-09 19:50:51 +0000652Bool bm_load_8_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000653{
bart3772a982008-03-15 08:11:03 +0000654 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000655 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000656 else
657 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000658}
659
bart7e81a172008-06-09 19:50:51 +0000660Bool bm_store_1_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000661{
bartf8bc71d2008-03-15 11:42:34 +0000662 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000663}
664
bart7e81a172008-06-09 19:50:51 +0000665Bool bm_store_2_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000666{
bart3772a982008-03-15 08:11:03 +0000667 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000668 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000669 else
670 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000671}
672
bart7e81a172008-06-09 19:50:51 +0000673Bool bm_store_4_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000674{
bart3772a982008-03-15 08:11:03 +0000675 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000676 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000677 else
678 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000679}
680
bart7e81a172008-06-09 19:50:51 +0000681Bool bm_store_8_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000682{
bart3772a982008-03-15 08:11:03 +0000683 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000684 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000685 else
686 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000687}
688
bart7e81a172008-06-09 19:50:51 +0000689Bool bm_store_has_conflict_with(struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000690 const Addr a1, const Addr a2)
691{
bart3772a982008-03-15 08:11:03 +0000692 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000693}
694
bartc2c81db2008-05-10 11:19:10 +0000695/** Return True if the two bitmaps *lhs and *rhs are identical, and false
bart7cd7d7f2008-04-14 16:10:01 +0000696 * if not.
697 */
bart7e81a172008-06-09 19:50:51 +0000698Bool bm_equal(struct bitmap* const lhs, struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000699{
700 struct bitmap2* bm2l;
701 struct bitmap2ref* bm2l_ref;
702 struct bitmap2* bm2r;
703 const struct bitmap2ref* bm2r_ref;
704
barta3f61092008-05-04 07:46:20 +0000705 /* It's not possible to have two independent iterators over the same OSet, */
706 /* so complain if lhs == rhs. */
707 tl_assert(lhs != rhs);
708
bart7cd7d7f2008-04-14 16:10:01 +0000709 VG_(OSetGen_ResetIter)(lhs->oset);
710 VG_(OSetGen_ResetIter)(rhs->oset);
711
712 for ( ; (bm2l_ref = VG_(OSetGen_Next)(lhs->oset)) != 0; )
713 {
bartf5acbbc2008-05-10 08:22:20 +0000714 while (bm2l_ref
715 && (bm2l = bm2l_ref->bm2)
716 && bm2l
717 && ! bm_has_any_access(lhs,
718 bm2l->addr << ADDR0_BITS,
719 (bm2l->addr + 1) << ADDR0_BITS))
720 {
721 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
722 }
723 if (bm2l_ref == 0)
724 break;
bart7cd7d7f2008-04-14 16:10:01 +0000725 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000726#if 0
727 VG_(message)(Vg_DebugMsg, "bm_equal: at 0x%lx", bm2l->addr << ADDR0_BITS);
728#endif
729
bart7cd7d7f2008-04-14 16:10:01 +0000730 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
731 if (bm2r_ref == 0)
barta3f61092008-05-04 07:46:20 +0000732 {
733#if 0
734 VG_(message)(Vg_DebugMsg, "bm_equal: no match found");
735#endif
bart7cd7d7f2008-04-14 16:10:01 +0000736 return False;
barta3f61092008-05-04 07:46:20 +0000737 }
bart7cd7d7f2008-04-14 16:10:01 +0000738 bm2r = bm2r_ref->bm2;
739 tl_assert(bm2r);
740 tl_assert(bm_has_any_access(rhs,
741 bm2r->addr << ADDR0_BITS,
742 (bm2r->addr + 1) << ADDR0_BITS));
barta3f61092008-05-04 07:46:20 +0000743
744 if (bm2l != bm2r
745 && (bm2l->addr != bm2r->addr
746 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
bart7cd7d7f2008-04-14 16:10:01 +0000747 {
barta3f61092008-05-04 07:46:20 +0000748#if 0
749 VG_(message)(Vg_DebugMsg, "bm_equal: rhs 0x%lx -- returning false",
750 bm2r->addr << ADDR0_BITS);
751#endif
bart7cd7d7f2008-04-14 16:10:01 +0000752 return False;
753 }
barta3f61092008-05-04 07:46:20 +0000754 }
755 bm2r = VG_(OSetGen_Next)(rhs->oset);
756 if (bm2r)
757 {
758 tl_assert(bm_has_any_access(rhs,
759 bm2r->addr << ADDR0_BITS,
760 (bm2r->addr + 1) << ADDR0_BITS));
761#if 0
762 VG_(message)(Vg_DebugMsg,
763 "bm_equal: remaining rhs 0x%lx -- returning false",
764 bm2r->addr << ADDR0_BITS);
765#endif
766 return False;
bart7cd7d7f2008-04-14 16:10:01 +0000767 }
768 return True;
769}
770
sewardjaf44c822007-11-25 14:01:38 +0000771void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
772{
bart3772a982008-03-15 08:11:03 +0000773 OSet* const tmp = bm1->oset;
774 bm1->oset = bm2->oset;
775 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000776}
777
bartf647d342008-03-24 19:12:12 +0000778/** Merge bitmaps *lhs and *rhs into *lhs. */
sewardjaf44c822007-11-25 14:01:38 +0000779void bm_merge2(struct bitmap* const lhs,
bart7e81a172008-06-09 19:50:51 +0000780 struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +0000781{
bart3772a982008-03-15 08:11:03 +0000782 struct bitmap2* bm2l;
bartf647d342008-03-24 19:12:12 +0000783 struct bitmap2ref* bm2l_ref;
784 struct bitmap2* bm2r;
785 const struct bitmap2ref* bm2r_ref;
sewardjaf44c822007-11-25 14:01:38 +0000786
bart3772a982008-03-15 08:11:03 +0000787 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000788
bartf647d342008-03-24 19:12:12 +0000789 for ( ; (bm2r_ref = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000790 {
bartf647d342008-03-24 19:12:12 +0000791 bm2r = bm2r_ref->bm2;
792 bm2l_ref = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
793 if (bm2l_ref)
bart3772a982008-03-15 08:11:03 +0000794 {
bartf647d342008-03-24 19:12:12 +0000795 bm2l = bm2l_ref->bm2;
796 if (bm2l != bm2r)
797 {
798 if (bm2l->refcnt > 1)
799 bm2l = bm2_make_exclusive(lhs, bm2l_ref);
800 bm2_merge(bm2l, bm2r);
801 }
802 }
803 else
804 {
805 bm2_insert_addref(lhs, bm2r);
806 }
bart3772a982008-03-15 08:11:03 +0000807 }
sewardjaf44c822007-11-25 14:01:38 +0000808}
809
810/**
811 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
812 * @param lhs First bitmap.
813 * @param rhs Bitmap to be compared with lhs.
814 * @return !=0 if there are data races, == 0 if there are none.
815 */
bart7e81a172008-06-09 19:50:51 +0000816int bm_has_races(struct bitmap* const lhs,
817 struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +0000818{
bart3772a982008-03-15 08:11:03 +0000819 VG_(OSetGen_ResetIter)(lhs->oset);
820 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000821
bart3772a982008-03-15 08:11:03 +0000822 for (;;)
823 {
bartf647d342008-03-24 19:12:12 +0000824 const struct bitmap2ref* bm2l_ref;
825 const struct bitmap2ref* bm2r_ref;
826 const struct bitmap2* bm2l;
827 const struct bitmap2* bm2r;
bart3772a982008-03-15 08:11:03 +0000828 const struct bitmap1* bm1l;
829 const struct bitmap1* bm1r;
830 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000831
bartf647d342008-03-24 19:12:12 +0000832 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
833 bm2l = bm2l_ref->bm2;
834 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
835 bm2r = bm2r_ref->bm2;
bart3772a982008-03-15 08:11:03 +0000836 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
837 {
838 if (bm2l->addr < bm2r->addr)
bartf647d342008-03-24 19:12:12 +0000839 bm2l = (bm2l_ref = VG_(OSetGen_Next)(lhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000840 else
bartf647d342008-03-24 19:12:12 +0000841 bm2r = (bm2r_ref = VG_(OSetGen_Next)(rhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000842 }
843 if (bm2l == 0 || bm2r == 0)
844 break;
845
846 bm1l = &bm2l->bm1;
847 bm1r = &bm2r->bm1;
848
849 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
850 {
851 unsigned b;
852 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000853 {
barta3f61092008-05-04 07:46:20 +0000854 UWord const access_mask
bart3772a982008-03-15 08:11:03 +0000855 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
856 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
857 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
858 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
859 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
barta3f61092008-05-04 07:46:20 +0000860 if (HAS_RACE(access_mask) && ! drd_is_suppressed(a, a + 1))
bart3772a982008-03-15 08:11:03 +0000861 {
862 return 1;
863 }
sewardjaf44c822007-11-25 14:01:38 +0000864 }
bart3772a982008-03-15 08:11:03 +0000865 }
866 }
867 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000868}
869
bart7e81a172008-06-09 19:50:51 +0000870void bm_print(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +0000871{
bart3772a982008-03-15 08:11:03 +0000872 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000873 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000874
bart3772a982008-03-15 08:11:03 +0000875 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000876
bartf647d342008-03-24 19:12:12 +0000877 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000878 {
bartf647d342008-03-24 19:12:12 +0000879 const struct bitmap1* bm1;
bart0008f5b2008-03-22 17:07:39 +0000880 unsigned b;
bartf647d342008-03-24 19:12:12 +0000881
882 bm2 = bm2ref->bm2;
883 bm1 = &bm2->bm1;
bart0008f5b2008-03-22 17:07:39 +0000884 for (b = 0; b < ADDR0_COUNT; b++)
bart3772a982008-03-15 08:11:03 +0000885 {
bart0008f5b2008-03-22 17:07:39 +0000886 const Addr a = (bm2->addr << ADDR0_BITS) | b;
887 const Bool r = bm0_is_set(bm1->bm0_r, b) != 0;
888 const Bool w = bm0_is_set(bm1->bm0_w, b) != 0;
889 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +0000890 {
bart0008f5b2008-03-22 17:07:39 +0000891 VG_(printf)("0x%08lx %c %c\n",
892 a,
893 w ? 'W' : ' ',
894 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +0000895 }
bart3772a982008-03-15 08:11:03 +0000896 }
897 }
sewardjaf44c822007-11-25 14:01:38 +0000898}
899
900ULong bm_get_bitmap_creation_count(void)
901{
bart3772a982008-03-15 08:11:03 +0000902 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000903}
904
bart588d90f2008-04-06 13:05:58 +0000905ULong bm_get_bitmap2_node_creation_count(void)
906{
bart3c9989f2008-06-11 19:17:01 +0000907 return s_bitmap2_node_creation_count;
bart588d90f2008-04-06 13:05:58 +0000908}
909
sewardjaf44c822007-11-25 14:01:38 +0000910ULong bm_get_bitmap2_creation_count(void)
911{
bart3772a982008-03-15 08:11:03 +0000912 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000913}
914
bartf647d342008-03-24 19:12:12 +0000915/** Allocate and initialize a second level bitmap. */
916static struct bitmap2* bm2_new(const UWord a1)
917{
918 struct bitmap2* bm2;
919
920 bm2 = VG_(malloc)(sizeof(*bm2));
921 bm2->addr = a1;
922 bm2->refcnt = 1;
923
924 s_bitmap2_creation_count++;
925
926 return bm2;
927}
928
929/** Make a copy of a shared second level bitmap such that the copy can be
930 * modified.
931 *
932 * @param a1 client address shifted right by ADDR0_BITS.
933 * @param bm bitmap pointer.
934 */
935static
936struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
937 struct bitmap2ref* const bm2ref)
938{
939 UWord a1;
940 struct bitmap2* bm2;
941 struct bitmap2* bm2_copy;
942
943 tl_assert(bm);
944 tl_assert(bm2ref);
945 bm2 = bm2ref->bm2;
946 tl_assert(bm2);
947 tl_assert(bm2->refcnt > 1);
948 bm2->refcnt--;
949 tl_assert(bm2->refcnt >= 1);
950 a1 = bm2->addr;
951 bm2_copy = bm2_new(a1);
952 tl_assert(bm2_copy);
953 tl_assert(bm2_copy->addr == a1);
954 tl_assert(bm2_copy->refcnt == 1);
955 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1));
956 bm2ref->bm2 = bm2_copy;
957
958 bm_update_cache(bm, a1, bm2_copy);
959
960 return bm2_copy;
961}
962
sewardjaf44c822007-11-25 14:01:38 +0000963static void bm2_merge(struct bitmap2* const bm2l,
964 const struct bitmap2* const bm2r)
965{
bart3772a982008-03-15 08:11:03 +0000966 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000967
bart33e56c92008-03-24 06:41:30 +0000968 tl_assert(bm2l);
969 tl_assert(bm2r);
bart3772a982008-03-15 08:11:03 +0000970 tl_assert(bm2l->addr == bm2r->addr);
bartf647d342008-03-24 19:12:12 +0000971 tl_assert(bm2l->refcnt == 1);
sewardjaf44c822007-11-25 14:01:38 +0000972
bart3772a982008-03-15 08:11:03 +0000973 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
974 {
975 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
976 }
977 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
978 {
979 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
980 }
sewardjaf44c822007-11-25 14:01:38 +0000981}