Title: [96463] trunk/Source/_javascript_Core
Revision
96463
Author
fpi...@apple.com
Date
2011-10-01 15:03:22 -0700 (Sat, 01 Oct 2011)

Log Message

All of JSC's heuristics should be in one place for easier tuning
https://bugs.webkit.org/show_bug.cgi?id=69201

Reviewed by Oliver Hunt.
        
This makes it possible to change tiered compilation heuristics in
one place (Heuristics.cpp) without recompiling the whole project.
        
It also makes it possible to enable setting heuristics using
environment variables. This is off by default. When turned on, it
makes tuning the system much easier.

* CMakeLists.txt:
* GNUmakefile.list.am:
* _javascript_Core.pro:
* _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shouldOptimizeNow):
* bytecode/CodeBlock.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
* jit/JIT.cpp:
(JSC::JIT::emitOptimizationCheck):
* runtime/Heuristics.cpp: Added.
(JSC::Heuristics::parse):
(JSC::Heuristics::setHeuristic):
(JSC::Heuristics::initializeHeuristics):
* runtime/Heuristics.h: Added.
* runtime/InitializeThreading.cpp:
(JSC::initializeThreadingOnce):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (96462 => 96463)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2011-10-01 22:03:22 UTC (rev 96463)
@@ -114,6 +114,7 @@
     runtime/FunctionPrototype.cpp
     runtime/GCActivityCallback.cpp
     runtime/GetterSetter.cpp
+    runtime/Heuristics.cpp
     runtime/Identifier.cpp
     runtime/InitializeThreading.cpp
     runtime/InternalFunction.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (96462 => 96463)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-01 22:03:22 UTC (rev 96463)
@@ -1,3 +1,37 @@
+2011-09-30  Filip Pizlo  <fpi...@apple.com>
+
+        All of JSC's heuristics should be in one place for easier tuning
+        https://bugs.webkit.org/show_bug.cgi?id=69201
+
+        Reviewed by Oliver Hunt.
+        
+        This makes it possible to change tiered compilation heuristics in
+        one place (Heuristics.cpp) without recompiling the whole project.
+        
+        It also makes it possible to enable setting heuristics using
+        environment variables. This is off by default. When turned on, it
+        makes tuning the system much easier.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * _javascript_Core.pro:
+        * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::shouldOptimizeNow):
+        * bytecode/CodeBlock.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
+        * jit/JIT.cpp:
+        (JSC::JIT::emitOptimizationCheck):
+        * runtime/Heuristics.cpp: Added.
+        (JSC::Heuristics::parse):
+        (JSC::Heuristics::setHeuristic):
+        (JSC::Heuristics::initializeHeuristics):
+        * runtime/Heuristics.h: Added.
+        * runtime/InitializeThreading.cpp:
+        (JSC::initializeThreadingOnce):
+
 2011-10-01  Oliver Hunt  <oli...@apple.com>
 
         Support string length in the DFG

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (96462 => 96463)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2011-10-01 22:03:22 UTC (rev 96463)
@@ -329,6 +329,8 @@
 	Source/_javascript_Core/runtime/GCActivityCallback.h \
 	Source/_javascript_Core/runtime/GetterSetter.cpp \
 	Source/_javascript_Core/runtime/GetterSetter.h \
+	Source/_javascript_Core/runtime/Heuristics.cpp \
+	Source/_javascript_Core/runtime/Heuristics.h \
 	Source/_javascript_Core/runtime/Identifier.cpp \
 	Source/_javascript_Core/runtime/Identifier.h \
 	Source/_javascript_Core/runtime/InitializeThreading.cpp \

Modified: trunk/Source/_javascript_Core/_javascript_Core.pro (96462 => 96463)


--- trunk/Source/_javascript_Core/_javascript_Core.pro	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/_javascript_Core.pro	2011-10-01 22:03:22 UTC (rev 96463)
@@ -144,6 +144,7 @@
     runtime/FunctionPrototype.cpp \
     runtime/GCActivityCallback.cpp \
     runtime/GetterSetter.cpp \
+    runtime/Heuristics.cpp \
     runtime/Identifier.cpp \
     runtime/InitializeThreading.cpp \
     runtime/InternalFunction.cpp \

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj (96462 => 96463)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2011-10-01 22:03:22 UTC (rev 96463)
@@ -734,6 +734,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\runtime\Heuristics.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\runtime\Heuristics.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\runtime\Identifier.cpp"
 				>
 			</File>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (96462 => 96463)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-10-01 22:03:22 UTC (rev 96463)
