<!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>[214069] trunk</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/214069">214069</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2017-03-16 14:19:23 -0700 (Thu, 16 Mar 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>FTL should support global and eval code
https://bugs.webkit.org/show_bug.cgi?id=169656
Reviewed by Geoffrey Garen and Saam Barati.
JSTests:
Added basic performance tests of global and eval code. These tests will run a lot faster in with
the FTL because of the object allocation.
* microbenchmarks/eval-code-ftl-reentry.js: Added.
* microbenchmarks/eval-code-ftl.js: Added.
* microbenchmarks/global-code-ftl.js: Added.
* stress/arith-log-on-various-types.js: This was a flaky fail with concurrent JIT, so I stopped running it with concurrent JIT. The failure was its assertion about how many times something gets compiled.
Source/JavaScriptCore:
Turned off the restriction against global and eval code running in the FTL, and then fixed all of
the things that didn't work.
This is a big speed-up on microbenchmarks that I wrote for this patch. One of the reasons why we
hadn't done this earlier is that we've never seen a benchmark that needed it. Global and eval
code rarely gets FTL-hot. Still, this seems like possibly a small JetStream speed-up.
* dfg/DFGJITCode.cpp:
(JSC::DFG::JITCode::setOSREntryBlock): I outlined this for better debugging.
* dfg/DFGJITCode.h:
(JSC::DFG::JITCode::setOSREntryBlock): Deleted.
* dfg/DFGNode.h:
(JSC::DFG::Node::isSemanticallySkippable): It turns out that global code often has InvalidationPoints before LoopHints. They are also skippable from the standpoint of OSR entrypoint analysis.
* dfg/DFGOperations.cpp: Don't do any normal compiles of global code - just do OSR compiles.
* ftl/FTLCapabilities.cpp: Enable FTL for global and eval code.
(JSC::FTL::canCompile):
* ftl/FTLCompile.cpp: Just debugging clean-ups.
(JSC::FTL::compile):
* ftl/FTLJITFinalizer.cpp: Implement finalize() and ensure that we only do things with the entrypoint buffer if we have one. We won't have one for eval code that we aren't OSR entering into.
(JSC::FTL::JITFinalizer::finalize):
(JSC::FTL::JITFinalizer::finalizeFunction):
(JSC::FTL::JITFinalizer::finalizeCommon):
* ftl/FTLJITFinalizer.h:
* ftl/FTLLink.cpp: When entering a function normally, we need the "entrypoint" to put the arity check code. Global and eval code don't need this.
(JSC::FTL::link):
* ftl/FTLOSREntry.cpp: Fix a dataLog statement.
(JSC::FTL::prepareOSREntry):
* ftl/FTLOSRExitCompiler.cpp: Remove dead code that happened to assert that we're exiting from a function.
(JSC::FTL::compileStub):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestsstressarithlogonvarioustypesjs">trunk/JSTests/stress/arith-log-on-various-types.js</a></li>
<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="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJITFinalizercpp">trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJITFinalizerh">trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLinkcpp">trunk/Source/JavaScriptCore/ftl/FTLLink.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSREntrycpp">trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsmicrobenchmarksevalcodeftlreentryjs">trunk/JSTests/microbenchmarks/eval-code-ftl-reentry.js</a></li>
<li><a href="#trunkJSTestsmicrobenchmarksevalcodeftljs">trunk/JSTests/microbenchmarks/eval-code-ftl.js</a></li>
<li><a href="#trunkJSTestsmicrobenchmarksglobalcodeftljs">trunk/JSTests/microbenchmarks/global-code-ftl.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/JSTests/ChangeLog        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-03-16 Filip Pizlo <fpizlo@apple.com>
+
+ FTL should support global and eval code
+ https://bugs.webkit.org/show_bug.cgi?id=169656
+
+ Reviewed by Geoffrey Garen and Saam Barati.
+
+ Added basic performance tests of global and eval code. These tests will run a lot faster in with
+ the FTL because of the object allocation.
+
+ * microbenchmarks/eval-code-ftl-reentry.js: Added.
+ * microbenchmarks/eval-code-ftl.js: Added.
+ * microbenchmarks/global-code-ftl.js: Added.
+ * stress/arith-log-on-various-types.js: This was a flaky fail with concurrent JIT, so I stopped running it with concurrent JIT. The failure was its assertion about how many times something gets compiled.
+
</ins><span class="cx"> 2017-03-16 Caio Lima <ticaiolima@gmail.com>
</span><span class="cx">
</span><span class="cx"> [ESnext] Implement Object Spread
</span></span></pre></div>
<a id="trunkJSTestsmicrobenchmarksevalcodeftlreentryjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/microbenchmarks/eval-code-ftl-reentry.js (0 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/eval-code-ftl-reentry.js         (rev 0)
+++ trunk/JSTests/microbenchmarks/eval-code-ftl-reentry.js        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+for (var _i = 0; _i < 1000; ++_i) {
+ eval(
+ "var result = 0;\n" +
+ "var n = 15000;\n" +
+ "for (var i = 0; i < n; ++i)\n" +
+ " result += {f: 1}.f;\n" +
+ "if (result != n)\n" +
+ " throw \"Error: bad result: \" + result;\n");
+}
+
</ins></span></pre></div>
<a id="trunkJSTestsmicrobenchmarksevalcodeftljs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/microbenchmarks/eval-code-ftl.js (0 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/eval-code-ftl.js         (rev 0)
+++ trunk/JSTests/microbenchmarks/eval-code-ftl.js        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+eval(
+ "var result = 0;\n" +
+ "var n = 15000000;\n" +
+ "for (var i = 0; i < n; ++i)\n" +
+ " result += {f: 1}.f;\n" +
+ "if (result != n)\n" +
+ " throw \"Error: bad result: \" + result;\n");
+
</ins></span></pre></div>
<a id="trunkJSTestsmicrobenchmarksglobalcodeftljs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/microbenchmarks/global-code-ftl.js (0 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/global-code-ftl.js         (rev 0)
+++ trunk/JSTests/microbenchmarks/global-code-ftl.js        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+var result = 0;
+var n = 15000000;
+for (var i = 0; i < n; ++i)
+ result += {f: 1}.f;
+if (result != n)
+ throw "Error: bad result: " + result;
+
</ins></span></pre></div>
<a id="trunkJSTestsstressarithlogonvarioustypesjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/stress/arith-log-on-various-types.js (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/arith-log-on-various-types.js        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/JSTests/stress/arith-log-on-various-types.js        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,4 +1,5 @@
</span><del>-//@ defaultNoEagerRun
</del><ins>+//@ runNoCJITValidatePhases
+//@ runFTLNoCJITValidate
</ins><span class="cx"> "use strict";
</span><span class="cx">
</span><span class="cx"> let logOfFour = Math.log(4);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2017-03-16 Filip Pizlo <fpizlo@apple.com>
+
+ FTL should support global and eval code
+ https://bugs.webkit.org/show_bug.cgi?id=169656
+
+ Reviewed by Geoffrey Garen and Saam Barati.
+
+ Turned off the restriction against global and eval code running in the FTL, and then fixed all of
+ the things that didn't work.
+
+ This is a big speed-up on microbenchmarks that I wrote for this patch. One of the reasons why we
+ hadn't done this earlier is that we've never seen a benchmark that needed it. Global and eval
+ code rarely gets FTL-hot. Still, this seems like possibly a small JetStream speed-up.
+
+ * dfg/DFGJITCode.cpp:
+ (JSC::DFG::JITCode::setOSREntryBlock): I outlined this for better debugging.
+ * dfg/DFGJITCode.h:
+ (JSC::DFG::JITCode::setOSREntryBlock): Deleted.
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::isSemanticallySkippable): It turns out that global code often has InvalidationPoints before LoopHints. They are also skippable from the standpoint of OSR entrypoint analysis.
+ * dfg/DFGOperations.cpp: Don't do any normal compiles of global code - just do OSR compiles.
+ * ftl/FTLCapabilities.cpp: Enable FTL for global and eval code.
+ (JSC::FTL::canCompile):
+ * ftl/FTLCompile.cpp: Just debugging clean-ups.
+ (JSC::FTL::compile):
+ * ftl/FTLJITFinalizer.cpp: Implement finalize() and ensure that we only do things with the entrypoint buffer if we have one. We won't have one for eval code that we aren't OSR entering into.
+ (JSC::FTL::JITFinalizer::finalize):
+ (JSC::FTL::JITFinalizer::finalizeFunction):
+ (JSC::FTL::JITFinalizer::finalizeCommon):
+ * ftl/FTLJITFinalizer.h:
+ * ftl/FTLLink.cpp: When entering a function normally, we need the "entrypoint" to put the arity check code. Global and eval code don't need this.
+ (JSC::FTL::link):
+ * ftl/FTLOSREntry.cpp: Fix a dataLog statement.
+ (JSC::FTL::prepareOSREntry):
+ * ftl/FTLOSRExitCompiler.cpp: Remove dead code that happened to assert that we're exiting from a function.
+ (JSC::FTL::compileStub):
+
</ins><span class="cx"> 2017-03-16 Michael Saboff <msaboff@apple.com>
</span><span class="cx">
</span><span class="cx"> WebAssembly: function-tests/load-offset.js fails on ARM64
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">
</span><span class="cx"> #include "CodeBlock.h"
</span><ins>+#include "FTLForOSREntryJITCode.h"
</ins><span class="cx"> #include "JSCInlines.h"
</span><span class="cx"> #include "TrackedReferences.h"
</span><span class="cx">
</span><span class="lines">@@ -201,6 +202,15 @@
</span><span class="cx"> }
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><ins>+
+void JITCode::setOSREntryBlock(VM& vm, const JSCell* owner, CodeBlock* osrEntryBlock)
+{
+ if (Options::verboseOSR()) {
+ dataLog(RawPointer(this), ": Setting OSR entry block to ", RawPointer(osrEntryBlock), "\n");
+ dataLog("OSR entries will go to ", osrEntryBlock->jitCode()->ftlForOSREntry()->addressForCall(ArityCheckNotRequired), "\n");
+ }
+ m_osrEntryBlock.set(vm, owner, osrEntryBlock);
+}
</ins><span class="cx"> #endif // ENABLE(FTL_JIT)
</span><span class="cx">
</span><span class="cx"> void JITCode::validateReferences(const TrackedReferences& trackedReferences)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCode.h (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCode.h        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCode.h        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx"> RegisterSet liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock*, CallSiteIndex) override;
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> CodeBlock* osrEntryBlock() { return m_osrEntryBlock.get(); }
</span><del>- void setOSREntryBlock(VM& vm, const JSCell* owner, CodeBlock* osrEntryBlock) { m_osrEntryBlock.set(vm, owner, osrEntryBlock); }
</del><ins>+ void setOSREntryBlock(VM&, const JSCell* owner, CodeBlock* osrEntryBlock);
</ins><span class="cx"> void clearOSREntryBlock() { m_osrEntryBlock.clear(); }
</span><span class="cx"> #endif
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1908,9 +1908,11 @@
</span><span class="cx"> return m_refCount;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ // Return true if the execution of this Node does not affect our ability to OSR to the FTL.
+ // FIXME: Isn't this just like checking if the node has effects?
</ins><span class="cx"> bool isSemanticallySkippable()
</span><span class="cx"> {
</span><del>- return op() == CountExecution;
</del><ins>+ return op() == CountExecution || op() == InvalidationPoint;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> unsigned refCount()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -2307,6 +2307,14 @@
</span><span class="cx">
</span><span class="cx"> static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
</span><span class="cx"> {
</span><ins>+ if (codeBlock->codeType() == GlobalCode) {
+ // Global code runs once, so we don't want to do anything. We don't want to defer indefinitely,
+ // since this may have been spuriously called from tier-up initiated in a loop, and that loop may
+ // later want to run faster code. Deferring for warm-up seems safest.
+ jitCode->optimizeAfterWarmUp(codeBlock);
+ return;
+ }
+
</ins><span class="cx"> Worklist::State worklistState;
</span><span class="cx"> if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
</span><span class="cx"> worklistState = worklist->completeAllReadyPlansForVM(
</span><span class="lines">@@ -2456,6 +2464,8 @@
</span><span class="cx"> if (canOSRFromHere) {
</span><span class="cx"> unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex);
</span><span class="cx"> if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
</span><ins>+ if (Options::verboseOSR())
+ dataLog("OSR entry: From ", RawPointer(jitCode), " got entry block ", RawPointer(entryBlock), "\n");
</ins><span class="cx"> if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
</span><span class="cx"> CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
</span><span class="cx"> return static_cast<char*>(address);
</span><span class="lines">@@ -2574,6 +2584,8 @@
</span><span class="cx"> // It's possible that the for-entry compile already succeeded. In that case OSR
</span><span class="cx"> // entry will succeed unless we ran out of stack. It's not clear what we should do.
</span><span class="cx"> // We signal to try again after a while if that happens.
</span><ins>+ if (Options::verboseOSR())
+ dataLog("Immediate OSR entry: From ", RawPointer(jitCode), " got entry block ", RawPointer(jitCode->osrEntryBlock()), "\n");
</ins><span class="cx"> void* address = FTL::prepareOSREntry(
</span><span class="cx"> exec, codeBlock, jitCode->osrEntryBlock(), originBytecodeIndex, streamIndex);
</span><span class="cx"> return static_cast<char*>(address);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -398,12 +398,6 @@
</span><span class="cx"> return CannotCompile;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (graph.m_codeBlock->codeType() != FunctionCode) {
- if (verboseCapabilities())
- dataLog("FTL rejecting ", *graph.m_codeBlock, " because it doesn't belong to a function.\n");
- return CannotCompile;
- }
-
</del><span class="cx"> if (UNLIKELY(graph.m_codeBlock->ownerScriptExecutable()->neverFTLOptimize())) {
</span><span class="cx"> if (verboseCapabilities())
</span><span class="cx"> dataLog("FTL rejecting ", *graph.m_codeBlock, " because it is marked as never FTL compile.\n");
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> #include "LinkBuffer.h"
</span><span class="cx"> #include "PCToCodeOriginMap.h"
</span><span class="cx"> #include "ScratchRegisterAllocator.h"
</span><ins>+#include <wtf/Function.h>
</ins><span class="cx">
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx">
</span><span class="lines">@@ -77,10 +78,8 @@
</span><span class="cx">
</span><span class="cx"> std::unique_ptr<RegisterAtOffsetList> registerOffsets =
</span><span class="cx"> std::make_unique<RegisterAtOffsetList>(state.proc->calleeSaveRegisters());
</span><del>- if (shouldDumpDisassembly()) {
- dataLog("Unwind info for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ":\n");
- dataLog(" ", *registerOffsets, "\n");
- }
</del><ins>+ if (shouldDumpDisassembly())
+ dataLog("Unwind info for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ": ", *registerOffsets, "\n");
</ins><span class="cx"> state.graph.m_codeBlock->setCalleeSaveRegisters(WTFMove(registerOffsets));
</span><span class="cx"> ASSERT(!(state.proc->frameSize() % sizeof(EncodedJSValue)));
</span><span class="cx"> state.jitCode->common.frameRegisterCount = state.proc->frameSize() / sizeof(EncodedJSValue);
</span><span class="lines">@@ -160,7 +159,7 @@
</span><span class="cx"> if (B3::Air::Disassembler* disassembler = state.proc->code().disassembler()) {
</span><span class="cx"> PrintStream& out = WTF::dataFile();
</span><span class="cx">
</span><del>- out.print("\nGenerated FTL JIT code for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ", instruction count = ", state.graph.m_codeBlock->instructionCount(), ":\n");
</del><ins>+ out.print("Generated ", state.graph.m_plan.mode, " code for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ", instruction count = ", state.graph.m_codeBlock->instructionCount(), ":\n");
</ins><span class="cx">
</span><span class="cx"> LinkBuffer& linkBuffer = *state.finalizer->b3CodeLinkBuffer;
</span><span class="cx"> B3::Value* currentB3Value = nullptr;
</span><span class="lines">@@ -182,7 +181,7 @@
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> HashSet<Node*> localPrintedNodes;
</span><del>- std::function<void(Node*)> printNodeRecursive = [&] (Node* node) {
</del><ins>+ WTF::Function<void(Node*)> printNodeRecursive = [&] (Node* node) {
</ins><span class="cx"> if (printedNodes.contains(node) || localPrintedNodes.contains(node))
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="lines">@@ -207,7 +206,7 @@
</span><span class="cx"> printDFGNode(bitwise_cast<Node*>(value->origin().data()));
</span><span class="cx">
</span><span class="cx"> HashSet<B3::Value*> localPrintedValues;
</span><del>- std::function<void(B3::Value*)> printValueRecursive = [&] (B3::Value* value) {
</del><ins>+ WTF::Function<void(B3::Value*)> printValueRecursive = [&] (B3::Value* value) {
</ins><span class="cx"> if (printedValues.contains(value) || localPrintedValues.contains(value))
</span><span class="cx"> return;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJITFinalizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2014, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -63,12 +63,16 @@
</span><span class="cx">
</span><span class="cx"> bool JITFinalizer::finalize()
</span><span class="cx"> {
</span><del>- RELEASE_ASSERT_NOT_REACHED();
- return false;
</del><ins>+ return finalizeCommon();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool JITFinalizer::finalizeFunction()
</span><span class="cx"> {
</span><ins>+ return finalizeCommon();
+}
+
+bool JITFinalizer::finalizeCommon()
+{
</ins><span class="cx"> bool dumpDisassembly = shouldDumpDisassembly() || Options::asyncDisassembly();
</span><span class="cx">
</span><span class="cx"> jitCode->initializeB3Code(
</span><span class="lines">@@ -76,10 +80,12 @@
</span><span class="cx"> dumpDisassembly, *b3CodeLinkBuffer,
</span><span class="cx"> ("FTL B3 code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data())));
</span><span class="cx">
</span><del>- jitCode->initializeArityCheckEntrypoint(
- FINALIZE_CODE_IF(
- dumpDisassembly, *entrypointLinkBuffer,
- ("FTL entrypoint thunk for %s with B3 generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data(), function)));
</del><ins>+ if (entrypointLinkBuffer) {
+ jitCode->initializeArityCheckEntrypoint(
+ FINALIZE_CODE_IF(
+ dumpDisassembly, *entrypointLinkBuffer,
+ ("FTL entrypoint thunk for %s with B3 generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data(), function)));
+ }
</ins><span class="cx">
</span><span class="cx"> m_plan.codeBlock->setJITCode(*jitCode);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJITFinalizerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.h (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.h        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.h        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -56,6 +56,8 @@
</span><span class="cx"> size_t codeSize() override;
</span><span class="cx"> bool finalize() override;
</span><span class="cx"> bool finalizeFunction() override;
</span><ins>+
+ bool finalizeCommon();
</ins><span class="cx">
</span><span class="cx"> std::unique_ptr<LinkBuffer> b3CodeLinkBuffer;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLinkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLink.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLink.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLLink.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -127,50 +127,52 @@
</span><span class="cx">
</span><span class="cx"> switch (graph.m_plan.mode) {
</span><span class="cx"> case FTLMode: {
</span><del>- CCallHelpers::JumpList mainPathJumps;
</del><ins>+ if (codeBlock->codeType() == FunctionCode) {
+ CCallHelpers::JumpList mainPathJumps;
</ins><span class="cx">
</span><del>- jit.load32(
- frame.withOffset(sizeof(Register) * CallFrameSlot::argumentCount),
- GPRInfo::regT1);
- mainPathJumps.append(jit.branch32(
- CCallHelpers::AboveOrEqual, GPRInfo::regT1,
- CCallHelpers::TrustedImm32(codeBlock->numParameters())));
- jit.emitFunctionPrologue();
- jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- jit.storePtr(GPRInfo::callFrameRegister, &vm.topCallFrame);
- CCallHelpers::Call callArityCheck = jit.call();
</del><ins>+ jit.load32(
+ frame.withOffset(sizeof(Register) * CallFrameSlot::argumentCount),
+ GPRInfo::regT1);
+ mainPathJumps.append(jit.branch32(
+ CCallHelpers::AboveOrEqual, GPRInfo::regT1,
+ CCallHelpers::TrustedImm32(codeBlock->numParameters())));
+ jit.emitFunctionPrologue();
+ jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ jit.storePtr(GPRInfo::callFrameRegister, &vm.topCallFrame);
+ CCallHelpers::Call callArityCheck = jit.call();
</ins><span class="cx">
</span><del>- auto noException = jit.branch32(CCallHelpers::GreaterThanOrEqual, GPRInfo::returnValueGPR, CCallHelpers::TrustedImm32(0));
- jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
- jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
- jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
- CCallHelpers::Call callLookupExceptionHandlerFromCallerFrame = jit.call();
- jit.jumpToExceptionHandler();
- noException.link(&jit);
</del><ins>+ auto noException = jit.branch32(CCallHelpers::GreaterThanOrEqual, GPRInfo::returnValueGPR, CCallHelpers::TrustedImm32(0));
+ jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
+ jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
+ jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+ CCallHelpers::Call callLookupExceptionHandlerFromCallerFrame = jit.call();
+ jit.jumpToExceptionHandler();
+ noException.link(&jit);
</ins><span class="cx">
</span><del>- if (!ASSERT_DISABLED) {
- jit.load64(vm.addressOfException(), GPRInfo::regT1);
- jit.jitAssertIsNull(GPRInfo::regT1);
- }
</del><ins>+ if (!ASSERT_DISABLED) {
+ jit.load64(vm.addressOfException(), GPRInfo::regT1);
+ jit.jitAssertIsNull(GPRInfo::regT1);
+ }
</ins><span class="cx">
</span><del>- jit.move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
- jit.emitFunctionEpilogue();
- mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::argumentGPR0));
- jit.emitFunctionPrologue();
- CCallHelpers::Call callArityFixup = jit.call();
- jit.emitFunctionEpilogue();
- mainPathJumps.append(jit.jump());
</del><ins>+ jit.move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
+ jit.emitFunctionEpilogue();
+ mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::argumentGPR0));
+ jit.emitFunctionPrologue();
+ CCallHelpers::Call callArityFixup = jit.call();
+ jit.emitFunctionEpilogue();
+ mainPathJumps.append(jit.jump());
</ins><span class="cx">
</span><del>- linkBuffer = std::make_unique<LinkBuffer>(vm, jit, codeBlock, JITCompilationCanFail);
- if (linkBuffer->didFailToAllocate()) {
- state.allocationFailed = true;
- return;
</del><ins>+ linkBuffer = std::make_unique<LinkBuffer>(vm, jit, codeBlock, JITCompilationCanFail);
+ if (linkBuffer->didFailToAllocate()) {
+ state.allocationFailed = true;
+ return;
+ }
+ linkBuffer->link(callArityCheck, codeBlock->m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
+ linkBuffer->link(callLookupExceptionHandlerFromCallerFrame, lookupExceptionHandlerFromCallerFrame);
+ linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code().executableAddress()));
+ linkBuffer->link(mainPathJumps, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
</ins><span class="cx"> }
</span><del>- linkBuffer->link(callArityCheck, codeBlock->m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
- linkBuffer->link(callLookupExceptionHandlerFromCallerFrame, lookupExceptionHandlerFromCallerFrame);
- linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code().executableAddress()));
- linkBuffer->link(mainPathJumps, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
-
</del><ins>+
</ins><span class="cx"> state.jitCode->initializeAddressForCall(MacroAssemblerCodePtr(bitwise_cast<void*>(state.generatedFunction)));
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSREntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx">
</span><span class="cx"> void* result = entryCode->addressForCall(ArityCheckNotRequired).executableAddress();
</span><span class="cx"> if (Options::verboseOSR())
</span><del>- dataLog(" Entry will succeed, going to address", RawPointer(result), "\n");
</del><ins>+ dataLog(" Entry will succeed, going to address ", RawPointer(result), "\n");
</ins><span class="cx">
</span><span class="cx"> return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (214068 => 214069)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2017-03-16 21:10:41 UTC (rev 214068)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2017-03-16 21:19:23 UTC (rev 214069)
</span><span class="lines">@@ -394,36 +394,6 @@
</span><span class="cx"> jit.store64(GPRInfo::regT0, unwindScratch + i);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- jit.load32(CCallHelpers::payloadFor(CallFrameSlot::argumentCount), GPRInfo::regT2);
-
- // Let's say that the FTL function had failed its arity check. In that case, the stack will
- // contain some extra stuff.
- //
- // We compute the padded stack space:
- //
- // paddedStackSpace = roundUp(codeBlock->numParameters - regT2 + 1)
- //
- // The stack will have regT2 + CallFrameHeaderSize stuff.
- // We want to make the stack look like this, from higher addresses down:
- //
- // - argument padding
- // - actual arguments
- // - call frame header
-
- // This code assumes that we're dealing with FunctionCode.
- RELEASE_ASSERT(codeBlock->codeType() == FunctionCode);
-
- jit.add32(
- MacroAssembler::TrustedImm32(-codeBlock->numParameters()), GPRInfo::regT2,
- GPRInfo::regT3);
- MacroAssembler::Jump arityIntact = jit.branch32(
- MacroAssembler::GreaterThanOrEqual, GPRInfo::regT3, MacroAssembler::TrustedImm32(0));
- jit.neg32(GPRInfo::regT3);
- jit.add32(MacroAssembler::TrustedImm32(1 + stackAlignmentRegisters() - 1), GPRInfo::regT3);
- jit.and32(MacroAssembler::TrustedImm32(-stackAlignmentRegisters()), GPRInfo::regT3);
- jit.add32(GPRInfo::regT3, GPRInfo::regT2);
- arityIntact.link(&jit);
-
</del><span class="cx"> CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(exit.m_codeOrigin);
</span><span class="cx">
</span><span class="cx"> // First set up SP so that our data doesn't get clobbered by signals.
</span></span></pre>
</div>
</div>
</body>
</html>