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(Prelude_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) = Prelude_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 = Prelude_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[existing-con-update-code]{Update code for existing constructors}
298 %************************************************************************
300 Here is the standard update code for objects that are returned in the
301 heap (or those which are initially returned in registers, but have
302 already been allocated in the heap earlier in the update chain). In
303 either case, @Node@ points to the heap object. The update code grabs
304 the address of the updatee out of the partial update frame (the return
305 address has already been popped), makes the updatee an indirection to
306 @Node@, and returns according to the convention for the constructor.
309 #define IND_UPD_TEMPLATE(label, retvector) \
313 UPD_EXISTING(); /* Ticky-ticky profiling info */ \
314 /* Update thing off stk with an indirection to Node */ \
315 UPD_IND(GRAB_UPDATEE(SpB), Node); \
316 /* Pop the standard update frame */ \
317 POP_STD_UPD_FRAME() \
323 IND_UPD_TEMPLATE(IndUpdRetDir, DIRECT(((P_)RetReg)))
324 IND_UPD_TEMPLATE(IndUpdRetV0, ((P_)RetReg)[RVREL(0)])
325 IND_UPD_TEMPLATE(IndUpdRetV1, ((P_)RetReg)[RVREL(1)])
326 IND_UPD_TEMPLATE(IndUpdRetV2, ((P_)RetReg)[RVREL(2)])
327 IND_UPD_TEMPLATE(IndUpdRetV3, ((P_)RetReg)[RVREL(3)])
328 IND_UPD_TEMPLATE(IndUpdRetV4, ((P_)RetReg)[RVREL(4)])
329 IND_UPD_TEMPLATE(IndUpdRetV5, ((P_)RetReg)[RVREL(5)])
330 IND_UPD_TEMPLATE(IndUpdRetV6, ((P_)RetReg)[RVREL(6)])
331 IND_UPD_TEMPLATE(IndUpdRetV7, ((P_)RetReg)[RVREL(7)])
334 %************************************************************************
336 \subsection[no-update-code]{Code for Erroneous Updates}
338 %************************************************************************
347 fprintf(stderr, "Update error: not a constructor!\n");
358 fprintf(stderr, "Standard error: should never happen!\n");
365 %************************************************************************
367 \subsection[permanent-indirections]{Lexical Scoping Updates}
369 %************************************************************************
371 A function entered without any arguments is updated with an
372 indirection. For lexically scoped profiling we still need to set the
373 cost centre if we enter the PAP. As the indirection is removed by the
374 garbage collector this would not be possible.
376 To solve this problem we introduce a permanent indirection which sets
377 the cost centre when entered. The heap profiler ignores the space
378 occupied by it as it would not reside in the heap during normal
381 In ticky-land: If we are trying to collect update-entry counts
382 (controlled by an RTS flag), then we must use permanent indirections
383 (the shorting-out of regular indirections loses the counts).
386 #if defined(PROFILING) || defined(TICKY_TICKY)
388 STGFUN(Perm_Ind_entry)
392 /* Don't add INDs to granularity cost */
394 /* Dont: ENT_IND(Node); for ticky-ticky; this ind is here only to help ticky */
396 /* Enter PAP cost centre -- lexical scoping only */
397 ENTER_CC_PAP_CL(Node);
399 Node = (P_) IND_CLOSURE_PTR((P_) Node);
401 /* Dont: ENT_VIA_NODE(); for ticky-ticky; as above */
403 InfoPtr=(D_)(INFO_PTR(Node));
405 JMP_(ENTRY_CODE(InfoPtr));
409 PERM_IND_ITBL(Perm_Ind_info,Perm_Ind_entry,const,EF_);
411 #endif /* PROFILING or TICKY */
414 %************************************************************************
416 \subsection[partial-application-updates]{Partial applications}
418 %************************************************************************
420 See STG paper implementation section of Partial application updates.
422 We jump here when the current function fails an argument satisfaction
423 check. There can be two reasons for this. In the usual case, there
424 is an update frame blocking our access to anything deeper on the
425 stack. We then update the updatee in the frame with a partial
426 application node and squeeze out the update frame. The other
427 possibility is that we are running threaded code, and we are sitting
428 on the bottom of a stack chunk. In this case, we still build the
429 partial application, but we have nothing in our hands to update, so we
430 underflow the stack (awakening the previous chunk) and enter the
431 partial application node just built.
433 On entry to @UpdatePAP@, we assume the following:
435 \item SuB points to topmost word of an update frame or to the bottom of a
437 \item SpA and SpB point to the topmost words of their respective stacks.
438 \item Node points to the closure which needs more arguments than are there.
445 * Use STG registers for these locals which must survive the HEAP_CHK.
446 * Don't squash Node (R1), because it's an implicit argument.
449 #define NNonPtrWords (R2.i)
450 #define NPtrWords (R3.i)
451 #define NArgWords (R4.i)
452 #define PapSize (R5.i)
453 #if defined(PROFILING)
454 # define CC_pap ((CostCentre)(R7.p))
457 /* These other locals do not have to survive a HEAP_CHK */
466 #if defined(GRAN_COUNT)
470 NPtrWords = AREL(SuA - SpA);
471 NNonPtrWords = BREL(SuB - SpB);
473 ASSERT(NPtrWords >= 0);
474 ASSERT(NNonPtrWords >= 0);
476 NArgWords = NPtrWords + NNonPtrWords + 1; /* +1 for Node */
478 #if defined(PROFILING)
479 /* set "CC_pap" to go in the updatee (see Sansom thesis, p 183) */
481 CC_pap /*really cc_enter*/ = (CostCentre) CC_HDR(Node);
482 if (IS_SUBSUMED_CC(CC_pap) /*really cc_enter*/)
486 if (NArgWords == 1) {
489 * No arguments, only Node. Skip building the PAP and
490 * just plan to update with an indirection.
497 /* Build the PAP. A generic PAP closure is laid out thus:
498 * code ptr, size, no of words of ptrs, Node, ptrs, non-ptrs
499 * (i.e. a DYN closure)
500 * ToDo: add stuff for special cases, to omit size and no. of ptrs
501 * (Still ToDo? (JSM))
504 PapSize = NArgWords + DYN_HS;
506 ALLOC_UPD_PAP(DYN_HS, NArgWords, 0, PapSize);
507 CC_ALLOC(CC_pap, PapSize, PAP_K);
509 /* Allocate PapClosure -- Only Node (R1) is live */
510 HEAP_CHK(LIVENESS_R1, PapSize, 0);
512 PapClosure = Hp + 1 - PapSize; /* The new PapClosure */
514 SET_DYN_HDR(PapClosure, PAP_info, CC_pap, NArgWords + DYN_VHS, NPtrWords + 1);
516 /* Now fill in the closure fields */
519 for (i = NNonPtrWords - 1; i >= 0; i--) *p-- = (W_) SpB[BREL(i)];
520 for (i = NPtrWords - 1; i >= 0; i--) *p-- = (W_) SpA[AREL(i)];
525 * Finished constructing PAP closure; now update the updatee. But
526 * wait! What if there is no updatee? Then we fall off the
531 if (SuB < STKO_BSTK_BOT(StkOReg)) {
534 LivenessReg = LIVENESS_R1;
536 JMP_(StackUnderflowEnterNode);
541 * Now we have a standard update frame, so we update the updatee with
542 * either the new PAP or Node.
544 * Supposedly, it is not possible to get a constructor update frame,
546 * (Because they have *never* been implemented. (WDP))
549 Updatee = GRAB_UPDATEE(SuB);
550 UPD_IND(Updatee, PapClosure); /* Indirect Updatee to PapClosure */
552 if (NArgWords != 1) {
553 UPD_PAP_IN_NEW(NArgWords);
558 #if defined(PROFILING)
560 * Lexical scoping requires a *permanent* indirection, and we
561 * also have to set the cost centre for the indirection.
563 INFO_PTR(Updatee) = (W_) Perm_Ind_info;
564 SET_CC_HDR(Updatee, CC_pap);
566 #endif /* PROFILING */
569 #if defined(PROFILING)
571 * Restore the Cost Centre too (if required); again see Sansom thesis p 183.
572 * Take the CC out of the update frame if a CAF/DICT.
575 CCC = (IS_CAF_OR_DICT_CC(CC_pap)) ? GRAB_COST_CENTRE(SuB) : CC_pap;
577 #endif /* PROFILING */
579 /* Restore SuA, SuB, RetReg */
580 RetReg = GRAB_RET(SuB);
585 * Squeeze out update frame from B stack. Note that despite our best
586 * efforts with [AB]REL and friends, the loop order depends on the B
589 for (i = NNonPtrWords - 1; i >= 0; i--)
590 SpB[BREL(i+STD_UF_SIZE)] = SpB[BREL(i)];
592 SpB += BREL(STD_UF_SIZE);
595 * All done! Restart by re-entering Node
596 * Don't count this entry for ticky-ticky profiling.
599 #if 0 /* defined(GRAN) */
600 GRAN_EXEC(16,4,7,4,0);
602 InfoPtr=(D_)(INFO_PTR(Node));
603 JMP_(ENTRY_CODE(InfoPtr));
616 The entry code for a generic PAP. @Node@ points to the PAP closure.
617 Reload the stacks from the PAP, and enter the closure stored in the
618 PAP. PAPs are in HNF so no update frame is needed.
623 /* Use STG registers for these locals which must survive the STK_CHK */
624 #define NPtrWords (R2.i)
625 #define NNonPtrWords (R3.i)
626 #if defined(PROFILING)
627 # define CC_pap ((CostCentre)(R7.p))
630 /* These locals don't have to survive the STK_CHK */
638 while (AREL(SuA - SpA) == 0 && BREL(SuB - SpB) == 0) {
640 if (SuB < STKO_BSTK_BOT(StkOReg)) {
642 LivenessReg = LIVENESS_R1;
644 JMP_(StackUnderflowEnterNode);
648 /* We're sitting on top of an update frame, so let's do the business */
650 Updatee = GRAB_UPDATEE(SuB);
651 UPD_IND(Updatee, Node);
653 #if defined(PROFILING)
655 * Restore the Cost Centre too (if required); again see Sansom
656 * thesis p 183. Take the CC out of the update frame if a
660 CC_pap = (CostCentre) CC_HDR(Node);
661 CCC = (IS_CAF_OR_DICT_CC(CC_pap)) ? GRAB_COST_CENTRE(SuB) : CC_pap;
663 #endif /* PROFILING */
665 RetReg = GRAB_RET(SuB);
668 SpB += BREL(STD_UF_SIZE);
671 NPtrWords = DYN_CLOSURE_NoPTRS(Node) - 1; /* The saved Node counts as one */
672 NNonPtrWords = DYN_CLOSURE_NoNONPTRS(Node);
674 /* Ticky-ticky profiling info */
677 /* Enter PAP cost centre -- lexical scoping only */
678 ENTER_CC_PAP_CL(Node);
681 * Check for stack overflow. Ask to take all of the current frame with
682 * us to the new world. If there is no update frame on the current stack,
683 * bWords will exceed the size of the B stack, but StackOverflow will deal
687 aWords = AREL(SuA - SpA);
688 bWords = BREL(SuB - SpB) + STD_UF_SIZE;
690 STK_CHK(LIVENESS_R1, NPtrWords, NNonPtrWords, aWords, bWords, 0, 0);
692 SpA -= AREL(NPtrWords);
693 SpB -= BREL(NNonPtrWords);
696 p = Node + DYN_HS; /* Point to first pointer word */
699 /* Reload the stacks */
701 for (i=0; i<NPtrWords; i++) SpA[AREL(i)] = (P_) *p++;
702 for (i=0; i<NNonPtrWords; i++) SpB[BREL(i)] = *p++;
706 InfoPtr=(D_)(INFO_PTR(Node));
707 JMP_(ENTRY_CODE(InfoPtr));
718 The info table for a generic PAP:
720 DYN_ITBL(PAP_info,PAP_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,EF_,PAP_K,"PAP","->");