A sanity check
[ghc-hetmet.git] / rts / sm / Storage.c
index d9c7f86..d7e5b67 100644 (file)
@@ -49,8 +49,6 @@ generation *generations = NULL;       /* all the generations */
 generation *g0         = NULL; /* generation 0, for convenience */
 generation *oldest_gen  = NULL; /* oldest generation, for convenience */
 
-ullong total_allocated = 0;    /* total memory allocated during run */
-
 nursery *nurseries = NULL;     /* array of nurseries, size == n_capabilities */
 
 #ifdef THREADED_RTS
@@ -79,6 +77,7 @@ initGeneration (generation *gen, int g)
     gen->n_old_blocks = 0;
     gen->large_objects = NULL;
     gen->n_large_blocks = 0;
+    gen->n_new_large_blocks = 0;
     gen->mut_list = allocBlock();
     gen->scavenged_large_objects = NULL;
     gen->n_scavenged_large_blocks = 0;
@@ -95,7 +94,7 @@ initGeneration (generation *gen, int g)
 void
 initStorage( void )
 {
-  nat g;
+    nat g, n;
 
   if (generations != NULL) {
       // multi-init protection
@@ -193,6 +192,13 @@ initStorage( void )
 
   N = 0;
 
+  // allocate a block for each mut list
+  for (n = 0; n < n_capabilities; n++) {
+      for (g = 1; g < RtsFlags.GcFlags.generations; g++) {
+          capabilities[n].mut_lists[g] = allocBlock();
+      }
+  }
+
   initGcThreads();
 
   IF_DEBUG(gc, statDescribeGens());
@@ -235,8 +241,8 @@ freeStorage (void)
 
    newCaf() does the following:
        
-      - it puts the CAF on the oldest generation's mut-once list.
-        This is so that we can treat the CAF as a root when collecting
+      - it puts the CAF on the oldest generation's mutable list.
+        This is so that we treat the CAF as a root when collecting
        younger generations.
 
    For GHCI, we have additional requirements when dealing with CAFs:
@@ -260,10 +266,8 @@ freeStorage (void)
    -------------------------------------------------------------------------- */
 
 void
-newCAF(StgClosure* caf)
+newCAF(StgRegTable *reg, StgClosure* caf)
 {
-  ACQUIRE_SM_LOCK;
-
 #ifdef DYNAMIC
   if(keepCAFs)
   {
@@ -278,24 +282,19 @@ newCAF(StgClosure* caf)
     // do another hack here and do an address range test on caf to figure
     // out whether it is from a dynamic library.
     ((StgIndStatic *)caf)->saved_info  = (StgInfoTable *)caf->header.info;
+
+    ACQUIRE_SM_LOCK; // caf_list is global, locked by sm_mutex
     ((StgIndStatic *)caf)->static_link = caf_list;
     caf_list = caf;
+    RELEASE_SM_LOCK;
   }
   else
 #endif
   {
-    /* Put this CAF on the mutable list for the old generation.
-    * This is a HACK - the IND_STATIC closure doesn't really have
-    * a mut_link field, but we pretend it has - in fact we re-use
-    * the STATIC_LINK field for the time being, because when we
-    * come to do a major GC we won't need the mut_link field
-    * any more and can use it as a STATIC_LINK.
-    */
+    // Put this CAF on the mutable list for the old generation.
     ((StgIndStatic *)caf)->saved_info = NULL;
-    recordMutableGen(caf, oldest_gen->no);
+    recordMutableCap(caf, regTableToCapability(reg), oldest_gen->no);
   }
-  
-  RELEASE_SM_LOCK;
 }
 
 // An alternate version of newCaf which is used for dynamically loaded
@@ -308,7 +307,7 @@ newCAF(StgClosure* caf)
 // The linker hackily arranges that references to newCaf from dynamic
 // code end up pointing to newDynCAF.
 void
-newDynCAF(StgClosure *caf)
+newDynCAF (StgRegTable *reg STG_UNUSED, StgClosure *caf)
 {
     ACQUIRE_SM_LOCK;
 
@@ -567,6 +566,7 @@ allocate (Capability *cap, lnat n)
        bd = allocGroup(req_blocks);
        dbl_link_onto(bd, &g0->large_objects);
        g0->n_large_blocks += bd->blocks; // might be larger than req_blocks
+       g0->n_new_large_blocks += bd->blocks;
         RELEASE_SM_LOCK;
         initBdescr(bd, g0, g0);
        bd->flags = BF_LARGE;
@@ -614,6 +614,8 @@ allocate (Capability *cap, lnat n)
     }
     p = bd->free;
     bd->free += n;
+
+    IF_DEBUG(sanity, ASSERT(*((StgWord8*)p) == 0xaa));
     return p;
 }
 
@@ -666,6 +668,7 @@ allocatePinned (Capability *cap, lnat n)
        cap->pinned_object_block = bd = allocBlock();
        dbl_link_onto(bd, &g0->large_objects);
        g0->n_large_blocks++;
+       g0->n_new_large_blocks++;
         RELEASE_SM_LOCK;
         initBdescr(bd, g0, g0);
        bd->flags  = BF_PINNED | BF_LARGE;
@@ -784,7 +787,8 @@ calcAllocated( void )
       }
   }
 
-  total_allocated += allocated;
+  allocated += g0->n_new_large_blocks * BLOCK_SIZE_W;
+
   return allocated;
 }