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 * --------------------------------------------------------------------------*/
16 import pthread_mutex_lock;
17 import base_GHCziBase_Czh_static_info;
18 import base_GHCziBase_Izh_static_info;
20 import EnterCriticalSection;
21 import LeaveCriticalSection;
23 /* ----------------------------------------------------------------------------
24 Support for the bytecode interpreter.
25 ------------------------------------------------------------------------- */
27 /* 9 bits of return code for constructors created by the interpreter. */
28 stg_interp_constr_entry
30 /* R1 points at the constructor */
31 jump %ENTRY_CODE(Sp(0));
34 /* Some info tables to be used when compiled code returns a value to
35 the interpreter, i.e. the interpreter pushes one of these onto the
36 stack before entering a value. What the code does is to
37 impedance-match the compiled return convention (in R1p/R1n/F1/D1 etc) to
38 the interpreter's convention (returned value is on top of stack),
39 and then cause the scheduler to enter the interpreter.
41 On entry, the stack (growing down) looks like this:
43 ptr to BCO holding return continuation
44 ptr to one of these info tables.
46 The info table code, both direct and vectored, must:
47 * push R1/F1/D1 on the stack, and its tag if necessary
48 * push the BCO (so it's now on the stack twice)
49 * Yield, ie, go to the scheduler.
51 Scheduler examines the t.o.s, discovers it is a BCO, and proceeds
52 directly to the bytecode interpreter. That pops the top element
53 (the BCO, containing the return continuation), and interprets it.
54 Net result: return continuation gets interpreted, with the
58 ptr to the info table just jumped thru
61 which is just what we want -- the "standard" return layout for the
64 Don't ask me how unboxed tuple returns are supposed to work. We
65 haven't got a good story about that yet.
68 INFO_TABLE_RET( stg_ctoi_R1p, RET_BCO)
72 Sp(0) = stg_enter_info;
73 jump stg_yield_to_interpreter;
77 * When the returned value is a pointer, but unlifted, in R1 ...
79 INFO_TABLE_RET( stg_ctoi_R1unpt, RET_BCO )
83 Sp(0) = stg_gc_unpt_r1_info;
84 jump stg_yield_to_interpreter;
88 * When the returned value is a non-pointer in R1 ...
90 INFO_TABLE_RET( stg_ctoi_R1n, RET_BCO )
94 Sp(0) = stg_gc_unbx_r1_info;
95 jump stg_yield_to_interpreter;
99 * When the returned value is in F1
101 INFO_TABLE_RET( stg_ctoi_F1, RET_BCO )
104 F_[Sp + WDS(1)] = F1;
105 Sp(0) = stg_gc_f1_info;
106 jump stg_yield_to_interpreter;
110 * When the returned value is in D1
112 INFO_TABLE_RET( stg_ctoi_D1, RET_BCO )
114 Sp_adj(-1) - SIZEOF_DOUBLE;
115 D_[Sp + WDS(1)] = D1;
116 Sp(0) = stg_gc_d1_info;
117 jump stg_yield_to_interpreter;
121 * When the returned value is in L1
123 INFO_TABLE_RET( stg_ctoi_L1, RET_BCO )
126 L_[Sp + WDS(1)] = L1;
127 Sp(0) = stg_gc_l1_info;
128 jump stg_yield_to_interpreter;
132 * When the returned value is a void
134 INFO_TABLE_RET( stg_ctoi_V, RET_BCO )
137 Sp(0) = stg_gc_void_info;
138 jump stg_yield_to_interpreter;
142 * Dummy info table pushed on the top of the stack when the interpreter
143 * should apply the BCO on the stack to its arguments, also on the
146 INFO_TABLE_RET( stg_apply_interp, RET_BCO )
148 /* Just in case we end up in here... (we shouldn't) */
149 jump stg_yield_to_interpreter;
152 /* ----------------------------------------------------------------------------
154 ------------------------------------------------------------------------- */
156 INFO_TABLE_FUN( stg_BCO, 4, 0, BCO, "BCO", "BCO", ARG_BCO )
158 /* entering a BCO means "apply it", same as a function */
161 Sp(0) = stg_apply_interp_info;
162 jump stg_yield_to_interpreter;
165 /* ----------------------------------------------------------------------------
166 Info tables for indirections.
168 SPECIALISED INDIRECTIONS: we have a specialised indirection for direct returns,
169 so that we can avoid entering
170 the object when we know it points directly to a value. The update
171 code (Updates.cmm) updates objects with the appropriate kind of
172 indirection. We only do this for young-gen indirections.
173 ------------------------------------------------------------------------- */
175 INFO_TABLE(stg_IND,1,0,IND,"IND","IND")
177 TICK_ENT_DYN_IND(); /* tick */
178 R1 = UNTAG(StgInd_indirectee(R1));
183 INFO_TABLE(stg_IND_direct,1,0,IND,"IND","IND")
185 TICK_ENT_DYN_IND(); /* tick */
186 R1 = StgInd_indirectee(R1);
188 jump %ENTRY_CODE(Sp(0));
191 INFO_TABLE(stg_IND_STATIC,1,0,IND_STATIC,"IND_STATIC","IND_STATIC")
193 TICK_ENT_STATIC_IND(); /* tick */
194 R1 = UNTAG(StgInd_indirectee(R1));
199 INFO_TABLE(stg_IND_PERM,1,0,IND_PERM,"IND_PERM","IND_PERM")
201 /* Don't add INDs to granularity cost */
203 /* Don't: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is
204 here only to help profiling */
206 #if defined(TICKY_TICKY) && !defined(PROFILING)
207 /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than
214 /* Enter PAP cost centre */
215 ENTER_CCS_PAP_CL(R1);
217 /* For ticky-ticky, change the perm_ind to a normal ind on first
218 * entry, so the number of ent_perm_inds is the number of *thunks*
219 * entered again, not the number of subsequent entries.
221 * Since this screws up cost centres, we die if profiling and
222 * ticky_ticky are on at the same time. KSW 1999-01.
226 # error Profiling and ticky-ticky do not mix at present!
227 # endif /* PROFILING */
228 StgHeader_info(R1) = stg_IND_info;
229 #endif /* TICKY_TICKY */
231 R1 = UNTAG(StgInd_indirectee(R1));
233 #if defined(TICKY_TICKY) && !defined(PROFILING)
241 INFO_TABLE(stg_IND_OLDGEN,1,0,IND_OLDGEN,"IND_OLDGEN","IND_OLDGEN")
243 TICK_ENT_STATIC_IND(); /* tick */
244 R1 = UNTAG(StgInd_indirectee(R1));
249 INFO_TABLE(stg_IND_OLDGEN_PERM,1,0,IND_OLDGEN_PERM,"IND_OLDGEN_PERM","IND_OLDGEN_PERM")
251 /* Don't: TICK_ENT_STATIC_IND(Node); for ticky-ticky;
252 this ind is here only to help profiling */
254 #if defined(TICKY_TICKY) && !defined(PROFILING)
255 /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND,
256 rather than being extra */
257 TICK_ENT_PERM_IND(); /* tick */
262 /* Enter PAP cost centre -- lexical scoping only */
263 ENTER_CCS_PAP_CL(R1);
265 /* see comment in IND_PERM */
268 # error Profiling and ticky-ticky do not mix at present!
269 # endif /* PROFILING */
270 StgHeader_info(R1) = stg_IND_OLDGEN_info;
271 #endif /* TICKY_TICKY */
273 R1 = UNTAG(StgInd_indirectee(R1));
279 /* ----------------------------------------------------------------------------
282 Entering a black hole normally causes a cyclic data dependency, but
283 in the concurrent world, black holes are synchronization points,
284 and they are turned into blocking queues when there are threads
285 waiting for the evaluation of the closure to finish.
286 ------------------------------------------------------------------------- */
288 /* Note: a BLACKHOLE must be big enough to be
289 * overwritten with an indirection/evacuee/catch. Thus we claim it
290 * has 1 non-pointer word of payload.
292 INFO_TABLE(stg_BLACKHOLE,0,1,BLACKHOLE,"BLACKHOLE","BLACKHOLE")
295 /* Before overwriting TSO_LINK */
296 STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1 /*Node*/);
302 // foreign "C" debugBelch("BLACKHOLE entry\n");
305 /* Actually this is not necessary because R1 is about to be destroyed. */
308 #if defined(THREADED_RTS)
309 ACQUIRE_LOCK(sched_mutex "ptr");
310 // released in stg_block_blackhole_finally
313 /* Put ourselves on the blackhole queue */
314 StgTSO_link(CurrentTSO) = W_[blackhole_queue];
315 W_[blackhole_queue] = CurrentTSO;
317 /* jot down why and on what closure we are blocked */
318 StgTSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16;
319 StgTSO_block_info(CurrentTSO) = R1;
321 jump stg_block_blackhole;
324 #if defined(PAR) || defined(GRAN)
326 INFO_TABLE(stg_RBH,1,1,RBH,"RBH","RBH")
329 /* mainly statistics gathering for GranSim simulation */
330 STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1 /*Node*/);
333 /* exactly the same as a BLACKHOLE_BQ_entry -- HWL */
334 /* Put ourselves on the blocking queue for this black hole */
335 TSO_link(CurrentTSO) = StgBlockingQueue_blocking_queue(R1);
336 StgBlockingQueue_blocking_queue(R1) = CurrentTSO;
337 /* jot down why and on what closure we are blocked */
338 TSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16;
339 TSO_block_info(CurrentTSO) = R1;
341 /* PAR: dumping of event now done in blockThread -- HWL */
343 /* stg_gen_block is too heavyweight, use a specialised one */
347 INFO_TABLE(stg_RBH_Save_0,0,2,CONSTR,"RBH_Save_0","RBH_Save_0")
348 { foreign "C" barf("RBH_Save_0 object entered!") never returns; }
350 INFO_TABLE(stg_RBH_Save_1,1,1,CONSTR,"RBH_Save_1","RBH_Save_1");
351 { foreign "C" barf("RBH_Save_1 object entered!") never returns; }
353 INFO_TABLE(stg_RBH_Save_2,2,0,CONSTR,"RBH_Save_2","RBH_Save_2");
354 { foreign "C" barf("RBH_Save_2 object entered!") never returns; }
356 #endif /* defined(PAR) || defined(GRAN) */
358 /* identical to BLACKHOLEs except for the infotag */
359 INFO_TABLE(stg_CAF_BLACKHOLE,0,1,CAF_BLACKHOLE,"CAF_BLACKHOLE","CAF_BLACKHOLE")
362 /* mainly statistics gathering for GranSim simulation */
363 STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1 /*Node*/);
369 #if defined(THREADED_RTS)
370 // foreign "C" debugBelch("BLACKHOLE entry\n");
373 #if defined(THREADED_RTS)
374 ACQUIRE_LOCK(sched_mutex "ptr");
375 // released in stg_block_blackhole_finally
378 /* Put ourselves on the blackhole queue */
379 StgTSO_link(CurrentTSO) = W_[blackhole_queue];
380 W_[blackhole_queue] = CurrentTSO;
382 /* jot down why and on what closure we are blocked */
383 StgTSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16;
384 StgTSO_block_info(CurrentTSO) = R1;
386 jump stg_block_blackhole;
389 #ifdef EAGER_BLACKHOLING
390 INFO_TABLE(stg_SE_BLACKHOLE,0,1,SE_BLACKHOLE,"SE_BLACKHOLE","SE_BLACKHOLE")
391 { foreign "C" barf("SE_BLACKHOLE object entered!") never returns; }
393 INFO_TABLE(stg_SE_CAF_BLACKHOLE,0,1,SE_CAF_BLACKHOLE,"SE_CAF_BLACKHOLE","SE_CAF_BLACKHOLE")
394 { foreign "C" barf("SE_CAF_BLACKHOLE object entered!") never returns; }
397 /* ----------------------------------------------------------------------------
398 Whiteholes are used for the "locked" state of a closure (see lockClosure())
400 The closure type is BLAKCHOLE, just because we need a valid closure type
402 ------------------------------------------------------------------------- */
404 INFO_TABLE(stg_WHITEHOLE, 0,0, BLACKHOLE, "WHITEHOLE", "WHITEHOLE")
405 { foreign "C" barf("WHITEHOLE object entered!") never returns; }
407 /* ----------------------------------------------------------------------------
408 Some static info tables for things that don't get entered, and
409 therefore don't need entry code (i.e. boxed but unpointed objects)
410 NON_ENTERABLE_ENTRY_CODE now defined at the beginning of the file
411 ------------------------------------------------------------------------- */
413 INFO_TABLE(stg_TSO, 0,0,TSO, "TSO", "TSO")
414 { foreign "C" barf("TSO object entered!") never returns; }
416 /* ----------------------------------------------------------------------------
417 Evacuees are left behind by the garbage collector. Any attempt to enter
419 ------------------------------------------------------------------------- */
421 INFO_TABLE(stg_EVACUATED,1,0,EVACUATED,"EVACUATED","EVACUATED")
422 { foreign "C" barf("EVACUATED object entered!") never returns; }
424 /* ----------------------------------------------------------------------------
427 Live weak pointers have a special closure type. Dead ones are just
428 nullary constructors (although they live on the heap - we overwrite
429 live weak pointers with dead ones).
430 ------------------------------------------------------------------------- */
432 INFO_TABLE(stg_WEAK,0,4,WEAK,"WEAK","WEAK")
433 { foreign "C" barf("WEAK object entered!") never returns; }
436 * It's important when turning an existing WEAK into a DEAD_WEAK
437 * (which is what finalizeWeak# does) that we don't lose the link
438 * field and break the linked list of weak pointers. Hence, we give
439 * DEAD_WEAK 4 non-pointer fields, the same as WEAK.
441 INFO_TABLE_CONSTR(stg_DEAD_WEAK,0,4,0,CONSTR,"DEAD_WEAK","DEAD_WEAK")
442 { foreign "C" barf("DEAD_WEAK object entered!") never returns; }
444 /* ----------------------------------------------------------------------------
447 This is a static nullary constructor (like []) that we use to mark an empty
448 finalizer in a weak pointer object.
449 ------------------------------------------------------------------------- */
451 INFO_TABLE_CONSTR(stg_NO_FINALIZER,0,0,0,CONSTR_NOCAF_STATIC,"NO_FINALIZER","NO_FINALIZER")
452 { foreign "C" barf("NO_FINALIZER object entered!") never returns; }
454 CLOSURE(stg_NO_FINALIZER_closure,stg_NO_FINALIZER);
456 /* ----------------------------------------------------------------------------
457 Stable Names are unlifted too.
458 ------------------------------------------------------------------------- */
460 INFO_TABLE(stg_STABLE_NAME,0,1,STABLE_NAME,"STABLE_NAME","STABLE_NAME")
461 { foreign "C" barf("STABLE_NAME object entered!") never returns; }
463 /* ----------------------------------------------------------------------------
466 There are two kinds of these: full and empty. We need an info table
467 and entry code for each type.
468 ------------------------------------------------------------------------- */
470 INFO_TABLE(stg_MVAR_CLEAN,3,0,MVAR_CLEAN,"MVAR","MVAR")
471 { foreign "C" barf("MVAR object entered!") never returns; }
473 INFO_TABLE(stg_MVAR_DIRTY,3,0,MVAR_DIRTY,"MVAR","MVAR")
474 { foreign "C" barf("MVAR object entered!") never returns; }
476 /* -----------------------------------------------------------------------------
478 -------------------------------------------------------------------------- */
480 INFO_TABLE(stg_TVAR, 0, 0, TVAR, "TVAR", "TVAR")
481 { foreign "C" barf("TVAR object entered!") never returns; }
483 INFO_TABLE(stg_TVAR_WATCH_QUEUE, 0, 0, TVAR_WATCH_QUEUE, "TVAR_WATCH_QUEUE", "TVAR_WATCH_QUEUE")
484 { foreign "C" barf("TVAR_WATCH_QUEUE object entered!") never returns; }
486 INFO_TABLE(stg_ATOMIC_INVARIANT, 0, 0, ATOMIC_INVARIANT, "ATOMIC_INVARIANT", "ATOMIC_INVARIANT")
487 { foreign "C" barf("ATOMIC_INVARIANT object entered!") never returns; }
489 INFO_TABLE(stg_INVARIANT_CHECK_QUEUE, 0, 0, INVARIANT_CHECK_QUEUE, "INVARIANT_CHECK_QUEUE", "INVARIANT_CHECK_QUEUE")
490 { foreign "C" barf("INVARIANT_CHECK_QUEUE object entered!") never returns; }
492 INFO_TABLE(stg_TREC_CHUNK, 0, 0, TREC_CHUNK, "TREC_CHUNK", "TREC_CHUNK")
493 { foreign "C" barf("TREC_CHUNK object entered!") never returns; }
495 INFO_TABLE(stg_TREC_HEADER, 0, 0, TREC_HEADER, "TREC_HEADER", "TREC_HEADER")
496 { foreign "C" barf("TREC_HEADER object entered!") never returns; }
498 INFO_TABLE_CONSTR(stg_END_STM_WATCH_QUEUE,0,0,0,CONSTR_NOCAF_STATIC,"END_STM_WATCH_QUEUE","END_STM_WATCH_QUEUE")
499 { foreign "C" barf("END_STM_WATCH_QUEUE object entered!") never returns; }
501 INFO_TABLE_CONSTR(stg_END_INVARIANT_CHECK_QUEUE,0,0,0,CONSTR_NOCAF_STATIC,"END_INVARIANT_CHECK_QUEUE","END_INVARIANT_CHECK_QUEUE")
502 { foreign "C" barf("END_INVARIANT_CHECK_QUEUE object entered!") never returns; }
504 INFO_TABLE_CONSTR(stg_END_STM_CHUNK_LIST,0,0,0,CONSTR_NOCAF_STATIC,"END_STM_CHUNK_LIST","END_STM_CHUNK_LIST")
505 { foreign "C" barf("END_STM_CHUNK_LIST object entered!") never returns; }
507 INFO_TABLE_CONSTR(stg_NO_TREC,0,0,0,CONSTR_NOCAF_STATIC,"NO_TREC","NO_TREC")
508 { foreign "C" barf("NO_TREC object entered!") never returns; }
510 CLOSURE(stg_END_STM_WATCH_QUEUE_closure,stg_END_STM_WATCH_QUEUE);
512 CLOSURE(stg_END_INVARIANT_CHECK_QUEUE_closure,stg_END_INVARIANT_CHECK_QUEUE);
514 CLOSURE(stg_END_STM_CHUNK_LIST_closure,stg_END_STM_CHUNK_LIST);
516 CLOSURE(stg_NO_TREC_closure,stg_NO_TREC);
518 /* ----------------------------------------------------------------------------
521 This is a static nullary constructor (like []) that we use to mark the
522 end of a linked TSO queue.
523 ------------------------------------------------------------------------- */
525 INFO_TABLE_CONSTR(stg_END_TSO_QUEUE,0,0,0,CONSTR_NOCAF_STATIC,"END_TSO_QUEUE","END_TSO_QUEUE")
526 { foreign "C" barf("END_TSO_QUEUE object entered!") never returns; }
528 CLOSURE(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE);
530 /* ----------------------------------------------------------------------------
532 ------------------------------------------------------------------------- */
534 INFO_TABLE_CONSTR(stg_END_EXCEPTION_LIST,0,0,0,CONSTR_NOCAF_STATIC,"END_EXCEPTION_LIST","END_EXCEPTION_LIST")
535 { foreign "C" barf("END_EXCEPTION_LIST object entered!") never returns; }
537 CLOSURE(stg_END_EXCEPTION_LIST_closure,stg_END_EXCEPTION_LIST);
539 INFO_TABLE(stg_EXCEPTION_CONS,1,1,CONSTR,"EXCEPTION_CONS","EXCEPTION_CONS")
540 { foreign "C" barf("EXCEPTION_CONS object entered!") never returns; }
542 /* ----------------------------------------------------------------------------
545 These come in two basic flavours: arrays of data (StgArrWords) and arrays of
546 pointers (StgArrPtrs). They all have a similar layout:
548 ___________________________
549 | Info | No. of | data....
551 ---------------------------
553 These are *unpointed* objects: i.e. they cannot be entered.
555 ------------------------------------------------------------------------- */
557 INFO_TABLE(stg_ARR_WORDS, 0, 0, ARR_WORDS, "ARR_WORDS", "ARR_WORDS")
558 { foreign "C" barf("ARR_WORDS object entered!") never returns; }
560 INFO_TABLE(stg_MUT_ARR_PTRS_CLEAN, 0, 0, MUT_ARR_PTRS_CLEAN, "MUT_ARR_PTRS_CLEAN", "MUT_ARR_PTRS_CLEAN")
561 { foreign "C" barf("MUT_ARR_PTRS_CLEAN object entered!") never returns; }
563 INFO_TABLE(stg_MUT_ARR_PTRS_DIRTY, 0, 0, MUT_ARR_PTRS_DIRTY, "MUT_ARR_PTRS_DIRTY", "MUT_ARR_PTRS_DIRTY")
564 { foreign "C" barf("MUT_ARR_PTRS_DIRTY object entered!") never returns; }
566 INFO_TABLE(stg_MUT_ARR_PTRS_FROZEN, 0, 0, MUT_ARR_PTRS_FROZEN, "MUT_ARR_PTRS_FROZEN", "MUT_ARR_PTRS_FROZEN")
567 { foreign "C" barf("MUT_ARR_PTRS_FROZEN object entered!") never returns; }
569 INFO_TABLE(stg_MUT_ARR_PTRS_FROZEN0, 0, 0, MUT_ARR_PTRS_FROZEN0, "MUT_ARR_PTRS_FROZEN0", "MUT_ARR_PTRS_FROZEN0")
570 { foreign "C" barf("MUT_ARR_PTRS_FROZEN0 object entered!") never returns; }
572 /* ----------------------------------------------------------------------------
574 ------------------------------------------------------------------------- */
576 INFO_TABLE(stg_MUT_VAR_CLEAN, 1, 0, MUT_VAR_CLEAN, "MUT_VAR_CLEAN", "MUT_VAR_CLEAN")
577 { foreign "C" barf("MUT_VAR_CLEAN object entered!") never returns; }
578 INFO_TABLE(stg_MUT_VAR_DIRTY, 1, 0, MUT_VAR_DIRTY, "MUT_VAR_DIRTY", "MUT_VAR_DIRTY")
579 { foreign "C" barf("MUT_VAR_DIRTY object entered!") never returns; }
581 /* ----------------------------------------------------------------------------
584 Entering this closure will just return to the address on the top of the
585 stack. Useful for getting a thread in a canonical form where we can
586 just enter the top stack word to start the thread. (see deleteThread)
587 * ------------------------------------------------------------------------- */
589 INFO_TABLE( stg_dummy_ret, 0, 0, CONSTR_NOCAF_STATIC, "DUMMY_RET", "DUMMY_RET")
591 jump %ENTRY_CODE(Sp(0));
593 CLOSURE(stg_dummy_ret_closure,stg_dummy_ret);
595 /* ----------------------------------------------------------------------------
596 CHARLIKE and INTLIKE closures.
598 These are static representations of Chars and small Ints, so that
599 we can remove dynamic Chars and Ints during garbage collection and
600 replace them with references to the static objects.
601 ------------------------------------------------------------------------- */
603 #if defined(__PIC__) && defined(mingw32_TARGET_OS)
605 * When sticking the RTS in a DLL, we delay populating the
606 * Charlike and Intlike tables until load-time, which is only
607 * when we've got the real addresses to the C# and I# closures.
610 #warning Is this correct? _imp is a pointer!
611 #define Char_hash_static_info _imp__base_GHCziBase_Czh_static
612 #define Int_hash_static_info _imp__base_GHCziBase_Izh_static
614 #define Char_hash_static_info base_GHCziBase_Czh_static
615 #define Int_hash_static_info base_GHCziBase_Izh_static
619 #define CHARLIKE_HDR(n) CLOSURE(Char_hash_static_info, n)
620 #define INTLIKE_HDR(n) CLOSURE(Int_hash_static_info, n)
622 /* put these in the *data* section, since the garbage collector relies
623 * on the fact that static closures live in the data section.
626 /* end the name with _closure, to convince the mangler this is a closure */
629 stg_CHARLIKE_closure:
890 INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
922 INTLIKE_HDR(16) /* MAX_INTLIKE == 16 */