Title: [187301] branches/safari-601.1-branch

Diff

Modified: branches/safari-601.1-branch/Source/_javascript_Core/ChangeLog (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/ChangeLog	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/ChangeLog	2015-07-24 06:33:53 UTC (rev 187301)
@@ -1,3 +1,41 @@
+2015-07-23  Lucas Forschler  <[email protected]>
+
+        Merge r187125
+
+    2015-07-21  Filip Pizlo  <[email protected]>
+
+            Fixed VM pool allocation should have a reserve for allocations that cannot fail
+            https://bugs.webkit.org/show_bug.cgi?id=147154
+            rdar://problem/21847618
+
+            Reviewed by Geoffrey Garen.
+
+            This adds the notion of a JIT pool reserve fraction. Some fraction, currently 1/4, of
+            the JIT pool is reserved for allocations that cannot fail. It makes sense to make this
+            a fraction rather than a constant because each allocation that can fail may cause some
+            number of allocations that cannot fail (for example, the OSR exit thunks that we
+            compile when we exit from some CodeBlock cannot fail).
+
+            I've tested this by adding a test mode where we artificially limit the JIT pool size.
+            Prior to the fix, we had >20 failures. Now we have none.
+
+            * heap/GCLogging.cpp:
+            (WTF::printInternal): I needed a dump method on Options members when debugging this.
+            * heap/GCLogging.h:
+            * jit/ExecutableAllocator.h: Raise the ARM64 limit to 32MB because 16MB is cutting it too close.
+            * jit/ExecutableAllocatorFixedVMPool.cpp:
+            (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): Add the ability to artificially limit JIT pool size for testing.
+            (JSC::ExecutableAllocator::memoryPressureMultiplier): Implement the reserve when computing memory pressure for JIT tier-up heuristics.
+            (JSC::ExecutableAllocator::allocate): Implement the reserve when allocating can-fail things.
+            * jsc.cpp: Rewire some options parsing so that CommandLine happens before we create the JIT pool.
+            (main):
+            (CommandLine::parseArguments):
+            (jscmain):
+            * runtime/Options.cpp: 
+            (JSC::OptionRange::dump): I needed a dump method on Options members when debugging this.
+            (JSC::Options::initialize): This can now be called more than once.
+            * runtime/Options.h:
+
 2015-07-20  Matthew Hanson  <[email protected]>
 
         Merge r186819. rdar://problem/21729083

Modified: branches/safari-601.1-branch/Source/_javascript_Core/heap/GCLogging.cpp (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/heap/GCLogging.cpp	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/heap/GCLogging.cpp	2015-07-24 06:33:53 UTC (rev 187301)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
 #include "HeapIterationScope.h"
 #include "JSCell.h"
 #include "JSCellInlines.h"
+#include <wtf/PrintStream.h>
 
 namespace JSC {
 
@@ -113,3 +114,26 @@
 }
 
 } // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::GCLogging::Level level)
+{
+    switch (level) {
+    case JSC::GCLogging::Level::None:
+        out.print("None");
+        return;
+    case JSC::GCLogging::Level::Basic:
+        out.print("Basic");
+        return;
+    case JSC::GCLogging::Level::Verbose:
+        out.print("Verbose");
+        return;
+    default:
+        out.print("Level=", level - JSC::GCLogging::Level::None);
+        return;
+    }
+}
+
+} // namespace WTF
+

Modified: branches/safari-601.1-branch/Source/_javascript_Core/heap/GCLogging.h (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/heap/GCLogging.h	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/heap/GCLogging.h	2015-07-24 06:33:53 UTC (rev 187301)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,4 +48,12 @@
 
 } // namespace JSC
 
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&, JSC::GCLogging::Level);
+
+} // namespace WTF
+
 #endif // GCLogging_h

