Use SPI to compute the jetsam limit on iOS instead of hardcoding 840MB
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jul 2018 20:35:05 +0000 (20:35 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jul 2018 20:35:05 +0000 (20:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188091
<rdar://problem/42647697>

Reviewed by Simon Fraser.

Source/bmalloc:

We want bmalloc to dynamically adapt to the jetsam limit of the process
it's running in. WTF::ramSize() is based off bmalloc's availableMemory,
so it will now reflect the result of the real jetsam limit when we can
read it.

Reading the jetsam limit requires an entitlement, so this patch opts in
the WebContent/Storage/Network processes. We fall back to 840MB (the
old hard coded value) when the SPI call fails (e.g, when we're in a
process without the proper entitlement).

* bmalloc.xcodeproj/project.pbxproj:
* bmalloc/AvailableMemory.cpp:
(bmalloc::jetsamLimit):
(bmalloc::computeAvailableMemory):
* bmalloc/darwin/MemoryStatusSPI.h: Added.

Source/WebKit:

Give the Network/Storage/WebContent process the com.apple.private.memorystatus
entitlement. This allows them to read the process jetsam limit.

* Configurations/Databases-iOS.entitlements:
* Configurations/Network-iOS.entitlements:
* Configurations/WebContent-iOS.entitlements:

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

Source/WebKit/ChangeLog
Source/WebKit/Configurations/Databases-iOS.entitlements
Source/WebKit/Configurations/Network-iOS.entitlements
Source/WebKit/Configurations/WebContent-iOS.entitlements
Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc.xcodeproj/project.pbxproj
Source/bmalloc/bmalloc/AvailableMemory.cpp
Source/bmalloc/bmalloc/darwin/MemoryStatusSPI.h [new file with mode: 0644]

index 5f70f15..2f47af0 100644 (file)
@@ -1,3 +1,18 @@
+2018-07-27  Saam Barati  <sbarati@apple.com>
+
+        Use SPI to compute the jetsam limit on iOS instead of hardcoding 840MB
+        https://bugs.webkit.org/show_bug.cgi?id=188091
+        <rdar://problem/42647697>
+
+        Reviewed by Simon Fraser.
+
+        Give the Network/Storage/WebContent process the com.apple.private.memorystatus
+        entitlement. This allows them to read the process jetsam limit.
+
+        * Configurations/Databases-iOS.entitlements:
+        * Configurations/Network-iOS.entitlements:
+        * Configurations/WebContent-iOS.entitlements:
+
 2018-07-03  David Fenton  <david_fenton@apple.com>
 
         Unreviewed, rolling out r233461.
index b317c3a..37475ee 100644 (file)
@@ -6,5 +6,7 @@
        <array>
                <string>com.apple.WebKit.Storage</string>
        </array>
+       <key>com.apple.private.memorystatus</key>
+       <true/>
 </dict>
 </plist>
index 0124754..cc96c82 100644 (file)
@@ -16,5 +16,7 @@
        <array>
                <string>com.apple.WebKit.Networking</string>
        </array>
+       <key>com.apple.private.memorystatus</key>
+       <true/>
 </dict>
 </plist>
index ea00b0e..c4d0967 100644 (file)
@@ -29,5 +29,7 @@
                <string>kTCCServiceMicrophone</string>
                <string>kTCCServiceCamera</string>
        </array>
+       <key>com.apple.private.memorystatus</key>
+       <true/>
 </dict>
 </plist>
index 19ed955..e4d5bec 100644 (file)
@@ -1,3 +1,27 @@
+2018-07-27  Saam Barati  <sbarati@apple.com>
+
+        Use SPI to compute the jetsam limit on iOS instead of hardcoding 840MB
+        https://bugs.webkit.org/show_bug.cgi?id=188091
+        <rdar://problem/42647697>
+
+        Reviewed by Simon Fraser.
+
+        We want bmalloc to dynamically adapt to the jetsam limit of the process
+        it's running in. WTF::ramSize() is based off bmalloc's availableMemory,
+        so it will now reflect the result of the real jetsam limit when we can
+        read it.
+        
+        Reading the jetsam limit requires an entitlement, so this patch opts in
+        the WebContent/Storage/Network processes. We fall back to 840MB (the
+        old hard coded value) when the SPI call fails (e.g, when we're in a
+        process without the proper entitlement).
+
+        * bmalloc.xcodeproj/project.pbxproj:
+        * bmalloc/AvailableMemory.cpp:
+        (bmalloc::jetsamLimit):
+        (bmalloc::computeAvailableMemory):
+        * bmalloc/darwin/MemoryStatusSPI.h: Added.
+
 2018-07-24  Saam Barati  <sbarati@apple.com>
 
         Revert back to using phys_footprint to calculate isUnderMemoryPressure()
index 7d18ef5..66d4067 100644 (file)
                4426E2801C838EE0008EB042 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4426E27E1C838EE0008EB042 /* Logging.cpp */; };
                4426E2811C838EE0008EB042 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E27F1C838EE0008EB042 /* Logging.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4426E2831C839547008EB042 /* BSoftLinking.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E2821C839547008EB042 /* BSoftLinking.h */; };
