blob: 396d72f81e2c8e53bf27cd7f0e9ae6dd6d240cbb [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
bart33e56c92008-03-24 06:41:30 +000026#ifndef __DRD_BITMAP_H
27#define __DRD_BITMAP_H
sewardjaf44c822007-11-25 14:01:38 +000028
29
30#include "pub_tool_oset.h"
bartd59bb0f2008-06-08 08:08:31 +000031#include "pub_tool_libcbase.h"
sewardjaf44c822007-11-25 14:01:38 +000032
33
34/*
35 Bitmap representation. A bitmap is a data structure in which two bits are
36 reserved per 32 bit address: one bit that indicates that the data at the
37 specified address has been read, and one bit that indicates that the data has
38 been written to.
39*/
40
41
42/* Macro definitions. */
43
bart8b4b2ee2008-06-11 13:17:56 +000044#define ADDR0_BITS 14
sewardjaf44c822007-11-25 14:01:38 +000045
barta79df6e2008-03-14 17:07:51 +000046#define ADDR0_COUNT ((UWord)1 << ADDR0_BITS)
sewardjaf44c822007-11-25 14:01:38 +000047
48#define ADDR0_MASK (ADDR0_COUNT - 1)
49
bart0268dfa2008-03-11 20:10:21 +000050#define SPLIT_ADDRESS(a) \
51 UWord a##0 = ((a) & ADDR0_MASK); \
sewardjaf44c822007-11-25 14:01:38 +000052 UWord a##1 = ((a) >> ADDR0_BITS);
53
54// Assumption: sizeof(Addr) == sizeof(UWord).
bart0268dfa2008-03-11 20:10:21 +000055#define MAKE_ADDRESS(a1, a0) \
sewardjaf44c822007-11-25 14:01:38 +000056 (Addr)(((UWord)(a1) << (ADDR0_BITS)) | ((UWord)(a0)))
57
58#define BITS_PER_UWORD (8UL*sizeof(UWord))
59#if defined(VGA_x86) || defined(VGA_ppc32)
60#define BITS_PER_BITS_PER_UWORD 5
61#elif defined(VGA_amd64) || defined(VGA_ppc64)
62#define BITS_PER_BITS_PER_UWORD 6
63#else
64#error Unknown platform.
65#endif
66
67#define BITMAP1_UWORD_COUNT (ADDR0_COUNT >> BITS_PER_BITS_PER_UWORD)
68
69/* Highest bits of an address that fit into the same UWord of bm0[]. */
70#define UWORD_MSB(a) ((a) & ~(BITS_PER_UWORD - 1))
71
72/* Lowest bits of an address that fit into the same UWord of bm0[]. */
73#define UWORD_LSB(a) ((a) & (BITS_PER_UWORD - 1))
74
75/* Highest address that fits in the same UWord as a. */
76#define UWORD_HIGHEST_ADDRESS(a) ((a) | (BITS_PER_UWORD - 1))
77
78
bart33e56c92008-03-24 06:41:30 +000079/* Local variables. */
sewardjaf44c822007-11-25 14:01:38 +000080
81static ULong s_bitmap2_creation_count;
bart3c9989f2008-06-11 19:17:01 +000082static ULong s_bitmap2_node_creation_count;
sewardjaf44c822007-11-25 14:01:38 +000083
84
bart0008f5b2008-03-22 17:07:39 +000085
86/*********************************************************************/
87/* Functions for manipulating a struct bitmap1. */
88/*********************************************************************/
89
90
sewardjaf44c822007-11-25 14:01:38 +000091/* Lowest level, corresponding to the lowest ADDR0_BITS of an address. */
92struct bitmap1
93{
94 UWord bm0_r[BITMAP1_UWORD_COUNT];
95 UWord bm0_w[BITMAP1_UWORD_COUNT];
96};
97
98static __inline__ UWord bm0_mask(const Addr a)
99{
barta79df6e2008-03-14 17:07:51 +0000100 return ((UWord)1 << UWORD_LSB(a));
sewardjaf44c822007-11-25 14:01:38 +0000101}
102
103static __inline__ void bm0_set(UWord* bm0, const Addr a)
104{
bart3c9989f2008-06-11 19:17:01 +0000105#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
106 tl_assert(a < ADDR0_COUNT);
107#endif
barta79df6e2008-03-14 17:07:51 +0000108 bm0[a >> BITS_PER_BITS_PER_UWORD] |= (UWord)1 << UWORD_LSB(a);
109}
110
bartf8bc71d2008-03-15 11:42:34 +0000111/** Set all of the addresses in range [ a1 .. a1 + size [ in bitmap bm0. */
112static __inline__ void bm0_set_range(UWord* bm0,
113 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000114{
bart8b4b2ee2008-06-11 13:17:56 +0000115#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
barta79df6e2008-03-14 17:07:51 +0000116 tl_assert(a1 < ADDR0_COUNT);
bartf8bc71d2008-03-15 11:42:34 +0000117 tl_assert(size > 0);
118 tl_assert(a1 + size <= ADDR0_COUNT);
119 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a1 + size - 1));
barta79df6e2008-03-14 17:07:51 +0000120#endif
121 bm0[a1 >> BITS_PER_BITS_PER_UWORD]
bartf8bc71d2008-03-15 11:42:34 +0000122 |= (((UWord)1 << size) - 1) << UWORD_LSB(a1);
sewardjaf44c822007-11-25 14:01:38 +0000123}
124
125static __inline__ void bm0_clear(UWord* bm0, const Addr a)
126{
bart3c9989f2008-06-11 19:17:01 +0000127#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
128 tl_assert(a < ADDR0_COUNT);
129#endif
barta79df6e2008-03-14 17:07:51 +0000130 bm0[a >> BITS_PER_BITS_PER_UWORD] &= ~((UWord)1 << UWORD_LSB(a));
sewardjaf44c822007-11-25 14:01:38 +0000131}
132
bart5955f332008-03-25 17:19:20 +0000133/** Clear all of the addresses in range [ a1 .. a1 + size [ in bitmap bm0. */
134static __inline__ void bm0_clear_range(UWord* bm0,
135 const Addr a1, const SizeT size)
136{
bart8b4b2ee2008-06-11 13:17:56 +0000137#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart5955f332008-03-25 17:19:20 +0000138 tl_assert(a1 < ADDR0_COUNT);
139 tl_assert(size > 0);
140 tl_assert(a1 + size <= ADDR0_COUNT);
141 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a1 + size - 1));
142#endif
143 bm0[a1 >> BITS_PER_BITS_PER_UWORD]
144 &= ~(((UWord)1 << size) - 1) << UWORD_LSB(a1);
145}
146
sewardjaf44c822007-11-25 14:01:38 +0000147static __inline__ UWord bm0_is_set(const UWord* bm0, const Addr a)
148{
bart3c9989f2008-06-11 19:17:01 +0000149#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
150 tl_assert(a < ADDR0_COUNT);
151#endif
barta79df6e2008-03-14 17:07:51 +0000152 return (bm0[a >> BITS_PER_BITS_PER_UWORD] & ((UWord)1 << UWORD_LSB(a)));
sewardjaf44c822007-11-25 14:01:38 +0000153}
154
bartf8bc71d2008-03-15 11:42:34 +0000155/** Return true if any of the bits [ a1 .. a1+size [ are set in bm0. */
barta79df6e2008-03-14 17:07:51 +0000156static __inline__ UWord bm0_is_any_set(const UWord* bm0,
bartf8bc71d2008-03-15 11:42:34 +0000157 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000158{
bart8b4b2ee2008-06-11 13:17:56 +0000159#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
barta79df6e2008-03-14 17:07:51 +0000160 tl_assert(a1 < ADDR0_COUNT);
bartf8bc71d2008-03-15 11:42:34 +0000161 tl_assert(size > 0);
162 tl_assert(a1 + size <= ADDR0_COUNT);
163 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a1 + size - 1));
barta79df6e2008-03-14 17:07:51 +0000164#endif
165 return (bm0[a1 >> BITS_PER_BITS_PER_UWORD]
bartf8bc71d2008-03-15 11:42:34 +0000166 & ((((UWord)1 << size) - 1) << UWORD_LSB(a1)));
barta79df6e2008-03-14 17:07:51 +0000167}
sewardjaf44c822007-11-25 14:01:38 +0000168
bartadbdf142008-03-19 17:00:12 +0000169
bart0008f5b2008-03-22 17:07:39 +0000170
171/*********************************************************************/
172/* Functions for manipulating a struct bitmap. */
bartadbdf142008-03-19 17:00:12 +0000173/*********************************************************************/
174
175
bart33e56c92008-03-24 06:41:30 +0000176/* Second level bitmap. */
sewardjaf44c822007-11-25 14:01:38 +0000177struct bitmap2
178{
bart33e56c92008-03-24 06:41:30 +0000179 Addr addr; ///< address >> ADDR0_BITS
bartf647d342008-03-24 19:12:12 +0000180 int refcnt;
sewardjaf44c822007-11-25 14:01:38 +0000181 struct bitmap1 bm1;
182};
183
bartf647d342008-03-24 19:12:12 +0000184/* One node of bitmap::oset. */
185struct bitmap2ref
186{
187 Addr addr; ///< address >> ADDR0_BITS
188 struct bitmap2* bm2;
189};
190
bart33e56c92008-03-24 06:41:30 +0000191struct bm_cache_elem
192{
193 Addr a1;
194 struct bitmap2* bm2;
195};
196
197#define N_CACHE_ELEM 4
198
sewardjaf44c822007-11-25 14:01:38 +0000199/* Complete bitmap. */
200struct bitmap
201{
bart33e56c92008-03-24 06:41:30 +0000202 struct bm_cache_elem cache[N_CACHE_ELEM];
203 OSet* oset;
sewardjaf44c822007-11-25 14:01:38 +0000204};
205
bart33e56c92008-03-24 06:41:30 +0000206
bartf647d342008-03-24 19:12:12 +0000207static struct bitmap2* bm2_new(const UWord a1);
208static struct bitmap2* bm2_make_exclusive(struct bitmap* const bm,
209 struct bitmap2ref* const bm2ref);
210
bart7e81a172008-06-09 19:50:51 +0000211/** Rotate elements cache[0..n-1] such that the element at position n-1 is
212 * moved to position 0. This allows to speed up future cache lookups.
213 */
214static __inline__
215void bm_cache_rotate(struct bm_cache_elem cache[], const int n)
216{
bart45af5ea2008-06-12 06:04:59 +0000217#if 0
bart7e81a172008-06-09 19:50:51 +0000218 struct bm_cache_elem t;
219
bartea2fa4c2008-06-10 06:32:49 +0000220 tl_assert(2 <= n && n <= 8);
bartea2fa4c2008-06-10 06:32:49 +0000221
bart7e81a172008-06-09 19:50:51 +0000222 t = cache[0];
223 if (n > 1)
224 cache[0] = cache[1];
225 if (n > 2)
226 cache[1] = cache[2];
227 if (n > 3)
228 cache[2] = cache[3];
229 if (n > 4)
230 cache[3] = cache[4];
231 if (n > 5)
232 cache[4] = cache[5];
233 if (n > 6)
234 cache[5] = cache[6];
235 if (n > 7)
236 cache[6] = cache[7];
237 cache[n - 1] = t;
bartea2fa4c2008-06-10 06:32:49 +0000238#endif
bart7e81a172008-06-09 19:50:51 +0000239}
bartf647d342008-03-24 19:12:12 +0000240
bartf647d342008-03-24 19:12:12 +0000241static __inline__
bart7e81a172008-06-09 19:50:51 +0000242Bool bm_cache_lookup(struct bitmap* const bm, const UWord a1,
bartf29205e2008-03-25 18:51:06 +0000243 struct bitmap2** bm2)
bart33e56c92008-03-24 06:41:30 +0000244{
bart8b4b2ee2008-06-11 13:17:56 +0000245#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart33e56c92008-03-24 06:41:30 +0000246 tl_assert(bm);
bartf29205e2008-03-25 18:51:06 +0000247 tl_assert(bm2);
bart7e81a172008-06-09 19:50:51 +0000248#endif
bart33e56c92008-03-24 06:41:30 +0000249
250#if N_CACHE_ELEM > 8
251#error Please update the code below.
252#endif
253#if N_CACHE_ELEM >= 1
254 if (a1 == bm->cache[0].a1)
bartf29205e2008-03-25 18:51:06 +0000255 {
256 *bm2 = bm->cache[0].bm2;
257 return True;
258 }
bart33e56c92008-03-24 06:41:30 +0000259#endif
260#if N_CACHE_ELEM >= 2
261 if (a1 == bm->cache[1].a1)
bartf29205e2008-03-25 18:51:06 +0000262 {
263 *bm2 = bm->cache[1].bm2;
264 return True;
265 }
bart33e56c92008-03-24 06:41:30 +0000266#endif
267#if N_CACHE_ELEM >= 3
268 if (a1 == bm->cache[2].a1)
bartf29205e2008-03-25 18:51:06 +0000269 {
270 *bm2 = bm->cache[2].bm2;
bart7e81a172008-06-09 19:50:51 +0000271 bm_cache_rotate(bm->cache, 3);
bartf29205e2008-03-25 18:51:06 +0000272 return True;
273 }
bart33e56c92008-03-24 06:41:30 +0000274#endif
275#if N_CACHE_ELEM >= 4
276 if (a1 == bm->cache[3].a1)
bartf29205e2008-03-25 18:51:06 +0000277 {
278 *bm2 = bm->cache[3].bm2;
bart7e81a172008-06-09 19:50:51 +0000279 bm_cache_rotate(bm->cache, 4);
bartf29205e2008-03-25 18:51:06 +0000280 return True;
281 }
bart33e56c92008-03-24 06:41:30 +0000282#endif
283#if N_CACHE_ELEM >= 5
284 if (a1 == bm->cache[4].a1)
bartf29205e2008-03-25 18:51:06 +0000285 {
286 *bm2 = bm->cache[4].bm2;
bart7e81a172008-06-09 19:50:51 +0000287 bm_cache_rotate(bm->cache, 5);
bartf29205e2008-03-25 18:51:06 +0000288 return True;
289 }
bart33e56c92008-03-24 06:41:30 +0000290#endif
291#if N_CACHE_ELEM >= 6
292 if (a1 == bm->cache[5].a1)
bartf29205e2008-03-25 18:51:06 +0000293 {
294 *bm2 = bm->cache[5].bm2;
bart7e81a172008-06-09 19:50:51 +0000295 bm_cache_rotate(bm->cache, 6);
bartf29205e2008-03-25 18:51:06 +0000296 return True;
297 }
bart33e56c92008-03-24 06:41:30 +0000298#endif
299#if N_CACHE_ELEM >= 7
300 if (a1 == bm->cache[6].a1)
bartf29205e2008-03-25 18:51:06 +0000301 {
302 *bm2 = bm->cache[6].bm2;
bart7e81a172008-06-09 19:50:51 +0000303 bm_cache_rotate(bm->cache, 7);
bartf29205e2008-03-25 18:51:06 +0000304 return True;
305 }
bart33e56c92008-03-24 06:41:30 +0000306#endif
307#if N_CACHE_ELEM >= 8
308 if (a1 == bm->cache[7].a1)
bartf29205e2008-03-25 18:51:06 +0000309 {
310 *bm2 = bm->cache[7].bm2;
bart7e81a172008-06-09 19:50:51 +0000311 bm_cache_rotate(bm->cache, 8);
bartf29205e2008-03-25 18:51:06 +0000312 return True;
313 }
bart33e56c92008-03-24 06:41:30 +0000314#endif
bartf29205e2008-03-25 18:51:06 +0000315 *bm2 = 0;
316 return False;
bart33e56c92008-03-24 06:41:30 +0000317}
318
319static __inline__
320void bm_update_cache(struct bitmap* const bm,
321 const UWord a1,
322 struct bitmap2* const bm2)
323{
bart3c9989f2008-06-11 19:17:01 +0000324#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart33e56c92008-03-24 06:41:30 +0000325 tl_assert(bm);
bart3c9989f2008-06-11 19:17:01 +0000326#endif
bart33e56c92008-03-24 06:41:30 +0000327
328#if N_CACHE_ELEM > 8
329#error Please update the code below.
330#endif
331#if N_CACHE_ELEM >= 8
332 bm->cache[7] = bm->cache[6];
333#endif
334#if N_CACHE_ELEM >= 7
335 bm->cache[6] = bm->cache[5];
336#endif
337#if N_CACHE_ELEM >= 6
338 bm->cache[5] = bm->cache[4];
339#endif
340#if N_CACHE_ELEM >= 5
341 bm->cache[4] = bm->cache[3];
342#endif
343#if N_CACHE_ELEM >= 4
344 bm->cache[3] = bm->cache[2];
345#endif
346#if N_CACHE_ELEM >= 3
347 bm->cache[2] = bm->cache[1];
348#endif
349#if N_CACHE_ELEM >= 2
350 bm->cache[1] = bm->cache[0];
351#endif
352 bm->cache[0].a1 = a1;
353 bm->cache[0].bm2 = bm2;
354}
355
bartf647d342008-03-24 19:12:12 +0000356/** Look up the address a1 in bitmap bm and return a pointer to a potentially
357 * shared second level bitmap. The bitmap where the returned pointer points
358 * at may not be modified by the caller.
359 *
bart0008f5b2008-03-22 17:07:39 +0000360 * @param a1 client address shifted right by ADDR0_BITS.
361 * @param bm bitmap pointer.
362 */
sewardjaf44c822007-11-25 14:01:38 +0000363static __inline__
bart7e81a172008-06-09 19:50:51 +0000364const struct bitmap2* bm2_lookup(struct bitmap* const bm, const UWord a1)
sewardjaf44c822007-11-25 14:01:38 +0000365{
bartf29205e2008-03-25 18:51:06 +0000366 struct bitmap2* bm2;
bartf647d342008-03-24 19:12:12 +0000367 struct bitmap2ref* bm2ref;
368
bart3c9989f2008-06-11 19:17:01 +0000369#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000370 tl_assert(bm);
bart3c9989f2008-06-11 19:17:01 +0000371#endif
bartf29205e2008-03-25 18:51:06 +0000372 if (! bm_cache_lookup(bm, a1, &bm2))
barta79df6e2008-03-14 17:07:51 +0000373 {
bartf29205e2008-03-25 18:51:06 +0000374 bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
375 if (bm2ref)
376 {
377 bm2 = bm2ref->bm2;
378 }
bartf647d342008-03-24 19:12:12 +0000379 bm_update_cache(*(struct bitmap**)&bm, a1, bm2);
bartf647d342008-03-24 19:12:12 +0000380 }
bartf29205e2008-03-25 18:51:06 +0000381 return bm2;
bartf647d342008-03-24 19:12:12 +0000382}
383
384/** Look up the address a1 in bitmap bm and return a pointer to a second
385 * level bitmap that is not shared and hence may be modified.
386 *
387 * @param a1 client address shifted right by ADDR0_BITS.
388 * @param bm bitmap pointer.
389 */
390static __inline__
391struct bitmap2*
bart7e81a172008-06-09 19:50:51 +0000392bm2_lookup_exclusive(struct bitmap* const bm, const UWord a1)
bartf647d342008-03-24 19:12:12 +0000393{
394 struct bitmap2ref* bm2ref;
395 struct bitmap2* bm2;
396
397 bm2ref = 0;
bartf29205e2008-03-25 18:51:06 +0000398 if (bm_cache_lookup(bm, a1, &bm2))
bartf647d342008-03-24 19:12:12 +0000399 {
bartf29205e2008-03-25 18:51:06 +0000400 if (bm2 == 0)
401 return 0;
bartf647d342008-03-24 19:12:12 +0000402 if (bm2->refcnt > 1)
bart33e56c92008-03-24 06:41:30 +0000403 {
bartf647d342008-03-24 19:12:12 +0000404 bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
bart33e56c92008-03-24 06:41:30 +0000405 }
barta79df6e2008-03-14 17:07:51 +0000406 }
bartf647d342008-03-24 19:12:12 +0000407 else
408 {
409 bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
bartf29205e2008-03-25 18:51:06 +0000410 if (bm2ref == 0)
bartf647d342008-03-24 19:12:12 +0000411 return 0;
bartf29205e2008-03-25 18:51:06 +0000412 bm2 = bm2ref->bm2;
bartf647d342008-03-24 19:12:12 +0000413 }
414
bart3c9989f2008-06-11 19:17:01 +0000415#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000416 tl_assert(bm2);
bart3c9989f2008-06-11 19:17:01 +0000417#endif
bartf647d342008-03-24 19:12:12 +0000418
419 if (bm2->refcnt > 1)
420 {
bart3c9989f2008-06-11 19:17:01 +0000421#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000422 tl_assert(bm2ref);
bart3c9989f2008-06-11 19:17:01 +0000423#endif
bartf647d342008-03-24 19:12:12 +0000424 bm2 = bm2_make_exclusive(*(struct bitmap**)&bm, bm2ref);
425 }
426
bart33e56c92008-03-24 06:41:30 +0000427 return bm2;
sewardjaf44c822007-11-25 14:01:38 +0000428}
429
bartf647d342008-03-24 19:12:12 +0000430/** Look up the address a1 in bitmap bm. The returned second level bitmap has
431 * reference count one and hence may be modified.
432 *
433 * @param a1 client address shifted right by ADDR0_BITS.
434 * @param bm bitmap pointer.
435 */
sewardjaf44c822007-11-25 14:01:38 +0000436static __inline__
bart7e81a172008-06-09 19:50:51 +0000437struct bitmap2* bm2_insert(struct bitmap* const bm, const UWord a1)
sewardjaf44c822007-11-25 14:01:38 +0000438{
bartf647d342008-03-24 19:12:12 +0000439 struct bitmap2ref* bm2ref;
bart33e56c92008-03-24 06:41:30 +0000440 struct bitmap2* bm2;
441
bart3c9989f2008-06-11 19:17:01 +0000442 s_bitmap2_node_creation_count++;
bartf647d342008-03-24 19:12:12 +0000443 bm2ref = VG_(OSetGen_AllocNode)(bm->oset, sizeof(*bm2ref));
444 bm2ref->addr = a1;
445 bm2 = bm2_new(a1);
446 bm2ref->bm2 = bm2;
bart0008f5b2008-03-22 17:07:39 +0000447 VG_(memset)(&bm2->bm1, 0, sizeof(bm2->bm1));
bartf647d342008-03-24 19:12:12 +0000448 VG_(OSetGen_Insert)(bm->oset, bm2ref);
barta79df6e2008-03-14 17:07:51 +0000449
bart33e56c92008-03-24 06:41:30 +0000450 bm_update_cache(*(struct bitmap**)&bm, a1, bm2);
bartf647d342008-03-24 19:12:12 +0000451
452 return bm2;
453}
454
455/** Insert a new node in bitmap bm that points to the second level bitmap
456 * *bm2. This means that *bm2 becomes shared over two or more bitmaps.
457 */
458static __inline__
bart7e81a172008-06-09 19:50:51 +0000459struct bitmap2* bm2_insert_addref(struct bitmap* const bm,
bartf647d342008-03-24 19:12:12 +0000460 struct bitmap2* const bm2)
461{
462 struct bitmap2ref* bm2ref;
463
bart3c9989f2008-06-11 19:17:01 +0000464#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000465 tl_assert(bm);
bart3c9989f2008-06-11 19:17:01 +0000466 tl_assert(VG_(OSetGen_Lookup)(bm->oset, &bm2->addr) == 0);
467#endif
bart588d90f2008-04-06 13:05:58 +0000468
bart3c9989f2008-06-11 19:17:01 +0000469 s_bitmap2_node_creation_count++;
bartf647d342008-03-24 19:12:12 +0000470 bm2ref = VG_(OSetGen_AllocNode)(bm->oset, sizeof(*bm2ref));
471 bm2ref->addr = bm2->addr;
472 bm2ref->bm2 = bm2;
473 bm2->refcnt++;
474 VG_(OSetGen_Insert)(bm->oset, bm2ref);
barta79df6e2008-03-14 17:07:51 +0000475
bartf647d342008-03-24 19:12:12 +0000476 bm_update_cache(*(struct bitmap**)&bm, bm2->addr, bm2);
477
bart0008f5b2008-03-22 17:07:39 +0000478 return bm2;
sewardjaf44c822007-11-25 14:01:38 +0000479}
480
bart0008f5b2008-03-22 17:07:39 +0000481/** Look up the address a1 in bitmap bm, and insert it if not found.
bartf647d342008-03-24 19:12:12 +0000482 * The returned second level bitmap may not be modified.
bart0008f5b2008-03-22 17:07:39 +0000483 *
484 * @param a1 client address shifted right by ADDR0_BITS.
485 * @param bm bitmap pointer.
486 */
sewardjaf44c822007-11-25 14:01:38 +0000487static __inline__
bart7e81a172008-06-09 19:50:51 +0000488struct bitmap2* bm2_lookup_or_insert(struct bitmap* const bm, const UWord a1)
sewardjaf44c822007-11-25 14:01:38 +0000489{
bartf647d342008-03-24 19:12:12 +0000490 struct bitmap2ref* bm2ref;
bart0008f5b2008-03-22 17:07:39 +0000491 struct bitmap2* bm2;
barta79df6e2008-03-14 17:07:51 +0000492
bart3c9989f2008-06-11 19:17:01 +0000493#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000494 tl_assert(bm);
bart3c9989f2008-06-11 19:17:01 +0000495#endif
bart567614d2008-03-25 19:16:20 +0000496 if (bm_cache_lookup(bm, a1, &bm2))
497 {
498 if (bm2 == 0)
499 {
500 bm2 = bm2_insert(bm, a1);
501 }
502 }
503 else
barta79df6e2008-03-14 17:07:51 +0000504 {
bartf647d342008-03-24 19:12:12 +0000505 bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
506 if (bm2ref)
507 {
508 bm2 = bm2ref->bm2;
509 }
510 else
bart33e56c92008-03-24 06:41:30 +0000511 {
512 bm2 = bm2_insert(bm, a1);
513 }
514 bm_update_cache(*(struct bitmap**)&bm, a1, bm2);
barta79df6e2008-03-14 17:07:51 +0000515 }
bart0008f5b2008-03-22 17:07:39 +0000516 return bm2;
sewardjaf44c822007-11-25 14:01:38 +0000517}
518
bartf647d342008-03-24 19:12:12 +0000519/** Look up the address a1 in bitmap bm, and insert it if not found.
520 * The returned second level bitmap may be modified.
521 *
522 * @param a1 client address shifted right by ADDR0_BITS.
523 * @param bm bitmap pointer.
524 */
525static __inline__
526struct bitmap2* bm2_lookup_or_insert_exclusive(struct bitmap* const bm,
527 const UWord a1)
528{
529 struct bitmap2* bm2;
530
bart3c9989f2008-06-11 19:17:01 +0000531#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000532 tl_assert(bm);
bart3c9989f2008-06-11 19:17:01 +0000533#endif
bartf647d342008-03-24 19:12:12 +0000534 bm2 = (struct bitmap2*)bm2_lookup_or_insert(bm, a1);
bart3c9989f2008-06-11 19:17:01 +0000535#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf647d342008-03-24 19:12:12 +0000536 tl_assert(bm2);
bart3c9989f2008-06-11 19:17:01 +0000537#endif
bartf647d342008-03-24 19:12:12 +0000538 if (bm2->refcnt > 1)
539 {
540 struct bitmap2ref* bm2ref;
541 bm2ref = VG_(OSetGen_Lookup)(bm->oset, &a1);
542 bm2 = bm2_make_exclusive(bm, bm2ref);
543 }
544 return bm2;
545}
546
bartd59bb0f2008-06-08 08:08:31 +0000547static __inline__
548void bm_access_aligned_load(struct bitmap* const bm,
549 const Addr a1, const SizeT size)
550{
551 struct bitmap2* bm2;
552
553 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
554 bm0_set_range(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size);
555}
556
557static __inline__
558void bm_access_aligned_store(struct bitmap* const bm,
559 const Addr a1, const SizeT size)
560{
561 struct bitmap2* bm2;
562
563 bm2 = bm2_lookup_or_insert_exclusive(bm, a1 >> ADDR0_BITS);
564 bm0_set_range(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size);
565}
566
567static __inline__
bart7e81a172008-06-09 19:50:51 +0000568Bool bm_aligned_load_has_conflict_with(struct bitmap* const bm,
bartd59bb0f2008-06-08 08:08:31 +0000569 const Addr a1, const SizeT size)
570{
571 const struct bitmap2* bm2;
572
573 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
574
575 return (bm2 && bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size));
576}
577
578static __inline__
bart7e81a172008-06-09 19:50:51 +0000579Bool bm_aligned_store_has_conflict_with(struct bitmap* const bm,
bartd59bb0f2008-06-08 08:08:31 +0000580 const Addr a1, const SizeT size)
581{
582 const struct bitmap2* bm2;
583
584 bm2 = bm2_lookup(bm, a1 >> ADDR0_BITS);
585
586 if (bm2)
587 {
588 if (bm0_is_any_set(bm2->bm1.bm0_r, a1 & ADDR0_MASK, size)
589 | bm0_is_any_set(bm2->bm1.bm0_w, a1 & ADDR0_MASK, size))
590 {
591 return True;
592 }
593 }
594 return False;
595}
sewardjaf44c822007-11-25 14:01:38 +0000596
bart33e56c92008-03-24 06:41:30 +0000597#endif /* __DRD_BITMAP_H */