Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (239194 => 239195)
--- trunk/Source/_javascript_Core/ChangeLog 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-12-14 04:05:41 UTC (rev 239195)
@@ -1,3 +1,23 @@
+2018-12-13 Saam Barati <[email protected]>
+
+ The JSC shell should listen for memory pressure events and respond to them
+ https://bugs.webkit.org/show_bug.cgi?id=192647
+
+ Reviewed by Keith Miller.
+
+ We want the JSC shell to behave more like the WebContent process when
+ it comes to running performance tests. One way to make the shell
+ more like this is to have it respond to memory pressure events in
+ a similar way as the WebContent process. This makes it easier to run
+ benchmarks like JetStream2 on the CLI on iOS.
+
+ * jsc.cpp:
+ (jscmain):
+ * runtime/VM.cpp:
+ (JSC::VM::drainMicrotasks):
+ * runtime/VM.h:
+ (JSC::VM::setOnEachMicrotaskTick):
+
2018-12-13 Mark Lam <[email protected]>
Ensure that StructureFlags initialization always starts with Base::StructureFlags.
Modified: trunk/Source/_javascript_Core/jsc.cpp (239194 => 239195)
--- trunk/Source/_javascript_Core/jsc.cpp 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/_javascript_Core/jsc.cpp 2018-12-14 04:05:41 UTC (rev 239195)
@@ -80,8 +80,10 @@
#include <sys/types.h>
#include <thread>
#include <type_traits>
+#include <wtf/Box.h>
#include <wtf/CommaPrinter.h>
#include <wtf/MainThread.h>
+#include <wtf/MemoryPressureHandler.h>
#include <wtf/MonotonicTime.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/StringPrintStream.h>
@@ -2871,9 +2873,49 @@
#endif
Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled();
+#if PLATFORM(COCOA)
+ auto& memoryPressureHandler = MemoryPressureHandler::singleton();
+ {
+ dispatch_queue_t queue = dispatch_queue_create("jsc shell memory pressure handler", DISPATCH_QUEUE_SERIAL);
+ memoryPressureHandler.setDispatchQueue(queue);
+ dispatch_release(queue);
+ }
+ Box<Critical> memoryPressureCriticalState = Box<Critical>::create(Critical::No);
+ Box<Synchronous> memoryPressureSynchronousState = Box<Synchronous>::create(Synchronous::No);
+ memoryPressureHandler.setLowMemoryHandler([=] (Critical critical, Synchronous synchronous) {
+ // We set these racily with respect to reading them from the JS execution thread.
+ *memoryPressureCriticalState = critical;
+ *memoryPressureSynchronousState = synchronous;
+ });
+ memoryPressureHandler.setShouldLogMemoryMemoryPressureEvents(false);
+ memoryPressureHandler.install();
+
+ auto _onEachMicrotaskTick_ = [&] (VM& vm) {
+ if (*memoryPressureCriticalState == Critical::No)
+ return;
+
+ *memoryPressureCriticalState = Critical::No;
+ bool isSynchronous = *memoryPressureSynchronousState == Synchronous::Yes;
+
+ WTF::releaseFastMallocFreeMemory();
+ vm.deleteAllCode(DeleteAllCodeIfNotCollecting);
+
+ if (!vm.heap.isCurrentThreadBusy()) {
+ if (isSynchronous) {
+ vm.heap.collectNow(Sync, CollectionScope::Full);
+ WTF::releaseFastMallocFreeMemory();
+ } else
+ vm.heap.collectNowFullIfNotDoneRecently(Async);
+ }
+ };
+#endif
+
int result = runJSC(
options, false,
- [&] (VM&, GlobalObject* globalObject, bool& success) {
+ [&] (VM& vm, GlobalObject* globalObject, bool& success) {
+#if PLATFORM(COCOA)
+ vm.setOnEachMicrotaskTick(WTFMove(onEachMicrotaskTick));
+#endif
runWithOptions(globalObject, options, success);
});
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (239194 => 239195)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2018-12-14 04:05:41 UTC (rev 239195)
@@ -1128,8 +1128,11 @@
void VM::drainMicrotasks()
{
- while (!m_microtaskQueue.isEmpty())
+ while (!m_microtaskQueue.isEmpty()) {
m_microtaskQueue.takeFirst()->run();
+ if (m_onEachMicrotaskTick)
+ m_onEachMicrotaskTick(*this);
+ }
}
void QueuedTask::run()
Modified: trunk/Source/_javascript_Core/runtime/VM.h (239194 => 239195)
--- trunk/Source/_javascript_Core/runtime/VM.h 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2018-12-14 04:05:41 UTC (rev 239195)
@@ -857,6 +857,7 @@
void queueMicrotask(JSGlobalObject&, Ref<Microtask>&&);
JS_EXPORT_PRIVATE void drainMicrotasks();
+ ALWAYS_INLINE void setOnEachMicrotaskTick(WTF::Function<void(VM&)>&& func) { m_onEachMicrotaskTick = WTFMove(func); }
void setGlobalConstRedeclarationShouldThrow(bool globalConstRedeclarationThrow) { m_globalConstRedeclarationShouldThrow = globalConstRedeclarationThrow; }
ALWAYS_INLINE bool globalConstRedeclarationShouldThrow() const { return m_globalConstRedeclarationShouldThrow; }
@@ -1016,6 +1017,8 @@
std::unique_ptr<ShadowChicken> m_shadowChicken;
std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;
+ WTF::Function<void(VM&)> m_onEachMicrotaskTick;
+
#if ENABLE(JIT)
#if !ASSERT_DISABLED
JS_EXPORT_PRIVATE static bool s_canUseJITIsSet;
Modified: trunk/Source/WTF/ChangeLog (239194 => 239195)
--- trunk/Source/WTF/ChangeLog 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/WTF/ChangeLog 2018-12-14 04:05:41 UTC (rev 239195)
@@ -1,3 +1,26 @@
+2018-12-13 Saam Barati <[email protected]>
+
+ The JSC shell should listen for memory pressure events and respond to them
+ https://bugs.webkit.org/show_bug.cgi?id=192647
+
+ Reviewed by Keith Miller.
+
+ * wtf/MemoryPressureHandler.cpp:
+ (WTF::MemoryPressureHandler::MemoryPressureHandler):
+ (WTF::MemoryPressureHandler::setDispatchQueue):
+ Make it so that we can customize which dispatch queue memory pressure
+ events get handled on.
+
+ * wtf/MemoryPressureHandler.h:
+ (WTF::MemoryPressureHandler::setShouldLogMemoryMemoryPressureEvents):
+ Make it so that we can disable logging that happens on each memory
+ pressure event.
+
+ * wtf/cocoa/MemoryPressureHandlerCocoa.mm:
+ (WTF::MemoryPressureHandler::install):
+ (WTF::MemoryPressureHandler::uninstall):
+ (WTF::MemoryPressureHandler::holdOff):
+
2018-12-13 David Kilzer <[email protected]>
clang-tidy: Fix unnecessary parameter copies in ParallelHelperPool.cpp
Modified: trunk/Source/WTF/wtf/MemoryPressureHandler.cpp (239194 => 239195)
--- trunk/Source/WTF/wtf/MemoryPressureHandler.cpp 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/WTF/wtf/MemoryPressureHandler.cpp 2018-12-14 04:05:41 UTC (rev 239195)
@@ -55,6 +55,9 @@
: m_windowsMeasurementTimer(RunLoop::main(), this, &MemoryPressureHandler::windowsMeasurementTimerFired)
#endif
{
+#if PLATFORM(COCOA)
+ setDispatchQueue(dispatch_get_main_queue());
+#endif
}
void MemoryPressureHandler::setShouldUsePeriodicMemoryMonitor(bool use)
@@ -298,4 +301,15 @@
void MemoryPressureHandler::platformInitialize() { }
#endif
+#if PLATFORM(COCOA)
+void MemoryPressureHandler::setDispatchQueue(dispatch_queue_t queue)
+{
+ RELEASE_ASSERT(!m_installed);
+ dispatch_retain(queue);
+ if (m_dispatchQueue)
+ dispatch_release(m_dispatchQueue);
+ m_dispatchQueue = queue;
+}
+#endif
+
} // namespace WebCore
Modified: trunk/Source/WTF/wtf/MemoryPressureHandler.h (239194 => 239195)
--- trunk/Source/WTF/wtf/MemoryPressureHandler.h 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/WTF/wtf/MemoryPressureHandler.h 2018-12-14 04:05:41 UTC (rev 239195)
@@ -94,6 +94,10 @@
WTF_EXPORT_PRIVATE static MemoryUsagePolicy currentMemoryUsagePolicy();
+#if PLATFORM(COCOA)
+ WTF_EXPORT_PRIVATE void setDispatchQueue(dispatch_queue_t);
+#endif
+
class ReliefLogger {
public:
explicit ReliefLogger(const char *log)
@@ -150,6 +154,8 @@
WTF_EXPORT_PRIVATE static void setPageCount(unsigned);
+ void setShouldLogMemoryMemoryPressureEvents(bool shouldLog) { m_shouldLogMemoryMemoryPressureEvents = shouldLog; }
+
private:
size_t thresholdForMemoryKill();
void memoryPressureStatusChanged();
@@ -180,6 +186,7 @@
std::atomic<bool> m_underMemoryPressure;
bool m_isSimulatingMemoryPressure { false };
+ bool m_shouldLogMemoryMemoryPressureEvents { true };
std::unique_ptr<RunLoop::Timer<MemoryPressureHandler>> m_measurementTimer;
MemoryUsagePolicy m_memoryUsagePolicy { MemoryUsagePolicy::Unrestricted };
@@ -198,6 +205,10 @@
RunLoop::Timer<MemoryPressureHandler> m_holdOffTimer;
void holdOffTimerFired();
#endif
+
+#if PLATFORM(COCOA)
+ dispatch_queue_t m_dispatchQueue { nullptr };
+#endif
};
extern WTFLogChannel LogMemoryPressure;
Modified: trunk/Source/WTF/wtf/cocoa/MemoryPressureHandlerCocoa.mm (239194 => 239195)
--- trunk/Source/WTF/wtf/cocoa/MemoryPressureHandlerCocoa.mm 2018-12-14 03:48:34 UTC (rev 239194)
+++ trunk/Source/WTF/wtf/cocoa/MemoryPressureHandlerCocoa.mm 2018-12-14 04:05:41 UTC (rev 239195)
@@ -67,13 +67,13 @@
if (m_installed || timerEventSource)
return;
- dispatch_async(dispatch_get_main_queue(), ^{
+ dispatch_async(m_dispatchQueue, ^{
#if PLATFORM(IOS_FAMILY)
auto memoryStatusFlags = DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL | DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN | DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL;
#else // PLATFORM(MAC)
auto memoryStatusFlags = DISPATCH_MEMORYPRESSURE_CRITICAL;
#endif
- memoryPressureEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, memoryStatusFlags, dispatch_get_main_queue());
+ memoryPressureEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, memoryStatusFlags, m_dispatchQueue);
dispatch_source_set_event_handler(memoryPressureEventSource, ^{
auto status = dispatch_source_get_data(memoryPressureEventSource);
@@ -102,13 +102,14 @@
#else // PLATFORM(MAC)
respondToMemoryPressure(Critical::Yes);
#endif
- WTFLogAlways("Received memory pressure event %lu vm pressure %d", status, isUnderMemoryPressure());
+ if (m_shouldLogMemoryMemoryPressureEvents)
+ WTFLogAlways("Received memory pressure event %lu vm pressure %d", status, isUnderMemoryPressure());
});
dispatch_resume(memoryPressureEventSource);
});
// Allow simulation of memory pressure with "notifyutil -p org.WebKit.lowMemory"
- notify_register_dispatch("org.WebKit.lowMemory", ¬ifyTokens[0], dispatch_get_main_queue(), ^(int) {
+ notify_register_dispatch("org.WebKit.lowMemory", ¬ifyTokens[0], m_dispatchQueue, ^(int) {
#if ENABLE(FMW_FOOTPRINT_COMPARISON)
auto footprintBefore = pagesPerVMTag();
#endif
@@ -122,15 +123,15 @@
logFootprintComparison(footprintBefore, footprintAfter);
#endif
- dispatch_async(dispatch_get_main_queue(), ^{
+ dispatch_async(m_dispatchQueue, ^{
endSimulatedMemoryPressure();
});
});
- notify_register_dispatch("org.WebKit.lowMemory.begin", ¬ifyTokens[1], dispatch_get_main_queue(), ^(int) {
+ notify_register_dispatch("org.WebKit.lowMemory.begin", ¬ifyTokens[1], m_dispatchQueue, ^(int) {
beginSimulatedMemoryPressure();
});
- notify_register_dispatch("org.WebKit.lowMemory.end", ¬ifyTokens[2], dispatch_get_main_queue(), ^(int) {
+ notify_register_dispatch("org.WebKit.lowMemory.end", ¬ifyTokens[2], m_dispatchQueue, ^(int) {
endSimulatedMemoryPressure();
});
@@ -142,7 +143,7 @@
if (!m_installed)
return;
- dispatch_async(dispatch_get_main_queue(), ^{
+ dispatch_async(m_dispatchQueue, ^{
if (memoryPressureEventSource) {
dispatch_source_cancel(memoryPressureEventSource);
memoryPressureEventSource = nullptr;
@@ -162,8 +163,8 @@
void MemoryPressureHandler::holdOff(Seconds seconds)
{
- dispatch_async(dispatch_get_main_queue(), ^{
- timerEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
+ dispatch_async(m_dispatchQueue, ^{
+ timerEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_dispatchQueue);
if (timerEventSource) {
dispatch_set_context(timerEventSource, this);
// FIXME: The final argument `s_minimumHoldOffTime.seconds()` seems wrong.