4cc84bc22567fdf071f642c3015c447fefcc2bf1
[ghc.git] / rts / StgStartup.cmm
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(HpAlloc == 0);                               \
30     ASSERT(Sp != 0);                                    \
31     ASSERT(SpLim != 0);                                 \
32     ASSERT(SpLim - WDS(RESERVED_STACK_WORDS) <= Sp);
33
34 /* -----------------------------------------------------------------------------
35    Returning from the STG world.
36    -------------------------------------------------------------------------- */
37
38 INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
39                W_ info_ptr,
40                PROF_HDR_FIELDS(W_,p1,p2))
41 /* no return list: explicit stack layout */
42 {
43     /*
44        The final exit.
45
46        The top-top-level closures (e.g., "main") are of type "IO a".
47        When entered, they perform an IO action and return an 'a' in R1.
48
49        We save R1 on top of the stack where the scheduler can find it,
50        tidy up the registers and return to the scheduler.
51
52        We Leave the stack looking like this:
53
54                 +----------------+
55                 |      -------------------> return value
56                 +----------------+
57                 | stg_enter_info |
58                 +----------------+
59
60        The stg_enter_info is just a dummy info table so that the
61        garbage collector can understand the stack (there must always
62        be an info table on top of the stack).
63     */
64
65     /*
66        Here we setup the stack unwinding annotation necessary to allow
67        debuggers to find their way back to the C stack.
68
69        This is a bit fiddly as we assume the layout of the stack prepared
70        for us by StgRun. Note that in most cases StgRun is written in assembler
71        and therefore has no associated unwind information. For this reason we
72        need to identify the platform stack pointer and return address values for
73        the StgRun's caller.
74      */
75 #ifdef x86_64_HOST_ARCH
76     // offset of 8 in MachSp value due to return address
77     unwind MachSp = MachSp + RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE + 8,
78            UnwindReturnReg = W_[MachSp + RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE];
79 #else
80     // FIXME: Fill in for other platforms
81     unwind MachSp = return,
82            UnwindReturnReg = return;
83 #endif
84
85     Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
86     Sp(1) = R1;
87     Sp(0) = stg_enter_info;
88
89     StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
90
91     SAVE_THREAD_STATE();
92
93     /* The return code goes in BaseReg->rRet, and BaseReg is returned in R1 */
94     StgRegTable_rRet(BaseReg) = ThreadFinished;
95     R1 = BaseReg;
96
97     jump StgReturn [R1];
98 }
99
100 /* -----------------------------------------------------------------------------
101    Start a thread from the scheduler by returning to the address on
102    the top of the stack.  This is used for all entries to STG code
103    from C land.
104
105    On the way back, we (usually) pass through stg_returnToSched which saves
106    the thread's state away nicely.
107    -------------------------------------------------------------------------- */
108
109 stg_returnToStackTop /* no args: explicit stack layout */
110 {
111   LOAD_THREAD_STATE();
112   CHECK_SENSIBLE_REGS();
113   jump %ENTRY_CODE(Sp(0)) [];
114 }
115
116 stg_returnToSched /* no args: explicit stack layout */
117 {
118   W_ r1;
119   r1 = R1; // foreign calls may clobber R1
120   SAVE_THREAD_STATE();
121   foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
122   R1 = r1;
123   jump StgReturn [R1];
124 }
125
126 // A variant of stg_returnToSched that doesn't call threadPaused() on the
127 // current thread.  This is used for switching from compiled execution to the
128 // interpreter, where calling threadPaused() on every switch would be too
129 // expensive.
130 stg_returnToSchedNotPaused /* no args: explicit stack layout */
131 {
132   SAVE_THREAD_STATE();
133   jump StgReturn [R1];
134 }
135
136 // A variant of stg_returnToSched, but instead of returning directly to the
137 // scheduler, we jump to the code fragment pointed to by R2.  This lets us
138 // perform some final actions after making the thread safe, such as unlocking
139 // the MVar on which we are about to block in SMP mode.
140 stg_returnToSchedButFirst /* no args: explicit stack layout */
141 {
142   W_ r1, r2, r3;
143   r1 = R1;
144   r2 = R2;
145   r3 = R3;
146   SAVE_THREAD_STATE();
147   // foreign calls may clobber R1/R2/.., so we save them above
148   foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
149   R1 = r1;
150   R2 = r2;
151   R3 = r3;
152   jump R2 [R1,R3];
153 }
154
155 stg_threadFinished /* no args: explicit stack layout */
156 {
157   StgRegTable_rRet(BaseReg) = ThreadFinished;
158   R1 = BaseReg;
159   jump StgReturn [R1];
160 }
161
162 /* -----------------------------------------------------------------------------
163     Strict IO application - performing an IO action and entering its result.
164
165     rts_evalIO() lets you perform Haskell IO actions from outside of
166     Haskell-land, returning back to you their result. Want this result
167     to be evaluated to WHNF by that time, so that we can easily get at
168     the int/char/whatever using the various get{Ty} functions provided
169     by the RTS API.
170
171     stg_forceIO takes care of this, performing the IO action and entering
172     the results that comes back.
173
174     ------------------------------------------------------------------------- */
175
176 INFO_TABLE_RET(stg_forceIO, RET_SMALL, P_ info_ptr)
177     return (P_ ret)
178 {
179     ENTER(ret);
180 }
181
182 /* -----------------------------------------------------------------------------
183    Special STG entry points for module registration.
184    -------------------------------------------------------------------------- */
185
186 stg_init_finish /* no args: explicit stack layout */
187 {
188   jump StgReturn [];
189 }
190
191 /* On entry to stg_init:
192  *    init_stack[0] = &stg_init_ret;
193  *    init_stack[1] = __stginit_Something;
194  */
195 stg_init /* no args: explicit stack layout */
196 {
197   W_ next;
198   Sp = W_[BaseReg + OFFSET_StgRegTable_rSp];
199   next = W_[Sp];
200   Sp_adj(1);
201   jump next [];
202 }