1 /* ----------------------------------------------------------------------------
3 * (c) The GHC Team, 1998-2004
5 * Entry code for various built-in closure types.
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.
11 * --------------------------------------------------------------------------*/
15 import pthread_mutex_lock;
16 import ghczmprim_GHCziTypes_Czh_static_info;
17 import ghczmprim_GHCziTypes_Izh_static_info;
18 import EnterCriticalSection;
19 import LeaveCriticalSection;
21 /* ----------------------------------------------------------------------------
23 ------------------------------------------------------------------------- */
25 INFO_TABLE_RET (stg_stack_underflow_frame, UNDERFLOW_FRAME, P_ unused)
31 ("ptr" ret_off) = foreign "C" threadStackUnderflow(MyCapability(),
35 jump %ENTRY_CODE(Sp(ret_off));
38 /* ----------------------------------------------------------------------------
39 Support for the bytecode interpreter.
40 ------------------------------------------------------------------------- */
42 /* 9 bits of return code for constructors created by the interpreter. */
43 stg_interp_constr_entry
45 /* R1 points at the constructor */
46 jump %ENTRY_CODE(Sp(0));
49 /* Some info tables to be used when compiled code returns a value to
50 the interpreter, i.e. the interpreter pushes one of these onto the
51 stack before entering a value. What the code does is to
52 impedance-match the compiled return convention (in R1p/R1n/F1/D1 etc) to
53 the interpreter's convention (returned value is on top of stack),
54 and then cause the scheduler to enter the interpreter.
56 On entry, the stack (growing down) looks like this:
58 ptr to BCO holding return continuation
59 ptr to one of these info tables.
61 The info table code, both direct and vectored, must:
62 * push R1/F1/D1 on the stack, and its tag if necessary
63 * push the BCO (so it's now on the stack twice)
64 * Yield, ie, go to the scheduler.
66 Scheduler examines the t.o.s, discovers it is a BCO, and proceeds
67 directly to the bytecode interpreter. That pops the top element
68 (the BCO, containing the return continuation), and interprets it.
69 Net result: return continuation gets interpreted, with the
73 ptr to the info table just jumped thru
76 which is just what we want -- the "standard" return layout for the
79 Don't ask me how unboxed tuple returns are supposed to work. We
80 haven't got a good story about that yet.
83 INFO_TABLE_RET( stg_ctoi_R1p, RET_BCO)
87 Sp(0) = stg_enter_info;
88 jump stg_yield_to_interpreter;
92 * When the returned value is a pointer, but unlifted, in R1 ...
94 INFO_TABLE_RET( stg_ctoi_R1unpt, RET_BCO )
98 Sp(0) = stg_gc_unpt_r1_info;
99 jump stg_yield_to_interpreter;
103 * When the returned value is a non-pointer in R1 ...
105 INFO_TABLE_RET( stg_ctoi_R1n, RET_BCO )
109 Sp(0) = stg_gc_unbx_r1_info;
110 jump stg_yield_to_interpreter;
114 * When the returned value is in F1
116 INFO_TABLE_RET( stg_ctoi_F1, RET_BCO )
119 F_[Sp + WDS(1)] = F1;
120 Sp(0) = stg_gc_f1_info;
121 jump stg_yield_to_interpreter;
125 * When the returned value is in D1
127 INFO_TABLE_RET( stg_ctoi_D1, RET_BCO )
129 Sp_adj(-1) - SIZEOF_DOUBLE;
130 D_[Sp + WDS(1)] = D1;
131 Sp(0) = stg_gc_d1_info;
132 jump stg_yield_to_interpreter;
136 * When the returned value is in L1
138 INFO_TABLE_RET( stg_ctoi_L1, RET_BCO )
141 L_[Sp + WDS(1)] = L1;
142 Sp(0) = stg_gc_l1_info;
143 jump stg_yield_to_interpreter;
147 * When the returned value is a void
149 INFO_TABLE_RET( stg_ctoi_V, RET_BCO )
152 Sp(0) = stg_gc_void_info;
153 jump stg_yield_to_interpreter;
157 * Dummy info table pushed on the top of the stack when the interpreter
158 * should apply the BCO on the stack to its arguments, also on the
161 INFO_TABLE_RET( stg_apply_interp, RET_BCO )
163 /* Just in case we end up in here... (we shouldn't) */
164 jump stg_yield_to_interpreter;
167 /* ----------------------------------------------------------------------------
169 ------------------------------------------------------------------------- */
171 INFO_TABLE_FUN( stg_BCO, 4, 0, BCO, "BCO", "BCO", ARG_BCO )
173 /* entering a BCO means "apply it", same as a function */
176 Sp(0) = stg_apply_interp_info;
177 jump stg_yield_to_interpreter;
180 /* ----------------------------------------------------------------------------
181 Info tables for indirections.
183 SPECIALISED INDIRECTIONS: we have a specialised indirection for direct returns,
184 so that we can avoid entering
185 the object when we know it points directly to a value. The update
186 code (Updates.cmm) updates objects with the appropriate kind of
187 indirection. We only do this for young-gen indirections.
188 ------------------------------------------------------------------------- */
190 INFO_TABLE(stg_IND,1,0,IND,"IND","IND")
192 TICK_ENT_DYN_IND(); /* tick */
193 R1 = UNTAG(StgInd_indirectee(R1));
198 INFO_TABLE(stg_IND_direct,1,0,IND,"IND","IND")
200 TICK_ENT_DYN_IND(); /* tick */
201 R1 = StgInd_indirectee(R1);
203 jump %ENTRY_CODE(Sp(0));
206 INFO_TABLE(stg_IND_STATIC,1,0,IND_STATIC,"IND_STATIC","IND_STATIC")
208 TICK_ENT_STATIC_IND(); /* tick */
209 R1 = UNTAG(StgInd_indirectee(R1));
214 INFO_TABLE(stg_IND_PERM,1,0,IND_PERM,"IND_PERM","IND_PERM")
216 /* Don't add INDs to granularity cost */
218 /* Don't: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is
219 here only to help profiling */
221 #if defined(TICKY_TICKY) && !defined(PROFILING)
222 /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than
229 /* Enter PAP cost centre */
230 ENTER_CCS_PAP_CL(R1);
232 /* For ticky-ticky, change the perm_ind to a normal ind on first
233 * entry, so the number of ent_perm_inds is the number of *thunks*
234 * entered again, not the number of subsequent entries.
236 * Since this screws up cost centres, we die if profiling and
237 * ticky_ticky are on at the same time. KSW 1999-01.
241 # error Profiling and ticky-ticky do not mix at present!
242 # endif /* PROFILING */
243 StgHeader_info(R1) = stg_IND_info;
244 #endif /* TICKY_TICKY */
246 R1 = UNTAG(StgInd_indirectee(R1));
248 #if defined(TICKY_TICKY) && !defined(PROFILING)
255 /* ----------------------------------------------------------------------------
258 Entering a black hole normally causes a cyclic data dependency, but
259 in the concurrent world, black holes are synchronization points,
260 and they are turned into blocking queues when there are threads
261 waiting for the evaluation of the closure to finish.
262 ------------------------------------------------------------------------- */
264 INFO_TABLE(stg_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE")
266 W_ r, p, info, bq, msg, owner, bd;
268 TICK_ENT_DYN_IND(); /* tick */
271 p = StgInd_indirectee(R1);
272 if (GETTAG(p) != 0) {
274 jump %ENTRY_CODE(Sp(0));
277 info = StgHeader_info(p);
278 if (info == stg_IND_info) {
279 // This could happen, if e.g. we got a BLOCKING_QUEUE that has
280 // just been replaced with an IND by another thread in
281 // wakeBlockingQueue().
285 if (info == stg_TSO_info ||
286 info == stg_BLOCKING_QUEUE_CLEAN_info ||
287 info == stg_BLOCKING_QUEUE_DIRTY_info)
289 ("ptr" msg) = foreign "C" allocate(MyCapability() "ptr",
290 BYTES_TO_WDS(SIZEOF_MessageBlackHole)) [R1];
292 SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM);
293 MessageBlackHole_tso(msg) = CurrentTSO;
294 MessageBlackHole_bh(msg) = R1;
296 (r) = foreign "C" messageBlackHole(MyCapability() "ptr", msg "ptr") [R1];
301 StgTSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16;
302 StgTSO_block_info(CurrentTSO) = msg;
303 jump stg_block_blackhole;
313 INFO_TABLE(__stg_EAGER_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE")
315 jump ENTRY_LBL(stg_BLACKHOLE);
318 // CAF_BLACKHOLE is allocated when entering a CAF. The reason it is
319 // distinct from BLACKHOLE is so that we can tell the difference
320 // between an update frame on the stack that points to a CAF under
321 // evaluation, and one that points to a closure that is under
322 // evaluation by another thread (a BLACKHOLE). See threadPaused().
324 INFO_TABLE(stg_CAF_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE")
326 jump ENTRY_LBL(stg_BLACKHOLE);
329 INFO_TABLE(stg_BLOCKING_QUEUE_CLEAN,4,0,BLOCKING_QUEUE,"BLOCKING_QUEUE","BLOCKING_QUEUE")
330 { foreign "C" barf("BLOCKING_QUEUE_CLEAN object entered!") never returns; }
333 INFO_TABLE(stg_BLOCKING_QUEUE_DIRTY,4,0,BLOCKING_QUEUE,"BLOCKING_QUEUE","BLOCKING_QUEUE")
334 { foreign "C" barf("BLOCKING_QUEUE_DIRTY object entered!") never returns; }
337 /* ----------------------------------------------------------------------------
338 Whiteholes are used for the "locked" state of a closure (see lockClosure())
339 ------------------------------------------------------------------------- */
341 INFO_TABLE(stg_WHITEHOLE, 0,0, WHITEHOLE, "WHITEHOLE", "WHITEHOLE")
343 #if defined(THREADED_RTS)
348 // spin until the WHITEHOLE is updated
349 info = StgHeader_info(R1);
350 if (info == stg_WHITEHOLE_info) {
352 if (i == SPIN_COUNT) {
354 foreign "C" yieldThread() [R1];
358 jump %ENTRY_CODE(info);
360 foreign "C" barf("WHITEHOLE object entered!") never returns;
364 /* ----------------------------------------------------------------------------
365 Some static info tables for things that don't get entered, and
366 therefore don't need entry code (i.e. boxed but unpointed objects)
367 NON_ENTERABLE_ENTRY_CODE now defined at the beginning of the file
368 ------------------------------------------------------------------------- */
370 INFO_TABLE(stg_TSO, 0,0,TSO, "TSO", "TSO")
371 { foreign "C" barf("TSO object entered!") never returns; }
373 INFO_TABLE(stg_STACK, 0,0, STACK, "STACK", "STACK")
374 { foreign "C" barf("STACK object entered!") never returns; }
376 /* ----------------------------------------------------------------------------
379 Live weak pointers have a special closure type. Dead ones are just
380 nullary constructors (although they live on the heap - we overwrite
381 live weak pointers with dead ones).
382 ------------------------------------------------------------------------- */
384 INFO_TABLE(stg_WEAK,1,4,WEAK,"WEAK","WEAK")
385 { foreign "C" barf("WEAK object entered!") never returns; }
388 * It's important when turning an existing WEAK into a DEAD_WEAK
389 * (which is what finalizeWeak# does) that we don't lose the link
390 * field and break the linked list of weak pointers. Hence, we give
391 * DEAD_WEAK 5 non-pointer fields.
393 INFO_TABLE_CONSTR(stg_DEAD_WEAK,0,5,0,CONSTR,"DEAD_WEAK","DEAD_WEAK")
394 { foreign "C" barf("DEAD_WEAK object entered!") never returns; }
396 /* ----------------------------------------------------------------------------
399 This is a static nullary constructor (like []) that we use to mark an empty
400 finalizer in a weak pointer object.
401 ------------------------------------------------------------------------- */
403 INFO_TABLE_CONSTR(stg_NO_FINALIZER,0,0,0,CONSTR_NOCAF_STATIC,"NO_FINALIZER","NO_FINALIZER")
404 { foreign "C" barf("NO_FINALIZER object entered!") never returns; }
406 CLOSURE(stg_NO_FINALIZER_closure,stg_NO_FINALIZER);
408 /* ----------------------------------------------------------------------------
409 Stable Names are unlifted too.
410 ------------------------------------------------------------------------- */
412 INFO_TABLE(stg_STABLE_NAME,0,1,PRIM,"STABLE_NAME","STABLE_NAME")
413 { foreign "C" barf("STABLE_NAME object entered!") never returns; }
415 /* ----------------------------------------------------------------------------
418 There are two kinds of these: full and empty. We need an info table
419 and entry code for each type.
420 ------------------------------------------------------------------------- */
422 INFO_TABLE(stg_MVAR_CLEAN,3,0,MVAR_CLEAN,"MVAR","MVAR")
423 { foreign "C" barf("MVAR object entered!") never returns; }
425 INFO_TABLE(stg_MVAR_DIRTY,3,0,MVAR_DIRTY,"MVAR","MVAR")
426 { foreign "C" barf("MVAR object entered!") never returns; }
428 /* -----------------------------------------------------------------------------
430 -------------------------------------------------------------------------- */
432 INFO_TABLE(stg_TVAR, 2, 1, MUT_PRIM, "TVAR", "TVAR")
433 { foreign "C" barf("TVAR object entered!") never returns; }
435 INFO_TABLE(stg_TVAR_WATCH_QUEUE, 3, 0, MUT_PRIM, "TVAR_WATCH_QUEUE", "TVAR_WATCH_QUEUE")
436 { foreign "C" barf("TVAR_WATCH_QUEUE object entered!") never returns; }
438 INFO_TABLE(stg_ATOMIC_INVARIANT, 2, 1, MUT_PRIM, "ATOMIC_INVARIANT", "ATOMIC_INVARIANT")
439 { foreign "C" barf("ATOMIC_INVARIANT object entered!") never returns; }
441 INFO_TABLE(stg_INVARIANT_CHECK_QUEUE, 3, 0, MUT_PRIM, "INVARIANT_CHECK_QUEUE", "INVARIANT_CHECK_QUEUE")
442 { foreign "C" barf("INVARIANT_CHECK_QUEUE object entered!") never returns; }
444 INFO_TABLE(stg_TREC_CHUNK, 0, 0, TREC_CHUNK, "TREC_CHUNK", "TREC_CHUNK")
445 { foreign "C" barf("TREC_CHUNK object entered!") never returns; }
447 INFO_TABLE(stg_TREC_HEADER, 3, 1, MUT_PRIM, "TREC_HEADER", "TREC_HEADER")
448 { foreign "C" barf("TREC_HEADER object entered!") never returns; }
450 INFO_TABLE_CONSTR(stg_END_STM_WATCH_QUEUE,0,0,0,CONSTR_NOCAF_STATIC,"END_STM_WATCH_QUEUE","END_STM_WATCH_QUEUE")
451 { foreign "C" barf("END_STM_WATCH_QUEUE object entered!") never returns; }
453 INFO_TABLE_CONSTR(stg_END_INVARIANT_CHECK_QUEUE,0,0,0,CONSTR_NOCAF_STATIC,"END_INVARIANT_CHECK_QUEUE","END_INVARIANT_CHECK_QUEUE")
454 { foreign "C" barf("END_INVARIANT_CHECK_QUEUE object entered!") never returns; }
456 INFO_TABLE_CONSTR(stg_END_STM_CHUNK_LIST,0,0,0,CONSTR_NOCAF_STATIC,"END_STM_CHUNK_LIST","END_STM_CHUNK_LIST")
457 { foreign "C" barf("END_STM_CHUNK_LIST object entered!") never returns; }
459 INFO_TABLE_CONSTR(stg_NO_TREC,0,0,0,CONSTR_NOCAF_STATIC,"NO_TREC","NO_TREC")
460 { foreign "C" barf("NO_TREC object entered!") never returns; }
462 CLOSURE(stg_END_STM_WATCH_QUEUE_closure,stg_END_STM_WATCH_QUEUE);
464 CLOSURE(stg_END_INVARIANT_CHECK_QUEUE_closure,stg_END_INVARIANT_CHECK_QUEUE);
466 CLOSURE(stg_END_STM_CHUNK_LIST_closure,stg_END_STM_CHUNK_LIST);
468 CLOSURE(stg_NO_TREC_closure,stg_NO_TREC);
470 /* ----------------------------------------------------------------------------
472 ------------------------------------------------------------------------- */
474 // PRIM rather than CONSTR, because PRIM objects cannot be duplicated by the GC.
476 INFO_TABLE_CONSTR(stg_MSG_TRY_WAKEUP,2,0,0,PRIM,"MSG_TRY_WAKEUP","MSG_TRY_WAKEUP")
477 { foreign "C" barf("MSG_TRY_WAKEUP object entered!") never returns; }
479 INFO_TABLE_CONSTR(stg_MSG_THROWTO,4,0,0,PRIM,"MSG_THROWTO","MSG_THROWTO")
480 { foreign "C" barf("MSG_THROWTO object entered!") never returns; }
482 INFO_TABLE_CONSTR(stg_MSG_BLACKHOLE,3,0,0,PRIM,"MSG_BLACKHOLE","MSG_BLACKHOLE")
483 { foreign "C" barf("MSG_BLACKHOLE object entered!") never returns; }
485 // used to overwrite a MSG_THROWTO when the message has been used/revoked
486 INFO_TABLE_CONSTR(stg_MSG_NULL,1,0,0,PRIM,"MSG_NULL","MSG_NULL")
487 { foreign "C" barf("MSG_NULL object entered!") never returns; }
489 /* ----------------------------------------------------------------------------
492 This is a static nullary constructor (like []) that we use to mark the
493 end of a linked TSO queue.
494 ------------------------------------------------------------------------- */
496 INFO_TABLE_CONSTR(stg_END_TSO_QUEUE,0,0,0,CONSTR_NOCAF_STATIC,"END_TSO_QUEUE","END_TSO_QUEUE")
497 { foreign "C" barf("END_TSO_QUEUE object entered!") never returns; }
499 CLOSURE(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE);
501 /* ----------------------------------------------------------------------------
504 These come in two basic flavours: arrays of data (StgArrWords) and arrays of
505 pointers (StgArrPtrs). They all have a similar layout:
507 ___________________________
508 | Info | No. of | data....
510 ---------------------------
512 These are *unpointed* objects: i.e. they cannot be entered.
514 ------------------------------------------------------------------------- */
516 INFO_TABLE(stg_ARR_WORDS, 0, 0, ARR_WORDS, "ARR_WORDS", "ARR_WORDS")
517 { foreign "C" barf("ARR_WORDS object entered!") never returns; }
519 INFO_TABLE(stg_MUT_ARR_PTRS_CLEAN, 0, 0, MUT_ARR_PTRS_CLEAN, "MUT_ARR_PTRS_CLEAN", "MUT_ARR_PTRS_CLEAN")
520 { foreign "C" barf("MUT_ARR_PTRS_CLEAN object entered!") never returns; }
522 INFO_TABLE(stg_MUT_ARR_PTRS_DIRTY, 0, 0, MUT_ARR_PTRS_DIRTY, "MUT_ARR_PTRS_DIRTY", "MUT_ARR_PTRS_DIRTY")
523 { foreign "C" barf("MUT_ARR_PTRS_DIRTY object entered!") never returns; }
525 INFO_TABLE(stg_MUT_ARR_PTRS_FROZEN, 0, 0, MUT_ARR_PTRS_FROZEN, "MUT_ARR_PTRS_FROZEN", "MUT_ARR_PTRS_FROZEN")
526 { foreign "C" barf("MUT_ARR_PTRS_FROZEN object entered!") never returns; }
528 INFO_TABLE(stg_MUT_ARR_PTRS_FROZEN0, 0, 0, MUT_ARR_PTRS_FROZEN0, "MUT_ARR_PTRS_FROZEN0", "MUT_ARR_PTRS_FROZEN0")
529 { foreign "C" barf("MUT_ARR_PTRS_FROZEN0 object entered!") never returns; }
531 /* ----------------------------------------------------------------------------
533 ------------------------------------------------------------------------- */
535 INFO_TABLE(stg_MUT_VAR_CLEAN, 1, 0, MUT_VAR_CLEAN, "MUT_VAR_CLEAN", "MUT_VAR_CLEAN")
536 { foreign "C" barf("MUT_VAR_CLEAN object entered!") never returns; }
537 INFO_TABLE(stg_MUT_VAR_DIRTY, 1, 0, MUT_VAR_DIRTY, "MUT_VAR_DIRTY", "MUT_VAR_DIRTY")
538 { foreign "C" barf("MUT_VAR_DIRTY object entered!") never returns; }
540 /* ----------------------------------------------------------------------------
543 Entering this closure will just return to the address on the top of the
544 stack. Useful for getting a thread in a canonical form where we can
545 just enter the top stack word to start the thread. (see deleteThread)
546 * ------------------------------------------------------------------------- */
548 INFO_TABLE( stg_dummy_ret, 0, 0, CONSTR_NOCAF_STATIC, "DUMMY_RET", "DUMMY_RET")
550 jump %ENTRY_CODE(Sp(0));
552 CLOSURE(stg_dummy_ret_closure,stg_dummy_ret);
554 /* ----------------------------------------------------------------------------
556 ------------------------------------------------------------------------- */
558 INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE")
559 { foreign "C" barf("MVAR_TSO_QUEUE object entered!") never returns; }
561 /* ----------------------------------------------------------------------------
562 CHARLIKE and INTLIKE closures.
564 These are static representations of Chars and small Ints, so that
565 we can remove dynamic Chars and Ints during garbage collection and
566 replace them with references to the static objects.
567 ------------------------------------------------------------------------- */
569 #if defined(__PIC__) && defined(mingw32_HOST_OS)
571 * When sticking the RTS in a Windows DLL, we delay populating the
572 * Charlike and Intlike tables until load-time, which is only
573 * when we've got the real addresses to the C# and I# closures.
575 * -- this is currently broken BL 2009/11/14.
576 * we don't rewrite to static closures at all with Windows DLLs.
578 // #warning Is this correct? _imp is a pointer!
579 #define Char_hash_static_info _imp__ghczmprim_GHCziTypes_Czh_static_info
580 #define Int_hash_static_info _imp__ghczmprim_GHCziTypes_Izh_static_info
582 #define Char_hash_static_info ghczmprim_GHCziTypes_Czh_static_info
583 #define Int_hash_static_info ghczmprim_GHCziTypes_Izh_static_info
587 #define CHARLIKE_HDR(n) CLOSURE(Char_hash_static_info, n)
588 #define INTLIKE_HDR(n) CLOSURE(Int_hash_static_info, n)
590 /* put these in the *data* section, since the garbage collector relies
591 * on the fact that static closures live in the data section.
594 /* end the name with _closure, to convince the mangler this is a closure */
596 #if !(defined(__PIC__) && defined(mingw32_HOST_OS))
598 stg_CHARLIKE_closure:
859 INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
891 INTLIKE_HDR(16) /* MAX_INTLIKE == 16 */
894 #endif // !(defined(__PIC__) && defined(mingw32_HOST_OS))