1 %************************************************************************
3 \section[update-code]{Code required for update abstraction}
5 %************************************************************************
7 This code is required by the update interface which sits on top of the
8 storage manager interface (See \tr{SMupdate.lh}).
11 \item Indirection entry code and info table.
12 \item Black Hole entry code and info table.
13 \item Update frame code and return vectors.
14 \item PAP update code.
15 \item PAP entry code and info table.
18 System-wide constants need to be included:
20 #define MAIN_REG_MAP /* STG world */
26 # include "Statistics.h"
30 EXTDATA(PrelBase_Z91Z93_closure);
32 #if defined(TICKY_TICKY)
33 void PrintTickyInfo(STG_NO_ARGS);
37 %************************************************************************
39 \subsection[indirection-code]{Indirection code}
41 %************************************************************************
43 The entry code for indirections and the indirection info-table.
48 ENT_IND(Node); /* Ticky-ticky profiling info */
50 Node = (P_) IND_CLOSURE_PTR((P_) Node);
52 InfoPtr=(D_)(INFO_PTR(Node));
53 JMP_(ENTRY_CODE(InfoPtr));
57 IND_ITBL(Ind_info,Ind_entry,const,EF_);
60 We also need a special @CAF@ indirection info table which is used to
61 indirect @CAF@s to evaluated results in the heap.
63 STGFUN(Caf_entry) /* same as Ind_entry */
68 Node = (P_) IND_CLOSURE_PTR((P_) Node);
70 InfoPtr=(D_)(INFO_PTR(Node));
71 JMP_(ENTRY_CODE(InfoPtr));
75 CAF_ITBL(Caf_info,Caf_entry,const,EF_);
78 %************************************************************************
80 \subsection[black-hole-code]{Black Hole code}
82 %************************************************************************
84 The entry code for black holes abort indicating a cyclic data dependency.
85 It is used to overwrite closures currently being evaluated.
87 In the concurrent world, black holes are synchronization points, and they
88 are turned into blocking queues when there are threads waiting for the
89 evaluation of the closure to finish.
93 EXTFUN(EnterNodeCode);
94 EXTFUN(StackUnderflowEnterNode);
97 void raiseError PROTO((StgStablePtr));
98 extern StgStablePtr errorHandler; /* NB: prone to magic-value-ery (WDP 95/12) */
105 (void) STGCALL1(int,(void *, FILE *),fflush,stdout);
106 (void) STGCALL2(int,(),fprintf,stderr,"Entered a `black hole': the program has a cyclic data dependency.\n");
108 # if defined(PROFILING)
110 CostCentre cc = (CostCentre) CC_HDR(Node);
111 (void) STGCALL5(int,(),fprintf,stderr,"Cost Centre: %s Module: %s Group %s\n",cc->label, cc->module, cc->group);
115 # if defined(TICKY_TICKY)
116 if (RTSflags.TickyFlags.showTickyStats) {
117 (void) STGCALL0(void,(),PrintTickyInfo);
121 (void) STGCALL1(void,(void *, StgStablePtr), raiseError, errorHandler);
129 if ( RTSflags.GranFlags.debug & 0x80 )
130 (void) STGCALL4(int,(),fprintf,stderr,"GRAN_CHECK in BH_UPD_entry: Entered a `black hole' @ 0x%x (CurrentTSO @ 0x%x\n ",Node,CurrentTSO);
134 /* Do this before losing its TSO_LINK */
135 STGCALL3(void,(),GranSimBlock,CurrentTSO,CurrentProc,Node);
138 TSO_LINK(CurrentTSO) = PrelBase_Z91Z93_closure;
139 SET_INFO_PTR(Node, BQ_info);
140 BQ_ENTRIES(Node) = (W_) CurrentTSO;
142 # if defined(GCap) || defined(GCgn)
143 /* If we modify a black hole in the old generation,
144 we have to make sure it goes on the mutables list */
146 if(Node <= StorageMgrInfo.OldLim) {
147 MUT_LINK(Node) = (W_) StorageMgrInfo.OldMutables;
148 StorageMgrInfo.OldMutables = Node;
150 MUT_LINK(Node) = MUT_NOT_LINKED;
153 LivenessReg = LIVENESS_R1;
155 TSO_PC1(CurrentTSO) = EnterNodeCode;
158 QP_Event1("GR", CurrentTSO);
162 if(RTSflags.ParFlags.granSimStats) {
163 TIME now = CURRENT_TIME;
164 TSO_EXECTIME(CurrentTSO) += now - TSO_BLOCKEDAT(CurrentTSO);
165 TSO_BLOCKCOUNT(CurrentTSO)++;
166 TSO_QUEUE(CurrentTSO) = Q_BLOCKED;
167 TSO_BLOCKEDAT(CurrentTSO) = now;
168 DumpGranEvent(GR_BLOCK, CurrentTSO);
173 /* CurrentTSO = PrelBase_Z91Z93_closure; */
174 ReSchedule(SAME_THREAD);
184 /* made external so that debugger can get at it more effectively */
185 STGFUN(BH_SINGLE_entry)
189 (void) STGCALL1(int,(void *, FILE *),fflush,stdout);
190 (void) STGCALL2(int,(),fprintf,stderr,"Entered a single-entry `black hole' --\n");
191 (void) STGCALL2(int,(),fprintf,stderr,"either the compiler made a mistake on single-entryness,\n");
192 (void) STGCALL2(int,(),fprintf,stderr,"or the program has a cyclic data dependency.\n");
194 #if defined(PROFILING)
196 CostCentre cc = (CostCentre) CC_HDR(Node);
197 (void) STGCALL5(int,(),fprintf,stderr, "Cost Centre: %s Module: %s Group %s\n",cc->label, cc->module, cc->group);
201 # if defined(TICKY_TICKY)
202 if (RTSflags.TickyFlags.showTickyStats) {
203 (void) STGCALL0(void,(),PrintTickyInfo);
208 (void) STGCALL1(void,(void *, StgStablePtr), raiseError, errorHandler);
217 Updatable closures are overwritten with a black hole of a fixed size,
221 CAT_DECLARE(BH,BH_K,"BH","BH") /* just one, shared */
223 BH_ITBL(BH_UPD_info,BH_UPD_entry,U,const,EF_);
226 Single-Entry closures, which are not updated, are also overwritten
227 with a black hole. They have size @MIN_NONUPD_SIZE@.
230 BH_ITBL(BH_SINGLE_info,BH_SINGLE_entry,N,const,EF_);
233 %************************************************************************
235 \subsection[static-update-code]{Static update code in update frames}
237 %************************************************************************
239 This code is pointed to from update frames. It has to cope with
240 any kind of algebraic return: vectored or unvectored.
242 See \tr{SMupdate.lh} for a description of the various update frames
243 and the macros defining their layout.
245 On entry to this code:
247 \item @R1@ points to a recently created heap object (return in heap) or
248 is dead (return in regs).
249 \item @R2@ points to the info table for the constructor.
250 \item When returning in regs, any of the return-regs (@R3@...) may be live,
251 but aren't used by this code. They must be preserved.
252 \item @SpB@ points to the topmost word of the update frame.
255 NEW update mechanism (Jan '94):
257 When returning to an update frame, we want to jump directly to the
258 update code for the constructor in hand. Because of the various
259 possible return conventions (all of which must be handled by the
260 generic update frame), we actually end up with a somewhat indirect
265 STGFUN(StdUpdFrameDirectReturn)
268 JMP_(UPDATE_CODE(InfoPtr));
273 NB: For direct returns to work properly, the name of the routine must be
274 the same as the name of the vector table with vtbl_ removed and DirectReturn
275 appended. This is all the mangler understands.
280 vtbl_StdUpdFrame[] = {
281 /* at least "MAX_VECTORED_RTN" elements (see GhcConstants.lh) */
282 (W_) StdUpdFrameDirectReturn/*0*/,
283 (W_) StdUpdFrameDirectReturn/*1*/,
284 (W_) StdUpdFrameDirectReturn/*2*/,
285 (W_) StdUpdFrameDirectReturn/*3*/,
286 (W_) StdUpdFrameDirectReturn/*4*/,
287 (W_) StdUpdFrameDirectReturn/*5*/,
288 (W_) StdUpdFrameDirectReturn/*6*/,
289 (W_) StdUpdFrameDirectReturn/*7*/
294 %************************************************************************
296 \subsection[seq-update-code]{Update code for seq}
298 %************************************************************************
303 IFN_(seqDirectReturn) {
307 RetReg = (StgRetAddr) SpB[BREL(0)];
308 cont = (void *) SpB[BREL(1)];
309 /* SpB += BREL(2); */
315 NB: For direct returns to work properly, the name of the routine must be
316 the same as the name of the vector table with vtbl_ removed and DirectReturn
317 appended. This is all the mangler understands.
322 (W_) seqDirectReturn,
323 (W_) seqDirectReturn,
324 (W_) seqDirectReturn,
325 (W_) seqDirectReturn,
326 (W_) seqDirectReturn,
327 (W_) seqDirectReturn,
328 (W_) seqDirectReturn,
333 %************************************************************************
335 \subsection[existing-con-update-code]{Update code for existing constructors}
337 %************************************************************************
339 Here is the standard update code for objects that are returned in the
340 heap (or those which are initially returned in registers, but have
341 already been allocated in the heap earlier in the update chain). In
342 either case, @Node@ points to the heap object. The update code grabs
343 the address of the updatee out of the partial update frame (the return
344 address has already been popped), makes the updatee an indirection to
345 @Node@, and returns according to the convention for the constructor.
348 #define IND_UPD_TEMPLATE(label, retvector) \
352 UPD_EXISTING(); /* Ticky-ticky profiling info */ \
353 /* Update thing off stk with an indirection to Node */ \
354 UPD_IND(GRAB_UPDATEE(SpB), Node); \
355 /* Pop the standard update frame */ \
356 POP_STD_UPD_FRAME() \
362 IND_UPD_TEMPLATE(IndUpdRetDir, DIRECT(((P_)RetReg)))
363 IND_UPD_TEMPLATE(IndUpdRetV0, ((P_)RetReg)[RVREL(0)])
364 IND_UPD_TEMPLATE(IndUpdRetV1, ((P_)RetReg)[RVREL(1)])
365 IND_UPD_TEMPLATE(IndUpdRetV2, ((P_)RetReg)[RVREL(2)])
366 IND_UPD_TEMPLATE(IndUpdRetV3, ((P_)RetReg)[RVREL(3)])
367 IND_UPD_TEMPLATE(IndUpdRetV4, ((P_)RetReg)[RVREL(4)])
368 IND_UPD_TEMPLATE(IndUpdRetV5, ((P_)RetReg)[RVREL(5)])
369 IND_UPD_TEMPLATE(IndUpdRetV6, ((P_)RetReg)[RVREL(6)])
370 IND_UPD_TEMPLATE(IndUpdRetV7, ((P_)RetReg)[RVREL(7)])
373 %************************************************************************
375 \subsection[no-update-code]{Code for Erroneous Updates}
377 %************************************************************************
386 fprintf(stderr, "Update error: not a constructor!\n");
397 fprintf(stderr, "Standard error: should never happen!\n");
404 %************************************************************************
406 \subsection[permanent-indirections]{Lexical Scoping Updates}
408 %************************************************************************
410 A function entered without any arguments is updated with an
411 indirection. For lexically scoped profiling we still need to set the
412 cost centre if we enter the PAP. As the indirection is removed by the
413 garbage collector this would not be possible.
415 To solve this problem we introduce a permanent indirection which sets
416 the cost centre when entered. The heap profiler ignores the space
417 occupied by it as it would not reside in the heap during normal
420 In ticky-land: If we are trying to collect update-entry counts
421 (controlled by an RTS flag), then we must use permanent indirections
422 (the shorting-out of regular indirections loses the counts).
425 #if defined(PROFILING) || defined(TICKY_TICKY)
427 STGFUN(Perm_Ind_entry)
431 /* Don't add INDs to granularity cost */
433 /* Dont: ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
435 /* Enter PAP cost centre -- lexical scoping only */
436 ENTER_CC_PAP_CL(Node);
438 Node = (P_) IND_CLOSURE_PTR((P_) Node);
440 /* Dont: ENT_VIA_NODE(); for ticky-ticky; as above */
442 InfoPtr=(D_)(INFO_PTR(Node));
444 JMP_(ENTRY_CODE(InfoPtr));
448 PERM_IND_ITBL(Perm_Ind_info,Perm_Ind_entry,const,EF_);
450 #endif /* PROFILING or TICKY */
453 %************************************************************************
455 \subsection[partial-application-updates]{Partial applications}
457 %************************************************************************
459 See STG paper implementation section of Partial application updates.
461 We jump here when the current function fails an argument satisfaction
462 check. There can be two reasons for this. In the usual case, there
463 is an update frame blocking our access to anything deeper on the
464 stack. We then update the updatee in the frame with a partial
465 application node and squeeze out the update frame. The other
466 possibility is that we are running threaded code, and we are sitting
467 on the bottom of a stack chunk. In this case, we still build the
468 partial application, but we have nothing in our hands to update, so we
469 underflow the stack (awakening the previous chunk) and enter the
470 partial application node just built.
472 On entry to @UpdatePAP@, we assume the following:
474 \item SuB points to topmost word of an update frame or to the bottom of a
476 \item SpA and SpB point to the topmost words of their respective stacks.
477 \item Node points to the closure which needs more arguments than are there.
484 * Use STG registers for these locals which must survive the HEAP_CHK.
485 * Don't squash Node (R1), because it's an implicit argument.
488 #define NNonPtrWords (R2.i)
489 #define NPtrWords (R3.i)
490 #define NArgWords (R4.i)
491 #define PapSize (R5.i)
492 #if defined(PROFILING)
493 # define CC_pap ((CostCentre)(R7.p))
496 /* These other locals do not have to survive a HEAP_CHK */
505 #if defined(GRAN_COUNT)
509 NPtrWords = AREL(SuA - SpA);
510 NNonPtrWords = BREL(SuB - SpB);
512 ASSERT(NPtrWords >= 0);
513 ASSERT(NNonPtrWords >= 0);
515 NArgWords = NPtrWords + NNonPtrWords + 1; /* +1 for Node */
517 #if defined(PROFILING)
518 /* set "CC_pap" to go in the updatee (see Sansom thesis, p 183) */
520 CC_pap /*really cc_enter*/ = (CostCentre) CC_HDR(Node);
521 if (IS_CAF_OR_DICT_OR_SUB_CC(CC_pap) /*really cc_enter*/)
525 if (NArgWords == 1) {
528 * No arguments, only Node. Skip building the PAP and
529 * just plan to update with an indirection.
536 /* Build the PAP. A generic PAP closure is laid out thus:
537 * code ptr, size, no of words of ptrs, Node, ptrs, non-ptrs
538 * (i.e. a DYN closure)
539 * ToDo: add stuff for special cases, to omit size and no. of ptrs
540 * (Still ToDo? (JSM))
543 PapSize = NArgWords + DYN_HS;
545 ALLOC_UPD_PAP(DYN_HS, NArgWords, 0, PapSize);
546 CC_ALLOC(CC_pap, PapSize, PAP_K);
548 /* Allocate PapClosure -- Only Node (R1) is live */
549 HEAP_CHK(LIVENESS_R1, PapSize, 0);
551 PapClosure = Hp + 1 - PapSize; /* The new PapClosure */
553 SET_DYN_HDR(PapClosure, PAP_info, CC_pap, NArgWords + DYN_VHS, NPtrWords + 1);
555 /* Now fill in the closure fields */
558 for (i = NNonPtrWords - 1; i >= 0; i--) *p-- = (W_) SpB[BREL(i)];
559 for (i = NPtrWords - 1; i >= 0; i--) *p-- = (W_) SpA[AREL(i)];
564 * Finished constructing PAP closure; now update the updatee. But
565 * wait! What if there is no updatee? Then we fall off the
570 if (SuB < STKO_BSTK_BOT(StkOReg)) {
573 LivenessReg = LIVENESS_R1;
575 JMP_(StackUnderflowEnterNode);
580 * Now we have a standard update frame, so we update the updatee with
581 * either the new PAP or Node.
583 * Supposedly, it is not possible to get a constructor update frame,
585 * (Because they have *never* been implemented. (WDP))
588 Updatee = GRAB_UPDATEE(SuB);
589 UPD_IND(Updatee, PapClosure); /* Indirect Updatee to PapClosure */
591 if (NArgWords != 1) {
592 UPD_PAP_IN_NEW(NArgWords);
597 #if defined(PROFILING)
599 * Lexical scoping requires a *permanent* indirection, and we
600 * also have to set the cost centre for the indirection.
602 INFO_PTR(Updatee) = (W_) Perm_Ind_info;
603 SET_CC_HDR(Updatee, CC_pap);
605 #endif /* PROFILING */
608 #if defined(PROFILING)
610 * Restore the Cost Centre too (if required); again see Sansom thesis p 183.
611 * Take the CC out of the update frame if a CAF/DICT.
614 CCC = (IS_CAF_OR_DICT_OR_SUB_CC(CC_pap)) ? GRAB_COST_CENTRE(SuB) : CC_pap;
616 #endif /* PROFILING */
618 /* Restore SuA, SuB, RetReg */
619 RetReg = GRAB_RET(SuB);
624 * Squeeze out update frame from B stack. Note that despite our best
625 * efforts with [AB]REL and friends, the loop order depends on the B
628 for (i = NNonPtrWords - 1; i >= 0; i--)
629 SpB[BREL(i+STD_UF_SIZE)] = SpB[BREL(i)];
631 SpB += BREL(STD_UF_SIZE);
634 * All done! Restart by re-entering Node
635 * Don't count this entry for ticky-ticky profiling.
638 #if 0 /* defined(GRAN) */
639 GRAN_EXEC(16,4,7,4,0);
641 InfoPtr=(D_)(INFO_PTR(Node));
642 JMP_(ENTRY_CODE(InfoPtr));
655 The entry code for a generic PAP. @Node@ points to the PAP closure.
656 Reload the stacks from the PAP, and enter the closure stored in the
657 PAP. PAPs are in HNF so no update frame is needed.
662 /* Use STG registers for these locals which must survive the STK_CHK */
663 #define NPtrWords (R2.i)
664 #define NNonPtrWords (R3.i)
665 #if defined(PROFILING)
666 # define CC_pap ((CostCentre)(R7.p))
669 /* These locals don't have to survive the STK_CHK */
678 If we come from StackUnderflowEnterNode the old StkO has been
679 nuked and the PAP carries over data from the old StkO.
680 The underflow code must restore RetReg to the right value
681 because it is not grabbed from the update frame if there is data
682 on one of the two stacks.
685 while (AREL(SuA - SpA) == 0 && BREL(SuB - SpB) == 0) {
687 if (SuB < STKO_BSTK_BOT(StkOReg)) {
689 LivenessReg = LIVENESS_R1;
691 JMP_(StackUnderflowEnterNode);
695 /* We're sitting on top of an update frame, so let's do the business */
697 Updatee = GRAB_UPDATEE(SuB);
698 UPD_IND(Updatee, Node);
700 #if defined(PROFILING)
702 * Restore the Cost Centre too (if required); again see Sansom
703 * thesis p 183. Take the CC out of the update frame if a
707 CC_pap = (CostCentre) CC_HDR(Node);
708 CCC = (IS_CAF_OR_DICT_OR_SUB_CC(CC_pap)) ? GRAB_COST_CENTRE(SuB) : CC_pap;
710 #endif /* PROFILING */
712 RetReg = GRAB_RET(SuB);
715 SpB += BREL(STD_UF_SIZE);
718 NPtrWords = DYN_CLOSURE_NoPTRS(Node) - 1; /* The saved Node counts as one */
719 NNonPtrWords = DYN_CLOSURE_NoNONPTRS(Node);
721 /* Ticky-ticky profiling info */
724 /* Enter PAP cost centre -- lexical scoping only */
725 ENTER_CC_PAP_CL(Node);
728 * Check for stack overflow. Ask to take all of the current frame with
729 * us to the new world. If there is no update frame on the current stack,
730 * bWords will exceed the size of the B stack, but StackOverflow will deal
734 aWords = AREL(SuA - SpA);
735 bWords = BREL(SuB - SpB) + STD_UF_SIZE;
737 STK_CHK(LIVENESS_R1, NPtrWords, NNonPtrWords, aWords, bWords, 0, 0);
739 SpA -= AREL(NPtrWords);
740 SpB -= BREL(NNonPtrWords);
743 p = Node + DYN_HS; /* Point to first pointer word */
746 /* Reload the stacks */
748 for (i=0; i<NPtrWords; i++) SpA[AREL(i)] = (P_) *p++;
749 for (i=0; i<NNonPtrWords; i++) SpB[BREL(i)] = *p++;
753 InfoPtr=(D_)(INFO_PTR(Node));
754 JMP_(ENTRY_CODE(InfoPtr));
765 The info table for a generic PAP:
767 DYN_ITBL(PAP_info,PAP_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,EF_,PAP_K,"PAP","->");