Title: [280155] trunk
Revision
280155
Author
[email protected]
Date
2021-07-21 13:10:49 -0700 (Wed, 21 Jul 2021)

Log Message

[GTK][WPE] Allow the user to configure the MemoryPressureHandler inside the web process
https://bugs.webkit.org/show_bug.cgi?id=222738

Reviewed by Carlos Garcia Campos.

Source/WebCore:

MemoryPressureHandler::currentMemoryUsagePolicy() is now an instance method and not a class one,
so update the call in RenderLayerCompositor to use the singleton instance.

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateCompositingPolicy):

Source/WebKit:

Add a new API type WebKitMemoryPressureSettings that can be used to configure the behavior
of the MemoryPressureHandler. Add a property to WebKitWebContext that can be used to pass
new settings to it, and store them inside its API::ProcessPoolConfiguration. Those settings
will be set to new web processes during the platform initialization stage.

* PlatformGTK.cmake:
* PlatformWPE.cmake:
* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):
* Shared/WebProcessCreationParameters.h:
* SourcesGTK.txt:
* SourcesWPE.txt:
* UIProcess/API/APIProcessPoolConfiguration.cpp:
(API::ProcessPoolConfiguration::copy):
* UIProcess/API/APIProcessPoolConfiguration.h:
* UIProcess/API/glib/WebKitMemoryPressureSettings.cpp: Added.
(webkit_memory_pressure_settings_new):
(webkit_memory_pressure_settings_copy):
(webkit_memory_pressure_settings_free):
(webkit_memory_pressure_settings_set_memory_limit):
(webkit_memory_pressure_settings_get_memory_limit):
(webkit_memory_pressure_settings_set_conservative_threshold):
(webkit_memory_pressure_settings_get_conservative_threshold):
(webkit_memory_pressure_settings_set_strict_threshold):
(webkit_memory_pressure_settings_get_strict_threshold):
(webkit_memory_pressure_settings_set_kill_threshold):
(webkit_memory_pressure_settings_get_kill_threshold):
(webkit_memory_pressure_settings_set_poll_interval):
(webkit_memory_pressure_settings_get_poll_interval):
(webkitMemoryPressureSettingsGetMemoryPressureHandlerConfiguration):
* UIProcess/API/glib/WebKitMemoryPressureSettingsPrivate.h: Added.
* UIProcess/API/glib/WebKitWebContext.cpp:
(webkitWebContextSetProperty):
(webkitWebContextConstructed):
(webkit_web_context_class_init):
* UIProcess/API/gtk/WebKitAutocleanups.h:
* UIProcess/API/gtk/WebKitMemoryPressureSettings.h: Added.
* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
* UIProcess/API/gtk/webkit2.h:
* UIProcess/API/wpe/WebKitAutocleanups.h:
* UIProcess/API/wpe/WebKitMemoryPressureSettings.h: Added.
* UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
* UIProcess/API/wpe/webkit.h:
* UIProcess/glib/WebProcessPoolGLib.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess):
* WebProcess/glib/WebProcessGLib.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):

Source/WTF:

Add a configuration structure to MemoryPressureHandler, with the methods to encode/decode it. Also
add a method to set a configuration structure to a MemoryPressureHandler instance, and modify the
behavior so the the configuration is used when checking the memory used by the process.

* wtf/MemoryPressureHandler.cpp:
(WTF::MemoryPressureHandler::setShouldUsePeriodicMemoryMonitor):
(WTF::MemoryPressureHandler::thresholdForMemoryKill):
(WTF::MemoryPressureHandler::thresholdForPolicy):
(WTF::MemoryPressureHandler::policyForFootprint):
(WTF::MemoryPressureHandler::Configuration::Configuration):
* wtf/MemoryPressureHandler.h:
(WTF::MemoryPressureHandler::Configuration::encode const):
(WTF::MemoryPressureHandler::Configuration::decode):
(WTF::MemoryPressureHandler::setConfiguration):

Tools:

Add a test for WebKitMemoryPressureSettings API and to test WebKitWebContext with
non default WebKitMemoryPressureSettings values.

* TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp:
(MemoryPressureTest::setup):
(MemoryPressureTest::teardown):
(MemoryPressureTest::webProcessTerminatedCallback):
(MemoryPressureTest::waitUntilWebProcessTerminated):
(testMemoryPressureSettings):
(beforeAll):
* TestWebKitAPI/glib/WebKitGLib/TestMain.cpp:
* TestWebKitAPI/glib/WebKitGLib/TestMain.h:
(Test::Test):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (280154 => 280155)


--- trunk/Source/WTF/ChangeLog	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WTF/ChangeLog	2021-07-21 20:10:49 UTC (rev 280155)
@@ -1,3 +1,25 @@
+2021-07-21  Miguel Gomez  <[email protected]>
+
+        [GTK][WPE] Allow the user to configure the MemoryPressureHandler inside the web process
+        https://bugs.webkit.org/show_bug.cgi?id=222738
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add a configuration structure to MemoryPressureHandler, with the methods to encode/decode it. Also
+        add a method to set a configuration structure to a MemoryPressureHandler instance, and modify the
+        behavior so the the configuration is used when checking the memory used by the process.
+
+        * wtf/MemoryPressureHandler.cpp:
+        (WTF::MemoryPressureHandler::setShouldUsePeriodicMemoryMonitor):
+        (WTF::MemoryPressureHandler::thresholdForMemoryKill):
+        (WTF::MemoryPressureHandler::thresholdForPolicy):
+        (WTF::MemoryPressureHandler::policyForFootprint):
+        (WTF::MemoryPressureHandler::Configuration::Configuration):
+        * wtf/MemoryPressureHandler.h:
+        (WTF::MemoryPressureHandler::Configuration::encode const):
+        (WTF::MemoryPressureHandler::Configuration::decode):
+        (WTF::MemoryPressureHandler::setConfiguration):
+
 2021-07-21  Chris Dumez  <[email protected]>
 
         Unreviewed, reverting r280129.

Modified: trunk/Source/WTF/wtf/MemoryPressureHandler.cpp (280154 => 280155)


--- trunk/Source/WTF/wtf/MemoryPressureHandler.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WTF/wtf/MemoryPressureHandler.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -38,6 +38,16 @@
 
 WTF_EXPORT_PRIVATE bool MemoryPressureHandler::ReliefLogger::s_loggingEnabled = false;
 
+#if PLATFORM(IOS_FAMILY)
+static const double s_conservativeThresholdFraction = 0.5;
+static const double s_strictThresholdFraction = 0.65;
+#else
+static const double s_conservativeThresholdFraction = 0.33;
+static const double s_strictThresholdFraction = 0.5;
+#endif
+static const std::optional<double> s_killThresholdFraction;
+static const Seconds s_pollInterval = 30_s;
+
 MemoryPressureHandler& MemoryPressureHandler::singleton()
 {
     static LazyNeverDestroyed<MemoryPressureHandler> memoryPressureHandler;
@@ -73,7 +83,7 @@
 
     if (use) {
         m_measurementTimer = makeUnique<RunLoop::Timer<MemoryPressureHandler>>(RunLoop::main(), this, &MemoryPressureHandler::measurementTimerFired);
-        m_measurementTimer->startRepeating(30_s);
+        m_measurementTimer->startRepeating(m_configuration.pollInterval);
     } else
         m_measurementTimer = nullptr;
 }
