summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2018-06-14 14:26:15 +0300
committerÖmer Sinan Ağacan <omeragacan@gmail.com>2018-06-14 14:26:45 +0300
commitf7b9456cbec62a68806a945479e539ae5a984a4e (patch)
tree01d445063c6e7bfe7d3024a9e3abe91dfda388af
parenta3c0b42ee6abe0b0fa4cf6f24a7011c5ebcb0225 (diff)
downloadhaskell-f7b9456cbec62a68806a945479e539ae5a984a4e.tar.gz
Minor refactoring and docs in selector optimisation
Reviewers: bgamari, simonmar, erikd Reviewed By: simonmar Subscribers: rwbarton, thomie, carter Differential Revision: https://phabricator.haskell.org/D4835
-rw-r--r--rts/sm/Evac.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c
index deaad27e6b..289031945d 100644
--- a/rts/sm/Evac.c
+++ b/rts/sm/Evac.c
@@ -43,7 +43,7 @@
*/
#define MAX_THUNK_SELECTOR_DEPTH 16
-static void eval_thunk_selector (StgClosure **q, StgSelector * p, bool);
+static void eval_thunk_selector (StgClosure **q, StgSelector *p, bool);
STATIC_INLINE void evacuate_large(StgPtr p);
/* -----------------------------------------------------------------------------
@@ -934,23 +934,34 @@ evacuate_BLACKHOLE(StgClosure **p)
copy(p,info,q,sizeofW(StgInd),gen_no);
}
-/* -----------------------------------------------------------------------------
- Evaluate a THUNK_SELECTOR if possible.
+/* ----------------------------------------------------------------------------
+ Update a chain of thunk selectors with the given value. All selectors in the
+ chain become IND pointing to the value, except when there is a loop (i.e.
+ the value of a THUNK_SELECTOR is the THUNK_SELECTOR itself), in that case we
+ leave the selector as-is.
+
+ p is the current selector to update. In eval_thunk_selector we make a list
+ from selectors using ((StgThunk*)p)->payload[0] for the link field and use
+ that field to traverse the chain here.
+
+ val is the final value of the selector chain.
- p points to a THUNK_SELECTOR that we want to evaluate. The
- result of "evaluating" it will be evacuated and a pointer to the
- to-space closure will be returned.
+ A chain is formed when we've got something like:
- If the THUNK_SELECTOR could not be evaluated (its selectee is still
- a THUNK, for example), then the THUNK_SELECTOR itself will be
- evacuated.
+ let x = C1 { f1 = e1 }
+ y = C2 { f2 = f1 x }
+ z = f2 y
+
+ Here the chain (p) we get when evacuating z is:
+
+ [ f2 y, f1 x ]
+
+ and val is e1.
-------------------------------------------------------------------------- */
+
static void
unchain_thunk_selectors(StgSelector *p, StgClosure *val)
{
- StgSelector *prev;
-
- prev = NULL;
while (p)
{
ASSERT(p->header.info == &stg_WHITEHOLE_info);
@@ -960,7 +971,7 @@ unchain_thunk_selectors(StgSelector *p, StgClosure *val)
// not evacuate it), so in this case val is in from-space.
// ASSERT(!HEAP_ALLOCED_GC(val) || Bdescr((P_)val)->gen_no > N || (Bdescr((P_)val)->flags & BF_EVACUATED));
- prev = (StgSelector*)((StgClosure *)p)->payload[0];
+ StgSelector *prev = (StgSelector*)((StgClosure *)p)->payload[0];
// Update the THUNK_SELECTOR with an indirection to the
// value. The value is still in from-space at this stage.
@@ -997,8 +1008,18 @@ unchain_thunk_selectors(StgSelector *p, StgClosure *val)
}
}
+/* -----------------------------------------------------------------------------
+ Evaluate a THUNK_SELECTOR if possible.
+
+ p points to a THUNK_SELECTOR that we want to evaluate.
+
+ If the THUNK_SELECTOR could not be evaluated (its selectee is still a THUNK,
+ for example), then the THUNK_SELECTOR itself will be evacuated depending on
+ the evac parameter.
+ -------------------------------------------------------------------------- */
+
static void
-eval_thunk_selector (StgClosure **q, StgSelector * p, bool evac)
+eval_thunk_selector (StgClosure **q, StgSelector *p, bool evac)
// NB. for legacy reasons, p & q are swapped around :(
{
uint32_t field;
@@ -1007,7 +1028,6 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, bool evac)
StgClosure *selectee;
StgSelector *prev_thunk_selector;
bdescr *bd;
- StgClosure *val;
prev_thunk_selector = NULL;
// this is a chain of THUNK_SELECTORs that we are going to update
@@ -1132,7 +1152,7 @@ selector_loop:
info->layout.payload.nptrs));
// Select the right field from the constructor
- val = selectee->payload[field];
+ StgClosure *val = selectee->payload[field];
#if defined(PROFILING)
// For the purposes of LDV profiling, we have destroyed
@@ -1164,6 +1184,8 @@ selector_loop:
val = ((StgInd *)val)->indirectee;
goto val_loop;
case THUNK_SELECTOR:
+ // Use payload to make a list of thunk selectors, to be
+ // used in unchain_thunk_selectors
((StgClosure*)p)->payload[0] = (StgClosure *)prev_thunk_selector;
prev_thunk_selector = p;
p = (StgSelector*)val;
@@ -1278,5 +1300,4 @@ bale_out:
copy(q,(const StgInfoTable *)info_ptr,(StgClosure *)p,THUNK_SELECTOR_sizeW(),bd->dest_no);
}
unchain_thunk_selectors(prev_thunk_selector, *q);
- return;
}