Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : local-gc

http://hackage.haskell.org/trac/ghc/changeset/ab5aad587de8e3d9dde539982ae728b33e5bca50

>---------------------------------------------------------------

commit ab5aad587de8e3d9dde539982ae728b33e5bca50
Author: Simon Marlow <[email protected]>
Date:   Mon Jun 6 04:52:27 2011 +0100

    fix an interaction between the new pinned_object_block policy and
    globalisation.

>---------------------------------------------------------------

 rts/sm/Globalise.c |   13 +++++++++++++
 rts/sm/Storage.c   |   12 ++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/rts/sm/Globalise.c b/rts/sm/Globalise.c
index ff9db7b..831d45e 100644
--- a/rts/sm/Globalise.c
+++ b/rts/sm/Globalise.c
@@ -217,6 +217,19 @@ globalise_large (StgPtr p)
 
     ACQUIRE_SPIN_LOCK(&gen->sync);
 
+    // the object we need to globalise might be in the
+    // pinned_object_block, which is still being allocated into.  In
+    // that case, we just mark the pinned_object_block with the global
+    // generation, and allocatePinned() will attach the block to the
+    // correct gen->large_objects list when it is full.
+    if (bd == gct->cap->pinned_object_block) {
+        new_gen = &all_generations[global_gen_ix];
+        initBdescr(bd, new_gen, new_gen->to);
+
+        RELEASE_SPIN_LOCK(&gen->sync);
+        return;
+    }
+
     // remove from large_object list 
     if (bd->u.back) {
         bd->u.back->link = bd->link;
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 3a8c0fa..eaffdc6 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -778,16 +778,20 @@ allocatePinned (Capability *cap, lnat n)
         // the next GC the BF_EVACUATED flag will be cleared, and the
         // block will be promoted as usual (if anything in it is
         // live).
-        ACQUIRE_SM_LOCK;
-        gen = cap->r.rG0; // use our local G0
         if (bd != NULL) {
+            gen = bd->gen;
+            // attach it to the correct generation - the block might
+            // have been globalised by now (see globalise_large()).
+            if (gen->no != 0) { ACQUIRE_SPIN_LOCK(&gen->sync); }
             dbl_link_onto(bd, &gen->large_objects);
             gen->n_large_blocks++;
-            g0->n_new_large_words += bd->free - bd->start;
+            gen->n_new_large_words += bd->free - bd->start;
+            if (gen->no != 0) { RELEASE_SPIN_LOCK(&gen->sync); }
         }
+        ACQUIRE_SM_LOCK;
         cap->pinned_object_block = bd = allocBlock();
         RELEASE_SM_LOCK;
-        initBdescr(bd, gen, gen);
+        initBdescr(bd, cap->r.rG0, cap->r.rG0);  // use our local G0
         bd->flags  = BF_PINNED | BF_LARGE | BF_EVACUATED;
         bd->free   = bd->start;
     }



_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to