@@ -110,6 +120,9 @@
 
 std::optional<size_t> MemoryPressureHandler::thresholdForMemoryKill()
 {
+    if (m_configuration.killThresholdFraction)
+        return m_configuration.baseThreshold * (*m_configuration.killThresholdFraction);
+
     switch (m_processState) {
     case WebsamProcessState::Inactive:
         return thresholdForMemoryKillOfInactiveProcess(m_pageCount);
@@ -119,25 +132,15 @@
     return std::nullopt;
 }
 
-static size_t thresholdForPolicy(MemoryUsagePolicy policy)
+size_t MemoryPressureHandler::thresholdForPolicy(MemoryUsagePolicy policy)
 {
-    const size_t baseThresholdForPolicy = std::min(3 * GB, ramSize());
-
-#if PLATFORM(IOS_FAMILY)
-    const double conservativeThresholdFraction = 0.5;
-    const double strictThresholdFraction = 0.65;
-#else
-    const double conservativeThresholdFraction = 0.33;
-    const double strictThresholdFraction = 0.5;
-#endif
-
     switch (policy) {
     case MemoryUsagePolicy::Unrestricted:
         return 0;
     case MemoryUsagePolicy::Conservative:
-        return baseThresholdForPolicy * conservativeThresholdFraction;
+        return m_configuration.baseThreshold * m_configuration.conservativeThresholdFraction;
     case MemoryUsagePolicy::Strict:
-        return baseThresholdForPolicy * strictThresholdFraction;
+        return m_configuration.baseThreshold * m_configuration.strictThresholdFraction;
     default:
         ASSERT_NOT_REACHED();
         return 0;
@@ -144,7 +147,7 @@
     }
 }
 
-static MemoryUsagePolicy policyForFootprint(size_t footprint)
+MemoryUsagePolicy MemoryPressureHandler::policyForFootprint(size_t footprint)
 {
     if (footprint >= thresholdForPolicy(MemoryUsagePolicy::Strict))
         return MemoryUsagePolicy::Strict;
@@ -316,4 +319,22 @@
 }
 #endif
 
+MemoryPressureHandler::Configuration::Configuration()
+    : baseThreshold(std::min(3 * GB, ramSize()))
+    , conservativeThresholdFraction(s_conservativeThresholdFraction)
+    , strictThresholdFraction(s_strictThresholdFraction)
+    , killThresholdFraction(s_killThresholdFraction)
+    , pollInterval(s_pollInterval)
+{
+}
+
+MemoryPressureHandler::Configuration::Configuration(size_t base, double conservative, double strict, std::optional<double> kill, Seconds interval)
+    : baseThreshold(base)
+    , conservativeThresholdFraction(conservative)
+    , strictThresholdFraction(strict)
+    , killThresholdFraction(kill)
+    , pollInterval(interval)
+{
+}
+
 } // namespace WebCore

Modified: trunk/Source/WTF/wtf/MemoryPressureHandler.h (280154 => 280155)


--- trunk/Source/WTF/wtf/MemoryPressureHandler.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WTF/wtf/MemoryPressureHandler.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -93,7 +93,7 @@
     bool isSimulatingMemoryPressure() const { return m_isSimulatingMemoryPressure; }
     void setUnderMemoryPressure(bool);
 
-    WTF_EXPORT_PRIVATE static MemoryUsagePolicy currentMemoryUsagePolicy();
+    WTF_EXPORT_PRIVATE MemoryUsagePolicy currentMemoryUsagePolicy();
 
 #if PLATFORM(COCOA)
     WTF_EXPORT_PRIVATE void setDispatchQueue(OSObjectPtr<dispatch_queue_t>&&);
@@ -147,6 +147,59 @@
         WTF_EXPORT_PRIVATE static bool s_loggingEnabled;
     };
 
+    struct Configuration {
+        WTF_MAKE_STRUCT_FAST_ALLOCATED;
+        WTF_EXPORT_PRIVATE Configuration();
+        WTF_EXPORT_PRIVATE Configuration(size_t, double, double, std::optional<double>, Seconds);
+
+        template<class Encoder> void encode(Encoder& encoder) const
+        {
+            encoder << baseThreshold;
+            encoder << conservativeThresholdFraction;
+            encoder << strictThresholdFraction;
+            encoder << killThresholdFraction;
+            encoder << pollInterval;
+        }
+
+        template<class Decoder>
+        static std::optional<Configuration> decode(Decoder& decoder)
+        {
+            std::optional<size_t> baseThreshold;
+            decoder >> baseThreshold;
+            if (!baseThreshold)
+                return std::nullopt;
+
+            std::optional<double> conservativeThresholdFraction;
+            decoder >> conservativeThresholdFraction;
+            if (!conservativeThresholdFraction)
+                return std::nullopt;
+
+            std::optional<double> strictThresholdFraction;
+            decoder >> strictThresholdFraction;
+            if (!strictThresholdFraction)
+                return std::nullopt;
+
+            std::optional<std::optional<double>> killThresholdFraction;
+            decoder >> killThresholdFraction;
+            if (!killThresholdFraction)
+                return std::nullopt;
+
+            std::optional<Seconds> pollInterval;
+            decoder >> pollInterval;
+            if (!pollInterval)
+                return std::nullopt;
+
+            return {{ *baseThreshold, *conservativeThresholdFraction, *strictThresholdFraction, *killThresholdFraction, *pollInterval }};
+        }
+
+        size_t baseThreshold;
+        double conservativeThresholdFraction;
+        double strictThresholdFraction;
+        std::optional<double> killThresholdFraction;
+        Seconds pollInterval;
+    };
+    void setConfiguration(Configuration&& configuration) { m_configuration = WTFMove(configuration); }
+
     WTF_EXPORT_PRIVATE void releaseMemory(Critical, Synchronous = Synchronous::No);
 
     WTF_EXPORT_PRIVATE void beginSimulatedMemoryPressure();
@@ -161,6 +214,9 @@
 
 private:
     std::optional<size_t> thresholdForMemoryKill();
+    size_t thresholdForPolicy(MemoryUsagePolicy);
+    MemoryUsagePolicy policyForFootprint(size_t);
+
     void memoryPressureStatusChanged();
 
     void uninstall();
@@ -198,6 +254,8 @@
     WTF::Function<void()> m_didExceedInactiveLimitWhileActiveCallback;
     LowMemoryHandler m_lowMemoryHandler;
 
+    Configuration m_configuration;
+
 #if OS(WINDOWS)
     void windowsMeasurementTimerFired();
     RunLoop::Timer<MemoryPressureHandler> m_windowsMeasurementTimer;

