blob: 2b9db28a68e4290b7ef47777893588f513bfc1b9 [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
Elliott Hughesed398002017-06-21 14:41:24 -07004 Copyright (C) 2006-2017 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 */
bart39934d62009-02-15 16:18:03 +000031#include "pub_tool_libcassert.h" /* tl_assert() */
32#include "pub_tool_libcbase.h" /* VG_(memset) */
33#include "pub_tool_libcprint.h" /* VG_(printf) */
bart39934d62009-02-15 16:18:03 +000034#include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
sewardjaf44c822007-11-25 14:01:38 +000035
36
bartf647d342008-03-24 19:12:12 +000037/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000038
39static void bm2_merge(struct bitmap2* const bm2l,
40 const struct bitmap2* const bm2r);
bart7b706b32009-05-10 06:55:39 +000041static void bm2_print(const struct bitmap2* const bm2);
sewardjaf44c822007-11-25 14:01:38 +000042
43
bart99edb292009-02-15 15:59:20 +000044/* Local variables. */
bartf647d342008-03-24 19:12:12 +000045
barte44bccc2012-01-18 09:46:57 +000046static OSet* s_bm2_set_template;
bartf647d342008-03-24 19:12:12 +000047static ULong s_bitmap_creation_count;
bart7b706b32009-05-10 06:55:39 +000048static ULong s_bitmap_merge_count;
49static ULong s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +000050
51
52/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000053
barte44bccc2012-01-18 09:46:57 +000054void DRD_(bm_module_init)(void)
55{
56 tl_assert(!s_bm2_set_template);
57 s_bm2_set_template
58 = VG_(OSetGen_Create_With_Pool)(0, 0, VG_(malloc), "drd.bitmap.bn.2",
59 VG_(free), 512, sizeof(struct bitmap2));
60}
61
62void DRD_(bm_module_cleanup)(void)
63{
64 tl_assert(s_bm2_set_template);
65 VG_(OSetGen_Destroy)(s_bm2_set_template);
66 s_bm2_set_template = NULL;
67}
68
bart99edb292009-02-15 15:59:20 +000069struct bitmap* DRD_(bm_new)()
sewardjaf44c822007-11-25 14:01:38 +000070{
bartbedfd232009-03-26 19:07:15 +000071 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000072
bartbedfd232009-03-26 19:07:15 +000073 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
74 /* in drd_bitmap.h. */
75 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000076
bartbedfd232009-03-26 19:07:15 +000077 bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
bart8f822af2009-06-08 18:20:42 +000078 DRD_(bm_init)(bm);
sewardjaf44c822007-11-25 14:01:38 +000079
bartbedfd232009-03-26 19:07:15 +000080 return bm;
sewardjaf44c822007-11-25 14:01:38 +000081}
82
bart99edb292009-02-15 15:59:20 +000083void DRD_(bm_delete)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +000084{
bartbedfd232009-03-26 19:07:15 +000085 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000086
bart8f822af2009-06-08 18:20:42 +000087 DRD_(bm_cleanup)(bm);
bartbedfd232009-03-26 19:07:15 +000088 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +000089}
90
bart8f822af2009-06-08 18:20:42 +000091/** Initialize *bm. */
92void DRD_(bm_init)(struct bitmap* const bm)
93{
94 unsigned i;
95
96 tl_assert(bm);
bart9f617a82009-06-21 18:08:31 +000097 /*
98 * Cache initialization. a1 is initialized with a value that never can
bart8f822af2009-06-08 18:20:42 +000099 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
100 * bits of a1 are always zero for a valid cache entry.
101 */
102 for (i = 0; i < DRD_BITMAP_N_CACHE_ELEM; i++)
103 {
104 bm->cache[i].a1 = ~(UWord)1;
105 bm->cache[i].bm2 = 0;
106 }
barte44bccc2012-01-18 09:46:57 +0000107 bm->oset = VG_(OSetGen_EmptyClone)(s_bm2_set_template);
bart9f617a82009-06-21 18:08:31 +0000108
109 s_bitmap_creation_count++;
bart8f822af2009-06-08 18:20:42 +0000110}
111
112/** Free the memory allocated by DRD_(bm_init)(). */
113void DRD_(bm_cleanup)(struct bitmap* const bm)
114{
115 VG_(OSetGen_Destroy)(bm->oset);
116}
117
sewardjaf44c822007-11-25 14:01:38 +0000118/**
bart36556122008-03-13 19:24:30 +0000119 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000120 * bitmap bm.
bart7b706b32009-05-10 06:55:39 +0000121 *
122 * @note The current implementation of bm_access_range does not work for the
123 * highest addresses in the address range. At least on Linux this is
124 * not a problem since the upper part of the address space is reserved
125 * for the kernel.
sewardjaf44c822007-11-25 14:01:38 +0000126 */
bart99edb292009-02-15 15:59:20 +0000127void DRD_(bm_access_range)(struct bitmap* const bm,
128 const Addr a1, const Addr a2,
129 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000130{
barte6e86c52009-04-25 06:53:00 +0000131 tl_assert(access_type == eLoad || access_type == eStore);
132
133 if (access_type == eLoad)
134 return DRD_(bm_access_range_load)(bm, a1, a2);
135 else
136 return DRD_(bm_access_range_store)(bm, a1, a2);
137}
138
bart7b706b32009-05-10 06:55:39 +0000139void DRD_(bm_access_range_load)(struct bitmap* const bm, Addr a1, Addr a2)
barte6e86c52009-04-25 06:53:00 +0000140{
bartbedfd232009-03-26 19:07:15 +0000141 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000142
bartbedfd232009-03-26 19:07:15 +0000143 tl_assert(bm);
barta3003982010-09-08 16:29:17 +0000144 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000145 tl_assert(a2 < first_address_with_higher_msb(a2));
146 tl_assert(a1 == first_address_with_same_lsb(a1));
147 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000148
bartbedfd232009-03-26 19:07:15 +0000149 for (b = a1; b < a2; b = b_next)
150 {
151 Addr b_start;
152 Addr b_end;
153 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000154 UWord b0;
bart36556122008-03-13 19:24:30 +0000155
bart7b706b32009-05-10 06:55:39 +0000156 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000157 if (b_next > a2)
158 {
159 b_next = a2;
160 }
bart36556122008-03-13 19:24:30 +0000161
bart7b706b32009-05-10 06:55:39 +0000162 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
bartbedfd232009-03-26 19:07:15 +0000163 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000164
bart7b706b32009-05-10 06:55:39 +0000165 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000166 b_start = a1;
bart36556122008-03-13 19:24:30 +0000167 else
bart7b706b32009-05-10 06:55:39 +0000168 if (make_address(bm2->addr, 0) < a2)
169 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000170 else
171 break;
bart36556122008-03-13 19:24:30 +0000172
bart7b706b32009-05-10 06:55:39 +0000173 if (make_address(bm2->addr + 1, 0) < a2)
174 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000175 else
176 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000177
178 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000179 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
180 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000181
bart7b706b32009-05-10 06:55:39 +0000182 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
bart36556122008-03-13 19:24:30 +0000183 {
bartf43b1772009-04-25 08:08:33 +0000184 unsigned k;
185
186 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
187 {
188 bm2->bm1.bm0_r[k] = ~(UWord)0;
189 }
190 }
191 else
192 {
bart7b706b32009-05-10 06:55:39 +0000193 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000194 {
195 bm0_set(bm2->bm1.bm0_r, b0);
196 }
bart3772a982008-03-15 08:11:03 +0000197 }
bartbedfd232009-03-26 19:07:15 +0000198 }
sewardjaf44c822007-11-25 14:01:38 +0000199}
200
bart99edb292009-02-15 15:59:20 +0000201void DRD_(bm_access_load_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000202{
bartbedfd232009-03-26 19:07:15 +0000203 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000204}
205
bart99edb292009-02-15 15:59:20 +0000206void DRD_(bm_access_load_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000207{
bartbedfd232009-03-26 19:07:15 +0000208 if ((a1 & 1) == 0)
209 bm_access_aligned_load(bm, a1, 2);
210 else
211 DRD_(bm_access_range)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000212}
213
bart99edb292009-02-15 15:59:20 +0000214void DRD_(bm_access_load_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000215{
bartbedfd232009-03-26 19:07:15 +0000216 if ((a1 & 3) == 0)
217 bm_access_aligned_load(bm, a1, 4);
218 else
219 DRD_(bm_access_range)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000220}
221
bart99edb292009-02-15 15:59:20 +0000222void DRD_(bm_access_load_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000223{
bartbedfd232009-03-26 19:07:15 +0000224 if ((a1 & 7) == 0)
225 bm_access_aligned_load(bm, a1, 8);
226 else if ((a1 & 3) == 0)
227 {
228 bm_access_aligned_load(bm, a1 + 0, 4);
229 bm_access_aligned_load(bm, a1 + 4, 4);
230 }
231 else
232 DRD_(bm_access_range)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000233}
234
bart99edb292009-02-15 15:59:20 +0000235void DRD_(bm_access_range_store)(struct bitmap* const bm,
236 const Addr a1, const Addr a2)
bartf5acbbc2008-05-10 08:22:20 +0000237{
barte6e86c52009-04-25 06:53:00 +0000238 Addr b, b_next;
239
240 tl_assert(bm);
barta3003982010-09-08 16:29:17 +0000241 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000242 tl_assert(a2 < first_address_with_higher_msb(a2));
243 tl_assert(a1 == first_address_with_same_lsb(a1));
244 tl_assert(a2 == first_address_with_same_lsb(a2));
barte6e86c52009-04-25 06:53:00 +0000245
246 for (b = a1; b < a2; b = b_next)
247 {
248 Addr b_start;
249 Addr b_end;
250 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000251 UWord b0;
barte6e86c52009-04-25 06:53:00 +0000252
bart7b706b32009-05-10 06:55:39 +0000253 b_next = first_address_with_higher_msb(b);
barte6e86c52009-04-25 06:53:00 +0000254 if (b_next > a2)
255 {
256 b_next = a2;
257 }
258
bart7b706b32009-05-10 06:55:39 +0000259 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
barte6e86c52009-04-25 06:53:00 +0000260 tl_assert(bm2);
261
bart7b706b32009-05-10 06:55:39 +0000262 if (make_address(bm2->addr, 0) < a1)
barte6e86c52009-04-25 06:53:00 +0000263 b_start = a1;
264 else
bart7b706b32009-05-10 06:55:39 +0000265 if (make_address(bm2->addr, 0) < a2)
266 b_start = make_address(bm2->addr, 0);
barte6e86c52009-04-25 06:53:00 +0000267 else
268 break;
barte6e86c52009-04-25 06:53:00 +0000269
bart7b706b32009-05-10 06:55:39 +0000270 if (make_address(bm2->addr + 1, 0) < a2)
271 b_end = make_address(bm2->addr + 1, 0);
barte6e86c52009-04-25 06:53:00 +0000272 else
273 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000274
275 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000276 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
277 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000278
bart7b706b32009-05-10 06:55:39 +0000279 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
barte6e86c52009-04-25 06:53:00 +0000280 {
bartf43b1772009-04-25 08:08:33 +0000281 unsigned k;
282
283 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
284 {
285 bm2->bm1.bm0_w[k] = ~(UWord)0;
286 }
287 }
288 else
289 {
bart7b706b32009-05-10 06:55:39 +0000290 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000291 {
292 bm0_set(bm2->bm1.bm0_w, b0);
293 }
barte6e86c52009-04-25 06:53:00 +0000294 }
295 }
bartf5acbbc2008-05-10 08:22:20 +0000296}
297
bart99edb292009-02-15 15:59:20 +0000298void DRD_(bm_access_store_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000299{
bartbedfd232009-03-26 19:07:15 +0000300 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000301}
302
bart99edb292009-02-15 15:59:20 +0000303void DRD_(bm_access_store_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000304{
bartbedfd232009-03-26 19:07:15 +0000305 if ((a1 & 1) == 0)
306 bm_access_aligned_store(bm, a1, 2);
307 else
308 DRD_(bm_access_range)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000309}
310
bart99edb292009-02-15 15:59:20 +0000311void DRD_(bm_access_store_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000312{
bartbedfd232009-03-26 19:07:15 +0000313 if ((a1 & 3) == 0)
314 bm_access_aligned_store(bm, a1, 4);
315 else
316 DRD_(bm_access_range)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000317}
318
bart99edb292009-02-15 15:59:20 +0000319void DRD_(bm_access_store_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000320{
bartbedfd232009-03-26 19:07:15 +0000321 if ((a1 & 7) == 0)
322 bm_access_aligned_store(bm, a1, 8);
323 else if ((a1 & 3) == 0)
324 {
325 bm_access_aligned_store(bm, a1 + 0, 4);
326 bm_access_aligned_store(bm, a1 + 4, 4);
327 }
328 else
329 DRD_(bm_access_range)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000330}
331
bart99edb292009-02-15 15:59:20 +0000332Bool DRD_(bm_has)(struct bitmap* const bm, const Addr a1, const Addr a2,
333 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000334{
bartda3a77b2009-04-23 20:07:23 +0000335 tl_assert(access_type == eLoad || access_type == eStore);
bartda3a77b2009-04-23 20:07:23 +0000336
337 if (access_type == eLoad)
338 return DRD_(bm_has_any_load)(bm, a1, a2);
339 else
340 return DRD_(bm_has_any_store)(bm, a1, a2);
sewardjaf44c822007-11-25 14:01:38 +0000341}
342
bart59d93d72011-12-12 19:02:34 +0000343Bool DRD_(bm_has_any_load_g)(struct bitmap* const bm)
344{
345 struct bitmap2* bm2;
346
347 tl_assert(bm);
348
349 VG_(OSetGen_ResetIter)(bm->oset);
350 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != NULL; ) {
351 Addr b_start;
352 Addr b_end;
353 UWord b0;
354 const struct bitmap1* const p1 = &bm2->bm1;
355
356 b_start = make_address(bm2->addr, 0);
357 b_end = make_address(bm2->addr + 1, 0);
358
359 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
360 if (bm0_is_set(p1->bm0_r, b0))
361 return True;
362 }
363 return False;
364}
365
bart99edb292009-02-15 15:59:20 +0000366Bool
367DRD_(bm_has_any_load)(struct bitmap* const bm, const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000368{
bartbedfd232009-03-26 19:07:15 +0000369 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000370
bartbedfd232009-03-26 19:07:15 +0000371 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000372
bartbedfd232009-03-26 19:07:15 +0000373 for (b = a1; b < a2; b = b_next)
374 {
bart7b706b32009-05-10 06:55:39 +0000375 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000376
bart7b706b32009-05-10 06:55:39 +0000377 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000378 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000379 {
bartbedfd232009-03-26 19:07:15 +0000380 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000381 }
bartbedfd232009-03-26 19:07:15 +0000382
383 if (bm2)
384 {
385 Addr b_start;
386 Addr b_end;
387 UWord b0;
388 const struct bitmap1* const p1 = &bm2->bm1;
389
bart7b706b32009-05-10 06:55:39 +0000390 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000391 b_start = a1;
392 else
bart7b706b32009-05-10 06:55:39 +0000393 if (make_address(bm2->addr, 0) < a2)
394 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000395 else
396 break;
397 tl_assert(a1 <= b_start && b_start <= a2);
398
bart7b706b32009-05-10 06:55:39 +0000399 if (make_address(bm2->addr + 1, 0) < a2)
400 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000401 else
402 b_end = a2;
403 tl_assert(a1 <= b_end && b_end <= a2);
404 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000405 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000406
bart7b706b32009-05-10 06:55:39 +0000407 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000408 {
409 if (bm0_is_set(p1->bm0_r, b0))
410 {
411 return True;
412 }
413 }
414 }
415 }
416 return 0;
bartd4907072008-03-30 18:41:07 +0000417}
418
bart99edb292009-02-15 15:59:20 +0000419Bool DRD_(bm_has_any_store)(struct bitmap* const bm,
420 const Addr a1, const Addr a2)
bartd4907072008-03-30 18:41:07 +0000421{
bartbedfd232009-03-26 19:07:15 +0000422 Addr b, b_next;
bartd4907072008-03-30 18:41:07 +0000423
bartbedfd232009-03-26 19:07:15 +0000424 tl_assert(bm);
bartd4907072008-03-30 18:41:07 +0000425
bartbedfd232009-03-26 19:07:15 +0000426 for (b = a1; b < a2; b = b_next)
427 {
bart7b706b32009-05-10 06:55:39 +0000428 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000429
bart7b706b32009-05-10 06:55:39 +0000430 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000431 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000432 {
bartbedfd232009-03-26 19:07:15 +0000433 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000434 }
bartbedfd232009-03-26 19:07:15 +0000435
436 if (bm2)
437 {
438 Addr b_start;
439 Addr b_end;
440 UWord b0;
441 const struct bitmap1* const p1 = &bm2->bm1;
442
bart7b706b32009-05-10 06:55:39 +0000443 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000444 b_start = a1;
445 else
bart7b706b32009-05-10 06:55:39 +0000446 if (make_address(bm2->addr, 0) < a2)
447 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000448 else
449 break;
450 tl_assert(a1 <= b_start && b_start <= a2);
451
bart7b706b32009-05-10 06:55:39 +0000452 if (make_address(bm2->addr + 1, 0) < a2)
453 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000454 else
455 b_end = a2;
456 tl_assert(a1 <= b_end && b_end <= a2);
457 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000458 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000459
bart7b706b32009-05-10 06:55:39 +0000460 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000461 {
462 if (bm0_is_set(p1->bm0_w, b0))
463 {
464 return True;
465 }
466 }
467 }
468 }
469 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000470}
471
bartc2c81db2008-05-10 11:19:10 +0000472/* Return True if there is a read access, write access or both */
473/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
bart99edb292009-02-15 15:59:20 +0000474Bool DRD_(bm_has_any_access)(struct bitmap* const bm,
475 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000476{
bartbedfd232009-03-26 19:07:15 +0000477 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000478
bartbedfd232009-03-26 19:07:15 +0000479 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000480
bartbedfd232009-03-26 19:07:15 +0000481 for (b = a1; b < a2; b = b_next)
482 {
bart7b706b32009-05-10 06:55:39 +0000483 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000484
bart7b706b32009-05-10 06:55:39 +0000485 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000486 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000487 {
bartbedfd232009-03-26 19:07:15 +0000488 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000489 }
bartbedfd232009-03-26 19:07:15 +0000490
491 if (bm2)
492 {
493 Addr b_start;
494 Addr b_end;
495 UWord b0;
496 const struct bitmap1* const p1 = &bm2->bm1;
497
bart7b706b32009-05-10 06:55:39 +0000498 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000499 b_start = a1;
500 else
bart7b706b32009-05-10 06:55:39 +0000501 if (make_address(bm2->addr, 0) < a2)
502 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000503 else
504 break;
505 tl_assert(a1 <= b_start && b_start <= a2);
506
bart7b706b32009-05-10 06:55:39 +0000507 if (make_address(bm2->addr + 1, 0) < a2)
508 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000509 else
510 b_end = a2;
511 tl_assert(a1 <= b_end && b_end <= a2);
512 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000513 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000514
bart7b706b32009-05-10 06:55:39 +0000515 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000516 {
bart8f822af2009-06-08 18:20:42 +0000517 /*
518 * Note: the statement below uses a binary or instead of a logical
519 * or on purpose.
520 */
bartbedfd232009-03-26 19:07:15 +0000521 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
522 {
523 return True;
524 }
525 }
526 }
527 }
528 return False;
sewardjaf44c822007-11-25 14:01:38 +0000529}
530
bart99edb292009-02-15 15:59:20 +0000531/**
532 * Report whether an access of type access_type at address a is recorded in
533 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000534 */
bart99edb292009-02-15 15:59:20 +0000535Bool DRD_(bm_has_1)(struct bitmap* const bm,
536 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000537{
bartbedfd232009-03-26 19:07:15 +0000538 const struct bitmap2* p2;
539 const struct bitmap1* p1;
540 const UWord* p0;
bart7b706b32009-05-10 06:55:39 +0000541 const UWord a0 = address_lsb(a);
sewardjaf44c822007-11-25 14:01:38 +0000542
bartbedfd232009-03-26 19:07:15 +0000543 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000544
bart7b706b32009-05-10 06:55:39 +0000545 p2 = bm2_lookup(bm, address_msb(a));
bartbedfd232009-03-26 19:07:15 +0000546 if (p2)
547 {
548 p1 = &p2->bm1;
549 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
550 return bm0_is_set(p0, a0) ? True : False;
551 }
552 return False;
sewardjaf44c822007-11-25 14:01:38 +0000553}
554
bart7b706b32009-05-10 06:55:39 +0000555void DRD_(bm_clear)(struct bitmap* const bm, Addr a1, Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000556{
bartbedfd232009-03-26 19:07:15 +0000557 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000558
bartbedfd232009-03-26 19:07:15 +0000559 tl_assert(bm);
560 tl_assert(a1);
561 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000562 tl_assert(a1 == first_address_with_same_lsb(a1));
563 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000564
bartbedfd232009-03-26 19:07:15 +0000565 for (b = a1; b < a2; b = b_next)
566 {
bart578eeb42009-04-23 15:42:27 +0000567 struct bitmap2* p2;
568 Addr c;
569
570#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
571 tl_assert(a1 <= b && b < a2);
572#endif
573
bart7b706b32009-05-10 06:55:39 +0000574 p2 = bm2_lookup_exclusive(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000575
bart7b706b32009-05-10 06:55:39 +0000576 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000577 if (b_next > a2)
sewardjaf44c822007-11-25 14:01:38 +0000578 {
bartbedfd232009-03-26 19:07:15 +0000579 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000580 }
bartbedfd232009-03-26 19:07:15 +0000581
barte2c7e672009-04-23 19:23:09 +0000582 if (p2 == 0)
583 continue;
584
bart578eeb42009-04-23 15:42:27 +0000585 c = b;
586 /* If the first address in the bitmap that must be cleared does not */
587 /* start on an UWord boundary, start clearing the first addresses. */
bart7b706b32009-05-10 06:55:39 +0000588 if (uword_lsb(address_lsb(c)))
sewardjaf44c822007-11-25 14:01:38 +0000589 {
bart7b706b32009-05-10 06:55:39 +0000590 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000591 if (c_next > b_next)
592 c_next = b_next;
593#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
594 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
595 && b_next <= a2);
596#endif
bart7b706b32009-05-10 06:55:39 +0000597 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
598 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000599 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000600 }
601 /* If some UWords have to be cleared entirely, do this now. */
bart7b706b32009-05-10 06:55:39 +0000602 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000603 {
bart7b706b32009-05-10 06:55:39 +0000604 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000605#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000606 tl_assert(uword_lsb(address_lsb(c)) == 0);
607 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000608 tl_assert(c_next <= b_next);
bart578eeb42009-04-23 15:42:27 +0000609#endif
bart25a439a2009-04-24 14:49:50 +0000610 if (c_next > c)
611 {
bart7b706b32009-05-10 06:55:39 +0000612 UWord idx = uword_msb(address_lsb(c));
613 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
614 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000615 c = c_next;
616 }
bart578eeb42009-04-23 15:42:27 +0000617 }
618 /* If the last address in the bitmap that must be cleared does not */
619 /* fall on an UWord boundary, clear the last addresses. */
bart25a439a2009-04-24 14:49:50 +0000620#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
621 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
622#endif
bart7b706b32009-05-10 06:55:39 +0000623 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
624 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000625 }
sewardjaf44c822007-11-25 14:01:38 +0000626}
sewardjaf44c822007-11-25 14:01:38 +0000627
bart99edb292009-02-15 15:59:20 +0000628/**
629 * Clear all references to loads in bitmap bm starting at address a1 and
630 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000631 */
bart7b706b32009-05-10 06:55:39 +0000632void DRD_(bm_clear_load)(struct bitmap* const bm, Addr a1, Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000633{
bart578eeb42009-04-23 15:42:27 +0000634 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000635
bart578eeb42009-04-23 15:42:27 +0000636 tl_assert(bm);
637 tl_assert(a1);
638 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000639 tl_assert(a1 == first_address_with_same_lsb(a1));
640 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000641
642 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000643 {
bart578eeb42009-04-23 15:42:27 +0000644 struct bitmap2* p2;
645 Addr c;
646
647#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
648 tl_assert(a1 <= b && b < a2);
649#endif
650
bart7b706b32009-05-10 06:55:39 +0000651 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000652
bart7b706b32009-05-10 06:55:39 +0000653 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000654 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000655 {
bart578eeb42009-04-23 15:42:27 +0000656 b_next = a2;
657 }
658
barte2c7e672009-04-23 19:23:09 +0000659 if (p2 == 0)
660 continue;
661
bart578eeb42009-04-23 15:42:27 +0000662 c = b;
663 /* If the first address in the bitmap that must be cleared does not */
664 /* start on an UWord boundary, start clearing the first addresses. */
665#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
666 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
667#endif
bart7b706b32009-05-10 06:55:39 +0000668 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000669 {
bart7b706b32009-05-10 06:55:39 +0000670 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000671 if (c_next > b_next)
672 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000673#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart25a439a2009-04-24 14:49:50 +0000674 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
675 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000676#endif
bart7b706b32009-05-10 06:55:39 +0000677 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000678 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000679 }
680 /* If some UWords have to be cleared entirely, do this now. */
681#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
682 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
683#endif
bart7b706b32009-05-10 06:55:39 +0000684 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000685 {
bart7b706b32009-05-10 06:55:39 +0000686 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000687#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000688 tl_assert(uword_lsb(address_lsb(c)) == 0);
689 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000690 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
691 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000692#endif
bart25a439a2009-04-24 14:49:50 +0000693 if (c_next > c)
694 {
bart7b706b32009-05-10 06:55:39 +0000695 UWord idx = uword_msb(address_lsb(c));
696 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000697 c = c_next;
698 }
bart578eeb42009-04-23 15:42:27 +0000699 }
700 /* If the last address in the bitmap that must be cleared does not */
701 /* fall on an UWord boundary, clear the last addresses. */
702#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
703 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
704#endif
bart7b706b32009-05-10 06:55:39 +0000705 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000706 }
bart9c4224c2008-03-29 14:40:08 +0000707}
708
bart99edb292009-02-15 15:59:20 +0000709/**
710 * Clear all references to stores in bitmap bm starting at address a1 and
711 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000712 */
bart99edb292009-02-15 15:59:20 +0000713void DRD_(bm_clear_store)(struct bitmap* const bm,
714 const Addr a1, const Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000715{
bart578eeb42009-04-23 15:42:27 +0000716 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000717
bart578eeb42009-04-23 15:42:27 +0000718 tl_assert(bm);
719 tl_assert(a1);
720 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000721 tl_assert(a1 == first_address_with_same_lsb(a1));
722 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000723
724 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000725 {
bart578eeb42009-04-23 15:42:27 +0000726 struct bitmap2* p2;
727 Addr c;
728
729#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
730 tl_assert(a1 <= b && b < a2);
731#endif
732
bart7b706b32009-05-10 06:55:39 +0000733 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000734
bart7b706b32009-05-10 06:55:39 +0000735 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000736 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000737 {
barte6e86c52009-04-25 06:53:00 +0000738 b_next = a2;
bart578eeb42009-04-23 15:42:27 +0000739 }
740
barte2c7e672009-04-23 19:23:09 +0000741 if (p2 == 0)
742 continue;
743
bart578eeb42009-04-23 15:42:27 +0000744 c = b;
745 /* If the first address in the bitmap that must be cleared does not */
746 /* start on an UWord boundary, start clearing the first addresses. */
747#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
748 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
749#endif
bart7b706b32009-05-10 06:55:39 +0000750 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000751 {
bart7b706b32009-05-10 06:55:39 +0000752 Addr c_next = first_address_with_higher_uword_msb(c);
barte6e86c52009-04-25 06:53:00 +0000753 if (c_next > b_next)
754 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000755#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
barte6e86c52009-04-25 06:53:00 +0000756 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
757 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000758#endif
bart7b706b32009-05-10 06:55:39 +0000759 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
barte6e86c52009-04-25 06:53:00 +0000760 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000761 }
762 /* If some UWords have to be cleared entirely, do this now. */
763#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
764 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
765#endif
bart7b706b32009-05-10 06:55:39 +0000766 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000767 {
bart7b706b32009-05-10 06:55:39 +0000768 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000769#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000770 tl_assert(uword_lsb(address_lsb(c)) == 0);
771 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
barte6e86c52009-04-25 06:53:00 +0000772 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
773 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000774#endif
barte6e86c52009-04-25 06:53:00 +0000775 if (c_next > c)
776 {
bart7b706b32009-05-10 06:55:39 +0000777 UWord idx = uword_msb(address_lsb(c));
778 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
barte6e86c52009-04-25 06:53:00 +0000779 c = c_next;
780 }
bart578eeb42009-04-23 15:42:27 +0000781 }
782 /* If the last address in the bitmap that must be cleared does not */
783 /* fall on an UWord boundary, clear the last addresses. */
784#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
785 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
786#endif
bart7b706b32009-05-10 06:55:39 +0000787 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000788 }
bart9c4224c2008-03-29 14:40:08 +0000789}
790
bart99edb292009-02-15 15:59:20 +0000791/**
792 * Clear bitmap bm starting at address a1 and up to but not including address
793 * a2. Return True if and only if any of the addresses was set before
794 * clearing.
bart8bf2f8b2008-03-30 17:56:43 +0000795 */
bart99edb292009-02-15 15:59:20 +0000796Bool DRD_(bm_test_and_clear)(struct bitmap* const bm,
797 const Addr a1, const Addr a2)
bart8bf2f8b2008-03-30 17:56:43 +0000798{
bartbedfd232009-03-26 19:07:15 +0000799 Bool result;
bart8bf2f8b2008-03-30 17:56:43 +0000800
bartbedfd232009-03-26 19:07:15 +0000801 result = DRD_(bm_has_any_access)(bm, a1, a2) != 0;
802 DRD_(bm_clear)(bm, a1, a2);
803 return result;
bart8bf2f8b2008-03-30 17:56:43 +0000804}
805
bart99edb292009-02-15 15:59:20 +0000806Bool DRD_(bm_has_conflict_with)(struct bitmap* const bm,
807 const Addr a1, const Addr a2,
808 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000809{
bartbedfd232009-03-26 19:07:15 +0000810 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000811
bartbedfd232009-03-26 19:07:15 +0000812 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000813
bartbedfd232009-03-26 19:07:15 +0000814 for (b = a1; b < a2; b = b_next)
815 {
bart7b706b32009-05-10 06:55:39 +0000816 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bart36556122008-03-13 19:24:30 +0000817
bart7b706b32009-05-10 06:55:39 +0000818 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000819 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000820 {
bartbedfd232009-03-26 19:07:15 +0000821 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000822 }
bartbedfd232009-03-26 19:07:15 +0000823
824 if (bm2)
825 {
826 Addr b_start;
827 Addr b_end;
828 UWord b0;
829 const struct bitmap1* const p1 = &bm2->bm1;
830
bart7b706b32009-05-10 06:55:39 +0000831 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000832 b_start = a1;
833 else
bart7b706b32009-05-10 06:55:39 +0000834 if (make_address(bm2->addr, 0) < a2)
835 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000836 else
837 break;
838 tl_assert(a1 <= b_start && b_start <= a2);
839
bart7b706b32009-05-10 06:55:39 +0000840 if (make_address(bm2->addr + 1, 0) < a2)
841 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000842 else
843 b_end = a2;
844 tl_assert(a1 <= b_end && b_end <= a2);
845 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000846 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000847
bart7b706b32009-05-10 06:55:39 +0000848 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000849 {
850 if (access_type == eLoad)
851 {
852 if (bm0_is_set(p1->bm0_w, b0))
853 {
854 return True;
855 }
856 }
857 else
858 {
859 tl_assert(access_type == eStore);
860 if (bm0_is_set(p1->bm0_r, b0)
861 | bm0_is_set(p1->bm0_w, b0))
862 {
863 return True;
864 }
865 }
866 }
867 }
868 }
869 return False;
sewardjaf44c822007-11-25 14:01:38 +0000870}
871
bart99edb292009-02-15 15:59:20 +0000872Bool DRD_(bm_load_has_conflict_with)(struct bitmap* const bm,
873 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000874{
bartbedfd232009-03-26 19:07:15 +0000875 return DRD_(bm_has_conflict_with)(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000876}
877
bart99edb292009-02-15 15:59:20 +0000878Bool DRD_(bm_load_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000879{
bartbedfd232009-03-26 19:07:15 +0000880 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000881}
882
bart99edb292009-02-15 15:59:20 +0000883Bool DRD_(bm_load_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000884{
bartbedfd232009-03-26 19:07:15 +0000885 if ((a1 & 1) == 0)
886 return bm_aligned_load_has_conflict_with(bm, a1, 2);
887 else
888 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000889}
890
bart99edb292009-02-15 15:59:20 +0000891Bool DRD_(bm_load_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000892{
bartbedfd232009-03-26 19:07:15 +0000893 if ((a1 & 3) == 0)
894 return bm_aligned_load_has_conflict_with(bm, a1, 4);
895 else
896 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000897}
898
bart99edb292009-02-15 15:59:20 +0000899Bool DRD_(bm_load_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000900{
bartbedfd232009-03-26 19:07:15 +0000901 if ((a1 & 7) == 0)
902 return bm_aligned_load_has_conflict_with(bm, a1, 8);
903 else
904 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000905}
906
bart99edb292009-02-15 15:59:20 +0000907Bool DRD_(bm_store_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000908{
bartbedfd232009-03-26 19:07:15 +0000909 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000910}
911
bart99edb292009-02-15 15:59:20 +0000912Bool DRD_(bm_store_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000913{
bartbedfd232009-03-26 19:07:15 +0000914 if ((a1 & 1) == 0)
915 return bm_aligned_store_has_conflict_with(bm, a1, 2);
916 else
917 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000918}
919
bart99edb292009-02-15 15:59:20 +0000920Bool DRD_(bm_store_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000921{
bartbedfd232009-03-26 19:07:15 +0000922 if ((a1 & 3) == 0)
923 return bm_aligned_store_has_conflict_with(bm, a1, 4);
924 else
925 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000926}
927
bart99edb292009-02-15 15:59:20 +0000928Bool DRD_(bm_store_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000929{
bartbedfd232009-03-26 19:07:15 +0000930 if ((a1 & 7) == 0)
931 return bm_aligned_store_has_conflict_with(bm, a1, 8);
932 else
933 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000934}
935
bart99edb292009-02-15 15:59:20 +0000936Bool DRD_(bm_store_has_conflict_with)(struct bitmap* const bm,
937 const Addr a1, const Addr a2)
bart36556122008-03-13 19:24:30 +0000938{
bartbedfd232009-03-26 19:07:15 +0000939 return DRD_(bm_has_conflict_with)(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000940}
941
bart99edb292009-02-15 15:59:20 +0000942/**
943 * Return True if the two bitmaps *lhs and *rhs are identical, and false
944 * if not.
bart7cd7d7f2008-04-14 16:10:01 +0000945 */
bart99edb292009-02-15 15:59:20 +0000946Bool DRD_(bm_equal)(struct bitmap* const lhs, struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000947{
bartbedfd232009-03-26 19:07:15 +0000948 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +0000949 struct bitmap2* bm2r;
bart7cd7d7f2008-04-14 16:10:01 +0000950
bartbedfd232009-03-26 19:07:15 +0000951 /* It's not possible to have two independent iterators over the same OSet, */
952 /* so complain if lhs == rhs. */
953 tl_assert(lhs != rhs);
barta3f61092008-05-04 07:46:20 +0000954
bartbedfd232009-03-26 19:07:15 +0000955 VG_(OSetGen_ResetIter)(lhs->oset);
956 VG_(OSetGen_ResetIter)(rhs->oset);
bart7cd7d7f2008-04-14 16:10:01 +0000957
bart7b706b32009-05-10 06:55:39 +0000958 for ( ; (bm2l = VG_(OSetGen_Next)(lhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +0000959 {
bart7b706b32009-05-10 06:55:39 +0000960 while (bm2l
bartbedfd232009-03-26 19:07:15 +0000961 && ! DRD_(bm_has_any_access)(lhs,
bart7b706b32009-05-10 06:55:39 +0000962 make_address(bm2l->addr, 0),
963 make_address(bm2l->addr + 1, 0)))
bartbedfd232009-03-26 19:07:15 +0000964 {
bart7b706b32009-05-10 06:55:39 +0000965 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +0000966 }
bart7b706b32009-05-10 06:55:39 +0000967 if (bm2l == 0)
bartbedfd232009-03-26 19:07:15 +0000968 break;
969 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000970
bartb634b5d2009-04-26 14:42:33 +0000971 do
bartbedfd232009-03-26 19:07:15 +0000972 {
bart7b706b32009-05-10 06:55:39 +0000973 bm2r = VG_(OSetGen_Next)(rhs->oset);
974 if (bm2r == 0)
bartb634b5d2009-04-26 14:42:33 +0000975 return False;
bartbedfd232009-03-26 19:07:15 +0000976 }
bartb634b5d2009-04-26 14:42:33 +0000977 while (! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000978 make_address(bm2r->addr, 0),
979 make_address(bm2r->addr + 1, 0)));
bartb634b5d2009-04-26 14:42:33 +0000980
bartbedfd232009-03-26 19:07:15 +0000981 tl_assert(bm2r);
982 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000983 make_address(bm2r->addr, 0),
984 make_address(bm2r->addr + 1, 0)));
barta3f61092008-05-04 07:46:20 +0000985
bartbedfd232009-03-26 19:07:15 +0000986 if (bm2l != bm2r
987 && (bm2l->addr != bm2r->addr
988 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
989 {
bartbedfd232009-03-26 19:07:15 +0000990 return False;
991 }
992 }
bartb634b5d2009-04-26 14:42:33 +0000993
994 do
995 {
996 bm2r = VG_(OSetGen_Next)(rhs->oset);
997 } while (bm2r && ! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000998 make_address(bm2r->addr, 0),
999 make_address(bm2r->addr + 1, 0)));
bartbedfd232009-03-26 19:07:15 +00001000 if (bm2r)
1001 {
1002 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +00001003 make_address(bm2r->addr, 0),
1004 make_address(bm2r->addr + 1, 0)));
bart7cd7d7f2008-04-14 16:10:01 +00001005 return False;
bartbedfd232009-03-26 19:07:15 +00001006 }
1007 return True;
bart7cd7d7f2008-04-14 16:10:01 +00001008}
1009
bart99edb292009-02-15 15:59:20 +00001010void DRD_(bm_swap)(struct bitmap* const bm1, struct bitmap* const bm2)
sewardjaf44c822007-11-25 14:01:38 +00001011{
bartbedfd232009-03-26 19:07:15 +00001012 OSet* const tmp = bm1->oset;
1013 bm1->oset = bm2->oset;
1014 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +00001015}
1016
bartf647d342008-03-24 19:12:12 +00001017/** Merge bitmaps *lhs and *rhs into *lhs. */
bart8f822af2009-06-08 18:20:42 +00001018void DRD_(bm_merge2)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +00001019{
bartbedfd232009-03-26 19:07:15 +00001020 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +00001021 struct bitmap2* bm2r;
bart7b706b32009-05-10 06:55:39 +00001022
bart8f822af2009-06-08 18:20:42 +00001023 /*
1024 * It's not possible to have two independent iterators over the same OSet,
1025 * so complain if lhs == rhs.
1026 */
bart7b706b32009-05-10 06:55:39 +00001027 tl_assert(lhs != rhs);
1028
1029 s_bitmap_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +00001030
bartbedfd232009-03-26 19:07:15 +00001031 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001032
bart7b706b32009-05-10 06:55:39 +00001033 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +00001034 {
bart7b706b32009-05-10 06:55:39 +00001035 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1036 if (bm2l)
bartf647d342008-03-24 19:12:12 +00001037 {
bart7b706b32009-05-10 06:55:39 +00001038 tl_assert(bm2l != bm2r);
1039 bm2_merge(bm2l, bm2r);
bartf647d342008-03-24 19:12:12 +00001040 }
bartbedfd232009-03-26 19:07:15 +00001041 else
1042 {
bart7b706b32009-05-10 06:55:39 +00001043 bm2_insert_copy(lhs, bm2r);
bartbedfd232009-03-26 19:07:15 +00001044 }
1045 }
sewardjaf44c822007-11-25 14:01:38 +00001046}
1047
bart8f822af2009-06-08 18:20:42 +00001048/** Clear bitmap2::recalc. */
1049void DRD_(bm_unmark)(struct bitmap* bm)
1050{
1051 struct bitmap2* bm2;
1052
1053 for (VG_(OSetGen_ResetIter)(bm->oset);
1054 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1055 )
1056 {
1057 bm2->recalc = False;
1058 }
1059}
1060
1061/**
1062 * Report whether bitmap2::recalc has been set for the second level bitmap
1063 * corresponding to address a.
1064 */
1065Bool DRD_(bm_is_marked)(struct bitmap* bm, const Addr a)
1066{
1067 const struct bitmap2* bm2;
1068
1069 bm2 = bm2_lookup(bm, a);
1070 return bm2 && bm2->recalc;
1071}
1072
1073/**
1074 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1075 * at least one access.
1076 *
1077 * @note Any new second-level bitmaps inserted in bml by this function are
1078 * uninitialized.
1079 */
1080void DRD_(bm_mark)(struct bitmap* bml, struct bitmap* bmr)
1081{
1082 struct bitmap2* bm2l;
1083 struct bitmap2* bm2r;
1084
1085 for (VG_(OSetGen_ResetIter)(bmr->oset);
1086 (bm2r = VG_(OSetGen_Next)(bmr->oset)) != 0;
1087 )
1088 {
bart43ab3392011-07-03 11:42:03 +00001089 bm2l = bm2_lookup_or_insert(bml, bm2r->addr);
1090 bm2l->recalc = True;
bart8f822af2009-06-08 18:20:42 +00001091 }
1092}
1093
1094/** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1095void DRD_(bm_clear_marked)(struct bitmap* bm)
1096{
1097 struct bitmap2* bm2;
1098
1099 for (VG_(OSetGen_ResetIter)(bm->oset);
1100 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1101 )
1102 {
1103 if (bm2->recalc)
1104 bm2_clear(bm2);
1105 }
1106}
1107
1108/** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1109void DRD_(bm_merge2_marked)(struct bitmap* const lhs, struct bitmap* const rhs)
1110{
1111 struct bitmap2* bm2l;
1112 struct bitmap2* bm2r;
1113
bart8f822af2009-06-08 18:20:42 +00001114 /*
1115 * It's not possible to have two independent iterators over the same OSet,
1116 * so complain if lhs == rhs.
1117 */
1118 tl_assert(lhs != rhs);
1119
1120 s_bitmap_merge_count++;
1121
1122 VG_(OSetGen_ResetIter)(rhs->oset);
1123
1124 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
1125 {
1126 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1127 if (bm2l && bm2l->recalc)
1128 {
1129 tl_assert(bm2l != bm2r);
1130 bm2_merge(bm2l, bm2r);
1131 }
1132 }
1133}
1134
1135/** Remove all marked second-level bitmaps that do not contain any access. */
1136void DRD_(bm_remove_cleared_marked)(struct bitmap* bm)
1137{
1138 struct bitmap2* bm2;
1139
1140 VG_(OSetGen_ResetIter)(bm->oset);
1141 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
1142 {
1143 const UWord a1 = bm2->addr;
1144 if (bm2->recalc
1145 && ! DRD_(bm_has_any_access(bm, make_address(a1, 0),
1146 make_address(a1 + 1, 0))))
1147 {
1148 bm2_remove(bm, a1);
1149 VG_(OSetGen_ResetIterAt)(bm->oset, &a1);
1150 }
1151 }
1152}
1153
sewardjaf44c822007-11-25 14:01:38 +00001154/**
1155 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1156 * @param lhs First bitmap.
1157 * @param rhs Bitmap to be compared with lhs.
1158 * @return !=0 if there are data races, == 0 if there are none.
1159 */
bart99edb292009-02-15 15:59:20 +00001160int DRD_(bm_has_races)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +00001161{
bartbedfd232009-03-26 19:07:15 +00001162 VG_(OSetGen_ResetIter)(lhs->oset);
1163 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001164
bartbedfd232009-03-26 19:07:15 +00001165 for (;;)
1166 {
bartbedfd232009-03-26 19:07:15 +00001167 const struct bitmap2* bm2l;
1168 const struct bitmap2* bm2r;
1169 const struct bitmap1* bm1l;
1170 const struct bitmap1* bm1r;
1171 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001172
bart7b706b32009-05-10 06:55:39 +00001173 bm2l = VG_(OSetGen_Next)(lhs->oset);
1174 bm2r = VG_(OSetGen_Next)(rhs->oset);
bartbedfd232009-03-26 19:07:15 +00001175 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
sewardjaf44c822007-11-25 14:01:38 +00001176 {
bartbedfd232009-03-26 19:07:15 +00001177 if (bm2l->addr < bm2r->addr)
bart7b706b32009-05-10 06:55:39 +00001178 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +00001179 else
bart7b706b32009-05-10 06:55:39 +00001180 bm2r = VG_(OSetGen_Next)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001181 }
bartbedfd232009-03-26 19:07:15 +00001182 if (bm2l == 0 || bm2r == 0)
1183 break;
1184
1185 bm1l = &bm2l->bm1;
1186 bm1r = &bm2r->bm1;
1187
1188 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1189 {
1190 unsigned b;
1191 for (b = 0; b < BITS_PER_UWORD; b++)
1192 {
1193 UWord const access_mask
1194 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
1195 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
1196 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
1197 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
bart7b706b32009-05-10 06:55:39 +00001198 Addr const a = make_address(bm2l->addr, k * BITS_PER_UWORD | b);
bartbedfd232009-03-26 19:07:15 +00001199 if (HAS_RACE(access_mask) && ! DRD_(is_suppressed)(a, a + 1))
1200 {
1201 return 1;
1202 }
1203 }
1204 }
1205 }
1206 return 0;
sewardjaf44c822007-11-25 14:01:38 +00001207}
1208
bart99edb292009-02-15 15:59:20 +00001209void DRD_(bm_print)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +00001210{
bartbedfd232009-03-26 19:07:15 +00001211 struct bitmap2* bm2;
sewardjaf44c822007-11-25 14:01:38 +00001212
bart7b706b32009-05-10 06:55:39 +00001213 for (VG_(OSetGen_ResetIter)(bm->oset);
1214 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1215 )
bartbedfd232009-03-26 19:07:15 +00001216 {
bart7b706b32009-05-10 06:55:39 +00001217 bm2_print(bm2);
1218 }
1219}
bartf647d342008-03-24 19:12:12 +00001220
bart7b706b32009-05-10 06:55:39 +00001221static void bm2_print(const struct bitmap2* const bm2)
1222{
1223 const struct bitmap1* bm1;
1224 Addr a;
1225
1226 tl_assert(bm2);
1227
1228 bm1 = &bm2->bm1;
1229 for (a = make_address(bm2->addr, 0);
1230 a <= make_address(bm2->addr + 1, 0) - 1;
1231 a++)
1232 {
1233 const Bool r = bm0_is_set(bm1->bm0_r, address_lsb(a)) != 0;
1234 const Bool w = bm0_is_set(bm1->bm0_w, address_lsb(a)) != 0;
1235 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +00001236 {
bart7b706b32009-05-10 06:55:39 +00001237 VG_(printf)("0x%08lx %c %c\n",
1238 a,
1239 w ? 'W' : ' ',
1240 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +00001241 }
bartbedfd232009-03-26 19:07:15 +00001242 }
sewardjaf44c822007-11-25 14:01:38 +00001243}
1244
bart99edb292009-02-15 15:59:20 +00001245ULong DRD_(bm_get_bitmap_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001246{
bartbedfd232009-03-26 19:07:15 +00001247 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001248}
1249
bart99edb292009-02-15 15:59:20 +00001250ULong DRD_(bm_get_bitmap2_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001251{
bartbedfd232009-03-26 19:07:15 +00001252 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001253}
1254
bart7b706b32009-05-10 06:55:39 +00001255ULong DRD_(bm_get_bitmap2_merge_count)(void)
bartf647d342008-03-24 19:12:12 +00001256{
bart7b706b32009-05-10 06:55:39 +00001257 return s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +00001258}
1259
bart7b706b32009-05-10 06:55:39 +00001260/** Compute *bm2l |= *bm2r. */
1261static
1262void bm2_merge(struct bitmap2* const bm2l, const struct bitmap2* const bm2r)
sewardjaf44c822007-11-25 14:01:38 +00001263{
bartbedfd232009-03-26 19:07:15 +00001264 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001265
bartbedfd232009-03-26 19:07:15 +00001266 tl_assert(bm2l);
1267 tl_assert(bm2r);
1268 tl_assert(bm2l->addr == bm2r->addr);
bart7b706b32009-05-10 06:55:39 +00001269
1270 s_bitmap2_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +00001271
bartbedfd232009-03-26 19:07:15 +00001272 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1273 {
1274 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1275 }
1276 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1277 {
1278 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1279 }
sewardjaf44c822007-11-25 14:01:38 +00001280}