diff options
author | Ben Gamari <ben@well-typed.com> | 2019-02-05 00:10:43 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2019-10-20 21:15:37 -0400 |
commit | 6ff29c064dc042855a0a9a7ebe2cfac55edf17f3 (patch) | |
tree | ee99c710d467d0d9bed375e21226b6a79807cad9 | |
parent | 04471c4f9037065c274736a3693cba116db7bcb9 (diff) | |
download | haskell-6ff29c064dc042855a0a9a7ebe2cfac55edf17f3.tar.gz |
rts: Introduce flag to enable the nonmoving old generation
This flag will enable the use of a non-moving oldest generation.
-rw-r--r-- | docs/users_guide/runtime_control.rst | 18 | ||||
-rw-r--r-- | includes/rts/Flags.h | 2 | ||||
-rw-r--r-- | rts/RtsFlags.c | 23 |
3 files changed, 43 insertions, 0 deletions
diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst index 665c8c08e0..add0b6c537 100644 --- a/docs/users_guide/runtime_control.rst +++ b/docs/users_guide/runtime_control.rst @@ -313,6 +313,24 @@ collection. Hopefully, you won't need any of these in normal operation, but there are several things that can be tweaked for maximum performance. +.. rts-flag:: -xn + + :default: off + :since: 8.8.1 + + .. index:: + single: concurrent mark and sweep + + Enable the concurrent mark-and-sweep garbage collector for old generation + collectors. Typically GHC uses a stop-the-world copying garbage collector + for all generations. This can cause long pauses in execution during major + garbage collections. :rts-flag:`-xn` enables the use of a concurrent + mark-and-sweep garbage collector for oldest generation collections. + Under this collection strategy oldest-generation garbage collection + can proceed concurrently with mutation. + + Note that :rts-flag:`-xn` cannot be used with ``-G1`` nor :rts-flag:`-c`. + .. rts-flag:: -A ⟨size⟩ :default: 1MB diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h index 678d556bf1..4499af9da6 100644 --- a/includes/rts/Flags.h +++ b/includes/rts/Flags.h @@ -52,6 +52,7 @@ typedef struct _GC_FLAGS { double oldGenFactor; double pcFreeHeap; + bool useNonmoving; uint32_t generations; bool squeezeUpdFrames; @@ -95,6 +96,7 @@ typedef struct _DEBUG_FLAGS { bool weak; /* 'w' */ bool gccafs; /* 'G' */ bool gc; /* 'g' */ + bool nonmoving_gc; /* 'n' */ bool block_alloc; /* 'b' */ bool sanity; /* 'S' warning: might be expensive! */ bool zero_on_gc; /* 'Z' */ diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index d36e9ffc66..7d486824ab 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -156,6 +156,7 @@ void initRtsFlagsDefaults(void) RtsFlags.GcFlags.heapSizeSuggestionAuto = false; RtsFlags.GcFlags.pcFreeHeap = 3; /* 3% */ RtsFlags.GcFlags.oldGenFactor = 2; + RtsFlags.GcFlags.useNonmoving = false; RtsFlags.GcFlags.generations = 2; RtsFlags.GcFlags.squeezeUpdFrames = true; RtsFlags.GcFlags.compact = false; @@ -179,6 +180,7 @@ void initRtsFlagsDefaults(void) RtsFlags.DebugFlags.weak = false; RtsFlags.DebugFlags.gccafs = false; RtsFlags.DebugFlags.gc = false; + RtsFlags.DebugFlags.nonmoving_gc = false; RtsFlags.DebugFlags.block_alloc = false; RtsFlags.DebugFlags.sanity = false; RtsFlags.DebugFlags.zero_on_gc = false; @@ -299,6 +301,7 @@ usage_text[] = { " -xb<addr> Sets the address from which a suitable start for the heap memory", " will be searched from. This is useful if the default address", " clashes with some third-party library.", +" -xn Use the non-moving collector for the old generation.", " -m<n> Minimum % of heap which must be available (default 3%)", " -G<n> Number of generations (default: 2)", " -c<n> Use in-place compaction instead of copying in the oldest generation", @@ -404,6 +407,7 @@ usage_text[] = { " -Dw DEBUG: weak", " -DG DEBUG: gccafs", " -Dg DEBUG: gc", +" -Dn DEBUG: non-moving gc", " -Db DEBUG: block", " -DS DEBUG: sanity", " -DZ DEBUG: zero freed memory during GC", @@ -1533,6 +1537,12 @@ error = true; break; #endif + case 'n': + OPTION_SAFE; + RtsFlags.GcFlags.useNonmoving = true; + unchecked_arg_start++; + break; + case 'c': /* Debugging tool: show current cost centre on an exception */ OPTION_SAFE; @@ -1706,6 +1716,16 @@ static void normaliseRtsOpts (void) if (RtsFlags.MiscFlags.generate_dump_file) { RtsFlags.MiscFlags.install_seh_handlers = true; } + + if (RtsFlags.GcFlags.useNonmoving && RtsFlags.GcFlags.generations == 1) { + barf("The non-moving collector doesn't support -G1"); + } + + if (RtsFlags.GcFlags.compact && RtsFlags.GcFlags.useNonmoving) { + errorBelch("The non-moving collector cannot be used in conjunction with\n" + "the compacting collector."); + errorUsage(); + } } static void errorUsage (void) @@ -1871,6 +1891,9 @@ static void read_debug_flags(const char* arg) case 'g': RtsFlags.DebugFlags.gc = true; break; + case 'n': + RtsFlags.DebugFlags.nonmoving_gc = true; + break; case 'b': RtsFlags.DebugFlags.block_alloc = true; break; |