Modified: trunk/Source/WebCore/ChangeLog (280154 => 280155)


--- trunk/Source/WebCore/ChangeLog	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebCore/ChangeLog	2021-07-21 20:10:49 UTC (rev 280155)
@@ -1,3 +1,16 @@
+2021-07-21  Miguel Gomez  <[email protected]>
+
+        [GTK][WPE] Allow the user to configure the MemoryPressureHandler inside the web process
+        https://bugs.webkit.org/show_bug.cgi?id=222738
+
+        Reviewed by Carlos Garcia Campos.
+
+        MemoryPressureHandler::currentMemoryUsagePolicy() is now an instance method and not a class one,
+        so update the call in RenderLayerCompositor to use the singleton instance.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateCompositingPolicy):
+
 2021-07-21  Chris Dumez  <[email protected]>
 
         Unreviewed, reverting r280129.

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (280154 => 280155)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -526,7 +526,7 @@
     static constexpr auto memoryPolicyCachingDuration = 2_s;
     auto now = MonotonicTime::now();
     if (now - cachedMemoryPolicyTime > memoryPolicyCachingDuration) {
-        cachedMemoryPolicy = MemoryPressureHandler::currentMemoryUsagePolicy();
+        cachedMemoryPolicy = MemoryPressureHandler::singleton().currentMemoryUsagePolicy();
         cachedMemoryPolicyTime = now;
     }
 

Modified: trunk/Source/WebKit/ChangeLog (280154 => 280155)


--- trunk/Source/WebKit/ChangeLog	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/ChangeLog	2021-07-21 20:10:49 UTC (rev 280155)
@@ -1,3 +1,59 @@
+2021-07-21  Miguel Gomez  <[email protected]>
+
+        [GTK][WPE] Allow the user to configure the MemoryPressureHandler inside the web process
+        https://bugs.webkit.org/show_bug.cgi?id=222738
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add a new API type WebKitMemoryPressureSettings that can be used to configure the behavior
+        of the MemoryPressureHandler. Add a property to WebKitWebContext that can be used to pass
+        new settings to it, and store them inside its API::ProcessPoolConfiguration. Those settings
+        will be set to new web processes during the platform initialization stage.
+
+        * PlatformGTK.cmake:
+        * PlatformWPE.cmake:
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode const):
+        (WebKit::WebProcessCreationParameters::decode):
+        * Shared/WebProcessCreationParameters.h:
+        * SourcesGTK.txt:
+        * SourcesWPE.txt:
+        * UIProcess/API/APIProcessPoolConfiguration.cpp:
+        (API::ProcessPoolConfiguration::copy):
+        * UIProcess/API/APIProcessPoolConfiguration.h:
+        * UIProcess/API/glib/WebKitMemoryPressureSettings.cpp: Added.
+        (webkit_memory_pressure_settings_new):
+        (webkit_memory_pressure_settings_copy):
+        (webkit_memory_pressure_settings_free):
+        (webkit_memory_pressure_settings_set_memory_limit):
+        (webkit_memory_pressure_settings_get_memory_limit):
+        (webkit_memory_pressure_settings_set_conservative_threshold):
+        (webkit_memory_pressure_settings_get_conservative_threshold):
+        (webkit_memory_pressure_settings_set_strict_threshold):
+        (webkit_memory_pressure_settings_get_strict_threshold):
+        (webkit_memory_pressure_settings_set_kill_threshold):
+        (webkit_memory_pressure_settings_get_kill_threshold):
+        (webkit_memory_pressure_settings_set_poll_interval):
+        (webkit_memory_pressure_settings_get_poll_interval):
+        (webkitMemoryPressureSettingsGetMemoryPressureHandlerConfiguration):
+        * UIProcess/API/glib/WebKitMemoryPressureSettingsPrivate.h: Added.
+        * UIProcess/API/glib/WebKitWebContext.cpp:
+        (webkitWebContextSetProperty):
+        (webkitWebContextConstructed):
+        (webkit_web_context_class_init):
+        * UIProcess/API/gtk/WebKitAutocleanups.h:
+        * UIProcess/API/gtk/WebKitMemoryPressureSettings.h: Added.
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+        * UIProcess/API/gtk/webkit2.h:
+        * UIProcess/API/wpe/WebKitAutocleanups.h:
+        * UIProcess/API/wpe/WebKitMemoryPressureSettings.h: Added.
+        * UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
+        * UIProcess/API/wpe/webkit.h:
+        * UIProcess/glib/WebProcessPoolGLib.cpp:
+        (WebKit::WebProcessPool::platformInitializeWebProcess):
+        * WebProcess/glib/WebProcessGLib.cpp:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+
 2021-07-21  Aditya Keerthi  <[email protected]>
 
         Crash in -[WKWebView takeSnapshotWithConfiguration:completionHandler:] when taking empty snapshots

Modified: trunk/Source/WebKit/PlatformGTK.cmake (280154 => 280155)


--- trunk/Source/WebKit/PlatformGTK.cmake	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/PlatformGTK.cmake	2021-07-21 20:10:49 UTC (rev 280155)
@@ -112,6 +112,7 @@
     ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h
     ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitJavascriptResult.h
     ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitMediaKeySystemPermissionRequest.h
+    ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitMemoryPressureSettings.h
     ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitMimeInfo.h
     ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitNavigationAction.h
     ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h

Modified: trunk/Source/WebKit/PlatformWPE.cmake (280154 => 280155)


--- trunk/Source/WebKit/PlatformWPE.cmake	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/PlatformWPE.cmake	2021-07-21 20:10:49 UTC (rev 280155)
@@ -144,6 +144,7 @@
     ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitInstallMissingMediaPluginsPermissionRequest.h
     ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitJavascriptResult.h
     ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitMediaKeySystemPermissionRequest.h
+    ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitMemoryPressureSettings.h
     ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitMimeInfo.h
     ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitNavigationAction.h
     ${WEBKIT_DIR}/UIProcess/API/wpe/WebKitNavigationPolicyDecision.h

Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp (280154 => 280155)


--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -208,6 +208,10 @@
 #endif
 
     encoder << accessibilityPreferences;
+
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    encoder << memoryPressureHandlerConfiguration;
+#endif
 }
 
 bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreationParameters& parameters)
@@ -569,6 +573,14 @@
         return false;
     parameters.accessibilityPreferences = WTFMove(*accessibilityPreferences);
 
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    std::optional<std::optional<MemoryPressureHandler::Configuration>> memoryPressureHandlerConfiguration;
+    decoder >> memoryPressureHandlerConfiguration;
+    if (!memoryPressureHandlerConfiguration)
+        return false;
+    parameters.memoryPressureHandlerConfiguration = WTFMove(*memoryPressureHandlerConfiguration);
+#endif
+
     return true;
 }
 

Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.h (280154 => 280155)


--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -52,6 +52,10 @@
 #include <WebCore/PluginData.h>
 #endif
 
