#include "rtsdefs.h"
-extern void PrintRednCountInfo(STG_NO_ARGS);
-extern I_ showRednCountStats;
+void PrintTickyInfo(STG_NO_ARGS);
#ifdef __DO_ARITY_CHKS__
I_ ExpectedArity;
fprintf(stderr, "Arity error: called with %ld args, should have been %ld\n",
ExpectedArity, n);
-#if defined(DO_REDN_COUNTING)
- if (showRednCountStats) {
- PrintRednCountInfo();
- }
+#if defined(TICKY_TICKY)
+ if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
#endif
EXIT(EXIT_FAILURE);
StackOverflow(STG_NO_ARGS)
{
fflush(stdout);
- StackOverflowHook(SM_word_stk_size * sizeof(W_)); /*msg*/
+ StackOverflowHook(RTSflags.GcFlags.stksSize * sizeof(W_)); /*msg*/
-#if defined(DO_REDN_COUNTING)
- if (showRednCountStats) {
- PrintRednCountInfo();
- }
+#if defined(TICKY_TICKY)
+ if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
#endif
EXIT(EXIT_FAILURE);
are turned into indirections to the common black hole (or blocking queue).
\begin{code}
-
-I_ squeeze_upd_frames = 1; /* now ON by default */
-
I_
SqueezeUpdateFrames(bottom, top, frame)
P_ bottom;
return 0;
if ((prev_frame = GRAB_SuB(frame)) <= bottom) {
-#if !defined(CONCURRENT) && defined(SM_DO_BH_UPDATE)
- if (!noBlackHoles)
+#if !defined(CONCURRENT)
+ if ( RTSflags.GcFlags.lazyBlackHoling )
UPD_BH(GRAB_UPDATEE(frame), BH_UPD_info);
#endif
return 0;
}
/*
- * Now, we're at the bottom. Frame points to the lowest update frame on the
- * stack, and its saved SuB actually points to the frame above. We have to walk
- * back up the stack, squeezing out empty update frames and turning the pointers
- * back around on the way back up.
+ * Now, we're at the bottom. Frame points to the lowest update
+ * frame on the stack, and its saved SuB actually points to the
+ * frame above. We have to walk back up the stack, squeezing out
+ * empty update frames and turning the pointers back around on the
+ * way back up.
*/
/*
- * The bottom-most frame has not been altered, and we never want to eliminate it
- * anyway. Just black hole the updatee and walk one step up
- * before starting to squeeze. When you get to the topmost frame,
- * remember that there are still some words above it that might
- * have to be moved.
+ * The bottom-most frame has not been altered, and we never want
+ * to eliminate it anyway. Just black hole the updatee and walk
+ * one step up before starting to squeeze. When you get to the
+ * topmost frame, remember that there are still some words above
+ * it that might have to be moved.
*/
-#if !defined(CONCURRENT) && defined(SM_DO_BH_UPDATE)
- if (!noBlackHoles)
+#if !defined(CONCURRENT)
+ if ( RTSflags.GcFlags.lazyBlackHoling )
UPD_BH(GRAB_UPDATEE(frame), BH_UPD_info);
#endif
prev_frame = frame;
frame = next_frame;
/*
- * Loop through all of the middle frames (everything except the very
- * bottom and the very top).
+ * Loop through all of the middle frames (everything except the
+ * very bottom and the very top).
*/
while ((next_frame = GRAB_SuB(frame)) != NULL) {
P_ sp;
/*
fprintf(stderr, "squeezing frame at %lx, ret %lx\n", frame,
GRAB_RET(frame));
- */
+ */
#ifdef CONCURRENT
/* Check for a blocking queue on the node that's going away */
/* Urgh. Two queues. Merge them. */
P_ tso = (P_) BQ_ENTRIES(updatee_keep);
- while (TSO_LINK(tso) != Nil_closure)
+ while (TSO_LINK(tso) != Prelude_Z91Z93_closure)
tso = TSO_LINK(tso);
TSO_LINK(tso) = (P_) BQ_ENTRIES(updatee_bypass);
}
#endif
- UPD_EXISTING(); /* ticky stuff (NB: nothing for spat-profiling) */
+ UPD_SQUEEZED(); /* ticky stuff (NB: nothing for spat-profiling) */
UPD_IND(updatee_bypass, updatee_keep);
sp = frame - BREL(1); /* Toss the current frame */
displacement += STD_UF_SIZE;
} else {
-#if !defined(CONCURRENT) && defined(SM_DO_BH_UPDATE)
- if (!noBlackHoles)
+#if !defined(CONCURRENT)
+ if ( RTSflags.GcFlags.lazyBlackHoling )
UPD_BH(GRAB_UPDATEE(frame), BH_UPD_info);
#endif
if (displacement > 0) {
P_ next_frame_bottom = next_frame + BREL(STD_UF_SIZE);
- /*
+ /*
fprintf(stderr, "sliding [%lx, %lx] by %d\n", sp, next_frame_bottom,
displacement);
*/
}
/*
- * Now handle the topmost frame. Patch SuB, black hole the updatee,
- * and slide down.
+ * Now handle the topmost frame. Patch SuB, black hole the
+ * updatee, and slide down.
*/
PUSH_SuB(frame, prev_frame);
-#if !defined(CONCURRENT) && defined(SM_DO_BH_UPDATE)
- if (!noBlackHoles)
+#if !defined(CONCURRENT)
+ if ( RTSflags.GcFlags.lazyBlackHoling )
UPD_BH(GRAB_UPDATEE(frame), BH_UPD_info);
#endif
}
return displacement;
}
-
\end{code}
%************************************************************************
SET_TASK_ACTIVITY(ST_OVERHEAD);
- /*
- * fprintf(stderr,"StackOverflow:liveness=%lx,a=%lx,b=%lx\n",
- * liveness,words_of_a,words_of_b);
- */
+ /*?
+ if (RTSflags.GcFlags.giveStats) {
+ fprintf(stderr,"StackOverflow:liveness=%lx,a=%lx,b=%lx\n",
+ liveness,words_of_a,words_of_b);
+ }
+ ?*/
old_stko = SAVE_StkO;
- /*
- * fprintf(stderr, "SpA %lx SuA %lx SpB %lx SuB %lx\n", STKO_SpA(old_stko),
- * STKO_SuA(old_stko), STKO_SpB(old_stko), STKO_SuB(old_stko));
- */
+ /*?
+ if (RTSflags.GcFlags.giveStats) {
+ fprintf(stderr, "stko: %lx SpA %lx SuA %lx SpB %lx SuB %lx\n",
+ old_stko, STKO_SpA(old_stko),
+ STKO_SuA(old_stko), STKO_SpB(old_stko), STKO_SuB(old_stko));
+ }
+ ?*/
+
+ if (RTSflags.GcFlags.squeezeUpdFrames) {
- if (squeeze_upd_frames) {
i = SqueezeUpdateFrames(STKO_BSTK_BOT(old_stko), STKO_SpB(old_stko),
- STKO_SuB(old_stko));
+ STKO_SuB(old_stko));
+
STKO_SuB(old_stko) += BREL(i);
STKO_SpB(old_stko) += BREL(i);
+
+ /*?
+ if (RTSflags.GcFlags.giveStats)
+ fprintf(stderr, "Just squeezed; now: SpB %lx SuB %lx retval %d\n", STKO_SpB(old_stko), STKO_SuB(old_stko), i); ?*/
+
if ((P_) STKO_SpA(old_stko) - AREL(headroom) > STKO_SpB(old_stko)) {
- /*
- * fprintf(stderr, "SpA %lx SpB %lx headroom %d\n", STKO_SpA(old_stko),
- * STKO_SpB(old_stko), headroom);
- */
+ /*?
+ if (RTSflags.GcFlags.giveStats) {
+ fprintf(stderr, "Squeezed; now: SpA %lx SpB %lx headroom %d\n", STKO_SpA(old_stko),
+ STKO_SpB(old_stko), headroom);
+ }
+ ?*/
/* We saved enough space to continue on the old StkO */
return 0;
}
SAVE_Liveness = liveness;
+ ASSERT(sanityChk_StkO(old_stko));
+
/* Double the stack chunk size each time we grow the stack */
+ /*?
+ if (RTSflags.GcFlags.giveStats) {
+ fprintf(stderr, "Stko %lx: about to double stk-chk size from %d...\n", old_stko, STKO_CLOSURE_CTS_SIZE(old_stko)); } ?*/
cts_size = STKO_CLOSURE_CTS_SIZE(old_stko) * 2;
if (SAVE_Hp + STKO_HS + cts_size > SAVE_HpLim) {
* Even in the uniprocessor world, we may have to reenter node in case
* node is a selector shorted out by GC.
*/
- assert(liveness & LIVENESS_R1);
+ ASSERT(liveness & LIVENESS_R1);
TSO_PC2(CurrentTSO) = EnterNodeCode;
really_reenter_node = 1;
}
+ /*?
+ if (RTSflags.GcFlags.giveStats) {
+ fprintf(stderr, "StkO %lx: stk-chk GC: size %d...\n",
+ old_stko, STKO_HS + cts_size);
+ } ?*/
ReallyPerformThreadGC(STKO_HS + cts_size, rtsFalse);
+ /*
+ now, GC semantics promise to have left SAVE_Hp with
+ the requested space *behind* it; as we will bump
+ SAVE_Hp just below, we had better first put it back.
+ (PS: Finding this was a two-day bug-hunting trip...)
+ Will & Phil 95/10
+ */
+ SAVE_Hp -= STKO_HS + cts_size;
+
old_stko = SAVE_StkO;
}
ALLOC_STK(STKO_HS, cts_size, 0);
SAVE_Hp += STKO_HS + cts_size;
SET_STKO_HDR(new_stko, StkO_info, CCC);
+ /*? if (RTSflags.GcFlags.giveStats) fprintf(stderr, "New StkO now %lx...\n", new_stko); ?*/
+
/* Initialize the StkO, as in NewThread */
STKO_SIZE(new_stko) = cts_size + STKO_VHS;
STKO_SpB(new_stko) = STKO_SuB(new_stko) = STKO_BSTK_BOT(new_stko) + BREL(1);
STKO_SpA(new_stko) = STKO_SuA(new_stko) = STKO_ASTK_BOT(new_stko) + AREL(1);
STKO_LINK(new_stko) = old_stko;
+ /*? if (RTSflags.GcFlags.giveStats) fprintf(stderr, "New StkO SpA = %lx...\n", STKO_SpA(new_stko) ); ?*/
+
STKO_RETURN(new_stko) = SAVE_Ret;
#ifdef PAR
* When we fall off of the top stack segment, we will either be
* returning an algebraic data type, in which case R2 holds a
* valid info ptr, or we will be returning a primitive
- * (e.g. int#), in which case R2 is garbage. If we need to perform
+ * (e.g. Int#), in which case R2 is garbage. If we need to perform
* GC to pull in the lower stack segment (this should only happen
* because of task migration), then we need to know the register
* liveness for the algebraic returns. We get the liveness out of
STKO_SpA(old_stko) += AREL(words_of_a);
STKO_SpB(old_stko) += BREL(words_of_b);
-#ifdef DO_REDN_COUNTING
+#ifdef TICKY_TICKY
/* Record the stack depths in chunks below the new stack object */
STKO_ADEP(new_stko) = STKO_ADEP(old_stko) +
#endif
if (STKO_SpB(old_stko) < STKO_BSTK_BOT(old_stko)) {
-
/*
- * This _should_ only happen if PAP_entry fails a stack check and there is
- * no update frame on the current stack. We can deal with this by storing a
- * function's argument requirements in its info table, peering into the PAP
- * (it had better be in R1) for the function pointer and taking only the
- * necessary number of arguments, but this would be hard, so we haven't done
- * it.
+ * This _should_ only happen if PAP_entry fails a stack check
+ * and there is no update frame on the current stack. We can
+ * deal with this by storing a function's argument
+ * requirements in its info table, peering into the PAP (it
+ * had better be in R1) for the function pointer and taking
+ * only the necessary number of arguments, but this would be
+ * hard, so we haven't done it.
*/
fflush(stdout);
- fprintf(stderr, "StackOverflow too deep. Probably a PAP with no update frame.\n");
+ fprintf(stderr, "StackOverflow too deep (SpB=%lx, Bstk bot=%lx). Probably a PAP with no update frame.\n", STKO_SpB(old_stko), STKO_BSTK_BOT(old_stko));
abort(); /* an 'abort' may be overkill WDP 95/04 */
}
/* Move A stack words from old StkO to new StkO */
P_ frame = STKO_SuB(new_stko) - BREL(STD_UF_SIZE);
/*
- * fprintf(stderr, "Stolen update frame: (old %lx, new %lx) SuA %lx, SuB
- * %lx, return %lx\n", old_stko, new_stko, GRAB_SuA(frame), GRAB_SuB(frame),
- * GRAB_RET(frame));
+ fprintf(stderr, "Stolen update frame: (old %lx, new %lx) SuA %lx, SuB
+ %lx, return %lx\n", old_stko, new_stko, GRAB_SuA(frame), GRAB_SuB(frame),
+ GRAB_RET(frame));
*/
STKO_SuA(old_stko) = GRAB_SuA(frame);
STKO_SuB(new_stko) = frame;
}
+
+ ASSERT(sanityChk_StkO(new_stko));
+
SAVE_StkO = new_stko;
+
return really_reenter_node;
}
\end{code}