Permalink
Browse files

Maintain per-generation lists of weak pointers

  • Loading branch information...
1 parent f6e9c26 commit c7345c68eaa1e7f9572e693b5e352e386df7d680 Takano Akio committed Mar 11, 2013
@@ -83,6 +83,10 @@ typedef struct generation_ {
StgTSO * threads; // threads in this gen
// linked via global_link
+ StgWeak * weak_ptr_list; // weak pointers in this gen
+ // ForeignPtrs with C finalizers rely on weak pointers inside weak_ptr_list
+ // to always be in the same order.
+
struct generation_ *to; // destination gen for live objects
// stats information
@@ -116,6 +120,8 @@ typedef struct generation_ {
bdescr * bitmap; // bitmap for compacting collection
StgTSO * old_threads;
+ StgWeak * old_weak_ptr_list;
+ StgWeak * weak_ptr_list_tail;
} generation;
extern generation * generations;
@@ -465,7 +465,6 @@ extern StgWord stg_stack_save_entries[];
// Storage.c
extern unsigned int RTS_VAR(g0);
extern unsigned int RTS_VAR(large_alloc_lim);
-extern StgWord RTS_VAR(weak_ptr_list);
extern StgWord RTS_VAR(atomic_modify_mutvar_mutex);
// RtsFlags
View
@@ -384,8 +384,8 @@ stg_mkWeakzh ( gcptr key,
StgWeak_cfinalizer(w) = stg_NO_FINALIZER_closure;
ACQUIRE_LOCK(sm_mutex);
- StgWeak_link(w) = W_[weak_ptr_list];
- W_[weak_ptr_list] = w;
+ StgWeak_link(w) = generation_weak_ptr_list(W_[g0]);
+ generation_weak_ptr_list(W_[g0]) = w;
RELEASE_LOCK(sm_mutex);
IF_DEBUG(weak, ccall debugBelch(stg_weak_msg,w));
@@ -435,8 +435,8 @@ stg_mkWeakForeignEnvzh ( gcptr key,
StgWeak_cfinalizer(w) = p;
ACQUIRE_LOCK(sm_mutex);
- StgWeak_link(w) = W_[weak_ptr_list];
- W_[weak_ptr_list] = w;
+ StgWeak_link(w) = generation_weak_ptr_list(W_[g0]);
+ generation_weak_ptr_list(W_[g0]) = w;
RELEASE_LOCK(sm_mutex);
IF_DEBUG(weak, ccall debugBelch(stg_weak_msg,w));
View
@@ -1767,9 +1767,11 @@ computeRetainerSet( void )
//
// The following code assumes that WEAK objects are considered to be roots
// for retainer profilng.
- for (weak = weak_ptr_list; weak != NULL; weak = weak->link)
- // retainRoot((StgClosure *)weak);
- retainRoot(NULL, (StgClosure **)&weak);
+ for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ for (weak = generations[g].weak_ptr_list; weak != NULL; weak = weak->link)
+ // retainRoot((StgClosure *)weak);
+ retainRoot(NULL, (StgClosure **)&weak);
+ }
// Consider roots from the stable ptr table.
markStableTables(retainRoot, NULL);
View
@@ -305,6 +305,8 @@ hs_add_root(void (*init_root)(void) STG_UNUSED)
static void
hs_exit_(rtsBool wait_foreign)
{
+ nat g;
+
if (hs_init_count <= 0) {
errorBelch("warning: too many hs_exit()s");
return;
@@ -335,7 +337,9 @@ hs_exit_(rtsBool wait_foreign)
exitScheduler(wait_foreign);
/* run C finalizers for all active weak pointers */
- runAllCFinalizers(weak_ptr_list);
+ for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ runAllCFinalizers(generations[g].weak_ptr_list);
+ }
#if defined(RTS_USER_SIGNALS)
if (RtsFlags.MiscFlags.install_signal_handlers) {
View
@@ -16,11 +16,6 @@
#include "Prelude.h"
#include "Trace.h"
-// ForeignPtrs with C finalizers rely on weak pointers inside weak_ptr_list
-// to always be in the same order.
-
-StgWeak *weak_ptr_list;
-
void
runCFinalizer(void *fn, void *ptr, void *env, StgWord flag)
{
View
@@ -14,7 +14,7 @@
#include "BeginPrivate.h"
extern rtsBool running_finalizers;
-extern StgWeak * weak_ptr_list;
+extern StgWeak * dead_weak_ptr_list;
void runCFinalizer(void *fn, void *ptr, void *env, StgWord flag);
void runAllCFinalizers(StgWeak *w);
View
@@ -917,11 +917,13 @@ compact(StgClosure *static_objects)
markScheduler((evac_fn)thread_root, NULL);
// the weak pointer lists...
- if (weak_ptr_list != NULL) {
- thread((void *)&weak_ptr_list);
+ for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ if (generations[g].weak_ptr_list != NULL)
+ thread((void *)&generations[g].weak_ptr_list);
}
- if (old_weak_ptr_list != NULL) {
- thread((void *)&old_weak_ptr_list); // tmp
+
+ if (dead_weak_ptr_list != NULL) {
+ thread((void *)&dead_weak_ptr_list); // tmp
}
// mutable lists
View
@@ -708,7 +708,7 @@ GarbageCollect (nat collect_gen,
// Start any pending finalizers. Must be after
// updateStableTables() and stableUnlock() (see #4221).
RELEASE_SM_LOCK;
- scheduleFinalizers(cap, old_weak_ptr_list);
+ scheduleFinalizers(cap, dead_weak_ptr_list);
ACQUIRE_SM_LOCK;
// check sanity after GC
Oops, something went wrong.

0 comments on commit c7345c6

Please sign in to comment.