*
* ---------------------------------------------------------------------------*/
-// Make static versions of inline functions in Stable.h:
-#define RTS_STABLE_C
-
#include "PosixSource.h"
#include "Rts.h"
#include "Hash.h"
#include "RtsAPI.h"
#include "RtsFlags.h"
#include "OSThreads.h"
+#include "Trace.h"
+#include "Stable.h"
/* Comment from ADR's implementation in old RTS:
#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.
*/
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 ||
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
*/
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;
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);
* -------------------------------------------------------------------------- */
void
-markStablePtrTable(evac_fn evac)
+markStablePtrTable(evac_fn evac, void *user)
{
snEntry *p, *end_stable_ptr_table;
StgPtr q;
// if the ref is non-zero, treat addr as a root
if (p->ref != 0) {
- evac((StgClosure **)&p->addr);
+ evac(user, (StgClosure **)&p->addr);
}
}
}
* -------------------------------------------------------------------------- */
void
-threadStablePtrTable( evac_fn evac )
+threadStablePtrTable( evac_fn evac, void *user )
{
snEntry *p, *end_stable_ptr_table;
StgPtr q;
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);
}
}
}
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);
}
}
}