[project @ 2003-04-22 16:25:08 by simonmar]
authorsimonmar <unknown>
Tue, 22 Apr 2003 16:25:12 +0000 (16:25 +0000)
committersimonmar <unknown>
Tue, 22 Apr 2003 16:25:12 +0000 (16:25 +0000)
Fix an obscure bug: the most general kind of heap check,
HEAP_CHECK_GEN(), is supposed to save the contents of *every* register
known to the STG machine (used in cases where we either can't figure
out which ones are live, or doing so would be too much hassle).  The
problem is that it wasn't saving the L1 register.

A slight complication arose in that saving the L1 register pushed the
size of the frame over the 16 words allowed for the size of the bitmap
stored in the frame, so I changed the layout of the frame a bit.
Describing all the registers using a single bitmap is overkill when
only 8 of them can actually be pointers, so now the bitmap is only 8
bits long and we always skip over a fixed number of non-ptr words to
account for all the non-ptr regs.  This is all described in StgMacros.h.

ghc/includes/StgMacros.h
ghc/rts/GC.c
ghc/rts/GCCompact.c
ghc/rts/HeapStackCheck.hc
ghc/rts/Interpreter.c
ghc/rts/Printer.c
ghc/rts/Sanity.c
ghc/rts/Storage.h

index b7e2fc5..faa8e07 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: StgMacros.h,v 1.50 2002/12/11 15:36:39 simonmar Exp $
+ * $Id: StgMacros.h,v 1.51 2003/04/22 16:25:08 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -230,14 +230,18 @@ typedef StgWord StgWordArray[];
 
    The stack frame layout for a RET_DYN is like this:
 
-          some pointers
-          some nonpointers
-          DblReg1-2
-         FltReg1-4
-         R1-8
-         return address
-         liveness mask
-         stg_gen_chk_info
+          some pointers         |-- GET_PTRS(liveness) words
+          some nonpointers      |-- GET_NONPTRS(liveness) words
+                              
+         L1                    \
+          D1-2                  |-- RET_DYN_NONPTR_REGS_SIZE words
+         F1-4                  /
+                              
+         R1-8                  |-- RET_DYN_BITMAP_SIZE words
+                              
+         return address        \
+         liveness mask         |-- StgRetDyn structure
+         stg_gen_chk_info      /
 
    we assume that the size of a double is always 2 pointers (wasting a
    word when it is only one pointer, but avoiding lots of #ifdefs).
@@ -247,8 +251,9 @@ typedef StgWord StgWordArray[];
 // VERY MAGIC CONSTANTS! 
 // must agree with code in HeapStackCheck.c, stg_gen_chk
 //
-#define ALL_NON_PTRS   0xffff
-#define RET_DYN_SIZE   16
+#define RET_DYN_BITMAP_SIZE 8
+#define RET_DYN_NONPTR_REGS_SIZE 10
+#define ALL_NON_PTRS 0xff
 
 #define LIVENESS_MASK(ptr_regs)  (ALL_NON_PTRS ^ (ptr_regs))
 
index 8cd4a2c..1c11938 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.153 2003/04/01 15:05:13 sof Exp $
+ * $Id: GC.c,v 1.154 2003/04/22 16:25:09 simonmar Exp $
  *
  * (c) The GHC Team 1998-2003
  *
@@ -3689,11 +3689,11 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
        // traverse the bitmap first
        bitmap = GET_LIVENESS(dyn);
        p      = (P_)&((StgRetDyn *)p)->payload[0];
-       size   = RET_DYN_SIZE;
+       size   = RET_DYN_BITMAP_SIZE;
        p = scavenge_small_bitmap(p, size, bitmap);
 
        // skip over the non-ptr words
-       p += GET_NONPTRS(dyn);
+       p += GET_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
        
        // follow the ptr words
        for (size = GET_PTRS(dyn); size > 0; size--) {
index 65e0335..4a28bd2 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GCCompact.c,v 1.15 2003/03/24 16:18:26 simonmar Exp $
+ * $Id: GCCompact.c,v 1.16 2003/04/22 16:25:10 simonmar Exp $
  *
  * (c) The GHC Team 2001
  *
@@ -270,7 +270,7 @@ thread_stack(StgPtr p, StgPtr stack_end)
            // traverse the bitmap first
            bitmap = GET_LIVENESS(dyn);
            p      = (P_)&((StgRetDyn *)p)->payload[0];
-           size   = RET_DYN_SIZE;
+           size   = RET_DYN_BITMAP_SIZE;
            while (size > 0) {
                if ((bitmap & 1) == 0) {
                    thread(p);
@@ -281,7 +281,7 @@ thread_stack(StgPtr p, StgPtr stack_end)
            }
            
            // skip over the non-ptr words
-           p += GET_NONPTRS(dyn);
+           p += GET_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
            
            // follow the ptr words
            for (size = GET_PTRS(dyn); size > 0; size--) {
index 2ab2023..a3aa5bf 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: HeapStackCheck.hc,v 1.29 2003/03/19 18:56:14 sof Exp $
+ * $Id: HeapStackCheck.hc,v 1.30 2003/04/22 16:25:10 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2002
  *
@@ -810,6 +810,7 @@ EXTFUN(stg_gc_fun_ret)
 // it's not a big deal.
 
 #define RESTORE_EVERYTHING                     \
+    L1   = PK_Word64(Sp+19);                   \
     D2   = PK_DBL(Sp+17);                      \
     D1   = PK_DBL(Sp+15);                      \
     F4   = PK_FLT(Sp+14);                      \
@@ -824,12 +825,13 @@ EXTFUN(stg_gc_fun_ret)
     R3.w = Sp[5];                              \
     R2.w = Sp[4];                              \
     R1.w = Sp[3];                              \
-    Sp += 19;
+    Sp += 21;
 
-#define RET_OFFSET (-17)
+#define RET_OFFSET (-19)
 
 #define SAVE_EVERYTHING                                \
-    Sp -= 19;                                  \
+    Sp -= 21;                                  \
+    ASSIGN_Word64(Sp+19,L1);                   \
     ASSIGN_DBL(Sp+17,D2);                      \
     ASSIGN_DBL(Sp+15,D1);                      \
     ASSIGN_FLT(Sp+14,F4);                      \
index 63719ad..96ba3b8 100644 (file)
@@ -1157,6 +1157,9 @@ run_BCO:
            int stk_offset            = BCO_NEXT;
            int o_itbl                = BCO_NEXT;
            void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl);
+           int ret_dyn_size = 
+               RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE
+               + sizeofW(StgRetDyn);
 
 #ifdef RTS_SUPPORTS_THREADS
            // Threaded RTS:
@@ -1168,7 +1171,7 @@ run_BCO:
            
            memcpy(arguments, Sp, sizeof(W_) * stk_offset);
 #endif
-               
+
            // There are a bunch of non-ptr words on the stack (the
            // ccall args, the ccall fun address and space for the
            // result), which we need to cover with an info table
@@ -1179,7 +1182,7 @@ run_BCO:
            // CCALL instruction.   So we build a RET_DYN stack frame
            // on the stack frame to describe this chunk of stack.
            //
-           Sp -= RET_DYN_SIZE + sizeofW(StgRetDyn);
+           Sp -= ret_dyn_size;
            ((StgRetDyn *)Sp)->liveness = ALL_NON_PTRS | N_NONPTRS(stk_offset);
            ((StgRetDyn *)Sp)->info = (StgInfoTable *)&stg_gc_gen_info;
 
@@ -1192,7 +1195,7 @@ run_BCO:
            // around (stack squeezing), so we have to grab the real
            // Sp out of the TSO to find the ccall args again.
 
-           marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + RET_DYN_SIZE + sizeofW(StgRetDyn)) );
+           marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + ret_dyn_size) );
 #else
            // Threaded RTS:
            // We already made a malloced copy of the arguments above.
