Partial fix for #2917
[ghc-hetmet.git] / rts / sm / Storage.c
index c9c9c1f..9dea30e 100644 (file)
@@ -272,10 +272,13 @@ initStorage( void )
 
 #ifdef THREADED_RTS
   initSpinLock(&gc_alloc_block_sync);
-  initSpinLock(&recordMutableGen_sync);
   whitehole_spin = 0;
 #endif
 
+  N = 0;
+
+  initGcThreads();
+
   IF_DEBUG(gc, statDescribeGens());
 
   RELEASE_SM_LOCK;
@@ -372,7 +375,7 @@ newCAF(StgClosure* caf)
     * any more and can use it as a STATIC_LINK.
     */
     ((StgIndStatic *)caf)->saved_info = NULL;
-    recordMutableGen(caf, oldest_gen);
+    recordMutableGen(caf, oldest_gen->no);
   }
   
   RELEASE_SM_LOCK;
@@ -613,11 +616,19 @@ allocateInGen (generation *g, lnat n)
         if (RtsFlags.GcFlags.maxHeapSize > 0 && 
             req_blocks >= RtsFlags.GcFlags.maxHeapSize) {
             heapOverflow();
+            // heapOverflow() doesn't exit (see #2592), but we aren't
+            // in a position to do a clean shutdown here: we
+            // either have to allocate the memory or exit now.
+            // Allocating the memory would be bad, because the user
+            // has requested that we not exceed maxHeapSize, so we
+            // just exit.
+           stg_exit(EXIT_HEAPOVERFLOW);
         }
 
        bd = allocGroup(req_blocks);
        dbl_link_onto(bd, &stp->large_objects);
        stp->n_large_blocks += bd->blocks; // might be larger than req_blocks
+       alloc_blocks += bd->blocks;
        bd->gen_no  = g->no;
        bd->step = stp;
        bd->flags = BF_LARGE;
@@ -744,7 +755,9 @@ allocateLocal (Capability *cap, lnat n)
             bd->flags = 0;
             // NO: alloc_blocks++;
             // calcAllocated() uses the size of the nursery, and we've
-            // already bumpted nursery->n_blocks above.
+            // already bumpted nursery->n_blocks above.  We'll GC
+            // pretty quickly now anyway, because MAYBE_GC() will
+            // notice that CurrentNursery->link is NULL.
         } else {
             // we have a block in the nursery: take it and put
             // it at the *front* of the nursery list, and use it
@@ -795,7 +808,9 @@ allocatePinned( lnat n )
     // If the request is for a large object, then allocate()
     // will give us a pinned object anyway.
     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
-       return allocate(n);
+       p = allocate(n);
+        Bdescr(p)->flags |= BF_PINNED;
+        return p;
     }
 
     ACQUIRE_SM_LOCK;
@@ -803,13 +818,6 @@ allocatePinned( lnat n )
     TICK_ALLOC_HEAP_NOCTR(n);
     CCS_ALLOC(CCCS,n);
 
-    // we always return 8-byte aligned memory.  bd->free must be
-    // 8-byte aligned to begin with, so we just round up n to
-    // the nearest multiple of 8 bytes.
-    if (sizeof(StgWord) == 4) {
-       n = (n+1) & ~1;
-    }
-
     // If we don't have a block of pinned objects yet, or the current
     // one isn't large enough to hold the new object, allocate a new one.
     if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) {
@@ -1470,9 +1478,6 @@ checkSanity( void )
                       == generations[g].steps[s].n_large_blocks);
                checkHeap(generations[g].steps[s].blocks);
                checkChain(generations[g].steps[s].large_objects);
-               if (g > 0) {
-                   checkMutableList(generations[g].mut_list, g);
-               }
            }
        }
 
@@ -1489,9 +1494,9 @@ checkSanity( void )
 #if defined(THREADED_RTS)
     // check the stacks too in threaded mode, because we don't do a
     // full heap sanity check in this case (see checkHeap())
-    checkGlobalTSOList(rtsTrue);
+    checkMutableLists(rtsTrue);
 #else
-    checkGlobalTSOList(rtsFalse);
+    checkMutableLists(rtsFalse);
 #endif
 }