+#if PLATFORM(GTK) || PLATFORM(WPE)
+#include <wtf/MemoryPressureHandler.h>
+#endif
+
 namespace API {
 class Data;
 }
@@ -249,6 +253,10 @@
 #endif
     
     AccessibilityPreferences accessibilityPreferences;
+
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    std::optional<MemoryPressureHandler::Configuration> memoryPressureHandlerConfiguration;
+#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/SourcesGTK.txt (280154 => 280155)


--- trunk/Source/WebKit/SourcesGTK.txt	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/SourcesGTK.txt	2021-07-21 20:10:49 UTC (rev 280155)
@@ -149,6 +149,7 @@
 UIProcess/API/glib/WebKitJavascriptResult.cpp @no-unify
 UIProcess/API/glib/WebKitMediaKeySystemPermissionRequest.cpp @no-unify
 UIProcess/API/glib/WebKitMimeInfo.cpp @no-unify
+UIProcess/API/glib/WebKitMemoryPressureSettings.cpp @no-unify
 UIProcess/API/glib/WebKitNavigationAction.cpp @no-unify
 UIProcess/API/glib/WebKitNavigationClient.cpp @no-unify
 UIProcess/API/glib/WebKitNavigationPolicyDecision.cpp @no-unify

Modified: trunk/Source/WebKit/SourcesWPE.txt (280154 => 280155)


--- trunk/Source/WebKit/SourcesWPE.txt	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/SourcesWPE.txt	2021-07-21 20:10:49 UTC (rev 280155)
@@ -139,6 +139,7 @@
 UIProcess/API/glib/WebKitInstallMissingMediaPluginsPermissionRequest.cpp @no-unify
 UIProcess/API/glib/WebKitJavascriptResult.cpp @no-unify
 UIProcess/API/glib/WebKitMediaKeySystemPermissionRequest.cpp @no-unify
+UIProcess/API/glib/WebKitMemoryPressureSettings.cpp @no-unify
 UIProcess/API/glib/WebKitMimeInfo.cpp @no-unify
 UIProcess/API/glib/WebKitNavigationAction.cpp @no-unify
 UIProcess/API/glib/WebKitNavigationClient.cpp @no-unify

Modified: trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -78,6 +78,9 @@
     copy->m_networkProcessPath = this->m_networkProcessPath;
     copy->m_userId = this->m_userId;
 #endif
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    copy->m_memoryPressureHandlerConfiguration = this->m_memoryPressureHandlerConfiguration;
+#endif
     return copy;
 }
 

Modified: trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -28,6 +28,7 @@
 #include "APIObject.h"
 #include "CacheModel.h"
 #include "WebsiteDataStore.h"
+#include <wtf/MemoryPressureHandler.h>
 #include <wtf/ProcessID.h>
 #include <wtf/Ref.h>
 #include <wtf/Vector.h>
@@ -153,6 +154,11 @@
     void setUserId(const int32_t userId) { m_userId = userId; }
 #endif
 
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    void setMemoryPressureHandlerConfiguration(const MemoryPressureHandler::Configuration& configuration) { m_memoryPressureHandlerConfiguration = configuration; }
+    const std::optional<MemoryPressureHandler::Configuration>& memoryPressureHandlerConfiguration() const { return m_memoryPressureHandlerConfiguration; }
+#endif
+
 private:
     WTF::String m_injectedBundlePath;
     Vector<WTF::String> m_customClassesForParameterCoder;
@@ -189,6 +195,9 @@
     WTF::String m_networkProcessPath;
     int32_t m_userId { -1 };
 #endif
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    std::optional<MemoryPressureHandler::Configuration> m_memoryPressureHandlerConfiguration;
+#endif
 };
 
 } // namespace API

