diff options
Diffstat (limited to 'rts/TraverseHeap.h')
-rw-r--r-- | rts/TraverseHeap.h | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/rts/TraverseHeap.h b/rts/TraverseHeap.h index e24b0aae87..8ea04dee32 100644 --- a/rts/TraverseHeap.h +++ b/rts/TraverseHeap.h @@ -16,8 +16,51 @@ #include "BeginPrivate.h" +typedef enum { + // Object with fixed layout. Keeps an information about that + // element was processed. (stackPos.next.step) + posTypeStep, + // Description of the pointers-first heap object. Keeps information + // about layout. (stackPos.next.ptrs) + posTypePtrs, + // Keeps SRT bitmap (stackPos.next.srt) + posTypeSRT, + // Keeps a new object that was not inspected yet. Keeps a parent + // element (stackPos.next.parent) + posTypeFresh, + // This stackElement is empty + posTypeEmpty +} nextPosType; + +typedef union { + // fixed layout or layout specified by a field in the closure + StgWord step; + + // layout.payload + struct { + // See StgClosureInfo in InfoTables.h + StgHalfWord pos; + StgHalfWord ptrs; + StgPtr payload; + } ptrs; + + // SRT + struct { + StgClosure *srt; + } srt; + + // parent of the current closure, used only when posTypeFresh is set + StgClosure *cp; +} nextPos; -typedef struct traverseState_ traverseState; +/** + * Position pointer into a closure. Determines what the next element to return + * for a stackElement is. + */ +typedef struct stackPos_ { + nextPosType type; + nextPos next; +} stackPos; typedef union stackData_ { /** @@ -30,7 +73,24 @@ typedef union stackAccum_ { StgWord subtree_sizeW; } stackAccum; -typedef struct stackElement_ stackElement; +/** + * An element of the traversal work-stack. Besides the closure itself this also + * stores it's parent, associated data and an accumulator. + * + * When 'info.type == posTypeFresh' a 'stackElement' represents just one + * closure, namely 'c' and 'cp' being it's parent. Otherwise 'info' specifies an + * offset into the children of 'c'. This is to support returning a closure's + * children one-by-one without pushing one element per child onto the stack. See + * traverseGetChildren() and traversePop(). + * + */ +typedef struct stackElement_ { + stackPos info; + StgClosure *c; + struct stackElement_ *sep; // stackElement of parent closure + stackData data; + stackAccum accum; +} stackElement; typedef struct traverseState_ { /** Note [Profiling heap traversal visited bit] @@ -163,6 +223,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); +void traversePushClosure(traverseState *ts, StgClosure *c, StgClosure *cp, stackElement *sep, stackData data); bool traverseMaybeInitClosureData(const traverseState* ts, StgClosure *c); void traverseInvalidateClosureData(traverseState* ts); |