Simplify the bitmap walker subroutines.
This change...
* Separates walking from sweeping. Walking had been implemented by a
sweeping with an empty mark bitmap argument.
* Localizes the finger machinations to scanBitmapCallback. There is
one use of the finger but all callbacks received the argument.
* Inlines a simplified bitmap walking routine operating a pointer at a
time. Only sweeping benefits from batching decoded addresses.
diff --git a/vm/alloc/HeapBitmap.h b/vm/alloc/HeapBitmap.h
index 5810d9a..b0dea99 100644
--- a/vm/alloc/HeapBitmap.h
+++ b/vm/alloc/HeapBitmap.h
@@ -18,6 +18,7 @@
#include <limits.h>
#include <stdint.h>
+#include "clz.h"
#define HB_OBJECT_ALIGNMENT 8
#define HB_BITS_PER_WORD (sizeof(unsigned long) * CHAR_BIT)
@@ -79,8 +80,8 @@
uintptr_t max;
} HeapBitmap;
-typedef void BitmapCallback(size_t numPtrs, void **ptrs,
- const void *finger, void *arg);
+typedef void BitmapCallback(void *addr, void *arg);
+typedef void BitmapSweepCallback(size_t numPtrs, void **ptrs, void *arg);
/*
* Initialize a HeapBitmap so that it points to a bitmap large
@@ -118,14 +119,38 @@
* end of the bitmap is reached.
*/
void dvmHeapBitmapSweepWalk(const HeapBitmap *liveHb, const HeapBitmap *markHb,
- BitmapCallback *callback, void *callbackArg);
+ BitmapSweepCallback *callback, void *callbackArg);
/*
* Similar to dvmHeapBitmapSweepWalk(), but visit the set bits
* in a single bitmap.
*/
-void dvmHeapBitmapWalk(const HeapBitmap *hb,
- BitmapCallback *callback, void *callbackArg);
+HB_INLINE_PROTO(
+ void
+ dvmHeapBitmapWalk(const HeapBitmap *bitmap,
+ BitmapCallback *callback, void *arg)
+)
+{
+ assert(bitmap != NULL);
+ assert(bitmap->bits != NULL);
+ assert(callback != NULL);
+ uintptr_t end = HB_OFFSET_TO_INDEX(bitmap->max - bitmap->base);
+ uintptr_t i;
+ for (i = 0; i <= end; ++i) {
+ unsigned long word = bitmap->bits[i];
+ if (UNLIKELY(word != 0)) {
+ unsigned long highBit = 1 << (HB_BITS_PER_WORD - 1);
+ uintptr_t ptrBase = HB_INDEX_TO_OFFSET(i) + bitmap->base;
+ while (word != 0) {
+ const int shift = CLZ(word);
+ word &= ~(highBit >> shift);
+ void *addr = (void *)(ptrBase + shift * HB_OBJECT_ALIGNMENT);
+ (*callback)(addr, arg);
+ end = HB_OFFSET_TO_INDEX(bitmap->max - bitmap->base);
+ }
+ }
+ }
+}
/*
* Return true iff <obj> is within the range of pointers that this