@@ -1203,8 +1206,7 @@ run_BCO:
            // And restart the thread again, popping the RET_DYN frame.
            cap = (Capability *)((void *)resumeThread(tok,rtsFalse) - sizeof(StgFunTable));
            LOAD_STACK_POINTERS;
-           Sp += RET_DYN_SIZE + sizeofW(StgRetDyn);
-
+           Sp += ret_dyn_size;
            
 #ifdef RTS_SUPPORTS_THREADS
            // Threaded RTS:
index 5766777..38ade81 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Printer.c,v 1.58 2003/04/01 17:09:40 sof Exp $
+ * $Id: Printer.c,v 1.59 2003/04/22 16:25:12 simonmar Exp $
  *
  * (c) The GHC Team, 1994-2000.
  *
@@ -558,8 +558,8 @@ printStackChunk( StgPtr sp, StgPtr spBottom )
 
            p = (P_)(r->payload);
            printSmallBitmap(spBottom, sp,
-                            GET_LIVENESS(r->liveness), RET_DYN_SIZE);
-           p += RET_DYN_SIZE;
+                            GET_LIVENESS(r->liveness), RET_DYN_BITMAP_SIZE);
+           p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;
 
            for (size = GET_NONPTRS(dyn); size > 0; size--) {
                fprintf(stderr,"   stk[%ld] (%p) = ", (long)(spBottom-p), p);
index 6a5ab22..383ef64 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Sanity.c,v 1.32 2003/03/24 14:46:56 simonmar Exp $
+ * $Id: Sanity.c,v 1.33 2003/04/22 16:25:12 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2001
  *
@@ -113,8 +113,8 @@ checkStackFrame( StgPtr c )
        dyn = r->liveness;
        
        p = (P_)(r->payload);
-       checkSmallBitmap(p,GET_LIVENESS(r->liveness),RET_DYN_SIZE);
-       p += RET_DYN_SIZE;
+       checkSmallBitmap(p,GET_LIVENESS(r->liveness),RET_DYN_BITMAP_SIZE);
+       p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;
 
        // skip over the non-pointers
        p += GET_NONPTRS(dyn);
@@ -125,7 +125,8 @@ checkStackFrame( StgPtr c )
            p++;
        }
        
-       return sizeofW(StgRetDyn) + RET_DYN_SIZE + 
+       return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE +
+           RET_DYN_NONPTR_REGS_SIZE +
            GET_NONPTRS(dyn) + GET_PTRS(dyn);
     }
 
index 79fee9d..c938fd8 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Storage.h,v 1.51 2003/03/27 13:54:32 simonmar Exp $
+ * $Id: Storage.h,v 1.52 2003/04/22 16:25:12 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2002
  *
@@ -419,7 +419,8 @@ static inline StgWord stack_frame_sizeW( StgClosure *frame )
     case RET_DYN:
     {
        StgRetDyn *dyn = (StgRetDyn *)frame;
-       return  sizeofW(StgRetDyn) + RET_DYN_SIZE + 
+       return  sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE + 
+           RET_DYN_NONPTR_REGS_SIZE +
            GET_PTRS(dyn->liveness) + GET_NONPTRS(dyn->liveness);
     }