diff options
Diffstat (limited to 'vm/alloc/Verify.c')
-rw-r--r-- | vm/alloc/Verify.c | 199 |
1 files changed, 9 insertions, 190 deletions
diff --git a/vm/alloc/Verify.c b/vm/alloc/Verify.c index 2afb955c8..f71b0f1f0 100644 --- a/vm/alloc/Verify.c +++ b/vm/alloc/Verify.c @@ -16,23 +16,19 @@ #include "Dalvik.h" #include "alloc/HeapBitmap.h" -#include "alloc/HeapSource.h" #include "alloc/Verify.h" #include "alloc/Visit.h" /* - * Helper routine for verifyRefernce that masks low-tag bits before - * applying verification checks. TODO: eliminate the use of low-tag - * bits and move this code into verifyReference. + * Checks that the given reference points to a valid object. */ -static void verifyReferenceUnmask(const void *addr, uintptr_t mask) +static void verifyReference(void *addr, void *arg) { const Object *obj; - uintptr_t tmp; bool isValid; - tmp = (uintptr_t)*(const Object **)addr; - obj = (const Object *)(tmp & ~mask); + assert(addr != NULL); + obj = *(const Object **)addr; if (obj == NULL) { isValid = true; } else { @@ -44,22 +40,13 @@ static void verifyReferenceUnmask(const void *addr, uintptr_t mask) } } -/* - * Assertion that the given reference points to a valid object. - */ -static void verifyReference(const void *addr) -{ - verifyReferenceUnmask(addr, 0); -} - static void visitorCallback(void *addr, void *arg) { - verifyReference(addr); + verifyReference(addr, arg); } /* - * Verifies an object reference. Determines the type of the reference - * and dispatches to a specialized verification routine. + * Verifies an object reference. */ void dvmVerifyObject(const Object *obj) { @@ -75,7 +62,7 @@ static bool verifyBitmapCallback(size_t numPtrs, void **ptrs, size_t i; for (i = 0; i < numPtrs; i++) { - dvmVerifyObject(*ptrs++); + dvmVerifyObject(ptrs[i]); } return true; } @@ -91,177 +78,9 @@ void dvmVerifyBitmap(const HeapBitmap *bitmap) } /* - * Applies a verification function to all present values in the hash table. - */ -static void verifyHashTable(HashTable *table, - void (*callback)(const void *arg)) -{ - int i; - - assert(table != NULL); - assert(callback != NULL); - dvmHashTableLock(table); - for (i = 0; i < table->tableSize; ++i) { - const HashEntry *entry = &table->pEntries[i]; - if (entry->data != NULL && entry->data != HASH_TOMBSTONE) { - (*callback)(&entry->data); - } - } - dvmHashTableUnlock(table); -} - -/* - * Applies the verify routine to the given object. - */ -static void verifyStringReference(const void *arg) -{ - assert(arg != NULL); - verifyReferenceUnmask(arg, 0x1); -} - -/* - * Verifies all entries in the reference table. - */ -static void verifyReferenceTable(const ReferenceTable *table) -{ - Object **entry; - - assert(table != NULL); - for (entry = table->table; entry < table->nextEntry; ++entry) { - assert(entry != NULL); - verifyReference(entry); - } -} - -/* - * Verifies a large heap reference table. These objects are list - * heads. As such, it is valid for table to be NULL. - */ -static void verifyLargeHeapRefTable(const LargeHeapRefTable *table) -{ - for (; table != NULL; table = table->next) { - verifyReferenceTable(&table->refs); - } -} - -/* - * Verifies all stack slots. TODO: verify native methods. - */ -static void verifyThreadStack(const Thread *thread) -{ - const StackSaveArea *saveArea; - const u4 *framePtr; - - assert(thread != NULL); - framePtr = (const u4 *)thread->curFrame; - for (; framePtr != NULL; framePtr = saveArea->prevFrame) { - Method *method; - saveArea = SAVEAREA_FROM_FP(framePtr); - method = (Method *)saveArea->method; - if (method != NULL && !dvmIsNativeMethod(method)) { - const RegisterMap* pMap = dvmGetExpandedRegisterMap(method); - const u1* regVector = NULL; - int i; - - if (pMap != NULL) { - /* found map, get registers for this address */ - int addr = saveArea->xtra.currentPc - method->insns; - regVector = dvmRegisterMapGetLine(pMap, addr); - } - if (regVector == NULL) { - /* - * Either there was no register map or there is no - * info for the current PC. Perform a conservative - * scan. - */ - for (i = 0; i < method->registersSize; ++i) { - if (dvmIsValidObject((Object *)framePtr[i])) { - verifyReference(&framePtr[i]); - } - } - } else { - /* - * Precise scan. v0 is at the lowest address on the - * interpreted stack, and is the first bit in the - * register vector, so we can walk through the - * register map and memory in the same direction. - * - * A '1' bit indicates a live reference. - */ - u2 bits = 1 << 1; - for (i = 0; i < method->registersSize; ++i) { - bits >>= 1; - if (bits == 1) { - /* set bit 9 so we can tell when we're empty */ - bits = *regVector++ | 0x0100; - } - if ((bits & 0x1) != 0) { - /* - * Register is marked as live, it's a valid root. - */ - verifyReference(&framePtr[i]); - } - } - dvmReleaseRegisterMapLine(pMap, regVector); - } - } - /* - * Don't fall into an infinite loop if things get corrupted. - */ - assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr || - saveArea->prevFrame == NULL); - } -} - -/* - * Verifies all roots associated with a thread. - */ -static void verifyThread(const Thread *thread) -{ - assert(thread != NULL); - assert(thread->status != THREAD_RUNNING || - thread->isSuspended || - thread == dvmThreadSelf()); - LOGV("Entering verifyThread(thread=%p)", thread); - verifyReference(&thread->threadObj); - verifyReference(&thread->exception); - verifyReferenceTable(&thread->internalLocalRefTable); - verifyReferenceTable(&thread->jniLocalRefTable); - if (thread->jniMonitorRefTable.table) { - verifyReferenceTable(&thread->jniMonitorRefTable); - } - verifyThreadStack(thread); - LOGV("Exiting verifyThread(thread=%p)", thread); -} - -/* - * Verifies all threads on the thread list. - */ -static void verifyThreads(void) -{ - Thread *thread; - - dvmLockThreadList(dvmThreadSelf()); - thread = gDvm.threadList; - while (thread) { - verifyThread(thread); - thread = thread->next; - } - dvmUnlockThreadList(); -} - -/* - * Verifies roots. TODO: verify all roots. + * Verifies references in the roots. */ void dvmVerifyRoots(void) { - verifyHashTable(gDvm.loadedClasses, verifyReference); - verifyHashTable(gDvm.dbgRegistry, verifyReference); - verifyHashTable(gDvm.internedStrings, verifyStringReference); - verifyReferenceTable(&gDvm.jniGlobalRefTable); - verifyReferenceTable(&gDvm.jniPinRefTable); - verifyLargeHeapRefTable(gDvm.gcHeap->referenceOperations); - verifyLargeHeapRefTable(gDvm.gcHeap->pendingFinalizationRefs); - verifyThreads(); - /* TODO: verify cached global references. */ + dvmVisitRoots(verifyReference, NULL); } |