|
@@ -4301,7 +4301,7 @@ use a standard program representation called a \emph{control flow
|
|
|
vertex is a labeled sequence of code, called a \emph{basic block}, and
|
|
|
each edge represents a jump to another block. The \key{Program}
|
|
|
construct of $C_0$ and $C_1$ contains a control flow graph represented
|
|
|
-as an alist mapping labels to basic blocks. Each block is
|
|
|
+as an alist mapping labels to basic blocks. Each basic block is
|
|
|
represented by the $\Tail$ non-terminal.
|
|
|
|
|
|
Figure~\ref{fig:explicate-control-s1-38} shows the output of the
|
|
@@ -4313,16 +4313,16 @@ Following the order of evaluation in the output of
|
|
|
\code{remove-complex-opera*}, we first have two calls to \code{(read)}
|
|
|
and then the less-than-comparison to \code{1} in the predicate of the
|
|
|
inner \key{if}. In the output of \code{explicate-control}, in the
|
|
|
-\code{start} block, this becomes two assignment statements followed by
|
|
|
-a conditional \key{goto} to either \code{block96} or
|
|
|
-\code{block97}. Each of these contains the translations of the code
|
|
|
-\code{(eq? x 0)} and \code{(eq? x 2)},
|
|
|
-respectively. Regarding \code{block96}, we start with the
|
|
|
-comparison to \code{0} and then have a conditional
|
|
|
-goto, either to \code{block92} or \code{block93}, which indirectly
|
|
|
-take us to \code{block90} and \code{block91}, the two branches of the
|
|
|
-outer \key{if}, i.e., \code{(+ y 2)} and \code{(+ y 10)}. The
|
|
|
-story for \code{block97} is similar.
|
|
|
+block labeled \code{start}, this becomes two assignment statements
|
|
|
+followed by a conditional \key{goto} to label \code{block96} or
|
|
|
+\code{block97}. The blocks associated with those labels contain the
|
|
|
+translations of the code \code{(eq? x 0)} and \code{(eq? x 2)},
|
|
|
+respectively. Regarding the block labeled with \code{block96}, we
|
|
|
+start with the comparison to \code{0} and then have a conditional
|
|
|
+goto, either to label \code{block92} or label \code{block93}, which
|
|
|
+indirectly take us to labels \code{block90} and \code{block91}, the
|
|
|
+two branches of the outer \key{if}, i.e., \code{(+ y 2)} and \code{(+
|
|
|
+ y 10)}. The story for the block labeled \code{block97} is similar.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{tabular}{lll}
|
|
@@ -4394,9 +4394,9 @@ block91:
|
|
|
The nice thing about the output of \code{explicate-control} is that
|
|
|
there are no unnecessary comparisons and every comparison is part of a
|
|
|
conditional jump. The down-side of this output is that it includes
|
|
|
-trivial blocks, such as \code{block92} through \code{block95}, that
|
|
|
-only jump to another block. We discuss a solution to this problem in
|
|
|
-Section~\ref{sec:opt-jumps}.
|
|
|
+trivial blocks, such as the blocks labeled \code{block92} through
|
|
|
+\code{block95}, that only jump to another block. We discuss a solution
|
|
|
+to this problem in Section~\ref{sec:opt-jumps}.
|
|
|
|
|
|
Recall that in Section~\ref{sec:explicate-control-r1} we implement
|
|
|
\code{explicate-control} for $R_1$ using two mutually recursive
|
|
@@ -4406,9 +4406,9 @@ later function translates expressions on the right-hand-side of a
|
|
|
\key{let}. With the addition of \key{if} expression in $R_2$ we have a
|
|
|
new kind of context to deal with: the predicate position of the
|
|
|
\key{if}. We need another function, \code{explicate-pred}, that takes
|
|
|
-an $R_2$ expression and two pieces of $C_1$ code (two $\Tail$'s) for
|
|
|
+an $R_2$ expression and two blocks (two $C_1$ $\Tail$ AST nodes) for
|
|
|
the then-branch and else-branch. The output of \code{explicate-pred}
|
|
|
-is a $C_1$ $\Tail$ and a list of formerly \key{let}-bound variables.
|
|
|
+is a block and a list of formerly \key{let}-bound variables.
|
|
|
|
|
|
Note that the three explicate functions need to construct a
|
|
|
control-flow graph, which we recommend they do via updates to a global
|
|
@@ -4421,28 +4421,37 @@ of cases for the \code{explicate-pred} function.
|
|
|
The \code{explicate-tail} function needs an additional case for
|
|
|
\key{if}. The branches of the \key{if} inherit the current context, so
|
|
|
they are in tail position. Let $B_1$ be the result of
|
|
|
-\code{explicate-tail} on the ``then'' branch of the \key{if} and $B_2$
|
|
|
-be the result of apply \code{explicate-tail} to the ``else''
|
|
|
-branch. Then the \key{if} as a whole translates to the block $B_3$
|
|
|
-which is the result of applying \code{explicate-pred} to the predicate
|
|
|
-$\itm{cnd}$ and the blocks $B_1$ and $B_2$.
|
|
|
+\code{explicate-tail} on the ``then'' branch of the \key{if}, so $B_1$
|
|
|
+is a $\Tail$ AST node. Let $B_2$ be the result of apply
|
|
|
+\code{explicate-tail} to the ``else'' branch. Finally, let $B_3$ be
|
|
|
+the $\Tail$ that results fromapplying \code{explicate-pred} to the
|
|
|
+predicate $\itm{cnd}$ and the blocks $B_1$ and $B_2$. Then the
|
|
|
+\key{if} as a whole translates to block $B_3$.
|
|
|
\[
|
|
|
(\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_3
|
|
|
\]
|
|
|
-
|
|
|
-Next we consider the case for \key{if} in the \code{explicate-assign}
|
|
|
+In the above discussion, we use the metavariables $B_1$, $B_2$, and
|
|
|
+$B_3$ to refer to blocks for the purposes of our discussion, but they
|
|
|
+should not be confused with the labels for the blocks that appear in
|
|
|
+the generated code. We initially construct unlabeled blocks; we only
|
|
|
+attach labels to blocks when we add them to the control-flow graph, as
|
|
|
+we shall see in the next case.
|
|
|
+
|
|
|
+Next consider the case for \key{if} in the \code{explicate-assign}
|
|
|
function. The context of the \key{if} is an assignment to some
|
|
|
variable $x$ and then the control continues to some block $B_1$. The
|
|
|
-code that we generate for the ``then'' and ``else'' branches needs to
|
|
|
-continue to $B_1$, so we add $B_1$ to the control flow graph with a
|
|
|
-fresh label $\ell_1$. Again, the branches of the \key{if} inherit the
|
|
|
-current context, so that are in assignment positions. Let $B_2$ be
|
|
|
-the result of applying \code{explicate-assign} to the ``then'' branch,
|
|
|
-variable $x$, and the block \GOTO{$\ell_1$}. Let $B_3$ be the result
|
|
|
-of applying \code{explicate-assign} to the ``else'' branch, variable
|
|
|
-$x$, and the block \GOTO{$\ell_1$}. The \key{if} translates to the
|
|
|
-block $B_4$ which is the result of applying \code{explicate-pred} to
|
|
|
-the predicate $\itm{cnd}$ and the blocks $B_2$ and $B_3$.
|
|
|
+code that we generate for both the ``then'' and ``else'' branches
|
|
|
+needs to continue to $B_1$, so to avoid duplicating $B_1$ we instead
|
|
|
+add it to the control flow graph with a fresh label $\ell_1$. The
|
|
|
+branches of the \key{if} inherit the current context, so that are in
|
|
|
+assignment positions. Let $B_2$ be the result of applying
|
|
|
+\code{explicate-assign} to the ``then'' branch, variable $x$, and the
|
|
|
+block \GOTO{$\ell_1$}. Let $B_3$ be the result of applying
|
|
|
+\code{explicate-assign} to the ``else'' branch, variable $x$, and the
|
|
|
+block \GOTO{$\ell_1$}. Finally, let $B_4$ be the result of applying
|
|
|
+\code{explicate-pred} to the predicate $\itm{cnd}$ and the blocks
|
|
|
+$B_2$ and $B_3$. The \key{if} as a whole translates to the block
|
|
|
+$B_4$.
|
|
|
\[
|
|
|
(\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_4
|
|
|
\]
|
|
@@ -4463,7 +4472,7 @@ translate it to the ``then'' branch $B_1$. Likewise, we translate
|
|
|
Next, suppose the expression is a less-than comparison. We translate
|
|
|
it to a conditional \code{goto}. We need labels for the two branches
|
|
|
$B_1$ and $B_2$, so we add those blocks to the control flow graph and
|
|
|
-obtain some labels $\ell_1$ and $\ell_2$. The translation of the
|
|
|
+obtain their labels $\ell_1$ and $\ell_2$. The translation of the
|
|
|
less-than comparison is as follows.
|
|
|
\[
|
|
|
(\key{<}~e_1~e_2) \quad\Rightarrow\quad
|
|
@@ -4479,7 +4488,7 @@ The case for \key{if} in \code{explicate-pred} is particularly
|
|
|
illuminating as it deals with the challenges that we discussed above
|
|
|
regarding the example of the nested \key{if} expressions. Again, we
|
|
|
add the two branches $B_1$ and $B_2$ to the control flow graph and
|
|
|
-obtain the labels $\ell_1$ and $\ell_2$. The ``then'' and ``else''
|
|
|
+obtain their labels $\ell_1$ and $\ell_2$. The ``then'' and ``else''
|
|
|
branches of the current \key{if} inherit their context from the
|
|
|
current one, that is, predicate context. So we apply
|
|
|
\code{explicate-pred} to the ``then'' branch with the two blocks
|
|
@@ -5009,6 +5018,8 @@ block7952:
|
|
|
\chapter{Tuples and Garbage Collection}
|
|
|
\label{ch:tuples}
|
|
|
|
|
|
+\margincomment{\scriptsize To do: challenge assignments: mark-and-sweep,
|
|
|
+ add simple structures. \\ --Jeremy}
|
|
|
\margincomment{\scriptsize To do: look through Andre's code comments for extra
|
|
|
things to discuss in this chapter. \\ --Jeremy}
|
|
|
\margincomment{\scriptsize To do: Flesh out this chapter, e.g., make sure
|
|
@@ -5151,10 +5162,10 @@ tuple from \code{t1}, so the result of this program is \code{42}.
|
|
|
\begin{center}
|
|
|
\begin{minipage}{0.96\textwidth}
|
|
|
\begin{lstlisting}
|
|
|
- (let ([t1 (vector 3 7)])
|
|
|
- (let ([t2 t1])
|
|
|
- (let ([_ (vector-set! t2 0 42)])
|
|
|
- (vector-ref t1 0))))
|
|
|
+(let ([t1 (vector 3 7)])
|
|
|
+ (let ([t2 t1])
|
|
|
+ (let ([_ (vector-set! t2 0 42)])
|
|
|
+ (vector-ref t1 0))))
|
|
|
\end{lstlisting}
|
|
|
\end{minipage}
|
|
|
\end{center}
|
|
@@ -5163,16 +5174,17 @@ The next issue concerns the lifetime of tuples. Of course, they are
|
|
|
created by the \code{vector} form, but when does their lifetime end?
|
|
|
Notice that $R_3$ does not include an operation for deleting
|
|
|
tuples. Furthermore, the lifetime of a tuple is not tied to any notion
|
|
|
-of static scoping. For example, the following program returns \code{3}
|
|
|
-even though the variable \code{t} goes out of scope prior to accessing
|
|
|
-the vector.
|
|
|
+of static scoping. For example, the following program returns
|
|
|
+\code{42} even though the variable \code{w} goes out of scope prior to
|
|
|
+the \code{vector-ref} that reads from the vector it was bound to.
|
|
|
\begin{center}
|
|
|
\begin{minipage}{0.96\textwidth}
|
|
|
\begin{lstlisting}
|
|
|
- (vector-ref
|
|
|
- (let ([t (vector 3 7)])
|
|
|
- t)
|
|
|
- 0)
|
|
|
+(let ([v (vector (vector 44))])
|
|
|
+ (let ([x (let ([w (vector 42)])
|
|
|
+ (let ([_ (vector-set! v 0 w)])
|
|
|
+ 0))])
|
|
|
+ (+ x (vector-ref (vector-ref v 0) 0))))
|
|
|
\end{lstlisting}
|
|
|
\end{minipage}
|
|
|
\end{center}
|
|
@@ -5235,7 +5247,6 @@ this information during type checking. The type checker in
|
|
|
Figure~\ref{fig:typecheck-R3} not only computes the type of an
|
|
|
expression, it also wraps every sub-expression $e$ with the form
|
|
|
$(\key{HasType}~e~T)$, where $T$ is $e$'s type.
|
|
|
-% TODO: UPDATE? -Jeremy
|
|
|
Subsequently, in the \code{uncover-locals} pass
|
|
|
(Section~\ref{sec:uncover-locals-r3}) this type information is
|
|
|
propagated to all variables (including the temporaries generated by
|
|
@@ -5345,19 +5356,20 @@ we will not need to revisit this issue.
|
|
|
\label{fig:copying-collector}
|
|
|
\end{figure}
|
|
|
|
|
|
-There are many alternatives to copying collectors (and their older
|
|
|
+There are many alternatives to copying collectors (and their bigger
|
|
|
siblings, the generational collectors) when its comes to garbage
|
|
|
-collection, such as mark-and-sweep and reference counting. The
|
|
|
-strengths of copying collectors are that allocation is fast (just a
|
|
|
-comparison and pointer increment), there is no fragmentation, cyclic
|
|
|
-garbage is collected, and the time complexity of collection only
|
|
|
-depends on the amount of live data, and not on the amount of
|
|
|
-garbage~\citep{Wilson:1992fk}. The main disadvantage of a two-space
|
|
|
-copying collector is that it uses a lot of space, though that problem
|
|
|
-is ameliorated in generational collectors. Racket and Scheme programs
|
|
|
-tend to allocate many small objects and generate a lot of garbage, so
|
|
|
-copying and generational collectors are a good fit. Garbage
|
|
|
-collection is an active research topic, especially concurrent garbage
|
|
|
+collection, such as mark-and-sweep~\citep{McCarthy:1960dz} and
|
|
|
+reference counting~\citep{Collins:1960aa}. The strengths of copying
|
|
|
+collectors are that allocation is fast (just a comparison and pointer
|
|
|
+increment), there is no fragmentation, cyclic garbage is collected,
|
|
|
+and the time complexity of collection only depends on the amount of
|
|
|
+live data, and not on the amount of garbage~\citep{Wilson:1992fk}. The
|
|
|
+main disadvantage of a two-space copying collector is that it uses a
|
|
|
+lot of space, though that problem is ameliorated in generational
|
|
|
+collectors. Racket and Scheme programs tend to allocate many small
|
|
|
+objects and generate a lot of garbage, so copying and generational
|
|
|
+collectors are a good fit. Garbage collection is an active research
|
|
|
+topic, especially concurrent garbage
|
|
|
collection~\citep{Tene:2011kx}. Researchers are continuously
|
|
|
developing new techniques and revisiting old
|
|
|
trade-offs~\citep{Blackburn:2004aa,Jones:2011aa,Shahriyar:2013aa,Cutler:2015aa,Shidal:2015aa,Osterlund:2016aa,Jacek:2019aa,Gamari:2020aa}. Researchers
|
|
@@ -6205,6 +6217,48 @@ _conclusion:
|
|
|
Figure~\ref{fig:R3-passes} gives an overview of all the passes needed
|
|
|
for the compilation of $R_3$.
|
|
|
|
|
|
+\section{Challenge: Simple Structures}
|
|
|
+\label{sec:simple-structures}
|
|
|
+
|
|
|
+\begin{figure}[tbp]
|
|
|
+\centering
|
|
|
+\fbox{
|
|
|
+\begin{minipage}{0.96\textwidth}
|
|
|
+\[
|
|
|
+\begin{array}{lcl}
|
|
|
+ \Type &::=& \gray{\key{Integer} \mid \key{Boolean}}
|
|
|
+ \mid (\key{Vector}\;\Type^{+}) \mid \key{Void}\\
|
|
|
+ \itm{cmp} &::= & \gray{ \key{eq?} \mid \key{<} \mid \key{<=} \mid \key{>} \mid \key{>=} } \\
|
|
|
+ \Exp &::=& \gray{ \Int \mid (\key{read}) \mid (\key{-}\;\Exp) \mid (\key{+} \; \Exp\;\Exp) \mid (\key{-}\;\Exp\;\Exp) } \\
|
|
|
+ &\mid& \gray{ \Var \mid (\key{let}~([\Var~\Exp])~\Exp) }\\
|
|
|
+ &\mid& \gray{ \key{\#t} \mid \key{\#f}
|
|
|
+ \mid (\key{and}\;\Exp\;\Exp)
|
|
|
+ \mid (\key{or}\;\Exp\;\Exp)
|
|
|
+ \mid (\key{not}\;\Exp) } \\
|
|
|
+ &\mid& \gray{ (\itm{cmp}\;\Exp\;\Exp)
|
|
|
+ \mid (\key{if}~\Exp~\Exp~\Exp) } \\
|
|
|
+ &\mid& \gray{ (\key{vector}\;\Exp^{+})
|
|
|
+ \mid (\key{vector-ref}\;\Exp\;\Int) } \\
|
|
|
+ &\mid& \gray{ (\key{vector-set!}\;\Exp\;\Int\;\Exp) }\\
|
|
|
+ &\mid& \gray{ (\key{void}) } \\
|
|
|
+ \Def &::=& (\key{struct}\; \Var \; ([\Var \,\key{:}\, \Type]^{*}))\\
|
|
|
+ R_3 &::=& \Def^{*} \; \Exp
|
|
|
+\end{array}
|
|
|
+\]
|
|
|
+\end{minipage}
|
|
|
+}
|
|
|
+\caption{The concrete syntax of $R^s_3$, extending $R_3$
|
|
|
+ (Figure~\ref{fig:r3-concrete-syntax}).}
|
|
|
+\label{fig:r3s-concrete-syntax}
|
|
|
+\end{figure}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+\section{Challenge: Generational Collection}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
\chapter{Functions}
|