Modified: branches/safari-601.1-branch/Source/_javascript_Core/jit/ExecutableAllocator.h (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/jit/ExecutableAllocator.h	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/jit/ExecutableAllocator.h	2015-07-24 06:33:53 UTC (rev 187301)
@@ -80,13 +80,16 @@
 #endif
 
 #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
-#if CPU(ARM) || CPU(ARM64)
+#if CPU(ARM)
 static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
+#elif CPU(ARM64)
+static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
 #elif CPU(X86_64)
 static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;
 #else
 static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
 #endif
+static const double executablePoolReservationFraction = 0.25;
 
 extern uintptr_t startOfFixedExecutableMemoryPool;
 #endif

Modified: branches/safari-601.1-branch/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp	2015-07-24 06:33:53 UTC (rev 187301)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,9 +60,14 @@
     FixedVMPoolExecutableAllocator()
         : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
     {
-        m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
+        size_t reservationSize;
+        if (Options::jitMemoryReservationSize())
+            reservationSize = Options::jitMemoryReservationSize();
+        else
+            reservationSize = fixedExecutableMemoryPoolSize;
+        m_reservation = PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
         if (m_reservation) {
-            ASSERT(m_reservation.size() == fixedExecutableMemoryPoolSize);
+            ASSERT(m_reservation.size() == reservationSize);
             addFreshFreeSpace(m_reservation.base(), m_reservation.size());
             
             startOfFixedExecutableMemoryPool = reinterpret_cast<uintptr_t>(m_reservation.base());
@@ -148,12 +153,14 @@
     MetaAllocator::Statistics statistics = allocator->currentStatistics();
     ASSERT(statistics.bytesAllocated <= statistics.bytesReserved);
     size_t bytesAllocated = statistics.bytesAllocated + addedMemoryUsage;
-    if (bytesAllocated >= statistics.bytesReserved)
-        bytesAllocated = statistics.bytesReserved;
+    size_t bytesAvailable = static_cast<size_t>(
+        statistics.bytesReserved * (1 - executablePoolReservationFraction));
+    if (bytesAllocated >= bytesAvailable)
+        bytesAllocated = bytesAvailable;
     double result = 1.0;
-    size_t divisor = statistics.bytesReserved - bytesAllocated;
+    size_t divisor = bytesAvailable - bytesAllocated;
     if (divisor)
-        result = static_cast<double>(statistics.bytesReserved) / divisor;
+        result = static_cast<double>(bytesAvailable) / divisor;
     if (result < 1.0)
         result = 1.0;
     return result;
@@ -170,6 +177,16 @@
         && doExecutableAllocationFuzzingIfEnabled() == PretendToFailExecutableAllocation)
         return nullptr;
     
+    if (effort == JITCompilationCanFail) {
+        // Don't allow allocations if we are down to reserve.
+        MetaAllocator::Statistics statistics = allocator->currentStatistics();
+        size_t bytesAllocated = statistics.bytesAllocated + sizeInBytes;
+        size_t bytesAvailable = static_cast<size_t>(
+            statistics.bytesReserved * (1 - executablePoolReservationFraction));
+        if (bytesAllocated > bytesAvailable)
+            return nullptr;
+    }
+    
     RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
     if (!result) {
         if (effort != JITCompilationCanFail) {

Modified: branches/safari-601.1-branch/Source/_javascript_Core/jsc.cpp (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/jsc.cpp	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/jsc.cpp	2015-07-24 06:33:53 UTC (rev 187301)
@@ -1247,12 +1247,6 @@
     ecore_init();
 #endif
 
-    // Initialize JSC before getting VM.
-#if ENABLE(SAMPLING_REGIONS)
-    WTF::initializeMainThread();
-#endif
-    JSC::initializeThreading();
-
     if (char* timeoutString = getenv("JSC_timeout")) {
         if (sscanf(timeoutString, "%lf", &s_desiredTimeout) != 1) {
             dataLog(
@@ -1428,6 +1422,8 @@
 
 void CommandLine::parseArguments(int argc, char** argv)
 {
+    Options::initialize();
+    
     int i = 1;
     bool needToDumpOptions = false;
     bool needToExit = false;
@@ -1492,8 +1488,7 @@
         }
 
         // See if the -- option is a JSC VM option.
-        // NOTE: At this point, we know that the arg starts with "--". Skip it.
-        if (JSC::Options::setOption(&arg[2])) {
+        if (strstr(arg, "--") == arg && JSC::Options::setOption(&arg[2])) {
             // The arg was recognized as a VM option and has been parsed.
             continue; // Just continue with the next arg. 
         }
@@ -1521,6 +1516,13 @@
     // Note that the options parsing can affect VM creation, and thus
     // comes first.
     CommandLine options(argc, argv);
+
+    // Initialize JSC before getting VM.
+#if ENABLE(SAMPLING_REGIONS)
+    WTF::initializeMainThread();
+#endif
+    JSC::initializeThreading();
+
     VM* vm = &VM::create(LargeHeap).leakRef();
     int result;
     {

Modified: branches/safari-601.1-branch/Source/_javascript_Core/runtime/Options.cpp (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/runtime/Options.cpp	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/runtime/Options.cpp	2015-07-24 06:33:53 UTC (rev 187301)
@@ -30,6 +30,7 @@
 #include <algorithm>
 #include <limits>
 #include <math.h>
+#include <mutex>
 #include <stdlib.h>
 #include <string.h>
 #include <wtf/DataLog.h>
@@ -201,6 +202,11 @@
     return m_state == Normal ? false : true;
 }
 
+void OptionRange::dump(PrintStream& out) const
+{
+    out.print(m_rangeString);
+}
+
 Options::Entry Options::s_options[Options::numberOfOptions];
 Options::Entry Options::s_defaultOptions[Options::numberOfOptions];
 
@@ -318,60 +324,66 @@
 
 void Options::initialize()
 {
-    // Initialize each of the options with their default values:
-#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
-    name_() = defaultValue_; \
-    name_##Default() = defaultValue_;
-    JSC_OPTIONS(FOR_EACH_OPTION)
+    static std::once_flag initializeOptionsOnceFlag;
+    
+    std::call_once(
+        initializeOptionsOnceFlag,
+        [] {
+            // Initialize each of the options with their default values:
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
+            name_() = defaultValue_;                                    \
+            name_##Default() = defaultValue_;
+            JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
     
-    // It *probably* makes sense for other platforms to enable this.
+                // It *probably* makes sense for other platforms to enable this.
 #if PLATFORM(IOS) && CPU(ARM64)
-    enableLLVMFastISel() = true;
+                enableLLVMFastISel() = true;
 #endif
         
-    // Allow environment vars to override options if applicable.
-    // The evn var should be the name of the option prefixed with
-    // "JSC_".
-#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
-    overrideOptionWithHeuristic(name_(), "JSC_" #name_);
-    JSC_OPTIONS(FOR_EACH_OPTION)
+            // Allow environment vars to override options if applicable.
+            // The evn var should be the name of the option prefixed with
+            // "JSC_".
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
+            overrideOptionWithHeuristic(name_(), "JSC_" #name_);
+            JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 
 #if 0
-    ; // Deconfuse editors that do auto indentation
+                ; // Deconfuse editors that do auto indentation
 #endif
     
-    recomputeDependentOptions();
+            recomputeDependentOptions();
 
-    // Do range checks where needed and make corrections to the options:
-    ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp());
-    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());
-    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0);
+            // Do range checks where needed and make corrections to the options:
+            ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp());
+            ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());
+            ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0);
 
-    if (Options::showOptions()) {
-        DumpLevel level = static_cast<DumpLevel>(Options::showOptions());
-        if (level > DumpLevel::Verbose)
-            level = DumpLevel::Verbose;
+            if (Options::showOptions()) {
+                DumpLevel level = static_cast<DumpLevel>(Options::showOptions());
+                if (level > DumpLevel::Verbose)
+                    level = DumpLevel::Verbose;
 
-        const char* title = nullptr;
-        switch (level) {
-        case DumpLevel::None:
-            break;
-        case DumpLevel::Overridden:
-            title = "Overridden JSC options:";
-            break;
-        case DumpLevel::All:
-            title = "All JSC options:";
-            break;
-        case DumpLevel::Verbose:
-            title = "All JSC options with descriptions:";
-            break;
-        }
-        dumpAllOptions(level, title);
-    }
+                const char* title = nullptr;
+                switch (level) {
+                case DumpLevel::None:
+                    break;
+                case DumpLevel::Overridden:
+                    title = "Overridden JSC options:";
+                    break;
+                case DumpLevel::All:
+                    title = "All JSC options:";
+                    break;
+                case DumpLevel::Verbose:
+                    title = "All JSC options with descriptions:";
+                    break;
+                }
+                dumpAllOptions(level, title);
+            }
 
-    ensureOptionsAreCoherent();
+            ensureOptionsAreCoherent();
+        });
 }
 
 // Parses a single command line option in the format "<optionName>=<value>"

Modified: branches/safari-601.1-branch/Source/_javascript_Core/runtime/Options.h (187300 => 187301)


--- branches/safari-601.1-branch/Source/_javascript_Core/runtime/Options.h	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Source/_javascript_Core/runtime/Options.h	2015-07-24 06:33:53 UTC (rev 187301)
@@ -30,6 +30,7 @@
 #include "JSExportMacros.h"
 #include <stdint.h>
 #include <stdio.h>
+#include <wtf/PrintStream.h>
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
@@ -80,6 +81,8 @@
     bool init(const char*);
     bool isInRange(unsigned);
     const char* rangeString() const { return (m_state > InitError) ? m_rangeString : "<null>"; }
+    
+    void dump(PrintStream& out) const;
 
 private:
     RangeState m_state;
@@ -106,6 +109,7 @@
     v(unsigned, errorModeReservedZoneSize, 64 * KB, nullptr) \
     \
     v(bool, crashIfCantAllocateJITMemory, false, nullptr) \
+    v(unsigned, jitMemoryReservationSize, 0, nullptr) \
     \
     v(bool, forceDFGCodeBlockLiveness, false, nullptr) \
     v(bool, forceICFailure, false, nullptr) \
@@ -349,7 +353,7 @@
         gcLogLevelType,
     };
 
-    static void initialize();
+    JS_EXPORT_PRIVATE static void initialize();
 
     // Parses a single command line option in the format "<optionName>=<value>"
     // (no spaces allowed) and set the specified option if appropriate.

Modified: branches/safari-601.1-branch/Tools/ChangeLog (187300 => 187301)


--- branches/safari-601.1-branch/Tools/ChangeLog	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Tools/ChangeLog	2015-07-24 06:33:53 UTC (rev 187301)
@@ -1,3 +1,20 @@
+2015-07-23  Lucas Forschler  <[email protected]>
+
+        Merge r187125
+
+    2015-07-21  Filip Pizlo  <[email protected]>
+
+            Fixed VM pool allocation should have a reserve for allocations that cannot fail
+            https://bugs.webkit.org/show_bug.cgi?id=147154
+            rdar://problem/21847618
+
+            Reviewed by Geoffrey Garen.
+
+            Add a new test mode where we artificially limit JIT memory to 50KB. If our JIT OOM
+            mitigations work, these should all pass. Prior to this patch there were >20 failures.
+
+            * Scripts/run-jsc-stress-tests:
+
 2015-07-20  Matthew Hanson  <[email protected]>
 
         Merge r186910. rdar://problem/21863296

Modified: branches/safari-601.1-branch/Tools/Scripts/run-jsc-stress-tests (187300 => 187301)


--- branches/safari-601.1-branch/Tools/Scripts/run-jsc-stress-tests	2015-07-24 06:31:07 UTC (rev 187300)
+++ branches/safari-601.1-branch/Tools/Scripts/run-jsc-stress-tests	2015-07-24 06:33:53 UTC (rev 187301)
@@ -758,6 +758,10 @@
     run("ftl-no-cjit-no-access-inlining", "--enableAccessInlining=false", *(FTL_OPTIONS + NO_CJIT_OPTIONS)) if $enableFTL
 end
 
+def runFTLNoCJITSmallPool
+    run("ftl-no-cjit-small-pool", "--jitMemoryReservationSize=50000", *(FTL_OPTIONS + NO_CJIT_OPTIONS)) if $enableFTL
+end
+
 def defaultRun
     runDefault
     runAlwaysTriggerCopyPhase
@@ -771,6 +775,7 @@
         runFTLNoCJITNoInlineValidate
         runFTLEager
         runFTLEagerNoCJITValidate
+        runFTLNoCJITSmallPool
     end
 end
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to