<!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>[196032] 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/196032">196032</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-02-02 15:21:12 -0800 (Tue, 02 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Get rid of anonymous stack slots
https://bugs.webkit.org/show_bug.cgi?id=151128

Reviewed by Mark Lam.

Source/JavaScriptCore:

When I first designed stack slots, the idea was that an &quot;anonymous&quot; stack slot was one that
behaved exactly like a C variable: if it never escaped, it would not need to get stack space
for the entire lifetime of the function - it could get any slab of stack so long as it
didn't interfere with other stack slots that would be live at the same time. The reason I
called them &quot;anonymous&quot; is that external code could not get its address. This felt like it
gave the stack slot anonymity. But it was never a good name for this concept.

Then I had the register allocator lower temporaries to anonymous stack slots when it spilled
them. Spilling became the sole client of anonymous stack slots.

Then I realized that there was an aspect of how spill slots work that make them want
slightly different semantics than a normal C variable. A C variable is a proper memory
location - you could do a store to only some bytes in the variable, and it's reasonable to
expect that this will not destroy the other bytes in the variable. But that means that to
compute their liveness, you have to do something like a per-byte liveness. That's overkill
for spill slots. You want any store to the spill slot to kill the whole slot even if it
writes to just part of the slot. This matches how temporaries work. So rather than implement
per-byte liveness, I decided to change the semantics of anonymous stack slots to make them
work like how I wanted spill slots to work. This was quite dirty, and put B3 in the awkward
situation that B3's anonymous stack slots behaved like spill slots. But it was OK since
nobody used anonymous stack slots in B3.

Then I added tail duplication, which required having a mechanism for introducing non-SSA
variables in B3. I decided to use anonymous stack slots for this purpose. All of a sudden
this all felt like it made sense: anonymous stack slots were just like variables! Hooray for
the amazing foresight of anonymous stack slots!

But then I realized that this was all very bad. We want B3 to be able to optimize Store and
Load operations by reasoning about how they affect bytes in memory. For example, if you do
a Load of a 64-bit value, and then you modify just the low 32 bits of that value, and then
you do a 64-bit store back to the same location, then it would be better to transform this
into 32-bit operations. We don't do this optimization yet, but it's the kind of thing that
we want B3 to be able to do. To do it, we need Store to mean that it only affects N bytes
starting at the pointer, where N is the size of the thing being stored. But that's not what
Store means for anonymous stack slots. For anonymous slots, storing to any byte in the slot
clobbers all bytes in the slot. We were never clear if you need to store directly to an
anonymous slot to get this behavior, or if any pointer that points to an anoymous slot must
exhibit this behavior when stored to. Neither kinds of semantics make sense to me.

This change fixes the problem by eradicating anonymous stack slots. In B3, they are replaced
with Variables. In Air, they are replaced with a different stack slot kind, called Spill.
There is no such thing as stack slot kinds in B3 anymore, all B3 stack slots are locked. In
Air, there is still the concept of stack slot kind - Locked or Spill.

B3 Variables are awesome. They are exactly what they seem to be. They have a type. They are
declared at the top level in the Procedure. You can access them with new opcodes, Get and
Set. This greatly simplifies demoting SSA values to variables and promoting them back to
SSA. I even made the instruction selector do the right things for variables, which means
that introducing variables won't hurt instruction selection (there will be extra moves, but
IRC will kill them). It's great to have non-SSA variables as an explicit concept in IR
because it means that you don't have to do any magic to use them - they Just Work.

Air spill slots behave almost like anonymous stack slots, with one exception: you cannot
escape them. We validate this by making it illegal to UseAddr on a spill slot. This removes
the need to answer awkward questions like: does a 32-bit Def on a pointer that may point to
a 64-bit spill slot do anything to the 32 bits above the pointer?  Does it write zero to it?
Does it write zero to it just when the pointer actually points to a spill slot or always?
These are silly questions, and we don't have to answer them because the only way to refer to
a spill slot is directly. No escaping means no aliasing.

This doesn't affect performance. It just makes the compiler more fun to work with by
removing some cognitive dissonance.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3ArgumentRegValue.h:
* b3/B3CCallValue.h:
* b3/B3CheckValue.cpp:
(JSC::B3::CheckValue::cloneImpl):
(JSC::B3::CheckValue::CheckValue):
* b3/B3CheckValue.h:
* b3/B3Const32Value.h:
* b3/B3Const64Value.h:
* b3/B3ConstDoubleValue.h:
* b3/B3ConstFloatValue.h:
* b3/B3ConstPtrValue.h:
(JSC::B3::ConstPtrValue::ConstPtrValue):
* b3/B3ControlValue.cpp:
(JSC::B3::ControlValue::convertToJump):
(JSC::B3::ControlValue::convertToOops):
(JSC::B3::ControlValue::dumpMeta):
* b3/B3ControlValue.h:
* b3/B3Effects.cpp:
(JSC::B3::Effects::interferes):
(JSC::B3::Effects::dump):
* b3/B3Effects.h:
(JSC::B3::Effects::mustExecute):
* b3/B3EliminateCommonSubexpressions.cpp:
* b3/B3FixSSA.cpp:
(JSC::B3::demoteValues):
(JSC::B3::fixSSA):
* b3/B3FixSSA.h:
* b3/B3IndexMap.h:
(JSC::B3::IndexMap::resize):
(JSC::B3::IndexMap::clear):
(JSC::B3::IndexMap::size):
(JSC::B3::IndexMap::operator[]):
* b3/B3IndexSet.h:
(JSC::B3::IndexSet::contains):
(JSC::B3::IndexSet::size):
(JSC::B3::IndexSet::isEmpty):
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::run):
(JSC::B3::Air::LowerToAir::lower):
* b3/B3MemoryValue.h:
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3PatchpointValue.cpp:
(JSC::B3::PatchpointValue::cloneImpl):
(JSC::B3::PatchpointValue::PatchpointValue):
* b3/B3PatchpointValue.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::Procedure):
(JSC::B3::Procedure::addBlock):
(JSC::B3::Procedure::addStackSlot):
(JSC::B3::Procedure::addVariable):
(JSC::B3::Procedure::clone):
(JSC::B3::Procedure::addIntConstant):
(JSC::B3::Procedure::dump):
(JSC::B3::Procedure::deleteStackSlot):
(JSC::B3::Procedure::deleteVariable):
(JSC::B3::Procedure::deleteValue):
(JSC::B3::Procedure::deleteOrphans):
(JSC::B3::Procedure::calleeSaveRegisters):
(JSC::B3::Procedure::addValueImpl):
(JSC::B3::Procedure::setBlockOrderImpl):
(JSC::B3::Procedure::addAnonymousStackSlot): Deleted.
(JSC::B3::Procedure::addStackSlotIndex): Deleted.
(JSC::B3::Procedure::addValueIndex): Deleted.
* b3/B3Procedure.h:
(JSC::B3::Procedure::setBlockOrder):
(JSC::B3::Procedure::stackSlots):
(JSC::B3::Procedure::variables):
(JSC::B3::Procedure::values):
(JSC::B3::Procedure::StackSlotsCollection::StackSlotsCollection): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::size): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::at): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::operator[]): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::iterator::iterator): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator*): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator++): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator==): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator!=): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::iterator::findNext): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::begin): Deleted.
(JSC::B3::Procedure::StackSlotsCollection::end): Deleted.
(JSC::B3::Procedure::ValuesCollection::ValuesCollection): Deleted.
(JSC::B3::Procedure::ValuesCollection::iterator::iterator): Deleted.
(JSC::B3::Procedure::ValuesCollection::iterator::operator*): Deleted.
(JSC::B3::Procedure::ValuesCollection::iterator::operator++): Deleted.
(JSC::B3::Procedure::ValuesCollection::iterator::operator==): Deleted.
(JSC::B3::Procedure::ValuesCollection::iterator::operator!=): Deleted.
(JSC::B3::Procedure::ValuesCollection::iterator::findNext): Deleted.
(JSC::B3::Procedure::ValuesCollection::begin): Deleted.
(JSC::B3::Procedure::ValuesCollection::end): Deleted.
(JSC::B3::Procedure::ValuesCollection::size): Deleted.
(JSC::B3::Procedure::ValuesCollection::at): Deleted.
(JSC::B3::Procedure::ValuesCollection::operator[]): Deleted.
* b3/B3ProcedureInlines.h:
(JSC::B3::Procedure::add):
* b3/B3ReduceStrength.cpp:
* b3/B3SlotBaseValue.h:
* b3/B3SparseCollection.h: Added.
(JSC::B3::SparseCollection::SparseCollection):
(JSC::B3::SparseCollection::add):
(JSC::B3::SparseCollection::addNew):
(JSC::B3::SparseCollection::remove):
(JSC::B3::SparseCollection::size):
(JSC::B3::SparseCollection::isEmpty):
(JSC::B3::SparseCollection::at):
(JSC::B3::SparseCollection::operator[]):
(JSC::B3::SparseCollection::iterator::iterator):
(JSC::B3::SparseCollection::iterator::operator*):
(JSC::B3::SparseCollection::iterator::operator++):
(JSC::B3::SparseCollection::iterator::operator==):
(JSC::B3::SparseCollection::iterator::operator!=):
(JSC::B3::SparseCollection::iterator::findNext):
(JSC::B3::SparseCollection::begin):
(JSC::B3::SparseCollection::end):
* b3/B3StackSlot.cpp:
(JSC::B3::StackSlot::deepDump):
(JSC::B3::StackSlot::StackSlot):
* b3/B3StackSlot.h:
(JSC::B3::StackSlot::byteSize):
(JSC::B3::StackSlot::index):
(JSC::B3::StackSlot::setOffsetFromFP):
(JSC::B3::StackSlot::kind): Deleted.
(JSC::B3::StackSlot::isLocked): Deleted.
* b3/B3StackSlotKind.cpp: Removed.
* b3/B3StackSlotKind.h: Removed.
* b3/B3StackmapValue.cpp:
(JSC::B3::StackmapValue::dumpMeta):
(JSC::B3::StackmapValue::StackmapValue):
* b3/B3StackmapValue.h:
* b3/B3SwitchValue.cpp:
(JSC::B3::SwitchValue::cloneImpl):
(JSC::B3::SwitchValue::SwitchValue):
* b3/B3SwitchValue.h:
* b3/B3UpsilonValue.h:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::replaceWithIdentity):
(JSC::B3::Value::replaceWithNop):
(JSC::B3::Value::replaceWithPhi):
(JSC::B3::Value::dump):
(JSC::B3::Value::effects):
(JSC::B3::Value::checkOpcode):
* b3/B3Value.h:
* b3/B3Variable.cpp: Added.
(JSC::B3::Variable::~Variable):
(JSC::B3::Variable::dump):
(JSC::B3::Variable::deepDump):
(JSC::B3::Variable::Variable):
* b3/B3Variable.h: Added.
(JSC::B3::Variable::type):
(JSC::B3::Variable::index):
(JSC::B3::DeepVariableDump::DeepVariableDump):
(JSC::B3::DeepVariableDump::dump):
(JSC::B3::deepDump):
* b3/B3VariableValue.cpp: Added.
(JSC::B3::VariableValue::~VariableValue):
(JSC::B3::VariableValue::dumpMeta):
(JSC::B3::VariableValue::cloneImpl):
(JSC::B3::VariableValue::VariableValue):
* b3/B3VariableValue.h: Added.
* b3/air/AirAllocateStack.cpp:
(JSC::B3::Air::allocateStack):
* b3/air/AirCode.cpp:
(JSC::B3::Air::Code::addStackSlot):
(JSC::B3::Air::Code::addSpecial):
(JSC::B3::Air::Code::cCallSpecial):
* b3/air/AirCode.h:
(JSC::B3::Air::Code::begin):
(JSC::B3::Air::Code::end):
(JSC::B3::Air::Code::stackSlots):
(JSC::B3::Air::Code::specials):
(JSC::B3::Air::Code::forAllTmps):
(JSC::B3::Air::Code::StackSlotsCollection::StackSlotsCollection): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::size): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::at): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::operator[]): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::iterator::iterator): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::iterator::operator*): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::iterator::operator++): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::iterator::operator==): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::iterator::operator!=): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::begin): Deleted.
(JSC::B3::Air::Code::StackSlotsCollection::end): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::SpecialsCollection): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::size): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::at): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::operator[]): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::iterator::iterator): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::iterator::operator*): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::iterator::operator++): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::iterator::operator==): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::iterator::operator!=): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::begin): Deleted.
(JSC::B3::Air::Code::SpecialsCollection::end): Deleted.
* b3/air/AirFixObviousSpills.cpp:
* b3/air/AirInstInlines.h:
* b3/air/AirIteratedRegisterCoalescing.cpp:
* b3/air/AirLiveness.h:
* b3/air/AirLowerAfterRegAlloc.cpp:
(JSC::B3::Air::lowerAfterRegAlloc):
* b3/air/AirSpecial.cpp:
(JSC::B3::Air::Special::Special):
* b3/air/AirSpecial.h:
* b3/air/AirSpillEverything.cpp:
(JSC::B3::Air::spillEverything):
* b3/air/AirStackSlot.cpp:
(JSC::B3::Air::StackSlot::dump):
(JSC::B3::Air::StackSlot::deepDump):
(JSC::B3::Air::StackSlot::StackSlot):
* b3/air/AirStackSlot.h:
(JSC::B3::Air::StackSlot::byteSize):
(JSC::B3::Air::StackSlot::kind):
(JSC::B3::Air::StackSlot::isLocked):
(JSC::B3::Air::StackSlot::isSpill):
(JSC::B3::Air::StackSlot::index):
(JSC::B3::Air::StackSlot::ensureSize):
* b3/air/AirStackSlotKind.cpp: Copied from Source/JavaScriptCore/b3/B3StackSlotKind.cpp.
(WTF::printInternal):
* b3/air/AirStackSlotKind.h: Copied from Source/JavaScriptCore/b3/B3StackSlotKind.h.
* b3/air/opcode_generator.rb:
* b3/air/testair.cpp:
(JSC::B3::Air::testShuffleBroadcastAllRegs):
(JSC::B3::Air::testShuffleShiftAllRegs):
(JSC::B3::Air::testShuffleRotateAllRegs):
* b3/testb3.cpp:
(JSC::B3::testStackSlot):
(JSC::B3::testStoreLoadStackSlot):
* ftl/FTLB3Output.cpp:
(JSC::FTL::Output::lockedStackSlot):
(JSC::FTL::Output::neg):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):

Websites/webkit.org:

This changes the documentation to account for the addition of Variables and the Get and Set
opcodes, and the removal of anonymous stack slots from B3 IR.

