diff --git a/libraries/base/src/GHC/RTS/Flags.hsc b/libraries/base/src/GHC/RTS/Flags.hsc index 2424a4f2c4391293c999bd4adb14c92aa939bb92..0999dcbfcf9d9d2729adb2ba0173f3a0b18a816e 100644 --- a/libraries/base/src/GHC/RTS/Flags.hsc +++ b/libraries/base/src/GHC/RTS/Flags.hsc @@ -144,6 +144,7 @@ data GCFlags = GCFlags , minOldGenSize :: Word32 , heapSizeSuggestion :: Word32 , heapSizeSuggestionAuto :: Bool + , arbitraryHeapStart :: Bool , oldGenFactor :: Double , returnDecayFactor :: Double , pcFreeHeap :: Double @@ -462,6 +463,8 @@ getGCFlags = do <*> #{peek GC_FLAGS, heapSizeSuggestion} ptr <*> (toBool <$> (#{peek GC_FLAGS, heapSizeSuggestionAuto} ptr :: IO CBool)) + <*> (toBool <$> + (#{peek GC_FLAGS, arbitraryHeapStart} ptr :: IO CBool)) <*> #{peek GC_FLAGS, oldGenFactor} ptr <*> #{peek GC_FLAGS, returnDecayFactor} ptr <*> #{peek GC_FLAGS, pcFreeHeap} ptr diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 8c384ad432728ab9ec8b5fc93e2a0c6fcf398870..6e841d838f9fb09490ecdf79b8c5253001a75af5 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -162,6 +162,7 @@ void initRtsFlagsDefaults(void) RtsFlags.GcFlags.heapLimitGrace = (1024 * 1024); RtsFlags.GcFlags.heapSizeSuggestion = 0; /* none */ RtsFlags.GcFlags.heapSizeSuggestionAuto = false; + RtsFlags.GcFlags.arbitraryHeapStart = false; RtsFlags.GcFlags.pcFreeHeap = 3; /* 3% */ RtsFlags.GcFlags.oldGenFactor = 2; RtsFlags.GcFlags.returnDecayFactor = 4; @@ -1055,6 +1056,11 @@ error = true; OPTION_UNSAFE; RtsFlags.HpcFlags.writeTixFile = false; } + else if (strequal("arbitrary-heap-start", + &rts_argv[arg][2])) { + OPTION_UNSAFE; + RtsFlags.GcFlags.arbitraryHeapStart = true; + } #if defined(THREADED_RTS) #if defined(mingw32_HOST_OS) else if (!strncmp("io-manager-threads", diff --git a/rts/include/rts/Flags.h b/rts/include/rts/Flags.h index e4405463311d625667b676ea195c6505efaa6248..5ef7273aace5465aad6493737b51383bd1500253 100644 --- a/rts/include/rts/Flags.h +++ b/rts/include/rts/Flags.h @@ -49,6 +49,7 @@ typedef struct _GC_FLAGS { uint32_t minOldGenSize; /* in *blocks* */ uint32_t heapSizeSuggestion; /* in *blocks* */ bool heapSizeSuggestionAuto; + bool arbitraryHeapStart; double oldGenFactor; double returnDecayFactor; double pcFreeHeap; diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c index a6eabfcdeedc3cfd69271d74ca791bc03f01a163..c9ad67d2a7253b15782b9b4d01d56f05bae03416 100644 --- a/rts/posix/OSMem.c +++ b/rts/posix/OSMem.c @@ -608,9 +608,11 @@ void *osReserveHeapMemory(void *startAddressPtr, W_ *len) // physical memory but a 511GB ulimit). See #14492. *len -= *len / 8; // debugBelch("Limit hit, reduced len: %zu\n", *len); - } else if ((W_)at >= minimumAddress) { + } else if (RtsFlags.GcFlags.arbitraryHeapStart || (W_)at >= minimumAddress) { // Success! We were given a block of memory starting above the 8 GB // mark, which is what we were looking for. + // Or we allow to allocate the block anywhere by setting + // arbitraryHeapStart flag. break; } else {