Added: trunk/Source/WebKit/UIProcess/API/glib/WebKitMemoryPressureSettings.cpp (0 => 280155)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitMemoryPressureSettings.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitMemoryPressureSettings.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitMemoryPressureSettings.h"
+
+#include <wtf/MemoryPressureHandler.h>
+
+/**
+ * SECTION: WebKitMemoryPressureSettings
+ * @Short_description: A boxed type representing the settings for the MemoryPressureHandler
+ * @Title: WebKitMemoryPressureSettings
+ * @See_also: #WebKitWebContext.
+ *
+ * #WebKitMemoryPressureSettings is a boxed type that can be used to provide some custom settings
+ * to control how the memory pressure situations are handled by the different processes.
+ *
+ * The memory pressure system implemented inside the different process will try to keep the memory usage
+ * under the defined memory limit. In order to do that, it will check the used memory with a user defined
+ * frequency and decide whether it should try to release memory. The thresholds passed will define how urgent
+ * is to release that memory.
+ *
+ * Take into account that badly defined parameters can greatly reduce the performance of the engine. For
+ * example, setting memory limit too low with a fast poll interval can cause the process to constantly
+ * be trying to release memory.
+ *
+ * A #WebKitMemoryPressureSettings can be passed to a #WebKitWebContext constructor, and the settings will
+ * be applied to all the web processes created by that context.
+ *
+ * Since: 2.34
+ */
+struct _WebKitMemoryPressureSettings {
+    MemoryPressureHandler::Configuration configuration;
+};
+
+G_DEFINE_BOXED_TYPE(WebKitMemoryPressureSettings, webkit_memory_pressure_settings, webkit_memory_pressure_settings_copy, webkit_memory_pressure_settings_free);
+
+/**
+ * webkit_memory_pressure_settings_new:
+ *
+ * Create a new #WebKitMemoryPressureSettings with the default values.
+ *
+ * Returns: (transfer full): A new #WebKitMemoryPressureSettings instance filled with the default values.
+ *
+ * Since: 2.34
+ */
+WebKitMemoryPressureSettings* webkit_memory_pressure_settings_new()
+{
+    WebKitMemoryPressureSettings* memoryPressureSettings = static_cast<WebKitMemoryPressureSettings*>(fastMalloc(sizeof(WebKitMemoryPressureSettings)));
+    new (memoryPressureSettings) WebKitMemoryPressureSettings;
+
+    return memoryPressureSettings;
+}
+
+/**
+ * webkit_memory_pressure_settings_copy:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Make a copy of @settings.
+ *
+ * Returns: (transfer full): A copy of of the passed #WebKitMemoryPressureSettings.
+ *
+ * Since: 2.34
+ */
+WebKitMemoryPressureSettings* webkit_memory_pressure_settings_copy(WebKitMemoryPressureSettings* settings)
+{
+    g_return_val_if_fail(settings, nullptr);
+
+    WebKitMemoryPressureSettings* copy = static_cast<WebKitMemoryPressureSettings*>(fastZeroedMalloc(sizeof(WebKitMemoryPressureSettings)));
+
+    copy->configuration = settings->configuration;
+
+    return copy;
+}
+
+/**
+ * webkit_memory_pressure_settings_free:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Free the #WebKitMemoryPressureSettings.
+ *
+ * Since: 2.34
+ */
+void webkit_memory_pressure_settings_free(WebKitMemoryPressureSettings* settings)
+{
+    g_return_if_fail(settings);
+
+    fastFree(settings);
+}
+
+/**
+ * webkit_memory_pressure_settings_set_memory_limit:
+ * @settings: a #WebKitMemoryPressureSettings
+ * @memory_limit: amount of memory (in MB) that the process is allowed to use.
+ *
+ * Sets @memory_limit the memory limit value to @settings.
+ *
+ * The default value is the system's RAM size with a maximum of 3GB.
+ *
+ * Since: 2.34
+ */
+void webkit_memory_pressure_settings_set_memory_limit(WebKitMemoryPressureSettings* settings, guint memoryLimit)
+{
+    g_return_if_fail(settings);
+    g_return_if_fail(memoryLimit);
+
+    settings->configuration.baseThreshold = memoryLimit * MB;
+}
+
+/**
+ * webkit_memory_pressure_settings_get_memory_limit:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Returns: the value in MB of the memory limit inside @settings.
+ *
+ * Since: 2.34
+ */
+guint webkit_memory_pressure_settings_get_memory_limit(WebKitMemoryPressureSettings* settings)
+{
+    g_return_val_if_fail(settings, 0);
+
+    return settings->configuration.baseThreshold / MB;
+}
+
+/**
+ * webkit_memory_pressure_settings_set_conservative_threshold:
+ * @settings: a #WebKitMemoryPressureSettings
+ * @value: fraction of the memory limit where the conservative policy starts working.
+ *
+ * Sets @value as the fraction of the defined memory limit where the conservative
+ * policy starts working. This policy will try to reduce the memory footprint by
+ * releasing non critical memory.
+ *
+ * The threshold must be bigger than 0 and smaller than 1, and it must be smaller
+ * than the strict threshold defined in @settings. The default value is 0.33.
+ *
+ * Since: 2.34
+ */
+void webkit_memory_pressure_settings_set_conservative_threshold(WebKitMemoryPressureSettings* settings, gdouble value)
+{
+    g_return_if_fail(settings);
+    g_return_if_fail(value > 0 && value < 1);
+    g_return_if_fail(value < settings->configuration.strictThresholdFraction);
+
+    settings->configuration.conservativeThresholdFraction = value;
+}
+
+/**
+ * webkit_memory_pressure_settings_get_conservative_threshold:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Returns: the value of the the conservative threshold inside @settings.
+ *
+ * Since: 2.34
+ */
+gdouble webkit_memory_pressure_settings_get_conservative_threshold(WebKitMemoryPressureSettings* settings)
+{
+    g_return_val_if_fail(settings, 0);
+
+    return settings->configuration.conservativeThresholdFraction;
+}
+
+/**
+ * webkit_memory_pressure_settings_set_strict_threshold:
+ * @settings: a #WebKitMemoryPressureSettings
+ * @value: fraction of the memory limit where the strict policy starts working.
+ *
+ * Sets @value as the fraction of the defined memory limit where the strict
+ * policy starts working. This policy will try to reduce the memory footprint by
+ * releasing critical memory.
+ *
+ * The threshold must be bigger than 0 and smaller than 1. Also, it must be bigger
+ * than the conservative threshold defined in @settings, and smaller than the kill
+ * threshold if the latter is not 0. The default value is 0.5.
+ *
+ * Since: 2.34
+ */
+void webkit_memory_pressure_settings_set_strict_threshold(WebKitMemoryPressureSettings* settings, gdouble value)
+{
+    g_return_if_fail(settings);
+    g_return_if_fail(value > 0 && value < 1);
+    g_return_if_fail(value > settings->configuration.conservativeThresholdFraction);
+    g_return_if_fail(!settings->configuration.killThresholdFraction || value < settings->configuration.killThresholdFraction);
+
+    settings->configuration.strictThresholdFraction = value;
+}
+
+/**
+ * webkit_memory_pressure_settings_get_strict_threshold:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Returns: the value of the the strict threshold inside @settings.
+ *
+ * Since: 2.34
+ */
+gdouble webkit_memory_pressure_settings_get_strict_threshold(WebKitMemoryPressureSettings* settings)
+{
+    g_return_val_if_fail(settings, 0);
+
+    return settings->configuration.strictThresholdFraction;
+}
+
+/**
+ * webkit_memory_pressure_settings_set_kill_threshold:
+ * @settings: a #WebKitMemoryPressureSettings
+ * @value: fraction of the memory limit where the process will be killed because
+ *   of excessive memory usage.
+ *
+ * Sets @value as the fraction of the defined memory limit where the process will be
+ * killed.
+ *
+ * The threshold must be a value bigger or equal to 0. A value of 0 means that the process
+ * is never killed. If the threshold is not 0, then it must be bigger than the strict threshold
+ * defined in @settings. The threshold can also have values bigger than 1. The default value is 0.
+ *
+ * Since: 2.34
+ */
+void webkit_memory_pressure_settings_set_kill_threshold(WebKitMemoryPressureSettings* settings, gdouble value)
+{
+    g_return_if_fail(settings);
+    g_return_if_fail(value >= 0);
+    g_return_if_fail(!value || value > settings->configuration.strictThresholdFraction);
+
+    settings->configuration.killThresholdFraction = value ? std::make_optional(value) : std::nullopt;
+}
+
+/**
+ * webkit_memory_pressure_settings_get_kill_threshold:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Returns: the value of the the kill threshold inside @settings.
+ *
+ * Since: 2.34
+ */
+gdouble webkit_memory_pressure_settings_get_kill_threshold(WebKitMemoryPressureSettings* settings)
+{
+    g_return_val_if_fail(settings, 0);
+
+    return settings->configuration.killThresholdFraction.value_or(0);
+}
+
+
+/**
+ * webkit_memory_pressure_settings_set_poll_interval:
+ * @settings: a #WebKitMemoryPressureSettings
+ * @value: period (in seconds) between memory usage measurements.
+ *
+ * Sets @value as the poll interval used by @settings.
+ *
+ * The poll interval value must be bigger than 0. The default value is 30 seconds.
+ *
+ * Since: 2.34
+ */
+void webkit_memory_pressure_settings_set_poll_interval(WebKitMemoryPressureSettings* settings, gdouble value)
+{
+    g_return_if_fail(settings);
+    g_return_if_fail(value > 0);
+
+    settings->configuration.pollInterval = Seconds(value);
+}
+
+/**
+ * webkit_memory_pressure_settings_get_poll_interval:
+ * @settings: a #WebKitMemoryPressureSettings
+ *
+ * Returns: the value in seconds of the the poll interval inside @settings.
+ *
+ * Since: 2.34
+ */
+gdouble webkit_memory_pressure_settings_get_poll_interval(WebKitMemoryPressureSettings* settings)
+{
+    g_return_val_if_fail(settings, 0);
+
+    return settings->configuration.pollInterval.seconds();
+}
+
+const MemoryPressureHandler::Configuration& webkitMemoryPressureSettingsGetMemoryPressureHandlerConfiguration(WebKitMemoryPressureSettings* settings)
+{
+    return settings->configuration;
+}

