Log Message
Value profiling should use tier-up threshold randomization to get more coverage https://bugs.webkit.org/show_bug.cgi?id=89802
Source/_javascript_Core:
Reviewed by Gavin Barraclough.
This patch causes both LLInt and Baseline JIT code to take the OSR slow path several
times before actually doing OSR. If we take the OSR slow path before the execution
count threshold is reached, then we just call CodeBlock::updateAllPredictions() to
compute the current latest least-upper-bound SpecType of all values seen in each
ValueProfile.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::stronglyVisitStrongReferences):
(JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
(JSC):
(JSC::CodeBlock::updateAllPredictions):
(JSC::CodeBlock::shouldOptimizeNow):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::llintExecuteCounter):
(JSC::CodeBlock::jitExecuteCounter):
(CodeBlock):
(JSC::CodeBlock::updateAllPredictions):
* bytecode/ExecutionCounter.cpp:
(JSC::ExecutionCounter::setThreshold):
(JSC::ExecutionCounter::status):
(JSC):
* bytecode/ExecutionCounter.h:
(JSC::ExecutionCounter::count):
(ExecutionCounter):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::entryOSR):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC):
* runtime/JSGlobalObject.h:
(JSGlobalObject):
(JSC::JSGlobalObject::weakRandomInteger):
* runtime/Options.cpp:
(Options):
(JSC::Options::initializeOptions):
* runtime/Options.h:
(Options):
* runtime/WeakRandom.h:
(WeakRandom):
(JSC::WeakRandom::seedUnsafe):
LayoutTests:
Reviewed by Gavin Barraclough.
* fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit-expected.txt: Added.
* fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html: Added.
* fast/js/script-tests/dfg-store-unexpected-value-into-argument-and-osr-exit.js: Added.
(foo):
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/Source/_javascript_Core/ChangeLog
- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def
- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp
- trunk/Source/_javascript_Core/bytecode/CodeBlock.h
- trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp
- trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h
- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp
- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp
- trunk/Source/_javascript_Core/jit/JITStubs.cpp
- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp
- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp
- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h
- trunk/Source/_javascript_Core/runtime/Options.cpp
- trunk/Source/_javascript_Core/runtime/Options.h
- trunk/Source/_javascript_Core/runtime/WeakRandom.h
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (121214 => 121215)
--- trunk/LayoutTests/ChangeLog 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/LayoutTests/ChangeLog 2012-06-26 02:14:07 UTC (rev 121215)
@@ -1,3 +1,15 @@
+2012-06-25 Filip Pizlo <[email protected]>
+
+ Value profiling should use tier-up threshold randomization to get more coverage
+ https://bugs.webkit.org/show_bug.cgi?id=89802
+
+ Reviewed by Gavin Barraclough.
+
+ * fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit-expected.txt: Added.
+ * fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html: Added.
+ * fast/js/script-tests/dfg-store-unexpected-value-into-argument-and-osr-exit.js: Added.
+ (foo):
+
2012-06-25 Shinya Kawanaka <[email protected]>
[Shadow] Deleting list distributed to Shadow DOM does not work correctly.
Added: trunk/LayoutTests/fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit-expected.txt (0 => 121215)
--- trunk/LayoutTests/fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit-expected.txt 2012-06-26 02:14:07 UTC (rev 121215)
@@ -0,0 +1,209 @@
+Tests what happens when you store an unexpected value into an argument (where the original argument value was the expected one) and then OSR exit.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 1
+PASS foo(3, {f:f, g:g}, p) is 85
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS foo(3, {f:f, g:g}, p) is 0.5
+PASS foo(3, {f:f, g:g}, p) is 85.5
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html (0 => 121215)
--- trunk/LayoutTests/fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html 2012-06-26 02:14:07 UTC (rev 121215)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/script-tests/dfg-store-unexpected-value-into-argument-and-osr-exit.js (0 => 121215)
--- trunk/LayoutTests/fast/js/script-tests/dfg-store-unexpected-value-into-argument-and-osr-exit.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-store-unexpected-value-into-argument-and-osr-exit.js 2012-06-26 02:14:07 UTC (rev 121215)
@@ -0,0 +1,41 @@
+description(
+"Tests what happens when you store an unexpected value into an argument (where the original argument value was the expected one) and then OSR exit."
+);
+
+function foo(x, o, p) {
+ x = o.f;
+ if (p) {
+ var result = o.g + x;
+ x = true; // Force x to not have a hoisted integer speculation.
+ return result;
+ } else
+ return o.g - x;
+}
+
+for (var i = 0; i < 200; ++i) {
+ var expected;
+ var p, f, g;
+ if (i < 150) {
+ f = 42;
+ g = 43;
+ if (i%2) {
+ p = true;
+ expected = 85;
+ } else {
+ p = false;
+ expected = 1;
+ }
+ } else {
+ f = 42.5;
+ g = 43;
+ if (i%2) {
+ p = true;
+ expected = 85.5;
+ } else {
+ p = false;
+ expected = 0.5;
+ }
+ }
+ shouldBe("foo(3, {f:f, g:g}, p)", "" + expected);
+}
+
Modified: trunk/Source/_javascript_Core/ChangeLog (121214 => 121215)
--- trunk/Source/_javascript_Core/ChangeLog 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-06-26 02:14:07 UTC (rev 121215)
@@ -1,3 +1,60 @@
+2012-06-22 Filip Pizlo <[email protected]>
+
+ Value profiling should use tier-up threshold randomization to get more coverage
+ https://bugs.webkit.org/show_bug.cgi?id=89802
+
+ Reviewed by Gavin Barraclough.
+
+ This patch causes both LLInt and Baseline JIT code to take the OSR slow path several
+ times before actually doing OSR. If we take the OSR slow path before the execution
+ count threshold is reached, then we just call CodeBlock::updateAllPredictions() to
+ compute the current latest least-upper-bound SpecType of all values seen in each
+ ValueProfile.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::stronglyVisitStrongReferences):
+ (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
+ (JSC):
+ (JSC::CodeBlock::updateAllPredictions):
+ (JSC::CodeBlock::shouldOptimizeNow):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::llintExecuteCounter):
+ (JSC::CodeBlock::jitExecuteCounter):
+ (CodeBlock):
+ (JSC::CodeBlock::updateAllPredictions):
+ * bytecode/ExecutionCounter.cpp:
+ (JSC::ExecutionCounter::setThreshold):
+ (JSC::ExecutionCounter::status):
+ (JSC):
+ * bytecode/ExecutionCounter.h:
+ (JSC::ExecutionCounter::count):
+ (ExecutionCounter):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ (JSC::LLInt::entryOSR):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ (JSC):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::weakRandomInteger):
+ * runtime/Options.cpp:
+ (Options):
+ (JSC::Options::initializeOptions):
+ * runtime/Options.h:
+ (Options):
+ * runtime/WeakRandom.h:
+ (WeakRandom):
+ (JSC::WeakRandom::seedUnsafe):
+
2012-06-25 Yong Li <[email protected]>
[BlackBerry] Add JSC statistics into about:memory
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (121214 => 121215)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-06-26 02:14:07 UTC (rev 121215)
@@ -9,6 +9,7 @@
??0DropAllLocks@JSLock@JSC@@QAE@W4JSLockBehavior@2@@Z
??0DynamicGlobalObjectScope@JSC@@QAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@@Z
??0InternalFunction@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@@Z
+ ??0JSGlobalObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@PBUGlobalObjectMethodTable@1@@Z
??0JSLock@JSC@@QAE@PAVExecState@1@@Z
??0MD5@WTF@@QAE@XZ
??0Mutex@WTF@@QAE@XZ
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -2104,26 +2104,7 @@
}
#endif
-#if ENABLE(DFG_JIT)
- if (hasCodeOrigins()) {
- // Make sure that executables that we have inlined don't die.
- // FIXME: If they would have otherwise died, we should probably trigger recompilation.
- for (size_t i = 0; i < inlineCallFrames().size(); ++i) {
- InlineCallFrame& inlineCallFrame = inlineCallFrames()[i];
- visitor.append(&inlineCallFrame.executable);
- visitor.append(&inlineCallFrame.callee);
- }
- }
-
- m_lazyOperandValueProfiles.computeUpdatedPredictions(Collection);
-#endif
-
-#if ENABLE(VALUE_PROFILER)
- for (unsigned profileIndex = 0; profileIndex < numberOfArgumentValueProfiles(); ++profileIndex)
- valueProfileForArgument(profileIndex)->computeUpdatedPrediction(Collection);
- for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex)
- valueProfile(profileIndex)->computeUpdatedPrediction(Collection);
-#endif
+ updateAllPredictions(Collection);
}
void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
@@ -2574,21 +2555,11 @@
#endif
#if ENABLE(VALUE_PROFILER)
-bool CodeBlock::shouldOptimizeNow()
+void CodeBlock::updateAllPredictionsAndCountLiveness(
+ OperationInProgress operation, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles)
{
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Considering optimizing %p...\n", this);
-#endif
-
-#if ENABLE(VERBOSE_VALUE_PROFILE)
- dumpValueProfiles();
-#endif
-
- if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay)
- return true;
-
- unsigned numberOfLiveNonArgumentValueProfiles = 0;
- unsigned numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full.
+ numberOfLiveNonArgumentValueProfiles = 0;
+ numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full.
for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) {
ValueProfile* profile = ""
unsigned numSamples = profile->totalNumberOfSamples();
@@ -2596,15 +2567,43 @@
numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight.
numberOfSamplesInProfiles += numSamples;
if (profile->m_bytecodeOffset < 0) {
- profile->computeUpdatedPrediction();
+ profile->computeUpdatedPrediction(operation);
continue;
}
if (profile->numberOfSamples() || profile->m_prediction != SpecNone)
numberOfLiveNonArgumentValueProfiles++;
- profile->computeUpdatedPrediction();
+ profile->computeUpdatedPrediction(operation);
}
+
+#if ENABLE(DFG_JIT)
+ m_lazyOperandValueProfiles.computeUpdatedPredictions(operation);
+#endif
+}
+void CodeBlock::updateAllPredictions(OperationInProgress operation)
+{
+ unsigned ignoredValue1, ignoredValue2;
+ updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2);
+}
+
+bool CodeBlock::shouldOptimizeNow()
+{
#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog("Considering optimizing %p...\n", this);
+#endif
+
+#if ENABLE(VERBOSE_VALUE_PROFILE)
+ dumpValueProfiles();
+#endif
+
+ if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay)
+ return true;
+
+ unsigned numberOfLiveNonArgumentValueProfiles;
+ unsigned numberOfSamplesInProfiles;
+ updateAllPredictionsAndCountLiveness(NoOperation, numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles);
+
+#if ENABLE(JIT_VERBOSE_OSR)
dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles());
#endif
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (121214 => 121215)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-06-26 02:14:07 UTC (rev 121215)
@@ -913,9 +913,9 @@
m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon, this);
}
- int32_t llintExecuteCounter() const
+ const ExecutionCounter& llintExecuteCounter() const
{
- return m_llintExecuteCounter.m_counter;
+ return m_llintExecuteCounter;
}
// Functions for controlling when tiered compilation kicks in. This
@@ -971,7 +971,7 @@
static ptrdiff_t offsetOfJITExecutionActiveThreshold() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_activeThreshold); }
static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_totalCount); }
- int32_t jitExecuteCounter() const { return m_jitExecuteCounter.m_counter; }
+ const ExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; }
unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; }
@@ -1100,8 +1100,10 @@
#if ENABLE(VALUE_PROFILER)
bool shouldOptimizeNow();
+ void updateAllPredictions(OperationInProgress = NoOperation);
#else
bool shouldOptimizeNow() { return false; }
+ void updateAllPredictions(OperationInProgress = NoOperation) { }
#endif
#if ENABLE(JIT)
@@ -1134,6 +1136,9 @@
#else
void tallyFrequentExitSites() { }
#endif
+#if ENABLE(VALUE_PROFILER)
+ void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
+#endif
void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&);
Modified: trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/bytecode/ExecutionCounter.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -28,6 +28,7 @@
#include "CodeBlock.h"
#include "ExecutableAllocator.h"
+#include <wtf/StringExtras.h>
namespace JSC {
@@ -125,7 +126,7 @@
ASSERT(!hasCrossedThreshold(codeBlock));
// Compute the true total count.
- double trueTotalCount = static_cast<double>(m_totalCount) + m_counter;
+ double trueTotalCount = count();
// Correct the threshold for current memory usage.
double threshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock);
@@ -143,9 +144,11 @@
return true;
}
- if (threshold > std::numeric_limits<int32_t>::max())
- threshold = std::numeric_limits<int32_t>::max();
-
+ int32_t maxThreshold =
+ codeBlock->globalObject()->weakRandomInteger() % Options::maximumExecutionCountsBetweenCheckpoints;
+ if (threshold > maxThreshold)
+ threshold = maxThreshold;
+
m_counter = static_cast<int32_t>(-threshold);
m_totalCount = trueTotalCount + threshold;
@@ -160,5 +163,12 @@
m_activeThreshold = 0;
}
+const char* ExecutionCounter::status() const
+{
+ static char result[80];
+ snprintf(result, sizeof(result), "%lf/%lf, %d", count(), static_cast<double>(m_activeThreshold), m_counter);
+ return result;
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h (121214 => 121215)
--- trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/bytecode/ExecutionCounter.h 2012-06-26 02:14:07 UTC (rev 121215)
@@ -38,6 +38,8 @@
bool checkIfThresholdCrossedAndSet(CodeBlock*);
void setNewThreshold(int32_t threshold, CodeBlock*);
void deferIndefinitely();
+ double count() const { return static_cast<double>(m_totalCount) + m_counter; }
+ const char* status() const;
static double applyMemoryUsageHeuristics(int32_t value, CodeBlock*);
static int32_t applyMemoryUsageHeuristicsAndConvertToInt(int32_t value, CodeBlock*);
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -1392,7 +1392,7 @@
case StructureTransitionWatchpoint: {
// FIXME: Turn CheckStructure into StructureTransitionWatchpoint when possible!
AbstractValue& value = forNode(node.child1());
- ASSERT(isCellSpeculation(value.m_type));
+ ASSERT(value.isClear() || isCellSpeculation(value.m_type)); // Value could be clear if we've proven must-exit due to a speculation statically known to be bad.
value.filter(node.structure());
node.setCanExit(true);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -1238,12 +1238,12 @@
SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
CodeBlock* codeBlock = debugInfo->codeBlock;
CodeBlock* alternative = codeBlock->alternative();
- dataLog("Speculation failure in %p at @%u with executeCounter = %d, "
+ dataLog("Speculation failure in %p at @%u with executeCounter = %s, "
"reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, "
"success/fail %u/(%u+%u)\n",
codeBlock,
debugInfo->nodeIndex,
- alternative ? alternative->jitExecuteCounter() : 0,
+ alternative ? alternative->jitExecuteCounter().status() : 0,
alternative ? alternative->reoptimizationRetryCounter() : 0,
alternative ? alternative->optimizationDelayCounter() : 0,
codeBlock->speculativeSuccessCounter(),
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -986,13 +986,8 @@
m_jit.jitAssertHasValidCallFrame();
ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
- for (size_t i = 0; i < m_arguments.size(); ++i) {
- NodeIndex nodeIndex = block.variablesAtHead.argument(i);
- if (nodeIndex == NoNode || m_jit.codeBlock()->argumentIsCaptured(i))
- m_arguments[i] = ValueSource(ValueInRegisterFile);
- else
- m_arguments[i] = ValueSource::forSpeculation(at(nodeIndex).variableAccessData()->prediction());
- }
+ for (size_t i = 0; i < m_arguments.size(); ++i)
+ m_arguments[i] = ValueSource(ValueInRegisterFile);
m_state.reset();
m_state.beginBasicBlock(&block);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -1928,11 +1928,13 @@
unsigned bytecodeIndex = stackFrame.args[0].int32();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
+ dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %s, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter().status(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
#endif
- if (!codeBlock->checkIfOptimizationThresholdReached())
+ if (!codeBlock->checkIfOptimizationThresholdReached()) {
+ codeBlock->updateAllPredictions();
return;
+ }
if (codeBlock->hasOptimizedReplacement()) {
#if ENABLE(JIT_VERBOSE_OSR)
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -264,6 +264,8 @@
// Returns true if we should try to OSR.
inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
{
+ codeBlock->updateAllPredictions();
+
if (!codeBlock->checkIfJITThresholdReached()) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLog(" JIT threshold should be lifted.\n");
@@ -300,7 +302,8 @@
static SlowPathReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
{
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered %s with executeCounter = %d\n", codeBlock, name, codeBlock->llintExecuteCounter());
+ dataLog("%p: Entered %s with executeCounter = %s\n", codeBlock, name,
+ codeBlock->llintExecuteCounter().status());
#endif
if (!shouldJIT(exec)) {
@@ -346,7 +349,8 @@
CodeBlock* codeBlock = exec->codeBlock();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered loop_osr with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
+ dataLog("%p: Entered loop_osr with executeCounter = %s\n", codeBlock,
+ codeBlock->llintExecuteCounter().status());
#endif
if (!shouldJIT(exec)) {
@@ -376,7 +380,8 @@
CodeBlock* codeBlock = exec->codeBlock();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
+ dataLog("%p: Entered replace with executeCounter = %s\n", codeBlock,
+ codeBlock->llintExecuteCounter().status());
#endif
if (shouldJIT(exec))
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -112,6 +112,15 @@
visitor.append(v);
}
+JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
+ : JSSegmentedVariableObject(globalData, structure, &m_symbolTable)
+ , m_globalScopeChain()
+ , m_weakRandom(Options::forceWeakRandomSeed ? Options::forcedWeakRandomSeed : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
+ , m_evalEnabled(true)
+ , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
+{
+}
+
JSGlobalObject::~JSGlobalObject()
{
ASSERT(JSLock::currentThreadIsHoldingLock());
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (121214 => 121215)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2012-06-26 02:14:07 UTC (rev 121215)
@@ -175,14 +175,7 @@
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- explicit JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable = 0)
- : JSSegmentedVariableObject(globalData, structure, &m_symbolTable)
- , m_globalScopeChain()
- , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
- , m_evalEnabled(true)
- , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
- {
- }
+ JS_EXPORT_PRIVATE explicit JSGlobalObject(JSGlobalData&, Structure*, const GlobalObjectMethodTable* = 0);
void finishCreation(JSGlobalData& globalData)
{
@@ -328,6 +321,7 @@
}
double weakRandomNumber() { return m_weakRandom.get(); }
+ unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSSegmentedVariableObject::StructureFlags;
Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (121214 => 121215)
--- trunk/Source/_javascript_Core/runtime/Options.cpp 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp 2012-06-26 02:14:07 UTC (rev 121215)
@@ -67,6 +67,8 @@
int32_t executionCounterIncrementForLoop;
int32_t executionCounterIncrementForReturn;
+int32_t maximumExecutionCountsBetweenCheckpoints;
+
unsigned desiredSpeculativeSuccessFailRatio;
double likelyToTakeSlowCaseThreshold;
@@ -95,6 +97,9 @@
unsigned numberOfGCMarkers;
unsigned opaqueRootMergeThreshold;
+bool forceWeakRandomSeed;
+unsigned forcedWeakRandomSeed;
+
#if ENABLE(RUN_TIME_HEURISTICS)
static bool parse(const char* string, bool& value)
{
@@ -184,6 +189,8 @@
SET(executionCounterIncrementForLoop, 1);
SET(executionCounterIncrementForReturn, 15);
+
+ SET(maximumExecutionCountsBetweenCheckpoints, 1000);
SET(desiredSpeculativeSuccessFailRatio, 6);
@@ -227,6 +234,9 @@
ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) > 0);
ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max()));
+
+ SET(forceWeakRandomSeed, false);
+ SET(forcedWeakRandomSeed, 0);
}
} } // namespace JSC::Options
Modified: trunk/Source/_javascript_Core/runtime/Options.h (121214 => 121215)
--- trunk/Source/_javascript_Core/runtime/Options.h 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2012-06-26 02:14:07 UTC (rev 121215)
@@ -53,6 +53,8 @@
extern int32_t executionCounterIncrementForLoop;
extern int32_t executionCounterIncrementForReturn;
+extern int32_t maximumExecutionCountsBetweenCheckpoints;
+
extern unsigned desiredSpeculativeSuccessFailRatio;
extern double likelyToTakeSlowCaseThreshold;
@@ -81,6 +83,9 @@
JS_EXPORTDATA extern unsigned numberOfGCMarkers;
JS_EXPORTDATA extern unsigned opaqueRootMergeThreshold;
+extern bool forceWeakRandomSeed;
+extern unsigned forcedWeakRandomSeed;
+
void initializeOptions();
} } // namespace JSC::Options
Modified: trunk/Source/_javascript_Core/runtime/WeakRandom.h (121214 => 121215)
--- trunk/Source/_javascript_Core/runtime/WeakRandom.h 2012-06-26 02:02:32 UTC (rev 121214)
+++ trunk/Source/_javascript_Core/runtime/WeakRandom.h 2012-06-26 02:14:07 UTC (rev 121215)
@@ -62,6 +62,9 @@
, m_high(seed)
{
}
+
+ // Returns the seed provided that you've never called get() or getUint32().
+ unsigned seedUnsafe() const { return m_high; }
double get()
{
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
