[project @ 2001-03-23 16:36:20 by simonmar]
[ghc-hetmet.git] / ghc / rts / HeapStackCheck.hc
index 2861372..8d0c46a 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: HeapStackCheck.hc,v 1.5 1999/03/17 13:19:21 simonm Exp $
+ * $Id: HeapStackCheck.hc,v 1.16 2001/03/23 16:36:21 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -7,6 +7,7 @@
  *
  * ---------------------------------------------------------------------------*/
 
+#include "Stg.h"
 #include "Rts.h"
 #include "Storage.h"           /* for CurrentTSO */
 #include "StgRun.h"    /* for StgReturn and register saving */
@@ -20,7 +21,7 @@
  *
  *    - If the context_switch flag is set, indicating that there are more
  *      threads waiting to run, we yield to the scheduler 
- *     (return ThreadYeilding).
+ *     (return ThreadYielding).
  *
  *    - If Hp > HpLim, we've had a heap check failure.  This means we've
  *     come to the end of the current heap block, so we try to chain
@@ -64,7 +65,7 @@
     R1.i = StackOverflow;                              \
   }                                                    \
   SaveThreadState();                                   \
-  CurrentTSO->whatNext = ThreadRunGHC;                 \
+  CurrentTSO->what_next = ThreadRunGHC;                        \
   JMP_(StgReturn);
 
 #define GC_ENTER                                       \
     R1.i = StackOverflow;                              \
   }                                                    \
   SaveThreadState();                                   \
-  CurrentTSO->whatNext = ThreadEnterGHC;               \
+  CurrentTSO->what_next = ThreadEnterGHC;              \
   JMP_(StgReturn);
 
 #define HP_GENERIC                     \
   SaveThreadState();                   \
-  CurrentTSO->whatNext = ThreadRunGHC; \
+  CurrentTSO->what_next = ThreadRunGHC;        \
   R1.i = HeapOverflow;                 \
   JMP_(StgReturn);
 
 #define STK_GENERIC                    \
   SaveThreadState();                   \
-  CurrentTSO->whatNext = ThreadRunGHC; \
+  CurrentTSO->what_next = ThreadRunGHC;        \
   R1.i = StackOverflow;                        \
   JMP_(StgReturn);
 
 #define YIELD_GENERIC                  \
   SaveThreadState();                   \
-  CurrentTSO->whatNext = ThreadRunGHC; \
+  CurrentTSO->what_next = ThreadRunGHC;        \
   R1.i = ThreadYielding;               \
   JMP_(StgReturn);
 
-#define YIELD_TO_HUGS                    \
+#define YIELD_TO_INTERPRETER             \
   SaveThreadState();                     \
-  CurrentTSO->whatNext = ThreadEnterHugs; \
+  CurrentTSO->what_next = ThreadEnterInterp; \
   R1.i = ThreadYielding;                 \
   JMP_(StgReturn);
 
 #define BLOCK_GENERIC                  \
   SaveThreadState();                   \
-  CurrentTSO->whatNext = ThreadRunGHC; \
+  CurrentTSO->what_next = ThreadRunGHC;        \
   R1.i = ThreadBlocked;                        \
   JMP_(StgReturn);
 
 #define BLOCK_ENTER                    \
   SaveThreadState();                   \
-  CurrentTSO->whatNext = ThreadEnterGHC;\
+  CurrentTSO->what_next = ThreadEnterGHC;\
   R1.i = ThreadBlocked;                        \
   JMP_(StgReturn);
 
+
 /* -----------------------------------------------------------------------------
    Heap Checks
    -------------------------------------------------------------------------- */
@@ -159,6 +161,18 @@ EXTFUN(stg_gc_enter_1)
   FE_
 }
 
+EXTFUN(stg_gc_enter_1_hponly)
+{
+  FB_
+  Sp -= 1;
+  Sp[0] = R1.w;
+  R1.i = HeapOverflow;
+  SaveThreadState();
+  CurrentTSO->what_next = ThreadEnterGHC;
+  JMP_(StgReturn);
+  FE_
+}
+
 /*- 2 Regs--------------------------------------------------------------------*/
 
 EXTFUN(stg_gc_enter_2)
@@ -264,6 +278,334 @@ EXTFUN(stg_gc_enter_8)
   FE_
 }
 
