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
20 static unsigned long dvmHeapBitmapSetAndReturnObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
21 static void dvmHeapBitmapSetObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
22 static void dvmHeapBitmapClearObjectBit(HeapBitmap *hb, const void *obj) __attribute__((used));
23
24 /*
25 * Internal function; do not call directly.
26 */
_heapBitmapModifyObjectBit(HeapBitmap * hb,const void * obj,bool setBit,bool returnOld)27 static 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 */
dvmHeapBitmapSetAndReturnObjectBit(HeapBitmap * hb,const void * obj)63 static 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 */
dvmHeapBitmapSetObjectBit(HeapBitmap * hb,const void * obj)73 static 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 */
dvmHeapBitmapClearObjectBit(HeapBitmap * hb,const void * obj)81 static 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 */
dvmHeapBitmapIsObjectBitSet(const HeapBitmap * hb,const void * obj)93 static 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