On memory-constrained iOS devices, reduce the rate at which the JS heap grows before...
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Aug 2017 18:15:14 +0000 (18:15 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Aug 2017 18:15:14 +0000 (18:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175041
<rdar://problem/33659370>

Reviewed by Filip Pizlo.

The testing I have done shows that this new function is a ~10%
progression running JetStream on 1GB iOS devices. I've also tried
this on a few > 1GB iOS devices, and the testing shows this is either neutral
or a regression. Right now, we'll just enable this for <= 1GB devices
since it's a win. In the future, we might want to either look into
tweaking these parameters or coming up with a new function for > 1GB
devices.

* heap/Heap.cpp:
* runtime/Options.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220144 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/runtime/Options.h

index deef0f6..1d7dff6 100644 (file)
@@ -1,3 +1,22 @@
+2017-08-02  Saam Barati  <sbarati@apple.com>
+
+        On memory-constrained iOS devices, reduce the rate at which the JS heap grows before a GC to try to keep more memory available for the system
+        https://bugs.webkit.org/show_bug.cgi?id=175041
+        <rdar://problem/33659370>
+
+        Reviewed by Filip Pizlo.
+
+        The testing I have done shows that this new function is a ~10%
+        progression running JetStream on 1GB iOS devices. I've also tried
+        this on a few > 1GB iOS devices, and the testing shows this is either neutral
+        or a regression. Right now, we'll just enable this for <= 1GB devices
+        since it's a win. In the future, we might want to either look into
+        tweaking these parameters or coming up with a new function for > 1GB
+        devices.
+
+        * heap/Heap.cpp:
+        * runtime/Options.h:
+
 2017-08-01  Filip Pizlo  <fpizlo@apple.com>
 
         Bmalloc and GC should put auxiliaries (butterflies, typed array backing stores) in a gigacage (separate multi-GB VM region)
index b2a97ce..23f3336 100644 (file)
@@ -71,6 +71,7 @@
 #include <algorithm>
 #if PLATFORM(IOS)
 #include <bmalloc/bmalloc.h>
+#include <sys/sysctl.h>
 #endif
 #include <wtf/CurrentTime.h>
 #include <wtf/ListDump.h>
@@ -116,9 +117,39 @@ size_t minHeapSize(HeapType heapType, size_t ramSize)
     return Options::smallHeapSize();
 }
 
+#if PLATFORM(IOS)
+static bool useAggressiveGCTrigger()
+{
+    static bool useAggressiveGCTrigger;
+    static std::once_flag once;
+    std::call_once(once, [] {
+        useAggressiveGCTrigger = false;
+
+        if (Options::forceAggressiveGCTrigger()) {
+            useAggressiveGCTrigger = true;
+            return;
+        }
+
+        uint64_t memSizeInBytes;
+        size_t sizeofMemSize = sizeof(memSizeInBytes);
+        if (sysctlbyname("hw.memsize", &memSizeInBytes, &sizeofMemSize, nullptr, 0))
+            return;
+        useAggressiveGCTrigger = memSizeInBytes <= 1 * GB;
+    });
+
+    return useAggressiveGCTrigger;
+}
+#endif
+
 size_t proportionalHeapSize(size_t heapSize, size_t ramSize)
 {
 #if PLATFORM(IOS)
+    if (useAggressiveGCTrigger()) {
+        double memoryUsed = bmalloc::api::percentAvailableMemoryInUse();
+        double result = ((1 - memoryUsed) / Options::aggressiveGCTriggerScalingValue()) + 1;
+        return heapSize * std::max(std::min(result, Options::aggressiveGCTriggerMaxMultiplier()), Options::aggressiveGCTriggerMinMultiplier());
+    }
+
     size_t memoryFootprint = bmalloc::api::memoryFootprint();
     if (memoryFootprint < ramSize * Options::smallHeapRAMFraction())
         return Options::smallHeapGrowthFactor() * heapSize;
index fefe14e..cf9e177 100644 (file)
@@ -210,6 +210,10 @@ typedef const char* optionString;
     v(double, mediumHeapRAMFraction, 0.5, Normal, nullptr) \
     v(double, mediumHeapGrowthFactor, 1.5, Normal, nullptr) \
     v(double, largeHeapGrowthFactor, 1.24, Normal, nullptr) \
+    v(bool, forceAggressiveGCTrigger, false, Normal, "If true, on iOS, we will use a different formula for proportionalHeapSize().") \
+    v(double, aggressiveGCTriggerMinMultiplier, 1.07, Normal, "This is the minimum we must grow by for proportionalHeapSize() when doing aggressive triggering.") \
+    v(double, aggressiveGCTriggerMaxMultiplier, 2.0, Normal,  "This is the maximum we can grow by for proportionalHeapSize() when doing aggressive triggering.") \
+    v(double, aggressiveGCTriggerScalingValue, 3.5, Normal, "This scales the above formula. A larger number is more aggressive in limiting heap growth. A smaller number is more permissive in allowing heap growth.") \
     v(double, criticalGCMemoryThreshold, 0.80, Normal, "percent memory in use the GC considers critical.  The collector is much more aggressive above this threshold") \
     v(double, minimumMutatorUtilization, 0, Normal, nullptr) \
     v(double, maximumMutatorUtilization, 0.7, Normal, nullptr) \