UNDO: slight improvement to scavenging ...
authorSimon Marlow <marlowsd@gmail.com>
Fri, 19 Mar 2010 15:34:13 +0000 (15:34 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Fri, 19 Mar 2010 15:34:13 +0000 (15:34 +0000)
Accidnetally pushed this patch which, while it validates, isn't
correct.

rolling back:

Fri Mar 19 11:21:27 GMT 2010  Simon Marlow <marlowsd@gmail.com>
  * slight improvement to scavenging of update frames when a collision has occurred

    M ./rts/sm/Scav.c -19 +15

rts/sm/Scav.c

index 29a6995..1b671a0 100644 (file)
@@ -1575,13 +1575,11 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
        // threadPaused().  We could traverse the whole stack again
        // before GC, but that seems like overkill.
        //
-        // So, if the frame points to an indirection, it will get
-        // shorted out when we evacuate.  If this happens, we have no
-        // closure to update any more.  In the past we solved this by
-        // replacing the IND with an IND_PERM, but a better solution
-        // is to replace the update frame with a frame that no longer
-        // does the update and just uses the value already computed by
-        // the other thread, so that is what we now do.
+       // Scavenging this update frame as normal would be disastrous;
+       // the updatee would end up pointing to the value.  So we turn
+       // the indirection into an IND_PERM, so that evacuate will
+       // copy the indirection into the old generation instead of
+       // discarding it.
         //
         // Note [upd-black-hole]
         // One slight hiccup is that the THUNK_SELECTOR machinery can
@@ -1592,16 +1590,22 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
         // the updatee is never a THUNK_SELECTOR and we're ok.
         // NB. this is a new invariant: blackholing is not optional.
     {
-        StgClosure *v;
-        StgUpdateFrame *frame = (StgUpdateFrame *)p;
-
-        evacuate(&frame->updatee);
-        v = frame->updatee;
-        if (GET_CLOSURE_TAG(v) != 0 ||
-            (get_itbl(v)->type != BLACKHOLE &&
-             get_itbl(v)->type != CAF_BLACKHOLE)) {
-            frame->header.info = (const StgInfoTable*)&stg_gc_unpt_r1_info;
+        nat type;
+        const StgInfoTable *i;
+        StgClosure *updatee;
+
+        updatee = ((StgUpdateFrame *)p)->updatee;
+        i = updatee->header.info;
+        if (!IS_FORWARDING_PTR(i)) {
+            type = get_itbl(updatee)->type;
+            if (type == IND) {
+                updatee->header.info = &stg_IND_PERM_info;
+            } else if (type == IND_OLDGEN) {
+                updatee->header.info = &stg_IND_OLDGEN_PERM_info;
+            }            
         }
+        evacuate(&((StgUpdateFrame *)p)->updatee);
+        ASSERT(GET_CLOSURE_TAG(((StgUpdateFrame *)p)->updatee) == 0);
         p += sizeofW(StgUpdateFrame);
         continue;
     }