summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2014-05-29 20:05:51 -0700
committerEdward Z. Yang <ezyang@cs.stanford.edu>2014-05-29 20:05:51 -0700
commit723095b0e4c5838c7eefd757af56ab2a7c614801 (patch)
tree1581da2255fe571fc567992feb3422cebf3f59c7 /rts/sm
parent0c1974c8262f1609ecb7dec438d8cd167f788a5c (diff)
downloadhaskell-723095b0e4c5838c7eefd757af56ab2a7c614801.tar.gz
Per-capability nursery weak pointer lists, fixes #9075
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/GC.c3
-rw-r--r--rts/sm/MarkWeak.c35
-rw-r--r--rts/sm/MarkWeak.h1
3 files changed, 39 insertions, 0 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index d22a31eccb..61432eabde 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -286,6 +286,9 @@ GarbageCollect (nat collect_gen,
memInventory(DEBUG_gc);
#endif
+ // do this *before* we start scavenging
+ collectFreshWeakPtrs();
+
// check sanity *before* GC
IF_DEBUG(sanity, checkSanity(rtsFalse /* before GC */, major_gc));
diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c
index af953cd881..0324f3b4b9 100644
--- a/rts/sm/MarkWeak.c
+++ b/rts/sm/MarkWeak.c
@@ -25,6 +25,8 @@
#include "Storage.h"
#include "Threads.h"
+#include "sm/Sanity.h"
+
/* -----------------------------------------------------------------------------
Weak Pointers
@@ -341,6 +343,39 @@ static void tidyThreadList (generation *gen)
}
}
+#ifdef DEBUG
+static void checkWeakPtrSanity(StgWeak *hd, StgWeak *tl)
+{
+ StgWeak *w, *prev;
+ for (w = hd; w != NULL; prev = w, w = w->link) {
+ ASSERT(INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure*)w)->header.info)->type == WEAK);
+ checkClosure((StgClosure*)w);
+ }
+ if (tl != NULL) {
+ ASSERT(prev == tl);
+ }
+}
+#endif
+
+void collectFreshWeakPtrs()
+{
+ nat i;
+ generation *gen = &generations[0];
+ // move recently allocated weak_ptr_list to the old list as well
+ for (i = 0; i < n_capabilities; i++) {
+ Capability *cap = capabilities[i];
+ if (cap->weak_ptr_list_tl != NULL) {
+ IF_DEBUG(sanity, checkWeakPtrSanity(cap->weak_ptr_list_hd, cap->weak_ptr_list_tl));
+ cap->weak_ptr_list_tl->link = gen->weak_ptr_list;
+ gen->weak_ptr_list = cap->weak_ptr_list_hd;
+ cap->weak_ptr_list_tl = NULL;
+ cap->weak_ptr_list_hd = NULL;
+ } else {
+ ASSERT(cap->weak_ptr_list_hd == NULL);
+ }
+ }
+}
+
/* -----------------------------------------------------------------------------
Evacuate every weak pointer object on the weak_ptr_list, and update
the link fields.
diff --git a/rts/sm/MarkWeak.h b/rts/sm/MarkWeak.h
index f9bacfa0da..bd0231d74c 100644
--- a/rts/sm/MarkWeak.h
+++ b/rts/sm/MarkWeak.h
@@ -20,6 +20,7 @@ extern StgWeak *old_weak_ptr_list;
extern StgTSO *resurrected_threads;
extern StgTSO *exception_threads;
+void collectFreshWeakPtrs ( void );
void initWeakForGC ( void );
rtsBool traverseWeakPtrList ( void );
void markWeakPtrList ( void );