... | ... | @@ -6,7 +6,7 @@ Error: HttpError (HttpExceptionRequest Request { |
|
|
secure = True
|
|
|
requestHeaders = []
|
|
|
path = "/trac/ghc/wiki/Commentary/Rts/HaskellExecution"
|
|
|
queryString = "?version=11"
|
|
|
queryString = "?version=13"
|
|
|
method = "GET"
|
|
|
proxy = Nothing
|
|
|
rawBody = False
|
... | ... | @@ -14,7 +14,7 @@ Error: HttpError (HttpExceptionRequest Request { |
|
|
responseTimeout = ResponseTimeoutDefault
|
|
|
requestVersion = HTTP/1.1
|
|
|
}
|
|
|
(StatusCodeException (Response {responseStatus = Status {statusCode = 403, statusMessage = "Forbidden"}, responseVersion = HTTP/1.1, responseHeaders = [("Date","Sun, 10 Mar 2019 06:57:01 GMT"),("Server","Apache/2.2.22 (Debian)"),("Strict-Transport-Security","max-age=63072000; includeSubDomains"),("Vary","Accept-Encoding"),("Content-Encoding","gzip"),("Content-Length","263"),("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/Rts/HaskellExecution\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"))
|
|
|
(StatusCodeException (Response {responseStatus = Status {statusCode = 403, statusMessage = "Forbidden"}, responseVersion = HTTP/1.1, responseHeaders = [("Date","Sun, 10 Mar 2019 06:57:49 GMT"),("Server","Apache/2.2.22 (Debian)"),("Strict-Transport-Security","max-age=63072000; includeSubDomains"),("Vary","Accept-Encoding"),("Content-Encoding","gzip"),("Content-Length","263"),("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/Rts/HaskellExecution\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"))
|
|
|
|
|
|
Original source:
|
|
|
|
... | ... | @@ -53,7 +53,10 @@ The code generator knows how many real registers there are, and tries to avoid u |
|
|
|
|
|
Source files: [[GhcFile(rts/Apply.h)]], [[GhcFile(rts/Apply.cmm)]]
|
|
|
|
|
|
Dealing with calls is by far the most complicated bit of the execution model, and hence of the code generator. Before we can talk about that, we need some terminology:
|
|
|
Dealing with calls is by far the most complicated bit of the execution model, and hence of the code generator. GHC uses an ''eval/apply'' strategy for compiling function calls; all the details of the design are in the paper [http://www.haskell.org/~simonmar/papers/eval-apply.pdf Making a fast curry: push/enter vs. eval/apply for higher-order languages].
|
|
|
|
|
|
First, we need some terminology:
|
|
|
|
|
|
* The '''arity''' of a function is the number of lambdas statically used in [wiki:Commentary/Compiler/StgSynType the lambda-form of its definition]. Note that arity is not deducible from the type. Example:
|
|
|
{{{
|
|
|
f :: Bool -> Bool -> Bool
|
... | ... | @@ -72,14 +75,15 @@ f = \x -> case x of |
|
|
|
|
|
|
|
|
When compiling a call, there are several cases to consider, which are treated separately.
|
|
|
* '''Known function, saturated call'''. The function is applied to exactly the right number of arguments to satisfy its arity. In that case, we simply load the arguments according to the standard entry convention, and tail-call (jump to) the function's entry point.
|
|
|
|
|
|
* '''Unknown function'''; a call in which we do not statically know what the function is. In that case we must do a "generic apply". This is so exciting that it deserves its [wiki:Commentary/Rts/HaskellExecution#Genericapply own section].
|
|
|
|
|
|
* '''Known function, saturated call'''. The function is applied to exactly the right number of arguments to satisfy its arity. In that case, we simply load the arguments according to the standard entry convention, and tail-call (jump to) the function's entry point. On average, about 80% of all calls fall into this category (see the eval/apply paper for measurements).
|
|
|
|
|
|
* '''Known function, too few arguments'''. In this case, we want to build a partial application (PAP), and return with a pointer to the PAP in the return register. Since building a PAP is a complicated business, instead we just behave as for an unknown function call, which will end up calling into the [[ref(Generic apply)]] code, which will build the PAP for us.
|
|
|
|
|
|
* '''Known function, too many arguments'''. We want to save the extra arguments on the stack, push a return address, and then behave just like a saturated call. When the result comes back, we should behave like "unknown call". However, to avoid needing to generate code for a new continuation here, the return address that we push on the stack is that of an appropriate [[ref(Generic apply)]] function, which will perform the application of the extra arguments to the (unknown) function returned by the saturated call.
|
|
|
|
|
|
* '''Unknown function'''; a call in which we do not statically know what the function is. In that case we must do a "generic apply". This is so exciting that it deserves its [wiki:Commentary/Rts/HaskellExecution#Genericapply own section].
|
|
|
|
|
|
=== Generic apply ===
|
|
|
|
|
|
Files: [[GhcFile(utils/genapply)]]
|
... | ... | |