diff options
author | Edward Z. Yang <ezyang@cs.stanford.edu> | 2014-05-29 20:05:51 -0700 |
---|---|---|
committer | Edward Z. Yang <ezyang@cs.stanford.edu> | 2014-05-29 20:05:51 -0700 |
commit | 723095b0e4c5838c7eefd757af56ab2a7c614801 (patch) | |
tree | 1581da2255fe571fc567992feb3422cebf3f59c7 /rts/sm | |
parent | 0c1974c8262f1609ecb7dec438d8cd167f788a5c (diff) | |
download | haskell-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.c | 3 | ||||
-rw-r--r-- | rts/sm/MarkWeak.c | 35 | ||||
-rw-r--r-- | rts/sm/MarkWeak.h | 1 |
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 ); |