[project @ 1996-01-11 14:06:51 by partain]
[ghc-hetmet.git] / ghc / runtime / main / StgOverflow.lc
index 720f243..aac16e5 100644 (file)
@@ -10,8 +10,7 @@
 
 #include "rtsdefs.h"
 
-extern void PrintRednCountInfo(STG_NO_ARGS);
-extern I_   showRednCountStats;
+void PrintTickyInfo(STG_NO_ARGS);
 
 #ifdef __DO_ARITY_CHKS__
 I_ ExpectedArity;
@@ -24,10 +23,8 @@ ArityError(n)
     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);
@@ -49,12 +46,10 @@ void
 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);
@@ -72,9 +67,6 @@ Code for squeezing out vacuous update frames.  Updatees of squeezed frames
 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;
@@ -93,8 +85,8 @@ P_ frame;
        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;
@@ -115,30 +107,31 @@ P_ frame;
     }
 
     /*
-     * 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;
@@ -155,7 +148,7 @@ P_ frame;
            /*
              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 */
@@ -182,15 +175,15 @@ P_ frame;
            }
 #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
 
@@ -206,7 +199,7 @@ P_ frame;
        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);
            */
@@ -221,14 +214,14 @@ P_ frame;
     }
 
     /* 
-     * 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
 
@@ -246,7 +239,6 @@ P_ frame;
     }
     return displacement;
 }
-
 \end{code}
 
 %************************************************************************
@@ -293,29 +285,35 @@ W_ args2;
     SET_TASK_ACTIVITY(ST_OVERHEAD);
 
 
-    /*
-     * fprintf(stderr,"StackOverflow:liveness=%lx,a=%lx,b=%lx\n",
-     * liveness,words_of_a,words_of_b);
-     */
+    /*?/
+      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));
-     */
+    /*?/
+      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);
+
+     /*?/ 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);
-            */
+           /*?/
+             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;
@@ -323,7 +321,10 @@ W_ args2;
     }
     SAVE_Liveness = liveness;
 
+    ASSERT(sanityChk_StkO(old_stko));
+
     /* Double the stack chunk size each time we grow the stack */
+    /*?/ 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) {
@@ -332,11 +333,21 @@ W_ args2;
             * 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;
        }
+       /*?/ 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);
@@ -344,12 +355,16 @@ W_ args2;
     SAVE_Hp += STKO_HS + cts_size;
     SET_STKO_HDR(new_stko, StkO_info, CCC);
 
+    /*?/ 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;
 
+    /*?/ fprintf(stderr, "New StkO SpA = %lx...\n", STKO_SpA(new_stko) ); /?*/
     STKO_RETURN(new_stko) = SAVE_Ret;
 
 #ifdef PAR
@@ -358,7 +373,7 @@ W_ args2;
      * 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
@@ -378,7 +393,7 @@ W_ args2;
     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) +
@@ -388,17 +403,17 @@ W_ args2;
 #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 */
@@ -420,9 +435,9 @@ W_ args2;
        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);
@@ -437,7 +452,11 @@ W_ args2;
 
        STKO_SuB(new_stko) = frame;
     }
+
+    ASSERT(sanityChk_StkO(new_stko));
+
     SAVE_StkO = new_stko;
+
     return really_reenter_node;
 }
 \end{code}