/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DALVIK_HEAP_BITMAPINLINES_H_
#define DALVIK_HEAP_BITMAPINLINES_H_
static unsigned long dvmHeapBitmapSetAndReturnObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
static void dvmHeapBitmapSetObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
static void dvmHeapBitmapClearObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
/*
* Internal function; do not call directly.
*/
static unsigned long _heapBitmapModifyObjectBit(HeapBitmap *hb, const void *obj,
bool setBit, bool returnOld)
{
const uintptr_t offset = (uintptr_t)obj - hb->base;
const size_t index = HB_OFFSET_TO_INDEX(offset);
const unsigned long mask = HB_OFFSET_TO_MASK(offset);
assert(hb->bits != NULL);
assert((uintptr_t)obj >= hb->base);
assert(index < hb->bitsLen / sizeof(*hb->bits));
if (setBit) {
if ((uintptr_t)obj > hb->max) {
hb->max = (uintptr_t)obj;
}
if (returnOld) {
unsigned long *p = hb->bits + index;
const unsigned long word = *p;
*p |= mask;
return word & mask;
} else {
hb->bits[index] |= mask;
}
} else {
hb->bits[index] &= ~mask;
}
return false;
}
/*
* Sets the bit corresponding to <obj>, and returns the previous value
* of that bit (as zero or non-zero). Does no range checking to see if
* <obj> is outside of the coverage of the bitmap.
*
* NOTE: casting this value to a bool is dangerous, because higher
* set bits will be lost.
*/
static unsigned long dvmHeapBitmapSetAndReturnObjectBit(HeapBitmap *hb,
const void *obj)
{
return _heapBitmapModifyObjectBit(hb, obj, true, true);
}
/*
* Sets the bit corresponding to <obj>, and widens the range of seen
* pointers if necessary. Does no range checking.
*/
static void dvmHeapBitmapSetObjectBit(HeapBitmap *hb, const void *obj)
{
_heapBitmapModifyObjectBit(hb, obj, true, false);
}
/*
* Clears the bit corresponding to <obj>. Does no range checking.
*/
static void dvmHeapBitmapClearObjectBit(HeapBitmap *hb, const void *obj)
{
_heapBitmapModifyObjectBit(hb, obj, false, false);
}
/*
* Returns the current value of the bit corresponding to <obj>,
* as zero or non-zero. Does no range checking.
*
* NOTE: casting this value to a bool is dangerous, because higher
* set bits will be lost.
*/
static unsigned long dvmHeapBitmapIsObjectBitSet(const HeapBitmap *hb,
const void *obj)
{
assert(dvmHeapBitmapCoversAddress(hb, obj));
assert(hb->bits != NULL);
assert((uintptr_t)obj >= hb->base);
if ((uintptr_t)obj <= hb->max) {
const uintptr_t offset = (uintptr_t)obj - hb->base;
return hb->bits[HB_OFFSET_TO_INDEX(offset)] & HB_OFFSET_TO_MASK(offset);
} else {
return 0;
}
}
#endif // DALVIK_HEAP_BITMAPINLINES_H_