blob: c5e8a1ddb6450df9f4938dc2e13acb8d109409e9 [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001/*
bart86562bd2009-02-16 19:43:56 +00002 This file is part of drd, a thread error detector.
sewardjaf44c822007-11-25 14:01:38 +00003
sewardj03f8d3f2012-08-05 15:46:46 +00004 Copyright (C) 2006-2012 Bart Van Assche <bvanassche@acm.org>.
sewardjaf44c822007-11-25 14:01:38 +00005
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307, USA.
20
21 The GNU General Public License is contained in the file COPYING.
22*/
23
24
bart39934d62009-02-15 16:18:03 +000025#include "drd_basics.h" /* DRD_() */
sewardjaf44c822007-11-25 14:01:38 +000026#include "drd_bitmap.h"
27#include "drd_error.h"
28#include "drd_suppression.h"
bart39934d62009-02-15 16:18:03 +000029#include "pub_drd_bitmap.h"
30#include "pub_tool_basics.h" /* Addr, SizeT */
31#include "pub_tool_debuginfo.h" /* VG_(get_objname)() */
32#include "pub_tool_libcassert.h" /* tl_assert() */
33#include "pub_tool_libcbase.h" /* VG_(memset) */
34#include "pub_tool_libcprint.h" /* VG_(printf) */
35#include "pub_tool_machine.h" /* VG_(get_IP)() */
36#include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
sewardjaf44c822007-11-25 14:01:38 +000037
38
bartf647d342008-03-24 19:12:12 +000039/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000040
41static void bm2_merge(struct bitmap2* const bm2l,
42 const struct bitmap2* const bm2r);
bart7b706b32009-05-10 06:55:39 +000043static void bm2_print(const struct bitmap2* const bm2);
sewardjaf44c822007-11-25 14:01:38 +000044
45
bart99edb292009-02-15 15:59:20 +000046/* Local variables. */
bartf647d342008-03-24 19:12:12 +000047
barte44bccc2012-01-18 09:46:57 +000048static OSet* s_bm2_set_template;
bartf647d342008-03-24 19:12:12 +000049static ULong s_bitmap_creation_count;
bart7b706b32009-05-10 06:55:39 +000050static ULong s_bitmap_merge_count;
51static ULong s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +000052
53
54/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000055
barte44bccc2012-01-18 09:46:57 +000056void DRD_(bm_module_init)(void)
57{
58 tl_assert(!s_bm2_set_template);
59 s_bm2_set_template
60 = VG_(OSetGen_Create_With_Pool)(0, 0, VG_(malloc), "drd.bitmap.bn.2",
61 VG_(free), 512, sizeof(struct bitmap2));
62}
63
64void DRD_(bm_module_cleanup)(void)
65{
66 tl_assert(s_bm2_set_template);
67 VG_(OSetGen_Destroy)(s_bm2_set_template);
68 s_bm2_set_template = NULL;
69}
70
bart99edb292009-02-15 15:59:20 +000071struct bitmap* DRD_(bm_new)()
sewardjaf44c822007-11-25 14:01:38 +000072{
bartbedfd232009-03-26 19:07:15 +000073 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000074
bartbedfd232009-03-26 19:07:15 +000075 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
76 /* in drd_bitmap.h. */
77 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000078
bartbedfd232009-03-26 19:07:15 +000079 bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
bart8f822af2009-06-08 18:20:42 +000080 DRD_(bm_init)(bm);
sewardjaf44c822007-11-25 14:01:38 +000081
bartbedfd232009-03-26 19:07:15 +000082 return bm;
sewardjaf44c822007-11-25 14:01:38 +000083}
84
bart99edb292009-02-15 15:59:20 +000085void DRD_(bm_delete)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +000086{
bartbedfd232009-03-26 19:07:15 +000087 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000088
bart8f822af2009-06-08 18:20:42 +000089 DRD_(bm_cleanup)(bm);
bartbedfd232009-03-26 19:07:15 +000090 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +000091}
92
bart8f822af2009-06-08 18:20:42 +000093/** Initialize *bm. */
94void DRD_(bm_init)(struct bitmap* const bm)
95{
96 unsigned i;
97
98 tl_assert(bm);
bart9f617a82009-06-21 18:08:31 +000099 /*
100 * Cache initialization. a1 is initialized with a value that never can
bart8f822af2009-06-08 18:20:42 +0000101 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
102 * bits of a1 are always zero for a valid cache entry.
103 */
104 for (i = 0; i < DRD_BITMAP_N_CACHE_ELEM; i++)
105 {
106 bm->cache[i].a1 = ~(UWord)1;
107 bm->cache[i].bm2 = 0;
108 }
barte44bccc2012-01-18 09:46:57 +0000109 bm->oset = VG_(OSetGen_EmptyClone)(s_bm2_set_template);
bart9f617a82009-06-21 18:08:31 +0000110
111 s_bitmap_creation_count++;
bart8f822af2009-06-08 18:20:42 +0000112}
113
114/** Free the memory allocated by DRD_(bm_init)(). */
115void DRD_(bm_cleanup)(struct bitmap* const bm)
116{
117 VG_(OSetGen_Destroy)(bm->oset);
118}
119
sewardjaf44c822007-11-25 14:01:38 +0000120/**
bart36556122008-03-13 19:24:30 +0000121 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000122 * bitmap bm.
bart7b706b32009-05-10 06:55:39 +0000123 *
124 * @note The current implementation of bm_access_range does not work for the
125 * highest addresses in the address range. At least on Linux this is
126 * not a problem since the upper part of the address space is reserved
127 * for the kernel.
sewardjaf44c822007-11-25 14:01:38 +0000128 */
bart99edb292009-02-15 15:59:20 +0000129void DRD_(bm_access_range)(struct bitmap* const bm,
130 const Addr a1, const Addr a2,
131 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000132{
barte6e86c52009-04-25 06:53:00 +0000133 tl_assert(access_type == eLoad || access_type == eStore);
134
135 if (access_type == eLoad)
136 return DRD_(bm_access_range_load)(bm, a1, a2);
137 else
138 return DRD_(bm_access_range_store)(bm, a1, a2);
139}
140
bart7b706b32009-05-10 06:55:39 +0000141void DRD_(bm_access_range_load)(struct bitmap* const bm, Addr a1, Addr a2)
barte6e86c52009-04-25 06:53:00 +0000142{
bartbedfd232009-03-26 19:07:15 +0000143 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000144
bartbedfd232009-03-26 19:07:15 +0000145 tl_assert(bm);
barta3003982010-09-08 16:29:17 +0000146 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000147 tl_assert(a2 < first_address_with_higher_msb(a2));
148 tl_assert(a1 == first_address_with_same_lsb(a1));
149 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000150
bartbedfd232009-03-26 19:07:15 +0000151 for (b = a1; b < a2; b = b_next)
152 {
153 Addr b_start;
154 Addr b_end;
155 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000156 UWord b0;
bart36556122008-03-13 19:24:30 +0000157
bart7b706b32009-05-10 06:55:39 +0000158 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000159 if (b_next > a2)
160 {
161 b_next = a2;
162 }
bart36556122008-03-13 19:24:30 +0000163
bart7b706b32009-05-10 06:55:39 +0000164 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
bartbedfd232009-03-26 19:07:15 +0000165 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000166
bart7b706b32009-05-10 06:55:39 +0000167 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000168 b_start = a1;
bart36556122008-03-13 19:24:30 +0000169 else
bart7b706b32009-05-10 06:55:39 +0000170 if (make_address(bm2->addr, 0) < a2)
171 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000172 else
173 break;
bart36556122008-03-13 19:24:30 +0000174
bart7b706b32009-05-10 06:55:39 +0000175 if (make_address(bm2->addr + 1, 0) < a2)
176 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000177 else
178 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000179
180 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000181 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
182 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000183
bart7b706b32009-05-10 06:55:39 +0000184 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
bart36556122008-03-13 19:24:30 +0000185 {
bartf43b1772009-04-25 08:08:33 +0000186 unsigned k;
187
188 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
189 {
190 bm2->bm1.bm0_r[k] = ~(UWord)0;
191 }
192 }
193 else
194 {
bart7b706b32009-05-10 06:55:39 +0000195 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000196 {
197 bm0_set(bm2->bm1.bm0_r, b0);
198 }
bart3772a982008-03-15 08:11:03 +0000199 }
bartbedfd232009-03-26 19:07:15 +0000200 }
sewardjaf44c822007-11-25 14:01:38 +0000201}
202
bart99edb292009-02-15 15:59:20 +0000203void DRD_(bm_access_load_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000204{
bartbedfd232009-03-26 19:07:15 +0000205 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000206}
207
bart99edb292009-02-15 15:59:20 +0000208void DRD_(bm_access_load_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000209{
bartbedfd232009-03-26 19:07:15 +0000210 if ((a1 & 1) == 0)
211 bm_access_aligned_load(bm, a1, 2);
212 else
213 DRD_(bm_access_range)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000214}
215
bart99edb292009-02-15 15:59:20 +0000216void DRD_(bm_access_load_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000217{
bartbedfd232009-03-26 19:07:15 +0000218 if ((a1 & 3) == 0)
219 bm_access_aligned_load(bm, a1, 4);
220 else
221 DRD_(bm_access_range)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000222}
223
bart99edb292009-02-15 15:59:20 +0000224void DRD_(bm_access_load_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000225{
bartbedfd232009-03-26 19:07:15 +0000226 if ((a1 & 7) == 0)
227 bm_access_aligned_load(bm, a1, 8);
228 else if ((a1 & 3) == 0)
229 {
230 bm_access_aligned_load(bm, a1 + 0, 4);
231 bm_access_aligned_load(bm, a1 + 4, 4);
232 }
233 else
234 DRD_(bm_access_range)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000235}
236
bart99edb292009-02-15 15:59:20 +0000237void DRD_(bm_access_range_store)(struct bitmap* const bm,
238 const Addr a1, const Addr a2)
bartf5acbbc2008-05-10 08:22:20 +0000239{
barte6e86c52009-04-25 06:53:00 +0000240 Addr b, b_next;
241
242 tl_assert(bm);
barta3003982010-09-08 16:29:17 +0000243 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000244 tl_assert(a2 < first_address_with_higher_msb(a2));
245 tl_assert(a1 == first_address_with_same_lsb(a1));
246 tl_assert(a2 == first_address_with_same_lsb(a2));
barte6e86c52009-04-25 06:53:00 +0000247
248 for (b = a1; b < a2; b = b_next)
249 {
250 Addr b_start;
251 Addr b_end;
252 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000253 UWord b0;
barte6e86c52009-04-25 06:53:00 +0000254
bart7b706b32009-05-10 06:55:39 +0000255 b_next = first_address_with_higher_msb(b);
barte6e86c52009-04-25 06:53:00 +0000256 if (b_next > a2)
257 {
258 b_next = a2;
259 }
260
bart7b706b32009-05-10 06:55:39 +0000261 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
barte6e86c52009-04-25 06:53:00 +0000262 tl_assert(bm2);
263
bart7b706b32009-05-10 06:55:39 +0000264 if (make_address(bm2->addr, 0) < a1)
barte6e86c52009-04-25 06:53:00 +0000265 b_start = a1;
266 else
bart7b706b32009-05-10 06:55:39 +0000267 if (make_address(bm2->addr, 0) < a2)
268 b_start = make_address(bm2->addr, 0);
barte6e86c52009-04-25 06:53:00 +0000269 else
270 break;
barte6e86c52009-04-25 06:53:00 +0000271
bart7b706b32009-05-10 06:55:39 +0000272 if (make_address(bm2->addr + 1, 0) < a2)
273 b_end = make_address(bm2->addr + 1, 0);
barte6e86c52009-04-25 06:53:00 +0000274 else
275 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000276
277 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000278 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
279 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000280
bart7b706b32009-05-10 06:55:39 +0000281 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
barte6e86c52009-04-25 06:53:00 +0000282 {
bartf43b1772009-04-25 08:08:33 +0000283 unsigned k;
284
285 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
286 {
287 bm2->bm1.bm0_w[k] = ~(UWord)0;
288 }
289 }
290 else
291 {
bart7b706b32009-05-10 06:55:39 +0000292 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000293 {
294 bm0_set(bm2->bm1.bm0_w, b0);
295 }
barte6e86c52009-04-25 06:53:00 +0000296 }
297 }
bartf5acbbc2008-05-10 08:22:20 +0000298}
299
bart99edb292009-02-15 15:59:20 +0000300void DRD_(bm_access_store_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000301{
bartbedfd232009-03-26 19:07:15 +0000302 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000303}
304
bart99edb292009-02-15 15:59:20 +0000305void DRD_(bm_access_store_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000306{
bartbedfd232009-03-26 19:07:15 +0000307 if ((a1 & 1) == 0)
308 bm_access_aligned_store(bm, a1, 2);
309 else
310 DRD_(bm_access_range)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000311}
312
bart99edb292009-02-15 15:59:20 +0000313void DRD_(bm_access_store_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000314{
bartbedfd232009-03-26 19:07:15 +0000315 if ((a1 & 3) == 0)
316 bm_access_aligned_store(bm, a1, 4);
317 else
318 DRD_(bm_access_range)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000319}
320
bart99edb292009-02-15 15:59:20 +0000321void DRD_(bm_access_store_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000322{
bartbedfd232009-03-26 19:07:15 +0000323 if ((a1 & 7) == 0)
324 bm_access_aligned_store(bm, a1, 8);
325 else if ((a1 & 3) == 0)
326 {
327 bm_access_aligned_store(bm, a1 + 0, 4);
328 bm_access_aligned_store(bm, a1 + 4, 4);
329 }
330 else
331 DRD_(bm_access_range)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000332}
333
bart99edb292009-02-15 15:59:20 +0000334Bool DRD_(bm_has)(struct bitmap* const bm, const Addr a1, const Addr a2,
335 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000336{
bartda3a77b2009-04-23 20:07:23 +0000337 tl_assert(access_type == eLoad || access_type == eStore);
bartda3a77b2009-04-23 20:07:23 +0000338
339 if (access_type == eLoad)
340 return DRD_(bm_has_any_load)(bm, a1, a2);
341 else
342 return DRD_(bm_has_any_store)(bm, a1, a2);
sewardjaf44c822007-11-25 14:01:38 +0000343}
344
bart59d93d72011-12-12 19:02:34 +0000345Bool DRD_(bm_has_any_load_g)(struct bitmap* const bm)
346{
347 struct bitmap2* bm2;
348
349 tl_assert(bm);
350
351 VG_(OSetGen_ResetIter)(bm->oset);
352 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != NULL; ) {
353 Addr b_start;
354 Addr b_end;
355 UWord b0;
356 const struct bitmap1* const p1 = &bm2->bm1;
357
358 b_start = make_address(bm2->addr, 0);
359 b_end = make_address(bm2->addr + 1, 0);
360
361 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
362 if (bm0_is_set(p1->bm0_r, b0))
363 return True;
364 }
365 return False;
366}
367
bart99edb292009-02-15 15:59:20 +0000368Bool
369DRD_(bm_has_any_load)(struct bitmap* const bm, const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000370{
bartbedfd232009-03-26 19:07:15 +0000371 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000372
bartbedfd232009-03-26 19:07:15 +0000373 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000374
bartbedfd232009-03-26 19:07:15 +0000375 for (b = a1; b < a2; b = b_next)
376 {
bart7b706b32009-05-10 06:55:39 +0000377 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000378
bart7b706b32009-05-10 06:55:39 +0000379 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000380 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000381 {
bartbedfd232009-03-26 19:07:15 +0000382 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000383 }
bartbedfd232009-03-26 19:07:15 +0000384
385 if (bm2)
386 {
387 Addr b_start;
388 Addr b_end;
389 UWord b0;
390 const struct bitmap1* const p1 = &bm2->bm1;
391
bart7b706b32009-05-10 06:55:39 +0000392 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000393 b_start = a1;
394 else
bart7b706b32009-05-10 06:55:39 +0000395 if (make_address(bm2->addr, 0) < a2)
396 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000397 else
398 break;
399 tl_assert(a1 <= b_start && b_start <= a2);
400
bart7b706b32009-05-10 06:55:39 +0000401 if (make_address(bm2->addr + 1, 0) < a2)
402 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000403 else
404 b_end = a2;
405 tl_assert(a1 <= b_end && b_end <= a2);
406 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000407 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000408
bart7b706b32009-05-10 06:55:39 +0000409 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000410 {
411 if (bm0_is_set(p1->bm0_r, b0))
412 {
413 return True;
414 }
415 }
416 }
417 }
418 return 0;
bartd4907072008-03-30 18:41:07 +0000419}
420
bart99edb292009-02-15 15:59:20 +0000421Bool DRD_(bm_has_any_store)(struct bitmap* const bm,
422 const Addr a1, const Addr a2)
bartd4907072008-03-30 18:41:07 +0000423{
bartbedfd232009-03-26 19:07:15 +0000424 Addr b, b_next;
bartd4907072008-03-30 18:41:07 +0000425
bartbedfd232009-03-26 19:07:15 +0000426 tl_assert(bm);
bartd4907072008-03-30 18:41:07 +0000427
bartbedfd232009-03-26 19:07:15 +0000428 for (b = a1; b < a2; b = b_next)
429 {
bart7b706b32009-05-10 06:55:39 +0000430 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000431
bart7b706b32009-05-10 06:55:39 +0000432 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000433 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000434 {
bartbedfd232009-03-26 19:07:15 +0000435 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000436 }
bartbedfd232009-03-26 19:07:15 +0000437
438 if (bm2)
439 {
440 Addr b_start;
441 Addr b_end;
442 UWord b0;
443 const struct bitmap1* const p1 = &bm2->bm1;
444
bart7b706b32009-05-10 06:55:39 +0000445 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000446 b_start = a1;
447 else
bart7b706b32009-05-10 06:55:39 +0000448 if (make_address(bm2->addr, 0) < a2)
449 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000450 else
451 break;
452 tl_assert(a1 <= b_start && b_start <= a2);
453
bart7b706b32009-05-10 06:55:39 +0000454 if (make_address(bm2->addr + 1, 0) < a2)
455 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000456 else
457 b_end = a2;
458 tl_assert(a1 <= b_end && b_end <= a2);
459 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000460 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000461
bart7b706b32009-05-10 06:55:39 +0000462 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000463 {
464 if (bm0_is_set(p1->bm0_w, b0))
465 {
466 return True;
467 }
468 }
469 }
470 }
471 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000472}
473
bartc2c81db2008-05-10 11:19:10 +0000474/* Return True if there is a read access, write access or both */
475/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
bart99edb292009-02-15 15:59:20 +0000476Bool DRD_(bm_has_any_access)(struct bitmap* const bm,
477 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000478{
bartbedfd232009-03-26 19:07:15 +0000479 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000480
bartbedfd232009-03-26 19:07:15 +0000481 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000482
bartbedfd232009-03-26 19:07:15 +0000483 for (b = a1; b < a2; b = b_next)
484 {
bart7b706b32009-05-10 06:55:39 +0000485 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000486
bart7b706b32009-05-10 06:55:39 +0000487 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000488 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000489 {
bartbedfd232009-03-26 19:07:15 +0000490 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000491 }
bartbedfd232009-03-26 19:07:15 +0000492
493 if (bm2)
494 {
495 Addr b_start;
496 Addr b_end;
497 UWord b0;
498 const struct bitmap1* const p1 = &bm2->bm1;
499
bart7b706b32009-05-10 06:55:39 +0000500 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000501 b_start = a1;
502 else
bart7b706b32009-05-10 06:55:39 +0000503 if (make_address(bm2->addr, 0) < a2)
504 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000505 else
506 break;
507 tl_assert(a1 <= b_start && b_start <= a2);
508
bart7b706b32009-05-10 06:55:39 +0000509 if (make_address(bm2->addr + 1, 0) < a2)
510 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000511 else
512 b_end = a2;
513 tl_assert(a1 <= b_end && b_end <= a2);
514 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000515 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000516
bart7b706b32009-05-10 06:55:39 +0000517 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000518 {
bart8f822af2009-06-08 18:20:42 +0000519 /*
520 * Note: the statement below uses a binary or instead of a logical
521 * or on purpose.
522 */
bartbedfd232009-03-26 19:07:15 +0000523 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
524 {
525 return True;
526 }
527 }
528 }
529 }
530 return False;
sewardjaf44c822007-11-25 14:01:38 +0000531}
532
bart99edb292009-02-15 15:59:20 +0000533/**
534 * Report whether an access of type access_type at address a is recorded in
535 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000536 */
bart99edb292009-02-15 15:59:20 +0000537Bool DRD_(bm_has_1)(struct bitmap* const bm,
538 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000539{
bartbedfd232009-03-26 19:07:15 +0000540 const struct bitmap2* p2;
541 const struct bitmap1* p1;
542 const UWord* p0;
bart7b706b32009-05-10 06:55:39 +0000543 const UWord a0 = address_lsb(a);
sewardjaf44c822007-11-25 14:01:38 +0000544
bartbedfd232009-03-26 19:07:15 +0000545 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000546
bart7b706b32009-05-10 06:55:39 +0000547 p2 = bm2_lookup(bm, address_msb(a));
bartbedfd232009-03-26 19:07:15 +0000548 if (p2)
549 {
550 p1 = &p2->bm1;
551 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
552 return bm0_is_set(p0, a0) ? True : False;
553 }
554 return False;
sewardjaf44c822007-11-25 14:01:38 +0000555}
556
bart7b706b32009-05-10 06:55:39 +0000557void DRD_(bm_clear)(struct bitmap* const bm, Addr a1, Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000558{
bartbedfd232009-03-26 19:07:15 +0000559 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000560
bartbedfd232009-03-26 19:07:15 +0000561 tl_assert(bm);
562 tl_assert(a1);
563 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000564 tl_assert(a1 == first_address_with_same_lsb(a1));
565 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000566
bartbedfd232009-03-26 19:07:15 +0000567 for (b = a1; b < a2; b = b_next)
568 {
bart578eeb42009-04-23 15:42:27 +0000569 struct bitmap2* p2;
570 Addr c;
571
572#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
573 tl_assert(a1 <= b && b < a2);
574#endif
575
bart7b706b32009-05-10 06:55:39 +0000576 p2 = bm2_lookup_exclusive(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000577
bart7b706b32009-05-10 06:55:39 +0000578 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000579 if (b_next > a2)
sewardjaf44c822007-11-25 14:01:38 +0000580 {
bartbedfd232009-03-26 19:07:15 +0000581 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000582 }
bartbedfd232009-03-26 19:07:15 +0000583
barte2c7e672009-04-23 19:23:09 +0000584 if (p2 == 0)
585 continue;
586
bart578eeb42009-04-23 15:42:27 +0000587 c = b;
588 /* If the first address in the bitmap that must be cleared does not */
589 /* start on an UWord boundary, start clearing the first addresses. */
bart7b706b32009-05-10 06:55:39 +0000590 if (uword_lsb(address_lsb(c)))
sewardjaf44c822007-11-25 14:01:38 +0000591 {
bart7b706b32009-05-10 06:55:39 +0000592 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000593 if (c_next > b_next)
594 c_next = b_next;
595#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
596 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
597 && b_next <= a2);
598#endif
bart7b706b32009-05-10 06:55:39 +0000599 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
600 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000601 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000602 }
603 /* If some UWords have to be cleared entirely, do this now. */
bart7b706b32009-05-10 06:55:39 +0000604 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000605 {
bart7b706b32009-05-10 06:55:39 +0000606 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000607#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000608 tl_assert(uword_lsb(address_lsb(c)) == 0);
609 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000610 tl_assert(c_next <= b_next);
bart578eeb42009-04-23 15:42:27 +0000611#endif
bart25a439a2009-04-24 14:49:50 +0000612 if (c_next > c)
613 {
bart7b706b32009-05-10 06:55:39 +0000614 UWord idx = uword_msb(address_lsb(c));
615 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
616 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000617 c = c_next;
618 }
bart578eeb42009-04-23 15:42:27 +0000619 }
620 /* If the last address in the bitmap that must be cleared does not */
621 /* fall on an UWord boundary, clear the last addresses. */
bart25a439a2009-04-24 14:49:50 +0000622#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
623 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
624#endif
bart7b706b32009-05-10 06:55:39 +0000625 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
626 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000627 }
sewardjaf44c822007-11-25 14:01:38 +0000628}
sewardjaf44c822007-11-25 14:01:38 +0000629
bart99edb292009-02-15 15:59:20 +0000630/**
631 * Clear all references to loads in bitmap bm starting at address a1 and
632 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000633 */
bart7b706b32009-05-10 06:55:39 +0000634void DRD_(bm_clear_load)(struct bitmap* const bm, Addr a1, Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000635{
bart578eeb42009-04-23 15:42:27 +0000636 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000637
bart578eeb42009-04-23 15:42:27 +0000638 tl_assert(bm);
639 tl_assert(a1);
640 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000641 tl_assert(a1 == first_address_with_same_lsb(a1));
642 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000643
644 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000645 {
bart578eeb42009-04-23 15:42:27 +0000646 struct bitmap2* p2;
647 Addr c;
648
649#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
650 tl_assert(a1 <= b && b < a2);
651#endif
652
bart7b706b32009-05-10 06:55:39 +0000653 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000654
bart7b706b32009-05-10 06:55:39 +0000655 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000656 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000657 {
bart578eeb42009-04-23 15:42:27 +0000658 b_next = a2;
659 }
660
barte2c7e672009-04-23 19:23:09 +0000661 if (p2 == 0)
662 continue;
663
bart578eeb42009-04-23 15:42:27 +0000664 c = b;
665 /* If the first address in the bitmap that must be cleared does not */
666 /* start on an UWord boundary, start clearing the first addresses. */
667#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
668 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
669#endif
bart7b706b32009-05-10 06:55:39 +0000670 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000671 {
bart7b706b32009-05-10 06:55:39 +0000672 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000673 if (c_next > b_next)
674 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000675#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart25a439a2009-04-24 14:49:50 +0000676 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
677 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000678#endif
bart7b706b32009-05-10 06:55:39 +0000679 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000680 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000681 }
682 /* If some UWords have to be cleared entirely, do this now. */
683#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
684 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
685#endif
bart7b706b32009-05-10 06:55:39 +0000686 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000687 {
bart7b706b32009-05-10 06:55:39 +0000688 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000689#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000690 tl_assert(uword_lsb(address_lsb(c)) == 0);
691 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000692 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
693 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000694#endif
bart25a439a2009-04-24 14:49:50 +0000695 if (c_next > c)
696 {
bart7b706b32009-05-10 06:55:39 +0000697 UWord idx = uword_msb(address_lsb(c));
698 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000699 c = c_next;
700 }
bart578eeb42009-04-23 15:42:27 +0000701 }
702 /* If the last address in the bitmap that must be cleared does not */
703 /* fall on an UWord boundary, clear the last addresses. */
704#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
705 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
706#endif
bart7b706b32009-05-10 06:55:39 +0000707 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000708 }
bart9c4224c2008-03-29 14:40:08 +0000709}
710
bart99edb292009-02-15 15:59:20 +0000711/**
712 * Clear all references to stores in bitmap bm starting at address a1 and
713 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000714 */
bart99edb292009-02-15 15:59:20 +0000715void DRD_(bm_clear_store)(struct bitmap* const bm,
716 const Addr a1, const Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000717{
bart578eeb42009-04-23 15:42:27 +0000718 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000719
bart578eeb42009-04-23 15:42:27 +0000720 tl_assert(bm);
721 tl_assert(a1);
722 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000723 tl_assert(a1 == first_address_with_same_lsb(a1));
724 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000725
726 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000727 {
bart578eeb42009-04-23 15:42:27 +0000728 struct bitmap2* p2;
729 Addr c;
730
731#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
732 tl_assert(a1 <= b && b < a2);
733#endif
734
bart7b706b32009-05-10 06:55:39 +0000735 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000736
bart7b706b32009-05-10 06:55:39 +0000737 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000738 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000739 {
barte6e86c52009-04-25 06:53:00 +0000740 b_next = a2;
bart578eeb42009-04-23 15:42:27 +0000741 }
742
barte2c7e672009-04-23 19:23:09 +0000743 if (p2 == 0)
744 continue;
745
bart578eeb42009-04-23 15:42:27 +0000746 c = b;
747 /* If the first address in the bitmap that must be cleared does not */
748 /* start on an UWord boundary, start clearing the first addresses. */
749#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
750 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
751#endif
bart7b706b32009-05-10 06:55:39 +0000752 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000753 {
bart7b706b32009-05-10 06:55:39 +0000754 Addr c_next = first_address_with_higher_uword_msb(c);
barte6e86c52009-04-25 06:53:00 +0000755 if (c_next > b_next)
756 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000757#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
barte6e86c52009-04-25 06:53:00 +0000758 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
759 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000760#endif
bart7b706b32009-05-10 06:55:39 +0000761 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
barte6e86c52009-04-25 06:53:00 +0000762 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000763 }
764 /* If some UWords have to be cleared entirely, do this now. */
765#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
766 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
767#endif
bart7b706b32009-05-10 06:55:39 +0000768 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000769 {
bart7b706b32009-05-10 06:55:39 +0000770 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000771#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000772 tl_assert(uword_lsb(address_lsb(c)) == 0);
773 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
barte6e86c52009-04-25 06:53:00 +0000774 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
775 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000776#endif
barte6e86c52009-04-25 06:53:00 +0000777 if (c_next > c)
778 {
bart7b706b32009-05-10 06:55:39 +0000779 UWord idx = uword_msb(address_lsb(c));
780 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
barte6e86c52009-04-25 06:53:00 +0000781 c = c_next;
782 }
bart578eeb42009-04-23 15:42:27 +0000783 }
784 /* If the last address in the bitmap that must be cleared does not */
785 /* fall on an UWord boundary, clear the last addresses. */
786#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
787 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
788#endif
bart7b706b32009-05-10 06:55:39 +0000789 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000790 }
bart9c4224c2008-03-29 14:40:08 +0000791}
792
bart99edb292009-02-15 15:59:20 +0000793/**
794 * Clear bitmap bm starting at address a1 and up to but not including address
795 * a2. Return True if and only if any of the addresses was set before
796 * clearing.
bart8bf2f8b2008-03-30 17:56:43 +0000797 */
bart99edb292009-02-15 15:59:20 +0000798Bool DRD_(bm_test_and_clear)(struct bitmap* const bm,
799 const Addr a1, const Addr a2)
bart8bf2f8b2008-03-30 17:56:43 +0000800{
bartbedfd232009-03-26 19:07:15 +0000801 Bool result;
bart8bf2f8b2008-03-30 17:56:43 +0000802
bartbedfd232009-03-26 19:07:15 +0000803 result = DRD_(bm_has_any_access)(bm, a1, a2) != 0;
804 DRD_(bm_clear)(bm, a1, a2);
805 return result;
bart8bf2f8b2008-03-30 17:56:43 +0000806}
807
bart99edb292009-02-15 15:59:20 +0000808Bool DRD_(bm_has_conflict_with)(struct bitmap* const bm,
809 const Addr a1, const Addr a2,
810 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000811{
bartbedfd232009-03-26 19:07:15 +0000812 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000813
bartbedfd232009-03-26 19:07:15 +0000814 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000815
bartbedfd232009-03-26 19:07:15 +0000816 for (b = a1; b < a2; b = b_next)
817 {
bart7b706b32009-05-10 06:55:39 +0000818 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bart36556122008-03-13 19:24:30 +0000819
bart7b706b32009-05-10 06:55:39 +0000820 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000821 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000822 {
bartbedfd232009-03-26 19:07:15 +0000823 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000824 }
bartbedfd232009-03-26 19:07:15 +0000825
826 if (bm2)
827 {
828 Addr b_start;
829 Addr b_end;
830 UWord b0;
831 const struct bitmap1* const p1 = &bm2->bm1;
832
bart7b706b32009-05-10 06:55:39 +0000833 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000834 b_start = a1;
835 else
bart7b706b32009-05-10 06:55:39 +0000836 if (make_address(bm2->addr, 0) < a2)
837 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000838 else
839 break;
840 tl_assert(a1 <= b_start && b_start <= a2);
841
bart7b706b32009-05-10 06:55:39 +0000842 if (make_address(bm2->addr + 1, 0) < a2)
843 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000844 else
845 b_end = a2;
846 tl_assert(a1 <= b_end && b_end <= a2);
847 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000848 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000849
bart7b706b32009-05-10 06:55:39 +0000850 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000851 {
852 if (access_type == eLoad)
853 {
854 if (bm0_is_set(p1->bm0_w, b0))
855 {
856 return True;
857 }
858 }
859 else
860 {
861 tl_assert(access_type == eStore);
862 if (bm0_is_set(p1->bm0_r, b0)
863 | bm0_is_set(p1->bm0_w, b0))
864 {
865 return True;
866 }
867 }
868 }
869 }
870 }
871 return False;
sewardjaf44c822007-11-25 14:01:38 +0000872}
873
bart99edb292009-02-15 15:59:20 +0000874Bool DRD_(bm_load_has_conflict_with)(struct bitmap* const bm,
875 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000876{
bartbedfd232009-03-26 19:07:15 +0000877 return DRD_(bm_has_conflict_with)(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000878}
879
bart99edb292009-02-15 15:59:20 +0000880Bool DRD_(bm_load_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000881{
bartbedfd232009-03-26 19:07:15 +0000882 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000883}
884
bart99edb292009-02-15 15:59:20 +0000885Bool DRD_(bm_load_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000886{
bartbedfd232009-03-26 19:07:15 +0000887 if ((a1 & 1) == 0)
888 return bm_aligned_load_has_conflict_with(bm, a1, 2);
889 else
890 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000891}
892
bart99edb292009-02-15 15:59:20 +0000893Bool DRD_(bm_load_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000894{
bartbedfd232009-03-26 19:07:15 +0000895 if ((a1 & 3) == 0)
896 return bm_aligned_load_has_conflict_with(bm, a1, 4);
897 else
898 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000899}
900
bart99edb292009-02-15 15:59:20 +0000901Bool DRD_(bm_load_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000902{
bartbedfd232009-03-26 19:07:15 +0000903 if ((a1 & 7) == 0)
904 return bm_aligned_load_has_conflict_with(bm, a1, 8);
905 else
906 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000907}
908
bart99edb292009-02-15 15:59:20 +0000909Bool DRD_(bm_store_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000910{
bartbedfd232009-03-26 19:07:15 +0000911 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000912}
913
bart99edb292009-02-15 15:59:20 +0000914Bool DRD_(bm_store_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000915{
bartbedfd232009-03-26 19:07:15 +0000916 if ((a1 & 1) == 0)
917 return bm_aligned_store_has_conflict_with(bm, a1, 2);
918 else
919 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000920}
921
bart99edb292009-02-15 15:59:20 +0000922Bool DRD_(bm_store_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000923{
bartbedfd232009-03-26 19:07:15 +0000924 if ((a1 & 3) == 0)
925 return bm_aligned_store_has_conflict_with(bm, a1, 4);
926 else
927 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000928}
929
bart99edb292009-02-15 15:59:20 +0000930Bool DRD_(bm_store_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000931{
bartbedfd232009-03-26 19:07:15 +0000932 if ((a1 & 7) == 0)
933 return bm_aligned_store_has_conflict_with(bm, a1, 8);
934 else
935 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000936}
937
bart99edb292009-02-15 15:59:20 +0000938Bool DRD_(bm_store_has_conflict_with)(struct bitmap* const bm,
939 const Addr a1, const Addr a2)
bart36556122008-03-13 19:24:30 +0000940{
bartbedfd232009-03-26 19:07:15 +0000941 return DRD_(bm_has_conflict_with)(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000942}
943
bart99edb292009-02-15 15:59:20 +0000944/**
945 * Return True if the two bitmaps *lhs and *rhs are identical, and false
946 * if not.
bart7cd7d7f2008-04-14 16:10:01 +0000947 */
bart99edb292009-02-15 15:59:20 +0000948Bool DRD_(bm_equal)(struct bitmap* const lhs, struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000949{
bartbedfd232009-03-26 19:07:15 +0000950 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +0000951 struct bitmap2* bm2r;
bart7cd7d7f2008-04-14 16:10:01 +0000952
bartbedfd232009-03-26 19:07:15 +0000953 /* It's not possible to have two independent iterators over the same OSet, */
954 /* so complain if lhs == rhs. */
955 tl_assert(lhs != rhs);
barta3f61092008-05-04 07:46:20 +0000956
bartbedfd232009-03-26 19:07:15 +0000957 VG_(OSetGen_ResetIter)(lhs->oset);
958 VG_(OSetGen_ResetIter)(rhs->oset);
bart7cd7d7f2008-04-14 16:10:01 +0000959
bart7b706b32009-05-10 06:55:39 +0000960 for ( ; (bm2l = VG_(OSetGen_Next)(lhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +0000961 {
bart7b706b32009-05-10 06:55:39 +0000962 while (bm2l
bartbedfd232009-03-26 19:07:15 +0000963 && ! DRD_(bm_has_any_access)(lhs,
bart7b706b32009-05-10 06:55:39 +0000964 make_address(bm2l->addr, 0),
965 make_address(bm2l->addr + 1, 0)))
bartbedfd232009-03-26 19:07:15 +0000966 {
bart7b706b32009-05-10 06:55:39 +0000967 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +0000968 }
bart7b706b32009-05-10 06:55:39 +0000969 if (bm2l == 0)
bartbedfd232009-03-26 19:07:15 +0000970 break;
971 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000972
bartb634b5d2009-04-26 14:42:33 +0000973 do
bartbedfd232009-03-26 19:07:15 +0000974 {
bart7b706b32009-05-10 06:55:39 +0000975 bm2r = VG_(OSetGen_Next)(rhs->oset);
976 if (bm2r == 0)
bartb634b5d2009-04-26 14:42:33 +0000977 return False;
bartbedfd232009-03-26 19:07:15 +0000978 }
bartb634b5d2009-04-26 14:42:33 +0000979 while (! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000980 make_address(bm2r->addr, 0),
981 make_address(bm2r->addr + 1, 0)));
bartb634b5d2009-04-26 14:42:33 +0000982
bartbedfd232009-03-26 19:07:15 +0000983 tl_assert(bm2r);
984 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000985 make_address(bm2r->addr, 0),
986 make_address(bm2r->addr + 1, 0)));
barta3f61092008-05-04 07:46:20 +0000987
bartbedfd232009-03-26 19:07:15 +0000988 if (bm2l != bm2r
989 && (bm2l->addr != bm2r->addr
990 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
991 {
bartbedfd232009-03-26 19:07:15 +0000992 return False;
993 }
994 }
bartb634b5d2009-04-26 14:42:33 +0000995
996 do
997 {
998 bm2r = VG_(OSetGen_Next)(rhs->oset);
999 } while (bm2r && ! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +00001000 make_address(bm2r->addr, 0),
1001 make_address(bm2r->addr + 1, 0)));
bartbedfd232009-03-26 19:07:15 +00001002 if (bm2r)
1003 {
1004 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +00001005 make_address(bm2r->addr, 0),
1006 make_address(bm2r->addr + 1, 0)));
bart7cd7d7f2008-04-14 16:10:01 +00001007 return False;
bartbedfd232009-03-26 19:07:15 +00001008 }
1009 return True;
bart7cd7d7f2008-04-14 16:10:01 +00001010}
1011
bart99edb292009-02-15 15:59:20 +00001012void DRD_(bm_swap)(struct bitmap* const bm1, struct bitmap* const bm2)
sewardjaf44c822007-11-25 14:01:38 +00001013{
bartbedfd232009-03-26 19:07:15 +00001014 OSet* const tmp = bm1->oset;
1015 bm1->oset = bm2->oset;
1016 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +00001017}
1018
bartf647d342008-03-24 19:12:12 +00001019/** Merge bitmaps *lhs and *rhs into *lhs. */
bart8f822af2009-06-08 18:20:42 +00001020void DRD_(bm_merge2)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +00001021{
bartbedfd232009-03-26 19:07:15 +00001022 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +00001023 struct bitmap2* bm2r;
bart7b706b32009-05-10 06:55:39 +00001024
bart8f822af2009-06-08 18:20:42 +00001025 /*
1026 * It's not possible to have two independent iterators over the same OSet,
1027 * so complain if lhs == rhs.
1028 */
bart7b706b32009-05-10 06:55:39 +00001029 tl_assert(lhs != rhs);
1030
1031 s_bitmap_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +00001032
bartbedfd232009-03-26 19:07:15 +00001033 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001034
bart7b706b32009-05-10 06:55:39 +00001035 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +00001036 {
bart7b706b32009-05-10 06:55:39 +00001037 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1038 if (bm2l)
bartf647d342008-03-24 19:12:12 +00001039 {
bart7b706b32009-05-10 06:55:39 +00001040 tl_assert(bm2l != bm2r);
1041 bm2_merge(bm2l, bm2r);
bartf647d342008-03-24 19:12:12 +00001042 }
bartbedfd232009-03-26 19:07:15 +00001043 else
1044 {
bart7b706b32009-05-10 06:55:39 +00001045 bm2_insert_copy(lhs, bm2r);
bartbedfd232009-03-26 19:07:15 +00001046 }
1047 }
sewardjaf44c822007-11-25 14:01:38 +00001048}
1049
bart8f822af2009-06-08 18:20:42 +00001050/** Clear bitmap2::recalc. */
1051void DRD_(bm_unmark)(struct bitmap* bm)
1052{
1053 struct bitmap2* bm2;
1054
1055 for (VG_(OSetGen_ResetIter)(bm->oset);
1056 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1057 )
1058 {
1059 bm2->recalc = False;
1060 }
1061}
1062
1063/**
1064 * Report whether bitmap2::recalc has been set for the second level bitmap
1065 * corresponding to address a.
1066 */
1067Bool DRD_(bm_is_marked)(struct bitmap* bm, const Addr a)
1068{
1069 const struct bitmap2* bm2;
1070
1071 bm2 = bm2_lookup(bm, a);
1072 return bm2 && bm2->recalc;
1073}
1074
1075/**
1076 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1077 * at least one access.
1078 *
1079 * @note Any new second-level bitmaps inserted in bml by this function are
1080 * uninitialized.
1081 */
1082void DRD_(bm_mark)(struct bitmap* bml, struct bitmap* bmr)
1083{
1084 struct bitmap2* bm2l;
1085 struct bitmap2* bm2r;
1086
1087 for (VG_(OSetGen_ResetIter)(bmr->oset);
1088 (bm2r = VG_(OSetGen_Next)(bmr->oset)) != 0;
1089 )
1090 {
bart43ab3392011-07-03 11:42:03 +00001091 bm2l = bm2_lookup_or_insert(bml, bm2r->addr);
1092 bm2l->recalc = True;
bart8f822af2009-06-08 18:20:42 +00001093 }
1094}
1095
1096/** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1097void DRD_(bm_clear_marked)(struct bitmap* bm)
1098{
1099 struct bitmap2* bm2;
1100
1101 for (VG_(OSetGen_ResetIter)(bm->oset);
1102 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1103 )
1104 {
1105 if (bm2->recalc)
1106 bm2_clear(bm2);
1107 }
1108}
1109
1110/** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1111void DRD_(bm_merge2_marked)(struct bitmap* const lhs, struct bitmap* const rhs)
1112{
1113 struct bitmap2* bm2l;
1114 struct bitmap2* bm2r;
1115
bart8f822af2009-06-08 18:20:42 +00001116 /*
1117 * It's not possible to have two independent iterators over the same OSet,
1118 * so complain if lhs == rhs.
1119 */
1120 tl_assert(lhs != rhs);
1121
1122 s_bitmap_merge_count++;
1123
1124 VG_(OSetGen_ResetIter)(rhs->oset);
1125
1126 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
1127 {
1128 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1129 if (bm2l && bm2l->recalc)
1130 {
1131 tl_assert(bm2l != bm2r);
1132 bm2_merge(bm2l, bm2r);
1133 }
1134 }
1135}
1136
1137/** Remove all marked second-level bitmaps that do not contain any access. */
1138void DRD_(bm_remove_cleared_marked)(struct bitmap* bm)
1139{
1140 struct bitmap2* bm2;
1141
1142 VG_(OSetGen_ResetIter)(bm->oset);
1143 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
1144 {
1145 const UWord a1 = bm2->addr;
1146 if (bm2->recalc
1147 && ! DRD_(bm_has_any_access(bm, make_address(a1, 0),
1148 make_address(a1 + 1, 0))))
1149 {
1150 bm2_remove(bm, a1);
1151 VG_(OSetGen_ResetIterAt)(bm->oset, &a1);
1152 }
1153 }
1154}
1155
sewardjaf44c822007-11-25 14:01:38 +00001156/**
1157 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1158 * @param lhs First bitmap.
1159 * @param rhs Bitmap to be compared with lhs.
1160 * @return !=0 if there are data races, == 0 if there are none.
1161 */
bart99edb292009-02-15 15:59:20 +00001162int DRD_(bm_has_races)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +00001163{
bartbedfd232009-03-26 19:07:15 +00001164 VG_(OSetGen_ResetIter)(lhs->oset);
1165 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001166
bartbedfd232009-03-26 19:07:15 +00001167 for (;;)
1168 {
bartbedfd232009-03-26 19:07:15 +00001169 const struct bitmap2* bm2l;
1170 const struct bitmap2* bm2r;
1171 const struct bitmap1* bm1l;
1172 const struct bitmap1* bm1r;
1173 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001174
bart7b706b32009-05-10 06:55:39 +00001175 bm2l = VG_(OSetGen_Next)(lhs->oset);
1176 bm2r = VG_(OSetGen_Next)(rhs->oset);
bartbedfd232009-03-26 19:07:15 +00001177 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
sewardjaf44c822007-11-25 14:01:38 +00001178 {
bartbedfd232009-03-26 19:07:15 +00001179 if (bm2l->addr < bm2r->addr)
bart7b706b32009-05-10 06:55:39 +00001180 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +00001181 else
bart7b706b32009-05-10 06:55:39 +00001182 bm2r = VG_(OSetGen_Next)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001183 }
bartbedfd232009-03-26 19:07:15 +00001184 if (bm2l == 0 || bm2r == 0)
1185 break;
1186
1187 bm1l = &bm2l->bm1;
1188 bm1r = &bm2r->bm1;
1189
1190 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1191 {
1192 unsigned b;
1193 for (b = 0; b < BITS_PER_UWORD; b++)
1194 {
1195 UWord const access_mask
1196 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
1197 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
1198 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
1199 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
bart7b706b32009-05-10 06:55:39 +00001200 Addr const a = make_address(bm2l->addr, k * BITS_PER_UWORD | b);
bartbedfd232009-03-26 19:07:15 +00001201 if (HAS_RACE(access_mask) && ! DRD_(is_suppressed)(a, a + 1))
1202 {
1203 return 1;
1204 }
1205 }
1206 }
1207 }
1208 return 0;
sewardjaf44c822007-11-25 14:01:38 +00001209}
1210
bart99edb292009-02-15 15:59:20 +00001211void DRD_(bm_print)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +00001212{
bartbedfd232009-03-26 19:07:15 +00001213 struct bitmap2* bm2;
sewardjaf44c822007-11-25 14:01:38 +00001214
bart7b706b32009-05-10 06:55:39 +00001215 for (VG_(OSetGen_ResetIter)(bm->oset);
1216 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1217 )
bartbedfd232009-03-26 19:07:15 +00001218 {
bart7b706b32009-05-10 06:55:39 +00001219 bm2_print(bm2);
1220 }
1221}
bartf647d342008-03-24 19:12:12 +00001222
bart7b706b32009-05-10 06:55:39 +00001223static void bm2_print(const struct bitmap2* const bm2)
1224{
1225 const struct bitmap1* bm1;
1226 Addr a;
1227
1228 tl_assert(bm2);
1229
1230 bm1 = &bm2->bm1;
1231 for (a = make_address(bm2->addr, 0);
1232 a <= make_address(bm2->addr + 1, 0) - 1;
1233 a++)
1234 {
1235 const Bool r = bm0_is_set(bm1->bm0_r, address_lsb(a)) != 0;
1236 const Bool w = bm0_is_set(bm1->bm0_w, address_lsb(a)) != 0;
1237 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +00001238 {
bart7b706b32009-05-10 06:55:39 +00001239 VG_(printf)("0x%08lx %c %c\n",
1240 a,
1241 w ? 'W' : ' ',
1242 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +00001243 }
bartbedfd232009-03-26 19:07:15 +00001244 }
sewardjaf44c822007-11-25 14:01:38 +00001245}
1246
bart99edb292009-02-15 15:59:20 +00001247ULong DRD_(bm_get_bitmap_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001248{
bartbedfd232009-03-26 19:07:15 +00001249 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001250}
1251
bart99edb292009-02-15 15:59:20 +00001252ULong DRD_(bm_get_bitmap2_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001253{
bartbedfd232009-03-26 19:07:15 +00001254 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001255}
1256
bart7b706b32009-05-10 06:55:39 +00001257ULong DRD_(bm_get_bitmap2_merge_count)(void)
bartf647d342008-03-24 19:12:12 +00001258{
bart7b706b32009-05-10 06:55:39 +00001259 return s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +00001260}
1261
bart7b706b32009-05-10 06:55:39 +00001262/** Compute *bm2l |= *bm2r. */
1263static
1264void bm2_merge(struct bitmap2* const bm2l, const struct bitmap2* const bm2r)
sewardjaf44c822007-11-25 14:01:38 +00001265{
bartbedfd232009-03-26 19:07:15 +00001266 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001267
bartbedfd232009-03-26 19:07:15 +00001268 tl_assert(bm2l);
1269 tl_assert(bm2r);
1270 tl_assert(bm2l->addr == bm2r->addr);
bart7b706b32009-05-10 06:55:39 +00001271
1272 s_bitmap2_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +00001273
bartbedfd232009-03-26 19:07:15 +00001274 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1275 {
1276 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1277 }
1278 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1279 {
1280 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1281 }
sewardjaf44c822007-11-25 14:01:38 +00001282}