<!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>[192856] 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/192856">192856</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-11-30 20:43:28 -0800 (Mon, 30 Nov 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>FTL lazy slow paths should work with B3
https://bugs.webkit.org/show_bug.cgi?id=151667
Reviewed by Geoffrey Garen.
This adds all of the glue necessary to make FTL::LazySlowPath work with B3. The B3 approach
allows us to put all of the code in FTL::LowerDFGToLLVM, instead of having supporting data
structures on the side and a bunch of complex code in FTLCompile.cpp.
* b3/B3CheckSpecial.cpp:
(JSC::B3::CheckSpecial::generate):
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::run):
* b3/B3PatchpointSpecial.cpp:
(JSC::B3::PatchpointSpecial::generate):
* b3/B3StackmapValue.h:
* ftl/FTLJSTailCall.cpp:
(JSC::FTL::DFG::recoveryFor):
(JSC::FTL::JSTailCall::emit):
* ftl/FTLLazySlowPath.cpp:
(JSC::FTL::LazySlowPath::LazySlowPath):
(JSC::FTL::LazySlowPath::generate):
* ftl/FTLLazySlowPath.h:
(JSC::FTL::LazySlowPath::createGenerator):
(JSC::FTL::LazySlowPath::patchableJump):
(JSC::FTL::LazySlowPath::done):
(JSC::FTL::LazySlowPath::patchpoint):
(JSC::FTL::LazySlowPath::usedRegisters):
(JSC::FTL::LazySlowPath::callSiteIndex):
(JSC::FTL::LazySlowPath::stub):
* ftl/FTLLocation.cpp:
(JSC::FTL::Location::forValueRep):
(JSC::FTL::Location::forStackmaps):
(JSC::FTL::Location::dump):
(JSC::FTL::Location::isGPR):
(JSC::FTL::Location::gpr):
(JSC::FTL::Location::isFPR):
(JSC::FTL::Location::fpr):
(JSC::FTL::Location::restoreInto):
* ftl/FTLLocation.h:
(JSC::FTL::Location::Location):
(JSC::FTL::Location::forRegister):
(JSC::FTL::Location::forIndirect):
(JSC::FTL::Location::forConstant):
(JSC::FTL::Location::kind):
(JSC::FTL::Location::hasReg):
(JSC::FTL::Location::reg):
(JSC::FTL::Location::hasOffset):
(JSC::FTL::Location::offset):
(JSC::FTL::Location::hash):
(JSC::FTL::Location::hasDwarfRegNum): Deleted.
(JSC::FTL::Location::dwarfRegNum): Deleted.
(JSC::FTL::Location::hasDwarfReg): Deleted.
(JSC::FTL::Location::dwarfReg): Deleted.
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::LowerDFGToLLVM):
(JSC::FTL::DFG::LowerDFGToLLVM::lazySlowPath):
* jit/RegisterSet.cpp:
(JSC::RegisterSet::stubUnavailableRegisters):
(JSC::RegisterSet::macroScratchRegisters):
(JSC::RegisterSet::calleeSaveRegisters):
* jit/RegisterSet.h:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckSpecialcpp">trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3PatchpointSpecialcpp">trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapValueh">trunk/Source/JavaScriptCore/b3/B3StackmapValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJSTailCallcpp">trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLazySlowPathcpp">trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLazySlowPathh">trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLocationcpp">trunk/Source/JavaScriptCore/ftl/FTLLocation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLocationh">trunk/Source/JavaScriptCore/ftl/FTLLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.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>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -1,3 +1,68 @@
</span><ins>+2015-11-30 Filip Pizlo <fpizlo@apple.com>
+
+ FTL lazy slow paths should work with B3
+ https://bugs.webkit.org/show_bug.cgi?id=151667
+
+ Reviewed by Geoffrey Garen.
+
+ This adds all of the glue necessary to make FTL::LazySlowPath work with B3. The B3 approach
+ allows us to put all of the code in FTL::LowerDFGToLLVM, instead of having supporting data
+ structures on the side and a bunch of complex code in FTLCompile.cpp.
+
+ * b3/B3CheckSpecial.cpp:
+ (JSC::B3::CheckSpecial::generate):
+ * b3/B3LowerToAir.cpp:
+ (JSC::B3::Air::LowerToAir::run):
+ * b3/B3PatchpointSpecial.cpp:
+ (JSC::B3::PatchpointSpecial::generate):
+ * b3/B3StackmapValue.h:
+ * ftl/FTLJSTailCall.cpp:
+ (JSC::FTL::DFG::recoveryFor):
+ (JSC::FTL::JSTailCall::emit):
+ * ftl/FTLLazySlowPath.cpp:
+ (JSC::FTL::LazySlowPath::LazySlowPath):
+ (JSC::FTL::LazySlowPath::generate):
+ * ftl/FTLLazySlowPath.h:
+ (JSC::FTL::LazySlowPath::createGenerator):
+ (JSC::FTL::LazySlowPath::patchableJump):
+ (JSC::FTL::LazySlowPath::done):
+ (JSC::FTL::LazySlowPath::patchpoint):
+ (JSC::FTL::LazySlowPath::usedRegisters):
+ (JSC::FTL::LazySlowPath::callSiteIndex):
+ (JSC::FTL::LazySlowPath::stub):
+ * ftl/FTLLocation.cpp:
+ (JSC::FTL::Location::forValueRep):
+ (JSC::FTL::Location::forStackmaps):
+ (JSC::FTL::Location::dump):
+ (JSC::FTL::Location::isGPR):
+ (JSC::FTL::Location::gpr):
+ (JSC::FTL::Location::isFPR):
+ (JSC::FTL::Location::fpr):
+ (JSC::FTL::Location::restoreInto):
+ * ftl/FTLLocation.h:
+ (JSC::FTL::Location::Location):
+ (JSC::FTL::Location::forRegister):
+ (JSC::FTL::Location::forIndirect):
+ (JSC::FTL::Location::forConstant):
+ (JSC::FTL::Location::kind):
+ (JSC::FTL::Location::hasReg):
+ (JSC::FTL::Location::reg):
+ (JSC::FTL::Location::hasOffset):
+ (JSC::FTL::Location::offset):
+ (JSC::FTL::Location::hash):
+ (JSC::FTL::Location::hasDwarfRegNum): Deleted.
+ (JSC::FTL::Location::dwarfRegNum): Deleted.
+ (JSC::FTL::Location::hasDwarfReg): Deleted.
+ (JSC::FTL::Location::dwarfReg): Deleted.
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::DFG::LowerDFGToLLVM::LowerDFGToLLVM):
+ (JSC::FTL::DFG::LowerDFGToLLVM::lazySlowPath):
+ * jit/RegisterSet.cpp:
+ (JSC::RegisterSet::stubUnavailableRegisters):
+ (JSC::RegisterSet::macroScratchRegisters):
+ (JSC::RegisterSet::calleeSaveRegisters):
+ * jit/RegisterSet.h:
+
</ins><span class="cx"> 2015-11-30 Geoffrey Garen <ggaren@apple.com>
</span><span class="cx">
</span><span class="cx"> Use a better RNG for Math.random()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -212,6 +212,7 @@
</span><span class="cx"> params.value = value;
</span><span class="cx"> params.reps = reps;
</span><span class="cx"> params.usedRegisters = value->m_usedRegisters;
</span><ins>+ params.context = &context;
</ins><span class="cx">
</span><span class="cx"> value->m_generator->run(jit, params);
</span><span class="cx"> }));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -119,8 +119,10 @@
</span><span class="cx">
</span><span class="cx"> // Make sure that the successors are set up correctly.
</span><span class="cx"> ASSERT(block->successors().size() <= 2);
</span><del>- for (B3::BasicBlock* successor : block->successorBlocks())
- m_blockToBlock[block]->successors().append(m_blockToBlock[successor]);
</del><ins>+ for (B3::FrequentedBlock successor : block->successors()) {
+ m_blockToBlock[block]->successors().append(
+ Air::FrequentedBlock(m_blockToBlock[successor.block()], successor.frequency()));
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Air::InsertionSet insertionSet(m_code);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3PatchpointSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -99,6 +99,7 @@
</span><span class="cx"> params.value = value;
</span><span class="cx"> params.reps = reps;
</span><span class="cx"> params.usedRegisters = value->m_usedRegisters;
</span><ins>+ params.context = &context;
</ins><span class="cx">
</span><span class="cx"> value->m_generator->run(jit, params);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackmapValue.h (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapValue.h        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapValue.h        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -39,6 +39,10 @@
</span><span class="cx">
</span><span class="cx"> class StackmapValue;
</span><span class="cx">
</span><ins>+namespace Air {
+struct GenerationContext;
+}
+
</ins><span class="cx"> struct StackmapGenerationParams {
</span><span class="cx"> // This is the stackmap value that we're generating.
</span><span class="cx"> StackmapValue* value;
</span><span class="lines">@@ -49,6 +53,9 @@
</span><span class="cx">
</span><span class="cx"> // This tells you the registers that were used.
</span><span class="cx"> RegisterSet usedRegisters;
</span><ins>+
+ // The Air::GenerationContext gives you even more power.
+ Air::GenerationContext* context;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> typedef void StackmapGeneratorFunction(CCallHelpers&, const StackmapGenerationParams&);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJSTailCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ftl/FTLJSTailCall.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -71,11 +71,11 @@
</span><span class="cx"> switch (location.kind()) {
</span><span class="cx"> case Location::Register:
</span><span class="cx"> // We handle the addend outside
</span><del>- return ValueRecovery::inRegister(location.dwarfReg().reg(), format);
</del><ins>+ return ValueRecovery::inRegister(location.reg(), format);
</ins><span class="cx">
</span><span class="cx"> case Location::Indirect:
</span><span class="cx"> // Oh LLVM, you crazy...
</span><del>- RELEASE_ASSERT(location.dwarfReg().reg() == Reg(MacroAssembler::framePointerRegister));
</del><ins>+ RELEASE_ASSERT(location.reg() == Reg(MacroAssembler::framePointerRegister));
</ins><span class="cx"> RELEASE_ASSERT(!(location.offset() % sizeof(void*)));
</span><span class="cx"> // DataFormatInt32 and DataFormatBoolean should be already be boxed.
</span><span class="cx"> RELEASE_ASSERT(format != DataFormatInt32 && format != DataFormatBoolean);
</span><span class="lines">@@ -263,7 +263,7 @@
</span><span class="cx"> shuffleData.args[i] = recoveryFor(m_arguments[i], *record, jitCode.stackmaps);
</span><span class="cx"> if (FTL::Location addend = getRegisterWithAddend(m_arguments[i], *record, jitCode.stackmaps)) {
</span><span class="cx"> withAddend.add(
</span><del>- addend.dwarfReg().reg(),
</del><ins>+ addend.reg(),
</ins><span class="cx"> Vector<std::pair<ValueRecovery*, int32_t>>()).iterator->value.append(
</span><span class="cx"> std::make_pair(&shuffleData.args[i], addend.addend()));
</span><span class="cx"> numAddends++;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLazySlowPathcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -34,16 +34,31 @@
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx">
</span><span class="cx"> LazySlowPath::LazySlowPath(
</span><del>- CodeLocationLabel patchpoint, CodeLocationLabel exceptionTarget,
- const RegisterSet& usedRegisters, CallSiteIndex callSiteIndex, RefPtr<Generator> generator,
- GPRReg newZeroReg, ScratchRegisterAllocator scratchRegisterAllocator)
</del><ins>+#if FTL_USES_B3
+ CodeLocationJump patchableJump, CodeLocationLabel done,
+#else // FTL_USES_B3
+ CodeLocationLabel patchpoint,
+#endif // FTL_USES_B3
+ CodeLocationLabel exceptionTarget,
+ const RegisterSet& usedRegisters, CallSiteIndex callSiteIndex, RefPtr<Generator> generator
+#if !FTL_USES_B3
+ , GPRReg newZeroReg, ScratchRegisterAllocator scratchRegisterAllocator
+#endif // !FTL_USES_B3
+ )
+#if FTL_USES_B3
+ : m_patchableJump(patchableJump)
+ , m_done(done)
+#else // FTL_USES_B3
</ins><span class="cx"> : m_patchpoint(patchpoint)
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> , m_exceptionTarget(exceptionTarget)
</span><span class="cx"> , m_usedRegisters(usedRegisters)
</span><span class="cx"> , m_callSiteIndex(callSiteIndex)
</span><span class="cx"> , m_generator(generator)
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx"> , m_newZeroValueRegister(newZeroReg)
</span><span class="cx"> , m_scratchRegisterAllocator(scratchRegisterAllocator)
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -63,6 +78,7 @@
</span><span class="cx"> params.exceptionJumps = m_exceptionTarget ? &exceptionJumps : nullptr;
</span><span class="cx"> params.lazySlowPath = this;
</span><span class="cx">
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx"> unsigned bytesSaved = m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</span><span class="cx"> // This is needed because LLVM may create a stackmap location that is the register SP.
</span><span class="cx"> // But on arm64, SP is also the same register number as ZR, so LLVM is telling us that it has
</span><span class="lines">@@ -71,9 +87,11 @@
</span><span class="cx"> // into a non-SP register.
</span><span class="cx"> if (m_newZeroValueRegister != InvalidGPRReg)
</span><span class="cx"> jit.move(CCallHelpers::TrustedImm32(0), m_newZeroValueRegister);
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx">
</span><span class="cx"> m_generator->run(jit, params);
</span><span class="cx">
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx"> CCallHelpers::Label doneLabel;
</span><span class="cx"> CCallHelpers::Jump jumpToEndOfPatchpoint;
</span><span class="cx"> if (bytesSaved) {
</span><span class="lines">@@ -81,18 +99,27 @@
</span><span class="cx"> m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesSaved, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
</span><span class="cx"> jumpToEndOfPatchpoint = jit.jump();
</span><span class="cx"> }
</span><ins>+#endif // !FTL_USES_B3
</ins><span class="cx">
</span><span class="cx"> LinkBuffer linkBuffer(vm, jit, codeBlock, JITCompilationMustSucceed);
</span><ins>+#if FTL_USES_B3
+ linkBuffer.link(params.doneJumps, m_done);
+#else // FTL_USES_B3
</ins><span class="cx"> if (bytesSaved) {
</span><span class="cx"> linkBuffer.link(params.doneJumps, linkBuffer.locationOf(doneLabel));
</span><span class="cx"> linkBuffer.link(jumpToEndOfPatchpoint, m_patchpoint.labelAtOffset(MacroAssembler::maxJumpReplacementSize()));
</span><span class="cx"> } else
</span><span class="cx"> linkBuffer.link(params.doneJumps, m_patchpoint.labelAtOffset(MacroAssembler::maxJumpReplacementSize()));
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> if (m_exceptionTarget)
</span><span class="cx"> linkBuffer.link(exceptionJumps, m_exceptionTarget);
</span><span class="cx"> m_stub = FINALIZE_CODE_FOR(codeBlock, linkBuffer, ("Lazy slow path call stub"));
</span><span class="cx">
</span><ins>+#if FTL_USES_B3
+ MacroAssembler::repatchJump(m_patchableJump, CodeLocationLabel(m_stub.code()));
+#else // FTL_USES_B3
</ins><span class="cx"> MacroAssembler::replaceWithJump(m_patchpoint, CodeLocationLabel(m_stub.code()));
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLazySlowPathh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.h (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.h        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ftl/FTLLazySlowPath.h        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -66,12 +66,26 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> LazySlowPath(
</span><del>- CodeLocationLabel patchpoint, CodeLocationLabel exceptionTarget, const RegisterSet& usedRegisters,
- CallSiteIndex, RefPtr<Generator>, GPRReg newZeroReg, ScratchRegisterAllocator);
</del><ins>+#if FTL_USES_B3
+ CodeLocationJump patchableJump, CodeLocationLabel done,
+#else // FLT_USES_B3
+ CodeLocationLabel patchpoint,
+#endif // FTL_USES_B3
+ CodeLocationLabel exceptionTarget, const RegisterSet& usedRegisters,
+ CallSiteIndex, RefPtr<Generator>
+#if !FTL_USES_B3
+ , GPRReg newZeroReg, ScratchRegisterAllocator
+#endif // FTL_USES_B3
+ );
</ins><span class="cx">
</span><span class="cx"> ~LazySlowPath();
</span><span class="cx">
</span><ins>+#if FTL_USES_B3
+ CodeLocationJump patchableJump() const { return m_patchableJump; }
+ CodeLocationLabel done() const { return m_done; }
+#else // FTL_USES_B3
</ins><span class="cx"> CodeLocationLabel patchpoint() const { return m_patchpoint; }
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> const RegisterSet& usedRegisters() const { return m_usedRegisters; }
</span><span class="cx"> CallSiteIndex callSiteIndex() const { return m_callSiteIndex; }
</span><span class="cx">
</span><span class="lines">@@ -80,14 +94,21 @@
</span><span class="cx"> MacroAssemblerCodeRef stub() const { return m_stub; }
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+#if FTL_USES_B3
+ CodeLocationJump m_patchableJump;
+ CodeLocationLabel m_done;
+#else // FTL_USES_B3
</ins><span class="cx"> CodeLocationLabel m_patchpoint;
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> CodeLocationLabel m_exceptionTarget;
</span><span class="cx"> RegisterSet m_usedRegisters;
</span><span class="cx"> CallSiteIndex m_callSiteIndex;
</span><span class="cx"> MacroAssemblerCodeRef m_stub;
</span><span class="cx"> RefPtr<Generator> m_generator;
</span><ins>+#if !FTL_USES_B3
</ins><span class="cx"> GPRReg m_newZeroValueRegister;
</span><span class="cx"> ScratchRegisterAllocator m_scratchRegisterAllocator;
</span><ins>+#endif // FTL_USES_B3
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLocationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLocation.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLocation.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ftl/FTLLocation.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</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-2015 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">@@ -28,6 +28,7 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx">
</span><ins>+#include "B3ValueRep.h"
</ins><span class="cx"> #include "FTLSaveRestore.h"
</span><span class="cx"> #include "RegisterSet.h"
</span><span class="cx"> #include <wtf/CommaPrinter.h>
</span><span class="lines">@@ -36,6 +37,25 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx">
</span><ins>+using namespace B3;
+
+#if FTL_USES_B3
+Location Location::forValueRep(const ValueRep& rep)
+{
+ switch (rep.kind()) {
+ case ValueRep::Register:
+ return forRegister(rep.reg(), 0);
+ case ValueRep::Stack:
+ return forIndirect(GPRInfo::callFrameRegister, rep.offsetFromFP());
+ case ValueRep::Constant:
+ return forConstant(rep.value());
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return Location();
+ }
+}
+#endif // FTL_USES_B3
+
</ins><span class="cx"> Location Location::forStackmaps(const StackMaps* stackmaps, const StackMaps::Location& location)
</span><span class="cx"> {
</span><span class="cx"> switch (location.kind) {
</span><span class="lines">@@ -66,8 +86,8 @@
</span><span class="cx"> void Location::dump(PrintStream& out) const
</span><span class="cx"> {
</span><span class="cx"> out.print("(", kind());
</span><del>- if (hasDwarfReg())
- out.print(", ", dwarfReg());
</del><ins>+ if (hasReg())
+ out.print(", ", reg());
</ins><span class="cx"> if (hasOffset())
</span><span class="cx"> out.print(", ", offset());
</span><span class="cx"> if (hasAddend())
</span><span class="lines">@@ -84,22 +104,22 @@
</span><span class="cx">
</span><span class="cx"> bool Location::isGPR() const
</span><span class="cx"> {
</span><del>- return kind() == Register && dwarfReg().reg().isGPR();
</del><ins>+ return kind() == Register && reg().isGPR();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> GPRReg Location::gpr() const
</span><span class="cx"> {
</span><del>- return dwarfReg().reg().gpr();
</del><ins>+ return reg().gpr();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool Location::isFPR() const
</span><span class="cx"> {
</span><del>- return kind() == Register && dwarfReg().reg().isFPR();
</del><ins>+ return kind() == Register && reg().isFPR();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> FPRReg Location::fpr() const
</span><span class="cx"> {
</span><del>- return dwarfReg().reg().fpr();
</del><ins>+ return reg().fpr();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void Location::restoreInto(MacroAssembler& jit, char* savedRegisters, GPRReg result, unsigned numFramesToPop) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLocationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLocation.h (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLocation.h        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ftl/FTLLocation.h        2015-12-01 04:43:28 UTC (rev 192856)
</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-2015 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">@@ -28,14 +28,22 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx">
</span><ins>+#include "DFGCommon.h"
</ins><span class="cx"> #include "FPRInfo.h"
</span><span class="cx"> #include "FTLDWARFRegister.h"
</span><span class="cx"> #include "FTLStackMaps.h"
</span><span class="cx"> #include "GPRInfo.h"
</span><ins>+#include "Reg.h"
</ins><span class="cx"> #include <wtf/HashMap.h>
</span><span class="cx">
</span><del>-namespace JSC { namespace FTL {
</del><ins>+namespace JSC {
</ins><span class="cx">
</span><ins>+namespace B3 {
+class ValueRep;
+} // namespace B3
+
+namespace FTL {
+
</ins><span class="cx"> class Location {
</span><span class="cx"> public:
</span><span class="cx"> enum Kind {
</span><span class="lines">@@ -56,25 +64,35 @@
</span><span class="cx"> {
</span><span class="cx"> u.constant = 1;
</span><span class="cx"> }
</span><del>-
- static Location forRegister(DWARFRegister dwarfReg, int32_t addend)
</del><ins>+
+ static Location forRegister(Reg reg, int32_t addend)
</ins><span class="cx"> {
</span><span class="cx"> Location result;
</span><span class="cx"> result.m_kind = Register;
</span><del>- result.u.variable.dwarfRegNum = dwarfReg.dwarfRegNum();
</del><ins>+ result.u.variable.regIndex = reg.index();
</ins><span class="cx"> result.u.variable.offset = addend;
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- static Location forIndirect(DWARFRegister dwarfReg, int32_t offset)
</del><ins>+ static Location forRegister(DWARFRegister dwarfReg, int32_t addend)
</ins><span class="cx"> {
</span><ins>+ return forRegister(dwarfReg.reg(), addend);
+ }
+
+ static Location forIndirect(Reg reg, int32_t offset)
+ {
</ins><span class="cx"> Location result;
</span><span class="cx"> result.m_kind = Indirect;
</span><del>- result.u.variable.dwarfRegNum = dwarfReg.dwarfRegNum();
</del><ins>+ result.u.variable.regIndex = reg.index();
</ins><span class="cx"> result.u.variable.offset = offset;
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ static Location forIndirect(DWARFRegister dwarfReg, int32_t offset)
+ {
+ return forIndirect(dwarfReg.reg(), offset);
+ }
+
</ins><span class="cx"> static Location forConstant(int64_t constant)
</span><span class="cx"> {
</span><span class="cx"> Location result;
</span><span class="lines">@@ -83,22 +101,23 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if FTL_USES_B3
+ static Location forValueRep(const B3::ValueRep&);
+#endif // FTL_USES_B3
+
</ins><span class="cx"> // You can pass a null StackMaps if you are confident that the location doesn't
</span><span class="cx"> // involve a wide constant.
</span><span class="cx"> static Location forStackmaps(const StackMaps*, const StackMaps::Location&);
</span><span class="cx">
</span><span class="cx"> Kind kind() const { return m_kind; }
</span><del>-
- bool hasDwarfRegNum() const { return kind() == Register || kind() == Indirect; }
- int16_t dwarfRegNum() const
</del><ins>+
+ bool hasReg() const { return kind() == Register || kind() == Indirect; }
+ Reg reg() const
</ins><span class="cx"> {
</span><del>- ASSERT(hasDwarfRegNum());
- return u.variable.dwarfRegNum;
</del><ins>+ ASSERT(hasReg());
+ return Reg::fromIndex(u.variable.regIndex);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- bool hasDwarfReg() const { return hasDwarfRegNum(); }
- DWARFRegister dwarfReg() const { return DWARFRegister(dwarfRegNum()); }
-
</del><span class="cx"> bool hasOffset() const { return kind() == Indirect; }
</span><span class="cx"> int32_t offset() const
</span><span class="cx"> {
</span><span class="lines">@@ -142,11 +161,11 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case Register:
</span><del>- result ^= u.variable.dwarfRegNum;
</del><ins>+ result ^= u.variable.regIndex;
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case Indirect:
</span><del>- result ^= u.variable.dwarfRegNum;
</del><ins>+ result ^= u.variable.regIndex;
</ins><span class="cx"> result ^= u.variable.offset;
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -182,7 +201,7 @@
</span><span class="cx"> union {
</span><span class="cx"> int64_t constant;
</span><span class="cx"> struct {
</span><del>- int16_t dwarfRegNum;
</del><ins>+ unsigned regIndex;
</ins><span class="cx"> int32_t offset;
</span><span class="cx"> } variable;
</span><span class="cx"> } u;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx">
</span><ins>+#include "AirGenerationContext.h"
+#include "AllowMacroScratchRegisterUsage.h"
</ins><span class="cx"> #include "CodeBlockWithJITType.h"
</span><span class="cx"> #include "DFGAbstractInterpreterInlines.h"
</span><span class="cx"> #include "DFGDominators.h"
</span><span class="lines">@@ -100,6 +102,7 @@
</span><span class="cx"> } while (false)
</span><span class="cx">
</span><span class="cx"> class LowerDFGToLLVM {
</span><ins>+ WTF_MAKE_NONCOPYABLE(LowerDFGToLLVM);
</ins><span class="cx"> public:
</span><span class="cx"> LowerDFGToLLVM(State& state)
</span><span class="cx"> : m_graph(state.graph)
</span><span class="lines">@@ -7835,14 +7838,78 @@
</span><span class="cx"> LValue lazySlowPath(const Functor& functor, const Vector<LValue>& userArguments)
</span><span class="cx"> {
</span><span class="cx"> #if FTL_USES_B3
</span><del>- UNUSED_PARAM(functor);
-
</del><ins>+ CodeOrigin origin = m_node->origin.semantic;
+
</ins><span class="cx"> B3::PatchpointValue* result = m_out.patchpoint(B3::Int64);
</span><span class="cx"> for (LValue arg : userArguments)
</span><del>- result->append(ConstrainedValue(arg, ValueRep::SomeRegister));
</del><ins>+ result->append(ConstrainedValue(arg, B3::ValueRep::SomeRegister));
+
+ // FIXME: As part of handling exceptions, we need to append OSR exit state here.
+
+ result->clobber(RegisterSet::macroScratchRegisters());
+ State* state = &m_ftlState;
+
</ins><span class="cx"> result->setGenerator(
</span><del>- [&] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
- jit.oops();
</del><ins>+ [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ Vector<Location> locations;
+ for (const B3::ValueRep& rep : params.reps)
+ locations.append(Location::forValueRep(rep));
+
+ RefPtr<LazySlowPath::Generator> generator = functor(locations);
+
+ CCallHelpers::PatchableJump patchableJump = jit.patchableJump();
+ CCallHelpers::Label done = jit.label();
+
+ RegisterSet usedRegisters = params.usedRegisters;
+
+ // FIXME: As part of handling exceptions, we need to create a concrete OSRExit here.
+ // Doing so should automagically register late paths that emit exit thunks.
+
+ params.context->latePaths.append(
+ createSharedTask<Air::GenerationContext::LatePathFunction>(
+ [=] (CCallHelpers& jit, Air::GenerationContext&) {
+ AllowMacroScratchRegisterUsage allowScratch(jit);
+ patchableJump.m_jump.link(&jit);
+ unsigned index = state->jitCode->lazySlowPaths.size();
+ state->jitCode->lazySlowPaths.append(nullptr);
+ jit.pushToSaveImmediateWithoutTouchingRegisters(
+ CCallHelpers::TrustedImm32(index));
+ CCallHelpers::Jump generatorJump = jit.jump();
+
+ // Note that so long as we're here, we don't really know if our late path
+ // runs before or after any other late paths that we might depend on, like
+ // the exception thunk.
+
+ RefPtr<JITCode> jitCode = state->jitCode;
+ VM* vm = &state->graph.m_vm;
+
+ jit.addLinkTask(
+ [=] (LinkBuffer& linkBuffer) {
+ linkBuffer.link(
+ generatorJump, CodeLocationLabel(
+ vm->getCTIStub(
+ lazySlowPathGenerationThunkGenerator).code()));
+
+ CodeLocationJump linkedPatchableJump = CodeLocationJump(
+ linkBuffer.locationOf(patchableJump));
+ CodeLocationLabel linkedDone = linkBuffer.locationOf(done);
+
+ // FIXME: Need a story for exceptions in FTL-B3. That basically means
+ // doing a lookup of the exception entrypoint here. We will have an
+ // OSR exit data structure of some sort.
+ // https://bugs.webkit.org/show_bug.cgi?id=151686
+ CodeLocationLabel exceptionTarget;
+ CallSiteIndex callSiteIndex =
+ jitCode->common.addUniqueCallSiteIndex(origin);
+
+ std::unique_ptr<LazySlowPath> lazySlowPath =
+ std::make_unique<LazySlowPath>(
+ linkedPatchableJump, linkedDone, exceptionTarget,
+ usedRegisters, callSiteIndex, generator);
+
+ jitCode->lazySlowPaths[index] = WTF::move(lazySlowPath);
+ });
+ }));
</ins><span class="cx"> });
</span><span class="cx"> return result;
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.cpp (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-12-01 04:43:28 UTC (rev 192856)
</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-2015 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">@@ -80,6 +80,15 @@
</span><span class="cx"> return RegisterSet(specialRegisters(), vmCalleeSaveRegisters());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RegisterSet RegisterSet::macroScratchRegisters()
+{
+#if CPU(X86_64)
+ return RegisterSet(MacroAssembler::s_scratchRegister);
+#else
+ return RegisterSet();
+#endif
+}
+
</ins><span class="cx"> RegisterSet RegisterSet::calleeSaveRegisters()
</span><span class="cx"> {
</span><span class="cx"> RegisterSet result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.h (192855 => 192856)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.h        2015-12-01 03:39:59 UTC (rev 192855)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.h        2015-12-01 04:43:28 UTC (rev 192856)
</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-2015 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">@@ -59,6 +59,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> static RegisterSet volatileRegistersForJSCall();
</span><span class="cx"> static RegisterSet stubUnavailableRegisters(); // The union of callee saves and special registers.
</span><ins>+ static RegisterSet macroScratchRegisters();
</ins><span class="cx"> JS_EXPORT_PRIVATE static RegisterSet allGPRs();
</span><span class="cx"> JS_EXPORT_PRIVATE static RegisterSet allFPRs();
</span><span class="cx"> static RegisterSet allRegisters();
</span></span></pre>
</div>
</div>
</body>
</html>