|
# GHC Commentary: The Code Generator
|
|
CONVERSION ERROR
|
|
|
|
|
|
[compiler/codeGen](/trac/ghc/browser/ghc/compiler/codeGen)
|
|
Error: HttpError (HttpExceptionRequest Request {
|
|
|
|
host = "ghc.haskell.org"
|
|
## Storage manager representations
|
|
port = 443
|
|
|
|
secure = True
|
|
|
|
requestHeaders = []
|
|
The code generator needs to know the layout of heap objects, because it generates code that accesses and constructs those heap objects. The runtime also needs to know about the layout of heap objects, because it contains the garbage collector. How can we share the definition of storage layout such that the code generator and the runtime both have access to it, and so that we don't have to keep two independent definitions in sync?
|
|
path = "/trac/ghc/wiki/Commentary/Compiler/CodeGen"
|
|
|
|
queryString = "?version=5"
|
|
|
|
method = "GET"
|
|
Currently we solve the problem this way:
|
|
proxy = Nothing
|
|
|
|
rawBody = False
|
|
- C types representing heap objects are defined in the C header files, see for example [includes/Closures.h](/trac/ghc/browser/ghc/includes/Closures.h).
|
|
redirectCount = 10
|
|
|
|
responseTimeout = ResponseTimeoutDefault
|
|
- A C program, [includes/mkDerivedConstants.c](/trac/ghc/browser/ghc/includes/mkDerivedConstants.c), `#includes` the runtime headers.
|
|
requestVersion = HTTP/1.1
|
|
This program is built and run when you type `make` or `make boot` in `includes/`. It is
|
|
}
|
|
run twice: once to generate `includes\DerivedConstants.h`, and again to generate
|
|
(StatusCodeException (Response {responseStatus = Status {statusCode = 403, statusMessage = "Forbidden"}, responseVersion = HTTP/1.1, responseHeaders = [("Date","Sun, 10 Mar 2019 07:03:55 GMT"),("Server","Apache/2.2.22 (Debian)"),("Strict-Transport-Security","max-age=63072000; includeSubDomains"),("Vary","Accept-Encoding"),("Content-Encoding","gzip"),("Content-Length","261"),("Content-Type","text/html; charset=iso-8859-1")], responseBody = (), responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}) "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>403 Forbidden</title>\n</head><body>\n<h1>Forbidden</h1>\n<p>You don't have permission to access /trac/ghc/wiki/Commentary/Compiler/CodeGen\non this server.</p>\n<hr>\n<address>Apache/2.2.22 (Debian) Server at ghc.haskell.org Port 443</address>\n</body></html>\n"))
|
|
`includes/GHCConstants.h`.
|
|
|
|
|
|
Original source:
|
|
- The file `DerivedConstants.h` contains lots of `#defines` like this:
|
|
|
|
|
|
```trac
|
|
```wiki
|
|
|
|
#define OFFSET_StgTSO_why_blocked 18
|
|
|
|
```
|
|
= GHC Commentary: The Code Generator =
|
|
|
|
|
|
which says that the offset to the why_blocked field of an `StgTSO` is 18 bytes. This file
|
|
[[GhcFile(compiler/codeGen)]]
|
|
is `#included` into [includes/Cmm.h](/trac/ghc/browser/ghc/includes/Cmm.h), so these offests are available to the
|
|
|
|
[hand-written .cmm files](commentary/rts/cmm).
|
|
See [wiki:Commentary/Rts/Storage The Storage Manager] for the [wiki:Commentary/Rts/Storage/Stack Layout of the stack].
|
|
|
|
|
|
- The file `GHCConstants.h` contains similar definitions:
|
|
|
|
|
|
== Storage manager representations ==
|
|
```wiki
|
|
|
|
oFFSET_StgTSO_why_blocked = 18::Int
|
|
The code generator needs to know the layout of heap objects, because it generates code that accesses and constructs those heap objects. The runtime also needs to know about the layout of heap objects, because it contains the garbage collector. How can we share the definition of storage layout such that the code generator and the runtime both have access to it, and so that we don't have to keep two independent definitions in sync?
|
|
```
|
|
|
|
|
|
Currently we solve the problem this way:
|
|
This time the definitions are in Haskell syntax, and this file is `#included` directly into
|
|
|
|
[compiler/main/Constants.lhs](/trac/ghc/browser/ghc/compiler/main/Constants.lhs). This is the way that these offsets are made
|
|
* C types representing heap objects are defined in the C header files, see for example [[GhcFile(includes/Closures.h)]].
|
|
available to GHC's code generator.
|
|
|
|
|
|
* A C program, [[GhcFile(includes/mkDerivedConstants.c)]], `#includes` the runtime headers.
|
|
## Generated Cmm Naming Convention
|
|
This program is built and run when you type `make` or `make boot` in `includes/`. It is
|
|
|
|
run twice: once to generate `includes\DerivedConstants.h`, and again to generate
|
|
|
|
`includes/GHCConstants.h`.
|
|
See [compiler/cmm/CLabel.hs](/trac/ghc/browser/ghc/compiler/cmm/CLabel.hs)
|
|
|
|
|
|
* The file `DerivedConstants.h` contains lots of `#defines` like this:
|
|
|
|
{{{
|
|
Labels generated by the code generator are of the form `<name>_<type>`
|
|
#define OFFSET_StgTSO_why_blocked 18
|
|
where `<name>` is `<Module>_<name>` for external names and `<unique>` for
|
|
}}}
|
|
internal names. `<type>` is one of the following:
|
|
which says that the offset to the why_blocked field of an `StgTSO` is 18 bytes. This file
|
|
|
|
is `#included` into [[GhcFile(includes/Cmm.h)]], so these offests are available to the
|
|
<table><tr><th>info</th>
|
|
[wiki:Commentary/Rts/Cmm hand-written .cmm files].
|
|
<td>Info table
|
|
|
|
</td></tr>
|
|
* The file `GHCConstants.h` contains similar definitions:
|
|
<tr><th>srt</th>
|
|
{{{
|
|
<td>Static reference table
|
|
oFFSET_StgTSO_why_blocked = 18::Int
|
|
</td></tr>
|
|
}}}
|
|
<tr><th>srtd</th>
|
|
This time the definitions are in Haskell syntax, and this file is `#included` directly into
|
|
<td>Static reference table descriptor
|
|
[[GhcFile(compiler/main/Constants.lhs)]]. This is the way that these offsets are made
|
|
</td></tr>
|
|
available to GHC's code generator.
|
|
<tr><th>entry</th>
|
|
|
|
<td>Entry code (function, closure)
|
|
== Generated Cmm Naming Convention ==
|
|
</td></tr>
|
|
|
|
<tr><th>slow</th>
|
|
See [[GhcFile(compiler/cmm/CLabel.hs)]]
|
|
<td>Slow entry code (if any)
|
|
|
|
</td></tr>
|
|
Labels generated by the code generator are of the form {{{<name>_<type>}}}
|
|
<tr><th>ret</th>
|
|
where {{{<name>}}} is {{{<Module>_<name>}}} for external names and {{{<unique>}}} for
|
|
<td>Direct return address
|
|
internal names. {{{<type>}}} is one of the following:
|
|
</td></tr>
|
|
|
|
<tr><th>vtbl</th>
|
|
info:: Info table
|
|
<td>Vector table
|
|
srt:: Static reference table
|
|
</td></tr>
|
|
srtd:: Static reference table descriptor
|
|
<tr><th>\<n\>_alt</th>
|
|
entry:: Entry code (function, closure)
|
|
<td>Case alternative (tag n)
|
|
slow:: Slow entry code (if any)
|
|
</td></tr>
|
|
ret:: Direct return address
|
|
<tr><th>dflt</th>
|
|
vtbl:: Vector table
|
|
<td>Default case alternative
|
|
<n>_alt:: Case alternative (tag n)
|
|
</td></tr>
|
|
dflt:: Default case alternative
|
|
<tr><th>btm</th>
|
|
btm:: Large bitmap vector
|
|
<td>Large bitmap vector
|
|
closure:: Static closure
|
|
</td></tr>
|
|
con_entry:: Dynamic Constructor entry code
|
|
<tr><th>closure</th>
|
|
con_info:: Dynamic Constructor info table
|
|
<td>Static closure
|
|
static_entry:: Static Constructor entry code
|
|
</td></tr>
|
|
static_info:: Static Constructor info table
|
|
<tr><th>con_entry</th>
|
|
sel_info:: Selector info table
|
|
<td>Dynamic Constructor entry code
|
|
sel_entry:: Selector entry code
|
|
</td></tr>
|
|
cc:: Cost centre
|
|
<tr><th>con_info</th>
|
|
ccs:: Cost centre stack
|
|
<td>Dynamic Constructor info table
|
|
|
|
</td></tr>
|
|
Many of these distinctions are only for documentation reasons. For
|
|
<tr><th>static_entry</th>
|
|
example, _ret is only distinguished from _entry to make it easy to
|
|
<td>Static Constructor entry code
|
|
tell whether a code fragment is a return point or a closure/function
|
|
</td></tr>
|
|
entry.
|
|
<tr><th>static_info</th>
|
|
|
|
<td>Static Constructor info table
|
|
``` |
|
</td></tr>
|
|
|
|
<tr><th>sel_info</th>
|
|
|
|
<td>Selector info table
|
|
|
|
</td></tr>
|
|
|
|
<tr><th>sel_entry</th>
|
|
|
|
<td>Selector entry code
|
|
|
|
</td></tr>
|
|
|
|
<tr><th>cc</th>
|
|
|
|
<td>Cost centre
|
|
|
|
</td></tr>
|
|
|
|
<tr><th>ccs</th>
|
|
|
|
<td>Cost centre stack
|
|
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
|
|
|
|
Many of these distinctions are only for documentation reasons. For
|
|
|
|
example, _ret is only distinguished from _entry to make it easy to
|
|
|
|
tell whether a code fragment is a return point or a closure/function
|
|
|
|
entry. |
|
|