From ab36a78a50ecff2863ea5b33cbbae3e19b72c2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Hillerstr=C3=B6m?= Date: Tue, 1 Dec 2020 23:19:09 +0000 Subject: [PATCH] Segmented stacks. --- thesis.bib | 10 +++++++++ thesis.tex | 65 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/thesis.bib b/thesis.bib index 24b1873..23c1443 100644 --- a/thesis.bib +++ b/thesis.bib @@ -2398,4 +2398,14 @@ pages = {75--90}, publisher = {{ACM}}, year = {2020} +} + +# Non-contiguous stacks +@inproceedings{Danvy87, + author = {Olivier Danvy}, + title = {Memory allocation and higher-order functions}, + booktitle = {{PLDI}}, + pages = {241--252}, + publisher = {{ACM}}, + year = {1987} } \ No newline at end of file diff --git a/thesis.tex b/thesis.tex index 83657c2..0968c1c 100644 --- a/thesis.tex +++ b/thesis.tex @@ -2232,7 +2232,7 @@ strategies and their trade-offs. For an in depth analysis the interested reader may consult the respective work of \citet{ClingerHO88} and \citet{FarvardinR20}, which contain thorough studies of implementation strategies for first-class continuations. - +% Table~\ref{tbl:ctrl-operators-impls} lists some programming languages with support for first-class control operators and their implementation strategies. @@ -2275,15 +2275,64 @@ implementation strategies. \hline \end{tabular} \caption{Some languages and their implementation strategies for continuations.}\label{tbl:ctrl-operators-impls} + \dhil{TODO: Figure out which implementation strategy Effekt uses} \end{table} % -At runtime the call stack represents the current continuation. -% -Thus continuation capture can be implemented by copying the current -stack, and continuation invocation as reinstatement of the stack. This -implementation strategy works well if continuations are captured -infrequently. A slight this implementation strategy is to defer -copying the stack until the continuation is invoked +The control stack provides a adequate runtime representation of +continuations as the contiguous sequence of activation records quite +literally represent what to do next. +% +Thus continuation capture can be implemented by making a copy of the +current stack (possibly up to some delimiter), and continuation +invocation as reinstatement of the stack. This implementation strategy +works well if continuations are captured infrequently. The MLton +implementation of Standard ML utilises this strategy~\cite{Fluet20}. +A slight variation is to defer the first copy action until the +continuation is invoked, which requires marking the stack to remember +which sequence of activation records to copy. + +Obviously, frequent continuation use on top of a stack copying +implementation can be expensive time wise as well as space wise, +because with undelimited continuations multiple copies of the stack +may be alive simultaneously. +% +Typically the prefix of copies will be identical, which suggests they +ought to be shared. One way to achieve optimal sharing is to move from +a contiguous stack to a non-contiguous stack representation, +e.g. representing the stack as a heap allocated linked list of +activation records~\cite{Danvy87}. With such a representation copying +is a constant time and space operation, because there is no need to +actually copy anything as the continuation is just a pointer into the +stack. +% +The disadvantage of this strategy is that it turns every operation +into an indirection. + +Segmented stacks provide a middle ground between contiguous stack and +non-contiguous stack representations. With this representation the +control stack is represented as a linked list of contiguous stacks +which makes it possible to only copy a segment of the stack. The +stacks grown and shrink dynamically as needed. This representation is +due to \citet{HiebDB90}. It is used by Chez Scheme, which is the +runtime that powers Racket~\cite{FlattD20}. +% +For undelimited continuations the basic idea is to create a pointer to +the current stack upon continuation capture, and then allocate a new +stack where subsequent computation happens. +% +For delimited continuations the control delimiter identify when a new +stack should be allocated. +% +A potential problem with this representation is \emph{stack + thrashing}, which is a phenomenon that occurs when a stack is being +continuously resized. +% +This problem was addressed by \citet{BruggemanWD96}, who designed a +slight variation of segmented stacks optimised for one-shot +continuations, which has been adapted by Multicore +OCaml~\cite{DolanEHMSW17}. + +\dhil{TODO: CPS and abstract machines} % \paragraph{Continuation marks}