[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / includes / Closures.h
index 981b84b..d546792 100644 (file)
@@ -1,7 +1,6 @@
 /* ----------------------------------------------------------------------------
- * $Id: Closures.h,v 1.32 2002/12/11 15:36:37 simonmar Exp $
  *
- * (c) The GHC Team, 1998-1999
+ * (c) The GHC Team, 1998-2004
  *
  * Closures
  *
@@ -52,8 +51,6 @@ typedef struct {
 #endif
 } StgHeader;
 
-#define FIXED_HS (sizeof(StgHeader))
-
 /* -----------------------------------------------------------------------------
    Closure Types
 
@@ -204,38 +201,82 @@ typedef struct _StgDeadWeak {     /* Weak v */
  * A BCO represents either a function or a stack frame.  In each case,
  * it needs a bitmap to describe to the garbage collector the
  * pointerhood of its arguments/free variables respectively, and in
- * the case of a function it also needs an arity.  These pieces of
- * information are stored at the beginning of the instruction array.
+ * the case of a function it also needs an arity.  These are stored
+ * directly in the BCO, rather than in the instrs array, for two
+ * reasons:
+ * (a) speed: we need to get at the bitmap info quickly when
+ *     the GC is examining APs and PAPs that point to this BCO
+ * (b) a subtle interaction with the compacting GC.  In compacting
+ *     GC, the info that describes the size/layout of a closure
+ *     cannot be in an object more than one level of indirection
+ *     away from the current object, because of the order in
+ *     which pointers are updated to point to their new locations.
  */
 
 typedef struct {
     StgHeader      header;
-    StgArrWords   *instrs;     /* a pointer to an ArrWords */
-    StgArrWords   *literals;   /* a pointer to an ArrWords */
-    StgMutArrPtrs *ptrs;       /* a pointer to a MutArrPtrs */
-    StgArrWords   *itbls;      /* a pointer to an ArrWords */
+    StgArrWords   *instrs;     // a pointer to an ArrWords
+    StgArrWords   *literals;   // a pointer to an ArrWords
+    StgMutArrPtrs *ptrs;       // a pointer to a  MutArrPtrs
+    StgArrWords   *itbls;      // a pointer to an ArrWords
+    StgHalfWord   arity;        // arity of this BCO
+    StgHalfWord   size;         // size of this BCO (in words)
+    StgWord       bitmap[FLEXIBLE_ARRAY];  // an StgLargeBitmap
 } StgBCO;
 
-typedef struct {
-    StgWord arity;
-    StgWord bitmap[FLEXIBLE_ARRAY];  // really an StgLargeBitmap
-} StgBCOInfo;
-
-#define BCO_INFO(bco)  ((StgBCOInfo *)(((StgBCO *)(bco))->instrs->payload))
-#define BCO_ARITY(bco) (BCO_INFO(bco)->arity)
-#define BCO_BITMAP(bco) ((StgLargeBitmap *)BCO_INFO(bco)->bitmap)
+#define BCO_BITMAP(bco)      ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
 #define BCO_BITMAP_SIZE(bco) (BCO_BITMAP(bco)->size)
 #define BCO_BITMAP_BITS(bco) (BCO_BITMAP(bco)->bitmap)
 #define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
                                / BITS_IN(StgWord))
-#define BCO_INSTRS(bco) ((StgWord16 *)(BCO_BITMAP_BITS(bco) + \
-                                       BCO_BITMAP_SIZEW(bco)))
 
-/* Dynamic stack frames - these have a liveness mask in the object
- * itself, rather than in the info table.  Useful for generic heap
- * check code.  See StgMacros.h, HEAP_CHK_GEN().
- */
+/* -----------------------------------------------------------------------------
+   Dynamic stack frames for generic heap checks.
+
+   These generic heap checks are slow, but have the advantage of being
+   usable in a variety of situations.
+
+   The one restriction is that any relevant SRTs must already be pointed
+   to from the stack.  The return address doesn't need to have an info
+   table attached: hence it can be any old code pointer.
+
+   The liveness mask contains a 1 at bit n, if register Rn contains a
+   non-pointer.  The contents of all 8 vanilla registers are always saved
+   on the stack; the liveness mask tells the GC which ones contain
+   pointers.
+
+   Good places to use a generic heap check: 
+
+        - case alternatives (the return address with an SRT is already
+         on the stack).
+
+       - primitives (no SRT required).
+
+   The stack frame layout for a RET_DYN is like this:
+
+          some pointers         |-- RET_DYN_PTRS(liveness) words
+          some nonpointers      |-- RET_DYN_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).
+
+   See Liveness.h for the macros (RET_DYN_PTRS() etc.).
+
+   NOTE: if you change the layout of RET_DYN stack frames, then you
+   might also need to adjust the value of RESERVED_STACK_WORDS in
+   Constants.h.
+   -------------------------------------------------------------------------- */
+
 typedef struct {
     const struct _StgInfoTable* info;
     StgWord        liveness;