small tidyups and refactorings
authorSimon Marlow <marlowsd@gmail.com>
Thu, 14 Feb 2013 08:58:03 +0000 (08:58 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 14 Feb 2013 10:57:10 +0000 (10:57 +0000)
rts/Stable.c

index ff3843e..e1807fa 100644 (file)
@@ -103,41 +103,36 @@ Mutex stable_mutex;
 static void enlargeStableNameTable(void);
 static void enlargeStablePtrTable(void);
 
-/* This hash table maps Haskell objects to stable names, so that every
+/*
+ * This hash table maps Haskell objects to stable names, so that every
  * call to lookupStableName on a given object will return the same
  * stable name.
- *
- * OLD COMMENTS about reference counting follow.  The reference count
- * in a stable name entry is now just a counter.
- *
- * Reference counting
- * ------------------
- * A plain stable name entry has a zero reference count, which means
- * the entry will dissappear when the object it points to is
- * unreachable.  For stable pointers, we need an entry that sticks
- * around and keeps the object it points to alive, so each stable name
- * entry has an associated reference count.
- *
- * A stable pointer has a weighted reference count N attached to it
- * (actually in its upper 5 bits), which represents the weight
- * 2^(N-1).  The stable name entry keeps a 32-bit reference count, which
- * represents any weight between 1 and 2^32 (represented as zero).
- * When the weight is 2^32, the stable name table owns "all" of the
- * stable pointers to this object, and the entry can be garbage
- * collected if the object isn't reachable.
- *
- * A new stable pointer is given the weight log2(W/2), where W is the
- * weight stored in the table entry.  The new weight in the table is W
- * - 2^log2(W/2).
- *
- * A stable pointer can be "split" into two stable pointers, by
- * dividing the weight by 2 and giving each pointer half.
- * When freeing a stable pointer, the weight of the pointer is added
- * to the weight stored in the table entry.
- * */
+ */
 
 static HashTable *addrToStableHash = NULL;
 
+/* -----------------------------------------------------------------------------
+ * We must lock the StablePtr table during GC, to prevent simultaneous
+ * calls to freeStablePtr().
+ * -------------------------------------------------------------------------- */
+
+void
+stableLock(void)
+{
+    initStableTables();
+    ACQUIRE_LOCK(&stable_mutex);
+}
+
+void
+stableUnlock(void)
+{
+    RELEASE_LOCK(&stable_mutex);
+}
+
+/* -----------------------------------------------------------------------------
+ * Initialising the tables
+ * -------------------------------------------------------------------------- */
+
 STATIC_INLINE void
 initSnEntryFreeList(snEntry *table, nat n, snEntry *free)
 {
@@ -187,6 +182,44 @@ initStableTables(void)
 #endif
 }
 
+/* -----------------------------------------------------------------------------
+ * Enlarging the tables
+ * -------------------------------------------------------------------------- */
+
+static void
+enlargeStableNameTable(void)
+{
+    nat old_SNT_size = SNT_size;
+
+    // 2nd and subsequent times
+    SNT_size *= 2;
+    stable_name_table =
+        stgReallocBytes(stable_name_table,
+                        SNT_size * sizeof *stable_name_table,
+                        "enlargeStableNameTable");
+
+    initSnEntryFreeList(stable_name_table + old_SNT_size, old_SNT_size, NULL);
+}
+
+static void
+enlargeStablePtrTable(void)
+{
+    nat old_SPT_size = SPT_size;
+
+    // 2nd and subsequent times
+    SPT_size *= 2;
+    stable_ptr_table =
+        stgReallocBytes(stable_ptr_table,
+                        SPT_size * sizeof *stable_ptr_table,
+                        "enlargeStablePtrTable");
+
+    initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL);
+}
+
+/* -----------------------------------------------------------------------------
+ * Freeing entries and tables
+ * -------------------------------------------------------------------------- */
+
 void
 exitStableTables(void)
 {
@@ -209,6 +242,40 @@ exitStableTables(void)
 #endif
 }
 
