blob: 248a5d29c9baa70e055e5087fd773c868cf2999b [file] [log] [blame]
/*
This file is part of drd, a data race detector.
Copyright (C) 2006-2007 Bart Van Assche
bart.vanassche@gmail.com
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file COPYING.
*/
#ifndef __DRD_BITMAP3_H
#define __DRD_BITMAP3_H
#include "pub_tool_oset.h"
/*
Bitmap representation. A bitmap is a data structure in which two bits are
reserved per 32 bit address: one bit that indicates that the data at the
specified address has been read, and one bit that indicates that the data has
been written to.
*/
/* Macro definitions. */
#define ADDR0_BITS 12
#define ADDR0_COUNT (1UL << ADDR0_BITS)
#define ADDR0_MASK (ADDR0_COUNT - 1)
#define SPLIT_ADDRESS(a) \
UWord a##0 = ((a) & ADDR0_MASK); \
UWord a##1 = ((a) >> ADDR0_BITS);
// Assumption: sizeof(Addr) == sizeof(UWord).
#define MAKE_ADDRESS(a1, a0) \
(Addr)(((UWord)(a1) << (ADDR0_BITS)) | ((UWord)(a0)))
#define BITS_PER_UWORD (8UL*sizeof(UWord))
#if defined(VGA_x86) || defined(VGA_ppc32)
#define BITS_PER_BITS_PER_UWORD 5
#elif defined(VGA_amd64) || defined(VGA_ppc64)
#define BITS_PER_BITS_PER_UWORD 6
#else
#error Unknown platform.
#endif
#define BITMAP1_UWORD_COUNT (ADDR0_COUNT >> BITS_PER_BITS_PER_UWORD)
/* Highest bits of an address that fit into the same UWord of bm0[]. */
#define UWORD_MSB(a) ((a) & ~(BITS_PER_UWORD - 1))
/* Lowest bits of an address that fit into the same UWord of bm0[]. */
#define UWORD_LSB(a) ((a) & (BITS_PER_UWORD - 1))
/* Highest address that fits in the same UWord as a. */
#define UWORD_HIGHEST_ADDRESS(a) ((a) | (BITS_PER_UWORD - 1))
// Local functions.
// Similar to const_cast<> in C++.
static __inline__ OSet* const_to_non_const_oset(const OSet* os)
{ return (OSet*)os; }
// Local constants.
static ULong s_bitmap2_creation_count;
/* Lowest level, corresponding to the lowest ADDR0_BITS of an address. */
struct bitmap1
{
UWord bm0_r[BITMAP1_UWORD_COUNT];
UWord bm0_w[BITMAP1_UWORD_COUNT];
};
static __inline__ UWord bm0_mask(const Addr a)
{
return (1UL << UWORD_LSB(a));
}
static __inline__ void bm0_set(UWord* bm0, const Addr a)
{
//tl_assert(a < ADDR0_COUNT);
bm0[a >> BITS_PER_BITS_PER_UWORD] |= 1UL << UWORD_LSB(a);
}
static __inline__ void bm0_clear(UWord* bm0, const Addr a)
{
//tl_assert(a < ADDR0_COUNT);
bm0[a >> BITS_PER_BITS_PER_UWORD] &= ~(1UL << UWORD_LSB(a));
}
static __inline__ UWord bm0_is_set(const UWord* bm0, const Addr a)
{
//tl_assert(a < ADDR0_COUNT);
return (bm0[a >> BITS_PER_BITS_PER_UWORD] & (1UL << UWORD_LSB(a)));
}
struct bitmap2
{
Addr addr; ///< address >> ADDR0_BITS
struct bitmap1 bm1;
};
/* Complete bitmap. */
struct bitmap
{
OSet* oset;
};
static __inline__
struct bitmap2* bm_lookup(const struct bitmap* const bm, const Addr a)
{
const UWord a1 = a >> ADDR0_BITS;
return VG_(OSetGen_Lookup)(const_to_non_const_oset(bm->oset), (void*)&a1);
}
static __inline__
struct bitmap2* bm2_insert(const struct bitmap* const bm,
const UWord a1)
{
struct bitmap2* const node = VG_(OSetGen_AllocNode)(bm->oset, sizeof(*node));
node->addr = a1;
VG_(memset)(&node->bm1, 0, sizeof(node->bm1));
VG_(OSetGen_Insert)(bm->oset, node);
s_bitmap2_creation_count++;
return node;
}
static __inline__
struct bitmap2* bm2_lookup_or_insert(const struct bitmap* const bm,
const UWord a1)
{
struct bitmap2* p2 = VG_(OSetGen_Lookup)(const_to_non_const_oset(bm->oset), (void*)&a1);
if (p2 == 0)
{
p2 = bm2_insert(bm, a1);
}
return p2;
}
#endif /* __DRD_BITMAP3_H */