Bläddra i källkod

more progress on updating ch. 5

Jeremy Siek 9 år sedan
förälder
incheckning
e6e9b07f1e
5 ändrade filer med 224 tillägg och 202 borttagningar
  1. 224 202
      book.tex
  2. BIN
      root-stack.graffle
  3. BIN
      root-stack.pdf
  4. BIN
      tuple-rep.graffle
  5. BIN
      tuple-rep.pdf

+ 224 - 202
book.tex

@@ -3838,7 +3838,7 @@ In this chapter we study the implementation of mutable tuples (called
 computer's \emph{heap} because the lifetime of a Racket tuple is
 indefinite, that is, a tuple does not follow a stack (FIFO) discipline
 but instead lives forever from the programmer's viewpoint. Of course,
-from an implementor's viewpoint, it is important to recycle the space
+from an implementor's viewpoint, it is important to reclaim the space
 associated with tuples when they are no longer needed, which is why we
 also study \emph{garbage collection} techniques in this chapter.
 
@@ -4052,34 +4052,44 @@ ToSpace. Initially, all allocations go to the FromSpace until there is
 not enough room for the next allocation request. At that point, the
 garbage collector goes to work to make more room.
 
-A running program has direct access to registers and the procedure
-call stack, and they may contain pointers into the heap. Those
-pointers are called the \emph{root set}. In
-Figure~\ref{fig:copying-collector} there are three pointers in the
-root set, one in a register and two on the stack.%
+
+The garbage collector must be careful not to reclaim tuples that will
+be used by the program in the future. Of course, it is impossible in
+general to predict what a program will do, but we can overapproximate
+the will-be-used tuples by preserving all tuples that could be
+accessed by \emph{any} program given the current computer state.  A
+program could access any tuple whose address is in a register or on
+the procedure call stack. These addresses are called the \emph{root
+  set}. In addition, a program could access any tuple that is
+transitively reachable from the root set. Thus, it is safe for the
+garbage collector to reclaim the tuples that are not reachable in this
+way. 
 %
 \footnote{The sitation in Figure~\ref{fig:copying-collector}, with a
   cycle, cannot be created by a well-typed program in $R_3$. However,
   creating cycles will be possible once we get to $R_6$.  We design
   the garbage collector to deal with cycles to begin with, so we will
   not need to revisit this issue.}
-%
-The goal of the garbage collector is twofold:
+
+So the goal of the garbage collector is twofold:
 \begin{enumerate}
-\item preserve all objects that are reachable
-from the root set via a path of pointers, i.e., the \emph{live}
-objects, and
-\item reclaim the storage of everything else, i.e., the
-\emph{garbage}. 
+\item preserve all tuple that are reachable from the root set via a
+  path of pointers, that is, the \emph{live} tuples, and
+\item reclaim the memory of everything else, that is, the
+  \emph{garbage}.
 \end{enumerate}
-A copying collector accomplished this by copying all of the live
+A copying collector accomplishes this by copying all of the live
 objects into the ToSpace and then performs a slight of hand, treating
 the ToSpace as the new FromSpace and the old FromSpace as the new
-ToSpace. In the bottom of Figure~\ref{fig:copying-collector} you can
-see the result of the copy.  All of the live objects have been copied
-to the ToSpace in a way that preserves the pointer relationships. For
-example, the pointer in the register still points to a 2-tuple whose
-first element is a 3-tuple and second element is a 2-tuple.
+ToSpace.  In the example of Figure~\ref{fig:copying-collector}, there
+are three pointers in the root set, one in a register and two on the
+stack.  All of the live objects have been copied to the ToSpace (the
+right-hand side of Figure~\ref{fig:copying-collector}) in a way that
+preserves the pointer relationships. For example, the pointer in the
+register still points to a 2-tuple whose first element is a 3-tuple
+and second element is a 2-tuple.  There are four tuples that are not
+reachable from the root set and therefore do not get copied into the
+ToSpace.
 
 \begin{figure}[tbp]
 \centering
@@ -4103,12 +4113,12 @@ 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 two-space
 copying collectors is that they use a lot of space, though that
-problem is ameliorated in the 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.  Of
+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.  Of
 course, garbage collection is an active research topic, especially
 concurrent garbage collection~\citep{Tene:2011kx}. Researchers are
-continuously development new techniques and revisiting old
+continuously developing new techniques and revisiting old
 trade-offs~\citep{Blackburn:2004aa,Jones:2011aa,Shahriyar:2013aa,Cutler:2015aa,Shidal:2015aa}.
 
 \subsection{Graph Copying via Cheney's Algorithm}
@@ -4125,8 +4135,8 @@ have already been visited, so as to ensure termination of the
 algorithm. These search algorithms also use a data structure such as a
 stack or queue as a to-do list to keep track of the vertices that need
 to be visited. We shall use breadth-first search and a trick due to
-Cheney~\citep{Cheney:1970aa} for simultaneously representing the queue
-and copying tuples into the ToSpace.
+\citet{Cheney:1970aa} for simultaneously representing the queue and
+copying tuples into the ToSpace.
 
 Figure~\ref{fig:cheney} shows several snapshots of the ToSpace as the
 copy progresses. The queue is represented by a chunk of contiguous
@@ -4154,11 +4164,9 @@ one step of the algorithm. The algorithm continues in this way until
 the front of the queue is empty, that is, until the front catches up
 with the back.
 
-
 \begin{figure}[tbp]
 \centering \includegraphics[width=0.9\textwidth]{cheney}
-\caption{Depiction of the Cheney algorithm copying
-   the live objects.}
+\caption{Depiction of the Cheney algorithm copying the live tuples.}
 \label{fig:cheney}
 \end{figure}
 
@@ -4171,10 +4179,10 @@ representations used by our compiler. First, the garbage collector
 needs to distinguish between pointers and other kinds of data. There
 are several ways to accomplish this.
 \begin{enumerate}
-\item Attached a tag to each object that says what kind of object it
-  is~\citep{Jones:1996aa}.
-\item Store different kinds of objects in different regions of
-  memory~\citep{Steele:1977ab}.
+\item Attached a tag to each object that identifies what type of
+  object it is~\citep{McCarthy:1960dz}.
+\item Store different types of objects in different
+  regions~\citep{Steele:1977ab}.
 \item Use type information from the program to either generate
   type-specific code for collecting or to generate tables that can
   guide the
@@ -4191,19 +4199,18 @@ a relatively high implementation complexity. To keep this chapter to a
 with separate strategies used for the stack and the heap.
 
 Regarding the stack, we recommend using a separate stack for
-pointers~\citep{Siebert:2001aa,Henderson:2002aa,Baker:2009aa} , which
-we call a \emph{root stack} (a.k.a a ``shadow stack''). That is, when
-a local variable needs to be spilled and is of type \code{(Vector
+pointers~\citep{Siebert:2001aa,Henderson:2002aa,Baker:2009aa}, which
+we call a \emph{root stack} (a.k.a. ``shadow stack''). That is, when a
+local variable needs to be spilled and is of type \code{(Vector
   $\Type_1 \ldots \Type_n$)}, then we put it on the root stack instead
-of the normal procedure call stack.  Figure~\ref{fig:shadow-stack}
-reproduces the example from Figure~\ref{fig:copying-collector} and
-contrasts it with the data layout using a root stack. The root stack
-contains the two pointers from the regular stack and also the pointer
-in the second register. Prior to invoking the garbage collector, we
-shall push all pointers in local variables (resident in registers or
-spilled to the stack) onto the root stack.  After the collection, the
-pointers must be popped back into the local variables because the
-locations of the pointed-to objects will have changed.
+of the normal procedure call stack. Furthermore, we always spill
+vector-typed variables if they are live during a call to the
+collector, thereby ensuring that no pointers are in registers during a
+collection. Figure~\ref{fig:shadow-stack} reproduces the example from
+Figure~\ref{fig:copying-collector} and contrasts it with the data
+layout using a root stack. The root stack contains the two pointers
+from the regular stack and also the pointer in the second
+register. 
 
 \begin{figure}[tbp]
 \centering \includegraphics[width=0.7\textwidth]{root-stack}
@@ -4239,20 +4246,20 @@ are always zero anyways because our tuples are 8-byte aligned.)
 \label{sec:organize-gz}
 
 The implementation of the garbage collector needs to do a lot of
-bit-level data manipulation and we will need to link it with our
+bit-level data manipulation and we need to link it with our
 compiler-generated x86 code. Thus, we recommend implementing the
 garbage collector in C~\citep{Kernighan:1988nx} and putting the code
 in the \code{runtime.c} file. Figure~\ref{fig:gc-header} shows the
 interface to the garbage collector. The \code{initialize} function
 creates the FromSpace, ToSpace, and root stack. The \code{initialize}
 function is meant to be called near the beginning of \code{main},
-before the body of the program executes.  The \code{initialize}
+before the rest of the program executes.  The \code{initialize}
 function puts the address of the beginning of the FromSpace into the
 global variable \code{free\_ptr}. The global \code{fromspace\_end}
 points to the address that is 1-past the last element of the
 FromSpace. (We use half-open intervals to represent chunks of
 memory~\citep{Dijkstra:1982aa}.)  The \code{rootstack\_begin} global
-should point to the first element of the root stack.
+points to the first element of the root stack.
 
 As long as there is room left in the FromSpace, your generated code
 can allocate tuples simply by moving the \code{free\_ptr} forward.
@@ -4308,10 +4315,6 @@ succeed.
   update the root stack so that it points to the objects in the
   ToSpace, and finally to swap the global pointers for the FromSpace
   and ToSpace.
-
-  [to do: talk about the \code{copy\_vector} auxilliary
-    function. --Jeremy]
-
 \end{exercise}
 
 
@@ -4319,17 +4322,111 @@ succeed.
 \label{sec:code-generation-gc}
 
 The introduction of garbage collection has a non-trivial impact on our
-compiler passes. We introduce two new compiler passes and make
-non-trivial changes to \code{flatten} and \code{select-instructions}.
-The following program will serve as our running example.  It creates
-two tuples, one nested inside the other. Both tuples have length
-one. The example then accesses the element in the inner tuple tuple
-via two vector references.
+compiler passes. We introduce one new compiler pass called
+\code{expose-allocation} and make non-trivial changes to
+\code{type-check}, \code{flatten}, \code{select-instructions},
+\code{allocate-registers}, and \code{print-x86}.  The following
+program will serve as our running example.  It creates two tuples, one
+nested inside the other. Both tuples have length one. The example then
+accesses the element in the inner tuple tuple via two vector
+references.
 % tests/s2_17.rkt
 \begin{lstlisting}
    (vector-ref (vector-ref (vector (vector 42)) 0) 0))
 \end{lstlisting}
 
+We already discuss the changes to \code{type-check} in
+Section~\ref{sec:r3}, including the addition of \code{has-type}, so we
+proceed to discuss the new \code{expose-allocation} pass.
+
+\subsection{Expose Allocation (New)}
+\label{sec:expose-allocation}
+
+The pass \code{expose-allocation} lowers the \code{vector} creation
+form into a conditional call to the collector followed by the
+allocation.  In the following, we show the transformation for the
+\code{vector} form into a conditional \code{collect} followed by
+\code{allocate} and then the initialization of the vector.  (The
+\itm{len} is the length of the vector and \itm{bytes} is how many
+total bytes need to be allocated for the vector, which is 8 for the
+tag plus \itm{len} times 8.)
+
+\begin{lstlisting}
+  (has-type (vector |$e_0 \ldots e_{n-1}$|) |\itm{type}|)
+|$\Longrightarrow$|
+  (let ([|$x_0$| |$e_0$|]) ... (let ([|$x_{n-1}$| |$e_{n-1}$|])
+  (let ([_ (if (< (+ (global-value free_ptr) |\itm{bytes}|)
+                  (global-value fromspace_end))
+               (void)
+               (collect |\itm{bytes}|))])
+  (let ([|$v$| (allocate |\itm{len}| |\itm{type}|)])
+  (let ([_ (vector-set! |$v$| |$0$| |$x_0$|)]) ...
+  (let ([_ (vector-set! |$v$| |$n-1$| |$x_{n-1}$|)])
+     |$v$|) ... )))) ...)
+\end{lstlisting}
+(In the above, we suppressed all of the \code{has-type} forms in the
+output for the sake of readability.)
+
+The output of \code{expose-allocation} is a language that extends
+$R_3$ with the three new forms that we use above in the translation of
+\code{vector}.
+\[
+\begin{array}{lcl}
+  \Exp &::=& \cdots 
+      \mid (\key{collect} \,\itm{int}) 
+      \mid (\key{allocate} \,\itm{int}\,\itm{type}) 
+      \mid (\key{global-value} \,\itm{name}) 
+\end{array}
+\]
+
+%% The \code{expose-allocation} inserts an \code{initialize} statement at
+%% the beginning of the program which will instruct the garbage collector
+%% to set up the FromSpace, ToSpace, and all the global variables.  The
+%% two arguments of \code{initialize} specify the initial allocated space
+%% for the root stack and for the heap.
+%
+%% The \code{expose-allocation} pass annotates all of the local variables
+%% in the \code{program} form with their type.
+
+
+Figure~\ref{fig:expose-alloc-output} shows the output of the
+\code{expose-allocation} pass on our running example.
+
+\begin{figure}[tbp]
+\begin{lstlisting}
+(program (type Integer)
+ (vector-ref
+  (vector-ref
+   (let ((vecinit32990
+	  (let ([vecinit32986 42])
+	    (let ((collectret32988
+		   (if (< (+ (global-value free_ptr) 16)
+			  (global-value fromspace_end))
+		       (void)
+		       (collect 16))))
+	      (let ([alloc32985
+		     (allocate 1 (Vector Integer))])
+		(let ([initret32987
+		       (vector-set! alloc32985 0 vecinit32986)])
+		  alloc32985))))))
+     (let ([collectret32992
+	    (if (< (+ (global-value free_ptr) 16)
+                   (global-value fromspace_end))
+                (void)
+                (collect 16))])
+       (let ([alloc32989 (allocate 1 (Vector (Vector Integer)))])
+	 (let ([initret32991 (vector-set! alloc32989 0 vecinit32990)])
+	   alloc32989))))
+   0)
+  0))
+\end{lstlisting}
+\caption{Output of the \code{expose-allocation} pass, minus
+  all of the \code{has-type} forms.}
+\label{fig:expose-alloc-output}
+\end{figure}
+
+
+\clearpage
 
 \subsection{Flatten and the $C_2$ intermediate language}
 \label{sec:flatten-gc}
@@ -4343,164 +4440,89 @@ via two vector references.
 \itm{cmp} &::= & \gray{  \key{eq?} \mid \key{<} \mid \key{<=} \mid \key{>} \mid \key{>=}  } \\
 \Exp &::= & \gray{ \Arg \mid (\key{read}) \mid (\key{-}\;\Arg) \mid (\key{+} \; \Arg\;\Arg)
       \mid (\key{not}\;\Arg) \mid (\itm{cmp}\;\Arg\;\Arg)  } \\
-   &\mid& (\key{vector}\, \Arg^{+}) 
+   &\mid& (\key{allocate} \,\itm{int}\,\itm{type}) 
    \mid (\key{vector-ref}\, \Arg\, \Int)  \\
-   &\mid& (\key{vector-set!}\,\Arg\,\Int\,\Arg) \\
+   &\mid& (\key{vector-set!}\,\Arg\,\Int\,\Arg) 
+    \mid (\key{global-value} \,\itm{name}) \\
 \Stmt &::=& \gray{ \ASSIGN{\Var}{\Exp} \mid \RETURN{\Arg} } \\
       &\mid& \gray{ \IF{(\itm{cmp}\, \Arg\,\Arg)}{\Stmt^{*}}{\Stmt^{*}} } \\
-      &\mid& (\key{initialize}\,\itm{int}\,\itm{int}) \\
-      &\mid& \IF{(\key{collection-needed?}\,\itm{int})}{\Stmt^{*}}{\Stmt^{*}} \\
       &\mid& (\key{collect} \,\itm{int}) \\
-      &\mid& (\key{allocate} \,\itm{int}\,\itm{type}) \\
-      &\mid& (\key{call-live-roots}\,(\Var^{*}) \,\Stmt^{*}) \\
 C_2 & ::= & \gray{ (\key{program}\;(\Var^{*})\;(\key{type}\;\textit{type})\;\Stmt^{+}) }
 \end{array}
 \]
 \end{minipage}
 }