+#if defined(GRAN)
+/*
+  ToDo: merge the block and yield macros, calling something like BLOCK(N)
+        at the end;
+*/
+
+/* 
+   Should we actually ever do a yield in such a case?? -- HWL
+*/
+EXTFUN(gran_yield_0)
+{
+  FB_
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+EXTFUN(gran_yield_1)
+{
+  FB_
+  Sp -= 1;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 2 Regs--------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_2)
+{
+  FB_
+  Sp -= 2;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 3 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_3)
+{
+  FB_
+  Sp -= 3;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 4 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_4)
+{
+  FB_
+  Sp -= 4;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 5 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_5)
+{
+  FB_
+  Sp -= 5;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 6 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_6)
+{
+  FB_
+  Sp -= 6;
+  Sp[5] = R6.w;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 7 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_7)
+{
+  FB_
+  Sp -= 7;
+  Sp[6] = R7.w;
+  Sp[5] = R6.w;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 8 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_yield_8)
+{
+  FB_
+  Sp -= 8;
+  Sp[7] = R8.w;
+  Sp[6] = R7.w;
+  Sp[5] = R6.w;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadYielding;
+  JMP_(StgReturn);
+  FE_
+}
+
+// the same routines but with a block rather than a yield
+
+EXTFUN(gran_block_1)
+{
+  FB_
+  Sp -= 1;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 2 Regs--------------------------------------------------------------------*/
+
+EXTFUN(gran_block_2)
+{
+  FB_
+  Sp -= 2;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 3 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_block_3)
+{
+  FB_
+  Sp -= 3;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 4 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_block_4)
+{
+  FB_
+  Sp -= 4;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 5 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_block_5)
+{
+  FB_
+  Sp -= 5;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 6 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_block_6)
+{
+  FB_
+  Sp -= 6;
+  Sp[5] = R6.w;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 7 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_block_7)
+{
+  FB_
+  Sp -= 7;
+  Sp[6] = R7.w;
+  Sp[5] = R6.w;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+/*- 8 Regs -------------------------------------------------------------------*/
+
+EXTFUN(gran_block_8)
+{
+  FB_
+  Sp -= 8;
+  Sp[7] = R8.w;
+  Sp[6] = R7.w;
+  Sp[5] = R6.w;
+  Sp[4] = R5.w;
+  Sp[3] = R4.w;
+  Sp[2] = R3.w;
+  Sp[1] = R2.w;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+#endif
+
+#if 0 && defined(PAR)
+
+/*
+  Similar to stg_block_1 (called via StgMacro BLOCK_NP) but separates the
+  saving of the thread state from the actual jump via an StgReturn.
+  We need this separation because we call RTS routines in blocking entry codes
+  before jumping back into the RTS (see parallel/FetchMe.hc).
+*/
+
+EXTFUN(par_block_1_no_jump)
+{
+  FB_
+  Sp -= 1;
+  Sp[0] = R1.w;
+  SaveThreadState();                                   
+  FE_
+}
+
+EXTFUN(par_jump)
+{
+  FB_
+  CurrentTSO->what_next = ThreadEnterGHC;              
+  R1.i = ThreadBlocked;
+  JMP_(StgReturn);
+  FE_
+}
+
+#endif
+
 /* -----------------------------------------------------------------------------
    For a case expression on a polymorphic or function-typed object, if
    the default branch (there can only be one branch) of the case fails
@@ -293,11 +635,28 @@ EXTFUN(stg_gc_seq_1)
    cases are covered below.
    -------------------------------------------------------------------------- */
 
-/*-- No regsiters live, return address already on the stack: ---------------- */
+/*-- No regsiters live (probably a void return) ----------------------------- */
+
+/* If we change the policy for thread startup to *not* remove the
+ * return address from the stack, we can get rid of this little
+ * function/info table...  
+ */
+INFO_TABLE_SRT_BITMAP(stg_gc_noregs_ret_info, stg_gc_noregs_ret, 0/*BITMAP*/, 
+                     0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+                     RET_SMALL,, EF_, 0, 0);
+
+EXTFUN(stg_gc_noregs_ret)
+{
+  FB_
+  JMP_(ENTRY_CODE(Sp[0]));
+  FE_
+}
 
 EXTFUN(stg_gc_noregs)
 {
   FB_
+  Sp -= 1;
+  Sp[0] = (W_)&stg_gc_noregs_ret_info;
   GC_GENERIC
   FE_
 }
@@ -306,7 +665,7 @@ EXTFUN(stg_gc_noregs)
 
 INFO_TABLE_SRT_BITMAP(stg_gc_unpt_r1_info, stg_gc_unpt_r1_entry, 0/*BITMAP*/, 
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
+                     RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_unpt_r1_entry)
 {
@@ -331,7 +690,7 @@ EXTFUN(stg_gc_unpt_r1)
 
 INFO_TABLE_SRT_BITMAP(stg_gc_unbx_r1_info, stg_gc_unbx_r1_entry, 1/*BITMAP*/,
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
+                     RET_SMALL,, EF_, 0, 0);
 /* the 1 is a bitmap - i.e. 1 non-pointer word on the stack. */
 
 EXTFUN(stg_gc_unbx_r1_entry)
@@ -357,7 +716,7 @@ EXTFUN(stg_gc_unbx_r1)
 
 INFO_TABLE_SRT_BITMAP(stg_gc_f1_info, stg_gc_f1_entry, 1/*BITMAP*/,
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
+                     RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_f1_entry)
 {
@@ -390,7 +749,7 @@ EXTFUN(stg_gc_f1)
 
 INFO_TABLE_SRT_BITMAP(stg_gc_d1_info, stg_gc_d1_entry, DBL_BITMAP,
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
+                     RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_d1_entry)
 {
@@ -443,14 +802,14 @@ EXTFUN(stg_gc_d1)
 
 INFO_TABLE_SRT_BITMAP(stg_gc_ut_1_0_info, stg_gc_ut_1_0_entry, 1/*BITMAP*/, 
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
+                     RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_ut_1_0_entry)
 {
   FB_
   R1.w = Sp[1];
   Sp += 2;
-  JMP_(Sp[-2]);
+  JMP_(ENTRY_CODE(Sp[-2]));
   FE_
 }
 
@@ -469,14 +828,14 @@ EXTFUN(stg_gc_ut_1_0)
 
 INFO_TABLE_SRT_BITMAP(stg_gc_ut_0_1_info, stg_gc_ut_0_1_entry, 3/*BITMAP*/, 
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
+                     RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_ut_0_1_entry)
 {
   FB_
   R1.w = Sp[1];
   Sp += 2;
-  JMP_(Sp[-2]);
+  JMP_(ENTRY_CODE(Sp[-2]));
   FE_
 }
 
@@ -764,7 +1123,7 @@ EXTFUN(stg_chk_8)
 
 INFO_TABLE_SRT_BITMAP(stg_gen_chk_info, stg_gen_chk_ret, 0,
                      0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_DYN, const, EF_, 0, 0);
+                     RET_DYN,, EF_, 0, 0);
 
 /* bitmap in the above info table is unused, the real one is on the stack. 
  */
@@ -773,7 +1132,7 @@ FN_(stg_gen_chk_ret)
 {
   FB_
   RESTORE_EVERYTHING;
-  JMP_(Sp[RET_OFFSET]);
+  JMP_(Sp[RET_OFFSET]); /* NO ENTRY_CODE() - this is a direct ret address */
   FE_
 }
 
@@ -810,31 +1169,20 @@ FN_(stg_gen_yield)
   FE_
 }
 
-INFO_TABLE_SRT_BITMAP(stg_yield_noregs_info, stg_yield_noregs_ret, 0/*BITMAP*/, 
-                     0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
-                     RET_SMALL, const, EF_, 0, 0);
-
-FN_(stg_yield_noregs_ret)
-{
-  FB_
-  JMP_(ENTRY_CODE(Sp[0]))
-  FE_
-}
-
 FN_(stg_yield_noregs)
 {
   FB_
   Sp--;
-  Sp[0] = (W_)&stg_yield_noregs_info;
+  Sp[0] = (W_)&stg_gc_noregs_ret_info;
   YIELD_GENERIC;
   FE_
 }
 
-FN_(stg_yield_to_Hugs)
+FN_(stg_yield_to_interpreter)
 {
   FB_
   /* No need to save everything - no live registers */
-  YIELD_TO_HUGS
+  YIELD_TO_INTERPRETER
   FE_
 }
 
@@ -850,6 +1198,15 @@ FN_(stg_gen_block)
   FE_
 }
 
+FN_(stg_block_noregs)
+{
+  FB_
+  Sp--;
+  Sp[0] = (W_)&stg_gc_noregs_ret_info;
+  BLOCK_GENERIC;
+  FE_
+}
+
 FN_(stg_block_1)
 {
   FB_