diff options
author | Daniel Gröber <dxld@darkboxed.org> | 2019-07-16 15:03:13 +0200 |
---|---|---|
committer | Daniel Gröber <dxld@darkboxed.org> | 2019-09-22 15:34:24 +0200 |
commit | 6118594842c942fc14846435f006c6669d28f5c0 (patch) | |
tree | 48dba00bdf7358d6b29074a4e7d7847538101abb | |
parent | 30bc0471aae90f1e977dcc4a60474ad4f8b4e31a (diff) | |
download | haskell-6118594842c942fc14846435f006c6669d28f5c0.tar.gz |
rts: TraverseHeap: Make "flip" bit flip into it's own function
Note that this commit changes the sense of the flip bit in order to allow
doing the "flip" after traverseWorkStack.
-rw-r--r-- | rts/RetainerProfile.c | 2 | ||||
-rw-r--r-- | rts/TraverseHeap.c | 38 | ||||
-rw-r--r-- | rts/TraverseHeap.h | 3 |
3 files changed, 30 insertions, 13 deletions
diff --git a/rts/RetainerProfile.c b/rts/RetainerProfile.c index 33a3b8d134..62f28ac439 100644 --- a/rts/RetainerProfile.c +++ b/rts/RetainerProfile.c @@ -407,6 +407,8 @@ computeRetainerSet( traverseState *ts ) rememberOldStableNameAddresses (); traverseWorkStack(ts, &retainVisitClosure); + + traverseInvalidateClosureData(ts); } /* ----------------------------------------------------------------------------- diff --git a/rts/TraverseHeap.c b/rts/TraverseHeap.c index 524e11513e..436941ef64 100644 --- a/rts/TraverseHeap.c +++ b/rts/TraverseHeap.c @@ -24,12 +24,17 @@ StgWord getTravData(const StgClosure *c) void setTravData(const traverseState *ts, StgClosure *c, StgWord w) { - c->header.prof.hp.trav = w | ts->flip; + c->header.prof.hp.trav = w | !ts->flip; +} + +STATIC_INLINE void invalidateTravData(const traverseState *ts, StgClosure *c) +{ + c->header.prof.hp.trav = ts->flip; } bool isTravDataValid(const traverseState *ts, const StgClosure *c) { - return (c->header.prof.hp.trav & 1) == ts->flip; + return (c->header.prof.hp.trav & 1) == !ts->flip; } typedef enum { @@ -1162,7 +1167,6 @@ resetMutableObjects(traverseState* ts) for (n = 0; n < n_capabilities; n++) { for (bd = capabilities[n]->mut_lists[g]; bd != NULL; bd = bd->link) { for (ml = bd->start; ml < bd->free; ml++) { - traverseMaybeInitClosureData(ts, (StgClosure *)*ml); } } @@ -1172,9 +1176,7 @@ resetMutableObjects(traverseState* ts) /** * Traverse all closures on the traversal work-stack, calling 'visit_cb' on each - * closure. See 'visitClosure_cb' for details. This function flips the 'flip' - * bit and hence every closure's profiling data will be reset to zero upon - * visiting. See Note [Profiling heap traversal visited bit]. + * closure. See 'visitClosure_cb' for details. */ void traverseWorkStack(traverseState *ts, visitClosure_cb visit_cb) @@ -1186,9 +1188,6 @@ traverseWorkStack(traverseState *ts, visitClosure_cb visit_cb) stackElement *sep; bool other_children; - // Now we flip the flip bit. - ts->flip = ts->flip ^ 1; - // c = Current closure (possibly tagged) // cp = Current closure's Parent (NOT tagged) // data = current closures' associated data (NOT tagged) @@ -1199,7 +1198,6 @@ loop: if (c == NULL) { debug("maxStackSize= %d\n", ts->maxStackSize); - resetMutableObjects(ts); return; } @@ -1401,6 +1399,22 @@ inner_loop: } /** + * This function flips the 'flip' bit and hence every closure's profiling data + * will be reset to zero upon visiting. See Note [Profiling heap traversal + * visited bit]. + */ +void +traverseInvalidateClosureData(traverseState* ts) +{ + // First make sure any unvisited mutable objects are valid so they're + // invalidated by the flip below + resetMutableObjects(ts); + + // Then flip the flip bit, invalidating all closures. + ts->flip = ts->flip ^ 1; +} + +/** * Traverse all static objects for which we compute retainer sets, * and reset their rs fields to NULL, which is accomplished by * invoking traverseMaybeInitClosureData(). This function must be called @@ -1444,7 +1458,7 @@ resetStaticObjectForProfiling( const traverseState *ts, StgClosure *static_objec p = (StgClosure*)*IND_STATIC_LINK(p); break; case THUNK_STATIC: - traverseMaybeInitClosureData(ts, p); + invalidateTravData(ts, p); p = (StgClosure*)*THUNK_STATIC_LINK(p); break; case FUN_STATIC: @@ -1453,7 +1467,7 @@ resetStaticObjectForProfiling( const traverseState *ts, StgClosure *static_objec case CONSTR_2_0: case CONSTR_1_1: case CONSTR_NOCAF: - traverseMaybeInitClosureData(ts, p); + invalidateTravData(ts, p); p = (StgClosure*)*STATIC_LINK(get_itbl(p), p); break; default: diff --git a/rts/TraverseHeap.h b/rts/TraverseHeap.h index 30a9c187d9..0d55f376eb 100644 --- a/rts/TraverseHeap.h +++ b/rts/TraverseHeap.h @@ -55,7 +55,7 @@ typedef struct traverseState_ { * variable, 'flip' and "flip" this variable when we want to invalidate all * objects. * - * When the visited bit is equal to the value of 'flip' the closure data + * When the visited bit is not equal to the value of 'flip' the closure data * is valid otherwise not (see isTravDataValid). We then invert the value of * 'flip' after each each profiling run (see * traverseInvalidateAllProfHeaders). @@ -162,6 +162,7 @@ bool isTravDataValid(const traverseState *ts, const StgClosure *c); void traverseWorkStack(traverseState *ts, visitClosure_cb visit_cb); void traversePushRoot(traverseState *ts, StgClosure *c, StgClosure *cp, stackData data); bool traverseMaybeInitClosureData(const traverseState* ts, StgClosure *c); +void traverseInvalidateClosureData(traverseState* ts); void initializeTraverseStack(traverseState *ts); void closeTraverseStack(traverseState *ts); |