// Visit the roots of this VM. void visitRoots(VM* vm, WBCallback callback) { callback(vm->globals); callback(vm->mainThread); // We visit all the threads, but the threads themselves (except the main thread, visited above) are not roots. // allThreads is basically a list of weakrefs to tables. for(Thread* t = vm->allThreads; t != nullptr; t = t->next) visitThread(t, callback, true); for(auto mt: vm->metaTabs) COND_CALLBACK(mt); for(auto ms: vm->metaStrings) callback(ms); COND_CALLBACK(vm->exception); callback(vm->registry); callback(vm->unhandledEx); for(auto n: vm->refTab) callback(n->value); callback(vm->location); for(auto n: vm->stdExceptions) { callback(n->key); callback(n->value); } }
/* * Visits all threads on the thread list. */ static void visitThreads(RootVisitor *visitor, void *arg) { Thread *thread; assert(visitor != NULL); dvmLockThreadList(dvmThreadSelf()); thread = gDvm.threadList; while (thread) { visitThread(visitor, thread, arg); thread = thread->next; } dvmUnlockThreadList(); }
// Dynamically dispatch the appropriate visiting method at runtime from a GCObject*. void visitObj(GCObject* o, bool isModifyPhase, WBCallback callback) { // Green objects have no references to other objects. if(GCOBJ_COLOR(o) == GCFlags_Green) return; switch(o->type) { case CrocType_Table: visitTable (cast(Table*)o, callback, isModifyPhase); return; case CrocType_Namespace: visitNamespace(cast(Namespace*)o, callback, isModifyPhase); return; case CrocType_Array: visitArray (cast(Array*)o, callback, isModifyPhase); return; case CrocType_Function: visitFunction (cast(Function*)o, callback); return; case CrocType_Funcdef: visitFuncdef (cast(Funcdef*)o, callback); return; case CrocType_Class: visitClass (cast(Class*)o, callback, isModifyPhase); return; case CrocType_Instance: visitInstance (cast(Instance*)o, callback, isModifyPhase); return; case CrocType_Thread: visitThread (cast(Thread*)o, callback, false); return; case CrocType_Upval: visitUpval (cast(Upval*)o, callback); return; default: DBGPRINT("%p %u %03x %u\n", cast(void*)o, o->type, GCOBJ_COLOR(o), o->refCount); assert(false); } }