1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef DALVIK_HEAP_BITMAPINLINES_H_
18#define DALVIK_HEAP_BITMAPINLINES_H_
19
20static unsigned long dvmHeapBitmapSetAndReturnObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
21static void dvmHeapBitmapSetObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
22static void dvmHeapBitmapClearObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
23
24/*
25 * Internal function; do not call directly.
26 */
27static unsigned long _heapBitmapModifyObjectBit(HeapBitmap *hb, const void *obj,
28                                                bool setBit, bool returnOld)
29{
30    const uintptr_t offset = (uintptr_t)obj - hb->base;
31    const size_t index = HB_OFFSET_TO_INDEX(offset);
32    const unsigned long mask = HB_OFFSET_TO_MASK(offset);
33
34    assert(hb->bits != NULL);
35    assert((uintptr_t)obj >= hb->base);
36    assert(index < hb->bitsLen / sizeof(*hb->bits));
37    if (setBit) {
38        if ((uintptr_t)obj > hb->max) {
39            hb->max = (uintptr_t)obj;
40        }
41        if (returnOld) {
42            unsigned long *p = hb->bits + index;
43            const unsigned long word = *p;
44            *p |= mask;
45            return word & mask;
46        } else {
47            hb->bits[index] |= mask;
48        }
49    } else {
50        hb->bits[index] &= ~mask;
51    }
52    return false;
53}
54
55/*
56 * Sets the bit corresponding to <obj>, and returns the previous value
57 * of that bit (as zero or non-zero). Does no range checking to see if
58 * <obj> is outside of the coverage of the bitmap.
59 *
60 * NOTE: casting this value to a bool is dangerous, because higher
61 * set bits will be lost.
62 */
63static unsigned long dvmHeapBitmapSetAndReturnObjectBit(HeapBitmap *hb,
64                                                        const void *obj)
65{
66    return _heapBitmapModifyObjectBit(hb, obj, true, true);
67}
68
69/*
70 * Sets the bit corresponding to <obj>, and widens the range of seen
71 * pointers if necessary.  Does no range checking.
72 */
73static void dvmHeapBitmapSetObjectBit(HeapBitmap *hb, const void *obj)
74{
75    _heapBitmapModifyObjectBit(hb, obj, true, false);
76}
77
78/*
79 * Clears the bit corresponding to <obj>.  Does no range checking.
80 */
81static void dvmHeapBitmapClearObjectBit(HeapBitmap *hb, const void *obj)
82{
83    _heapBitmapModifyObjectBit(hb, obj, false, false);
84}
85
86/*
87 * Returns the current value of the bit corresponding to <obj>,
88 * as zero or non-zero.  Does no range checking.
89 *
90 * NOTE: casting this value to a bool is dangerous, because higher
91 * set bits will be lost.
92 */
93static unsigned long dvmHeapBitmapIsObjectBitSet(const HeapBitmap *hb,
94                                                 const void *obj)
95{
96    assert(dvmHeapBitmapCoversAddress(hb, obj));
97    assert(hb->bits != NULL);
98    assert((uintptr_t)obj >= hb->base);
99    if ((uintptr_t)obj <= hb->max) {
100        const uintptr_t offset = (uintptr_t)obj - hb->base;
101        return hb->bits[HB_OFFSET_TO_INDEX(offset)] & HB_OFFSET_TO_MASK(offset);
102    } else {
103        return 0;
104    }
105}
106
107#endif  // DALVIK_HEAP_BITMAPINLINES_H_
108