root/rts/StgStartup.cmm

Revision ac89ecf3848b7422c8460065d9a2063829fcfb95, 5.0 KB (checked in by Simon Marlow <marlowsd@…>, 3 months ago)

comments only

  • Property mode set to 100644
Line 
1/* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2012
4 *
5 * Code for starting, stopping and restarting threads.
6 *
7 * This file is written in a subset of C--, extended with various
8 * features specific to GHC.  It is compiled by GHC directly.  For the
9 * syntax of .cmm files, see the parser in ghc/compiler/cmm/CmmParse.y.
10 *
11 * ---------------------------------------------------------------------------*/
12
13#include "Cmm.h"
14
15/*
16 * This module contains the two entry points and the final exit point
17 * to/from the Haskell world.  We can enter either by:
18 *
19 *   a) returning to the address on the top of the stack, or
20 *   b) entering the closure on the top of the stack
21 *
22 * the function stg_stop_thread_entry is the final exit for a
23 * thread: it is the last return address on the stack.  It returns
24 * to the scheduler marking the thread as finished.
25 */
26
27#define CHECK_SENSIBLE_REGS() \
28    ASSERT(Hp != 0);                    \
29    ASSERT(Sp != 0);                    \
30    ASSERT(SpLim != 0);                 \
31    ASSERT(SpLim - WDS(RESERVED_STACK_WORDS) <= Sp);
32
33/* -----------------------------------------------------------------------------
34   Returning from the STG world.
35   -------------------------------------------------------------------------- */
36
37INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
38#if defined(PROFILING)
39  W_ unused,
40  W_ unused
41#endif
42)
43{
44    /*
45       The final exit.
46     
47       The top-top-level closures (e.g., "main") are of type "IO a".
48       When entered, they perform an IO action and return an 'a' in R1.
49     
50       We save R1 on top of the stack where the scheduler can find it,
51       tidy up the registers and return to the scheduler.
52     
53       We Leave the stack looking like this:
54     
55                +----------------+
56                |      -------------------> return value
57                +----------------+
58                | stg_enter_info |
59                +----------------+
60     
61       The stg_enter_info is just a dummy info table so that the
62       garbage collector can understand the stack (there must always
63       be an info table on top of the stack).
64    */
65
66    Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
67    Sp(1) = R1;
68    Sp(0) = stg_enter_info;
69
70    StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
71
72    SAVE_THREAD_STATE();
73
74    /* The return code goes in BaseReg->rRet, and BaseReg is returned in R1 */
75    StgRegTable_rRet(BaseReg) = ThreadFinished;
76    R1 = BaseReg;
77
78    jump StgReturn;
79}
80
81/* -----------------------------------------------------------------------------
82   Start a thread from the scheduler by returning to the address on
83   the top of the stack.  This is used for all entries to STG code
84   from C land.
85
86   On the way back, we (usually) pass through stg_returnToSched which saves
87   the thread's state away nicely.
88   -------------------------------------------------------------------------- */
89
90stg_returnToStackTop
91{
92  LOAD_THREAD_STATE();
93  CHECK_SENSIBLE_REGS();
94  jump %ENTRY_CODE(Sp(0));
95}
96
97stg_returnToSched
98{
99  SAVE_THREAD_STATE();
100  foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
101  jump StgReturn;
102}
103
104// A variant of stg_returnToSched that doesn't call threadPaused() on the
105// current thread.  This is used for switching from compiled execution to the
106// interpreter, where calling threadPaused() on every switch would be too
107// expensive.
108stg_returnToSchedNotPaused
109{
110  SAVE_THREAD_STATE();
111  jump StgReturn;
112}
113
114// A variant of stg_returnToSched, but instead of returning directly to the
115// scheduler, we jump to the code fragment pointed to by R2.  This lets us
116// perform some final actions after making the thread safe, such as unlocking
117// the MVar on which we are about to block in SMP mode.
118stg_returnToSchedButFirst
119{
120  SAVE_THREAD_STATE();
121  foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
122  jump R2;
123}
124
125stg_threadFinished
126{
127  StgRegTable_rRet(BaseReg) = ThreadFinished;
128  R1 = BaseReg;
129  jump StgReturn;
130
131
132/* -----------------------------------------------------------------------------
133    Strict IO application - performing an IO action and entering its result.
134   
135    rts_evalIO() lets you perform Haskell IO actions from outside of
136    Haskell-land, returning back to you their result. Want this result
137    to be evaluated to WHNF by that time, so that we can easily get at
138    the int/char/whatever using the various get{Ty} functions provided
139    by the RTS API.
140
141    stg_forceIO takes care of this, performing the IO action and entering
142    the results that comes back.
143
144    ------------------------------------------------------------------------- */
145
146INFO_TABLE_RET(stg_forceIO, RET_SMALL)
147
148{
149  Sp_adj(1);
150  ENTER();
151}
152
153/* -----------------------------------------------------------------------------
154   Special STG entry points for module registration.
155   -------------------------------------------------------------------------- */
156
157stg_init_finish
158{
159  jump StgReturn;
160}
161
162/* On entry to stg_init:
163 *    init_stack[0] = &stg_init_ret;
164 *    init_stack[1] = __stginit_Something;
165 */
166stg_init
167{
168  W_ next;
169  Sp = W_[BaseReg + OFFSET_StgRegTable_rSp];
170  next = W_[Sp];
171  Sp_adj(1);
172  jump next;
173}
Note: See TracBrowser for help on using the browser.