/* * Mark phase. Mark objects that are still in use and should not be collected. */ static void mark(Ejs *ejs, int generation) { EjsModule *mp; EjsGC *gc; EjsBlock *block; EjsVar *vp, **sp, **top; int next; gc = &ejs->gc; gc->collectGeneration = generation; resetMarks(ejs); markGlobal(ejs, generation); if (ejs->result) { ejsMarkVar(ejs, NULL, ejs->result); } if (ejs->exception) { ejsMarkVar(ejs, NULL, ejs->exception); } if (ejs->exceptionArg) { ejsMarkVar(ejs, NULL, ejs->exceptionArg); } if (ejs->memoryCallback) { ejsMarkVar(ejs, NULL, (EjsVar*) ejs->memoryCallback); } if (ejs->sessions) { ejsMarkVar(ejs, NULL, (EjsVar*) ejs->sessions); } /* * Mark initializers */ for (next = 0; (mp = (EjsModule*) mprGetNextItem(ejs->modules, &next)) != 0;) { if (mp->initializer) { ejsMarkVar(ejs, NULL, (EjsVar*) mp->initializer); } } /* * Mark blocks. This includes frames and blocks. */ for (block = ejs->state->bp; block; block = block->prev) { ejsMarkVar(ejs, NULL, (EjsVar*) block); } /* * Mark the evaluation stack */ top = ejs->state->stack; for (sp = ejs->state->stackBase; sp <= top; sp++) { if ((vp = *sp) != NULL) { ejsMarkVar(ejs, NULL, vp); } } }
static void markArrayVar(Ejs *ejs, EjsVar *parent, EjsArray *ap) { EjsVar *vp; int i; mprAssert(ejsIsArray(ap)); ejsMarkObject(ejs, parent, (EjsObject*) ap); for (i = ap->length - 1; i >= 0; i--) { if ((vp = ap->data[i]) != 0) { ejsMarkVar(ejs, (EjsVar*) ap, vp); } } }
/* Mark the global object */ static void markGlobal(Ejs *ejs, int generation) { EjsGC *gc; EjsObject *obj; EjsBlock *block; EjsVar *item; MprHash *hp; int i, next; gc = &ejs->gc; obj = (EjsObject*) ejs->global; obj->var.marked = 1; if (generation == EJS_GEN_ETERNAL) { for (i = 0; i < obj->numProp; i++) { ejsMarkVar(ejs, NULL, obj->slots[i]); } for (hp = 0; (hp = mprGetNextHash(ejs->standardSpaces, hp)) != 0; ) { ejsMarkVar(ejs, NULL, (EjsVar*) hp->data); } } else { for (i = gc->firstGlobal; i < obj->numProp; i++) { ejsMarkVar(ejs, NULL, obj->slots[i]); } } block = ejs->globalBlock; if (block->prevException) { ejsMarkVar(ejs, (EjsVar*) block, (EjsVar*) block->prevException); } if (block->namespaces.length > 0) { for (next = 0; ((item = (EjsVar*) ejsGetNextItem(&block->namespaces, &next)) != 0); ) { ejsMarkVar(ejs, (EjsVar*) block, item); } } }
static void markIteratorVar(Ejs *ejs, EjsVar *parent, EjsIterator *ip) { if (ip->target) { ejsMarkVar(ejs, (EjsVar*) ip, ip->target); } }