[project @ 2002-09-17 12:32:40 by simonmar]
[ghc-hetmet.git] / ghc / rts / StgMiscClosures.hc
1 /* -----------------------------------------------------------------------------
2  * $Id: StgMiscClosures.hc,v 1.78 2002/09/17 12:32:40 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-2000
5  *
6  * Entry code for various built-in closure types.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "Stg.h"
11 #include "Rts.h"
12 #include "RtsUtils.h"
13 #include "RtsFlags.h"
14 #include "StgMiscClosures.h"
15 #include "Storage.h"
16 #include "StoragePriv.h"
17 #include "Profiling.h"
18 #include "Prelude.h"
19 #include "Schedule.h"
20 #include "SMP.h"
21 #if defined(GRAN) || defined(PAR)
22 # include "GranSimRts.h"      /* for DumpRawGranEvent */
23 # include "StgRun.h"    /* for StgReturn and register saving */
24 #endif
25
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29
30 /* ToDo: make the printing of panics more win32-friendly, i.e.,
31  *       pop up some lovely message boxes (as well).
32  */
33 #define DUMP_ERRMSG(msg) STGCALL2(fprintf,stderr,msg)
34
35 /*
36   Template for the entry code of non-enterable closures.
37 */
38
39 #define NON_ENTERABLE_ENTRY_CODE(type)          \
40 STGFUN(stg_##type##_entry)                      \
41 {                                               \
42   FB_                                           \
43     barf(#type " object entered!\n");           \
44     return NULL;                                \
45   FE_                                           \
46 }
47
48
49 /* -----------------------------------------------------------------------------
50    Support for the bytecode interpreter.
51    -------------------------------------------------------------------------- */
52
53 /* 9 bits of return code for constructors created by the interpreter. */
54 FN_(stg_interp_constr_entry) 
55
56   /* R1 points at the constructor */
57   FB_ 
58     /* STGCALL2(fprintf,stderr,"stg_interp_constr_entry (direct return)!\n"); */
59     /* Pointless, since SET_TAG doesn't do anything */
60     SET_TAG( GET_TAG(GET_INFO(R1.cl))); 
61     JMP_(ENTRY_CODE((P_)(*Sp))); 
62   FE_ 
63 }
64
65 FN_(stg_interp_constr1_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),0)); FE_ }
66 FN_(stg_interp_constr2_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),1)); FE_ }
67 FN_(stg_interp_constr3_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),2)); FE_ }
68 FN_(stg_interp_constr4_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),3)); FE_ }
69 FN_(stg_interp_constr5_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),4)); FE_ }
70 FN_(stg_interp_constr6_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),5)); FE_ }
71 FN_(stg_interp_constr7_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),6)); FE_ }
72 FN_(stg_interp_constr8_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),7)); FE_ }
73  
74 /* Some info tables to be used when compiled code returns a value to
75    the interpreter, i.e. the interpreter pushes one of these onto the
76    stack before entering a value.  What the code does is to
77    impedance-match the compiled return convention (in R1p/R1n/F1/D1 etc) to
78    the interpreter's convention (returned value is on top of stack),
79    and then cause the scheduler to enter the interpreter.
80
81    On entry, the stack (growing down) looks like this:
82
83       ptr to BCO holding return continuation
84       ptr to one of these info tables.
85  
86    The info table code, both direct and vectored, must:
87       * push R1/F1/D1 on the stack, and its tag if necessary
88       * push the BCO (so it's now on the stack twice)
89       * Yield, ie, go to the scheduler.
90
91    Scheduler examines the t.o.s, discovers it is a BCO, and proceeds
92    directly to the bytecode interpreter.  That pops the top element
93    (the BCO, containing the return continuation), and interprets it.
94    Net result: return continuation gets interpreted, with the
95    following stack:
96
97       ptr to this BCO
98       ptr to the info table just jumped thru
99       return value
100
101    which is just what we want -- the "standard" return layout for the
102    interpreter.  Hurrah!
103
104    Don't ask me how unboxed tuple returns are supposed to work.  We
105    haven't got a good story about that yet.
106 */
107
108 /* When the returned value is in R1 and it is a pointer, so doesn't
109    need tagging ... */
110 #define STG_CtoI_RET_R1p_Template(label)        \
111    IFN_(label)                          \
112    {                                    \
113       StgPtr bco;                       \
114       FB_                               \
115       bco = ((StgPtr*)Sp)[1];           \
116       Sp -= 1;                          \
117       ((StgPtr*)Sp)[0] = R1.p;          \
118       Sp -= 1;                          \
119       ((StgPtr*)Sp)[0] = bco;           \
120       JMP_(stg_yield_to_interpreter);   \
121       FE_                               \
122    }
123
124 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_entry);
125 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_0_entry);
126 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_1_entry);
127 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_2_entry);
128 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_3_entry);
129 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_4_entry);
130 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_5_entry);
131 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_6_entry);
132 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_7_entry);
133
134 VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1p,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
135
136
137
138 /* When the returned value is in R1 and it isn't a pointer. */
139 #define STG_CtoI_RET_R1n_Template(label)        \
140    IFN_(label)                          \
141    {                                    \
142       StgPtr bco;                       \
143       FB_                               \
144       bco = ((StgPtr*)Sp)[1];           \
145       Sp -= 1;                          \
146       ((StgPtr*)Sp)[0] = (StgPtr)R1.i;  \
147       Sp -= 1;                          \
148       ((StgPtr*)Sp)[0] = (StgPtr)1; /* tag */   \
149       Sp -= 1;                          \
150       ((StgPtr*)Sp)[0] = bco;           \
151       JMP_(stg_yield_to_interpreter);   \
152       FE_                               \
153    }
154
155 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_entry);
156 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_0_entry);
157 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_1_entry);
158 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_2_entry);
159 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_3_entry);
160 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_4_entry);
161 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_5_entry);
162 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_6_entry);
163 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_7_entry);
164
165 VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1n,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
166
167
168
169 /* When the returned value is in F1 ... */
170 #define STG_CtoI_RET_F1_Template(label)         \
171    IFN_(label)                          \
172    {                                    \
173       StgPtr bco;                       \
174       FB_                               \
175       bco = ((StgPtr*)Sp)[1];           \
176       Sp -= sizeofW(StgFloat);          \
177       ASSIGN_FLT((W_*)Sp, F1);          \
178       Sp -= 1;                          \
179       ((StgPtr*)Sp)[0] = (StgPtr)sizeofW(StgFloat); \
180       Sp -= 1;                          \
181       ((StgPtr*)Sp)[0] = bco;           \
182       JMP_(stg_yield_to_interpreter);   \
183       FE_                               \
184    }
185
186 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_entry);
187 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_0_entry);
188 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_1_entry);
189 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_2_entry);
190 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_3_entry);
191 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_4_entry);
192 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_5_entry);
193 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_6_entry);
194 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_7_entry);
195
196 VEC_POLY_INFO_TABLE(stg_ctoi_ret_F1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
197
198
199 /* When the returned value is in D1 ... */
200 #define STG_CtoI_RET_D1_Template(label)         \
201    IFN_(label)                          \
202    {                                    \
203       StgPtr bco;                       \
204       FB_                               \
205       bco = ((StgPtr*)Sp)[1];           \
206       Sp -= sizeofW(StgDouble);         \
207       ASSIGN_DBL((W_*)Sp, D1);          \
208       Sp -= 1;                          \
209       ((StgPtr*)Sp)[0] = (StgPtr)sizeofW(StgDouble); \
210       Sp -= 1;                          \
211       ((StgPtr*)Sp)[0] = bco;           \
212       JMP_(stg_yield_to_interpreter);   \
213       FE_                               \
214    }
215
216 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_entry);
217 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_0_entry);
218 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_1_entry);
219 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_2_entry);
220 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_3_entry);
221 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_4_entry);
222 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_5_entry);
223 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_6_entry);
224 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_7_entry);
225
226 VEC_POLY_INFO_TABLE(stg_ctoi_ret_D1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
227
228
229 /* When the returned value a VoidRep ... */
230 #define STG_CtoI_RET_V_Template(label)  \
231    IFN_(label)                          \
232    {                                    \
233       StgPtr bco;                       \
234       FB_                               \
235       bco = ((StgPtr*)Sp)[1];           \
236       Sp -= 1;                          \
237       ((StgPtr*)Sp)[0] = 0; /* VoidRep tag */ \
238       Sp -= 1;                          \
239       ((StgPtr*)Sp)[0] = bco;           \
240       JMP_(stg_yield_to_interpreter);   \
241       FE_                               \
242    }
243
244 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_entry);
245 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_0_entry);
246 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_1_entry);
247 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_2_entry);
248 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_3_entry);
249 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_4_entry);
250 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_5_entry);
251 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_6_entry);
252 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_7_entry);
253
254 VEC_POLY_INFO_TABLE(stg_ctoi_ret_V,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
255
256
257 /* The other way round: when the interpreter returns a value to
258    compiled code.  The stack looks like this:
259
260       return info table (pushed by compiled code)
261       return value (pushed by interpreter)
262
263    If the value is ptr-rep'd, the interpreter simply returns to the
264    scheduler, instructing it to ThreadEnterGHC.
265
266    Otherwise (unboxed return value), we replace the top stack word,
267    which must be the tag, with stg_gc_unbx_r1_info (or f1_info or d1_info),
268    and return to the scheduler, instructing it to ThreadRunGHC.
269
270    No supporting code needed!
271 */
272
273
274 /* Entering a BCO.  Heave it on the stack and defer to the
275    scheduler. */
276 INFO_TABLE(stg_BCO_info,stg_BCO_entry,4,0,BCO,,EF_,"BCO","BCO");
277 STGFUN(stg_BCO_entry) {
278   FB_
279     Sp -= 1;
280     Sp[0] = R1.w;
281     JMP_(stg_yield_to_interpreter);
282   FE_
283 }
284
285
286 /* -----------------------------------------------------------------------------
287    Entry code for an indirection.
288    -------------------------------------------------------------------------- */
289
290 INFO_TABLE(stg_IND_info,stg_IND_entry,1,0,IND,,EF_,"IND","IND");
291 STGFUN(stg_IND_entry)
292 {
293     FB_
294     TICK_ENT_DYN_IND(Node);     /* tick */
295     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
296     TICK_ENT_VIA_NODE();
297     JMP_(GET_ENTRY(R1.cl));
298     FE_
299 }
300
301 INFO_TABLE(stg_IND_STATIC_info,stg_IND_STATIC_entry,1,0,IND_STATIC,,EF_,"IND_STATIC","IND_STATIC");
302 STGFUN(stg_IND_STATIC_entry)
303 {
304     FB_
305     TICK_ENT_STATIC_IND(Node);  /* tick */
306     R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
307     TICK_ENT_VIA_NODE();
308     JMP_(GET_ENTRY(R1.cl));
309     FE_
310 }
311
312 INFO_TABLE(stg_IND_PERM_info,stg_IND_PERM_entry,1,1,IND_PERM,,EF_,"IND_PERM","IND_PERM");
313 STGFUN(stg_IND_PERM_entry)
314 {
315     FB_
316     /* Don't add INDs to granularity cost */
317     /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */
318
319 #if defined(TICKY_TICKY) && !defined(PROFILING)
320     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
321     TICK_ENT_PERM_IND(R1.p); /* tick */
322 #endif
323
324     LDV_ENTER((StgInd *)R1.p);
325
326     /* Enter PAP cost centre -- lexical scoping only */
327     ENTER_CCS_PAP_CL(R1.cl);
328
329     /* For ticky-ticky, change the perm_ind to a normal ind on first
330      * entry, so the number of ent_perm_inds is the number of *thunks*
331      * entered again, not the number of subsequent entries.
332      *
333      * Since this screws up cost centres, we die if profiling and
334      * ticky_ticky are on at the same time.  KSW 1999-01.
335      */
336
337 #ifdef TICKY_TICKY
338 #  ifdef PROFILING
339 #    error Profiling and ticky-ticky do not mix at present!
340 #  endif  /* PROFILING */
341     SET_INFO((StgInd*)R1.p,&stg_IND_info);
342 #endif /* TICKY_TICKY */
343
344     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
345
346     /* Dont: TICK_ENT_VIA_NODE(); for ticky-ticky; as above */
347
348 #if defined(TICKY_TICKY) && !defined(PROFILING)
349     TICK_ENT_VIA_NODE();
350 #endif
351
352     JMP_(GET_ENTRY(R1.cl));
353     FE_
354 }  
355
356 INFO_TABLE(stg_IND_OLDGEN_info,stg_IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,"IND_OLDGEN","IND_OLDGEN");
357 STGFUN(stg_IND_OLDGEN_entry)
358 {
359     FB_
360     TICK_ENT_STATIC_IND(Node);  /* tick */
361     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
362     TICK_ENT_VIA_NODE();
363     JMP_(GET_ENTRY(R1.cl));
364     FE_
365 }
366
367 INFO_TABLE(stg_IND_OLDGEN_PERM_info,stg_IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,"IND_OLDGEN_PERM","IND_OLDGEN_PERM");
368 STGFUN(stg_IND_OLDGEN_PERM_entry)
369 {
370     FB_
371     /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */
372
373 #if defined(TICKY_TICKY) && !defined(PROFILING)
374     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
375     TICK_ENT_PERM_IND(R1.p); /* tick */
376 #endif
377
378     LDV_ENTER((StgInd *)R1.p);
379
380     /* Enter PAP cost centre -- lexical scoping only */
381     ENTER_CCS_PAP_CL(R1.cl);
382
383     /* see comment in IND_PERM */
384 #ifdef TICKY_TICKY
385 #  ifdef PROFILING
386 #    error Profiling and ticky-ticky do not mix at present!
387 #  endif  /* PROFILING */
388     SET_INFO((StgInd*)R1.p,&stg_IND_OLDGEN_info);
389 #endif /* TICKY_TICKY */
390
391     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
392     TICK_ENT_VIA_NODE();
393     JMP_(GET_ENTRY(R1.cl));
394     FE_
395 }
396
397 /* -----------------------------------------------------------------------------
398    Entry code for a black hole.
399
400    Entering a black hole normally causes a cyclic data dependency, but
401    in the concurrent world, black holes are synchronization points,
402    and they are turned into blocking queues when there are threads
403    waiting for the evaluation of the closure to finish.
404    -------------------------------------------------------------------------- */
405
406 /* Note: a BLACKHOLE and BLACKHOLE_BQ must be big enough to be
407  * overwritten with an indirection/evacuee/catch.  Thus we claim it
408  * has 1 non-pointer word of payload (in addition to the pointer word
409  * for the blocking queue in a BQ), which should be big enough for an
410  * old-generation indirection. 
411  */
412
413 INFO_TABLE(stg_BLACKHOLE_info, stg_BLACKHOLE_entry,0,2,BLACKHOLE,,EF_,"BLACKHOLE","BLACKHOLE");
414 STGFUN(stg_BLACKHOLE_entry)
415 {
416   FB_
417 #if defined(GRAN)
418     /* Before overwriting TSO_LINK */
419     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
420 #endif
421
422 #ifdef SMP
423     {
424       bdescr *bd = Bdescr(R1.p);
425       if (bd->u.back != (bdescr *)BaseReg) {
426         if (bd->gen_no >= 1 || bd->step->no >= 1) {
427           CMPXCHG(R1.cl->header.info, &stg_BLACKHOLE_info, &stg_WHITEHOLE_info);
428         } else {
429           EXTFUN_RTS(stg_gc_enter_1_hponly);
430           JMP_(stg_gc_enter_1_hponly);
431         }
432       }
433     }
434 #endif
435     TICK_ENT_BH();
436
437     // Actually this is not necessary because R1.p is about to be destroyed.
438     LDV_ENTER((StgClosure *)R1.p);
439
440     /* Put ourselves on the blocking queue for this black hole */
441 #if defined(GRAN) || defined(PAR)
442     // in fact, only difference is the type of the end-of-queue marker!
443     CurrentTSO->link = END_BQ_QUEUE;
444     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
445 #else
446     CurrentTSO->link = END_TSO_QUEUE;
447     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
448 #endif
449     // jot down why and on what closure we are blocked
450     CurrentTSO->why_blocked = BlockedOnBlackHole;
451     CurrentTSO->block_info.closure = R1.cl;
452
453     /* Change the BLACKHOLE into a BLACKHOLE_BQ */
454 #ifdef PROFILING
455
456     // The size remains the same, so we call LDV_recordDead() - no need to fill slop.
457     LDV_recordDead((StgClosure *)R1.p, BLACKHOLE_sizeW());
458 #endif
459     // 
460     // Todo: maybe use SET_HDR() and remove LDV_recordCreate()?
461     // 
462     ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info;
463 #ifdef PROFILING
464     LDV_recordCreate((StgClosure *)R1.p);
465 #endif
466
467     // closure is mutable since something has just been added to its BQ
468     recordMutable((StgMutClosure *)R1.cl);
469
470     // PAR: dumping of event now done in blockThread -- HWL
471
472     // stg_gen_block is too heavyweight, use a specialised one
473     BLOCK_NP(1);
474   FE_
475 }
476
477 INFO_TABLE(stg_BLACKHOLE_BQ_info, stg_BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,,EF_,"BLACKHOLE","BLACKHOLE");
478 STGFUN(stg_BLACKHOLE_BQ_entry)
479 {
480   FB_
481 #if defined(GRAN)
482     /* Before overwriting TSO_LINK */
483     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
484 #endif
485
486 #ifdef SMP
487     {
488       bdescr *bd = Bdescr(R1.p);
489       if (bd->u.back != (bdescr *)BaseReg) {
490         if (bd->gen_no >= 1 || bd->step->no >= 1) {
491           CMPXCHG(R1.cl->header.info, &stg_BLACKHOLE_info, &stg_WHITEHOLE_info);
492         } else {
493           EXTFUN_RTS(stg_gc_enter_1_hponly);
494           JMP_(stg_gc_enter_1_hponly);
495         }
496       }
497     }
498 #endif
499
500     TICK_ENT_BH();
501     LDV_ENTER((StgClosure *)R1.p);
502
503     /* Put ourselves on the blocking queue for this black hole */
504     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
505     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
506     /* jot down why and on what closure we are blocked */
507     CurrentTSO->why_blocked = BlockedOnBlackHole;
508     CurrentTSO->block_info.closure = R1.cl;
509 #ifdef SMP
510     ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info;
511 #endif
512
513     /* PAR: dumping of event now done in blockThread -- HWL */
514
515     /* stg_gen_block is too heavyweight, use a specialised one */
516     BLOCK_NP(1);
517   FE_
518 }
519
520 /*
521    Revertible black holes are needed in the parallel world, to handle
522    negative acknowledgements of messages containing updatable closures.
523    The idea is that when the original message is transmitted, the closure
524    is turned into a revertible black hole...an object which acts like a
525    black hole when local threads try to enter it, but which can be reverted
526    back to the original closure if necessary.
527
528    It's actually a lot like a blocking queue (BQ) entry, because revertible
529    black holes are initially set up with an empty blocking queue.
530 */
531
532 #if defined(PAR) || defined(GRAN)
533
534 INFO_TABLE(stg_RBH_info, stg_RBH_entry,1,1,RBH,,EF_,"RBH","RBH");
535 STGFUN(stg_RBH_entry)
536 {
537   FB_
538 # if defined(GRAN)
539     /* mainly statistics gathering for GranSim simulation */
540     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
541 # endif
542
543     /* exactly the same as a BLACKHOLE_BQ_entry -- HWL */
544     /* Put ourselves on the blocking queue for this black hole */
545     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
546     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
547     /* jot down why and on what closure we are blocked */
548     CurrentTSO->why_blocked = BlockedOnBlackHole;
549     CurrentTSO->block_info.closure = R1.cl;
550
551     /* PAR: dumping of event now done in blockThread -- HWL */
552
553     /* stg_gen_block is too heavyweight, use a specialised one */
554     BLOCK_NP(1); 
555   FE_
556 }
557
558 INFO_TABLE(stg_RBH_Save_0_info, stg_RBH_Save_0_entry,0,2,CONSTR,,EF_,"RBH_Save_0","RBH_Save_0");
559 NON_ENTERABLE_ENTRY_CODE(RBH_Save_0);
560
561 INFO_TABLE(stg_RBH_Save_1_info, stg_RBH_Save_1_entry,1,1,CONSTR,,EF_,"RBH_Save_1","RBH_Save_1");
562 NON_ENTERABLE_ENTRY_CODE(RBH_Save_1);
563
564 INFO_TABLE(stg_RBH_Save_2_info, stg_RBH_Save_2_entry,2,0,CONSTR,,EF_,"RBH_Save_2","RBH_Save_2");
565 NON_ENTERABLE_ENTRY_CODE(RBH_Save_2);
566 #endif /* defined(PAR) || defined(GRAN) */
567
568 /* identical to BLACKHOLEs except for the infotag */
569 INFO_TABLE(stg_CAF_BLACKHOLE_info, stg_CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,,EF_,"CAF_BLACKHOLE","CAF_BLACKHOLE");
570 STGFUN(stg_CAF_BLACKHOLE_entry)
571 {
572   FB_
573 #if defined(GRAN)
574     /* mainly statistics gathering for GranSim simulation */
575     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
576 #endif
577
578 #ifdef SMP
579     {
580       bdescr *bd = Bdescr(R1.p);
581       if (bd->u.back != (bdescr *)BaseReg) {
582         if (bd->gen_no >= 1 || bd->step->no >= 1) {
583           CMPXCHG(R1.cl->header.info, &stg_CAF_BLACKHOLE_info, &stg_WHITEHOLE_info);
584         } else {
585           EXTFUN_RTS(stg_gc_enter_1_hponly);
586           JMP_(stg_gc_enter_1_hponly);
587         }
588       }
589     }
590 #endif
591
592     TICK_ENT_BH();
593     LDV_ENTER((StgClosure *)R1.p);
594
595     // Put ourselves on the blocking queue for this black hole
596 #if defined(GRAN) || defined(PAR)
597     // in fact, only difference is the type of the end-of-queue marker!
598     CurrentTSO->link = END_BQ_QUEUE;
599     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
600 #else
601     CurrentTSO->link = END_TSO_QUEUE;
602     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
603 #endif
604     // jot down why and on what closure we are blocked
605     CurrentTSO->why_blocked = BlockedOnBlackHole;
606     CurrentTSO->block_info.closure = R1.cl;
607
608     // Change the CAF_BLACKHOLE into a BLACKHOLE_BQ_STATIC
609     ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info;
610
611     // closure is mutable since something has just been added to its BQ
612     recordMutable((StgMutClosure *)R1.cl);
613
614     // PAR: dumping of event now done in blockThread -- HWL
615
616     // stg_gen_block is too heavyweight, use a specialised one
617     BLOCK_NP(1);
618   FE_
619 }
620
621 #ifdef TICKY_TICKY
622 INFO_TABLE(stg_SE_BLACKHOLE_info, stg_SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,"SE_BLACKHOLE","SE_BLACKHOLE");
623 STGFUN(stg_SE_BLACKHOLE_entry)
624 {
625   FB_
626     STGCALL3(fprintf,stderr,"SE_BLACKHOLE at %p entered!\n",R1.p);
627     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
628   FE_
629 }
630
631 INFO_TABLE(stg_SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,"CAF_BLACKHOLE","CAF_BLACKHOLE");
632 STGFUN(stg_SE_CAF_BLACKHOLE_entry)
633 {
634   FB_
635     STGCALL3(fprintf,stderr,"SE_CAF_BLACKHOLE at %p entered!\n",R1.p);
636     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
637   FE_
638 }
639 #endif
640
641 #ifdef SMP
642 INFO_TABLE(stg_WHITEHOLE_info, stg_WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,"WHITEHOLE","WHITEHOLE");
643 STGFUN(stg_WHITEHOLE_entry)
644 {
645   FB_
646      JMP_(GET_ENTRY(R1.cl));
647   FE_
648 }
649 #endif
650
651 /* -----------------------------------------------------------------------------
652    Some static info tables for things that don't get entered, and
653    therefore don't need entry code (i.e. boxed but unpointed objects)
654    NON_ENTERABLE_ENTRY_CODE now defined at the beginning of the file
655    -------------------------------------------------------------------------- */
656
657 INFO_TABLE(stg_TSO_info, stg_TSO_entry, 0,0,TSO,,EF_,"TSO","TSO");
658 NON_ENTERABLE_ENTRY_CODE(TSO);
659
660 /* -----------------------------------------------------------------------------
661    Evacuees are left behind by the garbage collector.  Any attempt to enter
662    one is a real bug.
663    -------------------------------------------------------------------------- */
664
665 INFO_TABLE(stg_EVACUATED_info,stg_EVACUATED_entry,1,0,EVACUATED,,EF_,"EVACUATED","EVACUATED");
666 NON_ENTERABLE_ENTRY_CODE(EVACUATED);
667
668 /* -----------------------------------------------------------------------------
669    Weak pointers
670
671    Live weak pointers have a special closure type.  Dead ones are just
672    nullary constructors (although they live on the heap - we overwrite
673    live weak pointers with dead ones).
674    -------------------------------------------------------------------------- */
675
676 INFO_TABLE(stg_WEAK_info,stg_WEAK_entry,0,4,WEAK,,EF_,"WEAK","WEAK");
677 NON_ENTERABLE_ENTRY_CODE(WEAK);
678
679 // It's important when turning an existing WEAK into a DEAD_WEAK
680 // (which is what finalizeWeak# does) that we don't lose the link
681 // field and break the linked list of weak pointers.  Hence, we give
682 // DEAD_WEAK 4 non-pointer fields, the same as WEAK.
683
684 INFO_TABLE_CONSTR(stg_DEAD_WEAK_info,stg_DEAD_WEAK_entry,0,4,0,CONSTR,,EF_,"DEAD_WEAK","DEAD_WEAK");
685 NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK);
686
687 /* -----------------------------------------------------------------------------
688    NO_FINALIZER
689
690    This is a static nullary constructor (like []) that we use to mark an empty
691    finalizer in a weak pointer object.
692    -------------------------------------------------------------------------- */
693
694 INFO_TABLE_CONSTR(stg_NO_FINALIZER_info,stg_NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"NO_FINALIZER","NO_FINALIZER");
695 NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER);
696
697 SET_STATIC_HDR(stg_NO_FINALIZER_closure,stg_NO_FINALIZER_info,0/*CC*/,,EI_)
698 , /*payload*/{} };
699
700 /* -----------------------------------------------------------------------------
701    Foreign Objects are unlifted and therefore never entered.
702    -------------------------------------------------------------------------- */
703
704 INFO_TABLE(stg_FOREIGN_info,stg_FOREIGN_entry,0,1,FOREIGN,,EF_,"FOREIGN","FOREIGN");
705 NON_ENTERABLE_ENTRY_CODE(FOREIGN);
706
707 /* -----------------------------------------------------------------------------
708    Stable Names are unlifted too.
709    -------------------------------------------------------------------------- */
710
711 INFO_TABLE(stg_STABLE_NAME_info,stg_STABLE_NAME_entry,0,1,STABLE_NAME,,EF_,"STABLE_NAME","STABLE_NAME");
712 NON_ENTERABLE_ENTRY_CODE(STABLE_NAME);
713
714 /* -----------------------------------------------------------------------------
715    MVars
716
717    There are two kinds of these: full and empty.  We need an info table
718    and entry code for each type.
719    -------------------------------------------------------------------------- */
720
721 INFO_TABLE(stg_FULL_MVAR_info,stg_FULL_MVAR_entry,4,0,MVAR,,EF_,"MVAR","MVAR");
722 NON_ENTERABLE_ENTRY_CODE(FULL_MVAR);
723
724 INFO_TABLE(stg_EMPTY_MVAR_info,stg_EMPTY_MVAR_entry,4,0,MVAR,,EF_,"MVAR","MVAR");
725 NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR);
726
727 /* -----------------------------------------------------------------------------
728    END_TSO_QUEUE
729
730    This is a static nullary constructor (like []) that we use to mark the
731    end of a linked TSO queue.
732    -------------------------------------------------------------------------- */
733
734 INFO_TABLE_CONSTR(stg_END_TSO_QUEUE_info,stg_END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_TSO_QUEUE","END_TSO_QUEUE");
735 NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE);
736
737 SET_STATIC_HDR(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE_info,0/*CC*/,,EI_)
738 , /*payload*/{} };
739
740 /* -----------------------------------------------------------------------------
741    Mutable lists
742
743    Mutable lists (used by the garbage collector) consist of a chain of
744    StgMutClosures connected through their mut_link fields, ending in
745    an END_MUT_LIST closure.
746    -------------------------------------------------------------------------- */
747
748 INFO_TABLE_CONSTR(stg_END_MUT_LIST_info,stg_END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_MUT_LIST","END_MUT_LIST");
749 NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST);
750
751 SET_STATIC_HDR(stg_END_MUT_LIST_closure,stg_END_MUT_LIST_info,0/*CC*/,,EI_)
752 , /*payload*/{} };
753
754 INFO_TABLE(stg_MUT_CONS_info, stg_MUT_CONS_entry, 1, 1, MUT_CONS, , EF_, "MUT_CONS", "MUT_CONS");
755 NON_ENTERABLE_ENTRY_CODE(MUT_CONS);
756
757 /* -----------------------------------------------------------------------------
758    Exception lists
759    -------------------------------------------------------------------------- */
760
761 INFO_TABLE_CONSTR(stg_END_EXCEPTION_LIST_info,stg_END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_EXCEPTION_LIST","END_EXCEPTION_LIST");
762 NON_ENTERABLE_ENTRY_CODE(END_EXCEPTION_LIST);
763
764 SET_STATIC_HDR(stg_END_EXCEPTION_LIST_closure,stg_END_EXCEPTION_LIST_info,0/*CC*/,,EI_)
765 , /*payload*/{} };
766
767 INFO_TABLE(stg_EXCEPTION_CONS_info, stg_EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, "EXCEPTION_CONS", "EXCEPTION_CONS");
768 NON_ENTERABLE_ENTRY_CODE(EXCEPTION_CONS);
769
770 /* -----------------------------------------------------------------------------
771    Arrays
772
773    These come in two basic flavours: arrays of data (StgArrWords) and arrays of
774    pointers (StgArrPtrs).  They all have a similar layout:
775
776         ___________________________
777         | Info | No. of | data....
778         |  Ptr | Words  |
779         ---------------------------
780
781    These are *unpointed* objects: i.e. they cannot be entered.
782
783    -------------------------------------------------------------------------- */
784
785 #define ArrayInfo(type)                                 \
786 INFO_TABLE(stg_##type##_info, stg_##type##_entry, 0, 0, type, , EF_,"" # type "","" # type "");
787
788 ArrayInfo(ARR_WORDS);
789 NON_ENTERABLE_ENTRY_CODE(ARR_WORDS);
790 ArrayInfo(MUT_ARR_PTRS);
791 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS);
792 ArrayInfo(MUT_ARR_PTRS_FROZEN);
793 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS_FROZEN);
794
795 #undef ArrayInfo
796
797 /* -----------------------------------------------------------------------------
798    Mutable Variables
799    -------------------------------------------------------------------------- */
800
801 INFO_TABLE(stg_MUT_VAR_info, stg_MUT_VAR_entry, 1, 1, MUT_VAR, , EF_, "MUT_VAR", "MUT_VAR");
802 NON_ENTERABLE_ENTRY_CODE(MUT_VAR);
803
804 /* -----------------------------------------------------------------------------
805    Standard Error Entry.
806
807    This is used for filling in vector-table entries that can never happen,
808    for instance.
809    -------------------------------------------------------------------------- */
810 /* No longer used; we use NULL, because a) it never happens, right? and b)
811    Windows doesn't like DLL entry points being used as static initialisers
812 STGFUN(stg_error_entry)                                                 \
813 {                                                                       \
814   FB_                                                                   \
815     DUMP_ERRMSG("fatal: stg_error_entry");                              \
816     STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);                     \
817     return NULL;                                                        \
818   FE_                                                                   \
819 }
820 */
821 /* -----------------------------------------------------------------------------
822    Dummy return closure
823  
824    Entering this closure will just return to the address on the top of the
825    stack.  Useful for getting a thread in a canonical form where we can
826    just enter the top stack word to start the thread.  (see deleteThread)
827  * -------------------------------------------------------------------------- */
828
829 INFO_TABLE(stg_dummy_ret_info, stg_dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, "DUMMY_RET", "DUMMY_RET");
830 STGFUN(stg_dummy_ret_entry)
831 {
832   W_ ret_addr;
833   FB_
834   ret_addr = Sp[0];
835   Sp++;
836   JMP_(ENTRY_CODE(ret_addr));
837   FE_
838 }
839 SET_STATIC_HDR(stg_dummy_ret_closure,stg_dummy_ret_info,CCS_DONT_CARE,,EI_)
840 , /*payload*/{} };
841
842 /* -----------------------------------------------------------------------------
843     Strict IO application - performing an IO action and entering its result.
844     
845     rts_evalIO() lets you perform Haskell IO actions from outside of Haskell-land,
846     returning back to you their result. Want this result to be evaluated to WHNF
847     by that time, so that we can easily get at the int/char/whatever using the
848     various get{Ty} functions provided by the RTS API.
849
850     forceIO takes care of this, performing the IO action and entering the
851     results that comes back.
852
853  * -------------------------------------------------------------------------- */
854
855 #ifdef REG_R1
856 INFO_TABLE_SRT_BITMAP(stg_forceIO_ret_info,stg_forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
857 STGFUN(stg_forceIO_ret_entry)
858 {
859   FB_
860   Sp++;
861   Sp -= sizeofW(StgSeqFrame);
862   PUSH_SEQ_FRAME(Sp);
863   JMP_(GET_ENTRY(R1.cl));
864 }
865 #else
866 INFO_TABLE_SRT_BITMAP(stg_forceIO_ret_info,stg_forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
867 STGFUN(stg_forceIO_ret_entry)
868 {
869   StgClosure *rval;
870   FB_
871   rval = (StgClosure *)Sp[0];
872   Sp += 2;
873   Sp -= sizeofW(StgSeqFrame);
874   PUSH_SEQ_FRAME(Sp);
875   R1.cl = rval;
876   JMP_(GET_ENTRY(R1.cl));
877 }
878 #endif
879
880 INFO_TABLE(stg_forceIO_info,stg_forceIO_entry,1,0,FUN_STATIC,,EF_,"FORCE_IO","FORCE_IO");
881 FN_(stg_forceIO_entry)
882 {
883   FB_
884   /* Sp[0] contains the IO action we want to perform */
885   R1.p  = (P_)Sp[0];
886   /* Replace it with the return continuation that enters the result. */
887   Sp[0] = (W_)&stg_forceIO_ret_info;
888   Sp--;
889   /* Push the RealWorld# tag and enter */
890   Sp[0] =(W_)REALWORLD_TAG;
891   JMP_(GET_ENTRY(R1.cl));
892   FE_
893 }
894 SET_STATIC_HDR(stg_forceIO_closure,stg_forceIO_info,CCS_DONT_CARE,,EI_)
895 , /*payload*/{} };
896
897
898 /* -----------------------------------------------------------------------------
899    CHARLIKE and INTLIKE closures.  
900
901    These are static representations of Chars and small Ints, so that
902    we can remove dynamic Chars and Ints during garbage collection and
903    replace them with references to the static objects.
904    -------------------------------------------------------------------------- */
905
906 #if defined(INTERPRETER) || defined(ENABLE_WIN32_DLL_SUPPORT)
907 /*
908  * When sticking the RTS in a DLL, we delay populating the
909  * Charlike and Intlike tables until load-time, which is only
910  * when we've got the real addresses to the C# and I# closures.
911  *
912  */
913 static INFO_TBL_CONST StgInfoTable czh_static_info;
914 static INFO_TBL_CONST StgInfoTable izh_static_info;
915 #define Char_hash_static_info czh_static_info
916 #define Int_hash_static_info izh_static_info
917 #else
918 #define Char_hash_static_info GHCziBase_Czh_static_info
919 #define Int_hash_static_info GHCziBase_Izh_static_info
920 #endif
921
922 #define CHARLIKE_HDR(n)                                         \
923         {                                                       \
924           STATIC_HDR(Char_hash_static_info, /* C# */            \
925                          CCS_DONT_CARE),                        \
926           data : n                                              \
927         }
928                                              
929 #define INTLIKE_HDR(n)                                          \
930         {                                                       \
931           STATIC_HDR(Int_hash_static_info,  /* I# */            \
932                          CCS_DONT_CARE),                        \
933           data : n                                              \
934         }
935
936 /* put these in the *data* section, since the garbage collector relies
937  * on the fact that static closures live in the data section.
938  */
939
940 /* end the name with _closure, to convince the mangler this is a closure */
941
942 StgIntCharlikeClosure stg_CHARLIKE_closure[] = {
943     CHARLIKE_HDR(0),
944     CHARLIKE_HDR(1),
945     CHARLIKE_HDR(2),
946     CHARLIKE_HDR(3),
947     CHARLIKE_HDR(4),
948     CHARLIKE_HDR(5),
949     CHARLIKE_HDR(6),
950     CHARLIKE_HDR(7),
951     CHARLIKE_HDR(8),
952     CHARLIKE_HDR(9),
953     CHARLIKE_HDR(10),
954     CHARLIKE_HDR(11),
955     CHARLIKE_HDR(12),
956     CHARLIKE_HDR(13),
957     CHARLIKE_HDR(14),
958     CHARLIKE_HDR(15),
959     CHARLIKE_HDR(16),
960     CHARLIKE_HDR(17),
961     CHARLIKE_HDR(18),
962     CHARLIKE_HDR(19),
963     CHARLIKE_HDR(20),
964     CHARLIKE_HDR(21),
965     CHARLIKE_HDR(22),
966     CHARLIKE_HDR(23),
967     CHARLIKE_HDR(24),
968     CHARLIKE_HDR(25),
969     CHARLIKE_HDR(26),
970     CHARLIKE_HDR(27),
971     CHARLIKE_HDR(28),
972     CHARLIKE_HDR(29),
973     CHARLIKE_HDR(30),
974     CHARLIKE_HDR(31),
975     CHARLIKE_HDR(32),
976     CHARLIKE_HDR(33),
977     CHARLIKE_HDR(34),
978     CHARLIKE_HDR(35),
979     CHARLIKE_HDR(36),
980     CHARLIKE_HDR(37),
981     CHARLIKE_HDR(38),
982     CHARLIKE_HDR(39),
983     CHARLIKE_HDR(40),
984     CHARLIKE_HDR(41),
985     CHARLIKE_HDR(42),
986     CHARLIKE_HDR(43),
987     CHARLIKE_HDR(44),
988     CHARLIKE_HDR(45),
989     CHARLIKE_HDR(46),
990     CHARLIKE_HDR(47),
991     CHARLIKE_HDR(48),
992     CHARLIKE_HDR(49),
993     CHARLIKE_HDR(50),
994     CHARLIKE_HDR(51),
995     CHARLIKE_HDR(52),
996     CHARLIKE_HDR(53),
997     CHARLIKE_HDR(54),
998     CHARLIKE_HDR(55),
999     CHARLIKE_HDR(56),
1000     CHARLIKE_HDR(57),
1001     CHARLIKE_HDR(58),
1002     CHARLIKE_HDR(59),
1003     CHARLIKE_HDR(60),
1004     CHARLIKE_HDR(61),
1005     CHARLIKE_HDR(62),
1006     CHARLIKE_HDR(63),
1007     CHARLIKE_HDR(64),
1008     CHARLIKE_HDR(65),
1009     CHARLIKE_HDR(66),
1010     CHARLIKE_HDR(67),
1011     CHARLIKE_HDR(68),
1012     CHARLIKE_HDR(69),
1013     CHARLIKE_HDR(70),
1014     CHARLIKE_HDR(71),
1015     CHARLIKE_HDR(72),
1016     CHARLIKE_HDR(73),
1017     CHARLIKE_HDR(74),
1018     CHARLIKE_HDR(75),
1019     CHARLIKE_HDR(76),
1020     CHARLIKE_HDR(77),
1021     CHARLIKE_HDR(78),
1022     CHARLIKE_HDR(79),
1023     CHARLIKE_HDR(80),
1024     CHARLIKE_HDR(81),
1025     CHARLIKE_HDR(82),
1026     CHARLIKE_HDR(83),
1027     CHARLIKE_HDR(84),
1028     CHARLIKE_HDR(85),
1029     CHARLIKE_HDR(86),
1030     CHARLIKE_HDR(87),
1031     CHARLIKE_HDR(88),
1032     CHARLIKE_HDR(89),
1033     CHARLIKE_HDR(90),
1034     CHARLIKE_HDR(91),
1035     CHARLIKE_HDR(92),
1036     CHARLIKE_HDR(93),
1037     CHARLIKE_HDR(94),
1038     CHARLIKE_HDR(95),
1039     CHARLIKE_HDR(96),
1040     CHARLIKE_HDR(97),
1041     CHARLIKE_HDR(98),
1042     CHARLIKE_HDR(99),
1043     CHARLIKE_HDR(100),
1044     CHARLIKE_HDR(101),
1045     CHARLIKE_HDR(102),
1046     CHARLIKE_HDR(103),
1047     CHARLIKE_HDR(104),
1048     CHARLIKE_HDR(105),
1049     CHARLIKE_HDR(106),
1050     CHARLIKE_HDR(107),
1051     CHARLIKE_HDR(108),
1052     CHARLIKE_HDR(109),
1053     CHARLIKE_HDR(110),
1054     CHARLIKE_HDR(111),
1055     CHARLIKE_HDR(112),
1056     CHARLIKE_HDR(113),
1057     CHARLIKE_HDR(114),
1058     CHARLIKE_HDR(115),
1059     CHARLIKE_HDR(116),
1060     CHARLIKE_HDR(117),
1061     CHARLIKE_HDR(118),
1062     CHARLIKE_HDR(119),
1063     CHARLIKE_HDR(120),
1064     CHARLIKE_HDR(121),
1065     CHARLIKE_HDR(122),
1066     CHARLIKE_HDR(123),
1067     CHARLIKE_HDR(124),
1068     CHARLIKE_HDR(125),
1069     CHARLIKE_HDR(126),
1070     CHARLIKE_HDR(127),
1071     CHARLIKE_HDR(128),
1072     CHARLIKE_HDR(129),
1073     CHARLIKE_HDR(130),
1074     CHARLIKE_HDR(131),
1075     CHARLIKE_HDR(132),
1076     CHARLIKE_HDR(133),
1077     CHARLIKE_HDR(134),
1078     CHARLIKE_HDR(135),
1079     CHARLIKE_HDR(136),
1080     CHARLIKE_HDR(137),
1081     CHARLIKE_HDR(138),
1082     CHARLIKE_HDR(139),
1083     CHARLIKE_HDR(140),
1084     CHARLIKE_HDR(141),
1085     CHARLIKE_HDR(142),
1086     CHARLIKE_HDR(143),
1087     CHARLIKE_HDR(144),
1088     CHARLIKE_HDR(145),
1089     CHARLIKE_HDR(146),
1090     CHARLIKE_HDR(147),
1091     CHARLIKE_HDR(148),
1092     CHARLIKE_HDR(149),
1093     CHARLIKE_HDR(150),
1094     CHARLIKE_HDR(151),
1095     CHARLIKE_HDR(152),
1096     CHARLIKE_HDR(153),
1097     CHARLIKE_HDR(154),
1098     CHARLIKE_HDR(155),
1099     CHARLIKE_HDR(156),
1100     CHARLIKE_HDR(157),
1101     CHARLIKE_HDR(158),
1102     CHARLIKE_HDR(159),
1103     CHARLIKE_HDR(160),
1104     CHARLIKE_HDR(161),
1105     CHARLIKE_HDR(162),
1106     CHARLIKE_HDR(163),
1107     CHARLIKE_HDR(164),
1108     CHARLIKE_HDR(165),
1109     CHARLIKE_HDR(166),
1110     CHARLIKE_HDR(167),
1111     CHARLIKE_HDR(168),
1112     CHARLIKE_HDR(169),
1113     CHARLIKE_HDR(170),
1114     CHARLIKE_HDR(171),
1115     CHARLIKE_HDR(172),
1116     CHARLIKE_HDR(173),
1117     CHARLIKE_HDR(174),
1118     CHARLIKE_HDR(175),
1119     CHARLIKE_HDR(176),
1120     CHARLIKE_HDR(177),
1121     CHARLIKE_HDR(178),
1122     CHARLIKE_HDR(179),
1123     CHARLIKE_HDR(180),
1124     CHARLIKE_HDR(181),
1125     CHARLIKE_HDR(182),
1126     CHARLIKE_HDR(183),
1127     CHARLIKE_HDR(184),
1128     CHARLIKE_HDR(185),
1129     CHARLIKE_HDR(186),
1130     CHARLIKE_HDR(187),
1131     CHARLIKE_HDR(188),
1132     CHARLIKE_HDR(189),
1133     CHARLIKE_HDR(190),
1134     CHARLIKE_HDR(191),
1135     CHARLIKE_HDR(192),
1136     CHARLIKE_HDR(193),
1137     CHARLIKE_HDR(194),
1138     CHARLIKE_HDR(195),
1139     CHARLIKE_HDR(196),
1140     CHARLIKE_HDR(197),
1141     CHARLIKE_HDR(198),
1142     CHARLIKE_HDR(199),
1143     CHARLIKE_HDR(200),
1144     CHARLIKE_HDR(201),
1145     CHARLIKE_HDR(202),
1146     CHARLIKE_HDR(203),
1147     CHARLIKE_HDR(204),
1148     CHARLIKE_HDR(205),
1149     CHARLIKE_HDR(206),
1150     CHARLIKE_HDR(207),
1151     CHARLIKE_HDR(208),
1152     CHARLIKE_HDR(209),
1153     CHARLIKE_HDR(210),
1154     CHARLIKE_HDR(211),
1155     CHARLIKE_HDR(212),
1156     CHARLIKE_HDR(213),
1157     CHARLIKE_HDR(214),
1158     CHARLIKE_HDR(215),
1159     CHARLIKE_HDR(216),
1160     CHARLIKE_HDR(217),
1161     CHARLIKE_HDR(218),
1162     CHARLIKE_HDR(219),
1163     CHARLIKE_HDR(220),
1164     CHARLIKE_HDR(221),
1165     CHARLIKE_HDR(222),
1166     CHARLIKE_HDR(223),
1167     CHARLIKE_HDR(224),
1168     CHARLIKE_HDR(225),
1169     CHARLIKE_HDR(226),
1170     CHARLIKE_HDR(227),
1171     CHARLIKE_HDR(228),
1172     CHARLIKE_HDR(229),
1173     CHARLIKE_HDR(230),
1174     CHARLIKE_HDR(231),
1175     CHARLIKE_HDR(232),
1176     CHARLIKE_HDR(233),
1177     CHARLIKE_HDR(234),
1178     CHARLIKE_HDR(235),
1179     CHARLIKE_HDR(236),
1180     CHARLIKE_HDR(237),
1181     CHARLIKE_HDR(238),
1182     CHARLIKE_HDR(239),
1183     CHARLIKE_HDR(240),
1184     CHARLIKE_HDR(241),
1185     CHARLIKE_HDR(242),
1186     CHARLIKE_HDR(243),
1187     CHARLIKE_HDR(244),
1188     CHARLIKE_HDR(245),
1189     CHARLIKE_HDR(246),
1190     CHARLIKE_HDR(247),
1191     CHARLIKE_HDR(248),
1192     CHARLIKE_HDR(249),
1193     CHARLIKE_HDR(250),
1194     CHARLIKE_HDR(251),
1195     CHARLIKE_HDR(252),
1196     CHARLIKE_HDR(253),
1197     CHARLIKE_HDR(254),
1198     CHARLIKE_HDR(255)
1199 };
1200
1201 StgIntCharlikeClosure stg_INTLIKE_closure[] = {
1202     INTLIKE_HDR(-16),   /* MIN_INTLIKE == -16 */
1203     INTLIKE_HDR(-15),
1204     INTLIKE_HDR(-14),
1205     INTLIKE_HDR(-13),
1206     INTLIKE_HDR(-12),
1207     INTLIKE_HDR(-11),
1208     INTLIKE_HDR(-10),
1209     INTLIKE_HDR(-9),
1210     INTLIKE_HDR(-8),
1211     INTLIKE_HDR(-7),
1212     INTLIKE_HDR(-6),
1213     INTLIKE_HDR(-5),
1214     INTLIKE_HDR(-4),
1215     INTLIKE_HDR(-3),
1216     INTLIKE_HDR(-2),
1217     INTLIKE_HDR(-1),
1218     INTLIKE_HDR(0),
1219     INTLIKE_HDR(1),
1220     INTLIKE_HDR(2),
1221     INTLIKE_HDR(3),
1222     INTLIKE_HDR(4),
1223     INTLIKE_HDR(5),
1224     INTLIKE_HDR(6),
1225     INTLIKE_HDR(7),
1226     INTLIKE_HDR(8),
1227     INTLIKE_HDR(9),
1228     INTLIKE_HDR(10),
1229     INTLIKE_HDR(11),
1230     INTLIKE_HDR(12),
1231     INTLIKE_HDR(13),
1232     INTLIKE_HDR(14),
1233     INTLIKE_HDR(15),
1234     INTLIKE_HDR(16)     /* MAX_INTLIKE == 16 */
1235 };