Added: trunk/Source/WebKit/UIProcess/API/glib/WebKitMemoryPressureSettingsPrivate.h (0 => 280155)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitMemoryPressureSettingsPrivate.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitMemoryPressureSettingsPrivate.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "WebKitMemoryPressureSettings.h"
+#include <wtf/MemoryPressureHandler.h>
+
+const MemoryPressureHandler::Configuration& webkitMemoryPressureSettingsGetMemoryPressureHandlerConfiguration(WebKitMemoryPressureSettings*);

Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -39,6 +39,8 @@
 #include "WebKitGeolocationManagerPrivate.h"
 #include "WebKitInitialize.h"
 #include "WebKitInjectedBundleClient.h"
+#include "WebKitMemoryPressureSettings.h"
+#include "WebKitMemoryPressureSettingsPrivate.h"
 #include "WebKitNotificationProvider.h"
 #include "WebKitPrivate.h"
 #include "WebKitProtocolHandler.h"
@@ -124,6 +126,7 @@
     PROP_USE_SYSTEM_APPEARANCE_FOR_SCROLLBARS,
 #endif
 #endif
+    PROP_MEMORY_PRESSURE_SETTINGS,
     N_PROPERTIES,
 };
 
@@ -241,6 +244,8 @@
 
     HashSet<String> dnsPrefetchedHosts;
     PAL::HysteresisActivity dnsPrefetchHystereris;
+
+    WebKitMemoryPressureSettings* memoryPressureSettings;
 };
 
 static guint signals[LAST_SIGNAL] = { 0, };
@@ -376,6 +381,11 @@
         break;
 #endif
 #endif
+    case PROP_MEMORY_PRESSURE_SETTINGS: {
+        gpointer settings = g_value_get_boxed(value);
+        context->priv->memoryPressureSettings = settings ? webkit_memory_pressure_settings_copy(static_cast<WebKitMemoryPressureSettings*>(settings)) : nullptr;
+        break;
+    }
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
     }
@@ -399,6 +409,11 @@
     configuration.setUseSystemAppearanceForScrollbars(priv->useSystemAppearanceForScrollbars);
 #endif
 #endif
+    if (priv->memoryPressureSettings) {
+        configuration.setMemoryPressureHandlerConfiguration(webkitMemoryPressureSettingsGetMemoryPressureHandlerConfiguration(priv->memoryPressureSettings));
+        // Once the settings have been passed to the ProcessPoolConfiguration, we don't need them anymore so we can free them.
+        g_clear_pointer(&priv->memoryPressureSettings, webkit_memory_pressure_settings_free);
+    }
 
     if (!priv->websiteDataManager)
         priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new("local-storage-directory", priv->localStorageDirectory.data(), nullptr));
@@ -543,6 +558,21 @@
 #endif
 #endif
 
+    /**
+     * WebKitWebContext:memory-pressure-settings:
+     *
+     * The #WebKitMemoryPressureSettings applied to the web processes created by this context.
+     *
+     * Since: 2.34
+     */
+    sObjProperties[PROP_MEMORY_PRESSURE_SETTINGS] =
+        g_param_spec_boxed(
+            "memory-pressure-settings",
+            _("Memory Pressure Settings"),
+            _("The WebKitMemoryPressureSettings applied to the web processes created by this context"),
+            WEBKIT_TYPE_MEMORY_PRESSURE_SETTINGS,
+            static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
     g_object_class_install_properties(gObjectClass, N_PROPERTIES, sObjProperties);
 
     /**

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitAutocleanups.h (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitAutocleanups.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitAutocleanups.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -79,6 +79,7 @@
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitITPFirstParty, webkit_itp_first_party_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitITPThirdParty, webkit_itp_third_party_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitJavascriptResult, webkit_javascript_result_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitMemoryPressureSettings, webkit_memory_pressure_settings_free)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitMimeInfo, webkit_mime_info_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNavigationAction, webkit_navigation_action_free)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNetworkProxySettings, webkit_network_proxy_settings_free)

Added: trunk/Source/WebKit/UIProcess/API/gtk/WebKitMemoryPressureSettings.h (0 => 280155)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitMemoryPressureSettings.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitMemoryPressureSettings.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitMemoryPressureSettings_h
+#define WebKitMemoryPressureSettings_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_MEMORY_PRESSURE_SETTINGS (webkit_memory_pressure_settings_get_type())
+
+typedef struct _WebKitMemoryPressureSettings WebKitMemoryPressureSettings;
+
+WEBKIT_API GType
+webkit_memory_pressure_settings_get_type                   (void);
+
+WEBKIT_API WebKitMemoryPressureSettings *
+webkit_memory_pressure_settings_new                        (void);
+
+WEBKIT_API WebKitMemoryPressureSettings *
+webkit_memory_pressure_settings_copy                       (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_free                       (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_memory_limit           (WebKitMemoryPressureSettings *settings,
+                                                            guint                         memory_limit);
+
+WEBKIT_API guint
+webkit_memory_pressure_settings_get_memory_limit           (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_conservative_threshold (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_conservative_threshold (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_strict_threshold       (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_strict_threshold       (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_kill_threshold         (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_kill_threshold         (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_poll_interval          (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_poll_interval          (WebKitMemoryPressureSettings *settings);
+
+G_END_DECLS
+
+#endif /* WebKitMemoryPressureSettings_h */

Modified: trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2021-07-21 20:10:49 UTC (rev 280155)
@@ -1953,4 +1953,27 @@
 webkit_website_policies_get_type
 </SECTION>
 
+<SECTION>
+<FILE>WebKitMemoryPressureSettings</FILE>
+WebKitMemoryPressureSettings
+webkit_memory_pressure_settings_new
+webkit_memory_pressure_settings_copy
+webkit_memory_pressure_settings_free
+webkit_memory_pressure_settings_set_memory_limit
+webkit_memory_pressure_settings_get_memory_limit
+webkit_memory_pressure_settings_set_conservative_threshold
+webkit_memory_pressure_settings_get_conservative_threshold
+webkit_memory_pressure_settings_set_strict_threshold
+webkit_memory_pressure_settings_get_strict_threshold
+webkit_memory_pressure_settings_set_kill_threshold
+webkit_memory_pressure_settings_get_kill_threshold
+webkit_memory_pressure_settings_set_poll_interval
+webkit_memory_pressure_settings_get_poll_interval
 
+<SUBSECTION Private>
+webkit_memory_pressure_settings_get_type
+
+<SUBSECTION Standard>
+WEBKIT_TYPE_MEMORY_PRESSURE_SETTINGS
+</SECTION>
+

Modified: trunk/Source/WebKit/UIProcess/API/gtk/webkit2.h (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/gtk/webkit2.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/gtk/webkit2.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -56,6 +56,7 @@
 #include <webkit2/WebKitInstallMissingMediaPluginsPermissionRequest.h>
 #include <webkit2/WebKitJavascriptResult.h>
 #include <webkit2/WebKitMediaKeySystemPermissionRequest.h>
+#include <webkit2/WebKitMemoryPressureSettings.h>
 #include <webkit2/WebKitMimeInfo.h>
 #include <webkit2/WebKitNavigationAction.h>
 #include <webkit2/WebKitNavigationPolicyDecision.h>

Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitAutocleanups.h (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitAutocleanups.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitAutocleanups.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -72,6 +72,7 @@
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitITPFirstParty, webkit_itp_first_party_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitITPThirdParty, webkit_itp_third_party_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitJavascriptResult, webkit_javascript_result_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitMemoryPressureSettings, webkit_memory_pressure_settings_free)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitMimeInfo, webkit_mime_info_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNavigationAction, webkit_navigation_action_free)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNetworkProxySettings, webkit_network_proxy_settings_free)

