<!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>[166463] 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/166463">166463</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-03-30 11:43:41 -0700 (Sun, 30 Mar 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Land the stackmap register liveness glue with the uses of the liveness disabled
https://bugs.webkit.org/show_bug.cgi?id=130924
Source/JavaScriptCore:
Reviewed by Oliver Hunt.
Add the liveness and fix other bugs I found.
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFor):
* ftl/FTLCompile.cpp:
(JSC::FTL::usedRegistersFor):
(JSC::FTL::fixFunctionBasedOnStackMaps):
* ftl/FTLSlowPathCall.cpp:
* ftl/FTLSlowPathCallKey.cpp:
(JSC::FTL::SlowPathCallKey::dump):
* ftl/FTLSlowPathCallKey.h:
(JSC::FTL::SlowPathCallKey::SlowPathCallKey):
(JSC::FTL::SlowPathCallKey::argumentRegisters):
(JSC::FTL::SlowPathCallKey::withCallTarget):
* ftl/FTLStackMaps.cpp:
(JSC::FTL::StackMaps::Record::locationSet):
(JSC::FTL::StackMaps::Record::liveOutsSet):
(JSC::FTL::StackMaps::Record::usedRegisterSet):
* ftl/FTLStackMaps.h:
* ftl/FTLThunks.cpp:
(JSC::FTL::registerClobberCheck):
(JSC::FTL::slowPathCallThunkGenerator):
* jit/RegisterSet.cpp:
(JSC::RegisterSet::stackRegisters):
(JSC::RegisterSet::reservedHardwareRegisters):
(JSC::RegisterSet::runtimeRegisters):
(JSC::RegisterSet::specialRegisters):
(JSC::RegisterSet::dump):
* jit/RegisterSet.h:
(JSC::RegisterSet::RegisterSet):
(JSC::RegisterSet::setAny):
(JSC::RegisterSet::setMany):
* jit/Repatch.cpp:
(JSC::tryCacheGetByID):
(JSC::tryCachePutByID):
(JSC::tryRepatchIn):
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):
* runtime/Options.h:
Tools:
Reviewed by Oliver Hunt.
* Scripts/run-jsc-stress-tests:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLSlowPathCallcpp">trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLSlowPathCallKeycpp">trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLSlowPathCallKeyh">trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStackMapscpp">trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStackMapsh">trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLThunkscpp">trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterSetcpp">trunk/Source/JavaScriptCore/jit/RegisterSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterSeth">trunk/Source/JavaScriptCore/jit/RegisterSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionscpp">trunk/Source/JavaScriptCore/runtime/Options.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsrunjscstresstests">trunk/Tools/Scripts/run-jsc-stress-tests</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2014-03-28 Filip Pizlo <fpizlo@apple.com>
+
+ Land the stackmap register liveness glue with the uses of the liveness disabled
+ https://bugs.webkit.org/show_bug.cgi?id=130924
+
+ Reviewed by Oliver Hunt.
+
+ Add the liveness and fix other bugs I found.
+
+ * bytecode/PutByIdStatus.cpp:
+ (JSC::PutByIdStatus::computeFor):
+ * ftl/FTLCompile.cpp:
+ (JSC::FTL::usedRegistersFor):
+ (JSC::FTL::fixFunctionBasedOnStackMaps):
+ * ftl/FTLSlowPathCall.cpp:
+ * ftl/FTLSlowPathCallKey.cpp:
+ (JSC::FTL::SlowPathCallKey::dump):
+ * ftl/FTLSlowPathCallKey.h:
+ (JSC::FTL::SlowPathCallKey::SlowPathCallKey):
+ (JSC::FTL::SlowPathCallKey::argumentRegisters):
+ (JSC::FTL::SlowPathCallKey::withCallTarget):
+ * ftl/FTLStackMaps.cpp:
+ (JSC::FTL::StackMaps::Record::locationSet):
+ (JSC::FTL::StackMaps::Record::liveOutsSet):
+ (JSC::FTL::StackMaps::Record::usedRegisterSet):
+ * ftl/FTLStackMaps.h:
+ * ftl/FTLThunks.cpp:
+ (JSC::FTL::registerClobberCheck):
+ (JSC::FTL::slowPathCallThunkGenerator):
+ * jit/RegisterSet.cpp:
+ (JSC::RegisterSet::stackRegisters):
+ (JSC::RegisterSet::reservedHardwareRegisters):
+ (JSC::RegisterSet::runtimeRegisters):
+ (JSC::RegisterSet::specialRegisters):
+ (JSC::RegisterSet::dump):
+ * jit/RegisterSet.h:
+ (JSC::RegisterSet::RegisterSet):
+ (JSC::RegisterSet::setAny):
+ (JSC::RegisterSet::setMany):
+ * jit/Repatch.cpp:
+ (JSC::tryCacheGetByID):
+ (JSC::tryCachePutByID):
+ (JSC::tryRepatchIn):
+ * runtime/Options.cpp:
+ (JSC::recomputeDependentOptions):
+ * runtime/Options.h:
+
</ins><span class="cx"> 2014-03-28 Mark Lam <mark.lam@apple.com>
</span><span class="cx">
</span><span class="cx"> mandreel throws a checksum error on 32-bit x86.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -238,7 +238,10 @@
</span><span class="cx"> result = computeForStubInfo(locker, dfgBlock, dfgMap.get(codeOrigin), uid);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (result.isSet())
</del><ins>+ // We use TakesSlowPath in some cases where the stub was unset. That's weird and
+ // it would be better not to do that. But it means that we have to defend
+ // ourselves here.
+ if (result.isSimple())
</ins><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -163,6 +163,13 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static RegisterSet usedRegistersFor(const StackMaps::Record& record)
+{
+ if (Options::assumeAllRegsInFTLICAreLive())
+ return RegisterSet::allRegisters();
+ return record.usedRegisterSet();
+}
+
</ins><span class="cx"> static void fixFunctionBasedOnStackMaps(
</span><span class="cx"> State& state, CodeBlock* codeBlock, JITCode* jitCode, GeneratedFunction generatedFunction,
</span><span class="cx"> StackMaps::RecordMap& recordMap, bool didSeeUnwindInfo)
</span><span class="lines">@@ -300,9 +307,7 @@
</span><span class="cx"> for (unsigned i = 0; i < iter->value.size(); ++i) {
</span><span class="cx"> StackMaps::Record& record = iter->value[i];
</span><span class="cx">
</span><del>- // FIXME: Use the liveness information that LLVM gives us.
- // https://bugs.webkit.org/show_bug.cgi?id=130791
- RegisterSet usedRegisters = RegisterSet::allRegisters();
</del><ins>+ RegisterSet usedRegisters = usedRegistersFor(record);
</ins><span class="cx">
</span><span class="cx"> GPRReg result = record.locations[0].directGPR();
</span><span class="cx"> GPRReg base = record.locations[1].directGPR();
</span><span class="lines">@@ -339,9 +344,7 @@
</span><span class="cx"> for (unsigned i = 0; i < iter->value.size(); ++i) {
</span><span class="cx"> StackMaps::Record& record = iter->value[i];
</span><span class="cx">
</span><del>- // FIXME: Use the liveness information that LLVM gives us.
- // https://bugs.webkit.org/show_bug.cgi?id=130791
- RegisterSet usedRegisters = RegisterSet::allRegisters();
</del><ins>+ RegisterSet usedRegisters = usedRegistersFor(record);
</ins><span class="cx">
</span><span class="cx"> GPRReg base = record.locations[0].directGPR();
</span><span class="cx"> GPRReg value = record.locations[1].directGPR();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLSlowPathCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -67,7 +67,8 @@
</span><span class="cx"> (std::max(m_numArgs, NUMBER_OF_ARGUMENT_REGISTERS) - NUMBER_OF_ARGUMENT_REGISTERS) * wordSize;
</span><span class="cx">
</span><span class="cx"> for (unsigned i = std::min(NUMBER_OF_ARGUMENT_REGISTERS, numArgs); i--;)
</span><del>- m_callingConventionRegisters.set(GPRInfo::toArgumentRegister(i));
</del><ins>+ m_argumentRegisters.set(GPRInfo::toArgumentRegister(i));
+ m_callingConventionRegisters.merge(m_argumentRegisters);
</ins><span class="cx"> if (returnRegister != InvalidGPRReg)
</span><span class="cx"> m_callingConventionRegisters.set(GPRInfo::returnValueGPR);
</span><span class="cx"> m_callingConventionRegisters.filter(m_usedRegisters);
</span><span class="lines">@@ -84,10 +85,8 @@
</span><span class="cx"> stackBytesNeededForReturnAddress +
</span><span class="cx"> (m_usedRegisters.numberOfSetRegisters() - numberOfCallingConventionRegisters) * wordSize;
</span><span class="cx">
</span><del>- size_t stackAlignment = 16;
</del><ins>+ m_stackBytesNeeded = (m_stackBytesNeeded + stackAlignmentBytes() - 1) & ~(stackAlignmentBytes() - 1);
</ins><span class="cx">
</span><del>- m_stackBytesNeeded = (m_stackBytesNeeded + stackAlignment - 1) & ~(stackAlignment - 1);
-
</del><span class="cx"> m_jit.subPtr(CCallHelpers::TrustedImm32(m_stackBytesNeeded), CCallHelpers::stackPointerRegister);
</span><span class="cx">
</span><span class="cx"> m_thunkSaveSet = m_usedRegisters;
</span><span class="lines">@@ -133,7 +132,7 @@
</span><span class="cx">
</span><span class="cx"> SlowPathCallKey keyWithTarget(void* callTarget) const
</span><span class="cx"> {
</span><del>- return SlowPathCallKey(usedRegisters(), callTarget, offset());
</del><ins>+ return SlowPathCallKey(usedRegisters(), callTarget, m_argumentRegisters, offset());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MacroAssembler::Call makeCall(void* callTarget, MacroAssembler::JumpList* exceptionTarget)
</span><span class="lines">@@ -149,6 +148,7 @@
</span><span class="cx"> private:
</span><span class="cx"> State& m_state;
</span><span class="cx"> RegisterSet m_usedRegisters;
</span><ins>+ RegisterSet m_argumentRegisters;
</ins><span class="cx"> RegisterSet m_callingConventionRegisters;
</span><span class="cx"> CCallHelpers& m_jit;
</span><span class="cx"> unsigned m_numArgs;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLSlowPathCallKeycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx">
</span><span class="cx"> void SlowPathCallKey::dump(PrintStream& out) const
</span><span class="cx"> {
</span><del>- out.print("<usedRegisters = ", m_usedRegisters, ", offset = ", m_offset, ", callTarget = ", RawPointer(m_callTarget), ">");
</del><ins>+ out.print("<usedRegisters = ", m_usedRegisters, ", offset = ", m_offset, ", callTarget = ", RawPointer(m_callTarget), ", argumentRegisters = ", m_argumentRegisters, ">");
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLSlowPathCallKeyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.h (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.h        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLSlowPathCallKey.h        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -50,20 +50,24 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>- SlowPathCallKey(const RegisterSet& set, void* callTarget, ptrdiff_t offset)
</del><ins>+ SlowPathCallKey(
+ const RegisterSet& set, void* callTarget, const RegisterSet& argumentRegisters,
+ ptrdiff_t offset)
</ins><span class="cx"> : m_usedRegisters(set)
</span><span class="cx"> , m_callTarget(callTarget)
</span><ins>+ , m_argumentRegisters(argumentRegisters)
</ins><span class="cx"> , m_offset(offset)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const RegisterSet& usedRegisters() const { return m_usedRegisters; }
</span><span class="cx"> void* callTarget() const { return m_callTarget; }
</span><ins>+ const RegisterSet& argumentRegisters() const { return m_argumentRegisters; }
</ins><span class="cx"> ptrdiff_t offset() const { return m_offset; }
</span><span class="cx">
</span><span class="cx"> SlowPathCallKey withCallTarget(void* callTarget)
</span><span class="cx"> {
</span><del>- return SlowPathCallKey(usedRegisters(), callTarget, offset());
</del><ins>+ return SlowPathCallKey(usedRegisters(), callTarget, argumentRegisters(), offset());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void dump(PrintStream&) const;
</span><span class="lines">@@ -102,6 +106,7 @@
</span><span class="cx"> private:
</span><span class="cx"> RegisterSet m_usedRegisters;
</span><span class="cx"> void* m_callTarget;
</span><ins>+ RegisterSet m_argumentRegisters;
</ins><span class="cx"> ptrdiff_t m_offset;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStackMapscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -149,6 +149,44 @@
</span><span class="cx"> listDump(liveOuts), "])");
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RegisterSet StackMaps::Record::locationSet() const
+{
+ RegisterSet result;
+ for (unsigned i = locations.size(); i--;) {
+ Reg reg = locations[i].dwarfReg.reg();
+ if (!reg)
+ continue;
+ result.set(reg);
+ }
+ return result;
+}
+
+RegisterSet StackMaps::Record::liveOutsSet() const
+{
+ RegisterSet result;
+ for (unsigned i = liveOuts.size(); i--;) {
+ LiveOut liveOut = liveOuts[i];
+ Reg reg = liveOut.dwarfReg.reg();
+ // FIXME: Either assert that size is not greater than sizeof(pointer), or actually
+ // save the high bits of registers.
+ // https://bugs.webkit.org/show_bug.cgi?id=130885
+ if (!reg) {
+ dataLog("Invalid liveOuts entry in: ", *this, "\n");
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ result.set(reg);
+ }
+ return result;
+}
+
+RegisterSet StackMaps::Record::usedRegisterSet() const
+{
+ RegisterSet result;
+ result.merge(locationSet());
+ result.merge(liveOutsSet());
+ return result;
+}
+
</ins><span class="cx"> bool StackMaps::parse(DataView* view)
</span><span class="cx"> {
</span><span class="cx"> ParseContext context;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStackMapsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "DataView.h"
</span><span class="cx"> #include "FTLDWARFRegister.h"
</span><span class="cx"> #include "GPRInfo.h"
</span><ins>+#include "RegisterSet.h"
</ins><span class="cx"> #include <wtf/HashMap.h>
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -106,6 +107,10 @@
</span><span class="cx">
</span><span class="cx"> bool parse(ParseContext&);
</span><span class="cx"> void dump(PrintStream&) const;
</span><ins>+
+ RegisterSet liveOutsSet() const;
+ RegisterSet locationSet() const;
+ RegisterSet usedRegisterSet() const;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> unsigned version;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLThunkscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -106,6 +106,34 @@
</span><span class="cx"> return FINALIZE_CODE(patchBuffer, ("FTL OSR exit generation thunk"));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static void registerClobberCheck(AssemblyHelpers& jit, RegisterSet dontClobber)
+{
+ if (!Options::clobberAllRegsInFTLICSlowPath())
+ return;
+
+ RegisterSet clobber = RegisterSet::allRegisters();
+ clobber.exclude(RegisterSet::reservedHardwareRegisters());
+ clobber.exclude(RegisterSet::stackRegisters());
+ clobber.exclude(RegisterSet::calleeSaveRegisters());
+ clobber.exclude(dontClobber);
+
+ GPRReg someGPR;
+ for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
+ if (!clobber.get(reg) || !reg.isGPR())
+ continue;
+
+ jit.move(AssemblyHelpers::TrustedImm32(0x1337beef), reg.gpr());
+ someGPR = reg.gpr();
+ }
+
+ for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
+ if (!clobber.get(reg) || !reg.isFPR())
+ continue;
+
+ jit.move64ToDouble(someGPR, reg.fpr());
+ }
+}
+
</ins><span class="cx"> MacroAssemblerCodeRef slowPathCallThunkGenerator(VM& vm, const SlowPathCallKey& key)
</span><span class="cx"> {
</span><span class="cx"> AssemblyHelpers jit(&vm, 0);
</span><span class="lines">@@ -134,13 +162,13 @@
</span><span class="cx"> currentOffset += sizeof(double);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // FIXME: CStack - Need to do soemething like jit.emitFunctionPrologue();
</del><span class="cx"> jit.preserveReturnAddressAfterCall(GPRInfo::nonArgGPR0);
</span><span class="cx"> jit.storePtr(GPRInfo::nonArgGPR0, AssemblyHelpers::Address(MacroAssembler::stackPointerRegister, key.offset()));
</span><span class="cx">
</span><ins>+ registerClobberCheck(jit, key.argumentRegisters());
+
</ins><span class="cx"> AssemblyHelpers::Call call = jit.call();
</span><span class="cx">
</span><del>- // FIXME: CStack - Need to do something like jit.emitFunctionEpilogue();
</del><span class="cx"> jit.loadPtr(AssemblyHelpers::Address(MacroAssembler::stackPointerRegister, key.offset()), GPRInfo::nonPreservedNonReturnGPR);
</span><span class="cx"> jit.restoreReturnAddressBeforeReturn(GPRInfo::nonPreservedNonReturnGPR);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -31,43 +31,39 @@
</span><span class="cx"> #include "GPRInfo.h"
</span><span class="cx"> #include "MacroAssembler.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><ins>+#include <wtf/CommaPrinter.h>
</ins><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="cx"> RegisterSet RegisterSet::stackRegisters()
</span><span class="cx"> {
</span><del>- RegisterSet result;
- result.set(MacroAssembler::stackPointerRegister);
- result.set(MacroAssembler::framePointerRegister);
- return result;
</del><ins>+ return RegisterSet(
+ MacroAssembler::stackPointerRegister,
+ MacroAssembler::framePointerRegister);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RegisterSet RegisterSet::reservedHardwareRegisters()
</span><span class="cx"> {
</span><del>- RegisterSet result;
</del><span class="cx"> #if CPU(ARM64)
</span><del>- result.set(ARM64Registers::lr);
</del><ins>+ return RegisterSet(ARM64Registers::lr);
+#else
+ return RegisterSet();
</ins><span class="cx"> #endif
</span><del>- return result;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RegisterSet RegisterSet::runtimeRegisters()
</span><span class="cx"> {
</span><del>- RegisterSet result;
</del><span class="cx"> #if USE(JSVALUE64)
</span><del>- result.set(GPRInfo::tagTypeNumberRegister);
- result.set(GPRInfo::tagMaskRegister);
</del><ins>+ return RegisterSet(GPRInfo::tagTypeNumberRegister, GPRInfo::tagMaskRegister);
+#else
+ return RegisterSet();
</ins><span class="cx"> #endif
</span><del>- return result;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RegisterSet RegisterSet::specialRegisters()
</span><span class="cx"> {
</span><del>- RegisterSet result;
- result.merge(stackRegisters());
- result.merge(reservedHardwareRegisters());
- result.merge(runtimeRegisters());
- return result;
</del><ins>+ return RegisterSet(
+ stackRegisters(), reservedHardwareRegisters(), runtimeRegisters());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RegisterSet RegisterSet::calleeSaveRegisters()
</span><span class="lines">@@ -155,7 +151,13 @@
</span><span class="cx">
</span><span class="cx"> void RegisterSet::dump(PrintStream& out) const
</span><span class="cx"> {
</span><del>- m_vector.dump(out);
</del><ins>+ CommaPrinter comma;
+ out.print("[");
+ for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
+ if (get(reg))
+ out.print(comma, reg);
+ }
+ out.print("]");
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.h (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.h        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.h        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -39,7 +39,11 @@
</span><span class="cx">
</span><span class="cx"> class RegisterSet {
</span><span class="cx"> public:
</span><del>- RegisterSet() { }
</del><ins>+ template<typename... Regs>
+ explicit RegisterSet(Regs... regs)
+ {
+ setMany(regs...);
+ }
</ins><span class="cx">
</span><span class="cx"> static RegisterSet stackRegisters();
</span><span class="cx"> static RegisterSet reservedHardwareRegisters();
</span><span class="lines">@@ -55,7 +59,7 @@
</span><span class="cx"> ASSERT(!!reg);
</span><span class="cx"> m_vector.set(reg.index(), value);
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> void set(JSValueRegs regs)
</span><span class="cx"> {
</span><span class="cx"> if (regs.tagGPR() != InvalidGPRReg)
</span><span class="lines">@@ -105,6 +109,16 @@
</span><span class="cx"> unsigned hash() const { return m_vector.hash(); }
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ void setAny(Reg reg) { set(reg); }
+ void setAny(const RegisterSet& set) { merge(set); }
+ void setMany() { }
+ template<typename RegType, typename... Regs>
+ void setMany(RegType reg, Regs... regs)
+ {
+ setAny(reg);
+ setMany(regs...);
+ }
+
</ins><span class="cx"> BitVector m_vector;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -490,6 +490,9 @@
</span><span class="cx">
</span><span class="cx"> static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
</span><span class="cx"> {
</span><ins>+ if (Options::forceICFailure())
+ return false;
+
</ins><span class="cx"> // FIXME: Write a test that proves we need to check for recursion here just
</span><span class="cx"> // like the interpreter does, then add a check for recursion.
</span><span class="cx">
</span><span class="lines">@@ -1110,6 +1113,9 @@
</span><span class="cx">
</span><span class="cx"> static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
</span><span class="cx"> {
</span><ins>+ if (Options::forceICFailure())
+ return false;
+
</ins><span class="cx"> CodeBlock* codeBlock = exec->codeBlock();
</span><span class="cx"> VM* vm = &exec->vm();
</span><span class="cx">
</span><span class="lines">@@ -1139,6 +1145,8 @@
</span><span class="cx">
</span><span class="cx"> // Skip optimizing the case where we need realloc, and the structure has
</span><span class="cx"> // indexing storage.
</span><ins>+ // FIXME: We shouldn't skip this! Implement it!
+ // https://bugs.webkit.org/show_bug.cgi?id=130914
</ins><span class="cx"> if (oldStructure->couldHaveIndexingHeader())
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="lines">@@ -1340,6 +1348,9 @@
</span><span class="cx"> ExecState* exec, JSCell* base, const Identifier& ident, bool wasFound,
</span><span class="cx"> const PropertySlot& slot, StructureStubInfo& stubInfo)
</span><span class="cx"> {
</span><ins>+ if (Options::forceICFailure())
+ return false;
+
</ins><span class="cx"> if (!base->structure()->propertyAccessesAreCacheable())
</span><span class="cx"> return false;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -206,7 +206,7 @@
</span><span class="cx"> #if !ENABLE(FTL_JIT)
</span><span class="cx"> Options::useFTLJIT() = false;
</span><span class="cx"> #endif
</span><del>-
</del><ins>+
</ins><span class="cx"> if (Options::showDisassembly()
</span><span class="cx"> || Options::showDFGDisassembly()
</span><span class="cx"> || Options::showFTLDisassembly()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -102,6 +102,7 @@
</span><span class="cx"> v(bool, crashIfCantAllocateJITMemory, false) \
</span><span class="cx"> \
</span><span class="cx"> v(bool, forceDFGCodeBlockLiveness, false) \
</span><ins>+ v(bool, forceICFailure, false) \
</ins><span class="cx"> \
</span><span class="cx"> v(bool, dumpGeneratedBytecodes, false) \
</span><span class="cx"> v(bool, dumpBytecodeLivenessResults, false) \
</span><span class="lines">@@ -157,6 +158,8 @@
</span><span class="cx"> v(unsigned, llvmMaxStackSize, 128 * KB) \
</span><span class="cx"> v(bool, llvmDisallowAVX, true) \
</span><span class="cx"> v(bool, ftlCrashes, false) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
</span><ins>+ v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED) \
+ v(bool, assumeAllRegsInFTLICAreLive, true) \
</ins><span class="cx"> \
</span><span class="cx"> v(bool, enableConcurrentJIT, true) \
</span><span class="cx"> v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1) \
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Tools/ChangeLog        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2014-03-28 Filip Pizlo <fpizlo@apple.com>
+
+ Land the stackmap register liveness glue with the uses of the liveness disabled
+ https://bugs.webkit.org/show_bug.cgi?id=130924
+
+ Reviewed by Oliver Hunt.
+
+ * Scripts/run-jsc-stress-tests:
+
</ins><span class="cx"> 2014-03-29 Alexey Proskuryakov <ap@apple.com>
</span><span class="cx">
</span><span class="cx"> Update WebKit1.StringTruncator for Mountain Lion.
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscstresstests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-stress-tests (166462 => 166463)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-stress-tests        2014-03-30 16:53:53 UTC (rev 166462)
+++ trunk/Tools/Scripts/run-jsc-stress-tests        2014-03-30 18:43:41 UTC (rev 166463)
</span><span class="lines">@@ -250,6 +250,10 @@
</span><span class="cx"> "awk " + Shellwords.shellescape("{ printf #{(prefix + ': ').inspect}; print }")
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+def redirectAndPrefixCommand(prefix)
+ prefixCommand(prefix) + " 2>&1"
+end
+
</ins><span class="cx"> def pipeAndPrefixCommand(outputFilename, prefix)
</span><span class="cx"> "tee " + Shellwords.shellescape(outputFilename.to_s) + " | " + prefixCommand(prefix)
</span><span class="cx"> end
</span><span class="lines">@@ -276,7 +280,7 @@
</span><span class="cx"> | outp, plan |
</span><span class="cx"> outp.puts "if test -e #{plan.failFile}"
</span><span class="cx"> outp.puts "then"
</span><del>- outp.puts " (echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "else"
</span><span class="cx"> outp.puts " " + plan.successCommand
</span><span class="lines">@@ -293,7 +297,7 @@
</span><span class="cx">
</span><span class="cx"> outp.puts "if test -e #{plan.failFile}"
</span><span class="cx"> outp.puts "then"
</span><del>- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "elif test -e ../#{Shellwords.shellescape(expectedFilename)}"
</span><span class="cx"> outp.puts "then"
</span><span class="lines">@@ -302,11 +306,11 @@
</span><span class="cx"> outp.puts " then"
</span><span class="cx"> outp.puts " " + plan.successCommand
</span><span class="cx"> outp.puts " else"
</span><del>- outp.puts " (echo \"DIFF FAILURE!\" && cat #{diffFilename}) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (echo \"DIFF FAILURE!\" && cat #{diffFilename}) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts " fi"
</span><span class="cx"> outp.puts "else"
</span><del>- outp.puts " (echo \"NO EXPECTATION!\" && cat #{outputFilename}) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (echo \"NO EXPECTATION!\" && cat #{outputFilename}) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "fi"
</span><span class="cx"> }
</span><span class="lines">@@ -321,11 +325,11 @@
</span><span class="cx">
</span><span class="cx"> outp.puts "if test -e #{plan.failFile}"
</span><span class="cx"> outp.puts "then"
</span><del>- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "elif grep -i -q failed! #{outputFilename}"
</span><span class="cx"> outp.puts "then"
</span><del>- outp.puts " (echo Detected failures: && cat #{outputFilename}) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (echo Detected failures: && cat #{outputFilename}) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "else"
</span><span class="cx"> outp.puts " " + plan.successCommand
</span><span class="lines">@@ -347,7 +351,7 @@
</span><span class="cx"> outp.puts "then"
</span><span class="cx"> outp.puts " " + plan.successCommand
</span><span class="cx"> outp.puts "else"
</span><del>- outp.puts " (echo NOTICE: You made this test pass, but it was expected to fail) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (echo NOTICE: You made this test pass, but it was expected to fail) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "fi"
</span><span class="cx"> }
</span><span class="lines">@@ -366,17 +370,17 @@
</span><span class="cx"> outp.puts " then"
</span><span class="cx"> outp.puts " if grep -i -q failed! #{outputFilename}"
</span><span class="cx"> outp.puts " then"
</span><del>- outp.puts " (echo Detected failures: && cat #{outputFilename}) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (echo Detected failures: && cat #{outputFilename}) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts " else"
</span><span class="cx"> outp.puts " " + plan.successCommand
</span><span class="cx"> outp.puts " fi"
</span><span class="cx"> outp.puts " else"
</span><del>- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts " fi"
</span><span class="cx"> outp.puts "else"
</span><del>- outp.puts " (cat #{outputFilename} && echo ERROR: Test expected to fail, but returned successfully) | " + prefixCommand(plan.name) + "1>&2"
</del><ins>+ outp.puts " (cat #{outputFilename} && echo ERROR: Test expected to fail, but returned successfully) | " + redirectAndPrefixCommand(plan.name)
</ins><span class="cx"> outp.puts " " + plan.failCommand
</span><span class="cx"> outp.puts "fi"
</span><span class="cx"> }
</span><span class="lines">@@ -610,6 +614,11 @@
</span><span class="cx"> runFTLNoCJIT
</span><span class="cx"> end
</span><span class="cx">
</span><ins>+def defaultFTLSpotCheck
+ defaultQuickRun
+ runFTLNoSimpleOpt
+end
+
</ins><span class="cx"> # This is expected to not do eager runs because eager runs can have a lot of recompilations
</span><span class="cx"> # for reasons that don't arise in the real world. It's used for tests that assert convergence
</span><span class="cx"> # by counting recompilations.
</span><span class="lines">@@ -639,7 +648,7 @@
</span><span class="cx"> prepareExtraRelativeFiles(["../#{testName}-expected.txt"], $benchmarkDirectory)
</span><span class="cx"> prepareExtraAbsoluteFiles(LAYOUTTESTS_PATH, ["resources/standalone-pre.js", "resources/standalone-post.js"])
</span><span class="cx">
</span><del>- args = [pathToVM.to_s] + options +
</del><ins>+ args = [pathToVM.to_s] + NO_FTL_OPTIONS + options +
</ins><span class="cx"> [(Pathname.new("resources") + "standalone-pre.js").to_s,
</span><span class="cx"> $benchmark.to_s,
</span><span class="cx"> (Pathname.new("resources") + "standalone-post.js").to_s]
</span><span class="lines">@@ -721,7 +730,7 @@
</span><span class="cx"> kind = "mozilla"
</span><span class="cx"> end
</span><span class="cx"> prepareExtraRelativeFiles(extraFiles.map{|v| (Pathname("..") + v).to_s}, $collection)
</span><del>- args = [pathToVM.to_s] + options + extraFiles.map{|v| v.to_s} + [$benchmark.to_s]
</del><ins>+ args = [pathToVM.to_s] + NO_FTL_OPTIONS + options + extraFiles.map{|v| v.to_s} + [$benchmark.to_s]
</ins><span class="cx"> case mode
</span><span class="cx"> when :normal
</span><span class="cx"> errorHandler = mozillaErrorHandler
</span></span></pre>
</div>
</div>
</body>
</html>