[project @ 2003-01-25 15:54:48 by wolfgang]
[ghc-hetmet.git] / ghc / includes / Closures.h
index 497fc82..981b84b 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: Closures.h,v 1.23 2000/12/19 12:34:00 sewardj Exp $
+ * $Id: Closures.h,v 1.32 2002/12/11 15:36:37 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
    The profiling header
    -------------------------------------------------------------------------- */
 
-#ifdef PROFILING
-
 typedef struct {
-   CostCentreStack *ccs;
+  CostCentreStack *ccs;
+  union {
+    struct _RetainerSet *rs;  // Retainer Set
+    StgWord ldvw;             // Lag/Drag/Void Word
+  } hp;
 } StgProfHeader;
 
-#else /* !PROFILING */
-
-typedef struct {
-       /* empty */
-} StgProfHeader;
-
-#endif /* PROFILING */
-
-/* -----------------------------------------------------------------------------
-   The parallel header
-   -------------------------------------------------------------------------- */
-
-#ifdef PAR
-
-typedef struct {
-  /* StgWord ga; */  /* nope! global addresses are managed via a hash table */
-} StgParHeader;
-
-#else /* !PAR */
-
-typedef struct {
-  /* empty */
-} StgParHeader;
-
-#endif /* PAR */
-
 /* -----------------------------------------------------------------------------
    The GranSim header
    -------------------------------------------------------------------------- */
 
-#if defined(GRAN)
-
 typedef struct {
   StgWord procs; /* bitmask indicating on which PEs this closure resides */
 } StgGranHeader;
 
-#else /* !GRAN */
-
-typedef struct {
-  /* empty */
-} StgGranHeader;
-
-#endif /* GRAN */
-
-/* -----------------------------------------------------------------------------
-   The ticky-ticky header
-
-   Comment from old Ticky.h:
-
-   This is used to record if a closure has been updated but not yet
-   entered. It is set when the closure is updated and cleared when
-   subsequently entered.
-   
-   NB: It is {\em not} an ``entry count'', it is an
-   ``entries-after-update count.''
-   
-   The commoning up of @CONST@, @CHARLIKE@ and @INTLIKE@ closures is
-   turned off(?) if this is required. This has only been done for 2s
-   collection.  It is done using a nasty hack which defines the
-   @_Evacuate@ and @_Scavenge@ code for @CONST@, @CHARLIKE@ and @INTLIKE@
-   info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
-   -------------------------------------------------------------------------- */
-
-#ifdef TICKY_TICKY
-
-typedef struct {
-  /* old: W_ updated; */
-} StgTickyHeader;
-
-#else /* !TICKY_TICKY */
-
-typedef struct {
-       /* empty */
-} StgTickyHeader;
-
-#endif /* TICKY_TICKY */
-
 /* -----------------------------------------------------------------------------
    The full fixed-size closure header
 
@@ -114,15 +47,9 @@ typedef struct {
 #ifdef PROFILING
        StgProfHeader         prof;
 #endif
-#ifdef PAR
-       StgParHeader          par;
-#endif
 #ifdef GRAN
        StgGranHeader         gran;
 #endif
-#ifdef TICKY_TICKY
-       StgTickyHeader        ticky;
-#endif
 } StgHeader;
 
 #define FIXED_HS (sizeof(StgHeader))
@@ -139,7 +66,7 @@ typedef struct {
 
 struct StgClosure_ {
     StgHeader   header;
-    struct StgClosure_ *payload[0];
+    struct StgClosure_ *payload[FLEXIBLE_ARRAY];
 };
 
 /* What a stroke of luck - all our mutable closures follow the same
@@ -152,7 +79,7 @@ typedef struct StgMutClosure_ {
     StgHeader   header;
     StgWord     padding;
     struct StgMutClosure_ *mut_link;
-    struct StgClosure_ *payload[0];
+    struct StgClosure_ *payload[FLEXIBLE_ARRAY];
 } StgMutClosure;
 
 typedef struct {
@@ -162,25 +89,21 @@ typedef struct {
 
 typedef struct {
     StgHeader   header;
-    StgWord     n_args;
-    StgClosure *fun;
-    StgClosure *payload[0];
+    StgHalfWord arity;         /* zero if it is an AP */
+    StgHalfWord n_args;
+    StgClosure *fun;           /* really points to a fun */
+    StgClosure *payload[FLEXIBLE_ARRAY];
 } StgPAP;
 