+               52F47249210BA30200B730BB /* MemoryStatusSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F47248210BA2F500B730BB /* MemoryStatusSPI.h */; };
                6543DDB420EEAEF3003B23D8 /* PerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6543DDB320EEAEF3003B23D8 /* PerThread.cpp */; };
                6599C5CC1EC3F15900A2F7BB /* AvailableMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6599C5CA1EC3F15900A2F7BB /* AvailableMemory.cpp */; };
                6599C5CD1EC3F15900A2F7BB /* AvailableMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 6599C5CB1EC3F15900A2F7BB /* AvailableMemory.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4426E27E1C838EE0008EB042 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logging.cpp; path = bmalloc/Logging.cpp; sourceTree = "<group>"; };
                4426E27F1C838EE0008EB042 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = bmalloc/Logging.h; sourceTree = "<group>"; };
                4426E2821C839547008EB042 /* BSoftLinking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BSoftLinking.h; path = bmalloc/darwin/BSoftLinking.h; sourceTree = "<group>"; };
+               52F47248210BA2F500B730BB /* MemoryStatusSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemoryStatusSPI.h; path = bmalloc/darwin/MemoryStatusSPI.h; sourceTree = "<group>"; };
                6543DDB320EEAEF3003B23D8 /* PerThread.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PerThread.cpp; path = bmalloc/PerThread.cpp; sourceTree = "<group>"; };
                6599C5CA1EC3F15900A2F7BB /* AvailableMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AvailableMemory.cpp; path = bmalloc/AvailableMemory.cpp; sourceTree = "<group>"; };
                6599C5CB1EC3F15900A2F7BB /* AvailableMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AvailableMemory.h; path = bmalloc/AvailableMemory.h; sourceTree = "<group>"; };
                4408F2961C9896C40012EC64 /* darwin */ = {
                        isa = PBXGroup;
                        children = (
+                               52F47248210BA2F500B730BB /* MemoryStatusSPI.h */,
                                4426E2821C839547008EB042 /* BSoftLinking.h */,
                        );
                        name = darwin;
                                0F5BF1731F23C5710029D91D /* BExport.h in Headers */,
                                14DD78C918F48D7500950702 /* BInline.h in Headers */,
                                0F7EB84C1F9541C700F1ABCB /* Bits.h in Headers */,
+                               52F47249210BA30200B730BB /* MemoryStatusSPI.h in Headers */,
                                1448C30118F3754C00502839 /* bmalloc.h in Headers */,
                                0F7EB84D1F9541C700F1ABCB /* BMalloced.h in Headers */,
                                14C919C918FCC59F0028DB43 /* BPlatform.h in Headers */,
index 5263e5e..1ef3d89 100644 (file)
@@ -26,6 +26,9 @@
 #include "AvailableMemory.h"
 
 #include "Environment.h"
+#if BPLATFORM(IOS)
+#include "MemoryStatusSPI.h"
+#endif
 #include "PerProcess.h"
 #include "Scavenger.h"
 #include "Sizes.h"
@@ -72,12 +75,23 @@ static size_t memorySizeAccordingToKernel()
 }
 #endif
 
+#if BPLATFORM(IOS)
+static size_t jetsamLimit()
+{
+    memorystatus_memlimit_properties_t properties;
+    pid_t pid = getpid();
+    if (memorystatus_control(MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES, pid, 0, &properties, sizeof(properties)))
+        return 840 * bmalloc::MB;
+    return static_cast<size_t>(properties.memlimit_active) * bmalloc::MB;
+}
+#endif
+
 static size_t computeAvailableMemory()
 {
 #if BOS(DARWIN)
     size_t sizeAccordingToKernel = memorySizeAccordingToKernel();
 #if BPLATFORM(IOS)
-    sizeAccordingToKernel = std::min(sizeAccordingToKernel, 840 * bmalloc::MB);
+    sizeAccordingToKernel = std::min(sizeAccordingToKernel, jetsamLimit());
 #endif
     size_t multiple = 128 * bmalloc::MB;
 
diff --git a/Source/bmalloc/bmalloc/darwin/MemoryStatusSPI.h b/Source/bmalloc/bmalloc/darwin/MemoryStatusSPI.h
new file mode 100644 (file)
index 0000000..7255eb6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BPlatform.h"
+
+#if BPLATFORM(IOS)
+
+#if __has_include(<System/sys/kern_memorystatus.h>)
+extern "C" {
+#include <System/sys/kern_memorystatus.h>
+}
+#else
+extern "C" {
+
+typedef struct memorystatus_memlimit_properties {
+    int32_t memlimit_active;                /* jetsam memory limit (in MB) when process is active */
+    uint32_t memlimit_active_attr;
+    int32_t memlimit_inactive;              /* jetsam memory limit (in MB) when process is inactive */
+    uint32_t memlimit_inactive_attr;
+} memorystatus_memlimit_properties_t;
+
+#define MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES 8
+
+}
+#endif // __has_include(<System/sys/kern_memorystatus.h>)
+
+extern "C" {
+int memorystatus_control(uint32_t command, int32_t pid, uint32_t flags, void *buffer, size_t buffersize);
+}
+
+#endif // BPLATFORM(IOS)