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