void MarkObject(Object* obj) { if(obj->marked) return; if(obj->type == OBJ_NATIVE) { if(obj->native.onMark) obj->native.onMark(obj->native.value); } if(obj->type == OBJ_ARRAY) { for(int i = 0; i < obj->array.length; ++i) { Object* mem = obj->array.members[i]; if(mem) MarkObject(mem); } } if(obj->type == OBJ_DICT) { for(int i = 0; i < obj->dict.capacity; ++i) { DictNode* node = obj->dict.buckets[i]; while(node) { MarkObject(node->value); node = node->next; } } } obj->marked = 1; }
static void MarkChildren(JSTracer *trc, types::TypeObject *type) { if (!type->singleton) { unsigned count = type->getPropertyCount(); for (unsigned i = 0; i < count; i++) { types::Property *prop = type->getProperty(i); if (prop) MarkId(trc, &prop->id, "type_prop"); } } if (type->proto) MarkObject(trc, &type->proto, "type_proto"); if (type->singleton && !type->lazy()) MarkObject(trc, &type->singleton, "type_singleton"); if (type->newScript) { MarkObject(trc, &type->newScript->fun, "type_new_function"); MarkShape(trc, &type->newScript->shape, "type_new_shape"); } if (type->interpretedFunction) MarkObject(trc, &type->interpretedFunction, "type_function"); }
void MarkObject(Object const &Q, bool M) { if (!Q.Exists()) return; MarkObject(Q.GetStorageBase(), M); }
void MarkAllObjects(EObjectMark Marks) { for( FObjectIterator It; It; ++It ) { MarkObject(*It,Marks); } }
void MarkAll(VM* vm) { for(int i = 0; i < vm->stackSize; ++i) { Object* reachable = vm->stack[i]; if(reachable) MarkObject(reachable); } }
void Registry::MarkAll(StorageBase &root, bool marked) { MarkObject(root, marked); const Dictionary &dict = root.GetDictionary(); Dictionary::const_iterator C = dict.begin(), D = dict.end(); for (; C != D; ++C) { Object const &child = C->second; StorageBase *base = GetStorageBase(child.GetHandle()); if (base == 0) continue; if (base->IsManaged()) MarkObject(*base, marked); if (base->GetSwitches() & IObject::NoRecurse) continue; MarkAll(*base, marked); } }
void MarkObjectAndChildren(StorageBase &Q, bool M) { MarkObject(Q, M); Dictionary::const_iterator A = Q.GetDictionary().begin(), B = Q.GetDictionary().end(); for (; A != B; ++A) { Object &child = const_cast<Object &>(A->second); if (child.GetHandle() == Q.GetHandle()) // HACK to sorta/kinda avoid cycles :/ continue; MarkObjectAndChildren(child, M); } }
void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain) { SQVM *vms = _thread(_root_vm); vms->Mark(tchain); _refs_table.Mark(tchain); MarkObject(_registry,tchain); MarkObject(_consts,tchain); MarkObject(_metamethodsmap,tchain); MarkObject(_table_default_delegate,tchain); MarkObject(_array_default_delegate,tchain); MarkObject(_string_default_delegate,tchain); MarkObject(_number_default_delegate,tchain); MarkObject(_generator_default_delegate,tchain); MarkObject(_thread_default_delegate,tchain); MarkObject(_closure_default_delegate,tchain); MarkObject(_class_default_delegate,tchain); MarkObject(_instance_default_delegate,tchain); MarkObject(_weakref_default_delegate,tchain); }
SQInteger SQSharedState::CollectGarbage(SQVM *vm) { SQInteger n=0; SQCollectable *tchain=NULL; SQVM *vms = _thread(_root_vm); vms->Mark(&tchain); SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); _refs_table.Mark(&tchain); MarkObject(_registry,&tchain); MarkObject(_consts,&tchain); MarkObject(_metamethodsmap,&tchain); MarkObject(_table_default_delegate,&tchain); MarkObject(_array_default_delegate,&tchain); MarkObject(_string_default_delegate,&tchain); MarkObject(_number_default_delegate,&tchain); MarkObject(_generator_default_delegate,&tchain); MarkObject(_thread_default_delegate,&tchain); MarkObject(_closure_default_delegate,&tchain); MarkObject(_class_default_delegate,&tchain); MarkObject(_instance_default_delegate,&tchain); MarkObject(_weakref_default_delegate,&tchain); SQCollectable *t = _gc_chain; SQCollectable *nx = NULL; while(t) { t->_uiRef++; t->Finalize(); nx = t->_next; if(--t->_uiRef == 0) t->Release(); t = nx; n++; } t = tchain; while(t) { t->UnMark(); t = t->_next; } _gc_chain = tchain; SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed(); assert(z == x); return n; }