Mark/compact: use a dynamically-sized mark stack, and don't do linear scan
[ghc-hetmet.git] / rts / sm / Evac.c
index b711914..379fbba 100644 (file)
@@ -20,6 +20,7 @@
 #include "GCThread.h"
 #include "GCUtils.h"
 #include "Compact.h"
+#include "MarkStack.h"
 #include "Prelude.h"
 #include "Trace.h"
 #include "LdvProfile.h"
@@ -97,8 +98,6 @@ copy_tag(StgClosure **p, const StgInfoTable *info,
 
     to = alloc_for_copy(size,stp);
     
-    TICK_GC_WORDS_COPIED(size);
-
     from = (StgPtr)src;
     to[0] = (W_)info;
     for (i = 1; i < size; i++) { // unroll for small i
@@ -112,8 +111,7 @@ copy_tag(StgClosure **p, const StgInfoTable *info,
 #if defined(PARALLEL_GC)
     {
         const StgInfoTable *new_info;
-        new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info,
-                                             (W_)info, MK_FORWARDING_PTR(to));
+        new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, (W_)info, MK_FORWARDING_PTR(to));
         if (new_info != info) {
             return evacuate(p); // does the failed_to_evac stuff
         } else {
@@ -144,8 +142,6 @@ copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
     *p = TAG_CLOSURE(tag,(StgClosure*)to);
     src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
     
-    TICK_GC_WORDS_COPIED(size);
-
     from = (StgPtr)src;
     to[0] = (W_)info;
     for (i = 1; i < size; i++) { // unroll for small i
@@ -169,39 +165,44 @@ copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
  * used to optimise evacuation of BLACKHOLEs.
  */
 static rtsBool
-copyPart(StgClosure **p, const StgInfoTable *info, StgClosure *src, 
-         nat size_to_reserve, nat size_to_copy, step *stp)
+copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
 {
     StgPtr to, from;
     nat i;
+    StgWord info;
     
-    to = alloc_for_copy(size_to_reserve, stp);
+#if defined(PARALLEL_GC)
+spin:
+       info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
+       if (info == (W_)&stg_WHITEHOLE_info) {
+#ifdef PROF_SPIN
+           whitehole_spin++;
+#endif
+           goto spin;
+       }
+    if (IS_FORWARDING_PTR(info)) {
+       src->header.info = (const StgInfoTable *)info;
+       evacuate(p); // does the failed_to_evac stuff
+       return rtsFalse;
+    }
+#else
+    info = (W_)src->header.info;
+#endif
 
-    TICK_GC_WORDS_COPIED(size_to_copy);
+    to = alloc_for_copy(size_to_reserve, stp);
+    *p = (StgClosure *)to;
 
     from = (StgPtr)src;
-    to[0] = (W_)info;
+    to[0] = info;
     for (i = 1; i < size_to_copy; i++) { // unroll for small i
        to[i] = from[i];
     }
     
 #if defined(PARALLEL_GC)
-    {
-        const StgInfoTable *new_info;
-        new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, 
-                                             (W_)info, MK_FORWARDING_PTR(to));
-        if (new_info != info) {
-            evacuate(p); // does the failed_to_evac stuff
-            return rtsFalse;
-        } else {
-            *p = (StgClosure*)to;
-        }
-    }
-#else
-    src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
-    *p = (StgClosure*)to;
+    write_barrier();
 #endif
-
+    src->header.info = (const StgInfoTable*)MK_FORWARDING_PTR(to);
+    
 #ifdef PROFILING
     // We store the size of the just evacuated object in the LDV word so that
     // the profiler can guess the position of the next object later.
@@ -499,11 +500,6 @@ loop:
        */
       if (!is_marked((P_)q,bd)) {
           mark((P_)q,bd);
-          if (mark_stack_full()) {
-              debugTrace(DEBUG_gc,"mark stack overflowed");
-              mark_stack_overflowed = rtsTrue;
-              reset_mark_stack();
-          }
           push_mark_stack((P_)q);
       }
       return;
@@ -633,7 +629,7 @@ loop:
 
   case CAF_BLACKHOLE:
   case BLACKHOLE:
-      copyPart(p,info,q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
+      copyPart(p,q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
       return;
 
   case THUNK_SELECTOR:
@@ -697,15 +693,14 @@ loop:
        goto loop;
       }
 
-      /* To evacuate a small TSO, we need to relocate the update frame
-       * list it contains.  
+      /* To evacuate a small TSO, we need to adjust the stack pointer
        */
       {
          StgTSO *new_tso;
          StgPtr r, s;
           rtsBool mine;
 
-         mine = copyPart(p,info,(StgClosure *)tso, tso_sizeW(tso), 
+         mine = copyPart(p,(StgClosure *)tso, tso_sizeW(tso), 
                           sizeofW(StgTSO), stp);
           if (mine) {
               new_tso = (StgTSO *)*p;