Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
GHC
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Gesh
GHC
Commits
7dabad36
Commit
7dabad36
authored
27 years ago
by
Simon Marlow
Browse files
Options
Downloads
Patches
Plain Diff
[project @ 1997-10-06 12:43:32 by simonm]
outstanding changes
parent
c37cc193
Loading
Loading
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
docs/rts/rts.verb
+96
-40
96 additions, 40 deletions
docs/rts/rts.verb
with
96 additions
and
40 deletions
docs/rts/rts.verb
+
96
−
40
View file @
7dabad36
...
...
@@ -743,59 +743,108 @@ May have to revert black holes - ouch!
@
\section{Switching Worlds}
\label{sect:switching-worlds}
Because this is a combined compiled/interpreted system, the
interpreter will sometimes encounter compiled code, and vice-versa.
All world-switches go via the scheduler, ensuring that the world is in
a known state ready to enter either compiled code or the interpreter.
When a thread is run from the scheduler, the @whatNext@ field is
checked to find out how to execute the thread.
\begin{itemize}
\item If @whatNext@ is set to @RunGHC@, we load up the required
registers from the TSO and jump to the address at the top of the user
stack.
\item If @whatNext@ is set to @RunHugs@, we execute the byte-code
object pointed to by the top word of the stack.
\end{itemize}
Sometimes instead of returning to the address at the top of the stack,
we need to enter a closure instead. This is achieved by pushing a
pointer to the closure to be entered on the stack, followed by a
pointer to a canned code sequence called @ghc_entertop@, or the dual
byte-code object @hugs_entertop@. Both code sequences do the following:
\begin{itemize}
\item pop the top word (either @ghc_entertop@ or @hugs_entertop@) from
the stack.
\item pop the next word off the stack and enter it.
\end{itemize}
There are six cases we need to consider:
\begin{enumerate}
\item A GHC thread enters a Hugs-built
thunk
.
\item A GHC thread enters a Hugs-built
closure
.
\item A GHC thread calls a Hugs-compiled function.
\item A GHC thread returns to a Hugs-compiled return address.
\item A Hugs thread enters a GHC-built
thunk
.
\item A Hugs thread enters a GHC-built
closure
.
\item A Hugs thread calls a GHC-compiled function.
\item A Hugs thread returns to a Hugs-compiled return address.
\end{enumerate}
\subsection{A GHC thread enters a Hugs-built thunk}
We now examine the various cases one by one and describe how the
switch happens in each situation.
\subsection{A GHC thread enters a Hugs-built closure}
A Hugs-built
thunk
look
s
like this:
A
ll
Hugs-built
closures
look like this:
\begin{center}
\begin{tabular}{|l|l|}
\hline
\emph{Hugs} & \emph{Hugs-specific
information
} \\
\hline
\emph{Hugs} & \emph{Hugs-specific
payload
} \\
\hline
\end{tabular}
\end{center}
\noindent where \emph{Hugs} is a pointer to a small
statically-
compiled
piece of code that does the following:
\noindent where \emph{Hugs} is a pointer to a small
statically
compiled
-
piece of code that does the following:
\begin{itemize}
\item Push the address of th
e
thunk on the stack.
\item Push @entertop@ on the stack.
\item Push the address of th
is
thunk on the stack.
\item Push @
hugs_
entertop@ on the stack.
\item Save the current state of the thread in the TSO.
\item Return to the scheduler, with the @whatNext@ field set to
@RunHugs@.
\item Return to the scheduler, with @whatNext@ set to @RunHugs@.
\end{itemize}
\noindent where @entertop@ is a small statically-compiled piece of
code that does the following:
\ToDo{What about static thunks? If all code lives on the heap, we'll
need an extra level of indirection for GHC references to Hugs
closures.}
\subsection{A GHC thread calls a Hugs-compiled function}
In order to call the fast entry point for a function, GHC needs arity
information from the defining module's interface file. Hugs doesn't
supply this information, so GHC will always call the slow entry point
for functions in Hugs-compiled modules.
When a GHC module is linked into a running system, the calls to
external Hugs-compiled functions will be resolved to point to
dynamically-generated code that does the following:
\begin{itemize}
\item pop the return address from the stack.
\item pop the next word off the stack into \Arg{1}.
\item enter \Arg{1}.
\item Push a pointer to the Hugs byte code object for the function on
the stack.
\item Push @hugs_entertop@ on the stack.
\item Save the current thread state in the TSO.
\item Return to the scheduler with @whatNext@ set to @RunHugs@
\end{itemize}
The infotable for @entertop@ has some byte-codes attached that do
essentially the same thing if the code is entered from Hugs.
Ok, but how does Hugs find the byte code object for the function?
These live on the heap, and can therefore move around. One solution
is to use a jump table, where each element in the table has two
elements:
\subsection{A GHC thread calls a Hugs-compiled function}
\begin{itemize}
\item A call instruction pointing to the code fragment above.
\item A pointer to the byte-code object for the function.
\end{itemize}
How do we do this?
When GHC jumps to the address in the jump table, the call takes it to
the statically-compiled code fragment, leaving a pointer to a pointer
to the byte-code object on the C stack, which can then be retrieved.
\subsection{A GHC thread returns to a Hugs-compiled return address}
...
...
@@ -807,37 +856,35 @@ When Hugs pushes return addresses on the stack, they look like this:
| | -----> bytecode object
|_______________|
| | _____
|_______________| |
___ GHC-friendly return code
_____
| |
| |
Info Table
|____|
. .
|_______________| |
|
_____
|
| |
Info Table
|
| |
|_____\ |____| hugs_return
/
. .
. . Code
. .
@
If GHC is returning, it will return to the address at the top of the
stack. The code at this address
stack. This address a pointer to a statically compiled code fragment
called @hugs_return@, which:
\begin{itemize}
\item pops the return address off the user stack.
\item saves the thread state in the TSO
\item returns to the scheduler with
a
@whatNext@
field of
@RunHugs@.
\item returns to the scheduler with @whatNext@
set to
@RunHugs@.
\end{itemize}
If Hugs is returning to one of these addresses, it can spot the
special return address at the top and instead jump to the bytecodes
pointed to by the second word on the stack.
\subsection{A Hugs thread enters a GHC-compiled thunk}
\subsection{A Hugs thread enters a GHC-compiled closure}
When Hugs is called on to enter a
non-Hugs
closure (these are
recognisable
by the lack of a \emph{Hugs} pointer at the front), the
following
sequence of instructions is executed:
When Hugs is called on to enter a
GHC
closure (these are
recognisable
by the lack of a \emph{Hugs} pointer at the front), the
following
sequence of instructions is executed:
\begin{itemize}
\item Push the address of the thunk on the stack.
\item Push @entertop@ on the stack.
\item Push @
ghc_
entertop@ on the stack.
\item Save the current state of the thread in the TSO.
\item Return to the scheduler, with the @whatNext@ field set to
@RunGHC@.
...
...
@@ -847,11 +894,20 @@ following sequence of instructions is executed:
Hugs never calls GHC-functions directly, it only enters closures
(which point to the slow entry point for the function). Hence in this
case, we just push the arguments on the stack and proceed as for a
thunk.
case, we just push the arguments on the stack and proceed as above.
\subsection{A Hugs thread returns to a GHC-compiled return address}
The return address at the top of the stack is recognisable as a
GHC-return address by virtue of not being @hugs_return@. In this
case, hugs recognises that it needs to do a world-switch and performs
the following sequence:
\begin{itemize}
\item save the state of the thread in the TSO.
\item return to the scheduler, setting @whatNext@ to @RunGHC@.
\end{itemize}
\section{Heap objects}
\label{sect:fixed-header}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment