blob: e89cb2367d86f731d32beb63a29fc8de57b2098d [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);
sewardjaf44c822007-11-25 14:01:38 +0000118
bart3772a982008-03-15 08:11:03 +0000119 for (b = a1; b < a2; b = b_next)
120 {
121 Addr b_start;
122 Addr b_end;
123 struct bitmap2* bm2;
124 SPLIT_ADDRESS(b);
bart36556122008-03-13 19:24:30 +0000125
bart3772a982008-03-15 08:11:03 +0000126 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
127 if (b_next > a2)
128 {
129 b_next = a2;
130 }
bart36556122008-03-13 19:24:30 +0000131
bartf647d342008-03-24 19:12:12 +0000132 bm2 = bm2_lookup_or_insert_exclusive(bm, b1);
bart3772a982008-03-15 08:11:03 +0000133 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000134
bart3772a982008-03-15 08:11:03 +0000135 if ((bm2->addr << ADDR0_BITS) < a1)
136 b_start = a1;
137 else
138 if ((bm2->addr << ADDR0_BITS) < a2)
139 b_start = (bm2->addr << ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000140 else
bart3772a982008-03-15 08:11:03 +0000141 break;
142 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000143
bart3772a982008-03-15 08:11:03 +0000144 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
145 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
146 else
147 b_end = a2;
148 tl_assert(a1 <= b_end && b_end <= a2);
149 tl_assert(b_start < b_end);
150 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000151
bart0008f5b2008-03-22 17:07:39 +0000152 if (access_type == eLoad)
bart3772a982008-03-15 08:11:03 +0000153 {
bart0008f5b2008-03-22 17:07:39 +0000154 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart36556122008-03-13 19:24:30 +0000155 {
bart3772a982008-03-15 08:11:03 +0000156 bm0_set(bm2->bm1.bm0_r, b0);
sewardjaf44c822007-11-25 14:01:38 +0000157 }
bart0008f5b2008-03-22 17:07:39 +0000158 }
159 else
160 {
161 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart3772a982008-03-15 08:11:03 +0000162 {
163 bm0_set(bm2->bm1.bm0_w, b0);
164 }
165 }
166 }
sewardjaf44c822007-11-25 14:01:38 +0000167}
168
barta79df6e2008-03-14 17:07:51 +0000169static inline
170void bm_access_aligned_load(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000171 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000172{
bart3772a982008-03-15 08:11:03 +0000173 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000174
bartf647d342008-03-24 19:12:12 +0000175 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000176 bm0_set_range(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000177}
178
179static inline
180void bm_access_aligned_store(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000181 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000182{
bart3772a982008-03-15 08:11:03 +0000183 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000184
bartf647d342008-03-24 19:12:12 +0000185 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000186 bm0_set_range(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000187}
188
bart36556122008-03-13 19:24:30 +0000189void bm_access_range_load(struct bitmap* const bm,
190 const Addr a1, const Addr a2)
191{
bart3772a982008-03-15 08:11:03 +0000192 bm_access_range(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000193}
194
barta79df6e2008-03-14 17:07:51 +0000195void bm_access_load_1(struct bitmap* const bm, const Addr a1)
196{
bartf8bc71d2008-03-15 11:42:34 +0000197 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000198}
199
200void bm_access_load_2(struct bitmap* const bm, const Addr a1)
201{
bart3772a982008-03-15 08:11:03 +0000202 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000203 bm_access_aligned_load(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000204 else
205 bm_access_range(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000206}
207
208void bm_access_load_4(struct bitmap* const bm, const Addr a1)
209{
bart3772a982008-03-15 08:11:03 +0000210 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000211 bm_access_aligned_load(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000212 else
213 bm_access_range(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000214}
215
216void bm_access_load_8(struct bitmap* const bm, const Addr a1)
217{
bart3772a982008-03-15 08:11:03 +0000218 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000219 bm_access_aligned_load(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000220 else if ((a1 & 3) == 0)
221 {
bartf8bc71d2008-03-15 11:42:34 +0000222 bm_access_aligned_load(bm, a1 + 0, 4);
223 bm_access_aligned_load(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000224 }
225 else
226 bm_access_range(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000227}
228
229void bm_access_store_1(struct bitmap* const bm, const Addr a1)
230{
bartf8bc71d2008-03-15 11:42:34 +0000231 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000232}
233
234void bm_access_store_2(struct bitmap* const bm, const Addr a1)
235{
bart3772a982008-03-15 08:11:03 +0000236 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000237 bm_access_aligned_store(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000238 else
239 bm_access_range(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000240}
241
242void bm_access_store_4(struct bitmap* const bm, const Addr a1)
243{
bart3772a982008-03-15 08:11:03 +0000244 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000245 bm_access_aligned_store(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000246 else
247 bm_access_range(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000248}
249
250void bm_access_store_8(struct bitmap* const bm, const Addr a1)
251{
bart3772a982008-03-15 08:11:03 +0000252 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000253 bm_access_aligned_store(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000254 else if ((a1 & 3) == 0)
255 {
bartf8bc71d2008-03-15 11:42:34 +0000256 bm_access_aligned_store(bm, a1 + 0, 4);
257 bm_access_aligned_store(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000258 }
259 else
260 bm_access_range(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000261}
262
bart36556122008-03-13 19:24:30 +0000263void bm_access_range_store(struct bitmap* const bm,
264 const Addr a1, const Addr a2)
265{
bart3772a982008-03-15 08:11:03 +0000266 bm_access_range(bm, a1, a2, eStore);
bart36556122008-03-13 19:24:30 +0000267}
268
269Bool bm_has(const struct bitmap* const bm, const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000270 const BmAccessTypeT access_type)
271{
bart3772a982008-03-15 08:11:03 +0000272 Addr b;
273 for (b = a1; b < a2; b++)
274 {
275 if (! bm_has_1(bm, b, access_type))
276 {
277 return False;
278 }
279 }
280 return True;
sewardjaf44c822007-11-25 14:01:38 +0000281}
282
bartd4907072008-03-30 18:41:07 +0000283Bool bm_has_any_load(const struct bitmap* const bm,
284 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000285{
bartd4907072008-03-30 18:41:07 +0000286 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000287
bart3772a982008-03-15 08:11:03 +0000288 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000289
bartd4907072008-03-30 18:41:07 +0000290 for (b = a1; b < a2; b = b_next)
bart3772a982008-03-15 08:11:03 +0000291 {
bartd4907072008-03-30 18:41:07 +0000292 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
293
294 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
295 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000296 {
bartd4907072008-03-30 18:41:07 +0000297 b_next = a2;
298 }
299
300 if (bm2)
301 {
302 Addr b_start;
303 Addr b_end;
304 UWord b0;
305 const struct bitmap1* const p1 = &bm2->bm1;
306
307 if ((bm2->addr << ADDR0_BITS) < a1)
308 b_start = a1;
309 else
310 if ((bm2->addr << ADDR0_BITS) < a2)
311 b_start = (bm2->addr << ADDR0_BITS);
312 else
313 break;
314 tl_assert(a1 <= b_start && b_start <= a2);
315
316 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
317 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
318 else
319 b_end = a2;
320 tl_assert(a1 <= b_end && b_end <= a2);
321 tl_assert(b_start < b_end);
322 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
323
324 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
325 {
326 if (bm0_is_set(p1->bm0_r, b0))
327 {
328 return True;
329 }
330 }
bart3772a982008-03-15 08:11:03 +0000331 }
332 }
bartd4907072008-03-30 18:41:07 +0000333 return 0;
334}
335
336Bool bm_has_any_store(const struct bitmap* const bm,
337 const Addr a1, const Addr a2)
338{
339 Addr b, b_next;
340
341 tl_assert(bm);
342
343 for (b = a1; b < a2; b = b_next)
344 {
345 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
346
347 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
348 if (b_next > a2)
349 {
350 b_next = a2;
351 }
352
353 if (bm2)
354 {
355 Addr b_start;
356 Addr b_end;
357 UWord b0;
358 const struct bitmap1* const p1 = &bm2->bm1;
359
360 if ((bm2->addr << ADDR0_BITS) < a1)
361 b_start = a1;
362 else
363 if ((bm2->addr << ADDR0_BITS) < a2)
364 b_start = (bm2->addr << ADDR0_BITS);
365 else
366 break;
367 tl_assert(a1 <= b_start && b_start <= a2);
368
369 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
370 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
371 else
372 b_end = a2;
373 tl_assert(a1 <= b_end && b_end <= a2);
374 tl_assert(b_start < b_end);
375 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
376
377 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
378 {
379 if (bm0_is_set(p1->bm0_w, b0))
380 {
381 return True;
382 }
383 }
384 }
385 }
386 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000387}
388
389/* Return a non-zero value if there is a read access, write access or both */
390/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
391UWord bm_has_any_access(const struct bitmap* const bm,
392 const Addr a1,
393 const Addr a2)
394{
bart3772a982008-03-15 08:11:03 +0000395 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000396
bart3772a982008-03-15 08:11:03 +0000397 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000398
bart3772a982008-03-15 08:11:03 +0000399 for (b = a1; b < a2; b = b_next)
400 {
bartf647d342008-03-24 19:12:12 +0000401 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000402
bart3772a982008-03-15 08:11:03 +0000403 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
404 if (b_next > a2)
405 {
406 b_next = a2;
407 }
sewardjaf44c822007-11-25 14:01:38 +0000408
bart3772a982008-03-15 08:11:03 +0000409 if (bm2)
410 {
411 Addr b_start;
412 Addr b_end;
413 UWord b0;
414 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000415
bart3772a982008-03-15 08:11:03 +0000416 if ((bm2->addr << ADDR0_BITS) < a1)
417 b_start = a1;
418 else
419 if ((bm2->addr << ADDR0_BITS) < a2)
420 b_start = (bm2->addr << ADDR0_BITS);
421 else
422 break;
423 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000424
bart3772a982008-03-15 08:11:03 +0000425 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
426 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
427 else
428 b_end = a2;
429 tl_assert(a1 <= b_end && b_end <= a2);
430 tl_assert(b_start < b_end);
431 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000432
bart3772a982008-03-15 08:11:03 +0000433 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
434 {
435 const UWord mask
436 = bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0);
437 if (mask)
438 {
439 return mask;
440 }
sewardjaf44c822007-11-25 14:01:38 +0000441 }
bart3772a982008-03-15 08:11:03 +0000442 }
443 }
444 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000445}
446
447/**
448 * Report whether an access of type access_type at address a is recorded in
449 * bitmap bm.
450 * @return != 0 means true, and == 0 means false
451 */
452UWord bm_has_1(const struct bitmap* const bm,
453 const Addr a,
454 const BmAccessTypeT access_type)
455{
bartf647d342008-03-24 19:12:12 +0000456 const struct bitmap2* p2;
457 const struct bitmap1* p1;
458 const UWord* p0;
bart3772a982008-03-15 08:11:03 +0000459 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000460
bart3772a982008-03-15 08:11:03 +0000461 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000462
bart11d0b502008-03-22 16:44:03 +0000463 p2 = bm2_lookup(bm, a >> ADDR0_BITS);
bart3772a982008-03-15 08:11:03 +0000464 if (p2)
465 {
466 p1 = &p2->bm1;
467 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
468 return bm0_is_set(p0, a0);
469 }
470 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000471}
472
sewardjaf44c822007-11-25 14:01:38 +0000473void bm_clear(const struct bitmap* const bm,
474 const Addr a1,
475 const Addr a2)
476{
bart3772a982008-03-15 08:11:03 +0000477 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000478
bart3772a982008-03-15 08:11:03 +0000479 tl_assert(bm);
480 tl_assert(a1);
481 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000482
bart3772a982008-03-15 08:11:03 +0000483 for (b = a1; b < a2; b = b_next)
484 {
bartf647d342008-03-24 19:12:12 +0000485 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000486
bart3772a982008-03-15 08:11:03 +0000487 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
488 if (b_next > a2)
489 {
490 b_next = a2;
491 }
492
493 if (p2)
494 {
495 Addr c = b;
bartf647d342008-03-24 19:12:12 +0000496 /* If the first address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000497 /* start on an UWord boundary, start clearing the first addresses. */
bart3772a982008-03-15 08:11:03 +0000498 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000499 {
bart3772a982008-03-15 08:11:03 +0000500 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
501 if (c_next > b_next)
502 c_next = b_next;
bart5955f332008-03-25 17:19:20 +0000503 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, c_next - c);
504 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, c_next - c);
bart3772a982008-03-15 08:11:03 +0000505 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000506 }
bartf647d342008-03-24 19:12:12 +0000507 /* If some UWords have to be cleared entirely, do this now. */
bart3772a982008-03-15 08:11:03 +0000508 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000509 {
bart3772a982008-03-15 08:11:03 +0000510 const Addr c_next = UWORD_MSB(b_next);
511 tl_assert(UWORD_LSB(c) == 0);
512 tl_assert(UWORD_LSB(c_next) == 0);
513 tl_assert(c_next <= b_next);
514 tl_assert(c <= c_next);
515 if (c_next > c)
516 {
517 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
518 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
519 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
520 c = c_next;
521 }
sewardjaf44c822007-11-25 14:01:38 +0000522 }
bartf647d342008-03-24 19:12:12 +0000523 /* If the last address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000524 /* fall on an UWord boundary, clear the last addresses. */
525 /* tl_assert(c <= b_next); */
526 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, b_next - c);
527 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, b_next - c);
bart3772a982008-03-15 08:11:03 +0000528 }
529 }
sewardjaf44c822007-11-25 14:01:38 +0000530}
sewardjaf44c822007-11-25 14:01:38 +0000531
bart9c4224c2008-03-29 14:40:08 +0000532/** Clear all references to loads in bitmap bm starting at address a1 and
533 * up to but not including address a2.
534 */
535void bm_clear_load(const struct bitmap* const bm,
536 const Addr a1, const Addr a2)
537{
538 Addr a;
539
540 for (a = a1; a < a2; a++)
541 {
542 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
543 if (p2)
544 {
545 bm0_clear(p2->bm1.bm0_r, a & ADDR0_MASK);
546 }
547 }
548}
549
550/** Clear all references to stores in bitmap bm starting at address a1 and
551 * up to but not including address a2.
552 */
553void bm_clear_store(const struct bitmap* const bm,
554 const Addr a1, const Addr a2)
555{
556 Addr a;
557
558 for (a = a1; a < a2; a++)
559 {
560 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
561 if (p2)
562 {
563 bm0_clear(p2->bm1.bm0_w, a & ADDR0_MASK);
564 }
565 }
566}
567
bart8bf2f8b2008-03-30 17:56:43 +0000568/** Clear bitmap bm starting at address a1 and up to but not including address
569 * a2. Return True if and only if any of the addresses was set before
570 * clearing.
571 */
572Bool bm_test_and_clear(const struct bitmap* const bm,
573 const Addr a1, const Addr a2)
574{
575 Bool result;
576
577 result = bm_has_any_access(bm, a1, a2) != 0;
578 bm_clear(bm, a1, a2);
579 return result;
580}
581
bart36556122008-03-13 19:24:30 +0000582Bool bm_has_conflict_with(const struct bitmap* const bm,
583 const Addr a1, const Addr a2,
584 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000585{
bart3772a982008-03-15 08:11:03 +0000586 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000587
bart3772a982008-03-15 08:11:03 +0000588 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000589
bart3772a982008-03-15 08:11:03 +0000590 for (b = a1; b < a2; b = b_next)
591 {
bartf647d342008-03-24 19:12:12 +0000592 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000593
bart3772a982008-03-15 08:11:03 +0000594 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
595 if (b_next > a2)
596 {
597 b_next = a2;
598 }
bart36556122008-03-13 19:24:30 +0000599
bart3772a982008-03-15 08:11:03 +0000600 if (bm2)
601 {
602 Addr b_start;
603 Addr b_end;
604 UWord b0;
605 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000606
bart3772a982008-03-15 08:11:03 +0000607 if ((bm2->addr << ADDR0_BITS) < a1)
608 b_start = a1;
609 else
610 if ((bm2->addr << ADDR0_BITS) < a2)
611 b_start = (bm2->addr << ADDR0_BITS);
612 else
613 break;
614 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000615
bart3772a982008-03-15 08:11:03 +0000616 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
617 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
618 else
619 b_end = a2;
620 tl_assert(a1 <= b_end && b_end <= a2);
621 tl_assert(b_start < b_end);
622 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000623
bart3772a982008-03-15 08:11:03 +0000624 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
625 {
626 if (access_type == eLoad)
627 {
628 if (bm0_is_set(p1->bm0_w, b0))
629 {
630 return True;
631 }
632 }
633 else
634 {
635 tl_assert(access_type == eStore);
636 if (bm0_is_set(p1->bm0_r, b0)
637 | bm0_is_set(p1->bm0_w, b0))
638 {
639 return True;
640 }
641 }
sewardjaf44c822007-11-25 14:01:38 +0000642 }
bart3772a982008-03-15 08:11:03 +0000643 }
644 }
645 return False;
sewardjaf44c822007-11-25 14:01:38 +0000646}
647
barta79df6e2008-03-14 17:07:51 +0000648static inline
649Bool bm_aligned_load_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000650 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000651{
bartf647d342008-03-24 19:12:12 +0000652 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000653
bart11d0b502008-03-22 16:44:03 +0000654 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000655
bartf8bc71d2008-03-15 11:42:34 +0000656 return (bm2 && bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size));
barta79df6e2008-03-14 17:07:51 +0000657}
658
659static inline
660Bool bm_aligned_store_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000661 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000662{
bartf647d342008-03-24 19:12:12 +0000663 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000664
bart11d0b502008-03-22 16:44:03 +0000665 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000666
bart3772a982008-03-15 08:11:03 +0000667 if (bm2)
668 {
bartf8bc71d2008-03-15 11:42:34 +0000669 if (bm0_is_any_set(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size)
670 | bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size))
bart3772a982008-03-15 08:11:03 +0000671 {
672 return True;
673 }
674 }
675 return False;
barta79df6e2008-03-14 17:07:51 +0000676}
677
bart36556122008-03-13 19:24:30 +0000678Bool bm_load_has_conflict_with(const struct bitmap* const bm,
679 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000680{
bart3772a982008-03-15 08:11:03 +0000681 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000682}
683
barta79df6e2008-03-14 17:07:51 +0000684Bool bm_load_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
685{
bartf8bc71d2008-03-15 11:42:34 +0000686 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000687}
688
689Bool bm_load_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
690{
bart3772a982008-03-15 08:11:03 +0000691 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000692 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000693 else
694 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000695}
696
697Bool bm_load_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
698{
bart3772a982008-03-15 08:11:03 +0000699 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000700 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000701 else
702 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000703}
704
705Bool bm_load_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
706{
bart3772a982008-03-15 08:11:03 +0000707 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000708 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000709 else
710 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000711}
712
713Bool bm_store_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
714{
bartf8bc71d2008-03-15 11:42:34 +0000715 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000716}
717
718Bool bm_store_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
719{
bart3772a982008-03-15 08:11:03 +0000720 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000721 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000722 else
723 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000724}
725
726Bool bm_store_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
727{
bart3772a982008-03-15 08:11:03 +0000728 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000729 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000730 else
731 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000732}
733
734Bool bm_store_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
735{
bart3772a982008-03-15 08:11:03 +0000736 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000737 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000738 else
739 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000740}
741
bart36556122008-03-13 19:24:30 +0000742Bool bm_store_has_conflict_with(const struct bitmap* const bm,
743 const Addr a1, const Addr a2)
744{
bart3772a982008-03-15 08:11:03 +0000745 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000746}
747
bart7cd7d7f2008-04-14 16:10:01 +0000748/** Return true if the two bitmaps *lhs and *rhs are identical, and false
749 * if not.
750 */
751Bool bm_compare(struct bitmap* const lhs,
752 const struct bitmap* const rhs)
753{
754 struct bitmap2* bm2l;
755 struct bitmap2ref* bm2l_ref;
756 struct bitmap2* bm2r;
757 const struct bitmap2ref* bm2r_ref;
758
759 VG_(OSetGen_ResetIter)(lhs->oset);
760 VG_(OSetGen_ResetIter)(rhs->oset);
761
762 for ( ; (bm2l_ref = VG_(OSetGen_Next)(lhs->oset)) != 0; )
763 {
764 bm2l = bm2l_ref->bm2;
765 tl_assert(bm2l);
766 tl_assert(bm_has_any_access(lhs,
767 bm2l->addr << ADDR0_BITS,
768 (bm2l->addr + 1) << ADDR0_BITS));
769 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
770 if (bm2r_ref == 0)
771 return False;
772 bm2r = bm2r_ref->bm2;
773 tl_assert(bm2r);
774 tl_assert(bm_has_any_access(rhs,
775 bm2r->addr << ADDR0_BITS,
776 (bm2r->addr + 1) << ADDR0_BITS));
777 if (bm2l->addr != bm2r->addr
778 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0)
779 {
780 return False;
781 }
782 bm2r = VG_(OSetGen_Next)(rhs->oset);
783 if (bm2r)
784 {
785 tl_assert(bm_has_any_access(rhs,
786 bm2r->addr << ADDR0_BITS,
787 (bm2r->addr + 1) << ADDR0_BITS));
788 return False;
789 }
790 }
791 return True;
792}
793
sewardjaf44c822007-11-25 14:01:38 +0000794void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
795{
bart3772a982008-03-15 08:11:03 +0000796 OSet* const tmp = bm1->oset;
797 bm1->oset = bm2->oset;
798 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000799}
800
bartf647d342008-03-24 19:12:12 +0000801/** Merge bitmaps *lhs and *rhs into *lhs. */
sewardjaf44c822007-11-25 14:01:38 +0000802void bm_merge2(struct bitmap* const lhs,
803 const struct bitmap* const rhs)
804{
bart3772a982008-03-15 08:11:03 +0000805 struct bitmap2* bm2l;
bartf647d342008-03-24 19:12:12 +0000806 struct bitmap2ref* bm2l_ref;
807 struct bitmap2* bm2r;
808 const struct bitmap2ref* bm2r_ref;
sewardjaf44c822007-11-25 14:01:38 +0000809
bart3772a982008-03-15 08:11:03 +0000810 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000811
bartf647d342008-03-24 19:12:12 +0000812 for ( ; (bm2r_ref = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000813 {
bartf647d342008-03-24 19:12:12 +0000814 bm2r = bm2r_ref->bm2;
815 bm2l_ref = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
816 if (bm2l_ref)
bart3772a982008-03-15 08:11:03 +0000817 {
bartf647d342008-03-24 19:12:12 +0000818 bm2l = bm2l_ref->bm2;
819 if (bm2l != bm2r)
820 {
821 if (bm2l->refcnt > 1)
822 bm2l = bm2_make_exclusive(lhs, bm2l_ref);
823 bm2_merge(bm2l, bm2r);
824 }
825 }
826 else
827 {
828 bm2_insert_addref(lhs, bm2r);
829 }
bart3772a982008-03-15 08:11:03 +0000830 }
sewardjaf44c822007-11-25 14:01:38 +0000831}
832
833/**
834 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
835 * @param lhs First bitmap.
836 * @param rhs Bitmap to be compared with lhs.
837 * @return !=0 if there are data races, == 0 if there are none.
838 */
839int bm_has_races(const struct bitmap* const lhs,
840 const struct bitmap* const rhs)
841{
bart3772a982008-03-15 08:11:03 +0000842 VG_(OSetGen_ResetIter)(lhs->oset);
843 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000844
bart3772a982008-03-15 08:11:03 +0000845 for (;;)
846 {
bartf647d342008-03-24 19:12:12 +0000847 const struct bitmap2ref* bm2l_ref;
848 const struct bitmap2ref* bm2r_ref;
849 const struct bitmap2* bm2l;
850 const struct bitmap2* bm2r;
bart3772a982008-03-15 08:11:03 +0000851 const struct bitmap1* bm1l;
852 const struct bitmap1* bm1r;
853 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000854
bartf647d342008-03-24 19:12:12 +0000855 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
856 bm2l = bm2l_ref->bm2;
857 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
858 bm2r = bm2r_ref->bm2;
bart3772a982008-03-15 08:11:03 +0000859 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
860 {
861 if (bm2l->addr < bm2r->addr)
bartf647d342008-03-24 19:12:12 +0000862 bm2l = (bm2l_ref = VG_(OSetGen_Next)(lhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000863 else
bartf647d342008-03-24 19:12:12 +0000864 bm2r = (bm2r_ref = VG_(OSetGen_Next)(rhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000865 }
866 if (bm2l == 0 || bm2r == 0)
867 break;
868
869 bm1l = &bm2l->bm1;
870 bm1r = &bm2r->bm1;
871
872 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
873 {
874 unsigned b;
875 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000876 {
bart3772a982008-03-15 08:11:03 +0000877 UWord const access
878 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
879 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
880 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
881 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
882 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
883 if (HAS_RACE(access) && ! drd_is_suppressed(a, a + 1))
884 {
885 return 1;
886 }
sewardjaf44c822007-11-25 14:01:38 +0000887 }
bart3772a982008-03-15 08:11:03 +0000888 }
889 }
890 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000891}
892
sewardjaf44c822007-11-25 14:01:38 +0000893void bm_print(const struct bitmap* const bm)
894{
bart3772a982008-03-15 08:11:03 +0000895 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000896 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000897
bart3772a982008-03-15 08:11:03 +0000898 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000899
bartf647d342008-03-24 19:12:12 +0000900 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000901 {
bartf647d342008-03-24 19:12:12 +0000902 const struct bitmap1* bm1;
bart0008f5b2008-03-22 17:07:39 +0000903 unsigned b;
bartf647d342008-03-24 19:12:12 +0000904
905 bm2 = bm2ref->bm2;
906 bm1 = &bm2->bm1;
bart0008f5b2008-03-22 17:07:39 +0000907 for (b = 0; b < ADDR0_COUNT; b++)
bart3772a982008-03-15 08:11:03 +0000908 {
bart0008f5b2008-03-22 17:07:39 +0000909 const Addr a = (bm2->addr << ADDR0_BITS) | b;
910 const Bool r = bm0_is_set(bm1->bm0_r, b) != 0;
911 const Bool w = bm0_is_set(bm1->bm0_w, b) != 0;
912 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +0000913 {
bart0008f5b2008-03-22 17:07:39 +0000914 VG_(printf)("0x%08lx %c %c\n",
915 a,
916 w ? 'W' : ' ',
917 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +0000918 }
bart3772a982008-03-15 08:11:03 +0000919 }
920 }
sewardjaf44c822007-11-25 14:01:38 +0000921}
922
923ULong bm_get_bitmap_creation_count(void)
924{
bart3772a982008-03-15 08:11:03 +0000925 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000926}
927
bart588d90f2008-04-06 13:05:58 +0000928ULong bm_get_bitmap2_node_creation_count(void)
929{
930 return s_bitmap2_creation_count;
931}
932
sewardjaf44c822007-11-25 14:01:38 +0000933ULong bm_get_bitmap2_creation_count(void)
934{
bart3772a982008-03-15 08:11:03 +0000935 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000936}
937
bartf647d342008-03-24 19:12:12 +0000938/** Allocate and initialize a second level bitmap. */
939static struct bitmap2* bm2_new(const UWord a1)
940{
941 struct bitmap2* bm2;
942
943 bm2 = VG_(malloc)(sizeof(*bm2));
944 bm2->addr = a1;
945 bm2->refcnt = 1;
946
947 s_bitmap2_creation_count++;
948
949 return bm2;
950}
951
952/** Make a copy of a shared second level bitmap such that the copy can be
953 * modified.
954 *
955 * @param a1 client address shifted right by ADDR0_BITS.
956 * @param bm bitmap pointer.
957 */
958static
959struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
960 struct bitmap2ref* const bm2ref)
961{
962 UWord a1;
963 struct bitmap2* bm2;
964 struct bitmap2* bm2_copy;
965
966 tl_assert(bm);
967 tl_assert(bm2ref);
968 bm2 = bm2ref->bm2;
969 tl_assert(bm2);
970 tl_assert(bm2->refcnt > 1);
971 bm2->refcnt--;
972 tl_assert(bm2->refcnt >= 1);
973 a1 = bm2->addr;
974 bm2_copy = bm2_new(a1);
975 tl_assert(bm2_copy);
976 tl_assert(bm2_copy->addr == a1);
977 tl_assert(bm2_copy->refcnt == 1);
978 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1));
979 bm2ref->bm2 = bm2_copy;
980
981 bm_update_cache(bm, a1, bm2_copy);
982
983 return bm2_copy;
984}
985
sewardjaf44c822007-11-25 14:01:38 +0000986static void bm2_merge(struct bitmap2* const bm2l,
987 const struct bitmap2* const bm2r)
988{
bart3772a982008-03-15 08:11:03 +0000989 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000990
bart33e56c92008-03-24 06:41:30 +0000991 tl_assert(bm2l);
992 tl_assert(bm2r);
bart3772a982008-03-15 08:11:03 +0000993 tl_assert(bm2l->addr == bm2r->addr);
bartf647d342008-03-24 19:12:12 +0000994 tl_assert(bm2l->refcnt == 1);
sewardjaf44c822007-11-25 14:01:38 +0000995
bart3772a982008-03-15 08:11:03 +0000996 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
997 {
998 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
999 }
1000 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1001 {
1002 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1003 }
sewardjaf44c822007-11-25 14:01:38 +00001004}
1005
1006#if 0
1007
1008/* Unit test */
1009static
1010struct { Addr address; SizeT size; BmAccessTypeT access_type; }
bart3772a982008-03-15 08:11:03 +00001011 s_args[] = {
bart0008f5b2008-03-22 17:07:39 +00001012 { 0 + ADDR0_COUNT, 1, eLoad },
1013 { 666 + ADDR0_COUNT, 4, eLoad },
1014 { 667 + ADDR0_COUNT, 2, eStore },
bart33e56c92008-03-24 06:41:30 +00001015 { -2 + 2*ADDR0_COUNT, 1, eStore },
bart0008f5b2008-03-22 17:07:39 +00001016 { 0x0001ffffUL, 1, eLoad },
1017 { 0x0002ffffUL, 1, eLoad },
1018 { 0x00ffffffUL, 1, eLoad },
1019 { 0xffffffffUL, 1, eStore },
bart3772a982008-03-15 08:11:03 +00001020 };
sewardjaf44c822007-11-25 14:01:38 +00001021
1022void bm_test(void)
1023{
bart3772a982008-03-15 08:11:03 +00001024 struct bitmap* bm;
1025 struct bitmap* bm2;
bart0008f5b2008-03-22 17:07:39 +00001026 unsigned i, j;
sewardjaf44c822007-11-25 14:01:38 +00001027
bart3772a982008-03-15 08:11:03 +00001028 VG_(printf)("Start of DRD BM unit test.\n");
sewardjaf44c822007-11-25 14:01:38 +00001029
bart3772a982008-03-15 08:11:03 +00001030 bm = bm_new();
sewardjaf44c822007-11-25 14:01:38 +00001031
bart3772a982008-03-15 08:11:03 +00001032 for (i = 0; i < sizeof(s_args)/sizeof(s_args[0]); i++)
1033 {
1034 bm_access_range(bm,
1035 s_args[i].address,
1036 s_args[i].address + s_args[i].size,
1037 s_args[i].access_type);
1038 }
sewardjaf44c822007-11-25 14:01:38 +00001039
bart3772a982008-03-15 08:11:03 +00001040 VG_(printf)("Map contents -- should contain 10 addresses:\n");
1041 bm_print(bm);
sewardjaf44c822007-11-25 14:01:38 +00001042
bart3772a982008-03-15 08:11:03 +00001043 for (i = 0; i < sizeof(s_args)/sizeof(s_args[0]); i++)
1044 {
1045 for (j = 0; j < s_args[i].size; j++)
1046 {
1047 tl_assert(bm_has_1(bm, s_args[i].address + j, s_args[i].access_type));
1048 }
1049 }
sewardjaf44c822007-11-25 14:01:38 +00001050
bart3772a982008-03-15 08:11:03 +00001051 VG_(printf)("Merge result:\n");
bart0008f5b2008-03-22 17:07:39 +00001052 bm2 = bm_new();
1053 bm_merge2(bm2, bm);
1054 bm_merge2(bm2, bm);
bart3772a982008-03-15 08:11:03 +00001055 bm_print(bm);
sewardjaf44c822007-11-25 14:01:38 +00001056
bart0008f5b2008-03-22 17:07:39 +00001057 VG_(printf)("Deleting bitmap bm\n");
bart3772a982008-03-15 08:11:03 +00001058 bm_delete(bm);
bart0008f5b2008-03-22 17:07:39 +00001059 VG_(printf)("Deleting bitmap bm2\n");
bart3772a982008-03-15 08:11:03 +00001060 bm_delete(bm2);
sewardjaf44c822007-11-25 14:01:38 +00001061
bart3772a982008-03-15 08:11:03 +00001062 VG_(printf)("End of DRD BM unit test.\n");
sewardjaf44c822007-11-25 14:01:38 +00001063}
1064#endif