+ * -------------------------------------------------------------------------- */
+
+void
+gcStablePtrTable( void )
+{
+ snEntry *p, *end_stable_ptr_table;
+ StgPtr q;
+
+ end_stable_ptr_table = &stable_ptr_table[SPT_size];
+
+ // NOTE: _starting_ at index 1; index 0 is unused.
+ for (p = stable_ptr_table + 1; p < end_stable_ptr_table; p++) {
+
+ // Update the pointer to the StableName object, if there is one
+ if (p->sn_obj != NULL) {
+ p->sn_obj = isAlive(p->sn_obj);
+ }
+
+ // Internal pointers are free slots. If q == NULL, it's a
+ // stable name where the object has been GC'd, but the
+ // StableName object (sn_obj) is still alive.
+ q = p->addr;
+ if (q && (q < (P_)stable_ptr_table || q >= (P_)end_stable_ptr_table)) {
+
+ // StableNames only:
+ if (p->ref == 0) {
+ if (p->sn_obj == NULL) {
+ // StableName object is dead
+ freeStableName(p);
+ IF_DEBUG(stable, fprintf(stderr,"GC'd Stable name %d\n",
+ p - stable_ptr_table));
+ continue;
+
+ } else {
+ p->addr = (StgPtr)isAlive((StgClosure *)p->addr);
+ IF_DEBUG(stable, fprintf(stderr,"Stable name %d still alive at %p, ref %d\n", p - stable_ptr_table, p->addr, p->ref));
+ }
+ }
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Update the StablePtr/StableName hash table