+STATIC_INLINE void
+freeSnEntry(snEntry *sn)
+{
+  ASSERT(sn->sn_obj == NULL);
+  sn->addr = (P_)stable_name_free;
+  stable_name_free = sn;
+}
+
+STATIC_INLINE void
+freeSpEntry(spEntry *sp)
+{
+    sp->addr = (P_)stable_ptr_free;
+    stable_ptr_free = sp;
+}
+
+void
+freeStablePtrUnsafe(StgStablePtr sp)
+{
+    ASSERT((StgWord)sp < SPT_size);
+    freeSpEntry(&stable_ptr_table[(StgWord)sp]);
+}
+
+void
+freeStablePtr(StgStablePtr sp)
+{
+    stableLock();
+    freeStablePtrUnsafe(sp);
+    stableUnlock();
+}
+
+/* -----------------------------------------------------------------------------
+ * Looking up
+ * -------------------------------------------------------------------------- */
+
 /*
  * get at the real stuff...remove indirections.
  * It untags pointers before dereferencing and
@@ -235,12 +302,14 @@ removeIndirections(StgClosure* p)
   return TAG_CLOSURE(tag,q);
 }
 
-static StgWord
-lookupStableName_(StgPtr p)
+StgWord
+lookupStableName (StgPtr p)
 {
   StgWord sn;
   void* sn_tmp;
 
+  stableLock();
+
   if (stable_name_free == NULL) {
     enlargeStableNameTable();
   }
@@ -259,6 +328,7 @@ lookupStableName_(StgPtr p)
   if (sn != 0) {
     ASSERT(stable_name_table[sn].addr == p);
     debugTrace(DEBUG_stable, "cached stable name %ld at %p",sn,p);
+    stableUnlock();
     return sn;
   }
 
@@ -271,40 +341,9 @@ lookupStableName_(StgPtr p)
   /* add the new stable name to the hash table */
   insertHashTable(addrToStableHash, (W_)p, (void *)sn);
 
-  return sn;
-}
-
-StgWord
-lookupStableName(StgPtr p)
-{
-    StgWord res;
-
-    initStableTables();
-    ACQUIRE_LOCK(&stable_mutex);
-    res = lookupStableName_(p);
-    RELEASE_LOCK(&stable_mutex);
-    return res;
-}
-
-STATIC_INLINE void
-freeSnEntry(snEntry *sn)
-{
-  ASSERT(sn->sn_obj == NULL);
-  if(sn->addr != NULL) {
-      /* StableName object may die before pointee, in which case we
-       * need to remove from hash table, or after pointee, in which
-       * case addr==NULL and we already removed it. */
-      removeHashTable(addrToStableHash, (W_)sn->addr, NULL);
-  }
-  sn->addr = (P_)stable_name_free;
-  stable_name_free = sn;
-}
+  stableUnlock();
 
-STATIC_INLINE void
-freeSpEntry(spEntry *sp)
-{
-    sp->addr = (P_)stable_ptr_free;
-    stable_ptr_free = sp;
+  return sn;
 }
 
 StgStablePtr
@@ -312,80 +351,15 @@ getStablePtr(StgPtr p)
 {
   StgWord sp;
 
-  initStableTables();
-  ACQUIRE_LOCK(&stable_mutex);
+  stableLock();
   if (!stable_ptr_free) enlargeStablePtrTable();
   sp = stable_ptr_free - stable_ptr_table;
   stable_ptr_free  = (spEntry*)(stable_ptr_free->addr);
   stable_ptr_table[sp].addr = p;
-  RELEASE_LOCK(&stable_mutex);
+  stableUnlock();
   return (StgStablePtr)(sp);
 }
 
-void
-freeStablePtrUnsafe(StgStablePtr sp)
-{
-    ASSERT((StgWord)sp < SPT_size);
-    freeSpEntry(&stable_ptr_table[(StgWord)sp]);
-}
-
-void
-freeStablePtr(StgStablePtr sp)
-{
-    initStableTables();
-    ACQUIRE_LOCK(&stable_mutex);
-    freeStablePtrUnsafe(sp);
-    RELEASE_LOCK(&stable_mutex);
-}
-
-static void
-enlargeStableNameTable(void)
-{
-    nat old_SNT_size = SNT_size;
-
-    // 2nd and subsequent times
-    SNT_size *= 2;
-    stable_name_table =
-        stgReallocBytes(stable_name_table,
-                        SNT_size * sizeof *stable_name_table,
-                        "enlargeStableNameTable");
-
-    initSnEntryFreeList(stable_name_table + old_SNT_size, old_SNT_size, NULL);
-}
-
-static void
-enlargeStablePtrTable(void)
-{
-    nat old_SPT_size = SPT_size;
-
-    // 2nd and subsequent times
-    SPT_size *= 2;
-    stable_ptr_table =
-        stgReallocBytes(stable_ptr_table,
-                        SPT_size * sizeof *stable_ptr_table,
-                        "enlargeStablePtrTable");
-
-    initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL);
-}
-
-/* -----------------------------------------------------------------------------
- * We must lock the StablePtr table during GC, to prevent simultaneous
- * calls to freeStablePtr().
- * -------------------------------------------------------------------------- */
-
-void
-stableLock(void)
-{
-    initStableTables();
-    ACQUIRE_LOCK(&stable_mutex);
-}
-
-void
-stableUnlock(void)
-{
-    RELEASE_LOCK(&stable_mutex);
-}
-
 /* -----------------------------------------------------------------------------
  * Treat stable pointers as roots for the garbage collector.
  * -------------------------------------------------------------------------- */