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}).
10 Some of this stuff has been separated (correctly!) into StgThreads.lhc
11 for version 0.23. Could someone (Hans?) bring us up to date, please!
15 \item Indirection entry code and info table.
16 \item Black Hole entry code and info table.
17 \item Update frame code and return vectors.
18 \item PAP update code.
19 \item PAP entry code and info table.
22 System-wide constants need to be included:
24 #define MAIN_REG_MAP /* STG world */
30 # include "Statistics.h"
36 #if defined(TICKY_TICKY)
37 void PrintTickyInfo(STG_NO_ARGS);
41 %************************************************************************
43 \subsection[indirection-code]{Indirection code}
45 %************************************************************************
47 The entry code for indirections and the indirection info-table.
52 ENT_IND(Node); /* Ticky-ticky profiling info */
54 Node = (P_) IND_CLOSURE_PTR((P_) Node);
56 InfoPtr=(D_)(INFO_PTR(Node));
57 JMP_(ENTRY_CODE(InfoPtr));
61 IND_ITBL(Ind_info,Ind_entry,const,EF_);
64 We also need a special @CAF@ indirection info table which is used to
65 indirect @CAF@s to evaluated results in the heap.
67 STGFUN(Caf_entry) /* same as Ind_entry */
72 Node = (P_) IND_CLOSURE_PTR((P_) Node);
74 InfoPtr=(D_)(INFO_PTR(Node));
75 JMP_(ENTRY_CODE(InfoPtr));
79 CAF_ITBL(Caf_info,Caf_entry,const,EF_);
82 %************************************************************************
84 \subsection[black-hole-code]{Black Hole code}
86 %************************************************************************
88 The entry code for black holes abort indicating a cyclic data dependency.
89 It is used to overwrite closures currently being evaluated.
91 In the concurrent world, black holes are synchronization points, and they
92 are turned into blocking queues when there are threads waiting for the
93 evaluation of the closure to finish.
97 EXTFUN(EnterNodeCode);
98 EXTFUN(StackUnderflowEnterNode);
101 void raiseError PROTO((StgStablePtr));
102 extern StgStablePtr errorHandler; /* NB: prone to magic-value-ery (WDP 95/12) */
109 (void) STGCALL1(int,(void *, FILE *),fflush,stdout);
110 (void) STGCALL2(int,(),fprintf,stderr,"Entered a `black hole': the program has a cyclic data dependency.\n");
112 # if defined(PROFILING)
114 CostCentre cc = (CostCentre) CC_HDR(Node);
115 (void) STGCALL5(int,(),fprintf,stderr,"Cost Centre: %s Module: %s Group %s\n",cc->label, cc->module, cc->group);
119 # if defined(TICKY_TICKY)
120 if (RTSflags.TickyFlags.showTickyStats) {
121 (void) STGCALL0(void,(),PrintTickyInfo);
125 (void) STGCALL1(void,(void *, StgStablePtr), raiseError, errorHandler);
134 (void) STGCALL4(int,(),fprintf,stderr,"GRAN_CHECK in BH_UPD_entry: Entered a `black hole' @ 0x%x (CurrentTSO @ 0x%x\n ",Node,CurrentTSO);
138 STGCALL0(void,(),GranSimBlock); /* Do this before losing its TSO_LINK */
141 TSO_LINK(CurrentTSO) = Nil_closure;
142 SET_INFO_PTR(Node, BQ_info);
143 BQ_ENTRIES(Node) = (W_) CurrentTSO;
145 # if defined(GCap) || defined(GCgn)
146 /* If we modify a black hole in the old generation,
147 we have to make sure it goes on the mutables list */
149 if(Node <= StorageMgrInfo.OldLim) {
150 MUT_LINK(Node) = (W_) StorageMgrInfo.OldMutables;
151 StorageMgrInfo.OldMutables = Node;
153 MUT_LINK(Node) = MUT_NOT_LINKED;
156 LivenessReg = LIVENESS_R1;
158 TSO_PC1(CurrentTSO) = EnterNodeCode;
161 QP_Event1("GR", CurrentTSO);
165 if(RTSflags.ParFlags.granSimStats) {
166 TIME now = CURRENT_TIME;
167 TSO_EXECTIME(CurrentTSO) += now - TSO_BLOCKEDAT(CurrentTSO);
168 TSO_BLOCKCOUNT(CurrentTSO)++;
169 TSO_QUEUE(CurrentTSO) = Q_BLOCKED;
170 TSO_BLOCKEDAT(CurrentTSO) = now;
171 DumpGranEvent(GR_BLOCK, CurrentTSO);
176 /* CurrentTSO = Nil_closure; */
177 ReSchedule(NEW_THREAD);
187 /* made external so that debugger can get at it more effectively */
188 STGFUN(BH_SINGLE_entry)
192 (void) STGCALL1(int,(void *, FILE *),fflush,stdout);
193 (void) STGCALL2(int,(),fprintf,stderr,"Entered a single-entry `black hole' --\n");
194 (void) STGCALL2(int,(),fprintf,stderr,"either the compiler made a mistake on single-entryness,\n");
195 (void) STGCALL2(int,(),fprintf,stderr,"or the program has a cyclic data dependency.\n");
197 #if defined(PROFILING)
199 CostCentre cc = (CostCentre) CC_HDR(Node);
200 (void) STGCALL5(int,(),fprintf,stderr, "Cost Centre: %s Module: %s Group %s\n",cc->label, cc->module, cc->group);
204 # if defined(TICKY_TICKY)
205 if (RTSflags.TickyFlags.showTickyStats) {
206 (void) STGCALL0(void,(),PrintTickyInfo);
211 (void) STGCALL1(void,(void *, StgStablePtr), raiseError, errorHandler);
220 Updatable closures are overwritten with a black hole of a fixed size,
224 CAT_DECLARE(BH,BH_K,"BH","BH") /* just one, shared */
226 BH_ITBL(BH_UPD_info,BH_UPD_entry,U,const,EF_);
229 Single-Entry closures, which are not updated, are also overwritten
230 with a black hole. They have size @MIN_NONUPD_SIZE@.
233 BH_ITBL(BH_SINGLE_info,BH_SINGLE_entry,N,const,EF_);
236 %************************************************************************
238 \subsection[static-update-code]{Static update code in update frames}
240 %************************************************************************
242 This code is pointed to from update frames. It has to cope with
243 any kind of algebraic return: vectored or unvectored.
245 See \tr{SMupdate.lh} for a description of the various update frames
246 and the macros defining their layout.
248 On entry to this code:
250 \item @R1@ points to a recently created heap object (return in heap) or
251 is dead (return in regs).
252 \item @R2@ points to the info table for the constructor.
253 \item When returning in regs, any of the return-regs (@R3@...) may be live,
254 but aren't used by this code. They must be preserved.
255 \item @SpB@ points to the topmost word of the update frame.
258 NEW update mechanism (Jan '94):
260 When returning to an update frame, we want to jump directly to the
261 update code for the constructor in hand. Because of the various
262 possible return conventions (all of which must be handled by the
263 generic update frame), we actually end up with a somewhat indirect
268 STGFUN(StdUpdFrameDirectReturn)
271 JMP_(UPDATE_CODE(InfoPtr));
276 NB: For direct returns to work properly, the name of the routine must be
277 the same as the name of the vector table with vtbl_ removed and DirectReturn
278 appended. This is all the mangler understands.
283 vtbl_StdUpdFrame[] = {
284 /* at least "MAX_VECTORED_RTN" elements (see GhcConstants.lh) */
285 (W_) StdUpdFrameDirectReturn/*0*/,
286 (W_) StdUpdFrameDirectReturn/*1*/,
287 (W_) StdUpdFrameDirectReturn/*2*/,
288 (W_) StdUpdFrameDirectReturn/*3*/,
289 (W_) StdUpdFrameDirectReturn/*4*/,
290 (W_) StdUpdFrameDirectReturn/*5*/,
291 (W_) StdUpdFrameDirectReturn/*6*/,
292 (W_) StdUpdFrameDirectReturn/*7*/
297 %************************************************************************
299 \subsection[existing-con-update-code]{Update code for existing constructors}
301 %************************************************************************
303 Here is the standard update code for objects that are returned in the
304 heap (or those which are initially returned in registers, but have
305 already been allocated in the heap earlier in the update chain). In
306 either case, @Node@ points to the heap object. The update code grabs
307 the address of the updatee out of the partial update frame (the return
308 address has already been popped), makes the updatee an indirection to
309 @Node@, and returns according to the convention for the constructor.
312 #define IND_UPD_TEMPLATE(label, retvector) \
316 UPD_EXISTING(); /* Ticky-ticky profiling info */ \
317 /* Update thing off stk with an indirection to Node */ \
318 UPD_IND(GRAB_UPDATEE(SpB), Node); \
319 /* Pop the standard update frame */ \
320 POP_STD_UPD_FRAME() \
326 IND_UPD_TEMPLATE(IndUpdRetDir, DIRECT(((P_)RetReg)))
327 IND_UPD_TEMPLATE(IndUpdRetV0, ((P_)RetReg)[RVREL(0)])
328 IND_UPD_TEMPLATE(IndUpdRetV1, ((P_)RetReg)[RVREL(1)])
329 IND_UPD_TEMPLATE(IndUpdRetV2, ((P_)RetReg)[RVREL(2)])
330 IND_UPD_TEMPLATE(IndUpdRetV3, ((P_)RetReg)[RVREL(3)])
331 IND_UPD_TEMPLATE(IndUpdRetV4, ((P_)RetReg)[RVREL(4)])
332 IND_UPD_TEMPLATE(IndUpdRetV5, ((P_)RetReg)[RVREL(5)])
333 IND_UPD_TEMPLATE(IndUpdRetV6, ((P_)RetReg)[RVREL(6)])
334 IND_UPD_TEMPLATE(IndUpdRetV7, ((P_)RetReg)[RVREL(7)])
337 %************************************************************************
339 \subsection[no-update-code]{Code for Erroneous Updates}
341 %************************************************************************
350 fprintf(stderr, "Update error: not a constructor!\n");
361 fprintf(stderr, "Standard error: should never happen!\n");
368 %************************************************************************
370 \subsection[permanent-indirections]{Lexical Scoping Updates}
372 %************************************************************************
374 A function entered without any arguments is updated with an
375 indirection. For lexically scoped profiling we still need to set the
376 cost centre if we enter the PAP. As the indirection is removed by the
377 garbage collector this would not be possible.
379 To solve this problem we introduce a permanent indirection which sets
380 the cost centre when entered. The heap profiler ignores the space
381 occupied by it as it would not reside in the heap during normal
384 In ticky-land: If we are trying to collect update-entry counts
385 (controlled by an RTS flag), then we must use permanent indirections
386 (the shorting-out of regular indirections loses the counts).
389 #if defined(PROFILING) || defined(TICKY_TICKY)
391 STGFUN(Perm_Ind_entry)
395 /* Don't add INDs to granularity cost */
397 /* Dont: ENT_IND(Node); for ticky-ticky; this ind is here only to help ticky */
399 /* Enter PAP cost centre -- lexical scoping only */
400 ENTER_CC_PAP_CL(Node);
402 Node = (P_) IND_CLOSURE_PTR((P_) Node);
404 /* Dont: ENT_VIA_NODE(); for ticky-ticky; as above */
406 InfoPtr=(D_)(INFO_PTR(Node));
409 GRAN_EXEC(1,1,2,0,0);
411 JMP_(ENTRY_CODE(InfoPtr));
415 PERM_IND_ITBL(Perm_Ind_info,Perm_Ind_entry,const,EF_);
417 #endif /* PROFILING or TICKY */
420 %************************************************************************
422 \subsection[partial-application-updates]{Partial applications}
424 %************************************************************************
426 See STG paper implementation section of Partial application updates.
428 We jump here when the current function fails an argument satisfaction
429 check. There can be two reasons for this. In the usual case, there
430 is an update frame blocking our access to anything deeper on the
431 stack. We then update the updatee in the frame with a partial
432 application node and squeeze out the update frame. The other
433 possibility is that we are running threaded code, and we are sitting
434 on the bottom of a stack chunk. In this case, we still build the
435 partial application, but we have nothing in our hands to update, so we
436 underflow the stack (awakening the previous chunk) and enter the
437 partial application node just built.
439 On entry to @UpdatePAP@, we assume the following:
441 \item SuB points to topmost word of an update frame or to the bottom of a
443 \item SpA and SpB point to the topmost words of their respective stacks.
444 \item Node points to the closure which needs more arguments than are there.
451 * Use STG registers for these locals which must survive the HEAP_CHK.
452 * Don't squash Node (R1), because it's an implicit argument.
455 #define NNonPtrWords (R2.i)
456 #define NPtrWords (R3.i)
457 #define NArgWords (R4.i)
458 #define PapSize (R5.i)
459 #if defined(PROFILING)
460 # define CC_pap ((CostCentre)(R7.p))
463 /* These other locals do not have to survive a HEAP_CHK */
476 NPtrWords = AREL(SuA - SpA);
477 NNonPtrWords = BREL(SuB - SpB);
479 ASSERT(NPtrWords >= 0);
480 ASSERT(NNonPtrWords >= 0);
482 NArgWords = NPtrWords + NNonPtrWords + 1; /* +1 for Node */
484 #if defined(PROFILING)
485 /* set "CC_pap" to go in the updatee (see Sansom thesis, p 183) */
487 CC_pap /*really cc_enter*/ = (CostCentre) CC_HDR(Node);
488 if (IS_SUBSUMED_CC(CC_pap) /*really cc_enter*/)
492 if (NArgWords == 1) {
495 * No arguments, only Node. Skip building the PAP and
496 * just plan to update with an indirection.
503 /* Build the PAP. A generic PAP closure is laid out thus:
504 * code ptr, size, no of words of ptrs, Node, ptrs, non-ptrs
505 * (i.e. a DYN closure)
506 * ToDo: add stuff for special cases, to omit size and no. of ptrs
507 * (Still ToDo? (JSM))
510 PapSize = NArgWords + DYN_HS;
512 ALLOC_UPD_PAP(DYN_HS, NArgWords, 0, PapSize);
513 CC_ALLOC(CC_pap, PapSize, PAP_K);
515 /* Allocate PapClosure -- Only Node (R1) is live */
516 HEAP_CHK(LIVENESS_R1, PapSize, 0);
518 PapClosure = Hp + 1 - PapSize; /* The new PapClosure */
520 SET_DYN_HDR(PapClosure, PAP_info, CC_pap, NArgWords + DYN_VHS, NPtrWords + 1);
522 /* Now fill in the closure fields */
525 for (i = NNonPtrWords - 1; i >= 0; i--) *p-- = (W_) SpB[BREL(i)];
526 for (i = NPtrWords - 1; i >= 0; i--) *p-- = (W_) SpA[AREL(i)];
531 * Finished constructing PAP closure; now update the updatee. But
532 * wait! What if there is no updatee? Then we fall off the
537 if (SuB < STKO_BSTK_BOT(StkOReg)) {
540 LivenessReg = LIVENESS_R1;
542 JMP_(StackUnderflowEnterNode);
547 * Now we have a standard update frame, so we update the updatee with
548 * either the new PAP or Node.
550 * Supposedly, it is not possible to get a constructor update frame,
552 * (Because they have *never* been implemented. (WDP))
555 Updatee = GRAB_UPDATEE(SuB);
556 UPD_IND(Updatee, PapClosure); /* Indirect Updatee to PapClosure */
558 if (NArgWords != 1) {
559 UPD_PAP_IN_NEW(NArgWords);
564 #if defined(PROFILING)
566 * Lexical scoping requires a *permanent* indirection, and we
567 * also have to set the cost centre for the indirection.
569 INFO_PTR(Updatee) = (W_) Perm_Ind_info;
570 SET_CC_HDR(Updatee, CC_pap);
572 #endif /* PROFILING */
575 #if defined(PROFILING)
577 * Restore the Cost Centre too (if required); again see Sansom thesis p 183.
578 * Take the CC out of the update frame if a CAF/DICT.
581 CCC = (IS_CAF_OR_DICT_CC(CC_pap)) ? GRAB_COST_CENTRE(SuB) : CC_pap;
583 #endif /* PROFILING */
585 /* Restore SuA, SuB, RetReg */
586 RetReg = GRAB_RET(SuB);
591 * Squeeze out update frame from B stack. Note that despite our best
592 * efforts with [AB]REL and friends, the loop order depends on the B
595 for (i = NNonPtrWords - 1; i >= 0; i--)
596 SpB[BREL(i+STD_UF_SIZE)] = SpB[BREL(i)];
598 SpB += BREL(STD_UF_SIZE);
601 * All done! Restart by re-entering Node
602 * Don't count this entry for ticky-ticky profiling.
606 GRAN_EXEC(16,4,7,4,0);
608 InfoPtr=(D_)(INFO_PTR(Node));
609 JMP_(ENTRY_CODE(InfoPtr));
622 The entry code for a generic PAP. @Node@ points to the PAP closure.
623 Reload the stacks from the PAP, and enter the closure stored in the
624 PAP. PAPs are in HNF so no update frame is needed.
629 /* Use STG registers for these locals which must survive the STK_CHK */
630 #define NPtrWords (R2.i)
631 #define NNonPtrWords (R3.i)
632 #if defined(PROFILING)
633 # define CC_pap ((CostCentre)(R7.p))
636 /* These locals don't have to survive the STK_CHK */
644 while (AREL(SuA - SpA) == 0 && BREL(SuB - SpB) == 0) {
646 if (SuB < STKO_BSTK_BOT(StkOReg)) {
648 LivenessReg = LIVENESS_R1;
650 JMP_(StackUnderflowEnterNode);
654 /* We're sitting on top of an update frame, so let's do the business */
656 Updatee = GRAB_UPDATEE(SuB);
657 UPD_IND(Updatee, Node);
659 #if defined(PROFILING)
661 * Restore the Cost Centre too (if required); again see Sansom
662 * thesis p 183. Take the CC out of the update frame if a
666 CC_pap = (CostCentre) CC_HDR(Node);
667 CCC = (IS_CAF_OR_DICT_CC(CC_pap)) ? GRAB_COST_CENTRE(SuB) : CC_pap;
669 #endif /* PROFILING */
671 RetReg = GRAB_RET(SuB);
674 SpB += BREL(STD_UF_SIZE);
677 NPtrWords = DYN_CLOSURE_NoPTRS(Node) - 1; /* The saved Node counts as one */
678 NNonPtrWords = DYN_CLOSURE_NoNONPTRS(Node);
680 /* Ticky-ticky profiling info */
683 /* Enter PAP cost centre -- lexical scoping only */
684 ENTER_CC_PAP_CL(Node);
687 * Check for stack overflow. Ask to take all of the current frame with
688 * us to the new world. If there is no update frame on the current stack,
689 * bWords will exceed the size of the B stack, but StackOverflow will deal
693 aWords = AREL(SuA - SpA);
694 bWords = BREL(SuB - SpB) + STD_UF_SIZE;
696 STK_CHK(LIVENESS_R1, NPtrWords, NNonPtrWords, aWords, bWords, 0, 0);
698 SpA -= AREL(NPtrWords);
699 SpB -= BREL(NNonPtrWords);
702 p = Node + DYN_HS; /* Point to first pointer word */
705 /* Reload the stacks */
707 for (i=0; i<NPtrWords; i++) SpA[AREL(i)] = (P_) *p++;
708 for (i=0; i<NNonPtrWords; i++) SpB[BREL(i)] = *p++;
712 InfoPtr=(D_)(INFO_PTR(Node));
713 JMP_(ENTRY_CODE(InfoPtr));
724 The info table for a generic PAP:
726 DYN_ITBL(PAP_info,PAP_entry,UpdErr,0,INFO_OTHER_TAG,0,0,const,EF_,PAP_K,"PAP","->");