/* Mark the set of root objects. * * Things we need to scan: * - System classes defined by root classloader * - For each thread: * - Interpreted stack, from top to "curFrame" * - Dalvik registers (args + local vars) * - JNI local references * - Automatic VM local references (TrackedAlloc) * - Associated Thread/VMThread object * - ThreadGroups (could track & start with these instead of working * upward from Threads) * - Exception currently being thrown, if present * - JNI global references * - Interned string table * - Primitive classes * - Special objects * - gDvm.outOfMemoryObj * - Objects allocated with ALLOC_NO_GC * - Objects pending finalization (but not yet finalized) * - Objects in debugger object registry * * Don't need: * - Native stack (for in-progress stuff in the VM) * - The TrackedAlloc stuff watches all native VM references. */ void dvmHeapMarkRootSet() { GcHeap *gcHeap = gDvm.gcHeap; HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_STICKY_CLASS, 0); LOG_SCAN("immune objects"); dvmMarkImmuneObjects(gcHeap->markContext.immuneLimit); LOG_SCAN("root class loader\n"); dvmGcScanRootClassLoader(); LOG_SCAN("primitive classes\n"); dvmGcScanPrimitiveClasses(); /* dvmGcScanRootThreadGroups() sets a bunch of * different scan states internally. */ HPROF_CLEAR_GC_SCAN_STATE(); LOG_SCAN("root thread groups\n"); dvmGcScanRootThreadGroups(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_INTERNED_STRING, 0); LOG_SCAN("interned strings\n"); dvmGcScanInternedStrings(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_GLOBAL, 0); LOG_SCAN("JNI global refs\n"); dvmGcMarkJniGlobalRefs(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_REFERENCE_CLEANUP, 0); LOG_SCAN("pending reference operations\n"); dvmHeapMarkLargeTableRefs(gcHeap->referenceOperations); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_FINALIZING, 0); LOG_SCAN("pending finalizations\n"); dvmHeapMarkLargeTableRefs(gcHeap->pendingFinalizationRefs); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_DEBUGGER, 0); LOG_SCAN("debugger refs\n"); dvmGcMarkDebuggerRefs(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_VM_INTERNAL, 0); /* Mark any special objects we have sitting around. */ LOG_SCAN("special objects\n"); dvmMarkObjectNonNull(gDvm.outOfMemoryObj); dvmMarkObjectNonNull(gDvm.internalErrorObj); dvmMarkObjectNonNull(gDvm.noClassDefFoundErrorObj); //TODO: scan object references sitting in gDvm; use pointer begin & end HPROF_CLEAR_GC_SCAN_STATE(); }
/* Mark the set of root objects. * * Things we need to scan: * - System classes defined by root classloader * - For each thread: * - Interpreted stack, from top to "curFrame" * - Dalvik registers (args + local vars) * - JNI local references * - Automatic VM local references (TrackedAlloc) * - Associated Thread/VMThread object * - ThreadGroups (could track & start with these instead of working * upward from Threads) * - Exception currently being thrown, if present * - JNI global references * - Interned string table * - Primitive classes * - Special objects * - gDvm.outOfMemoryObj * - Objects allocated with ALLOC_NO_GC * - Objects pending finalization (but not yet finalized) * - Objects in debugger object registry * * Don't need: * - Native stack (for in-progress stuff in the VM) * - The TrackedAlloc stuff watches all native VM references. */ void dvmHeapMarkRootSet() { HeapRefTable *refs; GcHeap *gcHeap; Object **op; gcHeap = gDvm.gcHeap; HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_STICKY_CLASS, 0); LOG_SCAN("root class loader\n"); dvmGcScanRootClassLoader(); LOG_SCAN("primitive classes\n"); dvmGcScanPrimitiveClasses(); /* dvmGcScanRootThreadGroups() sets a bunch of * different scan states internally. */ HPROF_CLEAR_GC_SCAN_STATE(); LOG_SCAN("root thread groups\n"); dvmGcScanRootThreadGroups(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_INTERNED_STRING, 0); LOG_SCAN("interned strings\n"); dvmGcScanInternedStrings(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_GLOBAL, 0); LOG_SCAN("JNI global refs\n"); dvmGcMarkJniGlobalRefs(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_REFERENCE_CLEANUP, 0); LOG_SCAN("pending reference operations\n"); dvmHeapMarkLargeTableRefs(gcHeap->referenceOperations, true); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_FINALIZING, 0); LOG_SCAN("pending finalizations\n"); dvmHeapMarkLargeTableRefs(gcHeap->pendingFinalizationRefs, false); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_DEBUGGER, 0); LOG_SCAN("debugger refs\n"); dvmGcMarkDebuggerRefs(); HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_VM_INTERNAL, 0); /* Mark all ALLOC_NO_GC objects. */ LOG_SCAN("ALLOC_NO_GC objects\n"); refs = &gcHeap->nonCollectableRefs; op = refs->table; while ((uintptr_t)op < (uintptr_t)refs->nextEntry) { dvmMarkObjectNonNull(*(op++)); } /* Mark any special objects we have sitting around. */ LOG_SCAN("special objects\n"); dvmMarkObjectNonNull(gDvm.outOfMemoryObj); dvmMarkObjectNonNull(gDvm.internalErrorObj); //TODO: scan object references sitting in gDvm; use pointer begin & end HPROF_CLEAR_GC_SCAN_STATE(); }