<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[163517] trunk/Source/JavaScriptCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/163517">163517</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-02-05 23:11:48 -0800 (Wed, 05 Feb 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Make FTL OSR entry something we only try after we've already compiled the function with the FTL and it still got stuck in a loop after that without ever returning like a sensible function oughta have
https://bugs.webkit.org/show_bug.cgi?id=128234
Reviewed by Geoffrey Garen.
Use DFG::JITCode::osrEntryRetry as a counter to decide when to invoke OSR entry. That
comes into play only after we've done a replacement compile.
This appears to still give us a speed-up on the kinds of things that OSR entry is good
for, while also eliminating pointless OSR entry compilations on other things.
* dfg/DFGJITCode.cpp:
(JSC::DFG::JITCode::JITCode):
* dfg/DFGJITCode.h:
* dfg/DFGOperations.cpp:
* dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp:
(JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete):
* runtime/Options.h:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCodecpp">trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCodeh">trunk/Source/JavaScriptCore/dfg/DFGJITCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGToFTLForOSREntryDeferredCompilationCallbackcpp">trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (163516 => 163517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-06 06:55:20 UTC (rev 163516)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-06 07:11:48 UTC (rev 163517)
</span><span class="lines">@@ -1,5 +1,26 @@
</span><span class="cx"> 2014-02-04 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><ins>+ Make FTL OSR entry something we only try after we've already compiled the function with the FTL and it still got stuck in a loop after that without ever returning like a sensible function oughta have
+ https://bugs.webkit.org/show_bug.cgi?id=128234
+
+ Reviewed by Geoffrey Garen.
+
+ Use DFG::JITCode::osrEntryRetry as a counter to decide when to invoke OSR entry. That
+ comes into play only after we've done a replacement compile.
+
+ This appears to still give us a speed-up on the kinds of things that OSR entry is good
+ for, while also eliminating pointless OSR entry compilations on other things.
+
+ * dfg/DFGJITCode.cpp:
+ (JSC::DFG::JITCode::JITCode):
+ * dfg/DFGJITCode.h:
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp:
+ (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete):
+ * runtime/Options.h:
+
+2014-02-04 Filip Pizlo <fpizlo@apple.com>
+
</ins><span class="cx"> Don't speculate on ToThis if we already know that arg0 has a questionable record with structure checks
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=128229
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp (163516 => 163517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp        2014-02-06 06:55:20 UTC (rev 163516)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp        2014-02-06 07:11:48 UTC (rev 163517)
</span><span class="lines">@@ -34,6 +34,10 @@
</span><span class="cx">
</span><span class="cx"> JITCode::JITCode()
</span><span class="cx"> : DirectJITCode(DFGJIT)
</span><ins>+#if ENABLE(FTL_JIT)
+ , osrEntryRetry(0)
+ , abandonOSREntry(false)
+#endif // ENABLE(FTL_JIT)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCode.h (163516 => 163517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCode.h        2014-02-06 06:55:20 UTC (rev 163516)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCode.h        2014-02-06 07:11:48 UTC (rev 163517)
</span><span class="lines">@@ -125,6 +125,8 @@
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> ExecutionCounter tierUpCounter;
</span><span class="cx"> RefPtr<CodeBlock> osrEntryBlock;
</span><ins>+ unsigned osrEntryRetry;
+ bool abandonOSREntry;
</ins><span class="cx"> #endif // ENABLE(FTL_JIT)
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (163516 => 163517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-02-06 06:55:20 UTC (rev 163516)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-02-06 07:11:48 UTC (rev 163517)
</span><span class="lines">@@ -1113,21 +1113,8 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><del>-void JIT_OPERATION triggerTierUpNow(ExecState* exec)
</del><ins>+static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
</ins><span class="cx"> {
</span><del>- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
- DeferGC deferGC(vm->heap);
- CodeBlock* codeBlock = exec->codeBlock();
-
- JITCode* jitCode = codeBlock->jitCode()->dfg();
-
- if (Options::verboseOSR()) {
- dataLog(
- *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
- jitCode->tierUpCounter, "\n");
- }
-
</del><span class="cx"> if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
</span><span class="cx"> if (Options::verboseOSR())
</span><span class="cx"> dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
</span><span class="lines">@@ -1175,6 +1162,24 @@
</span><span class="cx"> Operands<JSValue>(), ToFTLDeferredCompilationCallback::create(codeBlock));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void JIT_OPERATION triggerTierUpNow(ExecState* exec)
+{
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+ DeferGC deferGC(vm->heap);
+ CodeBlock* codeBlock = exec->codeBlock();
+
+ JITCode* jitCode = codeBlock->jitCode()->dfg();
+
+ if (Options::verboseOSR()) {
+ dataLog(
+ *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
+ jitCode->tierUpCounter, "\n");
+ }
+
+ triggerFTLReplacementCompile(vm, codeBlock, jitCode);
+}
+
</ins><span class="cx"> char* JIT_OPERATION triggerOSREntryNow(
</span><span class="cx"> ExecState* exec, int32_t bytecodeIndex, int32_t streamIndex)
</span><span class="cx"> {
</span><span class="lines">@@ -1191,57 +1196,47 @@
</span><span class="cx"> jitCode->tierUpCounter, "\n");
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
- if (Options::verboseOSR())
- dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
- jitCode->dontOptimizeAnytimeSoon(codeBlock);
</del><ins>+ // - If we don't have an FTL code block, then try to compile one.
+ // - If we do have an FTL code block, then try to enter for a while.
+ // - If we couldn't enter for a while, then trigger OSR entry.
+
+ triggerFTLReplacementCompile(vm, codeBlock, jitCode);
+
+ if (!codeBlock->hasOptimizedReplacement())
</ins><span class="cx"> return 0;
</span><del>- }
</del><span class="cx">
</span><del>- if (!jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
- if (Options::verboseOSR())
- dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
</del><ins>+ if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
+ jitCode->osrEntryRetry++;
</ins><span class="cx"> return 0;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- Worklist* worklist = existingGlobalFTLWorklistOrNull();
-
</del><ins>+ // It's time to try to compile code for OSR entry.
</ins><span class="cx"> Worklist::State worklistState;
</span><del>- if (worklist) {
</del><ins>+ if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
</ins><span class="cx"> worklistState = worklist->completeAllReadyPlansForVM(
</span><span class="cx"> *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
</span><span class="cx"> } else
</span><span class="cx"> worklistState = Worklist::NotKnown;
</span><span class="cx">
</span><del>- if (worklistState == Worklist::Compiling) {
- ASSERT(!jitCode->osrEntryBlock);
- jitCode->setOptimizationThresholdBasedOnCompilationResult(
- codeBlock, CompilationDeferred);
</del><ins>+ if (worklistState == Worklist::Compiling)
</ins><span class="cx"> return 0;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> if (CodeBlock* entryBlock = jitCode->osrEntryBlock.get()) {
</span><span class="cx"> void* address = FTL::prepareOSREntry(
</span><span class="cx"> exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
</span><del>- if (address) {
- jitCode->optimizeSoon(codeBlock);
</del><ins>+ if (address)
</ins><span class="cx"> return static_cast<char*>(address);
</span><del>- }
</del><span class="cx">
</span><span class="cx"> FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
</span><span class="cx"> entryCode->countEntryFailure();
</span><span class="cx"> if (entryCode->entryFailureCount() <
</span><del>- Options::ftlOSREntryFailureCountForReoptimization()) {
-
- jitCode->optimizeSoon(codeBlock);
</del><ins>+ Options::ftlOSREntryFailureCountForReoptimization())
</ins><span class="cx"> return 0;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> // OSR entry failed. Oh no! This implies that we need to retry. We retry
</span><span class="cx"> // without exponential backoff and we only do this for the entry code block.
</span><span class="cx"> jitCode->osrEntryBlock.clear();
</span><del>-
- jitCode->optimizeAfterWarmUp(codeBlock);
</del><ins>+ jitCode->osrEntryRetry = 0;
</ins><span class="cx"> return 0;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1252,7 +1247,8 @@
</span><span class="cx"> return 0;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // The first order of business is to trigger a for-entry compile.
</del><ins>+ // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
+ // something.
</ins><span class="cx"> Operands<JSValue> mustHandleValues;
</span><span class="cx"> jitCode->reconstruct(
</span><span class="cx"> exec, codeBlock, CodeOrigin(bytecodeIndex), streamIndex, mustHandleValues);
</span><span class="lines">@@ -1260,24 +1256,6 @@
</span><span class="cx"> *vm, codeBlock->newReplacement().get(), codeBlock, FTLForOSREntryMode, bytecodeIndex,
</span><span class="cx"> mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(codeBlock));
</span><span class="cx">
</span><del>- // But we also want to trigger a replacement compile. Of course, we don't want to
- // trigger it if we don't need to. Note that this is kind of weird because we might
- // have just finished an FTL compile and that compile failed or was invalidated.
- // But this seems uncommon enough that we sort of don't care. It's certainly sound
- // to fire off another compile right now so long as we're not already compiling and
- // we don't already have an optimized replacement. Note, we don't do this for
- // obviously bad cases like global code, where we know that there is a slim chance
- // of this code being invoked ever again.
- CompilationKey keyForReplacement(codeBlock->baselineVersion(), FTLMode);
- if (codeBlock->codeType() != GlobalCode
- && !codeBlock->hasOptimizedReplacement()
- && (!worklist
- || worklist->compilationState(keyForReplacement) == Worklist::NotKnown)) {
- compile(
- *vm, codeBlock->newReplacement().get(), codeBlock, FTLMode, UINT_MAX,
- Operands<JSValue>(), ToFTLDeferredCompilationCallback::create(codeBlock));
- }
-
</del><span class="cx"> if (forEntryResult != CompilationSuccessful)
</span><span class="cx"> return 0;
</span><span class="cx">
</span><span class="lines">@@ -1286,10 +1264,6 @@
</span><span class="cx"> // We signal to try again after a while if that happens.
</span><span class="cx"> void* address = FTL::prepareOSREntry(
</span><span class="cx"> exec, codeBlock, jitCode->osrEntryBlock.get(), bytecodeIndex, streamIndex);
</span><del>- if (address)
- jitCode->optimizeSoon(codeBlock);
- else
- jitCode->optimizeAfterWarmUp(codeBlock);
</del><span class="cx"> return static_cast<char*>(address);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGToFTLForOSREntryDeferredCompilationCallbackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp (163516 => 163517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp        2014-02-06 06:55:20 UTC (rev 163516)
+++ trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp        2014-02-06 07:11:48 UTC (rev 163517)
</span><span class="lines">@@ -73,13 +73,24 @@
</span><span class="cx"> ") result: ", result, "\n");
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (result == CompilationSuccessful)
- m_dfgCodeBlock->jitCode()->dfg()->osrEntryBlock = codeBlock;
</del><ins>+ JITCode* jitCode = m_dfgCodeBlock->jitCode()->dfg();
+
+ switch (result) {
+ case CompilationSuccessful:
+ jitCode->osrEntryBlock = codeBlock;
+ return;
+ case CompilationFailed:
+ jitCode->osrEntryRetry = 0;
+ jitCode->abandonOSREntry = true;
+ return;
+ case CompilationDeferred:
+ return;
+ case CompilationInvalidated:
+ jitCode->osrEntryRetry = 0;
+ return;
+ }
</ins><span class="cx">
</span><del>- // FIXME: if we failed, we might want to just turn off OSR entry rather than
- // totally turning off tier-up.
- m_dfgCodeBlock->jitCode()->dfg()->setOptimizationThresholdBasedOnCompilationResult(
- m_dfgCodeBlock.get(), result);
</del><ins>+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } } // JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (163516 => 163517)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2014-02-06 06:55:20 UTC (rev 163516)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2014-02-06 07:11:48 UTC (rev 163517)
</span><span class="lines">@@ -197,6 +197,7 @@
</span><span class="cx"> v(int32, ftlTierUpCounterIncrementForLoop, 1) \
</span><span class="cx"> v(int32, ftlTierUpCounterIncrementForReturn, 15) \
</span><span class="cx"> v(unsigned, ftlOSREntryFailureCountForReoptimization, 15) \
</span><ins>+ v(unsigned, ftlOSREntryRetryThreshold, 100) \
</ins><span class="cx"> \
</span><span class="cx"> v(int32, evalThresholdMultiplier, 10) \
</span><span class="cx"> \
</span></span></pre>
</div>
</div>
</body>
</html>