Kill dvmHeapSourceGetObjectBitmaps and aliasBitmaps.
In the beginning separate mark bitmaps and live bitmaps were kept for
each of the three heaps. Later, all heaps were allocated adjacent to
one another from a single contiguous tract of virtual memory. As
such, summary data structures such as the card table, mark bitmap, and
live bitmap, were similarly allocated from individual blocks of memory
instead of sparsely for each heap.
While the summary structures were changed, the sweeping routine was
left to assume separate bitmaps. In fact, the aliasBitmap hack was
added to continue the fiction of small bitmaps for each of the heaps.
It would have been preferable to change the sweeping routine, but that
routine was greatly entangled with generalities. Fortunately, those
entanglements have since been eliminated.
This change updates the sweeping routine to operate on memory address
ranges instead of whole bitmaps, obsoleting aliasBitmaps and its sole
caller. The bitmap sweep routine now receives a range of addresses
for sweeping. This range may span the entire bitmap or any contiguous
range within the span of the bitmap.
Change-Id: Iae206032738d6cad77e0625d27ae7b7d6551890d
diff --git a/vm/alloc/HeapBitmap.c b/vm/alloc/HeapBitmap.c
index c5f3d18..41867df 100644
--- a/vm/alloc/HeapBitmap.c
+++ b/vm/alloc/HeapBitmap.c
@@ -86,14 +86,14 @@
* The callback is not permitted to increase the max of either bitmap.
*/
void dvmHeapBitmapSweepWalk(const HeapBitmap *liveHb, const HeapBitmap *markHb,
+ uintptr_t base, uintptr_t max,
BitmapSweepCallback *callback, void *callbackArg)
{
void *pointerBuf[4 * HB_BITS_PER_WORD];
void **pb = pointerBuf;
- size_t index;
size_t i;
+ size_t start, end;
unsigned long *live, *mark;
- uintptr_t offset;
assert(liveHb != NULL);
assert(liveHb->bits != NULL);
@@ -102,16 +102,19 @@
assert(liveHb->base == markHb->base);
assert(liveHb->bitsLen == markHb->bitsLen);
assert(callback != NULL);
+ assert(base <= max);
+ assert(base >= liveHb->base);
+ assert(max <= liveHb->max);
if (liveHb->max < liveHb->base) {
/* Easy case; both are obviously empty.
*/
return;
}
- offset = liveHb->max - liveHb->base;
- index = HB_OFFSET_TO_INDEX(offset);
+ start = HB_OFFSET_TO_INDEX(base - liveHb->base);
+ end = HB_OFFSET_TO_INDEX(max - liveHb->base);
live = liveHb->bits;
mark = markHb->bits;
- for (i = 0; i <= index; i++) {
+ for (i = start; i <= end; i++) {
unsigned long garbage = live[i] & ~mark[i];
if (UNLIKELY(garbage != 0)) {
unsigned long highBit = 1 << (HB_BITS_PER_WORD - 1);
diff --git a/vm/alloc/HeapBitmap.h b/vm/alloc/HeapBitmap.h
index 7995f19..5f7f029 100644
--- a/vm/alloc/HeapBitmap.h
+++ b/vm/alloc/HeapBitmap.h
@@ -181,6 +181,7 @@
* The callback is not permitted to increase the max of either bitmap.
*/
void dvmHeapBitmapSweepWalk(const HeapBitmap *liveHb, const HeapBitmap *markHb,
+ uintptr_t base, uintptr_t max,
BitmapSweepCallback *callback, void *callbackArg);
/*
diff --git a/vm/alloc/HeapSource.c b/vm/alloc/HeapSource.c
index 9ebda9b..010774b 100644
--- a/vm/alloc/HeapSource.c
+++ b/vm/alloc/HeapSource.c
@@ -731,49 +731,6 @@
return total;
}
-static void aliasBitmap(HeapBitmap *dst, HeapBitmap *src,
- uintptr_t base, uintptr_t max) {
- size_t offset;
-
- dst->base = base;
- dst->max = max;
- dst->bitsLen = HB_OFFSET_TO_BYTE_INDEX(max - base) + sizeof(dst->bits);
- /* The exclusive limit from bitsLen is greater than the inclusive max. */
- assert(base + HB_MAX_OFFSET(dst) > max);
- /* The exclusive limit is at most one word of bits beyond max. */
- assert((base + HB_MAX_OFFSET(dst)) - max <=
- HB_OBJECT_ALIGNMENT * HB_BITS_PER_WORD);
- dst->allocLen = dst->bitsLen;
- offset = base - src->base;
- assert(HB_OFFSET_TO_MASK(offset) == 1 << 31);
- dst->bits = &src->bits[HB_OFFSET_TO_INDEX(offset)];
-}
-
-/*
- * Initializes a vector of object and mark bits to the object and mark
- * bits of each heap. The bits are aliased to the heapsource
- * object and mark bitmaps. This routine is used by the sweep code
- * which needs to free each object in the correct heap.
- */
-void dvmHeapSourceGetObjectBitmaps(HeapBitmap liveBits[], HeapBitmap markBits[],
- size_t numHeaps)
-{
- HeapSource *hs = gHs;
- uintptr_t base, max;
- size_t i;
-
- HS_BOILERPLATE();
-
- assert(numHeaps == hs->numHeaps);
- for (i = 0; i < hs->numHeaps; ++i) {
- base = (uintptr_t)hs->heaps[i].base;
- /* -1 because limit is exclusive but max is inclusive. */
- max = MIN((uintptr_t)hs->heaps[i].limit - 1, hs->markBits.max);
- aliasBitmap(&liveBits[i], &hs->liveBits, base, max);
- aliasBitmap(&markBits[i], &hs->markBits, base, max);
- }
-}
-
/*
* Get the bitmap representing all live objects.
*/
@@ -784,6 +741,16 @@
return &gHs->liveBits;
}
+/*
+ * Get the bitmap representing all marked objects.
+ */
+HeapBitmap *dvmHeapSourceGetMarkBits(void)
+{
+ HS_BOILERPLATE();
+
+ return &gHs->markBits;
+}
+
void dvmHeapSourceSwapBitmaps(void)
{
HeapBitmap tmp;
diff --git a/vm/alloc/HeapSource.h b/vm/alloc/HeapSource.h
index 84b5794..b182409 100644
--- a/vm/alloc/HeapSource.h
+++ b/vm/alloc/HeapSource.h
@@ -61,12 +61,6 @@
*/
void dvmHeapSourceShutdown(GcHeap **gcHeap);
-/*
- * Initializes a vector of object and mark bits to the object and mark
- * bits of each heap.
- */
-void dvmHeapSourceGetObjectBitmaps(HeapBitmap liveBits[], HeapBitmap markBits[],
- size_t numHeaps);
/*
* Get the bitmap representing all live objects.
@@ -74,6 +68,11 @@
HeapBitmap *dvmHeapSourceGetLiveBits(void);
/*
+ * Get the bitmap representing all marked objects.
+ */
+HeapBitmap *dvmHeapSourceGetMarkBits(void);
+
+/*
* Gets the begining of the allocation for the HeapSource.
*/
void *dvmHeapSourceGetBase(void);
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index fe8550d..c38a278 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -1065,27 +1065,24 @@
void dvmHeapSweepUnmarkedObjects(GcMode mode, bool isConcurrent,
size_t *numObjects, size_t *numBytes)
{
- HeapBitmap currMark[HEAP_SOURCE_MAX_HEAP_COUNT];
- HeapBitmap currLive[HEAP_SOURCE_MAX_HEAP_COUNT];
SweepContext ctx;
- size_t numBitmaps, numSweepBitmaps;
- size_t i;
+ HeapBitmap *prevLive, *prevMark;
+ uintptr_t base, max;
- numBitmaps = dvmHeapSourceGetNumHeaps();
- dvmHeapSourceGetObjectBitmaps(currLive, currMark, numBitmaps);
+ prevLive = dvmHeapSourceGetMarkBits();
+ prevMark = dvmHeapSourceGetLiveBits();
if (mode == GC_PARTIAL) {
- numSweepBitmaps = 1;
- assert((uintptr_t)gDvm.gcHeap->markContext.immuneLimit == currLive[0].base);
+ assert((uintptr_t)gDvm.gcHeap->markContext.immuneLimit == prevMark->base);
+ base = (uintptr_t)dvmHeapSourceGetImmuneLimit(mode);
} else {
- numSweepBitmaps = numBitmaps;
+ base = prevLive->base;
}
+ max = prevLive->max;
ctx.numObjects = ctx.numBytes = 0;
ctx.isConcurrent = isConcurrent;
- for (i = 0; i < numSweepBitmaps; i++) {
- HeapBitmap* prevLive = &currMark[i];
- HeapBitmap* prevMark = &currLive[i];
- dvmHeapBitmapSweepWalk(prevLive, prevMark, sweepBitmapCallback, &ctx);
- }
+ dvmHeapBitmapSweepWalk(prevLive, prevMark,
+ base, max,
+ sweepBitmapCallback, &ctx);
*numObjects = ctx.numObjects;
*numBytes = ctx.numBytes;
if (gDvm.allocProf.enabled) {