summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@well-typed.com>2018-07-03 19:58:37 -0400
committerBen Gamari <ben@smart-cactus.org>2019-10-18 15:26:53 -0400
commit61d2ed42f85469fd3878029944ea4b6e50687098 (patch)
tree1d9f6fc3887b2e595a932461ce063c6dae51ce93
parent697be2b6908d926bf89fcc6cd173459e29022f51 (diff)
downloadhaskell-61d2ed42f85469fd3878029944ea4b6e50687098.tar.gz
rts: Add Note explaining applicability of selector optimisation depth limit
This was slightly non-obvious so a note seems deserved.
-rw-r--r--rts/sm/Evac.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c
index 53a473d26c..666daf0e32 100644
--- a/rts/sm/Evac.c
+++ b/rts/sm/Evac.c
@@ -39,7 +39,19 @@
copy_tag(p, info, src, size, stp, tag)
#endif
-/* Used to avoid long recursion due to selector thunks
+/* Note [Selector optimisation depth limit]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * MAX_THUNK_SELECTOR_DEPTH is used to avoid long recursion of
+ * eval_thunk_selector due to nested selector thunks. Note that this *only*
+ * counts nested selector thunks, e.g. `fst (fst (... (fst x)))`. The collector
+ * will traverse interleaved selector-constructor pairs without limit, e.g.
+ *
+ * a = (fst b, _)
+ * b = (fst c, _)
+ * c = (fst d, _)
+ * d = (x, _)
+ *
*/
#define MAX_THUNK_SELECTOR_DEPTH 16
@@ -1257,6 +1269,7 @@ selector_loop:
// recursively evaluate this selector. We don't want to
// recurse indefinitely, so we impose a depth bound.
+ // See Note [Selector optimisation depth limit].
if (gct->thunk_selector_depth >= MAX_THUNK_SELECTOR_DEPTH) {
goto bale_out;
}