-\caption{The $C_2$ language, extending $C_1$ with tuples.}
+\caption{The $C_2$ language, extending $C_1$ with support for tuples.}
 \label{fig:c2-syntax}
 \end{figure}
 
-\marginpar{\tiny I don't like the collection-needed form.
-  Would it make sense to instead expose the free-ptr here?\\--Jeremy}
-
-The impact on \code{flatten} is straightforward. We add several $\Exp$
-forms for vectors. The output of \code{flatten} is a program in the
-intermediate language $C_2$, whose syntax is defined in
-Figure~\ref{fig:c2-syntax}.  Some of the forms in $C_2$ do not get
-used in \code{flatten}, but get used in upcoming passes.  The
-\code{flatten} pass should treat the new forms much like the other
-kinds of expressions. The output on our running example is shown in
-Figure~\ref{fig:flatten-gc}.
-
-\begin{figure}[tbp]
-\begin{lstlisting}
-   (program (t.1 t.2 t.3 t.4) (type Integer)
-     (assign t.1 (vector 42))
-     (assign t.2 (vector t.1))
-     (assign t.3 (vector-ref t.2 0))
-     (assign t.4 (vector-ref t.3 0))
-     (return t.4))
-\end{lstlisting}
-\caption{Output of \code{flatten} for the running example.}
-\label{fig:flatten-gc}
-\end{figure}
-
-\subsection{Expose Allocation (New)}
-\label{sec:expose-allocation}
-
-The pass \code{expose-allocation} lowers the vector creation form into
-a conditional call to the collector followed by the allocation.  In
-the following, we show the transformation for the \code{vector} form.
-The $\itm{len}$ is the length of the vector and $\itm{bytes}$ is how
-many total bytes need to be allocated for the vector, which is 8 (for
-the tag) plus $\itm{len}$ times 8.
-\begin{lstlisting}
-  (assign |$\itm{lhs}$| (vector |$e_0 \ldots e_{n-1}$|))
+The output of \code{flatten} is a program in the intermediate language
+$C_2$, whose syntax is defined in Figure~\ref{fig:c2-syntax}.  The new
+forms of $C_2$ include the expressions \key{allocate},
+\key{vector-ref}, and \key{vector-set!}, and \key{global-value} and
+the statement \code{collect}.  The \code{flatten} pass can treat these
+new forms much like the other forms.
+
+Recall that the \code{flatten} function collects all of the local
+variables so that it can decorate the \code{program} form with
+them. Also recall that we need to know the types of all the local
+variables for purposes of identifying the root set for the garbage
+collector.  Thus, we change \code{flatten} to collect not just the
+variables, but the variables and their types in the form of an
+association list.  Thanks to the \code{has-type} forms, the types are
+readily available.  For example, consider the translation of the
+\code{let} form.
+\begin{lstlisting}
+  (let ([|$x$| (has-type |\itm{rhs}| |\itm{type}|)]) |\itm{body}|)
 |$\Longrightarrow$|