Added: trunk/Source/WebKit/UIProcess/API/wpe/WebKitMemoryPressureSettings.h (0 => 280155)


--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitMemoryPressureSettings.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitMemoryPressureSettings.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if !defined(__WEBKIT_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <wpe/webkit.h> can be included directly."
+#endif
+
+#ifndef WebKitMemoryPressureSettings_h
+#define WebKitMemoryPressureSettings_h
+
+#include <glib-object.h>
+#include <wpe/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_MEMORY_PRESSURE_SETTINGS (webkit_memory_pressure_settings_get_type())
+
+typedef struct _WebKitMemoryPressureSettings WebKitMemoryPressureSettings;
+
+WEBKIT_API GType
+webkit_memory_pressure_settings_get_type                   (void);
+
+WEBKIT_API WebKitMemoryPressureSettings *
+webkit_memory_pressure_settings_new                        (void);
+
+WEBKIT_API WebKitMemoryPressureSettings *
+webkit_memory_pressure_settings_copy                       (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_free                       (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_memory_limit           (WebKitMemoryPressureSettings *settings,
+                                                            guint                         memory_limit);
+
+WEBKIT_API guint
+webkit_memory_pressure_settings_get_memory_limit           (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_conservative_threshold (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_conservative_threshold (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_strict_threshold       (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_strict_threshold       (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_kill_threshold         (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_kill_threshold         (WebKitMemoryPressureSettings *settings);
+
+WEBKIT_API void
+webkit_memory_pressure_settings_set_poll_interval          (WebKitMemoryPressureSettings *settings,
+                                                            gdouble                       value);
+
+WEBKIT_API gdouble
+webkit_memory_pressure_settings_get_poll_interval          (WebKitMemoryPressureSettings *settings);
+
+G_END_DECLS
+
+#endif /* WebKitMemoryPressureSettings_h */

Modified: trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt	2021-07-21 20:10:49 UTC (rev 280155)
@@ -1651,3 +1651,27 @@
 WebKitWebsitePoliciesPrivate
 webkit_website_policies_get_type
 </SECTION>
+
+<SECTION>
+<FILE>WebKitMemoryPressureSettings</FILE>
+WebKitMemoryPressureSettings
+webkit_memory_pressure_settings_new
+webkit_memory_pressure_settings_copy
+webkit_memory_pressure_settings_free
+webkit_memory_pressure_settings_set_memory_limit
+webkit_memory_pressure_settings_get_memory_limit
+webkit_memory_pressure_settings_set_conservative_threshold
+webkit_memory_pressure_settings_get_conservative_threshold
+webkit_memory_pressure_settings_set_strict_threshold
+webkit_memory_pressure_settings_get_strict_threshold
+webkit_memory_pressure_settings_set_kill_threshold
+webkit_memory_pressure_settings_get_kill_threshold
+webkit_memory_pressure_settings_set_poll_interval
+webkit_memory_pressure_settings_get_poll_interval
+
+<SUBSECTION Private>
+webkit_memory_pressure_settings_get_type
+
+<SUBSECTION Standard>
+WEBKIT_TYPE_MEMORY_PRESSURE_SETTINGS
+</SECTION>

Modified: trunk/Source/WebKit/UIProcess/API/wpe/webkit.h (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/API/wpe/webkit.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/API/wpe/webkit.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -54,6 +54,7 @@
 #include <wpe/WebKitInstallMissingMediaPluginsPermissionRequest.h>
 #include <wpe/WebKitJavascriptResult.h>
 #include <wpe/WebKitMediaKeySystemPermissionRequest.h>
+#include <wpe/WebKitMemoryPressureSettings.h>
 #include <wpe/WebKitMimeInfo.h>
 #include <wpe/WebKitNavigationAction.h>
 #include <wpe/WebKitNavigationPolicyDecision.h>

Modified: trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp (280154 => 280155)


--- trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -107,6 +107,8 @@
 #if PLATFORM(GTK) && !USE(GTK4)
     parameters.useSystemAppearanceForScrollbars = m_configuration->useSystemAppearanceForScrollbars();
 #endif
+
+    parameters.memoryPressureHandlerConfiguration = m_configuration->memoryPressureHandlerConfiguration();
 }
 
 void WebProcessPool::platformInvalidateContext()

Modified: trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp (280154 => 280155)


--- trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -105,6 +105,9 @@
 #if PLATFORM(GTK) && !USE(GTK4)
     setUseSystemAppearanceForScrollbars(parameters.useSystemAppearanceForScrollbars);
 #endif
+
+    if (parameters.memoryPressureHandlerConfiguration)
+        MemoryPressureHandler::singleton().setConfiguration(WTFMove(*parameters.memoryPressureHandlerConfiguration));
 }
 
 void WebProcess::platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&&)

Modified: trunk/Tools/ChangeLog (280154 => 280155)


--- trunk/Tools/ChangeLog	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Tools/ChangeLog	2021-07-21 20:10:49 UTC (rev 280155)
@@ -1,3 +1,24 @@
+2021-07-21  Miguel Gomez  <[email protected]>
+
+        [GTK][WPE] Allow the user to configure the MemoryPressureHandler inside the web process
+        https://bugs.webkit.org/show_bug.cgi?id=222738
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add a test for WebKitMemoryPressureSettings API and to test WebKitWebContext with
+        non default WebKitMemoryPressureSettings values.
+
+        * TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp:
+        (MemoryPressureTest::setup):
+        (MemoryPressureTest::teardown):
+        (MemoryPressureTest::webProcessTerminatedCallback):
+        (MemoryPressureTest::waitUntilWebProcessTerminated):
+        (testMemoryPressureSettings):
+        (beforeAll):
+        * TestWebKitAPI/glib/WebKitGLib/TestMain.cpp:
+        * TestWebKitAPI/glib/WebKitGLib/TestMain.h:
+        (Test::Test):
+
 2021-07-21  Aditya Keerthi  <[email protected]>
 
         Crash in -[WKWebView takeSnapshotWithConfiguration:completionHandler:] when taking empty snapshots

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp (280154 => 280155)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -770,6 +770,106 @@
 #endif
 }
 
+class MemoryPressureTest : public WebViewTest {
+public:
+    MAKE_GLIB_TEST_FIXTURE_WITH_SETUP_TEARDOWN(MemoryPressureTest, setup, teardown);
+
+    static void setup()
+    {
+        Test::s_memoryPressureSettings = webkit_memory_pressure_settings_new();
+        webkit_memory_pressure_settings_set_memory_limit(Test::s_memoryPressureSettings, 20);
+        webkit_memory_pressure_settings_set_poll_interval(Test::s_memoryPressureSettings, 0.5);
+        webkit_memory_pressure_settings_set_kill_threshold(Test::s_memoryPressureSettings, 1);
+        webkit_memory_pressure_settings_set_strict_threshold(Test::s_memoryPressureSettings, 0.75);
+        webkit_memory_pressure_settings_set_conservative_threshold(Test::s_memoryPressureSettings, 0.5);
+    }
+
+    static void teardown()
+    {
+        webkit_memory_pressure_settings_free(Test::s_memoryPressureSettings);
+        Test::s_memoryPressureSettings = nullptr;
+    }
+
+    static void webProcessTerminatedCallback(WebKitWebView* webView, WebKitWebProcessTerminationReason reason, MemoryPressureTest* test)
+    {
+        test->m_terminationReason = reason;
+        g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(webProcessTerminatedCallback), test);
+        g_main_loop_quit(test->m_mainLoop);
+    }
+
+    void waitUntilWebProcessTerminated()
+    {
+        g_signal_connect_after(m_webView, "web-process-terminated", G_CALLBACK(MemoryPressureTest::webProcessTerminatedCallback), this);
+        g_main_loop_run(m_mainLoop);
+    }
+
+    WebKitWebProcessTerminationReason m_terminationReason { WEBKIT_WEB_PROCESS_CRASHED };
+};
+
+static void testMemoryPressureSettings(MemoryPressureTest* test, gconstpointer)
+{
+    // Before testing the settings that have been set to the context, use a new instance
+    // of WebKitMemoryPressureSettings to test the default values, getters and setters.
+    WebKitMemoryPressureSettings* settings = webkit_memory_pressure_settings_new();
+
+    // We can't exactly know the default value for the memory limit, as it depends on
+    // the hardware of the machine, so just ensure that it's something > 0 and <= 3GB.
+    guint limit = webkit_memory_pressure_settings_get_memory_limit(settings);
+    g_assert_cmpuint(limit, >, 0);
+    g_assert_cmpuint(limit * MB, <=, 3 * GB);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_conservative_threshold(settings), ==, 0.33);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_strict_threshold(settings), ==, 0.5);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_kill_threshold(settings), ==, 0);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_poll_interval(settings), ==, 30);
+
+    // Test setting and getting values.
+    webkit_memory_pressure_settings_set_memory_limit(settings, 20);
+    g_assert_cmpuint(webkit_memory_pressure_settings_get_memory_limit(settings), ==, 20);
+
+    webkit_memory_pressure_settings_set_conservative_threshold(settings, 0.4);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_conservative_threshold(settings), ==, 0.4);
+
+    webkit_memory_pressure_settings_set_strict_threshold(settings, 0.6);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_strict_threshold(settings), ==, 0.6);
+
+    webkit_memory_pressure_settings_set_kill_threshold(settings, 1.1);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_kill_threshold(settings), ==, 1.1);
+
+    webkit_memory_pressure_settings_set_poll_interval(settings, 5);
+    g_assert_cmpfloat(webkit_memory_pressure_settings_get_poll_interval(settings), ==, 5);
+
+    webkit_memory_pressure_settings_free(settings);
+
+    // An empty view uses around 7MB of memory. We're setting a maximum of 20MB here, polling every 0.5 seconds,
+    // and the kill fraction is 1, so the web process will be killed when it exceeds 20MB.
+    // The test html will allocate a canvas of 3000x3000, which requires around 36MB of memory, so once it gets
+    // created, the MemoryPressureHandler will detect that the memory usage is too high and kill the web process.
+    // This triggers the web-process-terminated signal in the view with WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT
+    // as the termination reason.
+
+    static const char* html =
+        "<html>"
+        "  <body>"
+        "    <script>"
+        "      setTimeout(function() {"
+        "        var canvas = document.getElementById('canvas');"
+        "        canvas.width = 3000;"
+        "        canvas.height = 3000;"
+        "        var context = canvas.getContext('2d');"
+        "        context.fillStyle = 'green';"
+        "        context.fillRect(0, 0, 3000, 3000);"
+        "      }, 0);"
+        "    </script>"
+        "    <canvas id='canvas'></canvas>"
+        "  </body>"
+        "</html>";
+
+    test->m_expectedWebProcessCrash = true;
+    test->loadHtml(html, nullptr);
+    test->waitUntilWebProcessTerminated();
+    g_assert_cmpuint(test->m_terminationReason, ==, WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT);
+}
+
 void beforeAll()
 {
     kServer = new WebKitTestServer();
@@ -786,6 +886,7 @@
     SecurityPolicyTest::add("WebKitSecurityManager", "security-policy", testWebContextSecurityPolicy);
     WebViewTest::add("WebKitSecurityManager", "file-xhr", testWebContextSecurityFileXHR);
     ProxyTest::add("WebKitWebContext", "proxy", testWebContextProxySettings);
+    MemoryPressureTest::add("WebKitWebContext", "memory-pressure", testMemoryPressureSettings);
 }
 
 void afterAll()

Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.cpp (280154 => 280155)


