Do not link ghc stage1 using -threaded, only for stage2 or 3
[ghc-hetmet.git] / rts / Stable.c
index a4db5cd..94a756a 100644 (file)
@@ -6,9 +6,6 @@
  *
  * ---------------------------------------------------------------------------*/
 
-// Make static versions of inline functions in Stable.h:
-#define RTS_STABLE_C
-
 #include "PosixSource.h"
 #include "Rts.h"
 #include "Hash.h"
@@ -18,6 +15,8 @@
 #include "RtsAPI.h"
 #include "RtsFlags.h"
 #include "OSThreads.h"
+#include "Trace.h"
+#include "Stable.h"
 
 /* Comment from ADR's implementation in old RTS:
 
@@ -158,8 +157,26 @@ initStablePtrTable(void)
 #endif
 }
 
+void
+exitStablePtrTable(void)
+{
+  if (addrToStableHash)
+    freeHashTable(addrToStableHash, NULL);
+  addrToStableHash = NULL;
+  if (stable_ptr_table)
+    stgFree(stable_ptr_table);
+  stable_ptr_table = NULL;
+  SPT_size = 0;
+#ifdef THREADED_RTS
+  closeMutex(&stable_mutex);
+#endif
+}
+
 /*
  * get at the real stuff...remove indirections.
+ * It untags pointers before dereferencing and
+ * retags the real stuff with its tag (if there
+ * is any) when returning.
  *
  * ToDo: move to a better home.
  */
@@ -167,7 +184,8 @@ static
 StgClosure*
 removeIndirections(StgClosure* p)
 {
-  StgClosure* q = p;
+  StgWord tag = GET_CLOSURE_TAG(p);
+  StgClosure* q = UNTAG_CLOSURE(p);
 
   while (get_itbl(q)->type == IND ||
          get_itbl(q)->type == IND_STATIC ||
@@ -175,8 +193,11 @@ removeIndirections(StgClosure* p)
          get_itbl(q)->type == IND_PERM ||
          get_itbl(q)->type == IND_OLDGEN_PERM ) {
       q = ((StgInd *)q)->indirectee;
+      tag = GET_CLOSURE_TAG(q);
+      q = UNTAG_CLOSURE(q);
   }
-  return q;
+
+  return TAG_CLOSURE(tag,q);
 }
 
 static StgWord
@@ -194,12 +215,15 @@ lookupStableName_(StgPtr p)
    */
   p = (StgPtr)removeIndirections((StgClosure*)p);
 
+  // register the untagged pointer.  This just makes things simpler.
+  p = (StgPtr)UNTAG_CLOSURE((StgClosure*)p);
+
   sn_tmp = lookupHashTable(addrToStableHash,(W_)p);
   sn = (StgWord)sn_tmp;
   
   if (sn != 0) {
     ASSERT(stable_ptr_table[sn].addr == p);
-    IF_DEBUG(stable,debugBelch("cached stable name %ld at %p\n",sn,p));
+    debugTrace(DEBUG_stable, "cached stable name %ld at %p",sn,p);
     return sn;
   } else {
     sn = stable_ptr_free - stable_ptr_table;
@@ -207,7 +231,7 @@ lookupStableName_(StgPtr p)
     stable_ptr_table[sn].ref = 0;
     stable_ptr_table[sn].addr = p;
     stable_ptr_table[sn].sn_obj = NULL;
-    /* IF_DEBUG(stable,debugBelch("new stable name %d at %p\n",sn,p)); */
+    /* debugTrace(DEBUG_stable, "new stable name %d at %p\n",sn,p); */
     
     /* add the new stable name to the hash table */
     insertHashTable(addrToStableHash, (W_)p, (void *)sn);
@@ -299,7 +323,7 @@ enlargeStablePtrTable(void)
  * -------------------------------------------------------------------------- */
 
 void
-markStablePtrTable(evac_fn evac)
+markStablePtrTable(evac_fn evac, void *user)
 {
     snEntry *p, *end_stable_ptr_table;
     StgPtr q;
@@ -323,7 +347,7 @@ markStablePtrTable(evac_fn evac)
 
            // if the ref is non-zero, treat addr as a root
            if (p->ref != 0) {
-               evac((StgClosure **)&p->addr);
+               evac(user, (StgClosure **)&p->addr);
            }
        }
     }
@@ -338,7 +362,7 @@ markStablePtrTable(evac_fn evac)
  * -------------------------------------------------------------------------- */
 
 void
-threadStablePtrTable( evac_fn evac )
+threadStablePtrTable( evac_fn evac, void *user )
 {
     snEntry *p, *end_stable_ptr_table;
     StgPtr q;
@@ -348,12 +372,12 @@ threadStablePtrTable( evac_fn evac )
     for (p = stable_ptr_table+1; p < end_stable_ptr_table; p++) {
        
        if (p->sn_obj != NULL) {
-           evac((StgClosure **)&p->sn_obj);
+           evac(user, (StgClosure **)&p->sn_obj);
        }
 
        q = p->addr;
        if (q && (q < (P_)stable_ptr_table || q >= (P_)end_stable_ptr_table)) {
-           evac((StgClosure **)&p->addr);
+           evac(user, (StgClosure **)&p->addr);
        }
     }
 }
@@ -399,13 +423,15 @@ gcStablePtrTable( void )
                if (p->sn_obj == NULL) {
                    // StableName object is dead
                    freeStableName(p);
-                   IF_DEBUG(stable, debugBelch("GC'd Stable name %ld\n", 
-                                               p - stable_ptr_table));
+                   debugTrace(DEBUG_stable, "GC'd Stable name %ld",
+                              (long)(p - stable_ptr_table));
                    continue;
                    
                } else {
                  p->addr = (StgPtr)isAlive((StgClosure *)p->addr);
-                   IF_DEBUG(stable, debugBelch("Stable name %ld still alive at %p, ref %ld\n", p - stable_ptr_table, p->addr, p->ref));
+                 debugTrace(DEBUG_stable, 
+                            "stable name %ld still alive at %p, ref %ld\n",
+                            (long)(p - stable_ptr_table), p->addr, p->ref);
                }
            }
        }