-  (if (collection-needed? |$\itm{bytes}$|)
-      ((collect |$\itm{bytes}$|)) 
-      ())
-  (assign |$\itm{lhs}$| (allocate |$\itm{len}$| |$T$|))
-  (vector-set! |$\itm{lhs}$| |$0$| |$e_0$|)
-  |$\ldots$|
-  (vector-set! |$\itm{lhs}$| |$n{-}1$| |$e_{n-1}$|)
+  |\itm{body'}|
+  (|\itm{ss_1}| (assign |$x$| |\itm{rhs'}|)  |\itm{ss_2}|)
+  ((|$x$| . |\itm{type}|) |\itm{xt_1}| |\itm{xt_2}|)
 \end{lstlisting}
-
-The \code{expose-allocation} inserts an \code{initialize} statement at
-the beginning of the program which will instruct the garbage collector
-to set up the FromSpace, ToSpace, and all the global variables.  The
-two arguments of \code{initialize} specify the initial allocated space
-for the root stack and for the heap.
-%
-Finally, the \code{expose-allocation} pass
-annotates all of the local variables in the \code{program} form with
-their type.
-
-
-Figure~\ref{fig:expose-alloc-output} shows the output of the
-\code{expose-allocation} pass on our running example.  We highlight in
-red the parts of the program that were changed by the pass.
+where \itm{rhs'}, \itm{ss_1}, and \itm{xs_1} are the results of
+recursively flattening \itm{rhs} and \itm{body'}, \itm{ss_2}, and
+\itm{xs_2} are the results of recursively flattening \itm{body}.  The
+output on our running example is shown in Figure~\ref{fig:flatten-gc}.
 
 \begin{figure}[tbp]
 \begin{lstlisting}
-(program (~(t.1 . (Vector Integer))
-           (t.2 . (Vector (Vector Integer)))
-           (t.3 . (Vector Integer))
-           (t.4 . Integer)
-           (void.1 . Void)
-           (void.2 . Void)~) (type Integer)
-
-  ~(initialize 10000 10000)~
-
-  ~(if (collection-needed? 16)
-      ((collect 16))
-      ())
-  (assign t.1 (allocate 1 (Vector Integer)))
-  (assign void.1 (vector-set! t.1 0 42))~
-
-  ~(if (collection-needed? 16)
-      ((collect 16))
-      ())
-  (assign t.2 (allocate 1 (Vector (Vector Integer))))
-  (assign void.2 (vector-set! t.2 0 t.1))~
-
-  (assign t.3 (vector-ref t.2 0))
-  (assign t.4 (vector-ref t.3 0))
-  (return t.4))
+'(program
+  ((tmp33002 . Integer) (tmp33001 Vector Integer) (vecinit32990 Vector Integer)
+   (vecinit32986 . Integer) (collectret32988 . Void) (if32996 . Void)
+   (tmp32994 . Integer) (global32993 . Integer) (global32995 . Integer)
+   (alloc32985 Vector Integer) (initret32987 . Void) (collectret32992 . Void)
+   (if33000 . Void) (tmp32998 . Integer) (global32997 . Integer)
+   (global32999 . Integer) (alloc32989 Vector (Vector Integer))
+   (initret32991 . Void))
+  (type Integer)
+  (assign vecinit32986 42)
+  (assign global32993 (global-value free_ptr))
+  (assign tmp32994 (+ global32993 16))
+  (assign global32995 (global-value fromspace_end))
+  (if (< tmp32994 global32995)
+    ((assign if32996 (void)))
+    ((collect 16) (assign if32996 (void))))
+  (assign collectret32988 if32996)
+  (assign alloc32985 (allocate 1 (Vector Integer)))
+  (assign initret32987 (vector-set! alloc32985 0 vecinit32986))
+  (assign vecinit32990 alloc32985)
+  (assign global32997 (global-value free_ptr))
+  (assign tmp32998 (+ global32997 16))
+  (assign global32999 (global-value fromspace_end))
+  (if (< tmp32998 global32999)
+    ((assign if33000 (void)))
+    ((collect 16) (assign if33000 (void))))
+  (assign collectret32992 if33000)
+  (assign alloc32989 (allocate 1 (Vector (Vector Integer))))
+  (assign initret32991 (vector-set! alloc32989 0 vecinit32990))
+  (assign tmp33001 (vector-ref alloc32989 0))
+  (assign tmp33002 (vector-ref tmp33001 0))
+  (return tmp33002))
 \end{lstlisting}
-\caption{Output of the \code{expose-allocation} pass.}
-\label{fig:expose-alloc-output}
+\caption{Output of \code{flatten} for the running example.}
+\label{fig:flatten-gc}
 \end{figure}
 
-%% \subsection{Uncover Call-Live Roots (New)}
-%% \label{sec:call-live-roots}
-
-%% The goal of this pass is to discover which roots (variables of type
-%% \code{Vector}) are live during calls to the collector.  We recommend
-%% using an algorithm similar to the liveness analysis used in the
-%% register allocator.  In the next pass we shall copy these roots to and
-%% from the root stack. We extend $C_2$ again, adding a new statement
-%% form for recording the live variables that are roots.
-%% \[
-%% \begin{array}{lcl}
-%% \Stmt &::=& \ldots \mid (\key{call-live-roots}\, (\Var^{*}) \, \Stmt^{*})
-%% \end{array}
-%% \]
-
-%% Figure~\ref{fig:call-live-roots-output} shows the output of
-%% \code{uncover-call-live-roots} on the running example.  The only
-%% changes to the program are wrapping the two \code{collect} forms with
-%% the \code{call-live-roots}. For the first \code{collect} there are no
-%% live roots. For the second \code{collect}, the variable \code{t.1} is
-%% a root and it is live at that point.
-
-%% \begin{figure}[tbp]
-%% \begin{lstlisting}
-%%    (program (t.1 t.2 t.3 t.4 void.1 void.2) (type Integer)
-%%      (initialize 10000 10000)
-%%      (if (collection-needed? 16)
-%%          (~(call-live-roots () (collect 16))~) 
-%%          ())
-%%      (assign t.1 (allocate 1 (Vector Integer)))
-%%      (assign void.1 (vector-set! t.1 0 42))
-%%      (if (collection-needed? 16)
-%%          (~(call-live-roots (t.1) (collect 16))~)
-%%          ())
-%%      (assign t.2 (allocate 1 (Vector (Vector Integer))))
-%%      (assign void.2 (vector-set! t.2 0 t.1))
-%%      (assign t.3 (vector-ref t.2 0))
-%%      (assign t.4 (vector-ref t.3 0))
-%%      (return t.4))
-%% \end{lstlisting}
-%% \caption{Output of the \code{uncover-call-live-roots} pass.}
-%% \label{fig:call-live-roots-output}
-%% \end{figure}
-
-%% \marginpar{\tiny mention that we discard type information
-%%   for the local variables.\\--Jeremy}
-
 \subsection{Select Instructions}
 \label{sec:select-instructions-gc}
 
@@ -5952,20 +5974,20 @@ The type checker for $R_6$ is given in Figure~\ref{fig:typecheck-R6}.
        [`(inject ,(app recur new-e e-ty) ,ty)
         (cond
          [(equal? e-ty ty)
-          (values `(has-type (inject ,new-e ,ty) Any) 'Any)]
+          (values `(inject ,new-e ,ty) 'Any)]
          [else
           (error "inject expected ~a to have type ~a" e ty)])]
        [`(project ,(app recur new-e e-ty) ,ty)
         (cond
          [(equal? e-ty 'Any)
-          (values `(has-type (project ,new-e ,ty) ,ty) ty)]
+          (values `(project ,new-e ,ty) ty)]
          [else
           (error "project expected ~a to have type Any" e)])]
        [`(,pred ,e) #:when (set-member? type-predicates pred)
         (define-values (new-e e-ty) (recur e))
         (cond
          [(equal? e-ty 'Any)
-          (values `(has-type (,pred ,new-e) Boolean) 'Boolean)]
+          (values `(,pred ,new-e) 'Boolean)]
          [else
           (error "predicate expected arg of type Any, not" e-ty)])]
        [`(vector-ref ,(app recur e t) ,i)
@@ -5974,7 +5996,7 @@ The type checker for $R_6$ is given in Figure~\ref{fig:typecheck-R6}.
           [`(Vectorof ,t)
            (unless (exact-nonnegative-integer? i)
              (error 'type-check "invalid index ~a" i))
-           (values `(has-type (vector-ref ,e (has-type ,i Integer)) ,t) t)]
+           (values `(vector-ref ,e ,i) t)]
           [else (error "expected a vector in vector-ref, not" t)])]
        [`(vector-set! ,(app recur e-vec^ t-vec) ,i
                        ,(app recur e-arg^ t-arg))
@@ -5986,9 +6008,9 @@ The type checker for $R_6$ is given in Figure~\ref{fig:typecheck-R6}.
            (unless (equal? t t-arg)
              (error 'type-check "type mismatch in vector-set! ~a ~a" 
                     t t-arg))
-           (values `(has-type (vector-set! ,e-vec^
-                                           (has-type ,i Integer)
-                                           ,e-arg^) Void) 'Void)]
+           (values `(vector-set! ,e-vec^
+                                           ,i
+                                           ,e-arg^) 'Void)]
           [else (error 'type-check
                        "expected a vector in vector-set!, not ~a"
                        t-vec)])]

BIN
root-stack.graffle


BIN
root-stack.pdf


BIN
tuple-rep.graffle


BIN
tuple-rep.pdf