1 %/****************************************************************
3 %* Basic Continuations required by the STG Machine runtime *
5 %****************************************************************/
8 First continuation called by the mini-interpreter is
9 evaluateTopClosure. It has to set up return and jump to the user's
10 @main@ closure. If @errorIO@ is called, we will be back here, doing
11 the same thing for the specified continuation.
14 #define MAIN_REG_MAP /* STG world */
19 #include "Statistics.h"
23 /* ptr to the user's "main" closure (or "errorIO" arg closure),
24 to which we hope to be linked
28 EXTFUN(stopThreadDirectReturn);
29 UNVECTBL(,vtbl_stopStgWorld,stopThreadDirectReturn)
31 /* Well, we have to put the ArrayOfData and ArrayOfPtrs info tables
35 /* Array of data -- mutable */
36 STATICFUN(ArrayOfData_entry)
39 /* Don't wrap the calls; we're done with STG land */
41 fprintf(stderr, "Entered a primitive array (of data)---this shouldn't happen!\n");
46 DATA_ITBL(ArrayOfData_info,ArrayOfData_entry,UpdErr,0,INFO_OTHER_TAG,,,const,IF_,ARR_K,"DATA-ARRAY","ARRAY");
47 /* ToDo: could put a useful tag in there!!! */
49 /* Array of pointers -- mutable */
50 STATICFUN(ArrayOfPtrs_entry)
53 /* Don't wrap the calls; we're done with STG land */
55 fprintf(stderr, "Entered a primitive array (of pointers)---this shouldn't happen!\n");
60 MUTUPLE_ITBL(ArrayOfPtrs_info,ArrayOfPtrs_entry,UpdErr,0,INFO_OTHER_TAG,,,const,IF_,ARR_K,"PTR-ARRAY(mut)","ARRAY");
61 /* ToDo: could put a useful tag in there!!! */
63 STATICFUN(FullSVar_entry)
66 /* Don't wrap the calls; we're done with STG land */
68 fprintf(stderr, "Entered a full SVar---this shouldn't happen!\n");
73 MUTUPLE_ITBL(FullSVar_info,FullSVar_entry,UpdErr,0,INFO_OTHER_TAG,,,const,IF_,ARR_K,"FullSVar","ARRAY");
74 /* ToDo: could put a useful tag in there!!! */
76 STATICFUN(EmptySVar_entry)
79 /* Don't wrap the calls; we're done with STG land */
81 fprintf(stderr, "Entered an empty SVar---this shouldn't happen!\n");
86 MUTUPLE_ITBL(EmptySVar_info,EmptySVar_entry,UpdErr,0,INFO_OTHER_TAG,,,const,IF_,ARR_K,"EmptySVar","ARRAY");
87 /* ToDo: could put a useful tag in there!!! */
89 /* Array of pointers -- immutable */
90 STATICFUN(ImMutArrayOfPtrs_entry)
93 /* Don't wrap the calls; we're done with STG land */
95 fprintf(stderr, "Entered a primitive array (immutable, pointers)---this shouldn't happen!\n");
100 IMMUTUPLE_ITBL(ImMutArrayOfPtrs_info,ImMutArrayOfPtrs_entry,UpdErr,0,INFO_OTHER_TAG,,,const,IF_,ARR_K,"PTR-ARRAY(immut)","ARRAY");
101 /* ToDo: could put a useful tag in there!!! */
103 /* (end of Array whatnot) */
105 /* Question for Will: There seem to be a lot of these static things
106 now - worth putting them in a file by themselves?? [ADR] */
111 /* Ditto for Malloc Pointer entry point and info tables. [ADR]
113 BTW Will, I copied most of this blindly from above - what's with
114 this TAG stuff? And what kind of description/ type is wanted here?
117 STATICFUN(MallocPtr_entry)
120 /* Don't wrap the calls; we're done with STG land */
122 fprintf(stderr, "Compiler bug: Entered a Malloc Pointer---this shouldn't happen!\n");
127 MallocPtr_ITBL(MallocPtr_info,MallocPtr_entry,UpdErr,0,INFO_OTHER_TAG,,,const,EF_,MallocPtr_K,"MALLOC PTR","MallocPtr");
129 /* End of MallocPtr stuff */
131 /* Ditto for the unused Stable Pointer info table. [ADR]
134 extern void raiseError PROTO((StgStablePtr));
135 extern StgStablePtr errorHandler;
137 /* Unused Stable Pointer (ie unused slot in a stable pointer table) */
138 STATICFUN(UnusedSP_entry)
141 (void) SAFESTGCALL1(I_,(void *, FILE *),fflush,stdout);
142 (void) SAFESTGCALL2(I_,(void *, FILE *, char *),fprintf,stderr, "Entered an unused Stable Pointer---this shouldn't happen!\n(This could be program error (using stable pointer after freeing) or compiler bug.)\n");
144 (void) STGCALL1(void,(void *, StgStablePtr), raiseError, errorHandler);
148 STATIC_ITBL(UnusedSP_static_info,UnusedSP_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,IF_,CON_K,"UNUSED STABLE PTR","USP");
150 SET_STATIC_HDR(UnusedSP_closure,UnusedSP_static_info,CC_SUBSUMED,,ED_RO_)
153 /* Entry point and Info table for Stable Pointer Table. */
155 STATICFUN(StablePointerTable_entry)
158 /* Don't wrap the calls; we're done with STG land */
160 fprintf(stderr, "Entered the stable pointer table---this shouldn't happen!\n");
165 STATIC_ITBL(EmptyStablePointerTable_static_info,StablePointerTable_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,IF_,SPT_K,"SP_TABLE","SP_TABLE");
166 /* ToDo: could put a useful tag in there!!! */
168 DYN_ITBL(StablePointerTable_info,StablePointerTable_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,IF_,SPT_K,"SP_TABLE","SP_TABLE");
169 /* ToDo: could put a useful tag in there!!! */
172 /* To ease initialisation of the heap, we start with an empty stable
173 pointer table. When we try to create the first stable pointer, the
174 overflow will trigger creation of a table of useful size.
177 SET_STATIC_HDR(EmptySPTable_closure,EmptyStablePointerTable_static_info,CC_SUBSUMED,,ED_RO_)
178 , (W_) DYN_VHS + 0 + 1 + 0 /* size = DYN_VHS + n + 1 + n with n = 0 */
179 , (W_) 0 /* number of ptrs */
180 , (W_) 0 /* top of stack */
183 /* End of SP stuff */
187 /* the IoWorld token to start the whole thing off */
188 /* Question: this is just an amusing hex code isn't it
189 -- or does it mean something? ADR */
190 P_ realWorldZh_closure = (P_) 0xbadbadbaL;
192 SET_STATIC_HDR(WorldStateToken_closure,SZh_static_info,CC_SUBSUMED/*harmless*/,,ED_RO_)
198 STGFUN(startStgWorld)
201 /* At this point we are in the threaded-code world.
203 TopClosure points to a closure of type PrimIO (), which should be
204 performed (by applying it to the state of the world).
206 The smInfo storage-management info block is assumed to be
207 up to date, and is used to load the STG registers.
210 #if defined (DO_SPAT_PROFILING)
211 SET_ACTIVITY(ACT_REDN); /* init: do this first, so we count the restore insns */
214 RestoreAllStgRegs(); /* inline! */
216 /* ------- STG registers are now valid! -------------------------*/
218 /* Put a suitable return address on the B stack */
219 RetReg = (StgRetAddr) UNVEC(stopThreadDirectReturn,vtbl_stopStgWorld);
221 /* Put an IoWorld token on the A stack */
223 *SpA = (P_) WorldStateToken_closure;
225 Node = (P_) TopClosure; /* Point to the closure for main/errorIO-arg */
227 InfoPtr=(D_)(INFO_PTR(Node));
228 JMP_(ENTRY_CODE(InfoPtr));
231 #endif /* ! CONCURRENT */
235 %************************************************************************
237 \subsection[thread-return]{Polymorphic end-of-thread code}
239 %************************************************************************
244 Here's the polymorphic return for the end of a thread.
246 NB: For direct returns to work properly, the name of the routine must be
247 the same as the name of the vector table with vtbl_ removed and DirectReturn
248 appended. This is all the mangler understands.
252 vtbl_stopThread[] = {
253 /* at least "MAX_VECTORED_RTN" elements (see GhcConstants.lh) */
254 (W_) stopThreadDirectReturn,
255 (W_) stopThreadDirectReturn,
256 (W_) stopThreadDirectReturn,
257 (W_) stopThreadDirectReturn,
258 (W_) stopThreadDirectReturn,
259 (W_) stopThreadDirectReturn,
260 (W_) stopThreadDirectReturn,
261 (W_) stopThreadDirectReturn
264 STGFUN(stopThreadDirectReturn)
269 The top-top-level closures (e.g., "main") are of type "IO ()".
270 When entered, they perform an IO action and return a () --
271 essentially, TagReg is set to 1. Here, we don't need to do
274 We just tidy up the register stuff (real regs in *_SAVE, then
275 *_SAVE -> smInfo locs).
279 SET_TASK_ACTIVITY(ST_OVERHEAD);
282 SaveAllStgRegs(); /* inline! */
287 RESUME_(miniInterpretEnd);
295 I_ ErrorIO_call_count = 0;
298 EXTFUN(EnterNodeCode);
300 STGFUN(ErrorIO_innards)
301 /* Assumes that "TopClosure" has been set already */
304 if (ErrorIO_call_count >= 16 /* MAGIC CONSTANT */ ) {
305 /* Don't wrap the calls; we're done with STG land */
307 fprintf(stderr, "too many nested calls to `error'\n");
310 ErrorIO_call_count++; /* NB: undo later if decide to let someone else handle it */
312 /* Unlock all global closures held by this thread! (ToDo) --JSM */
314 switch(TSO_TYPE(CurrentTSO)) {
316 /* Re-initialize stack pointers (cf. NewThread) */
318 SpB = SuB = STKO_BSTK_BOT(StkOReg) + BREL(1);
319 SuA = STKO_ASTK_BOT(StkOReg) + AREL(1);
321 SuA = stackInfo.botA + AREL(1);
322 SuB = stackInfo.botB + BREL(1);
327 /* Re-initialize stack pointers (cf. NewThread) */
328 SpB = SuB = STKO_BSTK_BOT(StkOReg) + BREL(1);
329 SuA = STKO_ASTK_BOT(StkOReg) + AREL(1);
333 ErrorIO_call_count--; /* undo the damage, as someone else will deal with it */
334 /* Let the main thread eventually handle it */
335 JMP_(stopThreadDirectReturn);
341 /* Don't wrap the calls; we're done with STG land */
343 fprintf(stderr,"ErrorIO: %x unknown\n", TSO_TYPE(CurrentTSO));
347 /* Finish stack setup as if for a top-level task and enter the error node */
351 *SpA = (P_) WorldStateToken_closure;
353 STKO_LINK(StkOReg) = Nil_closure;
354 STKO_RETURN(StkOReg) = NULL;
356 #ifdef DO_REDN_COUNTING
357 STKO_ADEP(StkOReg) = STKO_BDEP(StkOReg) = 0;
361 Node = (P_) TopClosure;
362 RetReg = (StgRetAddr) UNVEC(stopThreadDirectReturn,vtbl_stopStgWorld);
369 We cannot afford to call @error@ too many times
370 (e.g., \tr{error x where x = error x}), so we keep count.
373 #else /* !CONCURRENT */
376 ErrorIO_innards(STG_NO_ARGS)
377 /* Assumes that "TopClosure" has been set already */
380 if (ErrorIO_call_count >= 16 /* MAGIC CONSTANT */ ) {
381 /* Don't wrap the calls; we're done with STG land */
383 fprintf(stderr, "too many nested calls to `error'\n");
386 ErrorIO_call_count++;
388 /* Copy the heap-related registers into smInfo. (Other registers get
389 saved in this process, but we aren't interested in them.)
391 Get a new stack (which re-initialises the smInfo stack stuff),
392 and start the world again.
394 /* ToDo: chk this has been handled in parallel world */
396 SaveAllStgRegs(); /* inline! */
398 if ( initStacks( &StorageMgrInfo ) != 0) {
399 /* Don't wrap the calls; we're done with STG land */
401 fprintf(stderr, "initStacks failed!\n");
405 JMP_( startStgWorld );
409 #endif /* !CONCURRENT */
415 STATICFUN(RBH_Save_0_entry)
418 fprintf(stderr,"Oops, entered an RBH save\n");
423 STATICFUN(RBH_Save_1_entry)
426 fprintf(stderr,"Oops, entered an RBH save\n");
431 STATICFUN(RBH_Save_2_entry)
434 fprintf(stderr,"Oops, entered an RBH save\n");
439 SPEC_N_ITBL(RBH_Save_0_info,RBH_Save_0_entry,UpdErr,0,INFO_OTHER_TAG,2,0,,IF_,INTERNAL_KIND,"RBH-SAVE","RBH_Save_0");
440 SPEC_N_ITBL(RBH_Save_1_info,RBH_Save_1_entry,UpdErr,0,INFO_OTHER_TAG,2,1,,IF_,INTERNAL_KIND,"RBH-SAVE","RBH_Save_1");
441 SPEC_N_ITBL(RBH_Save_2_info,RBH_Save_2_entry,UpdErr,0,INFO_OTHER_TAG,2,2,,IF_,INTERNAL_KIND,"RBH-SAVE","RBH_Save_2");
447 %/****************************************************************
449 %* Other Bits and Pieces *
451 %****************************************************************/
454 /* If we don't need the slow entry code for a closure, we put in a
455 pointer to this in the closure's slow entry code pointer instead.
458 STGFUN(__std_entry_error__) {
460 /* Don't wrap the calls; we're done with STG land */
462 fprintf(stderr, "Called non-existent slow-entry code!!!\n");
469 STGFUN(STK_STUB_entry) {
471 /* Don't wrap the calls; we're done with STG land */
473 fprintf(stderr, "Entered from a stubbed stack slot!\n");
480 STATIC_ITBL(STK_STUB_static_info,STK_STUB_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,EF_,INTERNAL_KIND,"STK_STUB","STK_STUB");
483 SET_STATIC_HDR(STK_STUB_closure,STK_STUB_static_info,CC_SUBSUMED,,EXTDATA_RO)
491 STGFUN(Event_Queue_entry) {
493 /* Don't wrap the calls; we're done with STG land */
495 fprintf(stderr, "Entered from an event queue!\n");
501 GEN_N_ITBL(Event_Queue_info,Event_Queue_entry,UpdErr,0,INFO_OTHER_TAG,5,2,const,EF_,INTERNAL_KIND,"EventQ","EventQ");
508 %/****************************************************************
510 %* Some GC info tables *
512 %****************************************************************/
514 These have to be in a .lhc file, so they will be reversed correctly.
517 #include "../storage/SMinternal.h"
519 #if defined(_INFO_COPYING)
521 STGFUN(Caf_Evac_Upd_entry) {
523 /* Don't wrap the calls; we're done with STG land */
525 fprintf(stderr,"Entered Caf_Evac_Upd %lx: Should never occur!\n", (W_) Node);
530 CAF_EVAC_UPD_ITBL(Caf_Evac_Upd_info,Caf_Evac_Upd_entry,const/*not static*/);
534 STGFUN(Forward_Ref_New_entry) {
536 /* Don't wrap the calls; we're done with STG land */
538 fprintf(stderr,"Entered Forward_Ref_New %lx: Should never occur!\n", (W_) Node);
542 FORWARDREF_ITBL(Forward_Ref_New_info,Forward_Ref_New_entry,const/*not static*/,_Evacuate_Old_Forward_Ref);
544 STGFUN(Forward_Ref_Old_entry) {
546 /* Don't wrap the calls; we're done with STG land */
548 fprintf(stderr,"Entered Forward_Ref_Old %lx: Should never occur!\n", (W_) Node);
552 FORWARDREF_ITBL(Forward_Ref_Old_info,Forward_Ref_Old_entry,const/*not static*/,_Evacuate_New_Forward_Ref);
554 STGFUN(OldRoot_Forward_Ref_entry) {
556 /* Don't wrap the calls; we're done with STG land */
558 fprintf(stderr,"Entered OldRoot_Forward_Ref %lx: Should never occur!\n", (W_) Node);
562 FORWARDREF_ITBL(OldRoot_Forward_Ref_info,OldRoot_Forward_Ref_entry,const/*not static*/,_Evacuate_OldRoot_Forward);
565 STGFUN(Forward_Ref_entry) {
567 /* Don't wrap the calls; we're done with STG land */
569 fprintf(stderr,"Entered Forward_Ref %lx: Should never occur!\n", (W_) Node);
573 FORWARDREF_ITBL(Forward_Ref_info,Forward_Ref_entry,const/*not static*/,_Evacuate_Forward_Ref);
576 #endif /* _INFO_COPYING */
579 OLDROOT_ITBL(OldRoot_info,Ind_Entry,const,EF_);
584 %/***************************************************************
586 %* Cost Centre stuff ... *
588 %****************************************************************/
590 For cost centres we need prelude cost centres and register routine.
592 N.B. ALL prelude cost centres should be declared here as none will
593 be declared when the prelude is compiled.
595 ToDo: Explicit cost centres in prelude for Input and Output costs.
598 #if defined(USE_COST_CENTRES)
600 STGFUN(startCcRegisteringWorld)
604 * We used to push miniInterpretEnd on the register stack, but
605 * miniInterpretEnd must only be entered with the RESUME_ macro,
606 * whereas the other addresses on the register stack must only be
607 * entered with the JMP_ macro. Now, we push NULL and test for
608 * it explicitly at each pop.
610 PUSH_REGISTER_STACK(NULL);
615 CC_DECLARE(CC_CAFs, "CAFs_in_...", "PRELUDE", "PRELUDE", CC_IS_CAF,/*not static*/);
616 CC_DECLARE(CC_DICTs, "DICTs_in_...", "PRELUDE", "PRELUDE", CC_IS_DICT,/*not static*/);
618 START_REGISTER_PRELUDE(_regPrelude);
619 REGISTER_CC(CC_CAFs);
620 REGISTER_CC(CC_DICTs);
624 We also need cost centre declarations and registering routines for other
625 built-in prelude-like modules.
627 ToDo: What built-in prelude-like modules exist ?
630 START_REGISTER_PRELUDE(_regByteOps); /* used in Glasgow tests only? */
633 /* _regPrelude is above */
635 START_REGISTER_PRELUDE(_regPreludeArray);
638 START_REGISTER_PRELUDE(_regPreludeCore);
641 START_REGISTER_PRELUDE(_regPreludeDialogueIO);
644 START_REGISTER_PRELUDE(_regPreludeGlaMisc);
647 START_REGISTER_PRELUDE(_regPreludeGlaST);
650 START_REGISTER_PRELUDE(_regPreludeIOError);
653 START_REGISTER_PRELUDE(_regPreludePS);
656 START_REGISTER_PRELUDE(_regPreludePrimIO);
659 START_REGISTER_PRELUDE(_regPreludeStdIO);