[project @ 2000-04-14 15:18:05 by sewardj]
[ghc-hetmet.git] / ghc / rts / Storage.h
index fc93e01..a9c6a09 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Storage.h,v 1.7 1999/02/05 16:03:01 simonm Exp $
+ * $Id: Storage.h,v 1.16 2000/04/14 15:18:07 sewardj Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -38,6 +38,9 @@ extern void exitStorage(void);
    lnat  allocated_bytes(void)  Returns the number of bytes allocated
                                 via allocate() since the last GC.
                                Used in the reoprting of statistics.
+
+   SMP: allocate and doYouWantToGC can be used from STG code, they are
+   surrounded by a mutex.
    -------------------------------------------------------------------------- */
 
 extern StgPtr  allocate(nat n);
@@ -56,9 +59,9 @@ extern lnat allocated_bytes(void);
   -------------------------------------------------------------------------- */
 
 #define ExtendNursery(hp,hplim)                        \
-  (current_nursery->free = (P_)(hp)+1,         \
-   current_nursery->link == NULL ? rtsFalse :  \
-   (current_nursery = current_nursery->link,   \
+  (CurrentNursery->free = (P_)(hp)+1,          \
+   CurrentNursery->link == NULL ? rtsFalse :   \
+   (CurrentNursery = CurrentNursery->link,     \
     OpenNursery(hp,hplim),                     \
     rtsTrue))
 
@@ -75,22 +78,24 @@ extern void PleaseStopAllocating(void);
    MarkRoot(StgClosure *p)     Returns the new location of the root.
    -------------------------------------------------------------------------- */
 
-extern void   GarbageCollect(void (*get_roots)(void));
+extern void   GarbageCollect(void (*get_roots)(void),rtsBool force_major_gc);
 extern StgClosure *MarkRoot(StgClosure *p);
 
 /* -----------------------------------------------------------------------------
    Generational garbage collection support
 
-   RecordMutable(StgPtr p)       Informs the garbage collector that a
+   recordMutable(StgPtr p)       Informs the garbage collector that a
                                 previously immutable object has
                                 become (permanently) mutable.  Used
                                 by thawArray and similar.
 
-   UpdateWithIndirection(p1,p2)  Updates the object at p1 with an
+   updateWithIndirection(p1,p2)  Updates the object at p1 with an
                                 indirection pointing to p2.  This is
                                 normally called for objects in an old
                                 generation (>0) when they are updated.
 
+   updateWithPermIndirection(p1,p2)  As above but uses a permanent indir.
+
    -------------------------------------------------------------------------- */
 
 static inline void
@@ -98,7 +103,11 @@ recordMutable(StgMutClosure *p)
 {
   bdescr *bd;
 
+#ifdef SMP
+  ASSERT(p->header.info == &WHITEHOLE_info || closure_MUTABLE(p));
+#else
   ASSERT(closure_MUTABLE(p));
+#endif
 
   bd = Bdescr((P_)p);
   if (bd->gen->no > 0) {
@@ -119,31 +128,73 @@ recordOldToNewPtrs(StgMutClosure *p)
   }
 }
 
+#define updateWithIndirection(info, p1, p2)                            \
+  {                                                                    \
+    bdescr *bd;                                                                \
+                                                                       \
+    bd = Bdescr((P_)p1);                                               \
+    if (bd->gen->no == 0) {                                            \
+      ((StgInd *)p1)->indirectee = p2;                                 \
+      SET_INFO(p1,&IND_info);                                          \
+      TICK_UPD_NEW_IND();                                              \
+    } else {                                                           \
+      ((StgIndOldGen *)p1)->indirectee = p2;                           \
+      if (info != &BLACKHOLE_BQ_info) {                                        \
+        ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list;       \
+        bd->gen->mut_once_list = (StgMutClosure *)p1;                  \
+      }                                                                        \
+      SET_INFO(p1,&IND_OLDGEN_info);                                   \
+      TICK_UPD_OLD_IND();                                              \
+    }                                                                  \
+  }
+
+#if defined(TICKY_TICKY) || defined(PROFILING)
 static inline void
-updateWithIndirection(StgClosure *p1, StgClosure *p2) 
+updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *p2) 
 {
   bdescr *bd;
 
   bd = Bdescr((P_)p1);
   if (bd->gen->no == 0) {
-    SET_INFO(p1,&IND_info);
     ((StgInd *)p1)->indirectee = p2;
-    TICK_UPD_NEW_IND();
+    SET_INFO(p1,&IND_PERM_info);
+    TICK_UPD_NEW_PERM_IND(p1);
   } else {
-    SET_INFO(p1,&IND_OLDGEN_info);
     ((StgIndOldGen *)p1)->indirectee = p2;
-    ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list;
-    bd->gen->mut_once_list = (StgMutClosure *)p1;
-    TICK_UPD_OLD_IND();
+    if (info != &BLACKHOLE_BQ_info) {
+      ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list;
+      bd->gen->mut_once_list = (StgMutClosure *)p1;
+    }
+    SET_INFO(p1,&IND_OLDGEN_PERM_info);
+    TICK_UPD_OLD_PERM_IND();
   }
 }
+#endif
 
 /* -----------------------------------------------------------------------------
-   The CAF list - used to let us revert CAFs
+   The CAF table - used to let us revert CAFs
 
    -------------------------------------------------------------------------- */
 
-extern StgCAF* enteredCAFs;
+#if defined(INTERPRETER)
+typedef struct StgCAFTabEntry_ {
+    StgClosure*   closure;
+    StgInfoTable* origItbl;
+} StgCAFTabEntry;
+
+extern void addToECafTable ( StgClosure* closure, StgInfoTable* origItbl );
+extern void clearECafTable ( void );
+
+extern StgCAF*         ecafList;
+extern StgCAFTabEntry* ecafTable;
+extern StgInt          usedECafTable;
+extern StgInt          sizeECafTable;
+#endif
+
+#if defined(DEBUG)
+void printMutOnceList(generation *gen);
+void printMutableList(generation *gen);
+#endif DEBUG
 
 #endif STORAGE_H