calculate wastage due to unused memory at the end of each block
authorsimonmar@microsoft.com <unknown>
Fri, 14 Dec 2007 13:58:42 +0000 (13:58 +0000)
committersimonmar@microsoft.com <unknown>
Fri, 14 Dec 2007 13:58:42 +0000 (13:58 +0000)
includes/Storage.h
rts/Stats.c
rts/sm/GC.c
rts/sm/Storage.c

index a40fd95..62d57b1 100644 (file)
@@ -519,7 +519,9 @@ extern void         GetRoots     ( evac_fn evac );
 extern ullong RTS_VAR(total_allocated);
 
 extern lnat calcAllocated  ( void );
-extern lnat calcLive       ( void );
+extern lnat calcLiveBlocks ( void );
+extern lnat calcLiveWords  ( void );
+extern lnat countOccupied  ( bdescr *bd );
 extern lnat calcNeeded     ( void );
 
 #if defined(DEBUG)
index 7059feb..b9df019 100644 (file)
@@ -676,14 +676,10 @@ statDescribeGens(void)
       for (bd = step->large_objects, lge = 0; bd; bd = bd->link) {
        lge++;
       }
-      live = step->n_large_blocks * BLOCK_SIZE;
-      bd = step->blocks;
       // This live figure will be slightly less that the "live" figure
       // given by +RTS -Sstderr, because we take don't count the
       // slop at the end of each block.
-      for (; bd; bd = bd->link) {
-       live += (bd->free - bd->start) * sizeof(W_);
-      }
+      live += countOccupied(step->blocks) + countOccupied(step->large_objects);
       if (s != 0) {
        debugBelch("%36s","");
       }
index 244da13..49f9831 100644 (file)
@@ -580,7 +580,9 @@ GarbageCollect ( rtsBool force_major_gc )
   resize_generations();
   
   // Guess the amount of live data for stats.
-  live = calcLive();
+  live = calcLiveBlocks() * BLOCK_SIZE_W;
+  debugTrace(DEBUG_gc, "Slop: %ldKB", 
+             (live - calcLiveWords()) / (1024/sizeof(W_)));
 
   // Free the small objects allocated via allocate(), since this will
   // all have been copied into G0S1 now.  
index c441826..ecd9b54 100644 (file)
@@ -918,15 +918,15 @@ calcAllocated( void )
 /* Approximate the amount of live data in the heap.  To be called just
  * after garbage collection (see GarbageCollect()).
  */
-extern lnat 
-calcLive(void)
+lnat 
+calcLiveBlocks(void)
 {
   nat g, s;
   lnat live = 0;
   step *stp;
 
   if (RtsFlags.GcFlags.generations == 1) {
-      return (g0s0->n_large_blocks + g0s0->n_blocks) * BLOCK_SIZE_W;
+      return g0s0->n_large_blocks + g0s0->n_blocks;
   }
 
   for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
@@ -938,12 +938,50 @@ calcLive(void)
          continue; 
       }
       stp = &generations[g].steps[s];
-      live += (stp->n_large_blocks + stp->n_blocks) * BLOCK_SIZE_W;
+      live += stp->n_large_blocks + stp->n_blocks;
     }
   }
   return live;
 }
 
+lnat
+countOccupied(bdescr *bd)
+{
+    lnat words;
+
+    words = 0;
+    for (; bd != NULL; bd = bd->link) {
+        words += bd->free - bd->start;
+    }
+    return words;
+}
+
+lnat
+calcLiveWords(void)
+{
+    nat g, s;
+    lnat live;
+    step *stp;
+    
+    if (RtsFlags.GcFlags.generations == 1) {
+        return countOccupied(g0s0->blocks) + countOccupied(g0s0->large_objects);
+    }
+    
+    live = 0;
+    for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+        for (s = 0; s < generations[g].n_steps; s++) {
+            /* approximate amount of live data (doesn't take into account slop
+             * at end of each block).
+             */
+            if (g == 0 && s == 0) continue; 
+            stp = &generations[g].steps[s];
+            live += countOccupied(stp->blocks) + 
+                    countOccupied(stp->large_objects);
+        } 
+    }
+    return live;
+}
+
 /* Approximate the number of blocks that will be needed at the next
  * garbage collection.
  *