/* * Visits all roots associated with a thread. */ static void visitThread(Visitor *visitor, Thread *thread, void *arg) { assert(visitor != NULL); assert(thread != NULL); (*visitor)(&thread->threadObj, arg); (*visitor)(&thread->exception, arg); visitReferenceTable(visitor, &thread->internalLocalRefTable, arg); visitReferenceTable(visitor, &thread->jniLocalRefTable, arg); if (thread->jniMonitorRefTable.table) { visitReferenceTable(visitor, &thread->jniMonitorRefTable, arg); } visitThreadStack(visitor, thread, arg); }
/* * Visits roots. TODO: visit cached global references. */ void dvmVisitRoots(RootVisitor *visitor, void *arg) { assert(visitor != NULL); //u4 t0 = dvmGetRelativeTimeMsec(); #ifndef FASTIVA_PRELOAD_STATIC_INSTANCE visitHashTable(visitor, gDvm.loadedClasses, ROOT_STICKY_CLASS, arg); visitPrimitiveTypes(visitor, arg); #endif if (gDvm.dbgRegistry != NULL) { visitHashTable(visitor, gDvm.dbgRegistry, ROOT_DEBUGGER, arg); } if (gDvm.literalStrings != NULL) { visitHashTable(visitor, gDvm.literalStrings, ROOT_INTERNED_STRING, arg); } dvmLockMutex(&gDvm.jniGlobalRefLock); visitIndirectRefTable(visitor, &gDvm.jniGlobalRefTable, 0, ROOT_JNI_GLOBAL, arg); dvmUnlockMutex(&gDvm.jniGlobalRefLock); dvmLockMutex(&gDvm.jniPinRefLock); visitReferenceTable(visitor, &gDvm.jniPinRefTable, 0, ROOT_VM_INTERNAL, arg); dvmUnlockMutex(&gDvm.jniPinRefLock); visitThreads(visitor, arg); (*visitor)(&gDvm.outOfMemoryObj, 0, ROOT_VM_INTERNAL, arg); (*visitor)(&gDvm.internalErrorObj, 0, ROOT_VM_INTERNAL, arg); (*visitor)(&gDvm.noClassDefFoundErrorObj, 0, ROOT_VM_INTERNAL, arg); #ifdef FASTIVA (*visitor)(&kernelData.g_pAnnotationsList, 0, ROOT_VM_INTERNAL, arg); #endif }
/* * Visits a large heap reference table. These objects are list heads. * As such, it is valid for table to be NULL. */ static void visitLargeHeapRefTable(Visitor *visitor, LargeHeapRefTable *table, void *arg) { assert(visitor != NULL); for (; table != NULL; table = table->next) { visitReferenceTable(visitor, &table->refs, arg); } }
/* * Visits roots. TODO: visit all roots. */ void dvmVisitRoots(Visitor *visitor, void *arg) { assert(visitor != NULL); visitHashTable(visitor, gDvm.loadedClasses, arg); visitHashTable(visitor, gDvm.dbgRegistry, arg); visitHashTable(visitor, gDvm.internedStrings, arg); visitHashTable(visitor, gDvm.literalStrings, arg); visitReferenceTable(visitor, &gDvm.jniGlobalRefTable, arg); visitReferenceTable(visitor, &gDvm.jniPinRefTable, arg); visitLargeHeapRefTable(visitor, gDvm.gcHeap->referenceOperations, arg); visitLargeHeapRefTable(visitor, gDvm.gcHeap->pendingFinalizationRefs, arg); visitThreads(visitor, arg); (*visitor)(&gDvm.outOfMemoryObj, arg); (*visitor)(&gDvm.internalErrorObj, arg); (*visitor)(&gDvm.noClassDefFoundErrorObj, arg); /* TODO: visit cached global references. */ }
/* * Visits all roots associated with a thread. */ static void visitThread(RootVisitor *visitor, Thread *thread, void *arg) { u4 threadId; assert(visitor != NULL); assert(thread != NULL); threadId = thread->threadId; (*visitor)(&thread->threadObj, threadId, ROOT_THREAD_OBJECT, arg); (*visitor)(&thread->exception, threadId, ROOT_NATIVE_STACK, arg); #ifdef FASTIVA_USE_CPP_EXCEPTION (*visitor)(&thread->m_pTopHandler, threadId, ROOT_NATIVE_STACK, arg); #endif visitReferenceTable(visitor, &thread->internalLocalRefTable, threadId, ROOT_NATIVE_STACK, arg); visitIndirectRefTable(visitor, &thread->jniLocalRefTable, threadId, ROOT_JNI_LOCAL, arg); if (thread->jniMonitorRefTable.table != NULL) { visitReferenceTable(visitor, &thread->jniMonitorRefTable, threadId, ROOT_JNI_MONITOR, arg); } visitThreadStack(visitor, thread, arg); }