blob: cd2244bb94aa56af9261b217823bce2b6618027b [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#ifndef __DRD_BITMAP3_H
27#define __DRD_BITMAP3_H
28
29
30#include "pub_tool_oset.h"
31
32
33/*
34 Bitmap representation. A bitmap is a data structure in which two bits are
35 reserved per 32 bit address: one bit that indicates that the data at the
36 specified address has been read, and one bit that indicates that the data has
37 been written to.
38*/
39
40
41/* Macro definitions. */
42
43#define ADDR0_BITS 12
44
barta79df6e2008-03-14 17:07:51 +000045#define ADDR0_COUNT ((UWord)1 << ADDR0_BITS)
sewardjaf44c822007-11-25 14:01:38 +000046
47#define ADDR0_MASK (ADDR0_COUNT - 1)
48
bart0268dfa2008-03-11 20:10:21 +000049#define SPLIT_ADDRESS(a) \
50 UWord a##0 = ((a) & ADDR0_MASK); \
sewardjaf44c822007-11-25 14:01:38 +000051 UWord a##1 = ((a) >> ADDR0_BITS);
52
53// Assumption: sizeof(Addr) == sizeof(UWord).
bart0268dfa2008-03-11 20:10:21 +000054#define MAKE_ADDRESS(a1, a0) \
sewardjaf44c822007-11-25 14:01:38 +000055 (Addr)(((UWord)(a1) << (ADDR0_BITS)) | ((UWord)(a0)))
56
57#define BITS_PER_UWORD (8UL*sizeof(UWord))
58#if defined(VGA_x86) || defined(VGA_ppc32)
59#define BITS_PER_BITS_PER_UWORD 5
60#elif defined(VGA_amd64) || defined(VGA_ppc64)
61#define BITS_PER_BITS_PER_UWORD 6
62#else
63#error Unknown platform.
64#endif
65
66#define BITMAP1_UWORD_COUNT (ADDR0_COUNT >> BITS_PER_BITS_PER_UWORD)
67
68/* Highest bits of an address that fit into the same UWord of bm0[]. */
69#define UWORD_MSB(a) ((a) & ~(BITS_PER_UWORD - 1))
70
71/* Lowest bits of an address that fit into the same UWord of bm0[]. */
72#define UWORD_LSB(a) ((a) & (BITS_PER_UWORD - 1))
73
74/* Highest address that fits in the same UWord as a. */
75#define UWORD_HIGHEST_ADDRESS(a) ((a) | (BITS_PER_UWORD - 1))
76
77
sewardjaf44c822007-11-25 14:01:38 +000078// Local constants.
79
80static ULong s_bitmap2_creation_count;
81
82
83/* Lowest level, corresponding to the lowest ADDR0_BITS of an address. */
84struct bitmap1
85{
86 UWord bm0_r[BITMAP1_UWORD_COUNT];
87 UWord bm0_w[BITMAP1_UWORD_COUNT];
88};
89
90static __inline__ UWord bm0_mask(const Addr a)
91{
barta79df6e2008-03-14 17:07:51 +000092 return ((UWord)1 << UWORD_LSB(a));
sewardjaf44c822007-11-25 14:01:38 +000093}
94
95static __inline__ void bm0_set(UWord* bm0, const Addr a)
96{
97 //tl_assert(a < ADDR0_COUNT);
barta79df6e2008-03-14 17:07:51 +000098 bm0[a >> BITS_PER_BITS_PER_UWORD] |= (UWord)1 << UWORD_LSB(a);
99}
100
bartf8bc71d2008-03-15 11:42:34 +0000101/** Set all of the addresses in range [ a1 .. a1 + size [ in bitmap bm0. */
102static __inline__ void bm0_set_range(UWord* bm0,
103 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000104{
105#if 0
106 tl_assert(a1 < ADDR0_COUNT);
bartf8bc71d2008-03-15 11:42:34 +0000107 tl_assert(size > 0);
108 tl_assert(a1 + size <= ADDR0_COUNT);
109 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a1 + size - 1));
barta79df6e2008-03-14 17:07:51 +0000110#endif
111 bm0[a1 >> BITS_PER_BITS_PER_UWORD]
bartf8bc71d2008-03-15 11:42:34 +0000112 |= (((UWord)1 << size) - 1) << UWORD_LSB(a1);
sewardjaf44c822007-11-25 14:01:38 +0000113}
114
115static __inline__ void bm0_clear(UWord* bm0, const Addr a)
116{
117 //tl_assert(a < ADDR0_COUNT);
barta79df6e2008-03-14 17:07:51 +0000118 bm0[a >> BITS_PER_BITS_PER_UWORD] &= ~((UWord)1 << UWORD_LSB(a));
sewardjaf44c822007-11-25 14:01:38 +0000119}
120
121static __inline__ UWord bm0_is_set(const UWord* bm0, const Addr a)
122{
123 //tl_assert(a < ADDR0_COUNT);
barta79df6e2008-03-14 17:07:51 +0000124 return (bm0[a >> BITS_PER_BITS_PER_UWORD] & ((UWord)1 << UWORD_LSB(a)));
sewardjaf44c822007-11-25 14:01:38 +0000125}
126
bartf8bc71d2008-03-15 11:42:34 +0000127/** Return true if any of the bits [ a1 .. a1+size [ are set in bm0. */
barta79df6e2008-03-14 17:07:51 +0000128static __inline__ UWord bm0_is_any_set(const UWord* bm0,
bartf8bc71d2008-03-15 11:42:34 +0000129 const Addr a1, const SizeT size)
barta79df6e2008-03-14 17:07:51 +0000130{
131#if 0
132 tl_assert(a1 < ADDR0_COUNT);
bartf8bc71d2008-03-15 11:42:34 +0000133 tl_assert(size > 0);
134 tl_assert(a1 + size <= ADDR0_COUNT);
135 tl_assert(UWORD_MSB(a1) == UWORD_MSB(a1 + size - 1));
barta79df6e2008-03-14 17:07:51 +0000136#endif
137 return (bm0[a1 >> BITS_PER_BITS_PER_UWORD]
bartf8bc71d2008-03-15 11:42:34 +0000138 & ((((UWord)1 << size) - 1) << UWORD_LSB(a1)));
barta79df6e2008-03-14 17:07:51 +0000139}
sewardjaf44c822007-11-25 14:01:38 +0000140
141struct bitmap2
142{
143 Addr addr; ///< address >> ADDR0_BITS
144 struct bitmap1 bm1;
145};
146
147/* Complete bitmap. */
148struct bitmap
149{
barta79df6e2008-03-14 17:07:51 +0000150 Addr last_lookup_a1;
151 struct bitmap2* last_lookup_result;
152 OSet* oset;
sewardjaf44c822007-11-25 14:01:38 +0000153};
154
155static __inline__
156struct bitmap2* bm_lookup(const struct bitmap* const bm, const Addr a)
157{
barta79df6e2008-03-14 17:07:51 +0000158 struct bitmap2* result;
sewardjaf44c822007-11-25 14:01:38 +0000159 const UWord a1 = a >> ADDR0_BITS;
barta79df6e2008-03-14 17:07:51 +0000160 if (a1 == bm->last_lookup_a1)
161 {
162 //tl_assert(bm->last_lookup_result == VG_(OSetGen_Lookup)(bm->oset, &a1));
163 return bm->last_lookup_result;
164 }
165 result = VG_(OSetGen_Lookup)(bm->oset,&a1);
166 if (result)
167 {
168 ((struct bitmap*)bm)->last_lookup_a1 = a1;
169 ((struct bitmap*)bm)->last_lookup_result = result;
170 }
171 return result;
sewardjaf44c822007-11-25 14:01:38 +0000172}
173
174static __inline__
175struct bitmap2* bm2_insert(const struct bitmap* const bm,
176 const UWord a1)
177{
barta79df6e2008-03-14 17:07:51 +0000178 struct bitmap2* const node = VG_(OSetGen_AllocNode)(bm->oset, sizeof(*node));
179 node->addr = a1;
180 VG_(memset)(&node->bm1, 0, sizeof(node->bm1));
181 VG_(OSetGen_Insert)(bm->oset, node);
182
183 ((struct bitmap*)bm)->last_lookup_a1 = a1;
184 ((struct bitmap*)bm)->last_lookup_result = node;
185
186 s_bitmap2_creation_count++;
187
188 return node;
sewardjaf44c822007-11-25 14:01:38 +0000189}
190
191static __inline__
192struct bitmap2* bm2_lookup_or_insert(const struct bitmap* const bm,
193 const UWord a1)
194{
barta79df6e2008-03-14 17:07:51 +0000195 struct bitmap2* p2;
196
197 if (a1 == bm->last_lookup_a1)
198 {
199 //tl_assert(bm->last_lookup_result == VG_(OSetGen_Lookup)(bm->oset, &a1));
200 return bm->last_lookup_result;
201 }
202
203 p2 = VG_(OSetGen_Lookup)(bm->oset, &a1);
204 if (p2 == 0)
205 {
206 p2 = bm2_insert(bm, a1);
207 }
208 ((struct bitmap*)bm)->last_lookup_a1 = a1;
209 ((struct bitmap*)bm)->last_lookup_result = p2;
210 return p2;
sewardjaf44c822007-11-25 14:01:38 +0000211}
212
213
214#endif /* __DRD_BITMAP3_H */