blob: 9e5d1bab24d88e77bf70a53f912a367bf88e2c77 [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001/*
2 This file is part of drd, a data race detector.
3
sewardj85642922008-01-14 11:54:56 +00004 Copyright (C) 2006-2008 Bart Van Assche
sewardjaf44c822007-11-25 14:01:38 +00005 bart.vanassche@gmail.com
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
26#include "pub_tool_basics.h" // Addr, SizeT
27#include "pub_tool_debuginfo.h" // VG_(get_objname)()
28#include "pub_tool_libcassert.h" // tl_assert()
29#include "pub_tool_libcbase.h" // VG_(memset)
30#include "pub_tool_libcprint.h" // VG_(printf)
31#include "pub_tool_machine.h" // VG_(get_IP)()
32#include "pub_tool_mallocfree.h" // VG_(malloc), VG_(free)
33#include "pub_drd_bitmap.h"
34#include "drd_bitmap.h"
35#include "drd_error.h"
36#include "drd_suppression.h"
37
38
bartf647d342008-03-24 19:12:12 +000039/* Forward declarations. */
sewardjaf44c822007-11-25 14:01:38 +000040
bartf647d342008-03-24 19:12:12 +000041struct bitmap2;
sewardjaf44c822007-11-25 14:01:38 +000042
43
bartf647d342008-03-24 19:12:12 +000044/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000045
46static void bm2_merge(struct bitmap2* const bm2l,
47 const struct bitmap2* const bm2r);
48
49
bartf647d342008-03-24 19:12:12 +000050/* Local constants. */
51
52static ULong s_bitmap_creation_count;
53
54
55/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000056
57struct bitmap* bm_new()
58{
bart33e56c92008-03-24 06:41:30 +000059 unsigned i;
bart3772a982008-03-15 08:11:03 +000060 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000061
bartf29205e2008-03-25 18:51:06 +000062 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
63 /* in drd_bitmap.h. */
bart3772a982008-03-15 08:11:03 +000064 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000065
sewardj9c606bd2008-09-18 18:12:50 +000066 bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
bart3772a982008-03-15 08:11:03 +000067 tl_assert(bm);
bartf29205e2008-03-25 18:51:06 +000068 /* Cache initialization. a1 is initialized with a value that never can */
69 /* match any valid address: the upper ADDR0_BITS bits of a1 are always */
70 /* zero for a valid cache entry. */
bart33e56c92008-03-24 06:41:30 +000071 for (i = 0; i < N_CACHE_ELEM; i++)
72 {
bartf29205e2008-03-25 18:51:06 +000073 bm->cache[i].a1 = ~(UWord)1;
bart33e56c92008-03-24 06:41:30 +000074 bm->cache[i].bm2 = 0;
75 }
sewardj9c606bd2008-09-18 18:12:50 +000076 bm->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), "drd.bitmap.bn.2",
77 VG_(free));
sewardjaf44c822007-11-25 14:01:38 +000078
bart3772a982008-03-15 08:11:03 +000079 s_bitmap_creation_count++;
sewardjaf44c822007-11-25 14:01:38 +000080
bart3772a982008-03-15 08:11:03 +000081 return bm;
sewardjaf44c822007-11-25 14:01:38 +000082}
83
84void bm_delete(struct bitmap* const bm)
85{
bartf647d342008-03-24 19:12:12 +000086 struct bitmap2* bm2;
87 struct bitmap2ref* bm2ref;
88
bart3772a982008-03-15 08:11:03 +000089 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000090
91 VG_(OSetGen_ResetIter)(bm->oset);
92 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
93 {
94 bm2 = bm2ref->bm2;
95 tl_assert(bm2->refcnt >= 1);
96 if (--bm2->refcnt == 0)
97 {
98 VG_(free)(bm2);
99 }
100 }
101
bart3772a982008-03-15 08:11:03 +0000102 VG_(OSetGen_Destroy)(bm->oset);
103 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +0000104}
105
106/**
bart36556122008-03-13 19:24:30 +0000107 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000108 * bitmap bm.
109 */
110void bm_access_range(struct bitmap* const bm,
bart9036dea2008-03-13 19:10:06 +0000111 const Addr a1, const Addr a2,
bart0268dfa2008-03-11 20:10:21 +0000112 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000113{
bart3772a982008-03-15 08:11:03 +0000114 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000115
bart3772a982008-03-15 08:11:03 +0000116 tl_assert(bm);
117 tl_assert(a1 < a2);
barta3f61092008-05-04 07:46:20 +0000118 /* The current implementation of bm_access_range does not work for the */
119 /* ADDR0_COUNT highest addresses in the address range. At least on Linux */
120 /* this is not a problem since the upper part of the address space is */
121 /* reserved for the kernel. */
122 tl_assert(a2 + ADDR0_COUNT > a2);
sewardjaf44c822007-11-25 14:01:38 +0000123
bart3772a982008-03-15 08:11:03 +0000124 for (b = a1; b < a2; b = b_next)
125 {
126 Addr b_start;
127 Addr b_end;
128 struct bitmap2* bm2;
129 SPLIT_ADDRESS(b);
bart36556122008-03-13 19:24:30 +0000130
bart3772a982008-03-15 08:11:03 +0000131 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
132 if (b_next > a2)
133 {
134 b_next = a2;
135 }
bart36556122008-03-13 19:24:30 +0000136
bartf647d342008-03-24 19:12:12 +0000137 bm2 = bm2_lookup_or_insert_exclusive(bm, b1);
bart3772a982008-03-15 08:11:03 +0000138 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000139
bart3772a982008-03-15 08:11:03 +0000140 if ((bm2->addr << ADDR0_BITS) < a1)
141 b_start = a1;
142 else
143 if ((bm2->addr << ADDR0_BITS) < a2)
144 b_start = (bm2->addr << ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000145 else
bart3772a982008-03-15 08:11:03 +0000146 break;
147 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000148
bart3772a982008-03-15 08:11:03 +0000149 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
150 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
151 else
152 b_end = a2;
153 tl_assert(a1 <= b_end && b_end <= a2);
154 tl_assert(b_start < b_end);
155 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000156
bart0008f5b2008-03-22 17:07:39 +0000157 if (access_type == eLoad)
bart3772a982008-03-15 08:11:03 +0000158 {
bart0008f5b2008-03-22 17:07:39 +0000159 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart36556122008-03-13 19:24:30 +0000160 {
bart3772a982008-03-15 08:11:03 +0000161 bm0_set(bm2->bm1.bm0_r, b0);
sewardjaf44c822007-11-25 14:01:38 +0000162 }
bart0008f5b2008-03-22 17:07:39 +0000163 }
164 else
165 {
166 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end - 1) & ADDR0_MASK); b0++)
bart3772a982008-03-15 08:11:03 +0000167 {
168 bm0_set(bm2->bm1.bm0_w, b0);
169 }
170 }
171 }
sewardjaf44c822007-11-25 14:01:38 +0000172}
173
bart36556122008-03-13 19:24:30 +0000174void bm_access_range_load(struct bitmap* const bm,
175 const Addr a1, const Addr a2)
176{
bart3772a982008-03-15 08:11:03 +0000177 bm_access_range(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000178}
179
barta79df6e2008-03-14 17:07:51 +0000180void bm_access_load_1(struct bitmap* const bm, const Addr a1)
181{
bartf8bc71d2008-03-15 11:42:34 +0000182 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000183}
184
185void bm_access_load_2(struct bitmap* const bm, const Addr a1)
186{
bart3772a982008-03-15 08:11:03 +0000187 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000188 bm_access_aligned_load(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000189 else
190 bm_access_range(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000191}
192
193void bm_access_load_4(struct bitmap* const bm, const Addr a1)
194{
bart3772a982008-03-15 08:11:03 +0000195 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000196 bm_access_aligned_load(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000197 else
198 bm_access_range(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000199}
200
201void bm_access_load_8(struct bitmap* const bm, const Addr a1)
202{
bart3772a982008-03-15 08:11:03 +0000203 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000204 bm_access_aligned_load(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000205 else if ((a1 & 3) == 0)
206 {
bartf8bc71d2008-03-15 11:42:34 +0000207 bm_access_aligned_load(bm, a1 + 0, 4);
208 bm_access_aligned_load(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000209 }
210 else
211 bm_access_range(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000212}
213
bartf5acbbc2008-05-10 08:22:20 +0000214void bm_access_range_store(struct bitmap* const bm,
215 const Addr a1, const Addr a2)
216{
217 bm_access_range(bm, a1, a2, eStore);
218}
219
barta79df6e2008-03-14 17:07:51 +0000220void bm_access_store_1(struct bitmap* const bm, const Addr a1)
221{
bartf8bc71d2008-03-15 11:42:34 +0000222 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000223}
224
225void bm_access_store_2(struct bitmap* const bm, const Addr a1)
226{
bart3772a982008-03-15 08:11:03 +0000227 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000228 bm_access_aligned_store(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000229 else
230 bm_access_range(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000231}
232
233void bm_access_store_4(struct bitmap* const bm, const Addr a1)
234{
bart3772a982008-03-15 08:11:03 +0000235 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000236 bm_access_aligned_store(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000237 else
238 bm_access_range(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000239}
240
241void bm_access_store_8(struct bitmap* const bm, const Addr a1)
242{
bart3772a982008-03-15 08:11:03 +0000243 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000244 bm_access_aligned_store(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000245 else if ((a1 & 3) == 0)
246 {
bartf8bc71d2008-03-15 11:42:34 +0000247 bm_access_aligned_store(bm, a1 + 0, 4);
248 bm_access_aligned_store(bm, a1 + 4, 4);
bart3772a982008-03-15 08:11:03 +0000249 }
250 else
251 bm_access_range(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000252}
253
bart7e81a172008-06-09 19:50:51 +0000254Bool bm_has(struct bitmap* const bm, const Addr a1, const Addr a2,
sewardjaf44c822007-11-25 14:01:38 +0000255 const BmAccessTypeT access_type)
256{
bart3772a982008-03-15 08:11:03 +0000257 Addr b;
258 for (b = a1; b < a2; b++)
259 {
260 if (! bm_has_1(bm, b, access_type))
261 {
262 return False;
263 }
264 }
265 return True;
sewardjaf44c822007-11-25 14:01:38 +0000266}
267
bart7e81a172008-06-09 19:50:51 +0000268Bool bm_has_any_load(struct bitmap* const bm, const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000269{
bartd4907072008-03-30 18:41:07 +0000270 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000271
bart3772a982008-03-15 08:11:03 +0000272 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000273
bartd4907072008-03-30 18:41:07 +0000274 for (b = a1; b < a2; b = b_next)
bart3772a982008-03-15 08:11:03 +0000275 {
bartd4907072008-03-30 18:41:07 +0000276 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
277
278 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
279 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000280 {
bartd4907072008-03-30 18:41:07 +0000281 b_next = a2;
282 }
283
284 if (bm2)
285 {
286 Addr b_start;
287 Addr b_end;
288 UWord b0;
289 const struct bitmap1* const p1 = &bm2->bm1;
290
291 if ((bm2->addr << ADDR0_BITS) < a1)
292 b_start = a1;
293 else
294 if ((bm2->addr << ADDR0_BITS) < a2)
295 b_start = (bm2->addr << ADDR0_BITS);
296 else
297 break;
298 tl_assert(a1 <= b_start && b_start <= a2);
299
300 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
301 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
302 else
303 b_end = a2;
304 tl_assert(a1 <= b_end && b_end <= a2);
305 tl_assert(b_start < b_end);
306 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
307
308 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
309 {
310 if (bm0_is_set(p1->bm0_r, b0))
311 {
312 return True;
313 }
314 }
bart3772a982008-03-15 08:11:03 +0000315 }
316 }
bartd4907072008-03-30 18:41:07 +0000317 return 0;
318}
319
bart7e81a172008-06-09 19:50:51 +0000320Bool bm_has_any_store(struct bitmap* const bm,
bartd4907072008-03-30 18:41:07 +0000321 const Addr a1, const Addr a2)
322{
323 Addr b, b_next;
324
325 tl_assert(bm);
326
327 for (b = a1; b < a2; b = b_next)
328 {
329 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
330
331 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
332 if (b_next > a2)
333 {
334 b_next = a2;
335 }
336
337 if (bm2)
338 {
339 Addr b_start;
340 Addr b_end;
341 UWord b0;
342 const struct bitmap1* const p1 = &bm2->bm1;
343
344 if ((bm2->addr << ADDR0_BITS) < a1)
345 b_start = a1;
346 else
347 if ((bm2->addr << ADDR0_BITS) < a2)
348 b_start = (bm2->addr << ADDR0_BITS);
349 else
350 break;
351 tl_assert(a1 <= b_start && b_start <= a2);
352
353 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
354 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
355 else
356 b_end = a2;
357 tl_assert(a1 <= b_end && b_end <= a2);
358 tl_assert(b_start < b_end);
359 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
360
361 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
362 {
363 if (bm0_is_set(p1->bm0_w, b0))
364 {
365 return True;
366 }
367 }
368 }
369 }
370 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000371}
372
bartc2c81db2008-05-10 11:19:10 +0000373/* Return True if there is a read access, write access or both */
374/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
bart7e81a172008-06-09 19:50:51 +0000375Bool bm_has_any_access(struct bitmap* const bm,
bartc2c81db2008-05-10 11:19:10 +0000376 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000377{
bart3772a982008-03-15 08:11:03 +0000378 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000379
bart3772a982008-03-15 08:11:03 +0000380 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000381
bart3772a982008-03-15 08:11:03 +0000382 for (b = a1; b < a2; b = b_next)
383 {
bartf647d342008-03-24 19:12:12 +0000384 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000385
bart3772a982008-03-15 08:11:03 +0000386 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
387 if (b_next > a2)
388 {
389 b_next = a2;
390 }
sewardjaf44c822007-11-25 14:01:38 +0000391
bart3772a982008-03-15 08:11:03 +0000392 if (bm2)
393 {
394 Addr b_start;
395 Addr b_end;
396 UWord b0;
397 const struct bitmap1* const p1 = &bm2->bm1;
sewardjaf44c822007-11-25 14:01:38 +0000398
bart3772a982008-03-15 08:11:03 +0000399 if ((bm2->addr << ADDR0_BITS) < a1)
400 b_start = a1;
401 else
402 if ((bm2->addr << ADDR0_BITS) < a2)
403 b_start = (bm2->addr << ADDR0_BITS);
404 else
405 break;
406 tl_assert(a1 <= b_start && b_start <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000407
bart3772a982008-03-15 08:11:03 +0000408 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
409 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
410 else
411 b_end = a2;
412 tl_assert(a1 <= b_end && b_end <= a2);
413 tl_assert(b_start < b_end);
414 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
sewardjaf44c822007-11-25 14:01:38 +0000415
bart3772a982008-03-15 08:11:03 +0000416 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
417 {
bartc2c81db2008-05-10 11:19:10 +0000418 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
bart3772a982008-03-15 08:11:03 +0000419 {
bartc2c81db2008-05-10 11:19:10 +0000420 return True;
bart3772a982008-03-15 08:11:03 +0000421 }
sewardjaf44c822007-11-25 14:01:38 +0000422 }
bart3772a982008-03-15 08:11:03 +0000423 }
424 }
bartc2c81db2008-05-10 11:19:10 +0000425 return False;
sewardjaf44c822007-11-25 14:01:38 +0000426}
427
bartc2c81db2008-05-10 11:19:10 +0000428/** Report whether an access of type access_type at address a is recorded in
429 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000430 */
bart7e81a172008-06-09 19:50:51 +0000431Bool bm_has_1(struct bitmap* const bm,
bartc2c81db2008-05-10 11:19:10 +0000432 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000433{
bartf647d342008-03-24 19:12:12 +0000434 const struct bitmap2* p2;
435 const struct bitmap1* p1;
436 const UWord* p0;
bart3772a982008-03-15 08:11:03 +0000437 const UWord a0 = a & ADDR0_MASK;
sewardjaf44c822007-11-25 14:01:38 +0000438
bart3772a982008-03-15 08:11:03 +0000439 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000440
bart11d0b502008-03-22 16:44:03 +0000441 p2 = bm2_lookup(bm, a >> ADDR0_BITS);
bart3772a982008-03-15 08:11:03 +0000442 if (p2)
443 {
444 p1 = &p2->bm1;
445 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
bartc2c81db2008-05-10 11:19:10 +0000446 return bm0_is_set(p0, a0) ? True : False;
bart3772a982008-03-15 08:11:03 +0000447 }
bartc2c81db2008-05-10 11:19:10 +0000448 return False;
sewardjaf44c822007-11-25 14:01:38 +0000449}
450
bart7e81a172008-06-09 19:50:51 +0000451void bm_clear(struct bitmap* const bm,
sewardjaf44c822007-11-25 14:01:38 +0000452 const Addr a1,
453 const Addr a2)
454{
bart3772a982008-03-15 08:11:03 +0000455 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000456
bart3772a982008-03-15 08:11:03 +0000457 tl_assert(bm);
458 tl_assert(a1);
459 tl_assert(a1 <= a2);
sewardjaf44c822007-11-25 14:01:38 +0000460
bart3772a982008-03-15 08:11:03 +0000461 for (b = a1; b < a2; b = b_next)
462 {
bartf647d342008-03-24 19:12:12 +0000463 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, b >> ADDR0_BITS);
sewardjaf44c822007-11-25 14:01:38 +0000464
bart3772a982008-03-15 08:11:03 +0000465 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
466 if (b_next > a2)
467 {
468 b_next = a2;
469 }
470
471 if (p2)
472 {
473 Addr c = b;
bartf647d342008-03-24 19:12:12 +0000474 /* If the first address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000475 /* start on an UWord boundary, start clearing the first addresses. */
bart3772a982008-03-15 08:11:03 +0000476 if (UWORD_LSB(c))
sewardjaf44c822007-11-25 14:01:38 +0000477 {
bart3772a982008-03-15 08:11:03 +0000478 Addr c_next = UWORD_MSB(c) + BITS_PER_UWORD;
479 if (c_next > b_next)
480 c_next = b_next;
bart5955f332008-03-25 17:19:20 +0000481 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, c_next - c);
482 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, c_next - c);
bart3772a982008-03-15 08:11:03 +0000483 c = c_next;
sewardjaf44c822007-11-25 14:01:38 +0000484 }
bartf647d342008-03-24 19:12:12 +0000485 /* If some UWords have to be cleared entirely, do this now. */
bart3772a982008-03-15 08:11:03 +0000486 if (UWORD_LSB(c) == 0)
sewardjaf44c822007-11-25 14:01:38 +0000487 {
bart3772a982008-03-15 08:11:03 +0000488 const Addr c_next = UWORD_MSB(b_next);
489 tl_assert(UWORD_LSB(c) == 0);
490 tl_assert(UWORD_LSB(c_next) == 0);
491 tl_assert(c_next <= b_next);
492 tl_assert(c <= c_next);
493 if (c_next > c)
494 {
495 UWord idx = (c & ADDR0_MASK) >> BITS_PER_BITS_PER_UWORD;
496 VG_(memset)(&p2->bm1.bm0_r[idx], 0, (c_next - c) / 8);
497 VG_(memset)(&p2->bm1.bm0_w[idx], 0, (c_next - c) / 8);
498 c = c_next;
499 }
sewardjaf44c822007-11-25 14:01:38 +0000500 }
bartf647d342008-03-24 19:12:12 +0000501 /* If the last address in the bitmap that must be cleared does not */
bart5955f332008-03-25 17:19:20 +0000502 /* fall on an UWord boundary, clear the last addresses. */
503 /* tl_assert(c <= b_next); */
504 bm0_clear_range(p2->bm1.bm0_r, c & ADDR0_MASK, b_next - c);
505 bm0_clear_range(p2->bm1.bm0_w, c & ADDR0_MASK, b_next - c);
bart3772a982008-03-15 08:11:03 +0000506 }
507 }
sewardjaf44c822007-11-25 14:01:38 +0000508}
sewardjaf44c822007-11-25 14:01:38 +0000509
bart9c4224c2008-03-29 14:40:08 +0000510/** Clear all references to loads in bitmap bm starting at address a1 and
511 * up to but not including address a2.
512 */
bart7e81a172008-06-09 19:50:51 +0000513void bm_clear_load(struct bitmap* const bm,
bart9c4224c2008-03-29 14:40:08 +0000514 const Addr a1, const Addr a2)
515{
516 Addr a;
517
518 for (a = a1; a < a2; a++)
519 {
520 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
521 if (p2)
522 {
523 bm0_clear(p2->bm1.bm0_r, a & ADDR0_MASK);
524 }
525 }
526}
527
528/** Clear all references to stores in bitmap bm starting at address a1 and
529 * up to but not including address a2.
530 */
bart7e81a172008-06-09 19:50:51 +0000531void bm_clear_store(struct bitmap* const bm,
bart9c4224c2008-03-29 14:40:08 +0000532 const Addr a1, const Addr a2)
533{
534 Addr a;
535
536 for (a = a1; a < a2; a++)
537 {
538 struct bitmap2* const p2 = bm2_lookup_exclusive(bm, a >> ADDR0_BITS);
539 if (p2)
540 {
541 bm0_clear(p2->bm1.bm0_w, a & ADDR0_MASK);
542 }
543 }
544}
545
bart8bf2f8b2008-03-30 17:56:43 +0000546/** Clear bitmap bm starting at address a1 and up to but not including address
547 * a2. Return True if and only if any of the addresses was set before
548 * clearing.
549 */
bart7e81a172008-06-09 19:50:51 +0000550Bool bm_test_and_clear(struct bitmap* const bm,
bart8bf2f8b2008-03-30 17:56:43 +0000551 const Addr a1, const Addr a2)
552{
553 Bool result;
554
555 result = bm_has_any_access(bm, a1, a2) != 0;
556 bm_clear(bm, a1, a2);
557 return result;
558}
559
bart7e81a172008-06-09 19:50:51 +0000560Bool bm_has_conflict_with(struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000561 const Addr a1, const Addr a2,
562 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000563{
bart3772a982008-03-15 08:11:03 +0000564 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000565
bart3772a982008-03-15 08:11:03 +0000566 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000567
bart3772a982008-03-15 08:11:03 +0000568 for (b = a1; b < a2; b = b_next)
569 {
bartf647d342008-03-24 19:12:12 +0000570 const struct bitmap2* bm2 = bm2_lookup(bm, b >> ADDR0_BITS);
bart36556122008-03-13 19:24:30 +0000571
bart3772a982008-03-15 08:11:03 +0000572 b_next = (b & ~ADDR0_MASK) + ADDR0_COUNT;
573 if (b_next > a2)
574 {
575 b_next = a2;
576 }
bart36556122008-03-13 19:24:30 +0000577
bart3772a982008-03-15 08:11:03 +0000578 if (bm2)
579 {
580 Addr b_start;
581 Addr b_end;
582 UWord b0;
583 const struct bitmap1* const p1 = &bm2->bm1;
bart36556122008-03-13 19:24:30 +0000584
bart3772a982008-03-15 08:11:03 +0000585 if ((bm2->addr << ADDR0_BITS) < a1)
586 b_start = a1;
587 else
588 if ((bm2->addr << ADDR0_BITS) < a2)
589 b_start = (bm2->addr << ADDR0_BITS);
590 else
591 break;
592 tl_assert(a1 <= b_start && b_start <= a2);
bart36556122008-03-13 19:24:30 +0000593
bart3772a982008-03-15 08:11:03 +0000594 if ((bm2->addr << ADDR0_BITS) + ADDR0_COUNT < a2)
595 b_end = (bm2->addr << ADDR0_BITS) + ADDR0_COUNT;
596 else
597 b_end = a2;
598 tl_assert(a1 <= b_end && b_end <= a2);
599 tl_assert(b_start < b_end);
600 tl_assert((b_start & ADDR0_MASK) <= ((b_end - 1) & ADDR0_MASK));
bart36556122008-03-13 19:24:30 +0000601
bart3772a982008-03-15 08:11:03 +0000602 for (b0 = b_start & ADDR0_MASK; b0 <= ((b_end-1) & ADDR0_MASK); b0++)
603 {
604 if (access_type == eLoad)
605 {
606 if (bm0_is_set(p1->bm0_w, b0))
607 {
608 return True;
609 }
610 }
611 else
612 {
613 tl_assert(access_type == eStore);
614 if (bm0_is_set(p1->bm0_r, b0)
615 | bm0_is_set(p1->bm0_w, b0))
616 {
617 return True;
618 }
619 }
sewardjaf44c822007-11-25 14:01:38 +0000620 }
bart3772a982008-03-15 08:11:03 +0000621 }
622 }
623 return False;
sewardjaf44c822007-11-25 14:01:38 +0000624}
625
bart7e81a172008-06-09 19:50:51 +0000626Bool bm_load_has_conflict_with(struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000627 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000628{
bart3772a982008-03-15 08:11:03 +0000629 return bm_has_conflict_with(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000630}
631
bart7e81a172008-06-09 19:50:51 +0000632Bool bm_load_1_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000633{
bartf8bc71d2008-03-15 11:42:34 +0000634 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000635}
636
bart7e81a172008-06-09 19:50:51 +0000637Bool bm_load_2_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000638{
bart3772a982008-03-15 08:11:03 +0000639 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000640 return bm_aligned_load_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000641 else
642 return bm_has_conflict_with(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000643}
644
bart7e81a172008-06-09 19:50:51 +0000645Bool bm_load_4_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000646{
bart3772a982008-03-15 08:11:03 +0000647 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000648 return bm_aligned_load_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000649 else
650 return bm_has_conflict_with(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000651}
652
bart7e81a172008-06-09 19:50:51 +0000653Bool bm_load_8_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000654{
bart3772a982008-03-15 08:11:03 +0000655 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000656 return bm_aligned_load_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000657 else
658 return bm_has_conflict_with(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000659}
660
bart7e81a172008-06-09 19:50:51 +0000661Bool bm_store_1_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000662{
bartf8bc71d2008-03-15 11:42:34 +0000663 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000664}
665
bart7e81a172008-06-09 19:50:51 +0000666Bool bm_store_2_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000667{
bart3772a982008-03-15 08:11:03 +0000668 if ((a1 & 1) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000669 return bm_aligned_store_has_conflict_with(bm, a1, 2);
bart3772a982008-03-15 08:11:03 +0000670 else
671 return bm_has_conflict_with(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000672}
673
bart7e81a172008-06-09 19:50:51 +0000674Bool bm_store_4_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000675{
bart3772a982008-03-15 08:11:03 +0000676 if ((a1 & 3) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000677 return bm_aligned_store_has_conflict_with(bm, a1, 4);
bart3772a982008-03-15 08:11:03 +0000678 else
679 return bm_has_conflict_with(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000680}
681
bart7e81a172008-06-09 19:50:51 +0000682Bool bm_store_8_has_conflict_with(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000683{
bart3772a982008-03-15 08:11:03 +0000684 if ((a1 & 7) == 0)
bartf8bc71d2008-03-15 11:42:34 +0000685 return bm_aligned_store_has_conflict_with(bm, a1, 8);
bart3772a982008-03-15 08:11:03 +0000686 else
687 return bm_has_conflict_with(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000688}
689
bart7e81a172008-06-09 19:50:51 +0000690Bool bm_store_has_conflict_with(struct bitmap* const bm,
bart36556122008-03-13 19:24:30 +0000691 const Addr a1, const Addr a2)
692{
bart3772a982008-03-15 08:11:03 +0000693 return bm_has_conflict_with(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000694}
695
bartc2c81db2008-05-10 11:19:10 +0000696/** Return True if the two bitmaps *lhs and *rhs are identical, and false
bart7cd7d7f2008-04-14 16:10:01 +0000697 * if not.
698 */
bart7e81a172008-06-09 19:50:51 +0000699Bool bm_equal(struct bitmap* const lhs, struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000700{
701 struct bitmap2* bm2l;
702 struct bitmap2ref* bm2l_ref;
703 struct bitmap2* bm2r;
704 const struct bitmap2ref* bm2r_ref;
705
barta3f61092008-05-04 07:46:20 +0000706 /* It's not possible to have two independent iterators over the same OSet, */
707 /* so complain if lhs == rhs. */
708 tl_assert(lhs != rhs);
709
bart7cd7d7f2008-04-14 16:10:01 +0000710 VG_(OSetGen_ResetIter)(lhs->oset);
711 VG_(OSetGen_ResetIter)(rhs->oset);
712
713 for ( ; (bm2l_ref = VG_(OSetGen_Next)(lhs->oset)) != 0; )
714 {
bartf5acbbc2008-05-10 08:22:20 +0000715 while (bm2l_ref
716 && (bm2l = bm2l_ref->bm2)
717 && bm2l
718 && ! bm_has_any_access(lhs,
719 bm2l->addr << ADDR0_BITS,
720 (bm2l->addr + 1) << ADDR0_BITS))
721 {
722 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
723 }
724 if (bm2l_ref == 0)
725 break;
bart7cd7d7f2008-04-14 16:10:01 +0000726 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000727#if 0
728 VG_(message)(Vg_DebugMsg, "bm_equal: at 0x%lx", bm2l->addr << ADDR0_BITS);
729#endif
730
bart7cd7d7f2008-04-14 16:10:01 +0000731 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
732 if (bm2r_ref == 0)
barta3f61092008-05-04 07:46:20 +0000733 {
734#if 0
735 VG_(message)(Vg_DebugMsg, "bm_equal: no match found");
736#endif
bart7cd7d7f2008-04-14 16:10:01 +0000737 return False;
barta3f61092008-05-04 07:46:20 +0000738 }
bart7cd7d7f2008-04-14 16:10:01 +0000739 bm2r = bm2r_ref->bm2;
740 tl_assert(bm2r);
741 tl_assert(bm_has_any_access(rhs,
742 bm2r->addr << ADDR0_BITS,
743 (bm2r->addr + 1) << ADDR0_BITS));
barta3f61092008-05-04 07:46:20 +0000744
745 if (bm2l != bm2r
746 && (bm2l->addr != bm2r->addr
747 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
bart7cd7d7f2008-04-14 16:10:01 +0000748 {
barta3f61092008-05-04 07:46:20 +0000749#if 0
750 VG_(message)(Vg_DebugMsg, "bm_equal: rhs 0x%lx -- returning false",
751 bm2r->addr << ADDR0_BITS);
752#endif
bart7cd7d7f2008-04-14 16:10:01 +0000753 return False;
754 }
barta3f61092008-05-04 07:46:20 +0000755 }
756 bm2r = VG_(OSetGen_Next)(rhs->oset);
757 if (bm2r)
758 {
759 tl_assert(bm_has_any_access(rhs,
760 bm2r->addr << ADDR0_BITS,
761 (bm2r->addr + 1) << ADDR0_BITS));
762#if 0
763 VG_(message)(Vg_DebugMsg,
764 "bm_equal: remaining rhs 0x%lx -- returning false",
765 bm2r->addr << ADDR0_BITS);
766#endif
767 return False;
bart7cd7d7f2008-04-14 16:10:01 +0000768 }
769 return True;
770}
771
sewardjaf44c822007-11-25 14:01:38 +0000772void bm_swap(struct bitmap* const bm1, struct bitmap* const bm2)
773{
bart3772a982008-03-15 08:11:03 +0000774 OSet* const tmp = bm1->oset;
775 bm1->oset = bm2->oset;
776 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000777}
778
bartf647d342008-03-24 19:12:12 +0000779/** Merge bitmaps *lhs and *rhs into *lhs. */
sewardjaf44c822007-11-25 14:01:38 +0000780void bm_merge2(struct bitmap* const lhs,
bart7e81a172008-06-09 19:50:51 +0000781 struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +0000782{
bart3772a982008-03-15 08:11:03 +0000783 struct bitmap2* bm2l;
bartf647d342008-03-24 19:12:12 +0000784 struct bitmap2ref* bm2l_ref;
785 struct bitmap2* bm2r;
786 const struct bitmap2ref* bm2r_ref;
sewardjaf44c822007-11-25 14:01:38 +0000787
bart3772a982008-03-15 08:11:03 +0000788 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000789
bartf647d342008-03-24 19:12:12 +0000790 for ( ; (bm2r_ref = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000791 {
bartf647d342008-03-24 19:12:12 +0000792 bm2r = bm2r_ref->bm2;
793 bm2l_ref = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
794 if (bm2l_ref)
bart3772a982008-03-15 08:11:03 +0000795 {
bartf647d342008-03-24 19:12:12 +0000796 bm2l = bm2l_ref->bm2;
797 if (bm2l != bm2r)
798 {
799 if (bm2l->refcnt > 1)
800 bm2l = bm2_make_exclusive(lhs, bm2l_ref);
801 bm2_merge(bm2l, bm2r);
802 }
803 }
804 else
805 {
806 bm2_insert_addref(lhs, bm2r);
807 }
bart3772a982008-03-15 08:11:03 +0000808 }
sewardjaf44c822007-11-25 14:01:38 +0000809}
810
811/**
812 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
813 * @param lhs First bitmap.
814 * @param rhs Bitmap to be compared with lhs.
815 * @return !=0 if there are data races, == 0 if there are none.
816 */
bart7e81a172008-06-09 19:50:51 +0000817int bm_has_races(struct bitmap* const lhs,
818 struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +0000819{
bart3772a982008-03-15 08:11:03 +0000820 VG_(OSetGen_ResetIter)(lhs->oset);
821 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000822
bart3772a982008-03-15 08:11:03 +0000823 for (;;)
824 {
bartf647d342008-03-24 19:12:12 +0000825 const struct bitmap2ref* bm2l_ref;
826 const struct bitmap2ref* bm2r_ref;
827 const struct bitmap2* bm2l;
828 const struct bitmap2* bm2r;
bart3772a982008-03-15 08:11:03 +0000829 const struct bitmap1* bm1l;
830 const struct bitmap1* bm1r;
831 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000832
bartf647d342008-03-24 19:12:12 +0000833 bm2l_ref = VG_(OSetGen_Next)(lhs->oset);
834 bm2l = bm2l_ref->bm2;
835 bm2r_ref = VG_(OSetGen_Next)(rhs->oset);
836 bm2r = bm2r_ref->bm2;
bart3772a982008-03-15 08:11:03 +0000837 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
838 {
839 if (bm2l->addr < bm2r->addr)
bartf647d342008-03-24 19:12:12 +0000840 bm2l = (bm2l_ref = VG_(OSetGen_Next)(lhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000841 else
bartf647d342008-03-24 19:12:12 +0000842 bm2r = (bm2r_ref = VG_(OSetGen_Next)(rhs->oset))->bm2;
bart3772a982008-03-15 08:11:03 +0000843 }
844 if (bm2l == 0 || bm2r == 0)
845 break;
846
847 bm1l = &bm2l->bm1;
848 bm1r = &bm2r->bm1;
849
850 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
851 {
852 unsigned b;
853 for (b = 0; b < BITS_PER_UWORD; b++)
sewardjaf44c822007-11-25 14:01:38 +0000854 {
barta3f61092008-05-04 07:46:20 +0000855 UWord const access_mask
bart3772a982008-03-15 08:11:03 +0000856 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
857 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
858 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
859 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
860 Addr const a = MAKE_ADDRESS(bm2l->addr, k * BITS_PER_UWORD | b);
barta3f61092008-05-04 07:46:20 +0000861 if (HAS_RACE(access_mask) && ! drd_is_suppressed(a, a + 1))
bart3772a982008-03-15 08:11:03 +0000862 {
863 return 1;
864 }
sewardjaf44c822007-11-25 14:01:38 +0000865 }
bart3772a982008-03-15 08:11:03 +0000866 }
867 }
868 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000869}
870
bart7e81a172008-06-09 19:50:51 +0000871void bm_print(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +0000872{
bart3772a982008-03-15 08:11:03 +0000873 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000874 struct bitmap2ref* bm2ref;
sewardjaf44c822007-11-25 14:01:38 +0000875
bart3772a982008-03-15 08:11:03 +0000876 VG_(OSetGen_ResetIter)(bm->oset);
sewardjaf44c822007-11-25 14:01:38 +0000877
bartf647d342008-03-24 19:12:12 +0000878 for ( ; (bm2ref = VG_(OSetGen_Next)(bm->oset)) != 0; )
bart3772a982008-03-15 08:11:03 +0000879 {
bartf647d342008-03-24 19:12:12 +0000880 const struct bitmap1* bm1;
bart0008f5b2008-03-22 17:07:39 +0000881 unsigned b;
bartf647d342008-03-24 19:12:12 +0000882
883 bm2 = bm2ref->bm2;
884 bm1 = &bm2->bm1;
bart0008f5b2008-03-22 17:07:39 +0000885 for (b = 0; b < ADDR0_COUNT; b++)
bart3772a982008-03-15 08:11:03 +0000886 {
bart0008f5b2008-03-22 17:07:39 +0000887 const Addr a = (bm2->addr << ADDR0_BITS) | b;
888 const Bool r = bm0_is_set(bm1->bm0_r, b) != 0;
889 const Bool w = bm0_is_set(bm1->bm0_w, b) != 0;
890 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +0000891 {
bart0008f5b2008-03-22 17:07:39 +0000892 VG_(printf)("0x%08lx %c %c\n",
893 a,
894 w ? 'W' : ' ',
895 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +0000896 }
bart3772a982008-03-15 08:11:03 +0000897 }
898 }
sewardjaf44c822007-11-25 14:01:38 +0000899}
900
901ULong bm_get_bitmap_creation_count(void)
902{
bart3772a982008-03-15 08:11:03 +0000903 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000904}
905
bart588d90f2008-04-06 13:05:58 +0000906ULong bm_get_bitmap2_node_creation_count(void)
907{
bart3c9989f2008-06-11 19:17:01 +0000908 return s_bitmap2_node_creation_count;
bart588d90f2008-04-06 13:05:58 +0000909}
910
sewardjaf44c822007-11-25 14:01:38 +0000911ULong bm_get_bitmap2_creation_count(void)
912{
bart3772a982008-03-15 08:11:03 +0000913 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +0000914}
915
bartf647d342008-03-24 19:12:12 +0000916/** Allocate and initialize a second level bitmap. */
917static struct bitmap2* bm2_new(const UWord a1)
918{
919 struct bitmap2* bm2;
920
sewardj9c606bd2008-09-18 18:12:50 +0000921 bm2 = VG_(malloc)("drd.bitmap.bm2n.1", sizeof(*bm2));
bartf647d342008-03-24 19:12:12 +0000922 bm2->addr = a1;
923 bm2->refcnt = 1;
924
925 s_bitmap2_creation_count++;
926
927 return bm2;
928}
929
930/** Make a copy of a shared second level bitmap such that the copy can be
931 * modified.
932 *
933 * @param a1 client address shifted right by ADDR0_BITS.
934 * @param bm bitmap pointer.
935 */
936static
937struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
938 struct bitmap2ref* const bm2ref)
939{
940 UWord a1;
941 struct bitmap2* bm2;
942 struct bitmap2* bm2_copy;
943
944 tl_assert(bm);
945 tl_assert(bm2ref);
946 bm2 = bm2ref->bm2;
947 tl_assert(bm2);
948 tl_assert(bm2->refcnt > 1);
949 bm2->refcnt--;
950 tl_assert(bm2->refcnt >= 1);
951 a1 = bm2->addr;
952 bm2_copy = bm2_new(a1);
953 tl_assert(bm2_copy);
954 tl_assert(bm2_copy->addr == a1);
955 tl_assert(bm2_copy->refcnt == 1);
956 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1));
957 bm2ref->bm2 = bm2_copy;
958
959 bm_update_cache(bm, a1, bm2_copy);
960
961 return bm2_copy;
962}
963
sewardjaf44c822007-11-25 14:01:38 +0000964static void bm2_merge(struct bitmap2* const bm2l,
965 const struct bitmap2* const bm2r)
966{
bart3772a982008-03-15 08:11:03 +0000967 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +0000968
bart33e56c92008-03-24 06:41:30 +0000969 tl_assert(bm2l);
970 tl_assert(bm2r);
bart3772a982008-03-15 08:11:03 +0000971 tl_assert(bm2l->addr == bm2r->addr);
bartf647d342008-03-24 19:12:12 +0000972 tl_assert(bm2l->refcnt == 1);
sewardjaf44c822007-11-25 14:01:38 +0000973
bart3772a982008-03-15 08:11:03 +0000974 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
975 {
976 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
977 }
978 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
979 {
980 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
981 }
sewardjaf44c822007-11-25 14:01:38 +0000982}