@@ -81,6 +81,8 @@
 		0FD82F2B1426CA6D00179C94 /* JettisonedCodeBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82F291426CA5A00179C94 /* JettisonedCodeBlocks.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FD82F2C1426CA7400179C94 /* JettisonedCodeBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD82F281426CA5A00179C94 /* JettisonedCodeBlocks.cpp */; };
 		0FD82F4B142806A100179C94 /* BitVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82F491428069200179C94 /* BitVector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE228ED1436AB2700196C48 /* Heuristics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Heuristics.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE228EE1436AB2C00196C48 /* Heuristics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Heuristics.cpp */; };
 		1400067712A6F7830064D123 /* OSAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1400067612A6F7830064D123 /* OSAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1400069312A6F9E10064D123 /* OSAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */; };
 		140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
@@ -836,6 +838,8 @@
 		0FD82F281426CA5A00179C94 /* JettisonedCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JettisonedCodeBlocks.cpp; sourceTree = "<group>"; };
 		0FD82F291426CA5A00179C94 /* JettisonedCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JettisonedCodeBlocks.h; sourceTree = "<group>"; };
 		0FD82F491428069200179C94 /* BitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitVector.h; sourceTree = "<group>"; };
+		0FE228EA1436AB2300196C48 /* Heuristics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Heuristics.cpp; sourceTree = "<group>"; };
+		0FE228EB1436AB2300196C48 /* Heuristics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Heuristics.h; sourceTree = "<group>"; };
 		1400067612A6F7830064D123 /* OSAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSAllocator.h; sourceTree = "<group>"; };
 		1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSAllocatorPosix.cpp; sourceTree = "<group>"; };
 		140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
@@ -2029,6 +2033,8 @@
 		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
 			isa = PBXGroup;
 			children = (
+				0FE228EA1436AB2300196C48 /* Heuristics.cpp */,
+				0FE228EB1436AB2300196C48 /* Heuristics.h */,
 				0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
 				0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
 				BCF605110E203EF800B9A64D /* ArgList.cpp */,
@@ -2856,6 +2862,7 @@
 				A7521E131429169A003C8D0C /* CardSet.h in Headers */,
 				0FD52AAE143035A00026DC9F /* UnionFind.h in Headers */,
 				86880F1E14328BB900B08D42 /* DFGJITCompilerInlineMethods.h in Headers */,
+				0FE228ED1436AB2700196C48 /* Heuristics.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3386,6 +3393,7 @@
 				86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
 				86880F44143531A800B08D42 /* DFGJITCodeGenerator64.cpp in Sources */,
 				86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */,
