}
mark(globals->save);
+ mark(globals->save_hash);
mark(globals->symbols);
mark(globals->meRef);
mark(globals->argRef);
{
LOCK();
globals->nThreads--;
+ // We might be the "last" thread needed for collection. Since
+ // we're releasing our modlock to do something else for a while,
+ // wake someone else up to do it.
+ if(globals->waitCount == globals->nThreads)
+ naSemUp(globals->sem, 1);
UNLOCK();
}
}
}
+void naGC()
+{
+ LOCK();
+ globals->needGC = 1;
+ bottleneck();
+ UNLOCK();
+ naCheckBottleneck();
+}
+
void naCheckBottleneck()
{
if(globals->bottleneck) { LOCK(); bottleneck(); UNLOCK(); }
static void naCode_gcclean(struct naCode* o)
{
- naFree(o->byteCode); o->byteCode = 0;
naFree(o->constants); o->constants = 0;
- naFree(o->argSyms); o->argSyms = 0;
- naFree(o->optArgSyms); o->optArgSyms = 0;
- naFree(o->optArgVals); o->optArgVals = 0;
- naFree(o->lineIps); o->lineIps = 0;
+}
+
+static void naCCode_gcclean(struct naCCode* c)
+{
+ if(c->fptru && c->user_data && c->destroy) c->destroy(c->user_data);
+ c->user_data = 0;
}
static void naGhost_gcclean(struct naGhost* g)
switch(p->type) {
case T_STR: naStr_gcclean ((struct naStr*) o); break;
case T_VEC: naVec_gcclean ((struct naVec*) o); break;
- case T_HASH: naHash_gcclean ((struct naHash*) o); break;
+ case T_HASH: naiGCHashClean ((struct naHash*) o); break;
case T_CODE: naCode_gcclean ((struct naCode*) o); break;
+ case T_CCODE: naCCode_gcclean((struct naCCode*)o); break;
case T_GHOST: naGhost_gcclean((struct naGhost*)o); break;
}
p->free[p->nfree++] = o; // ...and add it to the free list
mark(vr->array[i]);
}
-static void markhash(naRef r)
-{
- int i;
- struct HashRec* hr = PTR(r).hash->rec;
- if(!hr) return;
- for(i=0; i < (1<<hr->lgalloced); i++) {
- struct HashNode* hn = hr->table[i];
- while(hn) {
- mark(hn->key);
- mark(hn->val);
- hn = hn->next;
- }
- }
-}
-
// Sets the reference bit on the object, and recursively on all
// objects reachable from it. Uses the processor stack for recursion...
static void mark(naRef r)
PTR(r).obj->mark = 1;
switch(PTR(r).obj->type) {
case T_VEC: markvec(r); break;
- case T_HASH: markhash(r); break;
+ case T_HASH: naiGCMarkHash(r); break;
case T_CODE:
mark(PTR(r).code->srcFile);
for(i=0; i<PTR(r).code->nConstants; i++)
}
}
+void naiGCMark(naRef r)
+{
+ mark(r);
+}
+
// Collects all the unreachable objects into a free list, and
// allocates more space if needed.
static void reap(struct naPool* p)