diff options
author | Simon Marlow <marlowsd@gmail.com> | 2015-07-28 20:58:25 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2015-07-28 20:58:35 +0100 |
commit | f83aab95f59ae9b29f22fc7924e050512229cb9c (patch) | |
tree | 2f03ed82c7122f373da774148e3c806aa1dbcae8 /rts/sm/GC.c | |
parent | a1dd7dd6ea276832aef0caaf805f0ab9f4e16262 (diff) | |
download | haskell-f83aab95f59ae9b29f22fc7924e050512229cb9c.tar.gz |
Eliminate zero_static_objects_list()
Summary:
[Revised version of D1076 that was committed and then backed out]
In a workload with a large amount of code, zero_static_objects_list()
takes a significant amount of time, and furthermore it is in the
single-threaded part of the GC.
This patch uses a slightly fiddly scheme for marking objects on the
static object lists, using a flag in the low 2 bits that flips between
two states to indicate whether an object has been visited during this
GC or not. We also have to take into account objects that have not
been visited yet, which might appear at any time due to runtime linking.
Test Plan: validate
Reviewers: austin, ezyang, rwbarton, bgamari, thomie
Reviewed By: bgamari, thomie
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1106
Diffstat (limited to 'rts/sm/GC.c')
-rw-r--r-- | rts/sm/GC.c | 48 |
1 files changed, 12 insertions, 36 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 52d7f98fa0..e6a23395eb 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -134,6 +134,9 @@ long copied; // *words* copied & scavenged during this GC rtsBool work_stealing; +nat static_flag = STATIC_FLAG_B; +nat prev_static_flag = STATIC_FLAG_A; + DECLARE_GCT /* ----------------------------------------------------------------------------- @@ -141,7 +144,6 @@ DECLARE_GCT -------------------------------------------------------------------------- */ static void mark_root (void *user, StgClosure **root); -static void zero_static_object_list (StgClosure* first_static); static void prepare_collected_gen (generation *gen); static void prepare_uncollected_gen (generation *gen); static void init_gc_thread (gc_thread *t); @@ -246,6 +248,12 @@ GarbageCollect (nat collect_gen, N = collect_gen; major_gc = (N == RtsFlags.GcFlags.generations-1); + if (major_gc) { + prev_static_flag = static_flag; + static_flag = + static_flag == STATIC_FLAG_A ? STATIC_FLAG_B : STATIC_FLAG_A; + } + #if defined(THREADED_RTS) work_stealing = RtsFlags.ParFlags.parGcLoadBalancingEnabled && N >= RtsFlags.ParFlags.parGcLoadBalancingGen; @@ -672,20 +680,6 @@ GarbageCollect (nat collect_gen, resetStaticObjectForRetainerProfiling(gct->scavenged_static_objects); #endif - // zero the scavenged static object list - if (major_gc) { - nat i; - if (n_gc_threads == 1) { - zero_static_object_list(gct->scavenged_static_objects); - } else { - for (i = 0; i < n_gc_threads; i++) { - if (!gc_threads[i]->idle) { - zero_static_object_list(gc_threads[i]->scavenged_static_objects); - } - } - } - } - // Start any pending finalizers. Must be after // updateStableTables() and stableUnlock() (see #4221). RELEASE_SM_LOCK; @@ -1427,8 +1421,8 @@ collect_pinned_object_blocks (void) static void init_gc_thread (gc_thread *t) { - t->static_objects = END_OF_STATIC_LIST; - t->scavenged_static_objects = END_OF_STATIC_LIST; + t->static_objects = END_OF_STATIC_OBJECT_LIST; + t->scavenged_static_objects = END_OF_STATIC_OBJECT_LIST; t->scan_bd = NULL; t->mut_lists = t->cap->mut_lists; t->evac_gen_no = 0; @@ -1465,24 +1459,6 @@ mark_root(void *user USED_IF_THREADS, StgClosure **root) SET_GCT(saved_gct); } -/* ----------------------------------------------------------------------------- - Initialising the static object & mutable lists - -------------------------------------------------------------------------- */ - -static void -zero_static_object_list(StgClosure* first_static) -{ - StgClosure* p; - StgClosure* link; - const StgInfoTable *info; - - for (p = first_static; p != END_OF_STATIC_LIST; p = link) { - info = get_itbl(p); - link = *STATIC_LINK(info, p); - *STATIC_LINK(info,p) = NULL; - } -} - /* ---------------------------------------------------------------------------- Reset the sizes of the older generations when we do a major collection. @@ -1728,7 +1704,7 @@ static void gcCAFs(void) p = debug_caf_list; prev = NULL; - for (p = debug_caf_list; p != (StgIndStatic*)END_OF_STATIC_LIST; + for (p = debug_caf_list; p != (StgIndStatic*)END_OF_CAF_LIST; p = (StgIndStatic*)p->saved_info) { info = get_itbl((StgClosure*)p); |