Commit c0907fef authored by Daniel Gröber (dxld)'s avatar Daniel Gröber (dxld) Committed by Marge Bot

rts: TraverseHeap: Move stackElement to header

The point of this is to let user code call traversePushClosure directly
instead of going through traversePushRoot. This in turn allows specifying a
stackElement to be used when the traversal returns from a top-level (root)
closure.
parent 937feda3
......@@ -32,72 +32,6 @@ bool isTravDataValid(const traverseState *ts, const StgClosure *c)
return (c->header.prof.hp.trav & 1) == ts->flip;
}
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;
/**
* Position pointer into a closure. Determines what the next element to return
* for a stackElement is.
*/
typedef struct {
nextPosType type;
nextPos next;
} stackPos;
/**
* 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;
stackElement *sep; // stackElement of parent closure
stackData data;
stackAccum accum;
} stackElement;
#if defined(DEBUG)
unsigned int g_traversalDebugLevel = 0;
static inline void debug(const char *s, ...)
......@@ -333,7 +267,7 @@ pushStackElement(traverseState *ts, const stackElement se)
* c - closure
* data - data associated with closure.
*/
STATIC_INLINE void
inline void
traversePushClosure(traverseState *ts, StgClosure *c, StgClosure *cp, stackElement *sep, stackData data) {
stackElement se;
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment