diff options
| author | Ben Cheng <bccheng@android.com> | 2011-10-10 13:17:58 -0700 |
|---|---|---|
| committer | Ben Cheng <bccheng@android.com> | 2011-10-10 13:20:45 -0700 |
| commit | b2714082bad44fde247920b9280c1b40c4979c3a (patch) | |
| tree | ea336738be9e9209aff21dda7a1d28342856e8f7 /vm/alloc | |
| parent | 5a459d4a923cd2160026cc58e4d3da0858028320 (diff) | |
| download | android_dalvik-b2714082bad44fde247920b9280c1b40c4979c3a.tar.gz android_dalvik-b2714082bad44fde247920b9280c1b40c4979c3a.tar.bz2 android_dalvik-b2714082bad44fde247920b9280c1b40c4979c3a.zip | |
Revert "Use the card table to scan the immune region of the heap."
This reverts commit 6c355e53332502314c3d82a7afcf898d66118f27.
Conflicts are resolved in:
vm/alloc/CardTable.cpp
vm/alloc/HeapBitmap.cpp
vm/alloc/HeapInternal.h
vm/alloc/HeapSource.cpp
vm/alloc/MarkSweep.cpp
Tested with overnight monkey runs + Delaunay.
Bug: 5037417
Change-Id: I400eff8542d0bddd865ce570a479f7750c1ba484
Diffstat (limited to 'vm/alloc')
| -rw-r--r-- | vm/alloc/CardTable.cpp | 104 | ||||
| -rw-r--r-- | vm/alloc/Heap.cpp | 4 | ||||
| -rw-r--r-- | vm/alloc/HeapBitmap.cpp | 9 | ||||
| -rw-r--r-- | vm/alloc/HeapBitmap.h | 1 | ||||
| -rw-r--r-- | vm/alloc/HeapInternal.h | 4 | ||||
| -rw-r--r-- | vm/alloc/HeapSource.cpp | 15 | ||||
| -rw-r--r-- | vm/alloc/HeapSource.h | 3 | ||||
| -rw-r--r-- | vm/alloc/MarkSweep.cpp | 304 | ||||
| -rw-r--r-- | vm/alloc/MarkSweep.h | 2 |
9 files changed, 117 insertions, 329 deletions
diff --git a/vm/alloc/CardTable.cpp b/vm/alloc/CardTable.cpp index 2f6156ad3..c24be0187 100644 --- a/vm/alloc/CardTable.cpp +++ b/vm/alloc/CardTable.cpp @@ -44,7 +44,11 @@ * byte is equal to GC_DIRTY_CARD. See dvmCardTableStartup for details. */ -static bool allocCardTable(size_t heapMaximumSize) +/* + * Initializes the card table; must be called before any other + * dvmCardTable*() functions. + */ +bool dvmCardTableStartup(size_t heapMaximumSize) { size_t length; void *allocBase; @@ -56,7 +60,6 @@ static bool allocCardTable(size_t heapMaximumSize) /* Set up the card table */ length = heapMaximumSize / GC_CARD_SIZE; - assert(length * GC_CARD_SIZE == heapMaximumSize); /* Allocate an extra 256 bytes to allow fixed low-byte of base */ allocBase = dvmAllocRegion(length + 0x100, PROT_READ | PROT_WRITE, "dalvik-card-table"); @@ -82,108 +85,19 @@ static bool allocCardTable(size_t heapMaximumSize) return true; } -static bool allocModUnionTable(size_t heapSize) -{ - size_t cardsPerHeap = heapSize / GC_CARD_SIZE; - size_t byteLength = cardsPerHeap / CHAR_BIT; - assert(byteLength * GC_CARD_SIZE * CHAR_BIT == heapSize); - int prot = PROT_READ | PROT_WRITE; - void *allocBase = dvmAllocRegion(byteLength, prot, "dalvik-modunion-table"); - if (allocBase == NULL) { - return false; - } - GcHeap *gcHeap = gDvm.gcHeap; - gcHeap->modUnionTableBase = (u1*)allocBase; - gcHeap->modUnionTableLength = byteLength; - return true; -} - -/* - * Initializes the card table; must be called before any other - * dvmCardTable*() functions. - */ -bool dvmCardTableStartup(size_t heapMaximumSize) -{ - return allocCardTable(heapMaximumSize) && allocModUnionTable(heapMaximumSize); -} - -/* - * Releases storage for the card table and clears its globals. - */ -static void freeCardTable() -{ - if (gDvm.biasedCardTableBase == NULL) { - return; - } - gDvm.biasedCardTableBase = NULL; - munmap(gDvm.gcHeap->cardTableBase, gDvm.gcHeap->cardTableLength + 0x100); - gDvm.gcHeap->cardTableBase = NULL; - gDvm.gcHeap->cardTableLength = 0; -} - -/* - * Releases storage for the mod union table and clears its globals. - */ -static void freeModUnionTable() -{ - if (gDvm.gcHeap->modUnionTableBase == NULL) { - return; - } - munmap(gDvm.gcHeap->modUnionTableBase, gDvm.gcHeap->modUnionTableLength); - gDvm.gcHeap->modUnionTableBase = NULL; - gDvm.gcHeap->modUnionTableLength = 0; -} - /* * Tears down the entire CardTable. */ void dvmCardTableShutdown() { - freeCardTable(); - freeModUnionTable(); -} - -/* - * Set a bit in the mod union table for each dirty byte in the card - * table. Clears the corresponding byte in the card table. - */ -static void moveCardsToModUnion(u1 *base, u1 *limit) -{ - GcHeap *h = gDvm.gcHeap; - u1 *baseCard = dvmCardFromAddr(base); - u1 *limitCard = dvmCardFromAddr(limit); - u4 *bits = (u4*)h->modUnionTableBase; - u1 *heapBase = (u1*)dvmHeapSourceGetBase(); - for (u1 *card = baseCard; card < limitCard; ++card) { - if (*card == GC_CARD_CLEAN) { - continue; - } - u1 *addr = (u1*)dvmAddrFromCard(card); - u1 *biased = (u1*)((uintptr_t)addr - (uintptr_t)heapBase); - size_t offset = (uintptr_t)biased / GC_CARD_SIZE / HB_BITS_PER_WORD; - u4 bit = 1 << (((uintptr_t)biased / GC_CARD_SIZE) % HB_BITS_PER_WORD); - assert((u1*)&bits[offset] >= h->modUnionTableBase); - assert((u1*)&bits[offset] < h->modUnionTableBase+h->modUnionTableLength); - bits[offset] |= bit; - *card = GC_CARD_CLEAN; - } + gDvm.biasedCardTableBase = NULL; + munmap(gDvm.gcHeap->cardTableBase, gDvm.gcHeap->cardTableLength); } void dvmClearCardTable() { - uintptr_t base[HEAP_SOURCE_MAX_HEAP_COUNT]; - uintptr_t limit[HEAP_SOURCE_MAX_HEAP_COUNT]; - size_t numHeaps = dvmHeapSourceGetNumHeaps(); - dvmHeapSourceGetRegions(base, NULL, limit, numHeaps); - for (size_t i = 0; i < numHeaps; ++i) { - if (i != 0) { - moveCardsToModUnion((u1*)base[i], (u1*)limit[i]); - } else { - u1 *baseCard = dvmCardFromAddr((u1*)base[i]); - size_t length = (limit[i] - base[i]) >> GC_CARD_SHIFT; - memset(baseCard, GC_CARD_CLEAN, length); - } - } + assert(gDvm.gcHeap->cardTableBase != NULL); + memset(gDvm.gcHeap->cardTableBase, GC_CARD_CLEAN, gDvm.gcHeap->cardTableLength); } /* diff --git a/vm/alloc/Heap.cpp b/vm/alloc/Heap.cpp index 781a23969..db640a6c1 100644 --- a/vm/alloc/Heap.cpp +++ b/vm/alloc/Heap.cpp @@ -500,7 +500,6 @@ void dvmCollectGarbageInternal(const GcSpec* spec) /* Mark the set of objects that are strongly reachable from the roots. */ LOGD_HEAP("Marking..."); - dvmClearCardTable(); dvmHeapMarkRootSet(); /* dvmHeapScanMarkedObjects() will build the lists of known @@ -518,6 +517,7 @@ void dvmCollectGarbageInternal(const GcSpec* spec) * heap to allow mutator threads to allocate from free space. */ rootEnd = dvmGetRelativeTimeMsec(); + dvmClearCardTable(); dvmUnlockHeap(); dvmResumeAllThreads(SUSPEND_FOR_GC); } @@ -527,7 +527,7 @@ void dvmCollectGarbageInternal(const GcSpec* spec) * objects will also be marked. */ LOGD_HEAP("Recursing..."); - dvmHeapScanMarkedObjects(spec->isPartial); + dvmHeapScanMarkedObjects(); if (spec->isConcurrent) { /* diff --git a/vm/alloc/HeapBitmap.cpp b/vm/alloc/HeapBitmap.cpp index cf02708c7..8b6528717 100644 --- a/vm/alloc/HeapBitmap.cpp +++ b/vm/alloc/HeapBitmap.cpp @@ -129,17 +129,14 @@ void dvmHeapBitmapWalk(const HeapBitmap *bitmap, BitmapCallback *callback, * visited. */ void dvmHeapBitmapScanWalk(HeapBitmap *bitmap, - uintptr_t base, uintptr_t max, BitmapScanCallback *callback, void *arg) { assert(bitmap != NULL); assert(bitmap->bits != NULL); assert(callback != NULL); - assert(base <= max); - assert(base >= bitmap->base); - assert(max <= bitmap->max); - uintptr_t end = HB_OFFSET_TO_INDEX(max - base); - for (uintptr_t i = 0; i <= end; ++i) { + 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); diff --git a/vm/alloc/HeapBitmap.h b/vm/alloc/HeapBitmap.h index 7838eee2d..9f2a0a19f 100644 --- a/vm/alloc/HeapBitmap.h +++ b/vm/alloc/HeapBitmap.h @@ -113,7 +113,6 @@ void dvmHeapBitmapWalk(const HeapBitmap *bitmap, * address. */ void dvmHeapBitmapScanWalk(HeapBitmap *bitmap, - uintptr_t base, uintptr_t max, BitmapScanCallback *callback, void *arg); /* diff --git a/vm/alloc/HeapInternal.h b/vm/alloc/HeapInternal.h index 0d82570fe..a893bb259 100644 --- a/vm/alloc/HeapInternal.h +++ b/vm/alloc/HeapInternal.h @@ -50,10 +50,6 @@ struct GcHeap { size_t cardTableLength; size_t cardTableOffset; - /* GC's modified union table. */ - u1* modUnionTableBase; - size_t modUnionTableLength; - /* Is the GC running? Used to avoid recursive calls to GC. */ bool gcRunning; diff --git a/vm/alloc/HeapSource.cpp b/vm/alloc/HeapSource.cpp index 98c1448da..d3779d8f9 100644 --- a/vm/alloc/HeapSource.cpp +++ b/vm/alloc/HeapSource.cpp @@ -605,6 +605,8 @@ bool dvmHeapSourceStartupAfterZygote() */ bool dvmHeapSourceStartupBeforeFork() { + HeapSource *hs = gHs; // use a local to avoid the implicit "volatile" + HS_BOILERPLATE(); assert(gDvm.zygote); @@ -615,8 +617,7 @@ bool dvmHeapSourceStartupBeforeFork() */ LOGV("Splitting out new zygote heap"); gDvm.newZygoteHeapAllocated = true; - dvmClearCardTable(); - return addNewHeap(gHs); + return addNewHeap(hs); } return true; } @@ -701,8 +702,7 @@ size_t dvmHeapSourceGetValue(HeapSourceValueSpec spec, size_t perHeapStats[], return total; } -void dvmHeapSourceGetRegions(uintptr_t *base, uintptr_t *max, uintptr_t *limit, - size_t numHeaps) +void dvmHeapSourceGetRegions(uintptr_t *base, uintptr_t *max, size_t numHeaps) { HeapSource *hs = gHs; @@ -711,12 +711,7 @@ void dvmHeapSourceGetRegions(uintptr_t *base, uintptr_t *max, uintptr_t *limit, assert(numHeaps <= hs->numHeaps); for (size_t i = 0; i < numHeaps; ++i) { base[i] = (uintptr_t)hs->heaps[i].base; - if (max != NULL) { - max[i] = MIN((uintptr_t)hs->heaps[i].limit - 1, hs->markBits.max); - } - if (limit != NULL) { - limit[i] = (uintptr_t)hs->heaps[i].limit; - } + max[i] = MIN((uintptr_t)hs->heaps[i].limit - 1, hs->markBits.max); } } diff --git a/vm/alloc/HeapSource.h b/vm/alloc/HeapSource.h index d824beadf..66f2a6a21 100644 --- a/vm/alloc/HeapSource.h +++ b/vm/alloc/HeapSource.h @@ -75,8 +75,7 @@ void dvmHeapSourceShutdown(GcHeap **gcHeap); * heaps. The base and max values are suitable for passing directly * to the bitmap sweeping routine. */ -void dvmHeapSourceGetRegions(uintptr_t *base, uintptr_t *max, uintptr_t *limit, - size_t numHeaps); +void dvmHeapSourceGetRegions(uintptr_t *base, uintptr_t *max, size_t numHeaps); /* * Get the bitmap representing all live objects. diff --git a/vm/alloc/MarkSweep.cpp b/vm/alloc/MarkSweep.cpp index 3868909bd..d4f4669ba 100644 --- a/vm/alloc/MarkSweep.cpp +++ b/vm/alloc/MarkSweep.cpp @@ -22,7 +22,6 @@ #include "alloc/HeapSource.h" #include "alloc/MarkSweep.h" #include "alloc/Visit.h" -#include "alloc/VisitInlines.h" #include <limits.h> // for ULONG_MAX #include <sys/mman.h> // for madvise(), mmap() #include <errno.h> @@ -155,168 +154,6 @@ static void rootMarkObjectVisitor(void *addr, u4 thread, RootType type, } } -/* - * Visits all objects that start on the given card. - */ -static void visitCard(Visitor *visitor, u1 *card, void *arg) -{ - assert(visitor != NULL); - assert(card != NULL); - assert(dvmIsValidCard(card)); - u1 *addr= (u1*)dvmAddrFromCard(card); - u1 *limit = addr + GC_CARD_SIZE; - for (; addr < limit; addr += HB_OBJECT_ALIGNMENT) { - Object *obj = (Object *)addr; - GcMarkContext *ctx = &gDvm.gcHeap->markContext; - if (isMarked(obj, ctx)) { - (*visitor)(obj, arg); - } - } -} - -/* - * Visits objects on dirty cards marked the mod union table. - */ -static void visitModUnionTable(Visitor *visitor, u1 *base, u1 *limit, void *arg) -{ - assert(visitor != NULL); - assert(base != NULL); - assert(limit != NULL); - assert(base <= limit); - u1 *heapBase = (u1*)dvmHeapSourceGetBase(); - /* compute the start address in the bit table */ - assert(base >= heapBase); - u4 *bits = (u4*)gDvm.gcHeap->modUnionTableBase; - /* compute the end address in the bit table */ - size_t byteLength = (limit - base) / GC_CARD_SIZE / CHAR_BIT; - assert(byteLength <= gDvm.gcHeap->modUnionTableLength); - assert(byteLength % sizeof(*bits) == 0); - size_t wordLength = byteLength / sizeof(*bits); - for (size_t i = 0; i < wordLength; ++i) { - if (bits[i] == 0) { - continue; - } - u4 word = bits[i]; - bits[i] = 0; - for (size_t j = 0; j < sizeof(u4)*CHAR_BIT; ++j) { - if (word & (1 << j)) { - /* compute the base of the card */ - size_t offset = (i*sizeof(u4)*CHAR_BIT + j) * GC_CARD_SIZE; - u1* addr = heapBase + offset; - u1* card = dvmCardFromAddr(addr); - /* visit all objects on the card */ - visitCard(visitor, card, arg); - } - } - } -} - -/* - * Visits objects on dirty cards marked in the card table. - */ -static void visitCardTable(Visitor *visitor, u1 *base, u1 *limit, void *arg) -{ - assert(visitor != NULL); - assert(base != NULL); - assert(limit != NULL); - u1 *start = dvmCardFromAddr(base); - u1 *end = dvmCardFromAddr(limit); - while (start < end) { - u1 *dirty = (u1 *)memchr(start, GC_CARD_DIRTY, end - start); - if (dirty == NULL) { - break; - } - assert(dirty >= start); - assert(dirty <= end); - assert(dvmIsValidCard(dirty)); - visitCard(visitor, dirty, arg); - start = dirty + 1; - } -} - -struct ScanImmuneObjectContext { - Object *threatenBoundary; - Object *currObject; -}; - -/* - * Marks the referent of an immune object it is threatened. - */ -static void scanImmuneObjectReferent(void *addr, void *arg) -{ - assert(addr != NULL); - assert(arg != NULL); - Object *obj = *(Object **)addr; - ScanImmuneObjectContext *ctx = (ScanImmuneObjectContext *)arg; - if (obj == NULL) { - return; - } - if (obj >= ctx->threatenBoundary) { - /* TODO: set a bit in the mod union table instead. */ - dvmMarkCard(ctx->currObject); - markObjectNonNull(obj, &gDvm.gcHeap->markContext, false); - } -} - -/* - * This function is poorly named, as is its callee. - */ -static void scanImmuneObject(void *addr, void *arg) -{ - ScanImmuneObjectContext *ctx = (ScanImmuneObjectContext *)arg; - Object *obj = (Object *)addr; - ctx->currObject = obj; - visitObject(scanImmuneObjectReferent, obj, arg); -} - -/* - * Verifies that immune objects have their referents marked. - */ -static void verifyImmuneObjectsVisitor(void *addr, void *arg) -{ - assert(addr != NULL); - assert(arg != NULL); - Object *obj = *(Object **)addr; - GcMarkContext *ctx = (GcMarkContext *)arg; - if (obj == NULL || obj < (Object *)ctx->immuneLimit) { - return; - } - assert(dvmIsValidObject(obj)); - if (!isMarked(obj, ctx)) { - LOGE("Immune reference %p points to a white threatened object %p", - addr, obj); - dvmAbort(); - } -} - -/* - * Visitor that searches for immune objects and verifies that all - * threatened referents are marked. - */ -static void verifyImmuneObjectsCallback(Object *obj, void *arg) -{ - assert(obj != NULL); - assert(arg != NULL); - GcMarkContext *ctx = (GcMarkContext *)arg; - if (obj->clazz == NULL) { - LOGI("uninitialized object @ %p (has null clazz pointer)", obj); - return; - } - if (obj < (Object *)ctx->immuneLimit) { - visitObject(verifyImmuneObjectsVisitor, obj, ctx); - } -} - -/* - * Verify that immune objects refer to marked objects. - */ -static void verifyImmuneObjects() -{ - const HeapBitmap *bitmap = dvmHeapSourceGetLiveBits(); - GcMarkContext *ctx = &gDvm.gcHeap->markContext; - dvmHeapBitmapWalk(bitmap, verifyImmuneObjectsCallback, ctx); -} - /* Mark the set of root objects. * * Things we need to scan: @@ -341,10 +178,6 @@ static void verifyImmuneObjects() * - Native stack (for in-progress stuff in the VM) * - The TrackedAlloc stuff watches all native VM references. */ - -/* - * Blackens the root set. - */ void dvmHeapMarkRootSet() { GcHeap *gcHeap = gDvm.gcHeap; @@ -622,9 +455,7 @@ static void scanObject(const Object *obj, GcMarkContext *ctx) { assert(obj != NULL); assert(obj->clazz != NULL); - assert(ctx != NULL); - assert(isMarked(obj, ctx)); - if (dvmIsClassObject(obj)) { + if (obj->clazz == gDvm.classJavaLangClass) { scanClassObject(obj, ctx); } else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) { scanArrayObject(obj, ctx); @@ -649,34 +480,101 @@ static void processMarkStack(GcMarkContext *ctx) } } +static size_t objectSize(const Object *obj) +{ + assert(dvmIsValidObject(obj)); + assert(dvmIsValidObject((Object *)obj->clazz)); + if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) { + return dvmArrayObjectSize((ArrayObject *)obj); + } else if (obj->clazz == gDvm.classJavaLangClass) { + return dvmClassObjectSize((ClassObject *)obj); + } else { + return obj->clazz->objectSize; + } +} + /* - * Blackens gray objects found on dirty cards. + * Scans forward to the header of the next marked object between start + * and limit. Returns NULL if no marked objects are in that region. */ -static void scanGrayObjects(GcMarkContext *ctx) +static Object *nextGrayObject(const u1 *base, const u1 *limit, + const HeapBitmap *markBits) { - assert(ctx != NULL); - assert(ctx->bitmap != NULL); - HeapBitmap *bitmap = ctx->bitmap; - u1 *base = (u1 *)bitmap->base; - u1 *limit = (u1 *)ALIGN_UP(bitmap->max, GC_CARD_SIZE); - visitCardTable((Visitor *)scanObject, base, limit, ctx); + const u1 *ptr; + + assert(base < limit); + assert(limit - base <= GC_CARD_SIZE); + for (ptr = base; ptr < limit; ptr += HB_OBJECT_ALIGNMENT) { + if (dvmHeapBitmapIsObjectBitSet(markBits, ptr)) + return (Object *)ptr; + } + return NULL; } /* - * Iterate through the immune objects and mark their referents. Uses - * the mod union table to save scanning time. + * Scans range of dirty cards between start and end. A range of dirty + * cards is composed consecutively dirty cards or dirty cards spanned + * by a gray object. Returns the address of a clean card if the scan + * reached a clean card or NULL if the scan reached the end. */ -void dvmHeapScanImmuneObjects(const GcMarkContext *ctx) +const u1 *scanDirtyCards(const u1 *start, const u1 *end, + GcMarkContext *ctx) { - assert(ctx != NULL); - ScanImmuneObjectContext scanCtx; - memset(&scanCtx, 0, sizeof(scanCtx)); - scanCtx.threatenBoundary = (Object*)ctx->immuneLimit; - visitModUnionTable(scanImmuneObject, - (u1*)ctx->bitmap->base, (u1*)ctx->immuneLimit, - (void *)&scanCtx); - if (gDvm.verifyCardTable) { - verifyImmuneObjects(); + const HeapBitmap *markBits = ctx->bitmap; + const u1 *card = start, *prevAddr = NULL; + while (card < end) { + if (*card != GC_CARD_DIRTY) { + return card; + } + const u1 *ptr = prevAddr ? prevAddr : (u1*)dvmAddrFromCard(card); + const u1 *limit = ptr + GC_CARD_SIZE; + while (ptr < limit) { + Object *obj = nextGrayObject(ptr, limit, markBits); + if (obj == NULL) { + break; + } + scanObject(obj, ctx); + ptr = (u1*)obj + ALIGN_UP(objectSize(obj), HB_OBJECT_ALIGNMENT); + } + if (ptr < limit) { + /* Ended within the current card, advance to the next card. */ + ++card; + prevAddr = NULL; + } else { + /* Ended past the current card, skip ahead. */ + card = dvmCardFromAddr(ptr); + prevAddr = ptr; + } + } + return NULL; +} + +/* + * Blackens gray objects found on dirty cards. + */ +static void scanGrayObjects(GcMarkContext *ctx) +{ + GcHeap *h = gDvm.gcHeap; + const u1 *base, *limit, *ptr, *dirty; + size_t footprint; + + footprint = dvmHeapSourceGetValue(HS_FOOTPRINT, NULL, 0); + base = &h->cardTableBase[0]; + limit = dvmCardFromAddr((u1 *)dvmHeapSourceGetBase() + footprint); + assert(limit <= &h->cardTableBase[h->cardTableLength]); + + ptr = base; + for (;;) { + dirty = (const u1 *)memchr(ptr, GC_CARD_DIRTY, limit - ptr); + if (dirty == NULL) { + break; + } + assert((dirty > ptr) && (dirty < limit)); + ptr = scanDirtyCards(dirty, limit, ctx); + if (ptr == NULL) { + break; + } + assert((ptr > dirty) && (ptr < limit)); } } @@ -696,32 +594,22 @@ static void scanBitmapCallback(Object *obj, void *finger, void *arg) * reachable objects. When this returns, the entire set of * live objects will be marked and the mark stack will be empty. */ -void dvmHeapScanMarkedObjects(bool isPartial) +void dvmHeapScanMarkedObjects(void) { GcMarkContext *ctx = &gDvm.gcHeap->markContext; - assert(ctx != NULL); assert(ctx->finger == NULL); - u1 *start; - if (isPartial && dvmHeapSourceGetNumHeaps() > 1) { - dvmHeapScanImmuneObjects(ctx); - start = (u1 *)ctx->immuneLimit; - } else { - start = (u1*)ctx->bitmap->base; - } - /* - * All objects reachable from the root set have a bit set in the - * mark bitmap. Walk the mark bitmap and blacken these objects. + /* The bitmaps currently have bits set for the root set. + * Walk across the bitmaps and scan each object. */ - dvmHeapBitmapScanWalk(ctx->bitmap, - (uintptr_t)start, ctx->bitmap->max, - scanBitmapCallback, - ctx); + dvmHeapBitmapScanWalk(ctx->bitmap, scanBitmapCallback, ctx); ctx->finger = (void *)ULONG_MAX; - /* Process gray objects until the mark stack it is empty. */ + /* We've walked the mark bitmaps. Scan anything that's + * left on the mark stack. + */ processMarkStack(ctx); } @@ -1034,7 +922,7 @@ void dvmHeapSweepUnmarkedObjects(bool isPartial, bool isConcurrent, size_t numHeaps, numSweepHeaps; numHeaps = dvmHeapSourceGetNumHeaps(); - dvmHeapSourceGetRegions(base, max, NULL, numHeaps); + dvmHeapSourceGetRegions(base, max, numHeaps); if (isPartial) { assert((uintptr_t)gDvm.gcHeap->markContext.immuneLimit == base[0]); numSweepHeaps = 1; diff --git a/vm/alloc/MarkSweep.h b/vm/alloc/MarkSweep.h index 94bbf439f..b14333a64 100644 --- a/vm/alloc/MarkSweep.h +++ b/vm/alloc/MarkSweep.h @@ -49,7 +49,7 @@ struct GcMarkContext { bool dvmHeapBeginMarkStep(bool isPartial); void dvmHeapMarkRootSet(void); void dvmHeapReMarkRootSet(void); -void dvmHeapScanMarkedObjects(bool isPartial); +void dvmHeapScanMarkedObjects(void); void dvmHeapReScanMarkedObjects(void); void dvmHeapProcessReferences(Object **softReferences, bool clearSoftRefs, Object **weakReferences, |
