X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FStable.c;h=a2c47d785c64cd1d48c055a2e86d3af2e728edb4;hb=66579ff945831c5fc9a17c58c722ff01f2268d76;hp=813c6c8b47a904c45fd759ff0af0b53283164a20;hpb=88b35c172f9434fd98b700f706074d142914a8bb;p=ghc-hetmet.git diff --git a/rts/Stable.c b/rts/Stable.c index 813c6c8..a2c47d7 100644 --- a/rts/Stable.c +++ b/rts/Stable.c @@ -19,6 +19,7 @@ #include "RtsFlags.h" #include "OSThreads.h" #include "Trace.h" +#include "Stable.h" /* Comment from ADR's implementation in old RTS: @@ -176,6 +177,9 @@ exitStablePtrTable(void) /* * 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. */ @@ -183,7 +187,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 || @@ -191,8 +196,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 @@ -210,6 +218,9 @@ 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; @@ -315,7 +326,7 @@ enlargeStablePtrTable(void) * -------------------------------------------------------------------------- */ void -markStablePtrTable(evac_fn evac) +markStablePtrTable(evac_fn evac, void *user) { snEntry *p, *end_stable_ptr_table; StgPtr q; @@ -339,7 +350,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); } } } @@ -354,7 +365,7 @@ markStablePtrTable(evac_fn evac) * -------------------------------------------------------------------------- */ void -threadStablePtrTable( evac_fn evac ) +threadStablePtrTable( evac_fn evac, void *user ) { snEntry *p, *end_stable_ptr_table; StgPtr q; @@ -364,12 +375,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); } } }