+				0FE228EE1436AB2C00196C48 /* Heuristics.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (96462 => 96463)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-10-01 22:03:22 UTC (rev 96463)
@@ -1972,7 +1972,7 @@
     dumpValueProfiles();
 #endif
 
-    if (m_optimizationDelayCounter >= 5)
+    if (m_optimizationDelayCounter >= Heuristics::maximumOptimizationDelay)
         return true;
     
     unsigned numberOfNonArgumentValueProfiles = 0;
@@ -1998,8 +1998,8 @@
     printf("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles, (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles());
 #endif
 
-    if ((!numberOfNonArgumentValueProfiles || (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles >= 0.75)
-        && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= 0.25))
+    if ((!numberOfNonArgumentValueProfiles || (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles >= Heuristics::desiredProfileLivenessRate)
+        && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= Heuristics::desiredProfileFullnessRate))
         return true;
     
     m_optimizationDelayCounter++;

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (96462 => 96463)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-10-01 22:03:22 UTC (rev 96463)
@@ -33,6 +33,7 @@
 #include "CompactJITCodeMap.h"
 #include "DFGOSREntry.h"
 #include "EvalCodeCache.h"
+#include "Heuristics.h"
 #include "Instruction.h"
 #include "JITCode.h"
 #include "JITWriteBarrier.h"
@@ -718,32 +719,25 @@
         // to avoid thrashing.
         unsigned reoptimizationRetryCounter() const
         {
-            ASSERT(m_reoptimizationRetryCounter <= 18);
+            ASSERT(m_reoptimizationRetryCounter <= Heuristics::reoptimizationRetryCounterMax);
             return m_reoptimizationRetryCounter;
         }
         
         void countReoptimization()
         {
             m_reoptimizationRetryCounter++;
-            if (m_reoptimizationRetryCounter > 18)
-                m_reoptimizationRetryCounter = 18;
+            if (m_reoptimizationRetryCounter > Heuristics::reoptimizationRetryCounterMax)
+                m_reoptimizationRetryCounter = Heuristics::reoptimizationRetryCounterMax;
         }
         
-        // These functions are provided to support calling
-        // optimizeXYZ() methods from JIT-generated code.
-        static int32_t counterValueForOptimizeNextInvocation()
-        {
-            return 0;
-        }
-        
         int32_t counterValueForOptimizeAfterWarmUp()
         {
-            return -1000 << reoptimizationRetryCounter();
+            return Heuristics::executionCounterValueForOptimizeAfterWarmUp << reoptimizationRetryCounter();
         }
         
         int32_t counterValueForOptimizeAfterLongWarmUp()
         {
-            return -5000 << reoptimizationRetryCounter();
+            return Heuristics::executionCounterValueForOptimizeAfterLongWarmUp << reoptimizationRetryCounter();
         }
         
         int32_t* addressOfExecuteCounter()
@@ -762,7 +756,7 @@
         // expensive than executing baseline code.
         void optimizeNextInvocation()
         {
-            m_executeCounter = counterValueForOptimizeNextInvocation();
+            m_executeCounter = Heuristics::executionCounterValueForOptimizeNextInvocation;
         }
         
         // Call this to prevent optimization from happening again. Note that
@@ -772,7 +766,7 @@
         // the future as well.
         void dontOptimizeAnytimeSoon()
         {
-            m_executeCounter = std::numeric_limits<int32_t>::min();
+            m_executeCounter = Heuristics::executionCounterValueForDontOptimizeAnytimeSoon;
         }
         
         // Call this to reinitialize the counter to its starting state,
@@ -813,7 +807,7 @@
         // in the baseline code.
         void optimizeSoon()
         {
-            m_executeCounter = -100 << reoptimizationRetryCounter();
+            m_executeCounter = Heuristics::executionCounterValueForOptimizeSoon << reoptimizationRetryCounter();
         }
         
         // The speculative JIT tracks its success rate, so that we can
@@ -845,25 +839,18 @@
         static ptrdiff_t offsetOfSpeculativeSuccessCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeSuccessCounter); }
         static ptrdiff_t offsetOfSpeculativeFailCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeFailCounter); }
         
-        // The amount by which the JIT will increment m_executeCounter.
-        static unsigned executeCounterIncrementForLoop() { return 1; }
-        static unsigned executeCounterIncrementForReturn() { return 15; }
-
-        // The success/failure ratio we want.
-        unsigned desiredSuccessFailRatio() { return 6; }
-        
         // The number of failures that triggers the use of the ratio.
-        unsigned largeFailCountThreshold() { return 20 << alternative()->reoptimizationRetryCounter(); }
-        unsigned largeFailCountThresholdForLoop() { return 1 << alternative()->reoptimizationRetryCounter(); }
+        unsigned largeFailCountThreshold() { return Heuristics::largeFailCountThresholdBase << alternative()->reoptimizationRetryCounter(); }
+        unsigned largeFailCountThresholdForLoop() { return Heuristics::largeFailCountThresholdBaseForLoop << alternative()->reoptimizationRetryCounter(); }
         
         bool shouldReoptimizeNow()
         {
-            return desiredSuccessFailRatio() * speculativeFailCounter() >= speculativeSuccessCounter() && speculativeFailCounter() >= largeFailCountThreshold();
+            return Heuristics::desiredSpeculativeSuccessFailRatio * speculativeFailCounter() >= speculativeSuccessCounter() && speculativeFailCounter() >= largeFailCountThreshold();
         }
         
         bool shouldReoptimizeFromLoopNow()
         {
-            return desiredSuccessFailRatio() * speculativeFailCounter() >= speculativeSuccessCounter() && speculativeFailCounter() >= largeFailCountThresholdForLoop();
+            return Heuristics::desiredSpeculativeSuccessFailRatio * speculativeFailCounter() >= speculativeSuccessCounter() && speculativeFailCounter() >= largeFailCountThresholdForLoop();
         }
         
 #if ENABLE(VALUE_PROFILER)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (96462 => 96463)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-10-01 22:03:22 UTC (rev 96463)
@@ -451,12 +451,12 @@
     move(TrustedImmPtr(codeBlock()->alternative()), GPRInfo::regT0);
     
     Jump fewFails = branch32(BelowOrEqual, GPRInfo::regT2, Imm32(codeBlock()->largeFailCountThreshold()));
-    mul32(Imm32(codeBlock()->desiredSuccessFailRatio()), GPRInfo::regT2, GPRInfo::regT2);
+    mul32(Imm32(Heuristics::desiredSpeculativeSuccessFailRatio), GPRInfo::regT2, GPRInfo::regT2);
     
     Jump lowFailRate = branch32(BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1);
     
     // Reoptimize as soon as possible.
-    store32(Imm32(CodeBlock::counterValueForOptimizeNextInvocation()), Address(GPRInfo::regT0, CodeBlock::offsetOfExecuteCounter()));
+    store32(Imm32(Heuristics::executionCounterValueForOptimizeNextInvocation), Address(GPRInfo::regT0, CodeBlock::offsetOfExecuteCounter()));
     Jump doneAdjusting = jump();
     
     fewFails.link(this);

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (96462 => 96463)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2011-10-01 22:03:22 UTC (rev 96463)
@@ -99,7 +99,7 @@
     if (!shouldEmitProfiling())
         return;
     
-    Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? CodeBlock::executeCounterIncrementForLoop() : CodeBlock::executeCounterIncrementForReturn()), AbsoluteAddress(m_codeBlock->addressOfExecuteCounter()));
+    Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Heuristics::executionCounterIncrementForLoop : Heuristics::executionCounterIncrementForReturn), AbsoluteAddress(m_codeBlock->addressOfExecuteCounter()));
     JITStubCall stubCall(this, kind == LoopOptimizationCheck ? cti_optimize_from_loop : cti_optimize_from_ret);
     if (kind == LoopOptimizationCheck)
         stubCall.addArgument(Imm32(m_bytecodeOffset));

Added: trunk/Source/_javascript_Core/runtime/Heuristics.cpp (0 => 96463)


--- trunk/Source/_javascript_Core/runtime/Heuristics.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/Heuristics.cpp	2011-10-01 22:03:22 UTC (rev 96463)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "Heuristics.h"
+
+#include <limits>
+
+// Set to 1 to control the heuristics using environment variables.
+#define ENABLE_RUN_TIME_HEURISTICS 0
+
+#if ENABLE(RUN_TIME_HEURISTICS)
+#include <stdio.h>
+#include <stdlib.h>
+#include <wtf/StdLibExtras.h>
+#endif
+
+namespace JSC { namespace Heuristics {
+
+int32_t executionCounterValueForOptimizeAfterWarmUp;
+int32_t executionCounterValueForOptimizeAfterLongWarmUp;
+int32_t executionCounterValueForDontOptimizeAnytimeSoon;
+int32_t executionCounterValueForOptimizeSoon;
+int32_t executionCounterValueForOptimizeNextInvocation;
+
+int32_t executionCounterIncrementForLoop;
+int32_t executionCounterIncrementForReturn;
+
+unsigned desiredSpeculativeSuccessFailRatio;
+
+unsigned largeFailCountThresholdBase;
+unsigned largeFailCountThresholdBaseForLoop;
+
+unsigned reoptimizationRetryCounterMax;
+unsigned reoptimizationRetryCounterStep;
+
+unsigned maximumOptimizationDelay;
+double desiredProfileLivenessRate;
+double desiredProfileFullnessRate;
+
+#if ENABLE(RUN_TIME_HEURISTICS)
+static bool parse(const char* string, int32_t& value)
+{
+    return sscanf(string, "%d", &value) == 1;
+}
+
+static bool parse(const char* string, unsigned& value)
+{
+    return sscanf(string, "%u", &value) == 1;
+}
+
+static bool parse(const char* string, double& value)
+{
+    return sscanf(string, "%lf", &value) == 1;
+}
+
+template<typename T, typename U>
+void setHeuristic(T& variable, const char* name, U value)
+{
+    const char* stringValue = getenv(name);
+    if (!stringValue) {
+        variable = safeCast<T>(value);
+        return;
+    }
+    
+    if (parse(stringValue, variable))
+        return;
+    
+    fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
+    variable = safeCast<T>(value);
+}
+
+#define SET(variable, value) setHeuristic(variable, "JSC_" #variable, value)
+#else
+#define SET(variable, value) variable = value
+#endif
+
+void initializeHeuristics()
+{
+    SET(executionCounterValueForOptimizeAfterWarmUp,     -1000);
+    SET(executionCounterValueForOptimizeAfterLongWarmUp, -5000);
+    SET(executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min());
+    SET(executionCounterValueForOptimizeSoon,            -100);
+    SET(executionCounterValueForOptimizeNextInvocation,  0);
+
+    SET(executionCounterIncrementForLoop,   1);
+    SET(executionCounterIncrementForReturn, 15);
+
+    SET(desiredSpeculativeSuccessFailRatio, 6);
+
+    SET(largeFailCountThresholdBase,        20);
+    SET(largeFailCountThresholdBaseForLoop, 1);
+
+    SET(reoptimizationRetryCounterStep, 1);
+
+    SET(maximumOptimizationDelay,   5);
+    SET(desiredProfileLivenessRate, 0.75);
+    SET(desiredProfileFullnessRate, 0.25);
+    
+    ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp);
+    ASSERT(executionCounterValueForOptimizeAfterLongWarmUp <= executionCounterValueForOptimizeAfterWarmUp);
+    ASSERT(executionCounterValueForOptimizeAfterWarmUp <= executionCounterValueForOptimizeSoon);
+    ASSERT(executionCounterValueForOptimizeAfterWarmUp < 0);
+    ASSERT(executionCounterValueForOptimizeSoon <= executionCounterValueForOptimizeNextInvocation);
+    
+    // Compute the maximum value of the reoptimization retry counter. This is simply
+    // the largest value at which we don't overflow the execute counter, when using it
+    // to left-shift the execution counter by this amount. Currently the value ends
+    // up being 18, so this loop is not so terrible; it probably takes up ~100 cycles
+    // total on a 32-bit processor.
+    reoptimizationRetryCounterMax = 0;
+    while ((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << (reoptimizationRetryCounterMax + 1)) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min()))
+        reoptimizationRetryCounterMax++;
+    
+    ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) < 0);
+    ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min()));
+}
+
+} } // namespace JSC::Heuristics
+
+

Added: trunk/Source/_javascript_Core/runtime/Heuristics.h (0 => 96463)


--- trunk/Source/_javascript_Core/runtime/Heuristics.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/Heuristics.h	2011-10-01 22:03:22 UTC (rev 96463)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef Heuristics_h
+#define Heuristics_h
+
+#include <stdint.h>
+
+namespace JSC { namespace Heuristics {
+
+extern int32_t executionCounterValueForOptimizeAfterWarmUp;
+extern int32_t executionCounterValueForOptimizeAfterLongWarmUp;
+extern int32_t executionCounterValueForDontOptimizeAnytimeSoon;
+extern int32_t executionCounterValueForOptimizeSoon;
+extern int32_t executionCounterValueForOptimizeNextInvocation;
+
+extern int32_t executionCounterIncrementForLoop;
+extern int32_t executionCounterIncrementForReturn;
+
+extern unsigned desiredSpeculativeSuccessFailRatio;
+
+extern unsigned largeFailCountThresholdBase;
+extern unsigned largeFailCountThresholdBaseForLoop;
+
+extern unsigned reoptimizationRetryCounterMax;
+extern unsigned reoptimizationRetryCounterStep;
+
+extern unsigned maximumOptimizationDelay;
+extern double desiredProfileLivenessRate;
+extern double desiredProfileFullnessRate;
+
+void initializeHeuristics();
+
+} } // namespace JSC::Heuristics
+
+#endif // Heuristics_h
+

Modified: trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp (96462 => 96463)


--- trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp	2011-10-01 21:58:45 UTC (rev 96462)
+++ trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp	2011-10-01 22:03:22 UTC (rev 96463)
@@ -31,6 +31,7 @@
 
 #include "ExecutableAllocator.h"
 #include "Heap.h"
+#include "Heuristics.h"
 #include "Identifier.h"
 #include "JSGlobalObject.h"
 #include "UString.h"
@@ -52,6 +53,7 @@
 {
     WTF::double_conversion::initialize();
     WTF::initializeThreading();
+    Heuristics::initializeHeuristics();
 #if ENABLE(WRITE_BARRIER_PROFILING)
     WriteBarrierCounters::initialize();
 #endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to