Windows DLLs: use DLL aware runSparks_closure instead of base_GHCziConc_runSparks_clo...
[ghc-hetmet.git] / rts / sm / MarkWeak.c
index 2f5964f..7b7187c 100644 (file)
@@ -83,8 +83,8 @@ StgTSO *resurrected_threads;
 // List of blocked threads found to have pending throwTos
 StgTSO *exception_threads;
 
-static void resurrectUnreachableThreads (step *stp);
-static rtsBool tidyThreadList (step *stp);
+static void resurrectUnreachableThreads (generation *gen);
+static rtsBool tidyThreadList (generation *gen);
 
 void
 initWeakForGC(void)
@@ -113,7 +113,7 @@ traverseWeakPtrList(void)
       /* doesn't matter where we evacuate values/finalizers to, since
        * these pointers are treated as roots (iff the keys are alive).
        */
-      gct->evac_step = 0;
+      gct->evac_gen = 0;
       
       last_w = &old_weak_ptr_list;
       for (w = old_weak_ptr_list; w != NULL; w = next_w) {
@@ -127,14 +127,8 @@ traverseWeakPtrList(void)
              continue;
          }
          
-          info = w->header.info;
-          if (IS_FORWARDING_PTR(info)) {
-             next_w = (StgWeak *)UN_FORWARDING_PTR(info);
-             *last_w = next_w;
-             continue;
-          }
-
-         switch (INFO_PTR_TO_STRUCT(info)->type) {
+          info = get_itbl(w);
+         switch (info->type) {
 
          case WEAK:
              /* Now, check whether the key is reachable.
@@ -191,19 +185,18 @@ traverseWeakPtrList(void)
        * become garbage, we wake them up and administer an exception.
        */
   {
-      nat g, s, n;
+      nat g;
          
       // Traverse thread lists for generations we collected...
-      for (n = 0; n < n_capabilities; n++) {
-          if (tidyThreadList(&nurseries[n])) {
-              flag = rtsTrue;
-          }
-      }              
+//      ToDo when we have one gen per capability:
+//      for (n = 0; n < n_capabilities; n++) {
+//          if (tidyThreadList(&nurseries[n])) {
+//              flag = rtsTrue;
+//          }
+//      }              
       for (g = 0; g <= N; g++) {
-          for (s = 0; s < generations[g].n_steps; s++) {
-              if (tidyThreadList(&generations[g].steps[s])) {
-                  flag = rtsTrue;
-              }
+          if (tidyThreadList(&generations[g])) {
+              flag = rtsTrue;
           }
       }
 
@@ -214,15 +207,9 @@ traverseWeakPtrList(void)
       /* And resurrect any threads which were about to become garbage.
        */
       {
-          nat g, s, n;
-
-          for (n = 0; n < n_capabilities; n++) {
-              resurrectUnreachableThreads(&nurseries[n]);
-          }              
+          nat g;
           for (g = 0; g <= N; g++) {
-              for (s = 0; s < generations[g].n_steps; s++) {
-                  resurrectUnreachableThreads(&generations[g].steps[s]);
-              }
+              resurrectUnreachableThreads(&generations[g]);
           }
       }
         
@@ -251,11 +238,11 @@ traverseWeakPtrList(void)
   }
 }
   
-  static void resurrectUnreachableThreads (step *stp)
+  static void resurrectUnreachableThreads (generation *gen)
 {
     StgTSO *t, *tmp, *next;
 
-    for (t = stp->old_threads; t != END_TSO_QUEUE; t = next) {
+    for (t = gen->old_threads; t != END_TSO_QUEUE; t = next) {
         next = t->global_link;
         
         // ThreadFinished and ThreadComplete: we have to keep
@@ -275,14 +262,14 @@ traverseWeakPtrList(void)
     }
 }
 
-static rtsBool tidyThreadList (step *stp)
+static rtsBool tidyThreadList (generation *gen)
 {
     StgTSO *t, *tmp, *next, **prev;
     rtsBool flag = rtsFalse;
 
-    prev = &stp->old_threads;
+    prev = &gen->old_threads;
 
-    for (t = stp->old_threads; t != END_TSO_QUEUE; t = next) {
+    for (t = gen->old_threads; t != END_TSO_QUEUE; t = next) {
              
         tmp = (StgTSO *)isAlive((StgClosure *)t);
        
@@ -339,10 +326,10 @@ static rtsBool tidyThreadList (step *stp)
             *prev = next;
             
             // move this thread onto the correct threads list.
-            step *new_step;
-            new_step = Bdescr((P_)t)->step;
-            t->global_link = new_step->threads;
-            new_step->threads  = t;
+            generation *new_gen;
+            new_gen = Bdescr((P_)t)->gen;
+            t->global_link = new_gen->threads;
+            new_gen->threads  = t;
         }
     }
 
@@ -393,21 +380,17 @@ traverseBlackholeQueue (void)
 }
 
 /* -----------------------------------------------------------------------------
-   After GC, the live weak pointer list may have forwarding pointers
-   on it, because a weak pointer object was evacuated after being
-   moved to the live weak pointer list.  We remove those forwarding
-   pointers here.
-
-   Also, we don't consider weak pointer objects to be reachable, but
-   we must nevertheless consider them to be "live" and retain them.
-   Therefore any weak pointer objects which haven't as yet been
-   evacuated need to be evacuated now.
+   Evacuate every weak pointer object on the weak_ptr_list, and update
+   the link fields.
+
+   ToDo: with a lot of weak pointers, this will be expensive.  We
+   should have a per-GC weak pointer list, just like threads.
    -------------------------------------------------------------------------- */
 
 void
 markWeakPtrList ( void )
 {
-  StgWeak *w, **last_w, *tmp;
+  StgWeak *w, **last_w;
 
   last_w = &weak_ptr_list;
   for (w = weak_ptr_list; w; w = w->link) {
@@ -415,10 +398,13 @@ markWeakPtrList ( void )
       ASSERT(IS_FORWARDING_PTR(w->header.info)
              || w->header.info == &stg_DEAD_WEAK_info 
             || get_itbl(w)->type == WEAK);
-      tmp = w;
-      evacuate((StgClosure **)&tmp);
-      *last_w = w;
-      last_w = &(w->link);
+      evacuate((StgClosure **)last_w);
+      w = *last_w;
+      if (w->header.info == &stg_DEAD_WEAK_info) {
+          last_w = &(((StgDeadWeak*)w)->link);
+      } else {
+          last_w = &(w->link);
+      }
   }
 }