* docs/b3/intermediate-representation.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ArgumentRegValueh">trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CCallValueh">trunk/Source/JavaScriptCore/b3/B3CCallValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckValuecpp">trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckValueh">trunk/Source/JavaScriptCore/b3/B3CheckValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const32Valueh">trunk/Source/JavaScriptCore/b3/B3Const32Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const64Valueh">trunk/Source/JavaScriptCore/b3/B3Const64Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstDoubleValueh">trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstFloatValueh">trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstPtrValueh">trunk/Source/JavaScriptCore/b3/B3ConstPtrValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ControlValuecpp">trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ControlValueh">trunk/Source/JavaScriptCore/b3/B3ControlValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Effectscpp">trunk/Source/JavaScriptCore/b3/B3Effects.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Effectsh">trunk/Source/JavaScriptCore/b3/B3Effects.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3EliminateCommonSubexpressionscpp">trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FixSSAcpp">trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FixSSAh">trunk/Source/JavaScriptCore/b3/B3FixSSA.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3IndexMaph">trunk/Source/JavaScriptCore/b3/B3IndexMap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3IndexSeth">trunk/Source/JavaScriptCore/b3/B3IndexSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3MemoryValueh">trunk/Source/JavaScriptCore/b3/B3MemoryValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodecpp">trunk/Source/JavaScriptCore/b3/B3Opcode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodeh">trunk/Source/JavaScriptCore/b3/B3Opcode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3PatchpointValuecpp">trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3PatchpointValueh">trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedurecpp">trunk/Source/JavaScriptCore/b3/B3Procedure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedureh">trunk/Source/JavaScriptCore/b3/B3Procedure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ProcedureInlinesh">trunk/Source/JavaScriptCore/b3/B3ProcedureInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp">trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SlotBaseValueh">trunk/Source/JavaScriptCore/b3/B3SlotBaseValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSlotcpp">trunk/Source/JavaScriptCore/b3/B3StackSlot.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSloth">trunk/Source/JavaScriptCore/b3/B3StackSlot.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapValuecpp">trunk/Source/JavaScriptCore/b3/B3StackmapValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapValueh">trunk/Source/JavaScriptCore/b3/B3StackmapValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SwitchValuecpp">trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SwitchValueh">trunk/Source/JavaScriptCore/b3/B3SwitchValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3UpsilonValueh">trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Validatecpp">trunk/Source/JavaScriptCore/b3/B3Validate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valueh">trunk/Source/JavaScriptCore/b3/B3Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirAllocateStackcpp">trunk/Source/JavaScriptCore/b3/air/AirAllocateStack.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCodecpp">trunk/Source/JavaScriptCore/b3/air/AirCode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCodeh">trunk/Source/JavaScriptCore/b3/air/AirCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirFixObviousSpillscpp">trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInstInlinesh">trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirIteratedRegisterCoalescingcpp">trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLivenessh">trunk/Source/JavaScriptCore/b3/air/AirLiveness.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp">trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirSpecialcpp">trunk/Source/JavaScriptCore/b3/air/AirSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirSpecialh">trunk/Source/JavaScriptCore/b3/air/AirSpecial.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirSpillEverythingcpp">trunk/Source/JavaScriptCore/b3/air/AirSpillEverything.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirStackSlotcpp">trunk/Source/JavaScriptCore/b3/air/AirStackSlot.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirStackSloth">trunk/Source/JavaScriptCore/b3/air/AirStackSlot.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airopcode_generatorrb">trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airtestaircpp">trunk/Source/JavaScriptCore/b3/air/testair.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLB3Outputcpp">trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkWebsiteswebkitorgChangeLog">trunk/Websites/webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml">trunk/Websites/webkit.org/docs/b3/intermediate-representation.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3B3SparseCollectionh">trunk/Source/JavaScriptCore/b3/B3SparseCollection.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Variablecpp">trunk/Source/JavaScriptCore/b3/B3Variable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Variableh">trunk/Source/JavaScriptCore/b3/B3Variable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3VariableValuecpp">trunk/Source/JavaScriptCore/b3/B3VariableValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3VariableValueh">trunk/Source/JavaScriptCore/b3/B3VariableValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirStackSlotKindcpp">trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirStackSlotKindh">trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSlotKindcpp">trunk/Source/JavaScriptCore/b3/B3StackSlotKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSlotKindh">trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -97,6 +97,7 @@
</span><span class="cx">     b3/air/AirSpecial.cpp
</span><span class="cx">     b3/air/AirSpillEverything.cpp
</span><span class="cx">     b3/air/AirStackSlot.cpp
</span><ins>+    b3/air/AirStackSlotKind.cpp
</ins><span class="cx">     b3/air/AirTmp.cpp
</span><span class="cx">     b3/air/AirTmpWidth.cpp
</span><span class="cx">     b3/air/AirValidate.cpp
</span><span class="lines">@@ -151,7 +152,6 @@
</span><span class="cx">     b3/B3StackmapGenerationParams.cpp
</span><span class="cx">     b3/B3StackmapSpecial.cpp
</span><span class="cx">     b3/B3StackmapValue.cpp
</span><del>-    b3/B3StackSlotKind.cpp
</del><span class="cx">     b3/B3StackSlot.cpp
</span><span class="cx">     b3/B3SwitchCase.cpp
</span><span class="cx">     b3/B3SwitchValue.cpp
</span><span class="lines">@@ -163,6 +163,8 @@
</span><span class="cx">     b3/B3Value.cpp
</span><span class="cx">     b3/B3ValueKey.cpp
</span><span class="cx">     b3/B3ValueRep.cpp
</span><ins>+    b3/B3Variable.cpp
+    b3/B3VariableValue.cpp
</ins><span class="cx"> 
</span><span class="cx">     bindings/ScriptFunctionCall.cpp
</span><span class="cx">     bindings/ScriptObject.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -1,3 +1,309 @@
</span><ins>+2016-02-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Get rid of anonymous stack slots
+        https://bugs.webkit.org/show_bug.cgi?id=151128
+
+        Reviewed by Mark Lam.
+
+        When I first designed stack slots, the idea was that an &quot;anonymous&quot; stack slot was one that
+        behaved exactly like a C variable: if it never escaped, it would not need to get stack space
+        for the entire lifetime of the function - it could get any slab of stack so long as it
+        didn't interfere with other stack slots that would be live at the same time. The reason I
+        called them &quot;anonymous&quot; is that external code could not get its address. This felt like it
+        gave the stack slot anonymity. But it was never a good name for this concept.
+
+        Then I had the register allocator lower temporaries to anonymous stack slots when it spilled
+        them. Spilling became the sole client of anonymous stack slots.
+
+        Then I realized that there was an aspect of how spill slots work that make them want
+        slightly different semantics than a normal C variable. A C variable is a proper memory
+        location - you could do a store to only some bytes in the variable, and it's reasonable to
+        expect that this will not destroy the other bytes in the variable. But that means that to
+        compute their liveness, you have to do something like a per-byte liveness. That's overkill
+        for spill slots. You want any store to the spill slot to kill the whole slot even if it
+        writes to just part of the slot. This matches how temporaries work. So rather than implement
+        per-byte liveness, I decided to change the semantics of anonymous stack slots to make them
+        work like how I wanted spill slots to work. This was quite dirty, and put B3 in the awkward
+        situation that B3's anonymous stack slots behaved like spill slots. But it was OK since
+        nobody used anonymous stack slots in B3.
+
+        Then I added tail duplication, which required having a mechanism for introducing non-SSA
+        variables in B3. I decided to use anonymous stack slots for this purpose. All of a sudden
+        this all felt like it made sense: anonymous stack slots were just like variables! Hooray for
+        the amazing foresight of anonymous stack slots!
+
+        But then I realized that this was all very bad. We want B3 to be able to optimize Store and
+        Load operations by reasoning about how they affect bytes in memory. For example, if you do
+        a Load of a 64-bit value, and then you modify just the low 32 bits of that value, and then
+        you do a 64-bit store back to the same location, then it would be better to transform this
+        into 32-bit operations. We don't do this optimization yet, but it's the kind of thing that
+        we want B3 to be able to do. To do it, we need Store to mean that it only affects N bytes
+        starting at the pointer, where N is the size of the thing being stored. But that's not what
+        Store means for anonymous stack slots. For anonymous slots, storing to any byte in the slot
+        clobbers all bytes in the slot. We were never clear if you need to store directly to an
+        anonymous slot to get this behavior, or if any pointer that points to an anoymous slot must
+        exhibit this behavior when stored to. Neither kinds of semantics make sense to me.
+
+        This change fixes the problem by eradicating anonymous stack slots. In B3, they are replaced
+        with Variables. In Air, they are replaced with a different stack slot kind, called Spill.
+        There is no such thing as stack slot kinds in B3 anymore, all B3 stack slots are locked. In
+        Air, there is still the concept of stack slot kind - Locked or Spill.
+
+        B3 Variables are awesome. They are exactly what they seem to be. They have a type. They are
+        declared at the top level in the Procedure. You can access them with new opcodes, Get and
+        Set. This greatly simplifies demoting SSA values to variables and promoting them back to
+        SSA. I even made the instruction selector do the right things for variables, which means
+        that introducing variables won't hurt instruction selection (there will be extra moves, but
+        IRC will kill them). It's great to have non-SSA variables as an explicit concept in IR
+        because it means that you don't have to do any magic to use them - they Just Work.
+
+        Air spill slots behave almost like anonymous stack slots, with one exception: you cannot
+        escape them. We validate this by making it illegal to UseAddr on a spill slot. This removes
+        the need to answer awkward questions like: does a 32-bit Def on a pointer that may point to
+        a 64-bit spill slot do anything to the 32 bits above the pointer?  Does it write zero to it?
+        Does it write zero to it just when the pointer actually points to a spill slot or always?
+        These are silly questions, and we don't have to answer them because the only way to refer to
+        a spill slot is directly. No escaping means no aliasing.
+
+        This doesn't affect performance. It just makes the compiler more fun to work with by
+        removing some cognitive dissonance.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/B3ArgumentRegValue.h:
+        * b3/B3CCallValue.h:
+        * b3/B3CheckValue.cpp:
+        (JSC::B3::CheckValue::cloneImpl):
+        (JSC::B3::CheckValue::CheckValue):
+        * b3/B3CheckValue.h:
+        * b3/B3Const32Value.h:
+        * b3/B3Const64Value.h:
+        * b3/B3ConstDoubleValue.h:
+        * b3/B3ConstFloatValue.h:
+        * b3/B3ConstPtrValue.h:
+        (JSC::B3::ConstPtrValue::ConstPtrValue):
+        * b3/B3ControlValue.cpp:
+        (JSC::B3::ControlValue::convertToJump):
+        (JSC::B3::ControlValue::convertToOops):
+        (JSC::B3::ControlValue::dumpMeta):
+        * b3/B3ControlValue.h:
+        * b3/B3Effects.cpp:
+        (JSC::B3::Effects::interferes):
+        (JSC::B3::Effects::dump):
+        * b3/B3Effects.h:
+        (JSC::B3::Effects::mustExecute):
+        * b3/B3EliminateCommonSubexpressions.cpp:
+        * b3/B3FixSSA.cpp:
+        (JSC::B3::demoteValues):
+        (JSC::B3::fixSSA):
+        * b3/B3FixSSA.h:
+        * b3/B3IndexMap.h:
+        (JSC::B3::IndexMap::resize):
+        (JSC::B3::IndexMap::clear):
+        (JSC::B3::IndexMap::size):
+        (JSC::B3::IndexMap::operator[]):
+        * b3/B3IndexSet.h:
+        (JSC::B3::IndexSet::contains):
+        (JSC::B3::IndexSet::size):
+        (JSC::B3::IndexSet::isEmpty):
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::run):
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3MemoryValue.h:
+        * b3/B3Opcode.cpp:
+        (WTF::printInternal):
+        * b3/B3Opcode.h:
+        * b3/B3PatchpointValue.cpp:
+        (JSC::B3::PatchpointValue::cloneImpl):
+        (JSC::B3::PatchpointValue::PatchpointValue):
+        * b3/B3PatchpointValue.h:
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::Procedure):
+        (JSC::B3::Procedure::addBlock):
+        (JSC::B3::Procedure::addStackSlot):
+        (JSC::B3::Procedure::addVariable):
+        (JSC::B3::Procedure::clone):
+        (JSC::B3::Procedure::addIntConstant):
+        (JSC::B3::Procedure::dump):
+        (JSC::B3::Procedure::deleteStackSlot):
+        (JSC::B3::Procedure::deleteVariable):
+        (JSC::B3::Procedure::deleteValue):
+        (JSC::B3::Procedure::deleteOrphans):
+        (JSC::B3::Procedure::calleeSaveRegisters):
+        (JSC::B3::Procedure::addValueImpl):
+        (JSC::B3::Procedure::setBlockOrderImpl):
+        (JSC::B3::Procedure::addAnonymousStackSlot): Deleted.
+        (JSC::B3::Procedure::addStackSlotIndex): Deleted.
+        (JSC::B3::Procedure::addValueIndex): Deleted.
+        * b3/B3Procedure.h:
+        (JSC::B3::Procedure::setBlockOrder):
+        (JSC::B3::Procedure::stackSlots):
+        (JSC::B3::Procedure::variables):
+        (JSC::B3::Procedure::values):
+        (JSC::B3::Procedure::StackSlotsCollection::StackSlotsCollection): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::size): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::at): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::operator[]): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::iterator): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator*): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator++): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator==): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator!=): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::findNext): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::begin): Deleted.
+        (JSC::B3::Procedure::StackSlotsCollection::end): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::ValuesCollection): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::iterator::iterator): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::iterator::operator*): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::iterator::operator++): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::iterator::operator==): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::iterator::operator!=): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::iterator::findNext): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::begin): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::end): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::size): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::at): Deleted.
+        (JSC::B3::Procedure::ValuesCollection::operator[]): Deleted.
+        * b3/B3ProcedureInlines.h:
+        (JSC::B3::Procedure::add):
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3SlotBaseValue.h:
+        * b3/B3SparseCollection.h: Added.
+        (JSC::B3::SparseCollection::SparseCollection):
+        (JSC::B3::SparseCollection::add):
+        (JSC::B3::SparseCollection::addNew):
+        (JSC::B3::SparseCollection::remove):
+        (JSC::B3::SparseCollection::size):
+        (JSC::B3::SparseCollection::isEmpty):
+        (JSC::B3::SparseCollection::at):
+        (JSC::B3::SparseCollection::operator[]):
+        (JSC::B3::SparseCollection::iterator::iterator):
+        (JSC::B3::SparseCollection::iterator::operator*):
+        (JSC::B3::SparseCollection::iterator::operator++):
+        (JSC::B3::SparseCollection::iterator::operator==):
+        (JSC::B3::SparseCollection::iterator::operator!=):
+        (JSC::B3::SparseCollection::iterator::findNext):
+        (JSC::B3::SparseCollection::begin):
+        (JSC::B3::SparseCollection::end):
+        * b3/B3StackSlot.cpp:
+        (JSC::B3::StackSlot::deepDump):
+        (JSC::B3::StackSlot::StackSlot):
+        * b3/B3StackSlot.h:
+        (JSC::B3::StackSlot::byteSize):
+        (JSC::B3::StackSlot::index):
+        (JSC::B3::StackSlot::setOffsetFromFP):
+        (JSC::B3::StackSlot::kind): Deleted.
+        (JSC::B3::StackSlot::isLocked): Deleted.
+        * b3/B3StackSlotKind.cpp: Removed.
+        * b3/B3StackSlotKind.h: Removed.
+        * b3/B3StackmapValue.cpp:
+        (JSC::B3::StackmapValue::dumpMeta):
+        (JSC::B3::StackmapValue::StackmapValue):
+        * b3/B3StackmapValue.h:
+        * b3/B3SwitchValue.cpp:
+        (JSC::B3::SwitchValue::cloneImpl):
+        (JSC::B3::SwitchValue::SwitchValue):
+        * b3/B3SwitchValue.h:
+        * b3/B3UpsilonValue.h:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::replaceWithIdentity):
+        (JSC::B3::Value::replaceWithNop):
+        (JSC::B3::Value::replaceWithPhi):
+        (JSC::B3::Value::dump):
+        (JSC::B3::Value::effects):
+        (JSC::B3::Value::checkOpcode):
+        * b3/B3Value.h:
+        * b3/B3Variable.cpp: Added.
+        (JSC::B3::Variable::~Variable):
+        (JSC::B3::Variable::dump):
+        (JSC::B3::Variable::deepDump):
+        (JSC::B3::Variable::Variable):
+        * b3/B3Variable.h: Added.
+        (JSC::B3::Variable::type):
+        (JSC::B3::Variable::index):
+        (JSC::B3::DeepVariableDump::DeepVariableDump):
+        (JSC::B3::DeepVariableDump::dump):
+        (JSC::B3::deepDump):
+        * b3/B3VariableValue.cpp: Added.
+        (JSC::B3::VariableValue::~VariableValue):
+        (JSC::B3::VariableValue::dumpMeta):
+        (JSC::B3::VariableValue::cloneImpl):
+        (JSC::B3::VariableValue::VariableValue):
+        * b3/B3VariableValue.h: Added.
+        * b3/air/AirAllocateStack.cpp:
+        (JSC::B3::Air::allocateStack):
+        * b3/air/AirCode.cpp:
+        (JSC::B3::Air::Code::addStackSlot):
+        (JSC::B3::Air::Code::addSpecial):
+        (JSC::B3::Air::Code::cCallSpecial):
+        * b3/air/AirCode.h:
+        (JSC::B3::Air::Code::begin):
+        (JSC::B3::Air::Code::end):
+        (JSC::B3::Air::Code::stackSlots):
+        (JSC::B3::Air::Code::specials):
+        (JSC::B3::Air::Code::forAllTmps):
+        (JSC::B3::Air::Code::StackSlotsCollection::StackSlotsCollection): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::size): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::at): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::operator[]): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::iterator::iterator): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::iterator::operator*): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::iterator::operator++): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::iterator::operator==): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::iterator::operator!=): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::begin): Deleted.
+        (JSC::B3::Air::Code::StackSlotsCollection::end): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::SpecialsCollection): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::size): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::at): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::operator[]): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::iterator::iterator): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::iterator::operator*): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::iterator::operator++): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::iterator::operator==): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::iterator::operator!=): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::begin): Deleted.
+        (JSC::B3::Air::Code::SpecialsCollection::end): Deleted.
+        * b3/air/AirFixObviousSpills.cpp:
+        * b3/air/AirInstInlines.h:
+        * b3/air/AirIteratedRegisterCoalescing.cpp:
+        * b3/air/AirLiveness.h:
+        * b3/air/AirLowerAfterRegAlloc.cpp:
+        (JSC::B3::Air::lowerAfterRegAlloc):
+        * b3/air/AirSpecial.cpp:
+        (JSC::B3::Air::Special::Special):
+        * b3/air/AirSpecial.h:
+        * b3/air/AirSpillEverything.cpp:
+        (JSC::B3::Air::spillEverything):
+        * b3/air/AirStackSlot.cpp:
+        (JSC::B3::Air::StackSlot::dump):
+        (JSC::B3::Air::StackSlot::deepDump):
+        (JSC::B3::Air::StackSlot::StackSlot):
+        * b3/air/AirStackSlot.h:
+        (JSC::B3::Air::StackSlot::byteSize):
+        (JSC::B3::Air::StackSlot::kind):
+        (JSC::B3::Air::StackSlot::isLocked):
+        (JSC::B3::Air::StackSlot::isSpill):
+        (JSC::B3::Air::StackSlot::index):
+        (JSC::B3::Air::StackSlot::ensureSize):
+        * b3/air/AirStackSlotKind.cpp: Copied from Source/JavaScriptCore/b3/B3StackSlotKind.cpp.
+        (WTF::printInternal):
+        * b3/air/AirStackSlotKind.h: Copied from Source/JavaScriptCore/b3/B3StackSlotKind.h.
+        * b3/air/opcode_generator.rb:
+        * b3/air/testair.cpp:
+        (JSC::B3::Air::testShuffleBroadcastAllRegs):
+        (JSC::B3::Air::testShuffleShiftAllRegs):
+        (JSC::B3::Air::testShuffleRotateAllRegs):
+        * b3/testb3.cpp:
+        (JSC::B3::testStackSlot):
+        (JSC::B3::testStoreLoadStackSlot):
+        * ftl/FTLB3Output.cpp:
+        (JSC::FTL::Output::lockedStackSlot):
+        (JSC::FTL::Output::neg):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):
+
</ins><span class="cx"> 2016-02-02  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Introduce BytecodeIntrinsic constant rep like @undefined
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -239,6 +239,13 @@
</span><span class="cx">                 0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */; };
</span><span class="cx">                 0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F2BBD961C5FF3F50023EF23 /* B3SparseCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BBD911C5FF3F50023EF23 /* B3SparseCollection.h */; };
+                0F2BBD971C5FF3F50023EF23 /* B3Variable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BBD921C5FF3F50023EF23 /* B3Variable.cpp */; };
+                0F2BBD981C5FF3F50023EF23 /* B3Variable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BBD931C5FF3F50023EF23 /* B3Variable.h */; };
+                0F2BBD991C5FF3F50023EF23 /* B3VariableValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BBD941C5FF3F50023EF23 /* B3VariableValue.cpp */; };
+                0F2BBD9A1C5FF3F50023EF23 /* B3VariableValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BBD951C5FF3F50023EF23 /* B3VariableValue.h */; };
+                0F2BBD9D1C5FF4050023EF23 /* AirStackSlotKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BBD9B1C5FF4050023EF23 /* AirStackSlotKind.cpp */; };
+                0F2BBD9E1C5FF4050023EF23 /* AirStackSlotKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BBD9C1C5FF4050023EF23 /* AirStackSlotKind.h */; };
</ins><span class="cx">                 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */; };
</span><span class="cx">                 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */; };
</span><span class="cx">                 0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */; };
</span><span class="lines">@@ -832,8 +839,6 @@
</span><span class="cx">                 0FEC852D1BDACDAC0080FF74 /* B3ProcedureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */; };
</span><span class="cx">                 0FEC85301BDACDAC0080FF74 /* B3StackmapSpecial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */; };
</span><span class="cx">                 0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */; };
</span><del>-                0FEC85321BDACDAC0080FF74 /* B3StackSlotKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */; };
-                0FEC85331BDACDAC0080FF74 /* B3StackSlotKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */; };
</del><span class="cx">                 0FEC85341BDACDAC0080FF74 /* B3SlotBaseValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84EA1BDACDAC0080FF74 /* B3SlotBaseValue.cpp */; };
</span><span class="cx">                 0FEC85351BDACDAC0080FF74 /* B3SlotBaseValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84EB1BDACDAC0080FF74 /* B3SlotBaseValue.h */; };
</span><span class="cx">                 0FEC85361BDACDAC0080FF74 /* B3SuccessorCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84EC1BDACDAC0080FF74 /* B3SuccessorCollection.h */; };
</span><span class="lines">@@ -2433,6 +2438,13 @@
</span><span class="cx">                 0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitTimeObjectMaterialization.h; path = ftl/FTLExitTimeObjectMaterialization.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLOperations.cpp; path = ftl/FTLOperations.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOperations.h; path = ftl/FTLOperations.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F2BBD911C5FF3F50023EF23 /* B3SparseCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SparseCollection.h; path = b3/B3SparseCollection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2BBD921C5FF3F50023EF23 /* B3Variable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Variable.cpp; path = b3/B3Variable.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2BBD931C5FF3F50023EF23 /* B3Variable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Variable.h; path = b3/B3Variable.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2BBD941C5FF3F50023EF23 /* B3VariableValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3VariableValue.cpp; path = b3/B3VariableValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2BBD951C5FF3F50023EF23 /* B3VariableValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3VariableValue.h; path = b3/B3VariableValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2BBD9B1C5FF4050023EF23 /* AirStackSlotKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirStackSlotKind.cpp; path = b3/air/AirStackSlotKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2BBD9C1C5FF4050023EF23 /* AirStackSlotKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirStackSlotKind.h; path = b3/air/AirStackSlotKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFixupPhase.cpp; path = dfg/DFGFixupPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFixupPhase.h; path = dfg/DFGFixupPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertionSet.h; path = dfg/DFGInsertionSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3035,8 +3047,6 @@
</span><span class="cx">                 0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ProcedureInlines.h; path = b3/B3ProcedureInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackmapSpecial.cpp; path = b3/B3StackmapSpecial.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackmapSpecial.h; path = b3/B3StackmapSpecial.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackSlotKind.cpp; path = b3/B3StackSlotKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackSlotKind.h; path = b3/B3StackSlotKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0FEC84EA1BDACDAC0080FF74 /* B3SlotBaseValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3SlotBaseValue.cpp; path = b3/B3SlotBaseValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FEC84EB1BDACDAC0080FF74 /* B3SlotBaseValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SlotBaseValue.h; path = b3/B3SlotBaseValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FEC84EC1BDACDAC0080FF74 /* B3SuccessorCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SuccessorCollection.h; path = b3/B3SuccessorCollection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4870,6 +4880,7 @@
</span><span class="cx">                                 0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */,
</span><span class="cx">                                 0FEC84EA1BDACDAC0080FF74 /* B3SlotBaseValue.cpp */,
</span><span class="cx">                                 0FEC84EB1BDACDAC0080FF74 /* B3SlotBaseValue.h */,
</span><ins>+                                0F2BBD911C5FF3F50023EF23 /* B3SparseCollection.h */,
</ins><span class="cx">                                 0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */,
</span><span class="cx">                                 0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */,
</span><span class="cx">                                 0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */,
</span><span class="lines">@@ -4880,8 +4891,6 @@
</span><span class="cx">                                 0F338DF01BE93AD10013C88F /* B3StackmapValue.h */,
</span><span class="cx">                                 0F9495851C57F47500413A48 /* B3StackSlot.cpp */,
</span><span class="cx">                                 0F9495861C57F47500413A48 /* B3StackSlot.h */,
</span><del>-                                0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */,
-                                0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */,
</del><span class="cx">                                 0FEC84EC1BDACDAC0080FF74 /* B3SuccessorCollection.h */,
</span><span class="cx">                                 0FEC84ED1BDACDAC0080FF74 /* B3SwitchCase.cpp */,
</span><span class="cx">                                 0FEC84EE1BDACDAC0080FF74 /* B3SwitchCase.h */,
</span><span class="lines">@@ -4905,6 +4914,10 @@
</span><span class="cx">                                 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */,
</span><span class="cx">                                 0FEC84FC1BDACDAC0080FF74 /* B3ValueRep.cpp */,
</span><span class="cx">                                 0FEC84FD1BDACDAC0080FF74 /* B3ValueRep.h */,
</span><ins>+                                0F2BBD921C5FF3F50023EF23 /* B3Variable.cpp */,
+                                0F2BBD931C5FF3F50023EF23 /* B3Variable.h */,
+                                0F2BBD941C5FF3F50023EF23 /* B3VariableValue.cpp */,
+                                0F2BBD951C5FF3F50023EF23 /* B3VariableValue.h */,
</ins><span class="cx">                                 0FEC85AE1BDB5D5E0080FF74 /* testb3.cpp */,
</span><span class="cx">                         );
</span><span class="cx">                         name = b3;
</span><span class="lines">@@ -4975,6 +4988,8 @@
</span><span class="cx">                                 0FEC85651BDACDC70080FF74 /* AirSpillEverything.h */,
</span><span class="cx">                                 0FEC85661BDACDC70080FF74 /* AirStackSlot.cpp */,
</span><span class="cx">                                 0FEC85671BDACDC70080FF74 /* AirStackSlot.h */,
</span><ins>+                                0F2BBD9B1C5FF4050023EF23 /* AirStackSlotKind.cpp */,
+                                0F2BBD9C1C5FF4050023EF23 /* AirStackSlotKind.h */,
</ins><span class="cx">                                 0FEC85681BDACDC70080FF74 /* AirTmp.cpp */,
</span><span class="cx">                                 0FEC85691BDACDC70080FF74 /* AirTmp.h */,
</span><span class="cx">                                 0FEC856A1BDACDC70080FF74 /* AirTmpInlines.h */,
</span><span class="lines">@@ -7134,7 +7149,6 @@
</span><span class="cx">                                 0FEC852D1BDACDAC0080FF74 /* B3ProcedureInlines.h in Headers */,
</span><span class="cx">                                 0FEC85BD1BE1462F0080FF74 /* B3ReduceStrength.h in Headers */,
</span><span class="cx">                                 0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */,
</span><del>-                                0FEC85331BDACDAC0080FF74 /* B3StackSlotKind.h in Headers */,
</del><span class="cx">                                 0FEC85351BDACDAC0080FF74 /* B3SlotBaseValue.h in Headers */,
</span><span class="cx">                                 0FEC85361BDACDAC0080FF74 /* B3SuccessorCollection.h in Headers */,
</span><span class="cx">                                 0FEC85381BDACDAC0080FF74 /* B3SwitchCase.h in Headers */,
</span><span class="lines">@@ -7219,6 +7233,7 @@
</span><span class="cx">                                 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
</span><span class="cx">                                 6553A33217A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h in Headers */,
</span><span class="cx">                                 0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */,
</span><ins>+                                0F2BBD9E1C5FF4050023EF23 /* AirStackSlotKind.h in Headers */,
</ins><span class="cx">                                 A7E5A3A81797432D00E893C0 /* CompilationResult.h in Headers */,
</span><span class="cx">                                 BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
</span><span class="cx">                                 0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */,
</span><span class="lines">@@ -7292,6 +7307,7 @@
</span><span class="cx">                                 43422A631C158E6D00E2EB98 /* B3ConstFloatValue.h in Headers */,
</span><span class="cx">                                 0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */,
</span><span class="cx">                                 A7D89CF417A0B8CC00773AD8 /* DFGBlockInsertionSet.h in Headers */,
</span><ins>+                                0F2BBD961C5FF3F50023EF23 /* B3SparseCollection.h in Headers */,
</ins><span class="cx">                                 0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */,
</span><span class="cx">                                 0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */,
</span><span class="cx">                                 0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */,
</span><span class="lines">@@ -7571,6 +7587,7 @@
</span><span class="cx">                                 0F2B66AE17B6B54500A7AE3F /* GCIncomingRefCountedSet.h in Headers */,
</span><span class="cx">                                 0F2B66AF17B6B54500A7AE3F /* GCIncomingRefCountedSetInlines.h in Headers */,
</span><span class="cx">                                 2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
</span><ins>+                                0F2BBD981C5FF3F50023EF23 /* B3Variable.h in Headers */,
</ins><span class="cx">                                 A54E8EB018BFFBBB00556D28 /* GCSegmentedArray.h in Headers */,
</span><span class="cx">                                 A54E8EB118BFFBBE00556D28 /* GCSegmentedArrayInlines.h in Headers */,
</span><span class="cx">                                 9959E9311BD18272001AA413 /* generate-combined-inspector-json.py in Headers */,
</span><span class="lines">@@ -8183,6 +8200,7 @@
</span><span class="cx">                                 0F6B8ADD1C4EFAC300969052 /* B3SSACalculator.h in Headers */,
</span><span class="cx">                                 7B0247591B868EB700542440 /* WASMFunctionSyntaxChecker.h in Headers */,
</span><span class="cx">                                 7B39F76E1B62DE3200360FB4 /* WASMModuleParser.h in Headers */,
</span><ins>+                                0F2BBD9A1C5FF3F50023EF23 /* B3VariableValue.h in Headers */,
</ins><span class="cx">                                 7B39F7701B62DE3200360FB4 /* WASMReader.h in Headers */,
</span><span class="cx">                                 FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
</span><span class="cx">                                 0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
</span><span class="lines">@@ -8831,7 +8849,6 @@
</span><span class="cx">                                 43422A621C158E6A00E2EB98 /* B3ConstFloatValue.cpp in Sources */,
</span><span class="cx">                                 0FEC85BC1BE1462F0080FF74 /* B3ReduceStrength.cpp in Sources */,
</span><span class="cx">                                 0FEC85301BDACDAC0080FF74 /* B3StackmapSpecial.cpp in Sources */,
</span><del>-                                0FEC85321BDACDAC0080FF74 /* B3StackSlotKind.cpp in Sources */,
</del><span class="cx">                                 0FEC85341BDACDAC0080FF74 /* B3SlotBaseValue.cpp in Sources */,
</span><span class="cx">                                 0FEC85371BDACDAC0080FF74 /* B3SwitchCase.cpp in Sources */,
</span><span class="cx">                                 0FEC85391BDACDAC0080FF74 /* B3SwitchValue.cpp in Sources */,
</span><span class="lines">@@ -9067,6 +9084,7 @@
</span><span class="cx">                                 0FC97F4118202119002C9B26 /* DFGWatchpointCollectionPhase.cpp in Sources */,
</span><span class="cx">                                 0FDB2CE7174830A2007B3C1B /* DFGWorklist.cpp in Sources */,
</span><span class="cx">                                 0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */,
</span><ins>+                                0F2BBD9D1C5FF4050023EF23 /* AirStackSlotKind.cpp in Sources */,
</ins><span class="cx">                                 0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */,
</span><span class="cx">                                 0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */,
</span><span class="cx">                                 A70447ED17A0BD7000F5898E /* DumpContext.cpp in Sources */,
</span><span class="lines">@@ -9562,11 +9580,13 @@
</span><span class="cx">                                 2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */,
</span><span class="cx">                                 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
</span><span class="cx">                                 A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
</span><ins>+                                0F2BBD971C5FF3F50023EF23 /* B3Variable.cpp in Sources */,
</ins><span class="cx">                                 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
</span><span class="cx">                                 86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
</span><span class="cx">                                 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
</span><span class="cx">                                 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
</span><span class="cx">                                 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
</span><ins>+                                0F2BBD991C5FF3F50023EF23 /* B3VariableValue.cpp in Sources */,
</ins><span class="cx">                         );
</span><span class="cx">                         runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">                 };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ArgumentRegValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -49,8 +49,8 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    ArgumentRegValue(unsigned index, Origin origin, Reg reg)
-        : Value(index, CheckedOpcode, ArgumentReg, reg.isGPR() ? pointerType() : Double, origin)
</del><ins>+    ArgumentRegValue(Origin origin, Reg reg)
+        : Value(CheckedOpcode, ArgumentReg, reg.isGPR() ? pointerType() : Double, origin)
</ins><span class="cx">         , m_reg(reg)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(reg.isSet());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CCallValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CCallValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -48,15 +48,15 @@
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    CCallValue(unsigned index, Type type, Origin origin, Arguments... arguments)
-        : Value(index, CheckedOpcode, CCall, type, origin, arguments...)
</del><ins>+    CCallValue(Type type, Origin origin, Arguments... arguments)
+        : Value(CheckedOpcode, CCall, type, origin, arguments...)
</ins><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(numChildren() &gt;= 1);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    CCallValue(unsigned index, Type type, Origin origin, const Effects&amp; effects, Arguments... arguments)
-        : Value(index, CheckedOpcode, CCall, type, origin, arguments...)
</del><ins>+    CCallValue(Type type, Origin origin, const Effects&amp; effects, Arguments... arguments)
+        : Value(CheckedOpcode, CCall, type, origin, arguments...)
</ins><span class="cx">         , effects(effects)
</span><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(numChildren() &gt;= 1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -46,8 +46,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Use this form for CheckAdd, CheckSub, and CheckMul.
</span><del>-CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
-    : StackmapValue(index, CheckedOpcode, opcode, left-&gt;type(), origin)
</del><ins>+CheckValue::CheckValue(Opcode opcode, Origin origin, Value* left, Value* right)
+    : StackmapValue(CheckedOpcode, opcode, left-&gt;type(), origin)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(B3::isInt(type()));
</span><span class="cx">     ASSERT(left-&gt;type() == right-&gt;type());
</span><span class="lines">@@ -57,8 +57,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Use this form for Check.
</span><del>-CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* predicate)
-    : StackmapValue(index, CheckedOpcode, opcode, Void, origin)
</del><ins>+CheckValue::CheckValue(Opcode opcode, Origin origin, Value* predicate)
+    : StackmapValue(CheckedOpcode, opcode, Void, origin)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(opcode == Check);
</span><span class="cx">     append(ConstrainedValue(predicate, ValueRep::WarmAny));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3CheckValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -58,10 +58,10 @@
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="cx">     // Use this form for CheckAdd, CheckSub, and CheckMul.
</span><del>-    JS_EXPORT_PRIVATE CheckValue(unsigned index, Opcode, Origin, Value* left, Value* right);
</del><ins>+    JS_EXPORT_PRIVATE CheckValue(Opcode, Origin, Value* left, Value* right);
</ins><span class="cx"> 
</span><span class="cx">     // Use this form for Check.
</span><del>-    JS_EXPORT_PRIVATE CheckValue(unsigned index, Opcode, Origin, Value* predicate);
</del><ins>+    JS_EXPORT_PRIVATE CheckValue(Opcode, Origin, Value* predicate);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const32Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -77,8 +77,8 @@
</span><span class="cx"> 
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    Const32Value(unsigned index, Origin origin, int32_t value)
-        : Value(index, CheckedOpcode, Const32, Int32, origin)
</del><ins>+    Const32Value(Origin origin, int32_t value)
+        : Value(CheckedOpcode, Const32, Int32, origin)
</ins><span class="cx">         , m_value(value)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -77,8 +77,8 @@
</span><span class="cx"> 
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    Const64Value(unsigned index, Origin origin, int64_t value)
-        : Value(index, CheckedOpcode, Const64, Int64, origin)
</del><ins>+    Const64Value(Origin origin, int64_t value)
+        : Value(CheckedOpcode, Const64, Int64, origin)
</ins><span class="cx">         , m_value(value)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -70,8 +70,8 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    ConstDoubleValue(unsigned index, Origin origin, double value)
-        : Value(index, CheckedOpcode, ConstDouble, Double, origin)
</del><ins>+    ConstDoubleValue(Origin origin, double value)
+        : Value(CheckedOpcode, ConstDouble, Double, origin)
</ins><span class="cx">         , m_value(value)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstFloatValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -68,8 +68,8 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    ConstFloatValue(unsigned index, Origin origin, float value)
-        : Value(index, CheckedOpcode, ConstFloat, Float, origin)
</del><ins>+    ConstFloatValue(Origin origin, float value)
+        : Value(CheckedOpcode, ConstFloat, Float, origin)
</ins><span class="cx">         , m_value(value)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstPtrValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstPtrValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstPtrValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ConstPtrValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 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">@@ -54,13 +54,13 @@
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename T&gt;
</span><del>-    ConstPtrValue(unsigned index, Origin origin, T* pointer)
-        : ConstPtrValueBase(index, origin, bitwise_cast&lt;intptr_t&gt;(pointer))
</del><ins>+    ConstPtrValue(Origin origin, T* pointer)
+        : ConstPtrValueBase(origin, bitwise_cast&lt;intptr_t&gt;(pointer))
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     template&lt;typename T&gt;
</span><del>-    ConstPtrValue(unsigned index, Origin origin, T pointer)
-        : ConstPtrValueBase(index, origin, static_cast&lt;intptr_t&gt;(pointer))
</del><ins>+    ConstPtrValue(Origin origin, T pointer)
+        : ConstPtrValueBase(origin, static_cast&lt;intptr_t&gt;(pointer))
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ControlValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -59,9 +59,10 @@
</span><span class="cx"> 
</span><span class="cx">     this-&gt;ControlValue::~ControlValue();
</span><span class="cx"> 
</span><del>-    new (this) ControlValue(index, Jump, origin, FrequentedBlock(destination));
</del><ins>+    new (this) ControlValue(Jump, origin, FrequentedBlock(destination));
</ins><span class="cx"> 
</span><span class="cx">     this-&gt;owner = owner;
</span><ins>+    this-&gt;m_index = index;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ControlValue::convertToOops()
</span><span class="lines">@@ -72,9 +73,10 @@
</span><span class="cx"> 
</span><span class="cx">     this-&gt;ControlValue::~ControlValue();
</span><span class="cx"> 
</span><del>-    new (this) ControlValue(index, Oops, origin);
</del><ins>+    new (this) ControlValue(Oops, origin);
</ins><span class="cx"> 
</span><span class="cx">     this-&gt;owner = owner;
</span><ins>+    this-&gt;m_index = index;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ControlValue::dumpMeta(CommaPrinter&amp; comma, PrintStream&amp; out) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ControlValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ControlValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ControlValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ControlValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -109,8 +109,8 @@
</span><span class="cx"> 
</span><span class="cx">     // Use this for subclasses.
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    ControlValue(unsigned index, Opcode opcode, Type type, Origin origin, Arguments... arguments)
-        : Value(index, CheckedOpcode, opcode, type, origin, arguments...)
</del><ins>+    ControlValue(Opcode opcode, Type type, Origin origin, Arguments... arguments)
+        : Value(CheckedOpcode, opcode, type, origin, arguments...)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(accepts(opcode));
</span><span class="cx">     }
</span><span class="lines">@@ -122,22 +122,22 @@
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="cx">     // Use this for Oops.
</span><del>-    ControlValue(unsigned index, Opcode opcode, Origin origin)
-        : Value(index, CheckedOpcode, opcode, Void, origin)
</del><ins>+    ControlValue(Opcode opcode, Origin origin)
+        : Value(CheckedOpcode, opcode, Void, origin)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(opcode == Oops);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Use this for Return.
</span><del>-    ControlValue(unsigned index, Opcode opcode, Origin origin, Value* result)
-        : Value(index, CheckedOpcode, opcode, Void, origin, result)
</del><ins>+    ControlValue(Opcode opcode, Origin origin, Value* result)
+        : Value(CheckedOpcode, opcode, Void, origin, result)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(opcode == Return);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Use this for Jump.
</span><del>-    ControlValue(unsigned index, Opcode opcode, Origin origin, const FrequentedBlock&amp; target)
-        : Value(index, CheckedOpcode, opcode, Void, origin)
</del><ins>+    ControlValue(Opcode opcode, Origin origin, const FrequentedBlock&amp; target)
+        : Value(CheckedOpcode, opcode, Void, origin)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(opcode == Jump);
</span><span class="cx">         m_successors.append(target);
</span><span class="lines">@@ -145,9 +145,9 @@
</span><span class="cx"> 
</span><span class="cx">     // Use this for Branch.
</span><span class="cx">     ControlValue(
</span><del>-        unsigned index, Opcode opcode, Origin origin, Value* predicate,
</del><ins>+        Opcode opcode, Origin origin, Value* predicate,
</ins><span class="cx">         const FrequentedBlock&amp; yes, const FrequentedBlock&amp; no)
</span><del>-        : Value(index, CheckedOpcode, opcode, Void, origin, predicate)
</del><ins>+        : Value(CheckedOpcode, opcode, Void, origin, predicate)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(opcode == Branch);
</span><span class="cx">         m_successors.append(yes);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Effectscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Effects.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Effects.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Effects.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!terminal.terminal)
</span><span class="cx">         return false;
</span><del>-    return other.terminal || other.controlDependent || other.writesSSAState || other.writes;
</del><ins>+    return other.terminal || other.controlDependent || other.writesLocalState || other.writes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool interferesWithExitSideways(const Effects&amp; exitsSideways, const Effects&amp; other)
</span><span class="lines">@@ -54,11 +54,11 @@
</span><span class="cx">     return other.controlDependent || other.writes;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool interferesWithWritesSSAState(const Effects&amp; writesSSAState, const Effects&amp; other)
</del><ins>+bool interferesWithWritesLocalState(const Effects&amp; writesLocalState, const Effects&amp; other)
</ins><span class="cx"> {
</span><del>-    if (!writesSSAState.writesSSAState)
</del><ins>+    if (!writesLocalState.writesLocalState)
</ins><span class="cx">         return false;
</span><del>-    return other.writesSSAState || other.readsSSAState;
</del><ins>+    return other.writesLocalState || other.readsLocalState;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // anonymous namespace
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">         return true;
</span><span class="cx">     if (interferesWithExitSideways(*this, other) || interferesWithExitSideways(other, *this))
</span><span class="cx">         return true;
</span><del>-    if (interferesWithWritesSSAState(*this, other) || interferesWithWritesSSAState(other, *this))
</del><ins>+    if (interferesWithWritesLocalState(*this, other) || interferesWithWritesLocalState(other, *this))
</ins><span class="cx">         return true;
</span><span class="cx">     return writes.overlaps(other.writes)
</span><span class="cx">         || writes.overlaps(other.reads)
</span><span class="lines">@@ -85,10 +85,10 @@
</span><span class="cx">         out.print(comma, &quot;ExitsSideways&quot;);
</span><span class="cx">     if (controlDependent)
</span><span class="cx">         out.print(comma, &quot;ControlDependent&quot;);
</span><del>-    if (writesSSAState)
-        out.print(comma, &quot;WritesSSAState&quot;);
-    if (readsSSAState)
-        out.print(comma, &quot;ReadsSSAState&quot;);
</del><ins>+    if (writesLocalState)
+        out.print(comma, &quot;WritesLocalState&quot;);
+    if (readsLocalState)
+        out.print(comma, &quot;ReadsLocalState&quot;);
</ins><span class="cx">     if (writes)
</span><span class="cx">         out.print(comma, &quot;Writes:&quot;, writes);
</span><span class="cx">     if (reads)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Effectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Effects.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Effects.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Effects.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -48,14 +48,14 @@
</span><span class="cx">     // True if the instruction may change semantics if hoisted above some control flow.
</span><span class="cx">     bool controlDependent { false };
</span><span class="cx"> 
</span><del>-    // True if this writes to the SSA state. Operations that write SSA state don't write to anything
-    // in &quot;memory&quot; but they have a side-effect anyway. This is for modeling Upsilons. You can ignore
-    // this if you have your own way of modeling Upsilons or if you intend to just rebuild them
</del><ins>+    // True if this writes to the local state. Operations that write local state don't write to anything
+    // in &quot;memory&quot; but they have a side-effect anyway. This is for modeling Upsilons and Sets. You can ignore
+    // this if you have your own way of modeling Upsilons and Sets or if you intend to just rebuild them
</ins><span class="cx">     // anyway.
</span><del>-    bool writesSSAState { false };
</del><ins>+    bool writesLocalState { false };
</ins><span class="cx"> 
</span><del>-    // True if this reads from the SSA state. This is only used for Phi.
-    bool readsSSAState { false };
</del><ins>+    // True if this reads from the local state. This is only used for Phi and Get.
+    bool readsLocalState { false };
</ins><span class="cx"> 
</span><span class="cx">     HeapRange writes;
</span><span class="cx">     HeapRange reads;
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool mustExecute() const
</span><span class="cx">     {
</span><del>-        return terminal || exitsSideways || writesSSAState || writes;
</del><ins>+        return terminal || exitsSideways || writesLocalState || writes;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Returns true if reordering instructions with these respective effects would change program
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3EliminateCommonSubexpressionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -41,6 +41,8 @@
</span><span class="cx"> #include &quot;B3StackSlot.h&quot;
</span><span class="cx"> #include &quot;B3ValueKey.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><ins>+#include &quot;B3Variable.h&quot;
+#include &quot;B3VariableValue.h&quot;
</ins><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="lines">@@ -131,12 +133,10 @@
</span><span class="cx">             m_impureBlockData[m_block] = m_data;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (SlotBaseValue* stack : m_stacks)
-            m_insertionSet.insertValue(0, stack);
</del><span class="cx">         for (BasicBlock* block : m_proc) {
</span><span class="cx">             for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
</span><del>-                auto iter = m_stores.find(block-&gt;at(valueIndex));
-                if (iter == m_stores.end())
</del><ins>+                auto iter = m_sets.find(block-&gt;at(valueIndex));
+                if (iter == m_sets.end())
</ins><span class="cx">                     continue;
</span><span class="cx"> 
</span><span class="cx">                 for (Value* value : iter-&gt;value)
</span><span class="lines">@@ -369,21 +369,19 @@
</span><span class="cx">         // FIXME: It would be way better if this phase just did SSA calculation directly.
</span><span class="cx">         // Right now we're relying on the fact that CSE's position in the phase order is
</span><span class="cx">         // almost right before SSA fixup.
</span><del>-            
-        SlotBaseValue* stack = m_proc.add&lt;SlotBaseValue&gt;(
-            m_value-&gt;origin(), m_proc.addAnonymousStackSlot(m_value-&gt;type()));
-        m_stacks.append(stack);
</del><span class="cx"> 
</span><del>-        MemoryValue* load = m_insertionSet.insert&lt;MemoryValue&gt;(
-            m_index, Load, m_value-&gt;type(), m_value-&gt;origin(), stack);
</del><ins>+        Variable* variable = m_proc.addVariable(m_value-&gt;type());
+
+        VariableValue* get = m_insertionSet.insert&lt;VariableValue&gt;(
+            m_index, Get, m_value-&gt;origin(), variable);
</ins><span class="cx">         if (verbose)
</span><del>-            dataLog(&quot;    Inserting load of value: &quot;, *load, &quot;\n&quot;);
-        m_value-&gt;replaceWithIdentity(load);
</del><ins>+            dataLog(&quot;    Inserting get of value: &quot;, *get, &quot;\n&quot;);
+        m_value-&gt;replaceWithIdentity(get);
</ins><span class="cx">             
</span><span class="cx">         for (MemoryValue* match : matches) {
</span><del>-            Vector&lt;Value*&gt;&amp; stores = m_stores.add(match, Vector&lt;Value*&gt;()).iterator-&gt;value;
</del><ins>+            Vector&lt;Value*&gt;&amp; sets = m_sets.add(match, Vector&lt;Value*&gt;()).iterator-&gt;value;
</ins><span class="cx"> 
</span><del>-            Value* value = replace(match, stores);
</del><ins>+            Value* value = replace(match, sets);
</ins><span class="cx">             if (!value) {
</span><span class="cx">                 if (match-&gt;isStore())
</span><span class="cx">                     value = match-&gt;child(0);
</span><span class="lines">@@ -391,8 +389,8 @@
</span><span class="cx">                     value = match;
</span><span class="cx">             }
</span><span class="cx">                 
</span><del>-            Value* store = m_proc.add&lt;MemoryValue&gt;(Store, m_value-&gt;origin(), value, stack);
-            stores.append(store);
</del><ins>+            Value* set = m_proc.add&lt;VariableValue&gt;(Set, m_value-&gt;origin(), variable, value);
+            sets.append(set);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="lines">@@ -499,8 +497,7 @@
</span><span class="cx">     unsigned m_index;
</span><span class="cx">     Value* m_value;
</span><span class="cx"> 
</span><del>-    Vector&lt;SlotBaseValue*&gt; m_stacks;
-    HashMap&lt;Value*, Vector&lt;Value*&gt;&gt; m_stores;
</del><ins>+    HashMap&lt;Value*, Vector&lt;Value*&gt;&gt; m_sets;
</ins><span class="cx"> 
</span><span class="cx">     InsertionSet m_insertionSet;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FixSSAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -34,14 +34,13 @@
</span><span class="cx"> #include &quot;B3Dominators.h&quot;
</span><span class="cx"> #include &quot;B3IndexSet.h&quot;
</span><span class="cx"> #include &quot;B3InsertionSetInlines.h&quot;
</span><del>-#include &quot;B3MemoryValue.h&quot;
</del><span class="cx"> #include &quot;B3PhaseScope.h&quot;
</span><span class="cx"> #include &quot;B3ProcedureInlines.h&quot;
</span><span class="cx"> #include &quot;B3SSACalculator.h&quot;
</span><del>-#include &quot;B3SlotBaseValue.h&quot;
-#include &quot;B3StackSlot.h&quot;
</del><span class="cx"> #include &quot;B3UpsilonValue.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><ins>+#include &quot;B3Variable.h&quot;
+#include &quot;B3VariableValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="lines">@@ -52,23 +51,16 @@
</span><span class="cx"> 
</span><span class="cx"> void demoteValues(Procedure&amp; proc, const IndexSet&lt;Value&gt;&amp; values)
</span><span class="cx"> {
</span><del>-    HashMap&lt;Value*, SlotBaseValue*&gt; map;
-    HashMap&lt;Value*, SlotBaseValue*&gt; phiMap;
</del><ins>+    HashMap&lt;Value*, Variable*&gt; map;
+    HashMap&lt;Value*, Variable*&gt; phiMap;
</ins><span class="cx"> 
</span><span class="cx">     // Create stack slots.
</span><del>-    InsertionSet insertionSet(proc);
</del><span class="cx">     for (Value* value : values.values(proc.values())) {
</span><del>-        SlotBaseValue* stack = insertionSet.insert&lt;SlotBaseValue&gt;(
-            0, value-&gt;origin(), proc.addAnonymousStackSlot(value-&gt;type()));
-        map.add(value, stack);
</del><ins>+        map.add(value, proc.addVariable(value-&gt;type()));
</ins><span class="cx"> 
</span><del>-        if (value-&gt;opcode() == Phi) {
-            SlotBaseValue* phiStack = insertionSet.insert&lt;SlotBaseValue&gt;(
-                0, value-&gt;origin(), proc.addAnonymousStackSlot(value-&gt;type()));
-            phiMap.add(value, phiStack);
-        }
</del><ins>+        if (value-&gt;opcode() == Phi)
+            phiMap.add(value, proc.addVariable(value-&gt;type()));
</ins><span class="cx">     }
</span><del>-    insertionSet.execute(proc[0]);
</del><span class="cx"> 
</span><span class="cx">     if (verbose) {
</span><span class="cx">         dataLog(&quot;Demoting values as follows:\n&quot;);
</span><span class="lines">@@ -85,36 +77,37 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Change accesses to the values to accesses to the stack slots.
</span><ins>+    InsertionSet insertionSet(proc);
</ins><span class="cx">     for (BasicBlock* block : proc) {
</span><span class="cx">         for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
</span><span class="cx">             Value* value = block-&gt;at(valueIndex);
</span><span class="cx"> 
</span><span class="cx">             if (value-&gt;opcode() == Phi) {
</span><del>-                if (SlotBaseValue* slotBase = phiMap.get(value)) {
</del><ins>+                if (Variable* variable = phiMap.get(value)) {
</ins><span class="cx">                     value-&gt;replaceWithIdentity(
</span><del>-                        insertionSet.insert&lt;MemoryValue&gt;(
-                            valueIndex, Load, value-&gt;type(), value-&gt;origin(), slotBase));
</del><ins>+                        insertionSet.insert&lt;VariableValue&gt;(
+                            valueIndex, Get, value-&gt;origin(), variable));
</ins><span class="cx">                 }
</span><span class="cx">             } else {
</span><span class="cx">                 for (Value*&amp; child : value-&gt;children()) {
</span><del>-                    if (SlotBaseValue* slotBase = map.get(child)) {
-                        child = insertionSet.insert&lt;MemoryValue&gt;(
-                            valueIndex, Load, child-&gt;type(), value-&gt;origin(), slotBase);
</del><ins>+                    if (Variable* variable = map.get(child)) {
+                        child = insertionSet.insert&lt;VariableValue&gt;(
+                            valueIndex, Get, value-&gt;origin(), variable);
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 if (UpsilonValue* upsilon = value-&gt;as&lt;UpsilonValue&gt;()) {
</span><del>-                    if (SlotBaseValue* slotBase = phiMap.get(upsilon-&gt;phi())) {
-                        insertionSet.insert&lt;MemoryValue&gt;(
-                            valueIndex, Store, upsilon-&gt;origin(), upsilon-&gt;child(0), slotBase);
</del><ins>+                    if (Variable* variable = phiMap.get(upsilon-&gt;phi())) {
+                        insertionSet.insert&lt;VariableValue&gt;(
+                            valueIndex, Set, upsilon-&gt;origin(), variable, upsilon-&gt;child(0));
</ins><span class="cx">                         value-&gt;replaceWithNop();
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            if (SlotBaseValue* slotBase = map.get(value)) {
-                insertionSet.insert&lt;MemoryValue&gt;(
-                    valueIndex + 1, Store, value-&gt;origin(), value, slotBase);
</del><ins>+            if (Variable* variable = map.get(value)) {
+                insertionSet.insert&lt;VariableValue&gt;(
+                    valueIndex + 1, Set, value-&gt;origin(), variable, value);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         insertionSet.execute(block);
</span><span class="lines">@@ -124,80 +117,22 @@
</span><span class="cx"> bool fixSSA(Procedure&amp; proc)
</span><span class="cx"> {
</span><span class="cx">     PhaseScope phaseScope(proc, &quot;fixSSA&quot;);
</span><del>-    
-    // Collect the stack &quot;variables&quot;. If there aren't any, then we don't have anything to do.
-    // That's a fairly common case.
-    HashMap&lt;StackSlot*, Type&gt; stackVariable;
-    for (Value* value : proc.values()) {
-        if (SlotBaseValue* slotBase = value-&gt;as&lt;SlotBaseValue&gt;()) {
-            StackSlot* stack = slotBase-&gt;slot();
-            if (stack-&gt;kind() == StackSlotKind::Anonymous)
-                stackVariable.add(stack, Void);
-        }
-    }
</del><span class="cx"> 
</span><del>-    if (stackVariable.isEmpty())
-        return false;
-
-    // Make sure that we know how to optimize all of these. We only know how to handle Load and
-    // Store on anonymous variables.
</del><ins>+    // Just for sanity, remove any unused variables first. It's unlikely that this code has any
+    // bugs having to do with dead variables, but it would be silly to have to fix such a bug if
+    // it did arise.
+    IndexSet&lt;Variable&gt; liveVariables;
</ins><span class="cx">     for (Value* value : proc.values()) {
</span><del>-        auto reject = [&amp;] (Value* value) {
-            if (SlotBaseValue* slotBase = value-&gt;as&lt;SlotBaseValue&gt;())
-                stackVariable.remove(slotBase-&gt;slot());
-        };
-        
-        auto handleAccess = [&amp;] (Value* access, Type type) {
-            SlotBaseValue* slotBase = access-&gt;lastChild()-&gt;as&lt;SlotBaseValue&gt;();
-            if (!slotBase)
-                return;
-
-            StackSlot* stack = slotBase-&gt;slot();
-            
-            if (value-&gt;as&lt;MemoryValue&gt;()-&gt;offset()) {
-                stackVariable.remove(stack);
-                return;
-            }
-
-            auto result = stackVariable.find(stack);
-            if (result == stackVariable.end())
-                return;
-            if (result-&gt;value == Void) {
-                result-&gt;value = type;
-                return;
-            }
-            if (result-&gt;value == type)
-                return;
-            stackVariable.remove(result);
-        };
-        
-        switch (value-&gt;opcode()) {
-        case Load:
-            // We're OK with loads from stack variables at an offset of zero.
-            handleAccess(value, value-&gt;type());
-            break;
-        case Store:
-            // We're OK with stores to stack variables, but not storing stack variables.
-            reject(value-&gt;child(0));
-            handleAccess(value, value-&gt;child(0)-&gt;type());
-            break;
-        default:
-            for (Value* child : value-&gt;children())
-                reject(child);
-            break;
-        }
</del><ins>+        if (VariableValue* variableValue = value-&gt;as&lt;VariableValue&gt;())
+            liveVariables.add(variableValue-&gt;variable());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Vector&lt;StackSlot*&gt; deadSlots;
-    for (auto&amp; entry : stackVariable) {
-        if (entry.value == Void)
-            deadSlots.append(entry.key);
</del><ins>+    for (Variable* variable : proc.variables()) {
+        if (!liveVariables.contains(variable))
+            proc.deleteVariable(variable);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (StackSlot* deadSlot : deadSlots)
-        stackVariable.remove(deadSlot);
-
-    if (stackVariable.isEmpty())
</del><ins>+    if (proc.variables().isEmpty())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // We know that we have variables to optimize, so do that now.
</span><span class="lines">@@ -205,43 +140,38 @@
</span><span class="cx"> 
</span><span class="cx">     SSACalculator ssa(proc);
</span><span class="cx"> 
</span><del>-    // Create a SSACalculator::Variable for every stack variable.
-    Vector&lt;StackSlot*&gt; variableToStack;
-    HashMap&lt;StackSlot*, SSACalculator::Variable*&gt; stackToVariable;
</del><ins>+    // Create a SSACalculator::Variable (&quot;calcVar&quot;) for every variable.
+    Vector&lt;Variable*&gt; calcVarToVariable;
+    IndexMap&lt;Variable, SSACalculator::Variable*&gt; variableToCalcVar(proc.variables().size());
</ins><span class="cx"> 
</span><del>-    for (auto&amp; entry : stackVariable) {
-        StackSlot* stack = entry.key;
-        SSACalculator::Variable* variable = ssa.newVariable();
-        RELEASE_ASSERT(variable-&gt;index() == variableToStack.size());
-        variableToStack.append(stack);
-        stackToVariable.add(stack, variable);
</del><ins>+    for (Variable* variable : proc.variables()) {
+        SSACalculator::Variable* calcVar = ssa.newVariable();
+        RELEASE_ASSERT(calcVar-&gt;index() == calcVarToVariable.size());
+        calcVarToVariable.append(variable);
+        variableToCalcVar[variable] = calcVar;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Create Defs for all of the stores to the stack variable.
</span><span class="cx">     for (BasicBlock* block : proc) {
</span><span class="cx">         for (Value* value : *block) {
</span><del>-            if (value-&gt;opcode() != Store)
</del><ins>+            if (value-&gt;opcode() != Set)
</ins><span class="cx">                 continue;
</span><span class="cx"> 
</span><del>-            SlotBaseValue* slotBase = value-&gt;child(1)-&gt;as&lt;SlotBaseValue&gt;();
-            if (!slotBase)
-                continue;
</del><ins>+            Variable* variable = value-&gt;as&lt;VariableValue&gt;()-&gt;variable();
</ins><span class="cx"> 
</span><del>-            StackSlot* stack = slotBase-&gt;slot();
-
-            if (SSACalculator::Variable* variable = stackToVariable.get(stack))
-                ssa.newDef(variable, block, value-&gt;child(0));
</del><ins>+            if (SSACalculator::Variable* calcVar = variableToCalcVar[variable])
+                ssa.newDef(calcVar, block, value-&gt;child(0));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Decide where Phis are to be inserted. This creates them but does not insert them.
</span><span class="cx">     ssa.computePhis(
</span><del>-        [&amp;] (SSACalculator::Variable* variable, BasicBlock* block) -&gt; Value* {
-            StackSlot* stack = variableToStack[variable-&gt;index()];
-            Value* phi = proc.add&lt;Value&gt;(Phi, stackVariable.get(stack), block-&gt;at(0)-&gt;origin());
</del><ins>+        [&amp;] (SSACalculator::Variable* calcVar, BasicBlock* block) -&gt; Value* {
+            Variable* variable = calcVarToVariable[calcVar-&gt;index()];
+            Value* phi = proc.add&lt;Value&gt;(Phi, variable-&gt;type(), block-&gt;at(0)-&gt;origin());
</ins><span class="cx">             if (verbose) {
</span><span class="cx">                 dataLog(
</span><del>-                    &quot;Adding Phi for &quot;, pointerDump(stack), &quot; at &quot;, *block, &quot;: &quot;,
</del><ins>+                    &quot;Adding Phi for &quot;, pointerDump(variable), &quot; at &quot;, *block, &quot;: &quot;,
</ins><span class="cx">                     deepDump(proc, phi), &quot;\n&quot;);
</span><span class="cx">             }
</span><span class="cx">             return phi;
</span><span class="lines">@@ -249,24 +179,24 @@
</span><span class="cx"> 
</span><span class="cx">     // Now perform the conversion.
</span><span class="cx">     InsertionSet insertionSet(proc);
</span><del>-    HashMap&lt;StackSlot*, Value*&gt; mapping;
</del><ins>+    IndexMap&lt;Variable, Value*&gt; mapping(proc.variables().size());
</ins><span class="cx">     for (BasicBlock* block : proc.blocksInPreOrder()) {
</span><span class="cx">         mapping.clear();
</span><span class="cx"> 
</span><del>-        for (auto&amp; entry : stackToVariable) {
-            StackSlot* stack = entry.key;
-            SSACalculator::Variable* variable = entry.value;
</del><ins>+        for (unsigned index = calcVarToVariable.size(); index--;) {
+            Variable* variable = calcVarToVariable[index];
+            SSACalculator::Variable* calcVar = ssa.variable(index);
</ins><span class="cx"> 
</span><del>-            SSACalculator::Def* def = ssa.reachingDefAtHead(block, variable);
</del><ins>+            SSACalculator::Def* def = ssa.reachingDefAtHead(block, calcVar);
</ins><span class="cx">             if (def)
</span><del>-                mapping.set(stack, def-&gt;value());
</del><ins>+                mapping[variable] = def-&gt;value();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         for (SSACalculator::Def* phiDef : ssa.phisForBlock(block)) {
</span><del>-            StackSlot* stack = variableToStack[phiDef-&gt;variable()-&gt;index()];
</del><ins>+            Variable* variable = calcVarToVariable[phiDef-&gt;variable()-&gt;index()];
</ins><span class="cx"> 
</span><span class="cx">             insertionSet.insertValue(0, phiDef-&gt;value());
</span><del>-            mapping.set(stack, phiDef-&gt;value());
</del><ins>+            mapping[variable] = phiDef-&gt;value();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
</span><span class="lines">@@ -274,23 +204,25 @@
</span><span class="cx">             value-&gt;performSubstitution();
</span><span class="cx"> 
</span><span class="cx">             switch (value-&gt;opcode()) {
</span><del>-            case Load: {
-                if (SlotBaseValue* slotBase = value-&gt;child(0)-&gt;as&lt;SlotBaseValue&gt;()) {
-                    StackSlot* stack = slotBase-&gt;slot();
-                    if (Value* replacement = mapping.get(stack))
-                        value-&gt;replaceWithIdentity(replacement);
</del><ins>+            case Get: {
+                VariableValue* variableValue = value-&gt;as&lt;VariableValue&gt;();
+                Variable* variable = variableValue-&gt;variable();
+
+                if (Value* replacement = mapping[variable])
+                    value-&gt;replaceWithIdentity(replacement);
+                else {
+                    value-&gt;replaceWithIdentity(
+                        insertionSet.insertBottom(valueIndex, value));
</ins><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><del>-            case Store: {
-                if (SlotBaseValue* slotBase = value-&gt;child(1)-&gt;as&lt;SlotBaseValue&gt;()) {
-                    StackSlot* stack = slotBase-&gt;slot();
-                    if (stackToVariable.contains(stack)) {
-                        mapping.set(stack, value-&gt;child(0));
-                        value-&gt;replaceWithNop();
-                    }
-                }
</del><ins>+            case Set: {
+                VariableValue* variableValue = value-&gt;as&lt;VariableValue&gt;();
+                Variable* variable = variableValue-&gt;variable();
+
+                mapping[variable] = value-&gt;child(0);
+                value-&gt;replaceWithNop();
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -304,14 +236,14 @@
</span><span class="cx">         for (BasicBlock* successorBlock : block-&gt;successorBlocks()) {
</span><span class="cx">             for (SSACalculator::Def* phiDef : ssa.phisForBlock(successorBlock)) {
</span><span class="cx">                 Value* phi = phiDef-&gt;value();
</span><del>-                SSACalculator::Variable* variable = phiDef-&gt;variable();
-                StackSlot* stack = variableToStack[variable-&gt;index()];
</del><ins>+                SSACalculator::Variable* calcVar = phiDef-&gt;variable();
+                Variable* variable = calcVarToVariable[calcVar-&gt;index()];
</ins><span class="cx"> 
</span><del>-                Value* mappedValue = mapping.get(stack);
</del><ins>+                Value* mappedValue = mapping[variable];
</ins><span class="cx">                 if (verbose) {
</span><span class="cx">                     dataLog(
</span><del>-                        &quot;Mapped value for &quot;, *stack, &quot; with successor Phi &quot;, *phi, &quot; at end of &quot;,
-                        *block, &quot;: &quot;, pointerDump(mappedValue), &quot;\n&quot;);
</del><ins>+                        &quot;Mapped value for &quot;, *variable, &quot; with successor Phi &quot;, *phi,
+                        &quot; at end of &quot;, *block, &quot;: &quot;, pointerDump(mappedValue), &quot;\n&quot;);
</ins><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 if (!mappedValue)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FixSSAh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3FixSSA.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FixSSA.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3FixSSA.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -36,8 +36,8 @@
</span><span class="cx"> 
</span><span class="cx"> class Procedure;
</span><span class="cx"> 
</span><del>-// Turns all mentions of the given values into accesses to anonymous stack slots. This is meant
-// to be used from phases that don't like SSA for whatever reason.
</del><ins>+// Turns all mentions of the given values into accesses to variables. This is meant to be used
+// from phases that don't like SSA for whatever reason.
</ins><span class="cx"> void demoteValues(Procedure&amp;, const IndexSet&lt;Value&gt;&amp;);
</span><span class="cx"> 
</span><span class="cx"> // This fixes SSA for you. Use this after you have done demoteValues() and you have performed
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3IndexMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3IndexMap.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3IndexMap.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3IndexMap.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -49,6 +49,11 @@
</span><span class="cx">         m_vector.fill(Value(), size);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void clear()
+    {
+        m_vector.fill(Value(), m_vector.size());
+    }
+
</ins><span class="cx">     size_t size() const { return m_vector.size(); }
</span><span class="cx"> 
</span><span class="cx">     Value&amp; operator[](size_t index)
</span><span class="lines">@@ -71,11 +76,6 @@
</span><span class="cx">         return m_vector[key-&gt;index()];
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void clear()
-    {
-        m_vector.clear();
-    }
-    
</del><span class="cx"> private:
</span><span class="cx">     Vector&lt;Value&gt; m_vector;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3IndexSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3IndexSet.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3IndexSet.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3IndexSet.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -69,6 +69,16 @@
</span><span class="cx">         return m_set.get(value-&gt;index());
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    size_t size() const
+    {
+        return m_set.bitCount();
+    }
+
+    bool isEmpty() const
+    {
+        return !size();
+    }
+
</ins><span class="cx">     template&lt;typename CollectionType&gt;
</span><span class="cx">     class Iterable {
</span><span class="cx">     public:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -53,6 +53,8 @@
</span><span class="cx"> #include &quot;B3UpsilonValue.h&quot;
</span><span class="cx"> #include &quot;B3UseCounts.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><ins>+#include &quot;B3Variable.h&quot;
+#include &quot;B3VariableValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/ListDump.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if COMPILER(GCC) &amp;&amp; ASSERT_DISABLED
</span><span class="lines">@@ -102,6 +104,8 @@
</span><span class="cx"> 
</span><span class="cx">         for (B3::StackSlot* stack : m_procedure.stackSlots())
</span><span class="cx">             m_stackToStack.add(stack, m_code.addStackSlot(stack));
</span><ins>+        for (Variable* variable : m_procedure.variables())
+            m_variableToTmp.add(variable, m_code.newTmp(Arg::typeForB3Type(variable-&gt;type())));
</ins><span class="cx"> 
</span><span class="cx">         // Figure out which blocks are not rare.
</span><span class="cx">         m_fastWorklist.push(m_procedure[0]);
</span><span class="lines">@@ -2225,6 +2229,21 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case Set: {
+            Value* value = m_value-&gt;child(0);
+            append(
+                relaxedMoveForType(value-&gt;type()), immOrTmp(value),
+                m_variableToTmp.get(m_value-&gt;as&lt;VariableValue&gt;()-&gt;variable()));
+            return;
+        }
+
+        case Get: {
+            append(
+                relaxedMoveForType(m_value-&gt;type()),
+                m_variableToTmp.get(m_value-&gt;as&lt;VariableValue&gt;()-&gt;variable()), tmp(m_value));
+            return;
+        }
+
</ins><span class="cx">         case Branch: {
</span><span class="cx">             m_insts.last().append(createBranch(m_value-&gt;child(0)));
</span><span class="cx">             return;
</span><span class="lines">@@ -2316,6 +2335,7 @@
</span><span class="cx">     IndexMap&lt;Value, Tmp&gt; m_phiToTmp; // Each Phi gets its own Tmp.
</span><span class="cx">     IndexMap&lt;B3::BasicBlock, Air::BasicBlock*&gt; m_blockToBlock;
</span><span class="cx">     HashMap&lt;B3::StackSlot*, Air::StackSlot*&gt; m_stackToStack;
</span><ins>+    HashMap&lt;Variable*, Tmp&gt; m_variableToTmp;
</ins><span class="cx"> 
</span><span class="cx">     UseCounts m_useCounts;
</span><span class="cx">     PhiChildren m_phiChildren;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3MemoryValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3MemoryValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3MemoryValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3MemoryValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -75,10 +75,8 @@
</span><span class="cx"> 
</span><span class="cx">     // Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that
</span><span class="cx">     // describes the returned type).
</span><del>-    MemoryValue(
-        unsigned index, Opcode opcode, Type type, Origin origin, Value* pointer,
-        int32_t offset = 0)
-        : Value(index, CheckedOpcode, opcode, type, origin, pointer)
</del><ins>+    MemoryValue(Opcode opcode, Type type, Origin origin, Value* pointer, int32_t offset = 0)
+        : Value(CheckedOpcode, opcode, type, origin, pointer)
</ins><span class="cx">         , m_offset(offset)
</span><span class="cx">         , m_range(HeapRange::top())
</span><span class="cx">     {
</span><span class="lines">@@ -104,16 +102,14 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Use this form for loads where the return type is implied.
</span><del>-    MemoryValue(unsigned index, Opcode opcode, Origin origin, Value* pointer, int32_t offset = 0)
-        : MemoryValue(index, opcode, Int32, origin, pointer, offset)
</del><ins>+    MemoryValue(Opcode opcode, Origin origin, Value* pointer, int32_t offset = 0)
+        : MemoryValue(opcode, Int32, origin, pointer, offset)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Use this form for stores.
</span><del>-    MemoryValue(
-        unsigned index, Opcode opcode, Origin origin, Value* value, Value* pointer,
-        int32_t offset = 0)
-        : Value(index, CheckedOpcode, opcode, Void, origin, value, pointer)
</del><ins>+    MemoryValue(Opcode opcode, Origin origin, Value* value, Value* pointer, int32_t offset = 0)
+        : Value(CheckedOpcode, opcode, Void, origin, value, pointer)
</ins><span class="cx">         , m_offset(offset)
</span><span class="cx">         , m_range(HeapRange::top())
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -95,6 +95,12 @@
</span><span class="cx">     case ConstFloat:
</span><span class="cx">         out.print(&quot;ConstFloat&quot;);
</span><span class="cx">         return;
</span><ins>+    case Get:
+        out.print(&quot;Get&quot;);
+        return;
+    case Set:
+        out.print(&quot;Set&quot;);
+        return;
</ins><span class="cx">     case SlotBase:
</span><span class="cx">         out.print(&quot;SlotBase&quot;);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -48,9 +48,14 @@
</span><span class="cx">     ConstDouble,
</span><span class="cx">     ConstFloat,
</span><span class="cx"> 
</span><del>-    // The magical stack slot. This is viewed as executing at the top of the program regardless of
-    // where in control flow you put it. Each instance of a StackSlot Value gets a disjoint range of
-    // stack memory. Use the StackSlotValue class.
</del><ins>+    // B3 supports non-SSA variables. These are accessed using Get and Set opcodes. Use the
+    // VariableValue class. It's a good idea to run fixSSA() to turn these into SSA. The
+    // optimizer will do that eventually, but if your input tends to use these opcodes, you
+    // should run fixSSA() directly before launching the optimizer.
+    Set,
+    Get,
+
+    // Gets the base address of a StackSlot.
</ins><span class="cx">     SlotBase,
</span><span class="cx"> 
</span><span class="cx">     // The magical argument register. This is viewed as executing at the top of the program
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3PatchpointValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -49,8 +49,8 @@
</span><span class="cx">     return new PatchpointValue(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PatchpointValue::PatchpointValue(unsigned index, Type type, Origin origin)
-    : Base(index, CheckedOpcode, Patchpoint, type, origin)
</del><ins>+PatchpointValue::PatchpointValue(Type type, Origin origin)
+    : Base(CheckedOpcode, Patchpoint, type, origin)
</ins><span class="cx">     , effects(Effects::forCall())
</span><span class="cx">     , resultConstraint(type == Void ? ValueRep::WarmAny : ValueRep::SomeRegister)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3PatchpointValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE PatchpointValue(unsigned index, Type, Origin);
</del><ins>+    JS_EXPORT_PRIVATE PatchpointValue(Type, Origin);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;B3OpaqueByproducts.h&quot;
</span><span class="cx"> #include &quot;B3StackSlot.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><ins>+#include &quot;B3Variable.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><span class="lines">@@ -46,7 +47,6 @@
</span><span class="cx">     , m_lastPhaseName(&quot;initial&quot;)
</span><span class="cx">     , m_byproducts(std::make_unique&lt;OpaqueByproducts&gt;())
</span><span class="cx">     , m_code(new Air::Code(*this))
</span><del>-    , m_valuesCollection(*this)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -70,51 +70,22 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Procedure::setBlockOrderImpl(Vector&lt;BasicBlock*&gt;&amp; blocks)
</del><ins>+StackSlot* Procedure::addStackSlot(unsigned byteSize)
</ins><span class="cx"> {
</span><del>-    IndexSet&lt;BasicBlock&gt; blocksSet;
-    blocksSet.addAll(blocks);
-
-    for (BasicBlock* block : *this) {
-        if (!blocksSet.contains(block))
-            blocks.append(block);
-    }
-
-    // Place blocks into this's block list by first leaking all of the blocks and then readopting
-    // them.
-    for (auto&amp; entry : m_blocks)
-        entry.release();
-
-    m_blocks.resize(blocks.size());
-    for (unsigned i = 0; i &lt; blocks.size(); ++i) {
-        BasicBlock* block = blocks[i];
-        block-&gt;m_index = i;
-        m_blocks[i] = std::unique_ptr&lt;BasicBlock&gt;(block);
-    }
</del><ins>+    return m_stackSlots.addNew(byteSize);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-StackSlot* Procedure::addStackSlot(unsigned byteSize, StackSlotKind kind)
</del><ins>+Variable* Procedure::addVariable(Type type)
</ins><span class="cx"> {
</span><del>-    size_t index = addStackSlotIndex();
-    std::unique_ptr&lt;StackSlot&gt; slot(new StackSlot(index, byteSize, kind));
-    StackSlot* result = slot.get();
-    m_stackSlots[index] = WTFMove(slot);
-    return result;
</del><ins>+    return m_variables.addNew(type); 
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-StackSlot* Procedure::addAnonymousStackSlot(Type type)
-{
-    return addStackSlot(sizeofType(type), StackSlotKind::Anonymous);
-}
-
</del><span class="cx"> Value* Procedure::clone(Value* value)
</span><span class="cx"> {
</span><span class="cx">     std::unique_ptr&lt;Value&gt; clone(value-&gt;cloneImpl());
</span><del>-    Value* result = clone.get();
-    clone-&gt;m_index = addValueIndex();
</del><ins>+    clone-&gt;m_index = UINT_MAX;
</ins><span class="cx">     clone-&gt;owner = nullptr;
</span><del>-    m_values[clone-&gt;m_index] = WTFMove(clone);
-    return result;
</del><ins>+    return m_values.add(WTFMove(clone));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
</span><span class="lines">@@ -208,6 +179,11 @@
</span><span class="cx">         }
</span><span class="cx">         dataLog(&quot;    &quot;, deepDump(*this, value), &quot;\n&quot;);
</span><span class="cx">     }
</span><ins>+    if (variables().size()) {
+        out.print(&quot;Variables:\n&quot;);
+        for (Variable* variable : variables())
+            out.print(&quot;    &quot;, deepDump(variable), &quot;\n&quot;);
+    }
</ins><span class="cx">     if (stackSlots().size()) {
</span><span class="cx">         out.print(&quot;Stack slots:\n&quot;);
</span><span class="cx">         for (StackSlot* slot : stackSlots())
</span><span class="lines">@@ -229,17 +205,17 @@
</span><span class="cx"> 
</span><span class="cx"> void Procedure::deleteStackSlot(StackSlot* stackSlot)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_stackSlots[stackSlot-&gt;index()].get() == stackSlot);
-    RELEASE_ASSERT(!stackSlot-&gt;isLocked());
-    m_stackSlotIndexFreeList.append(stackSlot-&gt;index());
-    m_stackSlots[stackSlot-&gt;index()] = nullptr;
</del><ins>+    m_stackSlots.remove(stackSlot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Procedure::deleteVariable(Variable* variable)
+{
+    m_variables.remove(variable);
+}
+
</ins><span class="cx"> void Procedure::deleteValue(Value* value)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_values[value-&gt;index()].get() == value);
-    m_valueIndexFreeList.append(value-&gt;index());
-    m_values[value-&gt;index()] = nullptr;
</del><ins>+    m_values.remove(value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Procedure::deleteOrphans()
</span><span class="lines">@@ -311,26 +287,32 @@
</span><span class="cx">     return code().calleeSaveRegisters();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-size_t Procedure::addStackSlotIndex()
</del><ins>+Value* Procedure::addValueImpl(Value* value)
</ins><span class="cx"> {
</span><del>-    if (m_stackSlotIndexFreeList.isEmpty()) {
-        size_t index = m_stackSlots.size();
-        m_stackSlots.append(nullptr);
-        return index;
-    }
-    
-    return m_stackSlotIndexFreeList.takeLast();
</del><ins>+    return m_values.add(std::unique_ptr&lt;Value&gt;(value));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-size_t Procedure::addValueIndex()
</del><ins>+void Procedure::setBlockOrderImpl(Vector&lt;BasicBlock*&gt;&amp; blocks)
</ins><span class="cx"> {
</span><del>-    if (m_valueIndexFreeList.isEmpty()) {
-        size_t index = m_values.size();
-        m_values.append(nullptr);
-        return index;
</del><ins>+    IndexSet&lt;BasicBlock&gt; blocksSet;
+    blocksSet.addAll(blocks);
+
+    for (BasicBlock* block : *this) {
+        if (!blocksSet.contains(block))
+            blocks.append(block);
</ins><span class="cx">     }
</span><del>-    
-    return m_valueIndexFreeList.takeLast();
</del><ins>+
+    // Place blocks into this's block list by first leaking all of the blocks and then readopting
+    // them.
+    for (auto&amp; entry : m_blocks)
+        entry.release();
+
+    m_blocks.resize(blocks.size());
+    for (unsigned i = 0; i &lt; blocks.size(); ++i) {
+        BasicBlock* block = blocks[i];
+        block-&gt;m_index = i;
+        m_blocks[i] = std::unique_ptr&lt;BasicBlock&gt;(block);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> #include &quot;B3OpaqueByproducts.h&quot;
</span><span class="cx"> #include &quot;B3Origin.h&quot;
</span><span class="cx"> #include &quot;B3PCToOriginMap.h&quot;
</span><del>-#include &quot;B3StackSlotKind.h&quot;
</del><ins>+#include &quot;B3SparseCollection.h&quot;
</ins><span class="cx"> #include &quot;B3Type.h&quot;
</span><span class="cx"> #include &quot;B3ValueKey.h&quot;
</span><span class="cx"> #include &quot;PureNaN.h&quot;
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> class Dominators;
</span><span class="cx"> class StackSlot;
</span><span class="cx"> class Value;
</span><ins>+class Variable;
</ins><span class="cx"> 
</span><span class="cx"> namespace Air { class Code; }
</span><span class="cx"> 
</span><span class="lines">@@ -94,8 +95,8 @@
</span><span class="cx">         setBlockOrderImpl(blocks);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE StackSlot* addStackSlot(unsigned byteSize, StackSlotKind);
-    JS_EXPORT_PRIVATE StackSlot* addAnonymousStackSlot(Type);
</del><ins>+    JS_EXPORT_PRIVATE StackSlot* addStackSlot(unsigned byteSize);
+    JS_EXPORT_PRIVATE Variable* addVariable(Type);
</ins><span class="cx">     
</span><span class="cx">     template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx">     ValueType* add(Arguments...);
</span><span class="lines">@@ -178,143 +179,22 @@
</span><span class="cx">     Vector&lt;BasicBlock*&gt; blocksInPreOrder();
</span><span class="cx">     Vector&lt;BasicBlock*&gt; blocksInPostOrder();
</span><span class="cx"> 
</span><del>-    class StackSlotsCollection {
-    public:
-        StackSlotsCollection(const Procedure&amp; proc)
-            : m_proc(proc)
-        {
-        }
</del><ins>+    SparseCollection&lt;StackSlot&gt;&amp; stackSlots() { return m_stackSlots; }
+    const SparseCollection&lt;StackSlot&gt;&amp; stackSlots() const { return m_stackSlots; }
</ins><span class="cx"> 
</span><del>-        unsigned size() const { return m_proc.m_stackSlots.size(); }
-        StackSlot* at(unsigned index) const { return m_proc.m_stackSlots[index].get(); }
-        StackSlot* operator[](unsigned index) const { return at(index); }
-
-        class iterator {
-        public:
-            iterator()
-                : m_collection(nullptr)
-                , m_index(0)
-            {
-            }
-
-            iterator(const StackSlotsCollection&amp; collection, unsigned index)
-                : m_collection(&amp;collection)
-                , m_index(findNext(index))
-            {
-            }
-
-            StackSlot* operator*()
-            {
-                return m_collection-&gt;at(m_index);
-            }
-
-            iterator&amp; operator++()
-            {
-                m_index = findNext(m_index + 1);
-                return *this;
-            }
-
-            bool operator==(const iterator&amp; other) const
-            {
-                return m_index == other.m_index;
-            }
-
-            bool operator!=(const iterator&amp; other) const
-            {
-                return !(*this == other);
-            }
-
-        private:
-            unsigned findNext(unsigned index)
-            {
-                while (index &lt; m_collection-&gt;size() &amp;&amp; !m_collection-&gt;at(index))
-                    index++;
-                return index;
-            }
-            
-            const StackSlotsCollection* m_collection;
-            unsigned m_index;
-        };
-
-        iterator begin() const { return iterator(*this, 0); }
-        iterator end() const { return iterator(*this, size()); }
-
-    private:
-        const Procedure&amp; m_proc;
-    };
-
-    StackSlotsCollection stackSlots() const { return StackSlotsCollection(*this); }
-
</del><ins>+    // Short for stackSlots().remove(). It's better to call this method since it's out of line.
</ins><span class="cx">     void deleteStackSlot(StackSlot*);
</span><del>-    
-    class ValuesCollection {
-    public:
-        ValuesCollection(const Procedure&amp; procedure)
-            : m_procedure(procedure)
-        {
-        }
</del><span class="cx"> 
</span><del>-        class iterator {
-        public:
-            iterator()
-                : m_procedure(nullptr)
-                , m_index(0)
-            {
-            }
</del><ins>+    SparseCollection&lt;Variable&gt;&amp; variables() { return m_variables; }
+    const SparseCollection&lt;Variable&gt;&amp; variables() const { return m_variables; }
</ins><span class="cx"> 
</span><del>-            iterator(const Procedure&amp; procedure, unsigned index)
-                : m_procedure(&amp;procedure)
-                , m_index(findNext(index))
-            {
-            }
</del><ins>+    // Short for variables().remove(). It's better to call this method since it's out of line.
+    void deleteVariable(Variable*);
</ins><span class="cx"> 
</span><del>-            Value* operator*() const
-            {
-                return m_procedure-&gt;m_values[m_index].get();
-            }
</del><ins>+    SparseCollection&lt;Value&gt;&amp; values() { return m_values; }
+    const SparseCollection&lt;Value&gt;&amp; values() const { return m_values; }
</ins><span class="cx"> 
</span><del>-            iterator&amp; operator++()
-            {
-                m_index = findNext(m_index + 1);
-                return *this;
-            }
-
-            bool operator==(const iterator&amp; other) const
-            {
-                ASSERT(m_procedure == other.m_procedure);
-                return m_index == other.m_index;
-            }
-
-            bool operator!=(const iterator&amp; other) const
-            {
-                return !(*this == other);
-            }
-
-        private:
-            unsigned findNext(unsigned index)
-            {
-                while (index &lt; m_procedure-&gt;m_values.size() &amp;&amp; !m_procedure-&gt;m_values[index])
-                    index++;
-                return index;
-            }
-
-            const Procedure* m_procedure;
-            unsigned m_index;
-        };
-
-        iterator begin() const { return iterator(m_procedure, 0); }
-        iterator end() const { return iterator(m_procedure, m_procedure.m_values.size()); }
-
-        unsigned size() const { return m_procedure.m_values.size(); }
-        Value* at(unsigned index) const { return m_procedure.m_values[index].get(); }
-        Value* operator[](unsigned index) const { return at(index); }
-        
-    private:
-        const Procedure&amp; m_procedure;
-    };
-
-    const ValuesCollection&amp; values() const { return m_valuesCollection; }
-
</del><ins>+    // Short for values().remove(). It's better to call this method since it's out of line.
</ins><span class="cx">     void deleteValue(Value*);
</span><span class="cx"> 
</span><span class="cx">     // A valid procedure cannot contain any orphan values. An orphan is a value that is not in
</span><span class="lines">@@ -367,17 +247,14 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class BlockInsertionSet;
</span><del>-    
</del><ins>+
+    JS_EXPORT_PRIVATE Value* addValueImpl(Value*);
</ins><span class="cx">     void setBlockOrderImpl(Vector&lt;BasicBlock*&gt;&amp;);
</span><span class="cx"> 
</span><del>-    size_t addStackSlotIndex();
-    JS_EXPORT_PRIVATE size_t addValueIndex();
-
-    Vector&lt;std::unique_ptr&lt;StackSlot&gt;&gt; m_stackSlots;
</del><ins>+    SparseCollection&lt;StackSlot&gt; m_stackSlots;
+    SparseCollection&lt;Variable&gt; m_variables;
</ins><span class="cx">     Vector&lt;std::unique_ptr&lt;BasicBlock&gt;&gt; m_blocks;
</span><del>-    Vector&lt;std::unique_ptr&lt;Value&gt;&gt; m_values;
-    Vector&lt;size_t&gt; m_stackSlotIndexFreeList;
-    Vector&lt;size_t&gt; m_valueIndexFreeList;
</del><ins>+    SparseCollection&lt;Value&gt; m_values;
</ins><span class="cx">     std::unique_ptr&lt;CFG&gt; m_cfg;
</span><span class="cx">     std::unique_ptr&lt;Dominators&gt; m_dominators;
</span><span class="cx">     HashSet&lt;ValueKey&gt; m_fastConstants;
</span><span class="lines">@@ -386,7 +263,6 @@
</span><span class="cx">     std::unique_ptr&lt;Air::Code&gt; m_code;
</span><span class="cx">     RefPtr&lt;SharedTask&lt;void(PrintStream&amp;, Origin)&gt;&gt; m_originPrinter;
</span><span class="cx">     const void* m_frontendData;
</span><del>-    ValuesCollection m_valuesCollection;
</del><span class="cx">     PCToOriginMap m_pcToOriginMap;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ProcedureInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ProcedureInlines.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ProcedureInlines.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ProcedureInlines.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -36,11 +36,7 @@
</span><span class="cx"> template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx"> ValueType* Procedure::add(Arguments... arguments)
</span><span class="cx"> {
</span><del>-    size_t index = addValueIndex();
-    std::unique_ptr&lt;ValueType&gt; value(new ValueType(index, arguments...));
-    ValueType* result = value.get();
-    m_values[index] = WTFMove(value);
-    return result;
</del><ins>+    return static_cast&lt;ValueType*&gt;(addValueImpl(new ValueType(arguments...)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -45,6 +45,8 @@
</span><span class="cx"> #include &quot;B3UpsilonValue.h&quot;
</span><span class="cx"> #include &quot;B3ValueKeyInlines.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><ins>+#include &quot;B3Variable.h&quot;
+#include &quot;B3VariableValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/GraphNodeWorklist.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -2283,13 +2285,15 @@
</span><span class="cx">         Vector&lt;UpsilonValue*, 64&gt; upsilons;
</span><span class="cx">         for (BasicBlock* block : m_proc) {
</span><span class="cx">             for (Value* value : *block) {
</span><del>-                Effects effects = value-&gt;effects();
-                // We don't care about SSA Effects, since we model them more accurately than the
-                // effects() method does.
-                effects.writesSSAState = false;
-                effects.readsSSAState = false;
</del><ins>+                Effects effects;
+                // We don't care about effects of SSA operations, since we model them more
+                // accurately than the effects() method does.
+                if (value-&gt;opcode() != Phi &amp;&amp; value-&gt;opcode() != Upsilon)
+                    effects = value-&gt;effects();
+                
</ins><span class="cx">                 if (effects.mustExecute())
</span><span class="cx">                     worklist.push(value);
</span><ins>+                
</ins><span class="cx">                 if (UpsilonValue* upsilon = value-&gt;as&lt;UpsilonValue&gt;())
</span><span class="cx">                     upsilons.append(upsilon);
</span><span class="cx">             }
</span><span class="lines">@@ -2314,7 +2318,7 @@
</span><span class="cx">                 break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        IndexSet&lt;StackSlot&gt; liveStackSlots;
</del><ins>+        IndexSet&lt;Variable&gt; liveVariables;
</ins><span class="cx">         
</span><span class="cx">         for (BasicBlock* block : m_proc) {
</span><span class="cx">             size_t sourceIndex = 0;
</span><span class="lines">@@ -2322,8 +2326,8 @@
</span><span class="cx">             while (sourceIndex &lt; block-&gt;size()) {
</span><span class="cx">                 Value* value = block-&gt;at(sourceIndex++);
</span><span class="cx">                 if (worklist.saw(value)) {
</span><del>-                    if (SlotBaseValue* slotBase = value-&gt;as&lt;SlotBaseValue&gt;())
-                        liveStackSlots.add(slotBase-&gt;slot());
</del><ins>+                    if (VariableValue* variableValue = value-&gt;as&lt;VariableValue&gt;())
+                        liveVariables.add(variableValue-&gt;variable());
</ins><span class="cx">                     block-&gt;at(targetIndex++) = value;
</span><span class="cx">                 } else {
</span><span class="cx">                     m_proc.deleteValue(value);
</span><span class="lines">@@ -2338,10 +2342,9 @@
</span><span class="cx">             block-&gt;values().resize(targetIndex);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (StackSlot* slot : m_proc.stackSlots()) {
-            if (slot-&gt;isLocked() || liveStackSlots.contains(slot))
-                continue;
-            m_proc.deleteStackSlot(slot);
</del><ins>+        for (Variable* variable : m_proc.variables()) {
+            if (!liveVariables.contains(variable))
+                m_proc.deleteVariable(variable);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SlotBaseValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3SlotBaseValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SlotBaseValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3SlotBaseValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -50,8 +50,8 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    SlotBaseValue(unsigned index, Origin origin, StackSlot* slot)
-        : Value(index, CheckedOpcode, SlotBase, pointerType(), origin)
</del><ins>+    SlotBaseValue(Origin origin, StackSlot* slot)
+        : Value(CheckedOpcode, SlotBase, pointerType(), origin)
</ins><span class="cx">         , m_slot(slot)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SparseCollectionh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3SparseCollection.h (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SparseCollection.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3SparseCollection.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3SparseCollection_h
+#define B3SparseCollection_h
+
+#if ENABLE(B3_JIT)
+
+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC { namespace B3 {
+
+// B3::Procedure and Air::Code have a lot of collections of indexed things. This has all of the
+// logic.
+
+template&lt;typename T&gt;
+class SparseCollection {
+    typedef Vector&lt;std::unique_ptr&lt;T&gt;&gt; VectorType;
+    
+public:
+    SparseCollection()
+    {
+    }
+
+    T* add(std::unique_ptr&lt;T&gt; value)
+    {
+        T* result = value.get();
+        
+        size_t index;
+        if (m_indexFreeList.isEmpty()) {
+            index = m_vector.size();
+            m_vector.append(nullptr);
+        } else
+            index = m_indexFreeList.takeLast();
+
+        value-&gt;m_index = index;
+
+        m_vector[index] = WTFMove(value);
+
+        return result;
+    }
+
+    template&lt;typename... Arguments&gt;
+    T* addNew(Arguments&amp;&amp;... arguments)
+    {
+        return add(std::unique_ptr&lt;T&gt;(new T(std::forward&lt;Arguments&gt;(arguments)...)));
+    }
+
+    void remove(T* value)
+    {
+        RELEASE_ASSERT(m_vector[value-&gt;m_index].get() == value);
+        m_indexFreeList.append(value-&gt;m_index);
+        m_vector[value-&gt;m_index] = nullptr;
+    }
+
+    unsigned size() const { return m_vector.size(); }
+    bool isEmpty() const { return m_vector.isEmpty(); }
+    
+    T* at(unsigned index) const { return m_vector[index].get(); }
+    T* operator[](unsigned index) const { return at(index); }
+
+    class iterator {
+    public:
+        iterator()
+            : m_collection(nullptr)
+            , m_index(0)
+        {
+        }
+
+        iterator(const SparseCollection&amp; collection, unsigned index)
+            : m_collection(&amp;collection)
+            , m_index(findNext(index))
+        {
+        }
+
+        T* operator*()
+        {
+            return m_collection-&gt;at(m_index);
+        }
+
+        iterator&amp; operator++()
+        {
+            m_index = findNext(m_index + 1);
+            return *this;
+        }
+
+        bool operator==(const iterator&amp; other) const
+        {
+            ASSERT(m_collection == other.m_collection);
+            return m_index == other.m_index;
+        }
+
+        bool operator!=(const iterator&amp; other) const
+        {
+            return !(*this == other);
+        }
+
+    private:
+        unsigned findNext(unsigned index)
+        {
+            while (index &lt; m_collection-&gt;size() &amp;&amp; !m_collection-&gt;at(index))
+                index++;
+            return index;
+        }
+
+        const SparseCollection* m_collection;
+        unsigned m_index;
+    };
+
+    iterator begin() const { return iterator(*this, 0); }
+    iterator end() const { return iterator(*this, size()); }
+
+private:
+    Vector&lt;std::unique_ptr&lt;T&gt;&gt; m_vector;
+    Vector&lt;size_t&gt; m_indexFreeList;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3SparseCollection_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSlotcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackSlot.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlot.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlot.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -41,13 +41,11 @@
</span><span class="cx"> 
</span><span class="cx"> void StackSlot::deepDump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(&quot;byteSize = &quot;, m_byteSize, &quot;, offsetFromFP = &quot;, m_offsetFromFP, &quot;, kind = &quot;, m_kind);
</del><ins>+    out.print(&quot;byteSize = &quot;, m_byteSize, &quot;, offsetFromFP = &quot;, m_offsetFromFP);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-StackSlot::StackSlot(unsigned index, unsigned byteSize, StackSlotKind kind)
-    : m_index(index)
-    , m_byteSize(byteSize)
-    , m_kind(kind)
</del><ins>+StackSlot::StackSlot(unsigned byteSize)
+    : m_byteSize(byteSize)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSloth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackSlot.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlot.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlot.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><del>-#include &quot;B3StackSlotKind.h&quot;
</del><ins>+#include &quot;B3SparseCollection.h&quot;
</ins><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="lines">@@ -49,8 +49,6 @@
</span><span class="cx">     ~StackSlot();
</span><span class="cx"> 
</span><span class="cx">     unsigned byteSize() const { return m_byteSize; }
</span><del>-    StackSlotKind kind() const { return m_kind; }
-    bool isLocked() const { return m_kind == StackSlotKind::Locked; }
</del><span class="cx">     unsigned index() const { return m_index; }
</span><span class="cx"> 
</span><span class="cx">     // This gets assigned at the end of compilation. But, you can totally pin stack slots. Use the
</span><span class="lines">@@ -63,18 +61,18 @@
</span><span class="cx">         m_offsetFromFP = value;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void dump(PrintStream&amp; out) const;
</del><ins>+    void dump(PrintStream&amp;) const;
</ins><span class="cx">     void deepDump(PrintStream&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class Air::StackSlot;
</span><span class="cx">     friend class Procedure;
</span><ins>+    friend class SparseCollection&lt;StackSlot&gt;;
</ins><span class="cx"> 
</span><del>-    StackSlot(unsigned index, unsigned byteSize, StackSlotKind);
</del><ins>+    StackSlot(unsigned byteSize);
</ins><span class="cx"> 
</span><del>-    unsigned m_index;
-    unsigned m_byteSize;
-    StackSlotKind m_kind;
</del><ins>+    unsigned m_index { UINT_MAX };
+    unsigned m_byteSize { 0 };
</ins><span class="cx">     intptr_t m_offsetFromFP { 0 };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSlotKindcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/B3StackSlotKind.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlotKind.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlotKind.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -1,52 +0,0 @@
</span><del>-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include &quot;config.h&quot;
-#include &quot;B3StackSlotKind.h&quot;
-
-#if ENABLE(B3_JIT)
-
-#include &lt;wtf/PrintStream.h&gt;
-
-namespace WTF {
-
-using namespace JSC::B3;
-
-void printInternal(PrintStream&amp; out, StackSlotKind kind)
-{
-    switch (kind) {
-    case StackSlotKind::Locked:
-        out.print(&quot;Locked&quot;);
-        return;
-    case StackSlotKind::Anonymous:
-        out.print(&quot;Anonymous&quot;);
-        return;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-} // namespace WTF
-
-#endif // ENABLE(B3_JIT)
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSlotKindh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -1,63 +0,0 @@
</span><del>-/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef B3StackSlotKind_h
-#define B3StackSlotKind_h
-
-#if ENABLE(B3_JIT)
-
-namespace JSC { namespace B3 {
-
-enum class StackSlotKind : uint8_t {
-    // A locked stack slot needs to be kept disjoint from all others because we intend to escape
-    // it even if that's not obvious. This happens when the runtime takes the address of a stack
-    // slot.
-    Locked,
-
-    // These stack slots behave like variables. Undefined behavior happens if you store less than
-    // the width of the slot.
-    Anonymous
-
-    // FIXME: We should add a third mode, which means that the stack slot will be read asynchronously
-    // as with Locked, but never written to asynchronously. Then, Air could optimize spilling and
-    // filling by tracking whether the value had been stored to a read-only locked slot. If it had,
-    // then we can refill from that slot.
-    // https://bugs.webkit.org/show_bug.cgi?id=150587
-};
-
-} } // namespace JSC::B3
-
-namespace WTF {
-
-class PrintStream;
-
-void printInternal(PrintStream&amp;, JSC::B3::StackSlotKind);
-
-} // namespace WTF
-
-#endif // ENABLE(B3_JIT)
-
-#endif // B3StackSlotKind_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackmapValue.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapValue.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapValue.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -83,8 +83,8 @@
</span><span class="cx">         &quot;, lateClobbered = &quot;, m_lateClobbered, &quot;, usedRegisters = &quot;, m_usedRegisters);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-StackmapValue::StackmapValue(unsigned index, CheckedOpcodeTag, Opcode opcode, Type type, Origin origin)
-    : Value(index, CheckedOpcode, opcode, type, origin)
</del><ins>+StackmapValue::StackmapValue(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin)
+    : Value(CheckedOpcode, opcode, type, origin)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(accepts(opcode));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackmapValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -284,7 +284,7 @@
</span><span class="cx">     void dumpChildren(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><del>-    StackmapValue(unsigned index, CheckedOpcodeTag, Opcode, Type, Origin);
</del><ins>+    StackmapValue(CheckedOpcodeTag, Opcode, Type, Origin);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class CheckSpecial;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SwitchValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -68,9 +68,8 @@
</span><span class="cx">     return new SwitchValue(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SwitchValue::SwitchValue(
-    unsigned index, Origin origin, Value* child, const FrequentedBlock&amp; fallThrough)
-    : ControlValue(index, Switch, Void, origin, child)
</del><ins>+SwitchValue::SwitchValue(Origin origin, Value* child, const FrequentedBlock&amp; fallThrough)
+    : ControlValue(Switch, Void, origin, child)
</ins><span class="cx"> {
</span><span class="cx">     m_successors.append(fallThrough);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SwitchValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3SwitchValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SwitchValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3SwitchValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -121,8 +121,7 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE SwitchValue(
-        unsigned index, Origin, Value* child, const FrequentedBlock&amp; fallThrough);
</del><ins>+    JS_EXPORT_PRIVATE SwitchValue(Origin, Value* child, const FrequentedBlock&amp; fallThrough);
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;int64_t&gt; m_values;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3UpsilonValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -57,8 +57,8 @@
</span><span class="cx">     // Note that passing the Phi during construction is optional. A valid pattern is to first create
</span><span class="cx">     // the Upsilons without the Phi, then create the Phi, then go back and tell the Upsilons about
</span><span class="cx">     // the Phi. This allows you to emit code in its natural order.
</span><del>-    UpsilonValue(unsigned index, Origin origin, Value* value, Value* phi = nullptr)
-        : Value(index, CheckedOpcode, Upsilon, Void, origin, value)
</del><ins>+    UpsilonValue(Origin origin, Value* value, Value* phi = nullptr)
+        : Value(CheckedOpcode, Upsilon, Void, origin, value)
</ins><span class="cx">         , m_phi(phi)
</span><span class="cx">     {
</span><span class="cx">         if (phi)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -37,6 +37,8 @@
</span><span class="cx"> #include &quot;B3StackSlot.h&quot;
</span><span class="cx"> #include &quot;B3UpsilonValue.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><ins>+#include &quot;B3Variable.h&quot;
+#include &quot;B3VariableValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="lines">@@ -153,6 +155,14 @@
</span><span class="cx">                 VALIDATE(!value-&gt;numChildren(), (&quot;At &quot;, *value));
</span><span class="cx">                 VALIDATE(value-&gt;type() == Float, (&quot;At &quot;, *value));
</span><span class="cx">                 break;
</span><ins>+            case Set:
+                VALIDATE(value-&gt;numChildren() == 1, (&quot;At &quot;, *value));
+                VALIDATE(value-&gt;child(0)-&gt;type() == value-&gt;as&lt;VariableValue&gt;()-&gt;variable()-&gt;type(), (&quot;At &quot;, *value));
+                break;
+            case Get:
+                VALIDATE(!value-&gt;numChildren(), (&quot;At &quot;, *value));
+                VALIDATE(value-&gt;type() == value-&gt;as&lt;VariableValue&gt;()-&gt;variable()-&gt;type(), (&quot;At &quot;, *value));
+                break;
</ins><span class="cx">             case SlotBase:
</span><span class="cx">             case FramePointer:
</span><span class="cx">                 VALIDATE(!value-&gt;numChildren(), (&quot;At &quot;, *value));
</span><span class="lines">@@ -375,6 +385,9 @@
</span><span class="cx"> 
</span><span class="cx">             VALIDATE(!(value-&gt;effects().writes &amp;&amp; value-&gt;key()), (&quot;At &quot;, *value));
</span><span class="cx">         }
</span><ins>+
+        for (Variable* variable : m_procedure.variables())
+            VALIDATE(variable-&gt;type() != Void, (&quot;At &quot;, *variable));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;B3UpsilonValue.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="cx"> #include &quot;B3ValueKeyInlines.h&quot;
</span><ins>+#include &quot;B3VariableValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -72,9 +73,10 @@
</span><span class="cx"> 
</span><span class="cx">     this-&gt;Value::~Value();
</span><span class="cx"> 
</span><del>-    new (this) Value(index, Identity, type, origin, value);
</del><ins>+    new (this) Value(Identity, type, origin, value);
</ins><span class="cx"> 
</span><span class="cx">     this-&gt;owner = owner;
</span><ins>+    this-&gt;m_index = index;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Value::replaceWithNop()
</span><span class="lines">@@ -85,9 +87,10 @@
</span><span class="cx"> 
</span><span class="cx">     this-&gt;Value::~Value();
</span><span class="cx"> 
</span><del>-    new (this) Value(index, Nop, Void, origin);
</del><ins>+    new (this) Value(Nop, Void, origin);
</ins><span class="cx"> 
</span><span class="cx">     this-&gt;owner = owner;
</span><ins>+    this-&gt;m_index = index;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Value::replaceWithPhi()
</span><span class="lines">@@ -104,9 +107,10 @@
</span><span class="cx"> 
</span><span class="cx">     this-&gt;Value::~Value();
</span><span class="cx"> 
</span><del>-    new (this) Value(index, Phi, type, origin);
</del><ins>+    new (this) Value(Phi, type, origin);
</ins><span class="cx"> 
</span><span class="cx">     this-&gt;owner = owner;
</span><ins>+    this-&gt;m_index = index;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Value::dump(PrintStream&amp; out) const
</span><span class="lines">@@ -484,10 +488,12 @@
</span><span class="cx">         result.reads = HeapRange::top();
</span><span class="cx">         break;
</span><span class="cx">     case Upsilon:
</span><del>-        result.writesSSAState = true;
</del><ins>+    case Set:
+        result.writesLocalState = true;
</ins><span class="cx">         break;
</span><span class="cx">     case Phi:
</span><del>-        result.readsSSAState = true;
</del><ins>+    case Get:
+        result.readsLocalState = true;
</ins><span class="cx">         break;
</span><span class="cx">     case Jump:
</span><span class="cx">     case Branch:
</span><span class="lines">@@ -598,6 +604,7 @@
</span><span class="cx">     ASSERT(!PatchpointValue::accepts(opcode));
</span><span class="cx">     ASSERT(!SlotBaseValue::accepts(opcode));
</span><span class="cx">     ASSERT(!UpsilonValue::accepts(opcode));
</span><ins>+    ASSERT(!VariableValue::accepts(opcode));
</ins><span class="cx"> }
</span><span class="cx"> #endif // !ASSERT_DISABLED
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/B3Value.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;B3Effects.h&quot;
</span><span class="cx"> #include &quot;B3Opcode.h&quot;
</span><span class="cx"> #include &quot;B3Origin.h&quot;
</span><ins>+#include &quot;B3SparseCollection.h&quot;
</ins><span class="cx"> #include &quot;B3Type.h&quot;
</span><span class="cx"> #include &quot;B3ValueKey.h&quot;
</span><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="lines">@@ -226,6 +227,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><ins>+    friend class SparseCollection&lt;Value&gt;;
</ins><span class="cx"> 
</span><span class="cx">     // Checks that this opcode is valid for use with B3::Value.
</span><span class="cx"> #if ASSERT_DISABLED
</span><span class="lines">@@ -243,27 +245,24 @@
</span><span class="cx">     // Instantiate values via Procedure.
</span><span class="cx">     // This form requires specifying the type explicitly:
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, Value* firstChild, Arguments... arguments)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, Value* firstChild, Arguments... arguments)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(type)
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">         , m_children{ firstChild, arguments... }
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     // This form is for specifying the type explicitly when the opcode has no children:
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Type type, Origin origin)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(type)
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     // This form is for those opcodes that can infer their type from the opcode and first child:
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Origin origin, Value* firstChild)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Origin origin, Value* firstChild)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(typeFor(opcode, firstChild))
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">         , m_children{ firstChild }
</span><span class="lines">@@ -271,9 +270,8 @@
</span><span class="cx">     }
</span><span class="cx">     // This form is for those opcodes that can infer their type from the opcode and first and second child:
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(typeFor(opcode, firstChild, secondChild))
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">         , m_children{ firstChild, secondChild, arguments... }
</span><span class="lines">@@ -281,25 +279,22 @@
</span><span class="cx">     }
</span><span class="cx">     // This form is for those opcodes that can infer their type from the opcode alone, and that don't
</span><span class="cx">     // take any arguments:
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Origin origin)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Origin origin)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(typeFor(opcode, nullptr))
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     // Use this form for varargs.
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, const AdjacencyList&amp; children)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, const AdjacencyList&amp; children)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(type)
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">         , m_children(children)
</span><span class="cx">     {
</span><span class="cx">     }
</span><del>-    explicit Value(unsigned index, CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, AdjacencyList&amp;&amp; children)
-        : m_index(index)
-        , m_opcode(opcode)
</del><ins>+    explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, AdjacencyList&amp;&amp; children)
+        : m_opcode(opcode)
</ins><span class="cx">         , m_type(type)
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">         , m_children(WTFMove(children))
</span><span class="lines">@@ -309,8 +304,8 @@
</span><span class="cx">     // This is the constructor you end up actually calling, if you're instantiating Value
</span><span class="cx">     // directly.
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    explicit Value(unsigned index, Opcode opcode, Arguments&amp;&amp;... arguments)
-        : Value(index, CheckedOpcode, opcode, std::forward&lt;Arguments&gt;(arguments)...)
</del><ins>+    explicit Value(Opcode opcode, Arguments&amp;&amp;... arguments)
+        : Value(CheckedOpcode, opcode, std::forward&lt;Arguments&gt;(arguments)...)
</ins><span class="cx">     {
</span><span class="cx">         checkOpcode(opcode);
</span><span class="cx">     }
</span><span class="lines">@@ -321,7 +316,9 @@
</span><span class="cx">     static Type typeFor(Opcode, Value* firstChild, Value* secondChild = nullptr);
</span><span class="cx"> 
</span><span class="cx">     // This group of fields is arranged to fit in 64 bits.
</span><del>-    unsigned m_index;
</del><ins>+protected:
+    unsigned m_index { UINT_MAX };
+private:
</ins><span class="cx">     Opcode m_opcode;
</span><span class="cx">     Type m_type;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Variablecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3Variable.cpp (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Variable.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3Variable.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3Variable.h&quot;
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+Variable::~Variable()
+{
+}
+
+void Variable::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;var&quot;, m_index);
+}
+
+void Variable::deepDump(PrintStream&amp; out) const
+{
+    out.print(m_type, &quot; var&quot;, m_index);
+}
+
+Variable::Variable(Type type)
+    : m_type(type)
+{
+    ASSERT(type != Void);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Variableh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3Variable.h (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Variable.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3Variable.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3Variable_h
+#define B3Variable_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3SparseCollection.h&quot;
+#include &quot;B3Type.h&quot;
+#include &lt;wtf/FastMalloc.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+class Variable {
+    WTF_MAKE_NONCOPYABLE(Variable);
+    WTF_MAKE_FAST_ALLOCATED;
+
+public:
+    ~Variable();
+
+    Type type() const { return m_type; }
+    unsigned index() const { return m_index; }
+
+    void dump(PrintStream&amp;) const;
+    void deepDump(PrintStream&amp;) const;
+
+private:
+    friend class Procedure;
+    friend class SparseCollection&lt;Variable&gt;;
+
+    Variable(Type);
+    
+    unsigned m_index;
+    Type m_type;
+};
+
+class DeepVariableDump {
+public:
+    DeepVariableDump(const Variable* variable)
+        : m_variable(variable)
+    {
+    }
+
+    void dump(PrintStream&amp; out) const
+    {
+        if (m_variable)
+            m_variable-&gt;deepDump(out);
+        else
+            out.print(&quot;&lt;null&gt;&quot;);
+    }
+
+private:
+    const Variable* m_variable;
+};
+
+inline DeepVariableDump deepDump(const Variable* variable)
+{
+    return DeepVariableDump(variable);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3Variable_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3VariableValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3VariableValue.cpp (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3VariableValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3VariableValue.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3VariableValue.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3Variable.h&quot;
+
+namespace JSC { namespace B3 {
+
+VariableValue::~VariableValue()
+{
+}
+
+void VariableValue::dumpMeta(CommaPrinter&amp; comma, PrintStream&amp; out) const
+{
+    out.print(comma, pointerDump(m_variable));
+}
+
+Value* VariableValue::cloneImpl() const
+{
+    return new VariableValue(*this);
+}
+
+VariableValue::VariableValue(Opcode opcode, Origin origin, Variable* variable, Value* value)
+    : Value(CheckedOpcode, opcode, Void, origin, value)
+    , m_variable(variable)
+{
+    ASSERT(opcode == Set);
+}
+
+VariableValue::VariableValue(Opcode opcode, Origin origin, Variable* variable)
+    : Value(CheckedOpcode, opcode, variable-&gt;type(), origin)
+    , m_variable(variable)
+{
+    ASSERT(opcode == Get);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3VariableValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3VariableValue.h (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3VariableValue.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3VariableValue.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/*
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3VariableValue_h
+#define B3VariableValue_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3Value.h&quot;
+
+namespace JSC { namespace B3 {
+
+class Variable;
+
+class JS_EXPORT_PRIVATE VariableValue : public Value {
+public:
+    static bool accepts(Opcode opcode) { return opcode == Get || opcode == Set; }
+
+    ~VariableValue();
+
+    Variable* variable() const { return m_variable; }
+
+protected:
+    void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
+
+    Value* cloneImpl() const override;
+
+private:
+    friend class Procedure;
+
+    // Use this for Set.
+    VariableValue(Opcode, Origin, Variable*, Value*);
+
+    // Use this for Get.
+    VariableValue(Opcode, Origin, Variable*);
+
+    Variable* m_variable;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3VariableValue_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirAllocateStackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirAllocateStack.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirAllocateStack.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirAllocateStack.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -95,30 +95,13 @@
</span><span class="cx"> {
</span><span class="cx">     PhaseScope phaseScope(code, &quot;allocateStack&quot;);
</span><span class="cx"> 
</span><del>-    // Perform an escape analysis over stack slots. An escaping stack slot is one that is locked or
-    // is explicitly escaped in the code.
-    IndexSet&lt;StackSlot&gt; escapingStackSlots;
-    for (StackSlot* slot : code.stackSlots()) {
-        if (slot-&gt;isLocked())
-            escapingStackSlots.add(slot);
-    }
-    for (BasicBlock* block : code) {
-        for (Inst&amp; inst : *block) {
-            inst.forEachArg(
-                [&amp;] (Arg&amp; arg, Arg::Role role, Arg::Type, Arg::Width) {
-                    if (role == Arg::UseAddr &amp;&amp; arg.isStack())
-                        escapingStackSlots.add(arg.stackSlot());
-                });
-        }
-    }
-
</del><span class="cx">     // Allocate all of the escaped slots in order. This is kind of a crazy algorithm to allow for
</span><span class="cx">     // the possibility of stack slots being assigned frame offsets before we even get here.
</span><span class="cx">     ASSERT(!code.frameSize());
</span><span class="cx">     Vector&lt;StackSlot*&gt; assignedEscapedStackSlots;
</span><span class="cx">     Vector&lt;StackSlot*&gt; escapedStackSlotsWorklist;
</span><span class="cx">     for (StackSlot* slot : code.stackSlots()) {
</span><del>-        if (escapingStackSlots.contains(slot)) {
</del><ins>+        if (slot-&gt;isLocked()) {
</ins><span class="cx">             if (slot-&gt;offsetFromFP())
</span><span class="cx">                 assignedEscapedStackSlots.append(slot);
</span><span class="cx">             else
</span><span class="lines">@@ -136,7 +119,7 @@
</span><span class="cx">         assignedEscapedStackSlots.append(slot);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Now we handle the anonymous slots.
</del><ins>+    // Now we handle the spill slots.
</ins><span class="cx">     StackSlotLiveness liveness(code);
</span><span class="cx">     IndexMap&lt;StackSlot, HashSet&lt;StackSlot*&gt;&gt; interference(code.stackSlots().size());
</span><span class="cx">     Vector&lt;StackSlot*&gt; slots;
</span><span class="lines">@@ -154,7 +137,7 @@
</span><span class="cx">                     if (!arg.isStack())
</span><span class="cx">                         return;
</span><span class="cx">                     StackSlot* slot = arg.stackSlot();
</span><del>-                    if (slot-&gt;kind() != StackSlotKind::Anonymous)
</del><ins>+                    if (slot-&gt;kind() != StackSlotKind::Spill)
</ins><span class="cx">                         return;
</span><span class="cx"> 
</span><span class="cx">                     for (StackSlot* otherSlot : localCalc.live()) {
</span><span class="lines">@@ -187,7 +170,7 @@
</span><span class="cx">                             return;
</span><span class="cx">                         }
</span><span class="cx">                         StackSlot* slot = arg.stackSlot();
</span><del>-                        if (slot-&gt;kind() != StackSlotKind::Anonymous) {
</del><ins>+                        if (slot-&gt;kind() != StackSlotKind::Spill) {
</ins><span class="cx">                             ok = false;
</span><span class="cx">                             return;
</span><span class="cx">                         }
</span><span class="lines">@@ -287,7 +270,7 @@
</span><span class="cx">                     case Arg::Stack: {
</span><span class="cx">                         StackSlot* slot = arg.stackSlot();
</span><span class="cx">                         if (Arg::isZDef(role)
</span><del>-                            &amp;&amp; slot-&gt;kind() == StackSlotKind::Anonymous
</del><ins>+                            &amp;&amp; slot-&gt;kind() == StackSlotKind::Spill
</ins><span class="cx">                             &amp;&amp; slot-&gt;byteSize() &gt; Arg::bytes(width)) {
</span><span class="cx">                             // Currently we only handle this simple case because it's the only one
</span><span class="cx">                             // that arises: ZDef's are only 32-bit right now. So, when we hit these
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCode.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCode.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirCode.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -54,23 +54,18 @@
</span><span class="cx"> 
</span><span class="cx"> StackSlot* Code::addStackSlot(unsigned byteSize, StackSlotKind kind, B3::StackSlot* b3Slot)
</span><span class="cx"> {
</span><del>-    std::unique_ptr&lt;StackSlot&gt; slot(new StackSlot(byteSize, m_stackSlots.size(), kind, b3Slot));
-    StackSlot* result = slot.get();
-    m_stackSlots.append(WTFMove(slot));
-    return result;
</del><ins>+    return m_stackSlots.addNew(byteSize, kind, b3Slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> StackSlot* Code::addStackSlot(B3::StackSlot* b3Slot)
</span><span class="cx"> {
</span><del>-    return addStackSlot(b3Slot-&gt;byteSize(), b3Slot-&gt;kind(), b3Slot);
</del><ins>+    return addStackSlot(b3Slot-&gt;byteSize(), StackSlotKind::Locked, b3Slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Special* Code::addSpecial(std::unique_ptr&lt;Special&gt; special)
</span><span class="cx"> {
</span><del>-    Special* result = special.get();
-    result-&gt;m_code = this;
-    m_specials.append(WTFMove(special));
-    return result;
</del><ins>+    special-&gt;m_code = this;
+    return m_specials.add(WTFMove(special));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CCallSpecial* Code::cCallSpecial()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCode.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;AirSpecial.h&quot;
</span><span class="cx"> #include &quot;AirStackSlot.h&quot;
</span><span class="cx"> #include &quot;AirTmp.h&quot;
</span><ins>+#include &quot;B3SparseCollection.h&quot;
</ins><span class="cx"> #include &quot;RegisterAtOffsetList.h&quot;
</span><span class="cx"> #include &quot;StackAlignment.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -184,126 +185,12 @@
</span><span class="cx">     iterator begin() const { return iterator(*this, 0); }
</span><span class="cx">     iterator end() const { return iterator(*this, size()); }
</span><span class="cx"> 
</span><del>-    class StackSlotsCollection {
-    public:
-        StackSlotsCollection(const Code&amp; code)
-            : m_code(code)
-        {
-        }
</del><ins>+    const SparseCollection&lt;StackSlot&gt;&amp; stackSlots() const { return m_stackSlots; }
+    SparseCollection&lt;StackSlot&gt;&amp; stackSlots() { return m_stackSlots; }
</ins><span class="cx"> 
</span><del>-        unsigned size() const { return m_code.m_stackSlots.size(); }
-        StackSlot* at(unsigned index) const { return m_code.m_stackSlots[index].get(); }
-        StackSlot* operator[](unsigned index) const { return at(index); }
</del><ins>+    const SparseCollection&lt;Special&gt;&amp; specials() const { return m_specials; }
+    SparseCollection&lt;Special&gt;&amp; specials() { return m_specials; }
</ins><span class="cx"> 
</span><del>-        class iterator {
-        public:
-            iterator()
-                : m_collection(nullptr)
-                , m_index(0)
-            {
-            }
-
-            iterator(const StackSlotsCollection&amp; collection, unsigned index)
-                : m_collection(&amp;collection)
-                , m_index(index)
-            {
-            }
-
-            StackSlot* operator*()
-            {
-                return m_collection-&gt;at(m_index);
-            }
-
-            iterator&amp; operator++()
-            {
-                m_index++;
-                return *this;
-            }
-
-            bool operator==(const iterator&amp; other) const
-            {
-                return m_index == other.m_index;
-            }
-
-            bool operator!=(const iterator&amp; other) const
-            {
-                return !(*this == other);
-            }
-
-        private:
-            const StackSlotsCollection* m_collection;
-            unsigned m_index;
-        };
-
-        iterator begin() const { return iterator(*this, 0); }
-        iterator end() const { return iterator(*this, size()); }
-
-    private:
-        const Code&amp; m_code;
-    };
-
-    StackSlotsCollection stackSlots() const { return StackSlotsCollection(*this); }
-    
-    class SpecialsCollection {
-    public:
-        SpecialsCollection(const Code&amp; code)
-            : m_code(code)
-        {
-        }
-
-        unsigned size() const { return m_code.m_specials.size(); }
-        Special* at(unsigned index) const { return m_code.m_specials[index].get(); }
-        Special* operator[](unsigned index) const { return at(index); }
-
-        class iterator {
-        public:
-            iterator()
-                : m_collection(nullptr)
-                , m_index(0)
-            {
-            }
-
-            iterator(const SpecialsCollection&amp; collection, unsigned index)
-                : m_collection(&amp;collection)
-                , m_index(index)
-            {
-            }
-
-            Special* operator*()
-            {
-                return m_collection-&gt;at(m_index);
-            }
-
-            iterator&amp; operator++()
-            {
-                m_index++;
-                return *this;
-            }
-
-            bool operator==(const iterator&amp; other) const
-            {
-                return m_index == other.m_index;
-            }
-
-            bool operator!=(const iterator&amp; other) const
-            {
-                return !(*this == other);
-            }
-
-        private:
-            const SpecialsCollection* m_collection;
-            unsigned m_index;
-        };
-
-        iterator begin() const { return iterator(*this, 0); }
-        iterator end() const { return iterator(*this, size()); }
-
-    private:
-        const Code&amp; m_code;
-    };
-
-    SpecialsCollection specials() const { return SpecialsCollection(*this); }
-
</del><span class="cx">     template&lt;typename Callback&gt;
</span><span class="cx">     void forAllTmps(const Callback&amp; callback) const
</span><span class="cx">     {
</span><span class="lines">@@ -331,9 +218,9 @@
</span><span class="cx">     Code(Procedure&amp;);
</span><span class="cx"> 
</span><span class="cx">     Procedure&amp; m_proc; // Some meta-data, like byproducts, is stored in the Procedure.
</span><del>-    Vector&lt;std::unique_ptr&lt;StackSlot&gt;&gt; m_stackSlots;
</del><ins>+    SparseCollection&lt;StackSlot&gt; m_stackSlots;
</ins><span class="cx">     Vector&lt;std::unique_ptr&lt;BasicBlock&gt;&gt; m_blocks;
</span><del>-    Vector&lt;std::unique_ptr&lt;Special&gt;&gt; m_specials;
</del><ins>+    SparseCollection&lt;Special&gt; m_specials;
</ins><span class="cx">     HashSet&lt;Tmp&gt; m_fastTmps;
</span><span class="cx">     CCallSpecial* m_cCallSpecial { nullptr };
</span><span class="cx">     unsigned m_numGPTmps { 0 };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirFixObviousSpillscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -261,7 +261,7 @@
</span><span class="cx">     
</span><span class="cx">     static bool isSpillSlot(const Arg&amp; arg)
</span><span class="cx">     {
</span><del>-        return arg.isStack() &amp;&amp; !arg.stackSlot()-&gt;isLocked();
</del><ins>+        return arg.isStack() &amp;&amp; arg.stackSlot()-&gt;isSpill();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     struct RegConst {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInstInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;AirInst.h&quot;
</span><span class="cx"> #include &quot;AirOpcodeUtils.h&quot;
</span><span class="cx"> #include &quot;AirSpecial.h&quot;
</span><ins>+#include &quot;AirStackSlot.h&quot;
</ins><span class="cx"> #include &quot;B3Value.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirIteratedRegisterCoalescingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -1233,7 +1233,7 @@
</span><span class="cx"> 
</span><span class="cx">             // Allocate stack slot for each spilled value.
</span><span class="cx">             StackSlot* stackSlot = m_code.addStackSlot(
</span><del>-                m_tmpWidth.width(tmp) &lt;= Arg::Width32 ? 4 : 8, StackSlotKind::Anonymous);
</del><ins>+                m_tmpWidth.width(tmp) &lt;= Arg::Width32 ? 4 : 8, StackSlotKind::Spill);
</ins><span class="cx">             bool isNewTmp = stackSlots.add(tmp, stackSlot).isNewEntry;
</span><span class="cx">             ASSERT_UNUSED(isNewTmp, isNewTmp);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLivenessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLiveness.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLiveness.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirLiveness.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;AirBasicBlock.h&quot;
</span><span class="cx"> #include &quot;AirCode.h&quot;
</span><span class="cx"> #include &quot;AirInstInlines.h&quot;
</span><ins>+#include &quot;AirStackSlot.h&quot;
</ins><span class="cx"> #include &quot;AirTmpInlines.h&quot;
</span><span class="cx"> #include &quot;B3IndexMap.h&quot;
</span><span class="cx"> #include &quot;B3IndexSet.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">                 result[i] = Arg::stack(
</span><span class="cx">                     code.addStackSlot(
</span><span class="cx">                         Arg::bytes(Arg::conservativeWidth(type)),
</span><del>-                        StackSlotKind::Anonymous));
</del><ins>+                        StackSlotKind::Spill));
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         return result;
</span><span class="lines">@@ -182,7 +182,7 @@
</span><span class="cx">                         Arg arg(tmp);
</span><span class="cx">                         Arg::Width width = Arg::conservativeWidth(arg.type());
</span><span class="cx">                         StackSlot* stackSlot =
</span><del>-                            code.addStackSlot(Arg::bytes(width), StackSlotKind::Anonymous);
</del><ins>+                            code.addStackSlot(Arg::bytes(width), StackSlotKind::Spill);
</ins><span class="cx">                         pairs.append(ShufflePair(arg, Arg::stack(stackSlot), width));
</span><span class="cx">                         stackSlots.append(stackSlot);
</span><span class="cx">                     });
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirSpecial.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirSpecial.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirSpecial.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -36,8 +36,6 @@
</span><span class="cx"> const char* const Special::dumpPrefix = &quot;&amp;&quot;;
</span><span class="cx"> 
</span><span class="cx"> Special::Special()
</span><del>-    : m_index(UINT_MAX)
-    , m_code(nullptr)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirSpecialh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirSpecial.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirSpecial.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirSpecial.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AirInst.h&quot;
</span><ins>+#include &quot;B3SparseCollection.h&quot;
</ins><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/ScopedLambda.h&gt;
</span><span class="lines">@@ -98,10 +99,10 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class Code;
</span><ins>+    friend class SparseCollection&lt;Special&gt;;
</ins><span class="cx"> 
</span><del>-    const char* m_name;
-    unsigned m_index;
-    Code* m_code;
</del><ins>+    unsigned m_index { UINT_MAX };
+    Code* m_code { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class DeepSpecialDump {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirSpillEverythingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirSpillEverything.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirSpillEverything.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirSpillEverything.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx">         Arg::Type type = static_cast&lt;Arg::Type&gt;(typeIndex);
</span><span class="cx">         stackSlots.resize(code.numTmps(type));
</span><span class="cx">         for (unsigned tmpIndex = code.numTmps(type); tmpIndex--;)
</span><del>-            stackSlots[tmpIndex] = code.addStackSlot(8, StackSlotKind::Anonymous);
</del><ins>+            stackSlots[tmpIndex] = code.addStackSlot(8, StackSlotKind::Spill);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     InsertionSet insertionSet(code);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirStackSlotcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirStackSlot.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirStackSlot.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirStackSlot.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -41,7 +41,11 @@
</span><span class="cx"> 
</span><span class="cx"> void StackSlot::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(&quot;stack&quot;, m_index);
</del><ins>+    if (isSpill())
+        out.print(&quot;spill&quot;);
+    else
+        out.print(&quot;stack&quot;);
+    out.print(m_index);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StackSlot::deepDump(PrintStream&amp; out) const
</span><span class="lines">@@ -51,9 +55,8 @@
</span><span class="cx">         out.print(&quot;, b3Slot = &quot;, *m_b3Slot, &quot;: (&quot;, B3::deepDump(m_b3Slot), &quot;)&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-StackSlot::StackSlot(unsigned byteSize, unsigned index, StackSlotKind kind, B3::StackSlot* b3Slot)
</del><ins>+StackSlot::StackSlot(unsigned byteSize, StackSlotKind kind, B3::StackSlot* b3Slot)
</ins><span class="cx">     : m_byteSize(byteSize)
</span><del>-    , m_index(index)
</del><span class="cx">     , m_offsetFromFP(b3Slot ? b3Slot-&gt;offsetFromFP() : 0)
</span><span class="cx">     , m_kind(kind)
</span><span class="cx">     , m_b3Slot(b3Slot)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirStackSloth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirStackSlot.h (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirStackSlot.h        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/AirStackSlot.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -28,7 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><del>-#include &quot;B3StackSlotKind.h&quot;
</del><ins>+#include &quot;AirStackSlotKind.h&quot;
+#include &quot;B3SparseCollection.h&quot;
</ins><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="lines">@@ -46,6 +47,7 @@
</span><span class="cx">     unsigned byteSize() const { return m_byteSize; }
</span><span class="cx">     StackSlotKind kind() const { return m_kind; }
</span><span class="cx">     bool isLocked() const { return m_kind == StackSlotKind::Locked; }
</span><ins>+    bool isSpill() const { return m_kind == StackSlotKind::Spill; }
</ins><span class="cx">     unsigned index() const { return m_index; }
</span><span class="cx"> 
</span><span class="cx">     void ensureSize(unsigned requestedSize)
</span><span class="lines">@@ -79,14 +81,15 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class Code;
</span><ins>+    friend class SparseCollection&lt;StackSlot&gt;;
</ins><span class="cx"> 
</span><del>-    StackSlot(unsigned byteSize, unsigned index, StackSlotKind, B3::StackSlot*);
</del><ins>+    StackSlot(unsigned byteSize, StackSlotKind, B3::StackSlot*);
</ins><span class="cx">     
</span><del>-    unsigned m_byteSize;
-    unsigned m_index;
-    intptr_t m_offsetFromFP;
-    StackSlotKind m_kind;
-    B3::StackSlot* m_b3Slot;
</del><ins>+    unsigned m_byteSize { 0 };
+    unsigned m_index { UINT_MAX };
+    intptr_t m_offsetFromFP { 0 };
+    StackSlotKind m_kind { StackSlotKind::Locked };
+    B3::StackSlot* m_b3Slot { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class DeepStackSlotDump {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirStackSlotKindcppfromrev195901trunkSourceJavaScriptCoreb3B3StackSlotKindcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.cpp (from rev 195901, trunk/Source/JavaScriptCore/b3/B3StackSlotKind.cpp) (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;AirStackSlotKind.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace WTF {
+
+using namespace JSC::B3::Air;
+
+void printInternal(PrintStream&amp; out, StackSlotKind kind)
+{
+    switch (kind) {
+    case StackSlotKind::Locked:
+        out.print(&quot;Locked&quot;);
+        return;
+    case StackSlotKind::Spill:
+        out.print(&quot;Spill&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(B3_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirStackSlotKindhfromrev195901trunkSourceJavaScriptCoreb3B3StackSlotKindh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.h (from rev 195901, trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h) (0 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/air/AirStackSlotKind.h        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/*
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef AirStackSlotKind_h
+#define AirStackSlotKind_h
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 { namespace Air {
+
+enum class StackSlotKind : uint8_t {
+    // A locked stack slot is an area of stack requested by the client. It cannot be killed. The
+    // client can get its FP offset and write to it from stack walking code, so we must assume
+    // that reads and writes to a locked stack slot can be clobbered the same way as reads and
+    // writes to any memory location.
+    Locked,
+
+    // A spill slot. These have fundamentally different behavior than a typical memory location.
+    // They are lowered to from temporaries. This means for example that a 32-bit ZDef store to a
+    // 8 byte stack slot will zero the top 4 bytes, even though a 32-bit ZDef store to any other
+    // kind of memory location would do no such thing. UseAddr on a spill slot is not allowed, so
+    // they never escape.
+    Spill
+
+    // FIXME: We should add a third mode, which means that the stack slot will be read asynchronously
+    // as with Locked, but never written to asynchronously. Then, Air could optimize spilling and
+    // filling by tracking whether the value had been stored to a read-only locked slot. If it had,
+    // then we can refill from that slot.
+    // https://bugs.webkit.org/show_bug.cgi?id=150587
+};
+
+} } } // namespace JSC::B3::Air
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&amp;, JSC::B3::Air::StackSlotKind);
+
+} // namespace WTF
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3StackSlotKind_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airopcode_generatorrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -680,6 +680,18 @@
</span><span class="cx">                 filter = proc { false }
</span><span class="cx">                 callback = proc {
</span><span class="cx">                     | form |
</span><ins>+                    # This conservatively says that Stack is not a valid form for UseAddr,
+                    # because it's only valid if it's not a spill slot. This is consistent with
+                    # isValidForm() being conservative and it also happens to be practical since
+                    # we don't really use isValidForm for deciding when Stack is safe.
+                    overload.signature.length.times {
+                        | index |
+                        if overload.signature[index].role == &quot;UA&quot;
+                            outp.puts &quot;if (opgenHiddenPtrIdentity(kinds)[#{index}] == Arg::Stack)&quot;
+                            outp.puts &quot;    return false;&quot;
+                        end
+                    }
+                    
</ins><span class="cx">                     notCustom = (not form.kinds.detect { | kind | kind.custom })
</span><span class="cx">                     if notCustom
</span><span class="cx">                         beginArchs(outp, form.archs)
</span><span class="lines">@@ -787,6 +799,11 @@
</span><span class="cx">                     outp.puts &quot;if (!Arg::isValidImmForm(args[#{index}].value()))&quot;
</span><span class="cx">                     outp.puts &quot;OPGEN_RETURN(false);&quot;
</span><span class="cx">                 when &quot;Addr&quot;
</span><ins>+                    if arg.role == &quot;UA&quot;
+                        outp.puts &quot;if (args[#{index}].isStack() &amp;&amp; args[#{index}].stackSlot()-&gt;isSpill())&quot;
+                        outp.puts &quot;OPGEN_RETURN(false);&quot;
+                    end
+                    
</ins><span class="cx">                     outp.puts &quot;if (!Arg::isValidAddrForm(args[#{index}].offset()))&quot;
</span><span class="cx">                     outp.puts &quot;OPGEN_RETURN(false);&quot;
</span><span class="cx">                 when &quot;Index&quot;
</span><span class="lines">@@ -839,9 +856,11 @@
</span><span class="cx">                 numNo = 0
</span><span class="cx">                 opcode.overloads.each {
</span><span class="cx">                     | overload |
</span><ins>+                    useAddr = (overload.signature[argIndex] and
+                               overload.signature[argIndex].role == &quot;UA&quot;)
</ins><span class="cx">                     overload.forms.each {
</span><span class="cx">                         | form |
</span><del>-                        if form.kinds[argIndex] == &quot;Addr&quot;
</del><ins>+                        if form.kinds[argIndex] == &quot;Addr&quot; and not useAddr
</ins><span class="cx">                             numYes += 1
</span><span class="cx">                         else
</span><span class="cx">                             numNo += 1
</span><span class="lines">@@ -864,12 +883,15 @@
</span><span class="cx">                     opcode.overloads.each {
</span><span class="cx">                         | overload |
</span><span class="cx"> 
</span><ins>+                        useAddr = (overload.signature[argIndex] and
+                                   overload.signature[argIndex].role == &quot;UA&quot;)
+                        
</ins><span class="cx">                         # Again, check if all of them do what we want.
</span><span class="cx">                         numYes = 0
</span><span class="cx">                         numNo = 0
</span><span class="cx">                         overload.forms.each {
</span><span class="cx">                             | form |
</span><del>-                            if form.kinds[argIndex] == &quot;Addr&quot;
</del><ins>+                            if form.kinds[argIndex] == &quot;Addr&quot; and not useAddr
</ins><span class="cx">                                 numYes += 1
</span><span class="cx">                             else
</span><span class="cx">                                 numNo += 1
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airtestaircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/testair.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/testair.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/air/testair.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -408,7 +408,7 @@
</span><span class="cx">             shuffle.append(Tmp(GPRInfo::regT0), Tmp(reg), Arg::widthArg(Arg::Width32));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), B3::StackSlotKind::Locked);
</del><ins>+    StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), StackSlotKind::Locked);
</ins><span class="cx">     for (unsigned i = 0; i &lt; regs.size(); ++i)
</span><span class="cx">         root-&gt;append(Move32, nullptr, Tmp(regs[i]), Arg::stack(slot, i * sizeof(int32_t)));
</span><span class="cx"> 
</span><span class="lines">@@ -869,7 +869,7 @@
</span><span class="cx">     for (unsigned i = 1; i &lt; regs.size(); ++i)
</span><span class="cx">         shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width32));
</span><span class="cx"> 
</span><del>-    StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), B3::StackSlotKind::Locked);
</del><ins>+    StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), StackSlotKind::Locked);
</ins><span class="cx">     for (unsigned i = 0; i &lt; regs.size(); ++i)
</span><span class="cx">         root-&gt;append(Move32, nullptr, Tmp(regs[i]), Arg::stack(slot, i * sizeof(int32_t)));
</span><span class="cx"> 
</span><span class="lines">@@ -906,7 +906,7 @@
</span><span class="cx">         shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width32));
</span><span class="cx">     shuffle.append(Tmp(regs.last()), Tmp(regs[0]), Arg::widthArg(Arg::Width32));
</span><span class="cx"> 
</span><del>-    StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), B3::StackSlotKind::Locked);
</del><ins>+    StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), StackSlotKind::Locked);
</ins><span class="cx">     for (unsigned i = 0; i &lt; regs.size(); ++i)
</span><span class="cx">         root-&gt;append(Move32, nullptr, Tmp(regs[i]), Arg::stack(slot, i * sizeof(int32_t)));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -4990,7 +4990,7 @@
</span><span class="cx">         BasicBlock* root = proc.addBlock();
</span><span class="cx"> 
</span><span class="cx">         // Add a stack slot to make the frame non trivial.
</span><del>-        root-&gt;appendNew&lt;SlotBaseValue&gt;(proc, Origin(), proc.addStackSlot(8, StackSlotKind::Locked));
</del><ins>+        root-&gt;appendNew&lt;SlotBaseValue&gt;(proc, Origin(), proc.addStackSlot(8));
</ins><span class="cx"> 
</span><span class="cx">         // Sub on x86 UseDef the source. If FP is not protected correctly, it will be overridden since it is the last visible use.
</span><span class="cx">         Value* offset = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0);
</span><span class="lines">@@ -5004,7 +5004,7 @@
</span><span class="cx">         Procedure proc;
</span><span class="cx">         BasicBlock* root = proc.addBlock();
</span><span class="cx"> 
</span><del>-        root-&gt;appendNew&lt;SlotBaseValue&gt;(proc, Origin(), proc.addStackSlot(8, StackSlotKind::Locked));
</del><ins>+        root-&gt;appendNew&lt;SlotBaseValue&gt;(proc, Origin(), proc.addStackSlot(8));
</ins><span class="cx"> 
</span><span class="cx">         Value* offset = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0);
</span><span class="cx">         Value* fp = root-&gt;appendNew&lt;Value&gt;(proc, FramePointer, Origin());
</span><span class="lines">@@ -5024,8 +5024,7 @@
</span><span class="cx">     BasicBlock* root = proc.addBlock();
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(
</span><span class="cx">         proc, Return, Origin(),
</span><del>-        root-&gt;appendNew&lt;SlotBaseValue&gt;(
-            proc, Origin(), proc.addStackSlot(1, StackSlotKind::Anonymous)));
</del><ins>+        root-&gt;appendNew&lt;SlotBaseValue&gt;(proc, Origin(), proc.addStackSlot(1)));
</ins><span class="cx"> 
</span><span class="cx">     void* stackSlot = compileAndRun&lt;void*&gt;(proc);
</span><span class="cx">     CHECK(stackSlot &lt; &amp;proc);
</span><span class="lines">@@ -5053,8 +5052,8 @@
</span><span class="cx">     Procedure proc;
</span><span class="cx">     BasicBlock* root = proc.addBlock();
</span><span class="cx"> 
</span><del>-    SlotBaseValue* stack = root-&gt;appendNew&lt;SlotBaseValue&gt;(
-        proc, Origin(), proc.addStackSlot(sizeof(int), StackSlotKind::Anonymous));
</del><ins>+    SlotBaseValue* stack =
+        root-&gt;appendNew&lt;SlotBaseValue&gt;(proc, Origin(), proc.addStackSlot(sizeof(int)));
</ins><span class="cx"> 
</span><span class="cx">     root-&gt;appendNew&lt;MemoryValue&gt;(
</span><span class="cx">         proc, Store, Origin(),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLB3Outputcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -81,8 +81,7 @@
</span><span class="cx"> 
</span><span class="cx"> SlotBaseValue* Output::lockedStackSlot(size_t bytes)
</span><span class="cx"> {
</span><del>-    return m_block-&gt;appendNew&lt;SlotBaseValue&gt;(
-        m_proc, origin(), m_proc.addStackSlot(bytes, StackSlotKind::Locked));
</del><ins>+    return m_block-&gt;appendNew&lt;SlotBaseValue&gt;(m_proc, origin(), m_proc.addStackSlot(bytes));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LValue Output::neg(LValue value)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -5961,8 +5961,8 @@
</span><span class="cx"> 
</span><span class="cx">         // Set some obvious things.
</span><span class="cx">         patchpoint-&gt;effects.terminal = false;
</span><del>-        patchpoint-&gt;effects.writesSSAState = false;
-        patchpoint-&gt;effects.readsSSAState = false;
</del><ins>+        patchpoint-&gt;effects.writesLocalState = false;
+        patchpoint-&gt;effects.readsLocalState = false;
</ins><span class="cx">         
</span><span class="cx">         // This is how we tell B3 about the possibility of jump replacement.
</span><span class="cx">         patchpoint-&gt;effects.exitsSideways = true;
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/ChangeLog (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/ChangeLog        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Websites/webkit.org/ChangeLog        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-02-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Get rid of anonymous stack slots
+        https://bugs.webkit.org/show_bug.cgi?id=151128
+
+        Reviewed by Mark Lam.
+
+        This changes the documentation to account for the addition of Variables and the Get and Set
+        opcodes, and the removal of anonymous stack slots from B3 IR.
+
+        * docs/b3/intermediate-representation.html:
+
</ins><span class="cx"> 2016-02-02  Dan Bernstein  &lt;mitz@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Tagline in B3 docs should match the rest of the website
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/intermediate-representation.html (196031 => 196032)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-02-02 22:34:45 UTC (rev 196031)
+++ trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-02-02 23:21:12 UTC (rev 196032)
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">       for the load.  We use the MemoryValue class for memory-accessing values, which all have
</span><span class="cx">       such an offset.&lt;/p&gt;
</span><span class="cx"> 
</span><del>-    &lt;h2&gt;Stack Slot&lt;/h2&gt;
</del><ins>+    &lt;h2&gt;Stack Slots&lt;/h2&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;p&gt;B3 exposes the concept of stack-allocated data and gives the client a lot of control.
</span><span class="cx">       By default, stack slots get allocated wherever B3 chooses. It will try to pack them as
</span><span class="lines">@@ -99,25 +99,24 @@
</span><span class="cx">       for callee-saves.  Therefore, we recommend not using the frame pointer offset forcing
</span><span class="cx">       feature unless you know a lot about the ABI and you have no other choice.&lt;/p&gt;
</span><span class="cx"> 
</span><del>-    &lt;p&gt;Stack slots are also used for creating non-SSA variables with the intention of having B3
-      convert them into SSA.  There are two kinds of stack slots.&lt;/p&gt;
</del><ins>+    &lt;h2&gt;Variables&lt;/h2&gt;
</ins><span class="cx"> 
</span><del>-    &lt;dl&gt;
-      &lt;dt&gt;Anonymous&lt;/dt&gt;
-      &lt;dd&gt;Anonymous stack slots are used to represent local variables that aren't in SSA form.
-        B3 is allowed to assume that nobody will store to an anonymous stack slot except through
-        Store instructions in the B3 procedure.  B3 is allowed to assume that a Store that does
-        not write to the entire anonymous stack slot leaves the unwritten part in an undefined
-        state.  Usually, anonymous stack slots are allocated to have the same size as the type
-        of variable they are being used to represent.&lt;/dd&gt;
</del><ins>+    &lt;p&gt;Sometimes, SSA is inconvenient. For example, it's hard to do path specialization over SSA.
+      B3 has the concept of Variables as a fall-back. The backend knows how to handle them and
+      will coalesce and copy-propagate them. Inside the B3 optimizer, there is a classic SSA
+      builder that eliminates variables and builds SSA in their place.&lt;/p&gt;
</ins><span class="cx"> 
</span><del>-      &lt;dt&gt;Locked&lt;/dt&gt;
-      &lt;dd&gt;These stack slots are assumed to operate &quot;as if&quot; they were in the heap, in the sense
-        that the may get read or written using operations not visible in B3 IR.&lt;/dd&gt;
-    &lt;/dl&gt;
</del><ins>+    &lt;p&gt;You can create Variables by using Procedure::addVariable(), and then you can access them
+      using the Get and Set opcodes.&lt;/p&gt;
</ins><span class="cx"> 
</span><del>-    &lt;p&gt;The fixSSA() phase will convert anonymous stack slots to SSA.&lt;/p&gt;
</del><ins>+    &lt;p&gt;The fixSSA() phase will convert variables to SSA. If you use a lot of variables in your
+      input to B3, it's a good idea to run fixSSA() manually before running the compiler. The
+      default optimizer only runs fixSSA() towards the middle of optimizations. Passing non-SSA code
+      as input to the optimizer may render the early phases ineffective. Fortunately, B3 phases
+      are super easy to run. The following runs SSA fix-up on a Procedure named &quot;proc&quot;:&lt;/p&gt;
</ins><span class="cx"> 
</span><ins>+    &lt;pre&gt;&lt;code&gt;fixSSA(proc);&lt;/code&gt;&lt;/pre&gt;
+
</ins><span class="cx">     &lt;h2&gt;Control flow&lt;/h2&gt;
</span><span class="cx"> 
</span><span class="cx">     &lt;p&gt;B3 represents control flow using basic blocks.  Each basic block may have zero or more
</span><span class="lines">@@ -176,6 +175,13 @@
</span><span class="cx">       &lt;dt&gt;Double ConstDouble(constant)&lt;/dt&gt;
</span><span class="cx">       &lt;dd&gt;Double constant.  Must use the ConstDoubleValue class, which has space for the double constant.&lt;/dd&gt;
</span><span class="cx"> 
</span><ins>+      &lt;dt&gt;Void Set(value, variable)&lt;/dt&gt;
+      &lt;dd&gt;Assigns the given value to the given Variable. Must use the VariableValue class.&lt;/dd&gt;
+
+      &lt;dt&gt;T Get(variable)&lt;/dt&gt;
+      &lt;dd&gt;Returns the current value of the given Variable. Its return type depends on the
+        variable. Must use the VariableValue class.&lt;/dd&gt;
+
</ins><span class="cx">       &lt;dt&gt;IntPtr SlotBase(stackSlot)&lt;/dt&gt;
</span><span class="cx">       &lt;dd&gt;Returns a pointer to the base of the given stack slot.  Must use the SlotBaseValue
</span><span class="cx">         class.&lt;/dd&gt;
</span></span></pre>
</div>
</div>

</body>
</html>