ece080b8b755b8eec72d470b5f1f678c6e9a6667
[ghc-hetmet.git] / ghc / rts / StgStartup.cmm
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2004
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(HpLim != 0);                 \
32     ASSERT(SpLim - RESERVED_STACK_WORDS <= Sp); \
33     ASSERT(HpLim >= Hp);
34
35 /* -----------------------------------------------------------------------------
36    Returning from the STG world.
37
38    This is a polymorphic return address, meaning that any old constructor
39    can be returned, we don't care (actually, it's probably going to be
40    an IOok constructor, which will indirect through the vector table
41    slot 0).
42    -------------------------------------------------------------------------- */
43
44 #if defined(PROFILING)
45 #define STOP_THREAD_BITMAP 3
46 #define STOP_THREAD_WORDS  2
47 #else
48 #define STOP_THREAD_BITMAP 0
49 #define STOP_THREAD_WORDS  0
50 #endif
51
52 /* A polymorhpic return address, where all the vector slots point to the
53    direct entry point. */
54 INFO_TABLE_RET( stg_stop_thread, STOP_THREAD_WORDS, STOP_THREAD_BITMAP,
55                 STOP_FRAME, 
56                 RET_LBL(stg_stop_thread),
57                 RET_LBL(stg_stop_thread),
58                 RET_LBL(stg_stop_thread),
59                 RET_LBL(stg_stop_thread),
60                 RET_LBL(stg_stop_thread),
61                 RET_LBL(stg_stop_thread),
62                 RET_LBL(stg_stop_thread),
63                 RET_LBL(stg_stop_thread) )
64 {
65     /* 
66        The final exit.
67       
68        The top-top-level closures (e.g., "main") are of type "IO a".
69        When entered, they perform an IO action and return an 'a' in R1.
70       
71        We save R1 on top of the stack where the scheduler can find it,
72        tidy up the registers and return to the scheduler.
73       
74        We Leave the stack looking like this:
75       
76                 +----------------+
77                 |      -------------------> return value
78                 +----------------+
79                 | stg_enter_info |
80                 +----------------+
81       
82        The stg_enter_info is just a dummy info table so that the
83        garbage collector can understand the stack (there must always
84        be an info table on top of the stack).
85     */
86
87     Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
88     Sp(1) = R1;
89     Sp(0) = stg_enter_info;
90
91     StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
92
93     SAVE_THREAD_STATE();
94
95     /* R1 contains the return value of the thread */
96     R1 = ThreadFinished;
97
98     jump StgReturn;
99 }
100
101 /* -----------------------------------------------------------------------------
102    Start a thread from the scheduler by returning to the address on
103    the top of the stack.  This is used for all entries to STG code
104    from C land.
105
106    On the way back, we (usually) pass through stg_returnToSched which saves
107    the thread's state away nicely.
108    -------------------------------------------------------------------------- */
109
110 stg_returnToStackTop
111 {
112   LOAD_THREAD_STATE();
113   CHECK_SENSIBLE_REGS();
114   jump %ENTRY_CODE(Sp(0));
115 }
116
117 stg_returnToSched
118 {
119   SAVE_THREAD_STATE();
120   foreign "C" threadPaused(CurrentTSO);
121   jump StgReturn;
122 }
123
124 // A variant of stg_returntToSched that doesn't call threadPaused() on the
125 // current thread.  This is used for switching from compiled execution to the
126 // interpreter, where calling threadPaused() on every switch would be too
127 // expensive.
128 stg_returnToSchedNotPaused
129 {
130   SAVE_THREAD_STATE();
131   jump StgReturn;
132 }
133
134 // A variant of stg_returnToSched, but instead of returning directly to the
135 // scheduler, we jump to the code fragment pointed to by R2.  This lets us
136 // perform some final actions after making the thread safe, such as unlocking
137 // the MVar on which we are about to block in SMP mode.
138 stg_returnToSchedButFirst
139 {
140   SAVE_THREAD_STATE();
141   foreign "C" threadPaused(CurrentTSO);
142   jump R2;
143 }
144
145 /* -----------------------------------------------------------------------------
146     Strict IO application - performing an IO action and entering its result.
147     
148     rts_evalIO() lets you perform Haskell IO actions from outside of
149     Haskell-land, returning back to you their result. Want this result
150     to be evaluated to WHNF by that time, so that we can easily get at
151     the int/char/whatever using the various get{Ty} functions provided
152     by the RTS API.
153
154     forceIO takes care of this, performing the IO action and entering the
155     results that comes back.
156     ------------------------------------------------------------------------- */
157
158 INFO_TABLE_RET( stg_forceIO, 0/*size*/, 0/*bitmap*/, RET_SMALL)
159
160 #ifdef REG_R1
161 {
162   Sp_adj(1);
163   ENTER();
164 }
165 #else
166 {
167   R1 = Sp(0);
168   Sp_adj(2);
169   ENTER();
170 }
171 #endif
172
173 /* -----------------------------------------------------------------------------
174     Non-strict IO application.
175
176     This stack frame works like stg_forceIO_info except that it
177     doesn't evaluate the return value.  We need the layer because the
178     return convention for an IO action differs depending on whether R1
179     is a register or not.
180     ------------------------------------------------------------------------- */
181
182 INFO_TABLE_RET( stg_noforceIO, 0/*size*/, 0/*bitmap*/, RET_SMALL )
183
184 #ifdef REG_R1
185 {
186   Sp_adj(1);
187   jump %ENTRY_CODE(Sp(0));
188 }
189 #else
190 {
191   R1 = Sp(0);
192   Sp_adj(2);
193   jump %ENTRY_CODE(Sp(0));
194 }
195 #endif
196
197 /* -----------------------------------------------------------------------------
198    Special STG entry points for module registration.
199    -------------------------------------------------------------------------- */
200
201 stg_init_finish
202 {
203   jump StgReturn;
204 }
205
206 /* On entry to stg_init:
207  *    init_stack[0] = &stg_init_ret;
208  *    init_stack[1] = __stginit_Something;
209  */
210 stg_init
211 {
212   W_ next;
213   Sp = W_[BaseReg + OFFSET_StgRegTable_rSp];
214   next = W_[Sp];
215   Sp_adj(1);
216   jump next;
217 }