blob: 90e7ad5fd2ff76cc0d820b224813d20e7e082f71 [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
bart3772a982008-03-15 08:11:03 +000062 // If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD
63 // in drd_bitmap.h.
64 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);
bart33e56c92008-03-24 06:41:30 +000068 for (i = 0; i < N_CACHE_ELEM; i++)
69 {
70 bm->cache[i].a1 = 0;
71 bm->cache[i].bm2 = 0;
72 }
bartf647d342008-03-24 19:12:12 +000073 bm->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free));
sewardjaf44c822007-11-25 14:01:38 +000074
bart3772a982008-03-15 08:11:03 +000075 s_bitmap_creation_count++;
sewardjaf44c822007-11-25 14:01:38 +000076
bart3772a982008-03-15 08:11:03 +000077 return bm;
sewardjaf44c822007-11-25 14:01:38 +000078}
79
80void bm_delete(struct bitmap* const bm)
81{
bartf647d342008-03-24 19:12:12 +000082 struct bitmap2* bm2;
83 struct bitmap2ref* bm2ref;
84
bart3772a982008-03-15 08:11:03 +000085 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000086
87 VG_(OSetGen_ResetIter)(bm->oset);
88 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
89 {
90 bm2 = bm2ref->bm2;
91 tl_assert(bm2->refcnt >= 1);
92 if (--bm2->refcnt == 0)
93 {
94 VG_(free)(bm2);
95 }
96 }
97
bart3772a982008-03-15 08:11:03 +000098 VG_(OSetGen_Destroy)(bm->oset);
99 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +0000100}
101
102/**
bart36556122008-03-13 19:24:30 +0000103 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000104 * bitmap bm.
105 */
barta79df6e2008-03-14 17:07:51 +0000106static
sewardjaf44c822007-11-25 14:01:38 +0000107void bm_access_range(struct bitmap* const bm,
bart9036dea2008-03-13 19:10:06 +0000108 const Addr a1, const Addr a2,
bart0268dfa2008-03-11 20:10:21 +0000109 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000110{
bart3772a982008-03-15 08:11:03 +0000111 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000112
bart3772a982008-03-15 08:11:03 +0000113 tl_assert(bm);
114 tl_assert(a1 < a2);
sewardjaf44c822007-11-25 14:01:38 +0000115
bart3772a982008-03-15 08:11:03 +0000116 for (b = a1; b < a2; b = b_next)
117 {
118 Addr b_start;
119 Addr b_end;
120 struct bitmap2* bm2;
121 SPLIT_ADDRESS(b);
bart36556122008-03-13 19:24:30 +0000122
bart3772a982008-03-15 08:11:03 +0000123 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
124 if (b_next > a2)
125 {
126 b_next = a2;
127 }
bart36556122008-03-13 19:24:30 +0000128
bartf647d342008-03-24 19:12:12 +0000129 bm2 = bm2_lookup_or_insert_exclusive(bm, b1);
bart3772a982008-03-15 08:11:03 +0000130 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000131
bart3772a982008-03-15 08:11:03 +0000132 if ((bm2->addr << ADDR0_BITS) < a1)
133 b_start = a1;
134 else
135 if ((bm2->addr << ADDR0_BITS) < a2)
136 b_start = (bm2->addr << ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000137 else
bart3772a982008-03-15 08:11:03 +0000138 break;
139 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000140
bart3772a982008-03-15 08:11:03 +0000141 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
142 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
143 else
144 b_end = a2;
145 tl_assert(a1 <= b_end && b_end <= a2);
146 tl_assert(b_start < b_end);
147 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000148
bart0008f5b2008-03-22 17:07:39 +0000149 if (access_type == eLoad)
bart3772a982008-03-15 08:11:03 +0000150 {
bart0008f5b2008-03-22 17:07:39 +0000151 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart36556122008-03-13 19:24:30 +0000152 {
bart3772a982008-03-15 08:11:03 +0000153 bm0_set(bm2->bm1.bm0_r, b0);
sewardjaf44c822007-11-25 14:01:38 +0000154 }
bart0008f5b2008-03-22 17:07:39 +0000155 }
156 else
157 {
158 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart3772a982008-03-15 08:11:03 +0000159 {
160 bm0_set(bm2->bm1.bm0_w, b0);
161 }
162 }
163 }
sewardjaf44c822007-11-25 14:01:38 +0000164}
165
barta79df6e2008-03-14 17:07:51 +0000166static inline
167void bm_access_aligned_load(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000168 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000169{
bart3772a982008-03-15 08:11:03 +0000170 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000171
bartf647d342008-03-24 19:12:12 +0000172 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000173 bm0_set_range(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000174}
175
176static inline
177void bm_access_aligned_store(struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000178 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000179{
bart3772a982008-03-15 08:11:03 +0000180 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000181
bartf647d342008-03-24 19:12:12 +0000182 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
bartf8bc71d2008-03-15 11:42:34 +0000183 bm0_set_range(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size);
barta79df6e2008-03-14 17:07:51 +0000184}
185
bart36556122008-03-13 19:24:30 +0000186void bm_access_range_load(struct bitmap* const bm,
187 const Addr a1, const Addr a2)
188{
bart3772a982008-03-15 08:11:03 +0000189 bm_access_range(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000190}
191
barta79df6e2008-03-14 17:07:51 +0000192void bm_access_load_1(struct bitmap* const bm, const Addr a1)
193{
bartf8bc71d2008-03-15 11:42:34 +0000194 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000195}
196
197void bm_access_load_2(struct bitmap* const bm, const Addr a1)
198{
bart3772a982008-03-15 08:11:03 +0000199 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000200 bm_access_aligned_load(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000201 else
202 bm_access_range(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000203}
204
205void bm_access_load_4(struct bitmap* const bm, const Addr a1)
206{
bart3772a982008-03-15 08:11:03 +0000207 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000208 bm_access_aligned_load(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000209 else
210 bm_access_range(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000211}
212
213void bm_access_load_8(struct bitmap* const bm, const Addr a1)
214{
bart3772a982008-03-15 08:11:03 +0000215 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000216 bm_access_aligned_load(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000217 else if ((a1 & 3) == 0)
218 {
bartf8bc71d2008-03-15 11:42:34 +0000219 bm_access_aligned_load(bm, a1 + 0, 4);
220 bm_access_aligned_load(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000221 }
222 else
223 bm_access_range(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000224}
225
226void bm_access_store_1(struct bitmap* const bm, const Addr a1)
227{
bartf8bc71d2008-03-15 11:42:34 +0000228 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000229}
230
231void bm_access_store_2(struct bitmap* const bm, const Addr a1)
232{
bart3772a982008-03-15 08:11:03 +0000233 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000234 bm_access_aligned_store(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000235 else
236 bm_access_range(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000237}
238
239void bm_access_store_4(struct bitmap* const bm, const Addr a1)
240{
bart3772a982008-03-15 08:11:03 +0000241 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000242 bm_access_aligned_store(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000243 else
244 bm_access_range(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000245}
246
247void bm_access_store_8(struct bitmap* const bm, const Addr a1)
248{
bart3772a982008-03-15 08:11:03 +0000249 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000250 bm_access_aligned_store(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000251 else if ((a1 & 3) == 0)
252 {
bartf8bc71d2008-03-15 11:42:34 +0000253 bm_access_aligned_store(bm, a1 + 0, 4);
254 bm_access_aligned_store(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000255 }
256 else
257 bm_access_range(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000258}
259
bart36556122008-03-13 19:24:30 +0000260void bm_access_range_store(struct bitmap* const bm,
261 const Addr a1, const Addr a2)
262{
bart3772a982008-03-15 08:11:03 +0000263 bm_access_range(bm, a1, a2, eStore);
bart36556122008-03-13 19:24:30 +0000264}
265
266Bool bm_has(const struct bitmap* const bm, const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000267 const BmAccessTypeT access_type)
268{
bart3772a982008-03-15 08:11:03 +0000269 Addr b;
270 for (b = a1; b < a2; b++)
271 {
272 if (! bm_has_1(bm, b, access_type))
273 {
274 return False;
275 }
276 }
277 return True;
sewardjaf44c822007-11-25 14:01:38 +0000278}
279
280Bool bm_has_any(const struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000281 const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000282 const BmAccessTypeT access_type)
283{
bart3772a982008-03-15 08:11:03 +0000284 Addr b;
sewardjaf44c822007-11-25 14:01:38 +0000285
bart3772a982008-03-15 08:11:03 +0000286 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000287
bart3772a982008-03-15 08:11:03 +0000288 for (b = a1; b < a2; b++)
289 {
290 if (bm_has_1(bm, b, access_type))
291 {
292 return True;
293 }
294 }
295 return False;
sewardjaf44c822007-11-25 14:01:38 +0000296}
297
298/* Return a non-zero value if there is a read access, write access or both */
299/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
300UWord bm_has_any_access(const struct bitmap* const bm,
301 const Addr a1,
302 const Addr a2)
303{
bart3772a982008-03-15 08:11:03 +0000304 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000305
bart3772a982008-03-15 08:11:03 +0000306 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000307
bart3772a982008-03-15 08:11:03 +0000308 for (b = a1; b < a2; b = b_next)
309 {
bartf647d342008-03-24 19:12:12 +0000310 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000311
bart3772a982008-03-15 08:11:03 +0000312 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
313 if (b_next > a2)
314 {
315 b_next = a2;
316 }
sewardjaf44c822007-11-25 14:01:38 +0000317
bart3772a982008-03-15 08:11:03 +0000318 if (bm2)
319 {
320 Addr b_start;
321 Addr b_end;
322 UWord b0;
323 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000324
bart3772a982008-03-15 08:11:03 +0000325 if ((bm2->addr << ADDR0_BITS) < a1)
326 b_start = a1;
327 else
328 if ((bm2->addr << ADDR0_BITS) < a2)
329 b_start = (bm2->addr << ADDR0_BITS);
330 else
331 break;
332 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000333
bart3772a982008-03-15 08:11:03 +0000334 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
335 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
336 else
337 b_end = a2;
338 tl_assert(a1 <= b_end && b_end <= a2);
339 tl_assert(b_start < b_end);
340 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000341
bart3772a982008-03-15 08:11:03 +0000342 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
343 {
344 const UWord mask
345 = bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0);
346 if (mask)
347 {
348 return mask;
349 }
sewardjaf44c822007-11-25 14:01:38 +0000350 }
bart3772a982008-03-15 08:11:03 +0000351 }
352 }
353 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000354}
355
356/**
357 * Report whether an access of type access_type at address a is recorded in
358 * bitmap bm.
359 * @return != 0 means true, and == 0 means false
360 */
361UWord bm_has_1(const struct bitmap* const bm,
362 const Addr a,
363 const BmAccessTypeT access_type)
364{
bartf647d342008-03-24 19:12:12 +0000365 const struct bitmap2* p2;
366 const struct bitmap1* p1;
367 const UWord* p0;
bart3772a982008-03-15 08:11:03 +0000368 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000369
bart3772a982008-03-15 08:11:03 +0000370 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000371
bart11d0b502008-03-22 16:44:03 +0000372 p2 = bm2_lookup(bm, a >> ADDR0_BITS);
bart3772a982008-03-15 08:11:03 +0000373 if (p2)
374 {
375 p1 = &p2->bm1;
376 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
377 return bm0_is_set(p0, a0);
378 }
379 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000380}
381
382static __inline__
383void bm1_clear(struct bitmap1* const bm1, const Addr a1, const Addr a2)
384{
bart3772a982008-03-15 08:11:03 +0000385 UWord idx;
386 UWord mask;
sewardjaf44c822007-11-25 14:01:38 +0000387
388#if 0
bart3772a982008-03-15 08:11:03 +0000389 /* Commented out the statements below because of performance reasons. */
390 tl_assert(a1);
391 tl_assert(a1 <= a2);
392 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a2)
393 || UWORD_MSB(a1) == UWORD_MSB(a2 - 1));
sewardjaf44c822007-11-25 14:01:38 +0000394#endif
395
bart3772a982008-03-15 08:11:03 +0000396 idx = (a1 & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
397 /* mask: a contiguous series of one bits. The first bit set is bit */
398 /* UWORD_LSB(a2-1), and the last bit set is UWORD_LSB(a1). */
399 mask = UWORD_LSB(a2) ? bm0_mask(a2) - bm0_mask(a1) : - bm0_mask(a1);
400 bm1->bm0_r[idx] &= ~mask;
401 bm1->bm0_w[idx] &= ~mask;
sewardjaf44c822007-11-25 14:01:38 +0000402}
403
404void bm_clear_all(const struct bitmap* const bm)
405{
bart3772a982008-03-15 08:11:03 +0000406 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000407 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000408
bart3772a982008-03-15 08:11:03 +0000409 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000410
bartf647d342008-03-24 19:12:12 +0000411 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000412 {
bartf647d342008-03-24 19:12:12 +0000413 struct bitmap1* bm1;
414
415 bm2 = bm2ref->bm2;
416 bm1 = &bm2->bm1;
bart3772a982008-03-15 08:11:03 +0000417 tl_assert(bm1);
418 VG_(memset)(&bm1->bm0_r[0], 0, sizeof(bm1->bm0_r));
419 VG_(memset)(&bm1->bm0_w[0], 0, sizeof(bm1->bm0_w));
420 }
sewardjaf44c822007-11-25 14:01:38 +0000421}
422
sewardjaf44c822007-11-25 14:01:38 +0000423void bm_clear(const struct bitmap* const bm,
424 const Addr a1,
425 const Addr a2)
426{
bart3772a982008-03-15 08:11:03 +0000427 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000428
bart3772a982008-03-15 08:11:03 +0000429 tl_assert(bm);
430 tl_assert(a1);
431 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000432
bart3772a982008-03-15 08:11:03 +0000433 for (b = a1; b < a2; b = b_next)
434 {
bartf647d342008-03-24 19:12:12 +0000435 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000436
bart3772a982008-03-15 08:11:03 +0000437 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
438 if (b_next > a2)
439 {
440 b_next = a2;
441 }
442
443 if (p2)
444 {
445 Addr c = b;
bartf647d342008-03-24 19:12:12 +0000446 /* If the first address in the bitmap that must be cleared does not */
447 /* start on an UWord boundary, start clearing the first addresses */
448 /* by calling bm1_clear(). */
bart3772a982008-03-15 08:11:03 +0000449 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000450 {
bart3772a982008-03-15 08:11:03 +0000451 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
452 if (c_next > b_next)
453 c_next = b_next;
454 bm1_clear(&p2->bm1, c, c_next);
455 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000456 }
bartf647d342008-03-24 19:12:12 +0000457 /* If some UWords have to be cleared entirely, do this now. */
bart3772a982008-03-15 08:11:03 +0000458 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000459 {
bart3772a982008-03-15 08:11:03 +0000460 const Addr c_next = UWORD_MSB(b_next);
461 tl_assert(UWORD_LSB(c) == 0);
462 tl_assert(UWORD_LSB(c_next) == 0);
463 tl_assert(c_next <= b_next);
464 tl_assert(c <= c_next);
465 if (c_next > c)
466 {
467 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
468 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
469 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
470 c = c_next;
471 }
sewardjaf44c822007-11-25 14:01:38 +0000472 }
bartf647d342008-03-24 19:12:12 +0000473 /* If the last address in the bitmap that must be cleared does not */
474 /* fall on an UWord boundary, clear the last addresses by calling */
475 /* bm1_clear(). */
bart3772a982008-03-15 08:11:03 +0000476 if (c != b_next)
477 {
478 bm1_clear(&p2->bm1, c, b_next);
479 }
480 }
481 }
sewardjaf44c822007-11-25 14:01:38 +0000482}
sewardjaf44c822007-11-25 14:01:38 +0000483
bart36556122008-03-13 19:24:30 +0000484Bool bm_has_conflict_with(const struct bitmap* const bm,
485 const Addr a1, const Addr a2,
486 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000487{
bart3772a982008-03-15 08:11:03 +0000488 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000489
bart3772a982008-03-15 08:11:03 +0000490 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000491
bart3772a982008-03-15 08:11:03 +0000492 for (b = a1; b < a2; b = b_next)
493 {
bartf647d342008-03-24 19:12:12 +0000494 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000495
bart3772a982008-03-15 08:11:03 +0000496 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
497 if (b_next > a2)
498 {
499 b_next = a2;
500 }
bart36556122008-03-13 19:24:30 +0000501
bart3772a982008-03-15 08:11:03 +0000502 if (bm2)
503 {
504 Addr b_start;
505 Addr b_end;
506 UWord b0;
507 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000508
bart3772a982008-03-15 08:11:03 +0000509 if ((bm2->addr << ADDR0_BITS) < a1)
510 b_start = a1;
511 else
512 if ((bm2->addr << ADDR0_BITS) < a2)
513 b_start = (bm2->addr << ADDR0_BITS);
514 else
515 break;
516 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000517
bart3772a982008-03-15 08:11:03 +0000518 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
519 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
520 else
521 b_end = a2;
522 tl_assert(a1 <= b_end && b_end <= a2);
523 tl_assert(b_start < b_end);
524 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000525
bart3772a982008-03-15 08:11:03 +0000526 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
527 {
528 if (access_type == eLoad)
529 {
530 if (bm0_is_set(p1->bm0_w, b0))
531 {
532 return True;
533 }
534 }
535 else
536 {
537 tl_assert(access_type == eStore);
538 if (bm0_is_set(p1->bm0_r, b0)
539 | bm0_is_set(p1->bm0_w, b0))
540 {
541 return True;
542 }
543 }
sewardjaf44c822007-11-25 14:01:38 +0000544 }
bart3772a982008-03-15 08:11:03 +0000545 }
546 }
547 return False;
sewardjaf44c822007-11-25 14:01:38 +0000548}
549
barta79df6e2008-03-14 17:07:51 +0000550static inline
551Bool bm_aligned_load_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000552 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000553{
bartf647d342008-03-24 19:12:12 +0000554 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000555
bart11d0b502008-03-22 16:44:03 +0000556 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000557
bartf8bc71d2008-03-15 11:42:34 +0000558 return (bm2 && bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size));
barta79df6e2008-03-14 17:07:51 +0000559}
560
561static inline
562Bool bm_aligned_store_has_conflict_with(const struct bitmap* const bm,
bartf8bc71d2008-03-15 11:42:34 +0000563 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000564{
bartf647d342008-03-24 19:12:12 +0000565 const struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000566
bart11d0b502008-03-22 16:44:03 +0000567 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
barta79df6e2008-03-14 17:07:51 +0000568
bart3772a982008-03-15 08:11:03 +0000569 if (bm2)
570 {
bartf8bc71d2008-03-15 11:42:34 +0000571 if (bm0_is_any_set(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size)
572 | bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size))
bart3772a982008-03-15 08:11:03 +0000573 {
574 return True;
575 }
576 }
577 return False;
barta79df6e2008-03-14 17:07:51 +0000578}
579
bart36556122008-03-13 19:24:30 +0000580Bool bm_load_has_conflict_with(const struct bitmap* const bm,
581 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000582{
bart3772a982008-03-15 08:11:03 +0000583 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000584}
585
barta79df6e2008-03-14 17:07:51 +0000586Bool bm_load_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
587{
bartf8bc71d2008-03-15 11:42:34 +0000588 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000589}
590
591Bool bm_load_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
592{
bart3772a982008-03-15 08:11:03 +0000593 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000594 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000595 else
596 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000597}
598
599Bool bm_load_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
600{
bart3772a982008-03-15 08:11:03 +0000601 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000602 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000603 else
604 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000605}
606
607Bool bm_load_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
608{
bart3772a982008-03-15 08:11:03 +0000609 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000610 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000611 else
612 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000613}
614
615Bool bm_store_1_has_conflict_with(const struct bitmap* const bm, const Addr a1)
616{
bartf8bc71d2008-03-15 11:42:34 +0000617 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000618}
619
620Bool bm_store_2_has_conflict_with(const struct bitmap* const bm, const Addr a1)
621{
bart3772a982008-03-15 08:11:03 +0000622 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000623 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000624 else
625 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000626}
627
628Bool bm_store_4_has_conflict_with(const struct bitmap* const bm, const Addr a1)
629{
bart3772a982008-03-15 08:11:03 +0000630 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000631 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000632 else
633 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000634}
635
636Bool bm_store_8_has_conflict_with(const struct bitmap* const bm, const Addr a1)
637{
bart3772a982008-03-15 08:11:03 +0000638 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000639 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000640 else
641 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000642}
643
bart36556122008-03-13 19:24:30 +0000644Bool bm_store_has_conflict_with(const struct bitmap* const bm,
645 const Addr a1, const Addr a2)
646{
bart3772a982008-03-15 08:11:03 +0000647 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000648}
649
650void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
651{
bart3772a982008-03-15 08:11:03 +0000652 OSet* const tmp = bm1->oset;
653 bm1->oset = bm2->oset;
654 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000655}
656
bartf647d342008-03-24 19:12:12 +0000657/** Merge bitmaps *lhs and *rhs into *lhs. */
sewardjaf44c822007-11-25 14:01:38 +0000658void bm_merge2(struct bitmap* const lhs,
659 const struct bitmap* const rhs)
660{
bart3772a982008-03-15 08:11:03 +0000661 struct bitmap2* bm2l;
bartf647d342008-03-24 19:12:12 +0000662 struct bitmap2ref* bm2l_ref;
663 struct bitmap2* bm2r;
664 const struct bitmap2ref* bm2r_ref;
sewardjaf44c822007-11-25 14:01:38 +0000665
bart3772a982008-03-15 08:11:03 +0000666 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000667
bartf647d342008-03-24 19:12:12 +0000668 for ( ; (bm2r_ref = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000669 {
bartf647d342008-03-24 19:12:12 +0000670 bm2r = bm2r_ref->bm2;
671 bm2l_ref = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
672 if (bm2l_ref)
bart3772a982008-03-15 08:11:03 +0000673 {
bartf647d342008-03-24 19:12:12 +0000674 bm2l = bm2l_ref->bm2;
675 if (bm2l != bm2r)
676 {
677 if (bm2l->refcnt > 1)
678 bm2l = bm2_make_exclusive(lhs, bm2l_ref);
679 bm2_merge(bm2l, bm2r);
680 }
681 }
682 else
683 {
684 bm2_insert_addref(lhs, bm2r);
685 }
bart3772a982008-03-15 08:11:03 +0000686 }
sewardjaf44c822007-11-25 14:01:38 +0000687}
688
689/**
690 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
691 * @param lhs First bitmap.
692 * @param rhs Bitmap to be compared with lhs.
693 * @return !=0 if there are data races, == 0 if there are none.
694 */
695int bm_has_races(const struct bitmap* const lhs,
696 const struct bitmap* const rhs)
697{
bart3772a982008-03-15 08:11:03 +0000698 VG_(OSetGen_ResetIter)(lhs->oset);
699 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000700
bart3772a982008-03-15 08:11:03 +0000701 for (;;)
702 {
bartf647d342008-03-24 19:12:12 +0000703 const struct bitmap2ref* bm2l_ref;
704 const struct bitmap2ref* bm2r_ref;
705 const struct bitmap2* bm2l;
706 const struct bitmap2* bm2r;
bart3772a982008-03-15 08:11:03 +0000707 const struct bitmap1* bm1l;
708 const struct bitmap1* bm1r;
709 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000710
bartf647d342008-03-24 19:12:12 +0000711 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
712 bm2l = bm2l_ref->bm2;
713 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
714 bm2r = bm2r_ref->bm2;
bart3772a982008-03-15 08:11:03 +0000715 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
716 {
717 if (bm2l->addr < bm2r->addr)
bartf647d342008-03-24 19:12:12 +0000718 bm2l = (bm2l_ref = VG_(OSetGen_Next)(lhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000719 else
bartf647d342008-03-24 19:12:12 +0000720 bm2r = (bm2r_ref = VG_(OSetGen_Next)(rhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000721 }
722 if (bm2l == 0 || bm2r == 0)
723 break;
724
725 bm1l = &bm2l->bm1;
726 bm1r = &bm2r->bm1;
727
728 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
729 {
730 unsigned b;
731 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000732 {
bart3772a982008-03-15 08:11:03 +0000733 UWord const access
734 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
735 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
736 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
737 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
738 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
739 if (HAS_RACE(access) && ! drd_is_suppressed(a, a + 1))
740 {
741 return 1;
742 }
sewardjaf44c822007-11-25 14:01:38 +0000743 }
bart3772a982008-03-15 08:11:03 +0000744 }
745 }
746 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000747}
748
sewardjaf44c822007-11-25 14:01:38 +0000749void bm_print(const struct bitmap* const bm)
750{
bart3772a982008-03-15 08:11:03 +0000751 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000752 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000753
bart3772a982008-03-15 08:11:03 +0000754 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000755
bartf647d342008-03-24 19:12:12 +0000756 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000757 {
bartf647d342008-03-24 19:12:12 +0000758 const struct bitmap1* bm1;
bart0008f5b2008-03-22 17:07:39 +0000759 unsigned b;
bartf647d342008-03-24 19:12:12 +0000760
761 bm2 = bm2ref->bm2;
762 bm1 = &bm2->bm1;
bart0008f5b2008-03-22 17:07:39 +0000763 for (b = 0; b < ADDR0_COUNT; b++)
bart3772a982008-03-15 08:11:03 +0000764 {
bart0008f5b2008-03-22 17:07:39 +0000765 const Addr a = (bm2->addr << ADDR0_BITS) | b;
766 const Bool r = bm0_is_set(bm1->bm0_r, b) != 0;
767 const Bool w = bm0_is_set(bm1->bm0_w, b) != 0;
768 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +0000769 {
bart0008f5b2008-03-22 17:07:39 +0000770 VG_(printf)("0x%08lx %c %c\n",
771 a,
772 w ? 'W' : ' ',
773 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +0000774 }
bart3772a982008-03-15 08:11:03 +0000775 }
776 }
sewardjaf44c822007-11-25 14:01:38 +0000777}
778
779ULong bm_get_bitmap_creation_count(void)
780{
bart3772a982008-03-15 08:11:03 +0000781 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000782}
783
784ULong bm_get_bitmap2_creation_count(void)
785{
bart3772a982008-03-15 08:11:03 +0000786 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000787}
788
bartf647d342008-03-24 19:12:12 +0000789/** Allocate and initialize a second level bitmap. */
790static struct bitmap2* bm2_new(const UWord a1)
791{
792 struct bitmap2* bm2;
793
794 bm2 = VG_(malloc)(sizeof(*bm2));
795 bm2->addr = a1;
796 bm2->refcnt = 1;
797
798 s_bitmap2_creation_count++;
799
800 return bm2;
801}
802
803/** Make a copy of a shared second level bitmap such that the copy can be
804 * modified.
805 *
806 * @param a1 client address shifted right by ADDR0_BITS.
807 * @param bm bitmap pointer.
808 */
809static
810struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
811 struct bitmap2ref* const bm2ref)
812{
813 UWord a1;
814 struct bitmap2* bm2;
815 struct bitmap2* bm2_copy;
816
817 tl_assert(bm);
818 tl_assert(bm2ref);
819 bm2 = bm2ref->bm2;
820 tl_assert(bm2);
821 tl_assert(bm2->refcnt > 1);
822 bm2->refcnt--;
823 tl_assert(bm2->refcnt >= 1);
824 a1 = bm2->addr;
825 bm2_copy = bm2_new(a1);
826 tl_assert(bm2_copy);
827 tl_assert(bm2_copy->addr == a1);
828 tl_assert(bm2_copy->refcnt == 1);
829 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1));
830 bm2ref->bm2 = bm2_copy;
831
832 bm_update_cache(bm, a1, bm2_copy);
833
834 return bm2_copy;
835}
836
sewardjaf44c822007-11-25 14:01:38 +0000837static void bm2_merge(struct bitmap2* const bm2l,
838 const struct bitmap2* const bm2r)
839{
bart3772a982008-03-15 08:11:03 +0000840 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000841
bart33e56c92008-03-24 06:41:30 +0000842 tl_assert(bm2l);
843 tl_assert(bm2r);
bart3772a982008-03-15 08:11:03 +0000844 tl_assert(bm2l->addr == bm2r->addr);
bartf647d342008-03-24 19:12:12 +0000845 tl_assert(bm2l->refcnt == 1);
sewardjaf44c822007-11-25 14:01:38 +0000846
bart3772a982008-03-15 08:11:03 +0000847 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
848 {
849 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
850 }
851 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
852 {
853 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
854 }
sewardjaf44c822007-11-25 14:01:38 +0000855}
856
857#if 0
858
859/* Unit test */
860static
861struct { Addr address; SizeT size; BmAccessTypeT access_type; }
bart3772a982008-03-15 08:11:03 +0000862 s_args[] = {
bart0008f5b2008-03-22 17:07:39 +0000863 { 0 + ADDR0_COUNT, 1, eLoad },
864 { 666 + ADDR0_COUNT, 4, eLoad },
865 { 667 + ADDR0_COUNT, 2, eStore },
bart33e56c92008-03-24 06:41:30 +0000866 { -2 + 2*ADDR0_COUNT, 1, eStore },
bart0008f5b2008-03-22 17:07:39 +0000867 { 0x0001ffffUL, 1, eLoad },
868 { 0x0002ffffUL, 1, eLoad },
869 { 0x00ffffffUL, 1, eLoad },
870 { 0xffffffffUL, 1, eStore },
bart3772a982008-03-15 08:11:03 +0000871 };
sewardjaf44c822007-11-25 14:01:38 +0000872
873void bm_test(void)
874{
bart3772a982008-03-15 08:11:03 +0000875 struct bitmap* bm;
876 struct bitmap* bm2;
bart0008f5b2008-03-22 17:07:39 +0000877 unsigned i, j;
sewardjaf44c822007-11-25 14:01:38 +0000878
bart3772a982008-03-15 08:11:03 +0000879 VG_(printf)("Start of DRD BM unit test.\n");
sewardjaf44c822007-11-25 14:01:38 +0000880
bart3772a982008-03-15 08:11:03 +0000881 bm = bm_new();
sewardjaf44c822007-11-25 14:01:38 +0000882
bart3772a982008-03-15 08:11:03 +0000883 for (i = 0; i < sizeof(s_args)/sizeof(s_args[0]); i++)
884 {
885 bm_access_range(bm,
886 s_args[i].address,
887 s_args[i].address + s_args[i].size,
888 s_args[i].access_type);
889 }
sewardjaf44c822007-11-25 14:01:38 +0000890
bart3772a982008-03-15 08:11:03 +0000891 VG_(printf)("Map contents -- should contain 10 addresses:\n");
892 bm_print(bm);
sewardjaf44c822007-11-25 14:01:38 +0000893
bart3772a982008-03-15 08:11:03 +0000894 for (i = 0; i < sizeof(s_args)/sizeof(s_args[0]); i++)
895 {
896 for (j = 0; j < s_args[i].size; j++)
897 {
898 tl_assert(bm_has_1(bm, s_args[i].address + j, s_args[i].access_type));
899 }
900 }
sewardjaf44c822007-11-25 14:01:38 +0000901
bart3772a982008-03-15 08:11:03 +0000902 VG_(printf)("Merge result:\n");
bart0008f5b2008-03-22 17:07:39 +0000903 bm2 = bm_new();
904 bm_merge2(bm2, bm);
905 bm_merge2(bm2, bm);
bart3772a982008-03-15 08:11:03 +0000906 bm_print(bm);
sewardjaf44c822007-11-25 14:01:38 +0000907
bart0008f5b2008-03-22 17:07:39 +0000908 VG_(printf)("Deleting bitmap bm\n");
bart3772a982008-03-15 08:11:03 +0000909 bm_delete(bm);
bart0008f5b2008-03-22 17:07:39 +0000910 VG_(printf)("Deleting bitmap bm2\n");
bart3772a982008-03-15 08:11:03 +0000911 bm_delete(bm2);
sewardjaf44c822007-11-25 14:01:38 +0000912
bart3772a982008-03-15 08:11:03 +0000913 VG_(printf)("End of DRD BM unit test.\n");
sewardjaf44c822007-11-25 14:01:38 +0000914}
915#endif