-typedef struct {
-    StgHeader   header;
-    StgWord     n_args;
-    StgClosure *fun;
-    StgClosure *payload[0];
-} StgAP_UPD;
+// AP closures have the same layout, for convenience
+typedef StgPAP StgAP;
 
 typedef struct {
     StgHeader   header;
-    StgClosure *instrs;                /* a pointer to an ArrWords */
-    StgClosure *literals;      /* a pointer to an ArrWords */
-    StgClosure *ptrs;          /* a pointer to a MutArrPtrs */
-    StgClosure *itbls;         /* a pointer to an ArrWords */
-} StgBCO;
+    StgWord     size;                    // number of words in payload
+    StgClosure *fun;
+    StgClosure *payload[FLEXIBLE_ARRAY]; // contains a chunk of *stack*
+} StgAP_STACK;
 
 typedef struct {
     StgHeader   header;
@@ -194,30 +117,23 @@ typedef struct {
 } StgIndOldGen;
 
 typedef struct {
-    StgHeader   header;
-    StgClosure *indirectee;
-    StgClosure *static_link;
-} StgIndStatic;
-
-typedef struct StgCAF_ {
     StgHeader     header;
-    StgClosure    *body;
-    StgMutClosure *mut_link;
-    StgClosure    *value;
-    struct StgCAF_ *link;
-} StgCAF;
+    StgClosure   *indirectee;
+    StgClosure   *static_link;
+    struct _StgInfoTable *saved_info;
+} StgIndStatic;
 
 typedef struct {
     StgHeader  header;
     StgWord    words;
-    StgWord    payload[0];
+    StgWord    payload[FLEXIBLE_ARRAY];
 } StgArrWords;
 
 typedef struct {
     StgHeader   header;
     StgWord     ptrs;
     StgMutClosure *mut_link;   /* mutable list */
-    StgClosure *payload[0];
+    StgClosure *payload[FLEXIBLE_ARRAY];
 } StgMutArrPtrs;
 
 typedef struct {
@@ -226,29 +142,13 @@ typedef struct {
     StgMutClosure *mut_link;
 } StgMutVar;
 
-/* 
-   A collective typedef for all linkable stack frames i.e.
-     StgUpdateFrame, StgSeqFrame, StgCatchFrame
-*/
-typedef struct _StgFrame {
-    StgHeader  header;
-    struct _StgFrame *link;
-} StgFrame;
-
 typedef struct _StgUpdateFrame {
     StgHeader  header;
-    struct _StgUpdateFrame *link;
     StgClosure *updatee;
 } StgUpdateFrame;
 
 typedef struct {
     StgHeader  header;
-    struct _StgUpdateFrame *link;
-} StgSeqFrame;  
-
-typedef struct {
-    StgHeader  header;
-    struct _StgUpdateFrame *link;
     StgInt      exceptions_blocked;
     StgClosure *handler;
 } StgCatchFrame;
@@ -295,18 +195,68 @@ typedef struct _StgDeadWeak {     /* Weak v */
   struct _StgWeak *link;
 } StgDeadWeak;
 
+/* Byte code objects.  These are fixed size objects with pointers to
+ * four arrays, designed so that a BCO can be easily "re-linked" to
+ * other BCOs, to facilitate GHC's intelligent recompilation.  The
+ * array of instructions is static and not re-generated when the BCO
+ * is re-linked, but the other 3 arrays will be regenerated.
+ *
+ * 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.
+ */
+
+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 */
+} 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_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.
+ * check code.  See StgMacros.h, HEAP_CHK_GEN().
  */
  
 typedef struct {
-  const struct _StgInfoTable* info;
-  StgWord        liveness;
-  StgWord        ret_addr;
-  StgWord        payload[0];
+    const struct _StgInfoTable* info;
+    StgWord        liveness;
+    StgWord        ret_addr;
+    StgClosure *   payload[FLEXIBLE_ARRAY];
 } StgRetDyn;
 
+/* A function return stack frame: used when saving the state for a
+ * garbage collection at a function entry point.  The function
+ * arguments are on the stack, and we also save the function (its
+ * info table describes the pointerhood of the arguments).
+ *
+ * The stack frame size is also cached in the frame for convenience.
+ */
+typedef struct {
+    const struct _StgInfoTable* info;
+    StgWord        size;
+    StgClosure *   fun;
+    StgClosure *   payload[FLEXIBLE_ARRAY];
+} StgRetFun;
+
 /* Concurrent communication objects */
 
 typedef struct {
@@ -333,7 +283,7 @@ typedef struct StgBlockingQueueElement_ {
   StgHeader                         header;
   struct StgBlockingQueueElement_  *link;      /* next elem in BQ */
   StgMutClosure                    *mut_link;  /* next elem in mutable list */
-  struct StgClosure_               *payload[0];/* contents of the closure */
+  struct StgClosure_               *payload[FLEXIBLE_ARRAY];/* contents of the closure */
 } StgBlockingQueueElement;
 
 /* only difference to std code is type of the elem in the BQ */
@@ -346,7 +296,7 @@ typedef struct StgBlockingQueue_ {
 /* this closure is hanging at the end of a blocking queue in (see RBH.c) */
 typedef struct StgRBHSave_ {
   StgHeader    header;
-  StgClosure  *payload[0];     /* 2 words ripped out of the guts of the */
+  StgClosure  *payload[FLEXIBLE_ARRAY];     /* 2 words ripped out of the guts of the */
 } StgRBHSave;                  /*  closure holding the blocking queue */
  
 typedef struct StgRBH_ {