]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/gc.c
cppbind.Ghost: clean up a bit
[simgear.git] / simgear / nasal / gc.c
index f3853c96efbe219cb0c8c355802b7a100c869971..a965aa79c523e3f881a9b4d3e2ad1d53b69e4239 100644 (file)
@@ -54,6 +54,7 @@ static void garbageCollect()
     }
 
     mark(globals->save);
+    mark(globals->save_hash);
     mark(globals->symbols);
     mark(globals->meRef);
     mark(globals->argRef);
@@ -88,6 +89,11 @@ void naModUnlock()
 {
     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();
 }
 
@@ -113,6 +119,15 @@ static void bottleneck()
     }
 }
 
+void naGC()
+{
+    LOCK();
+    globals->needGC = 1;
+    bottleneck();
+    UNLOCK();
+    naCheckBottleneck();
+}
+
 void naCheckBottleneck()
 {
     if(globals->bottleneck) { LOCK(); bottleneck(); UNLOCK(); }
@@ -120,12 +135,13 @@ void naCheckBottleneck()
 
 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)
@@ -140,8 +156,9 @@ static void freeelem(struct naPool* p, struct naObj* o)
     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
@@ -220,21 +237,6 @@ static void markvec(naRef r)
         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)
@@ -250,7 +252,7 @@ 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++)
@@ -264,6 +266,11 @@ static void mark(naRef r)
     }
 }
 
+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)