--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.cpp	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.cpp	2021-07-21 20:10:49 UTC (rev 280155)
@@ -29,6 +29,7 @@
 GRefPtr<GDBusServer> Test::s_dbusServer;
 Vector<GRefPtr<GDBusConnection>> Test::s_dbusConnections;
 HashMap<uint64_t, GDBusConnection*> Test::s_dbusConnectionPageMap;
+WebKitMemoryPressureSettings* Test::s_memoryPressureSettings = nullptr;
 
 void beforeAll();
 void afterAll();

Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.h (280154 => 280155)


--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.h	2021-07-21 19:48:21 UTC (rev 280154)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.h	2021-07-21 20:10:49 UTC (rev 280155)
@@ -142,6 +142,7 @@
             "use-system-appearance-for-scrollbars", FALSE,
 #endif
 #endif
+            "memory-pressure-settings", s_memoryPressureSettings,
             nullptr)));
         assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webContext.get()));
         g_signal_connect(m_webContext.get(), "initialize-web-extensions", G_CALLBACK(initializeWebExtensionsCallback), this);
@@ -292,4 +293,5 @@
     static GRefPtr<GDBusServer> s_dbusServer;
     static Vector<GRefPtr<GDBusConnection>> s_dbusConnections;
     static HashMap<uint64_t, GDBusConnection*> s_dbusConnectionPageMap;
+    static WebKitMemoryPressureSettings* s_memoryPressureSettings;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to