summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gröber <dxld@darkboxed.org>2019-07-08 15:12:48 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-02-17 11:21:10 -0500
commitc3e8dd5fa3fea731a35d1c33c13fead1829ff4d2 (patch)
treecc06bf2e83764573fcfe69f57f71b7ebeb260569
parent044a53b83af3ecfb6e17a3c49a75d5b9b78dd11b (diff)
downloadhaskell-c3e8dd5fa3fea731a35d1c33c13fead1829ff4d2.tar.gz
rts: TraverseHeap: Increase lifetime of stackElements
This modifies the lifetime of stackElements such that they stay on the stack until processing of all child closures is complete. Currently the stackElement representing a set of child closures will be removed as soon as processing of the last closure _starts_. We will use this in a future commit to allow storing information on the stack which should be accumulated in a bottom-up manner along the closure parent-child relationship. Note that the lifetime increase does not apply to 'type == posTypeFresh' stack elements. This is because they will always be pushed right back onto the stack as regular stack elements anyways.
-rw-r--r--rts/TraverseHeap.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/rts/TraverseHeap.c b/rts/TraverseHeap.c
index 83cab200ae..c757c47992 100644
--- a/rts/TraverseHeap.c
+++ b/rts/TraverseHeap.c
@@ -61,7 +61,9 @@ typedef enum {
posTypeSRT,
// Keeps a new object that was not inspected yet. Keeps a parent
// element (stackPos.next.parent)
- posTypeFresh
+ posTypeFresh,
+ // This stackElement is empty
+ posTypeEmpty
} nextPosType;
typedef union {
@@ -680,10 +682,11 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
debug("traversePop(): stackTop = 0x%x\n", ts->stackTop);
- // Is this the last internal element? If so instead of modifying the current
- // stackElement in place we actually remove it from the stack.
+ // Is this the last internal sub-element?
bool last = false;
+ *c = NULL;
+
do {
if (isEmptyWorkStack(ts)) {
*c = NULL;
@@ -702,6 +705,9 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
*data = se->data;
popStackElement(ts);
return;
+ } else if (se->info.type == posTypeEmpty) {
+ popStackElement(ts);
+ continue;
}
// Note: The first ptr of all of these was already returned as
@@ -747,13 +753,10 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
// which field, and the rest of the bits indicate the
// entry number (starting from zero).
TRecEntry *entry;
- uint32_t entry_no = se->info.next.step >> 2;
- uint32_t field_no = se->info.next.step & 3;
- if (entry_no == ((StgTRecChunk *)se->c)->next_entry_idx) {
- *c = NULL;
- popStackElement(ts);
- break; // this breaks out of the switch not the loop
- }
+ StgWord step = se->info.next.step;
+ uint32_t entry_no = step >> 2;
+ uint32_t field_no = step & 3;
+
entry = &((StgTRecChunk *)se->c)->entries[entry_no];
if (field_no == 0) {
*c = (StgClosure *)entry->tvar;
@@ -762,7 +765,14 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
} else {
*c = entry->new_value;
}
- se->info.next.step++;
+
+ se->info.next.step = ++step;
+
+ entry_no = step >> 2;
+ if (entry_no == ((StgTRecChunk *)se->c)->next_entry_idx) {
+ se->info.type = posTypeEmpty;
+ continue;
+ }
goto out;
}
@@ -782,8 +792,8 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY:
*c = find_ptrs(&se->info);
if (*c == NULL) {
- popStackElement(ts);
- break; // this breaks out of the switch not the loop
+ se->info.type = posTypeEmpty;
+ continue;
}
goto out;
@@ -824,8 +834,8 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
case THUNK_1_1:
*c = find_srt(&se->info);
if(*c == NULL) {
- popStackElement(ts);
- break; // this breaks out of the switch not the loop
+ se->info.type = posTypeEmpty;
+ continue;
}
goto out;
@@ -871,7 +881,7 @@ out:
*data = se->data;
if(last)
- popStackElement(ts);
+ se->info.type = posTypeEmpty;
return;