summaryrefslogtreecommitdiff
path: root/rts/TraverseHeap.h
diff options
context:
space:
mode:
Diffstat (limited to 'rts/TraverseHeap.h')
-rw-r--r--rts/TraverseHeap.h65
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);