From 7800c097fe06c046a1f6bed8650dd546d7b7a886 Mon Sep 17 00:00:00 2001 From: Carl Shapiro Date: Tue, 11 May 2010 13:46:29 -0700 Subject: [PATCH] Two fixes to referencing processing. First, ensure the transporter allocates from blocks on the scavenger work queue. Previously, the transporter could have objects allocated in the free space of dequeued to-space blocks. When this condition occurs we unconditionally enqueue the block for re-scavenging. Second, finish the implementation of large heap table scavenging and add a verification routine for this root. Change-Id: I5a9caf4b2824673a1f532c4e215c53f64a6a4627 --- vm/alloc/Copying.c | 56 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/vm/alloc/Copying.c b/vm/alloc/Copying.c index 6792a9e2d..6742e64a3 100644 --- a/vm/alloc/Copying.c +++ b/vm/alloc/Copying.c @@ -662,9 +662,24 @@ void *dvmHeapSourceAllocAndGrow(size_t size) /* TODO: refactor along with dvmHeapSourceAlloc */ void *allocateGray(size_t size) { + HeapSource *heapSource; + void *addr; + size_t block; + /* TODO: add a check that we are in a GC. */ - /* assert(gDvm.gcHeap->heapSource->queueHead != QUEUE_TAIL); */ - return dvmHeapSourceAlloc(size); + heapSource = gDvm.gcHeap->heapSource; + addr = dvmHeapSourceAlloc(size); + block = addressToBlock(heapSource, (const u1 *)addr); + if (heapSource->queueHead == QUEUE_TAIL) { + /* + * Forcibly append the underlying block to the queue. This + * condition occurs when referents are transported following + * the initial trace. + */ + enqueueBlock(heapSource, block); + LOG_PROM("forced promoting block %zu %d @ %p", block, heapSource->blockSpace[block], addr); + } + return addr; } /* @@ -1309,7 +1324,7 @@ static void scavengeReferenceObject(Object *obj) queue = &gDvm.gcHeap->phantomReferences; } vmDataOffset = gDvm.offJavaLangRefReference_vmData; - dvmSetFieldObject(obj, vmDataOffset, (Object *)*queue); + dvmSetFieldObject(obj, vmDataOffset, *queue); *queue = obj; LOG_SCAV("scavengeReferenceObject: enqueueing %p", obj); } @@ -1687,17 +1702,32 @@ static void verifyReferenceTable(const ReferenceTable *table) LOG_VER("<<< verifyReferenceTable(table=%p)", table); } -static void scavengeLargeHeapRefTable(LargeHeapRefTable *table) +static void scavengeLargeHeapRefTable(LargeHeapRefTable *table, bool stripLowBits) { - Object **entry; + for (; table != NULL; table = table->next) { + Object **ref = table->refs.table; + for (; ref < table->refs.nextEntry; ++ref) { + if (stripLowBits) { + Object *obj = (Object *)((uintptr_t)*ref & ~3); + scavengeReference(&obj); + *ref = (Object *)((uintptr_t)obj | ((uintptr_t)*ref & 3)); + } else { + scavengeReference(ref); + } + } + } +} +static void verifyLargeHeapRefTable(LargeHeapRefTable *table, bool stripLowBits) +{ for (; table != NULL; table = table->next) { - for (entry = table->refs.table; entry < table->refs.nextEntry; ++entry) { - if ((uintptr_t)*entry & ~0x3) { - /* It's a pending reference operation. */ - assert(!"implemented"); + Object **ref = table->refs.table; + for (; ref < table->refs.nextEntry; ++ref) { + if (stripLowBits) { + dvmVerifyObject((Object *)((uintptr_t)*ref & ~3)); + } else { + dvmVerifyObject(*ref); } - scavengeReference(entry); } } } @@ -2511,10 +2541,10 @@ void dvmScavengeRoots(void) /* Needs a new name badly */ scavengeThreadList(); LOG_SCAV("Scavenging gDvm.gcHeap->referenceOperations"); - scavengeLargeHeapRefTable(gcHeap->referenceOperations); + scavengeLargeHeapRefTable(gcHeap->referenceOperations, true); LOG_SCAV("Scavenging gDvm.gcHeap->pendingFinalizationRefs"); - scavengeLargeHeapRefTable(gcHeap->pendingFinalizationRefs); + scavengeLargeHeapRefTable(gcHeap->pendingFinalizationRefs, false); LOG_SCAV("Scavenging random global stuff"); scavengeReference(&gDvm.outOfMemoryObj); @@ -2562,6 +2592,8 @@ void dvmScavengeRoots(void) /* Needs a new name badly */ /* * Verify the stack and heap. */ + verifyLargeHeapRefTable(gcHeap->referenceOperations, true); + verifyLargeHeapRefTable(gcHeap->pendingFinalizationRefs, false); verifyInternedStrings(); verifyThreadList(); verifyNewSpace(); -- 2.11.0