<!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>[173993] 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/173993">173993</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-09-25 20:59:33 -0700 (Thu, 25 Sep 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>FTL should sink object allocations
https://bugs.webkit.org/show_bug.cgi?id=136330

Reviewed by Oliver Hunt.
Source/JavaScriptCore:

        
This adds a comprehensive infrastructure for sinking object allocations in DFG SSA form. The
ultimate goal of sinking is to sink an allocation &quot;past the points of its death&quot; - i.e. to
eliminate it completely. The way sinking reasons about the CFG means that it resembles a
partial escape analysis: we create paths through a function where some allocation(s) don't
have to be done at all even if there are other paths along which those allocations still have
to happen. But it also produces other side benefits. Even if an allocation isn't eliminated
along any path, the act of sinking reduces the number of barriers that have to execute.
        
Because this was a fairly ambituous SSA analysis and transformation, I added a bunch of C++11
sugar to the DFG's internal APIs to allow for easier iteration over blocks, nodes, and
successors; and to add more functor goodness to allow for more lambdas.
        
This is just the beginning. The bug has a bunch of other bugs that depend on it. So far this
is a spectacular speed-up on microbenchmarks but it's still too limited to affect big
benchmarks. For example, doing o == p makes the sinking phase think that o and p escape.
That's just an omission and there are likely others; we can easily fix them. I think it's
best to land it in its current form and then to worry about the big benchmarks in subsequent
work (see bug 137126).

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/StructureSet.h:
(JSC::StructureSet::iterator::iterator):
(JSC::StructureSet::iterator::operator*):
(JSC::StructureSet::iterator::operator++):
(JSC::StructureSet::iterator::operator==):
(JSC::StructureSet::iterator::operator!=):
(JSC::StructureSet::begin):
(JSC::StructureSet::end):
* dfg/DFGAbstractInterpreter.h:
(JSC::DFG::AbstractInterpreter::phiChildren):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::AbstractInterpreter):
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::startExecuting):
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::execute):
* dfg/DFGAvailability.h:
(JSC::DFG::Availability::shouldUseNode):
(JSC::DFG::Availability::isFlushUseful):
(JSC::DFG::Availability::isDead):
(JSC::DFG::Availability::operator!=):
* dfg/DFGAvailabilityMap.cpp: Added.
(JSC::DFG::AvailabilityMap::prune):
(JSC::DFG::AvailabilityMap::clear):
(JSC::DFG::AvailabilityMap::dump):
(JSC::DFG::AvailabilityMap::operator==):
(JSC::DFG::AvailabilityMap::merge):
* dfg/DFGAvailabilityMap.h: Added.
(JSC::DFG::AvailabilityMap::forEachAvailability):
* dfg/DFGBasicBlock.cpp:
(JSC::DFG::BasicBlock::SSAData::SSAData):
* dfg/DFGBasicBlock.h:
(JSC::DFG::BasicBlock::begin):
(JSC::DFG::BasicBlock::end):
(JSC::DFG::BasicBlock::SuccessorsIterable::SuccessorsIterable):
(JSC::DFG::BasicBlock::SuccessorsIterable::iterator::iterator):
(JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator*):
(JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator++):
(JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator==):
(JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator!=):
(JSC::DFG::BasicBlock::SuccessorsIterable::begin):
(JSC::DFG::BasicBlock::SuccessorsIterable::end):
(JSC::DFG::BasicBlock::successors):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGFlushedAt.cpp:
(JSC::DFG::FlushedAt::dump):
* dfg/DFGFlushedAt.h:
(JSC::DFG::FlushedAt::FlushedAt):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dumpBlockHeader):
(JSC::DFG::Graph::mergeRelevantToOSR):
(JSC::DFG::Graph::invalidateCFG):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::NaturalBlockIterable::NaturalBlockIterable):
(JSC::DFG::Graph::NaturalBlockIterable::iterator::iterator):
(JSC::DFG::Graph::NaturalBlockIterable::iterator::operator*):
(JSC::DFG::Graph::NaturalBlockIterable::iterator::operator++):
(JSC::DFG::Graph::NaturalBlockIterable::iterator::operator==):
(JSC::DFG::Graph::NaturalBlockIterable::iterator::operator!=):
(JSC::DFG::Graph::NaturalBlockIterable::iterator::findNext):
(JSC::DFG::Graph::NaturalBlockIterable::begin):
(JSC::DFG::Graph::NaturalBlockIterable::end):
(JSC::DFG::Graph::blocksInNaturalOrder):
(JSC::DFG::Graph::doToChildrenWithNode):
(JSC::DFG::Graph::doToChildren):
* dfg/DFGHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGHeapLocation.h:
* dfg/DFGInsertOSRHintsForUpdate.cpp: Added.
(JSC::DFG::insertOSRHintsForUpdate):
* dfg/DFGInsertOSRHintsForUpdate.h: Added.
* dfg/DFGInsertionSet.h:
(JSC::DFG::InsertionSet::graph):
* dfg/DFGMayExit.cpp:
(JSC::DFG::mayExit):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToPutByOffsetHint):
(JSC::DFG::Node::convertToPutStructureHint):
(JSC::DFG::Node::convertToPhantomNewObject):
(JSC::DFG::Node::isCellConstant):
(JSC::DFG::Node::castConstant):
(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::hasStorageAccessData):
(JSC::DFG::Node::hasObjectMaterializationData):
(JSC::DFG::Node::objectMaterializationData):
(JSC::DFG::Node::isPhantomObjectAllocation):
* dfg/DFGNodeType.h:
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
(JSC::DFG::LocalOSRAvailabilityCalculator::endBlock):
(JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
* dfg/DFGOSRAvailabilityAnalysisPhase.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp: Added.
(JSC::DFG::ObjectAllocationSinkingPhase::ObjectAllocationSinkingPhase):
(JSC::DFG::ObjectAllocationSinkingPhase::run):
(JSC::DFG::ObjectAllocationSinkingPhase::performSinking):
(JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
(JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
(JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
(JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
(JSC::DFG::ObjectAllocationSinkingPhase::resolve):
(JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
(JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
(JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
(JSC::DFG::performObjectAllocationSinking):
* dfg/DFGObjectAllocationSinkingPhase.h: Added.
* dfg/DFGObjectMaterializationData.cpp: Added.
(JSC::DFG::PhantomPropertyValue::dump):
(JSC::DFG::ObjectMaterializationData::dump):
(JSC::DFG::ObjectMaterializationData::oneWaySimilarityScore):
(JSC::DFG::ObjectMaterializationData::similarityScore):
* dfg/DFGObjectMaterializationData.h: Added.
(JSC::DFG::PhantomPropertyValue::PhantomPropertyValue):
(JSC::DFG::PhantomPropertyValue::operator==):
* dfg/DFGPhantomCanonicalizationPhase.cpp:
(JSC::DFG::PhantomCanonicalizationPhase::run):
* dfg/DFGPhantomRemovalPhase.cpp:
(JSC::DFG::PhantomRemovalPhase::run):
* dfg/DFGPhiChildren.cpp: Added.
(JSC::DFG::PhiChildren::PhiChildren):
(JSC::DFG::PhiChildren::~PhiChildren):
(JSC::DFG::PhiChildren::upsilonsOf):
* dfg/DFGPhiChildren.h: Added.
(JSC::DFG::PhiChildren::forAllIncomingValues):
(JSC::DFG::PhiChildren::forAllTransitiveIncomingValues):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPrePostNumbering.cpp: Added.
(JSC::DFG::PrePostNumbering::PrePostNumbering):
(JSC::DFG::PrePostNumbering::~PrePostNumbering):
(JSC::DFG::PrePostNumbering::compute):
(WTF::printInternal):
* dfg/DFGPrePostNumbering.h: Added.
(JSC::DFG::PrePostNumbering::preNumber):
(JSC::DFG::PrePostNumbering::postNumber):
(JSC::DFG::PrePostNumbering::isStrictAncestorOf):
(JSC::DFG::PrePostNumbering::isAncestorOf):
(JSC::DFG::PrePostNumbering::isStrictDescendantOf):
(JSC::DFG::PrePostNumbering::isDescendantOf):
(JSC::DFG::PrePostNumbering::edgeKind):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGPromoteHeapAccess.h: Added.
(JSC::DFG::promoteHeapAccess):
* dfg/DFGPromotedHeapLocation.cpp: Added.
(JSC::DFG::PromotedLocationDescriptor::dump):
(JSC::DFG::PromotedHeapLocation::createHint):
(JSC::DFG::PromotedHeapLocation::dump):
(WTF::printInternal):
* dfg/DFGPromotedHeapLocation.h: Added.
(JSC::DFG::PromotedLocationDescriptor::PromotedLocationDescriptor):
(JSC::DFG::PromotedLocationDescriptor::operator!):
(JSC::DFG::PromotedLocationDescriptor::kind):
(JSC::DFG::PromotedLocationDescriptor::info):
(JSC::DFG::PromotedLocationDescriptor::hash):
(JSC::DFG::PromotedLocationDescriptor::operator==):
(JSC::DFG::PromotedLocationDescriptor::operator!=):
(JSC::DFG::PromotedLocationDescriptor::isHashTableDeletedValue):
(JSC::DFG::PromotedHeapLocation::PromotedHeapLocation):
(JSC::DFG::PromotedHeapLocation::operator!):
(JSC::DFG::PromotedHeapLocation::kind):
(JSC::DFG::PromotedHeapLocation::base):
(JSC::DFG::PromotedHeapLocation::info):
(JSC::DFG::PromotedHeapLocation::descriptor):
(JSC::DFG::PromotedHeapLocation::hash):
(JSC::DFG::PromotedHeapLocation::operator==):
(JSC::DFG::PromotedHeapLocation::isHashTableDeletedValue):
(JSC::DFG::PromotedHeapLocationHash::hash):
(JSC::DFG::PromotedHeapLocationHash::equal):
* dfg/DFGSSACalculator.cpp:
(JSC::DFG::SSACalculator::reset):
* dfg/DFGSSACalculator.h:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCurrentBlock):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStructureRegistrationPhase.cpp:
(JSC::DFG::StructureRegistrationPhase::run):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLExitPropertyValue.cpp: Added.
(JSC::FTL::ExitPropertyValue::dump):
* ftl/FTLExitPropertyValue.h: Added.
(JSC::FTL::ExitPropertyValue::ExitPropertyValue):
(JSC::FTL::ExitPropertyValue::operator!):
(JSC::FTL::ExitPropertyValue::location):
(JSC::FTL::ExitPropertyValue::value):
* ftl/FTLExitTimeObjectMaterialization.cpp: Added.
(JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
(JSC::FTL::ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization):
(JSC::FTL::ExitTimeObjectMaterialization::add):
(JSC::FTL::ExitTimeObjectMaterialization::get):
(JSC::FTL::ExitTimeObjectMaterialization::dump):
* ftl/FTLExitTimeObjectMaterialization.h: Added.
(JSC::FTL::ExitTimeObjectMaterialization::type):
(JSC::FTL::ExitTimeObjectMaterialization::properties):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::materializeNewObject):
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::isObjectMaterialization):
(JSC::FTL::ExitValue::objectMaterialization):
(JSC::FTL::ExitValue::withVirtualRegister):
(JSC::FTL::ExitValue::valueFormat):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
(JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
(JSC::FTL::LowerDFGToLLVM::compilePutStructure):
(JSC::FTL::LowerDFGToLLVM::compileNewObject):
(JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
(JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
(JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
(JSC::FTL::LowerDFGToLLVM::compileCheckStructureImmediate):
(JSC::FTL::LowerDFGToLLVM::compileMaterializeNewObject):
(JSC::FTL::LowerDFGToLLVM::checkStructure):
(JSC::FTL::LowerDFGToLLVM::allocateCell):
(JSC::FTL::LowerDFGToLLVM::storeStructure):
(JSC::FTL::LowerDFGToLLVM::allocateObject):
(JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
(JSC::FTL::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
(JSC::FTL::LowerDFGToLLVM::exitValueForNode):
(JSC::FTL::LowerDFGToLLVM::weakStructureID):
(JSC::FTL::LowerDFGToLLVM::weakStructure):
(JSC::FTL::LowerDFGToLLVM::availabilityMap):
(JSC::FTL::LowerDFGToLLVM::availability): Deleted.
* ftl/FTLOSRExit.h:
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileRecovery):
(JSC::FTL::compileStub):
* ftl/FTLOperations.cpp: Added.
(JSC::FTL::operationNewObjectWithButterfly):
(JSC::FTL::operationMaterializeObjectInOSR):
* ftl/FTLOperations.h: Added.
* ftl/FTLSwitchCase.h:
(JSC::FTL::SwitchCase::SwitchCase):
* runtime/JSObject.h:
(JSC::JSObject::finishCreation):
(JSC::JSFinalObject::JSFinalObject):
(JSC::JSFinalObject::create):
* runtime/Structure.cpp:
(JSC::Structure::canUseForAllocationsOf):
* runtime/Structure.h:
* tests/stress/elidable-new-object-roflcopter-then-exit.js: Added.
(sumOfArithSeries):
(foo):
* tests/stress/elide-new-object-dag-then-exit.js: Added.
(sumOfArithSeries):
(bar):
(verify):
(foo):
* tests/stress/obviously-elidable-new-object-then-exit.js: Added.
(sumOfArithSeries):
(foo):

Source/WTF:

        
Make it possible to reset a Bag.

* wtf/Bag.h:
(WTF::Bag::Bag):
(WTF::Bag::~Bag):
(WTF::Bag::clear):

LayoutTests:


* js/math-denorm.html: Added.
* js/regress/elidable-new-object-dag-expected.txt: Added.
* js/regress/elidable-new-object-dag.html: Added.
* js/regress/elidable-new-object-roflcopter-expected.txt: Added.
* js/regress/elidable-new-object-roflcopter.html: Added.
* js/regress/elidable-new-object-tree-expected.txt: Added.
* js/regress/elidable-new-object-tree.html: Added.
* js/regress/obvious-sink-pathology-expected.txt: Added.
* js/regress/obvious-sink-pathology-taken-expected.txt: Added.
* js/regress/obvious-sink-pathology-taken.html: Added.
* js/regress/obvious-sink-pathology.html: Added.
* js/regress/obviously-elidable-new-object-expected.txt: Added.
* js/regress/obviously-elidable-new-object.html: Added.
* js/regress/script-tests/elidable-new-object-dag.js: Added.
(sumOfArithSeries):
(foo):
* js/regress/script-tests/elidable-new-object-roflcopter.js: Added.
(sumOfArithSeries):
(foo):
* js/regress/script-tests/elidable-new-object-tree.js: Added.
(sumOfArithSeries):
(foo):
* js/regress/script-tests/obvious-sink-pathology-taken.js: Added.
(sumOfArithSeries):
(bar):
(foo):
* js/regress/script-tests/obvious-sink-pathology.js: Added.
(sumOfArithSeries):
(bar):
(foo):
* js/regress/script-tests/obviously-elidable-new-object.js: Added.
(sumOfArithSeries):
(foo):
* js/regress/script-tests/sinkable-new-object-dag.js: Added.
(sumOfArithSeries):
(verify):
(foo):
* js/regress/script-tests/sinkable-new-object-taken.js: Added.
(sumOfArithSeries):
(bar):
(foo):
* js/regress/script-tests/sinkable-new-object.js: Added.
(sumOfArithSeries):
(bar):
(foo):
* js/regress/sinkable-new-object-dag-expected.txt: Added.
* js/regress/sinkable-new-object-dag.html: Added.
* js/regress/sinkable-new-object-expected.txt: Added.
* js/regress/sinkable-new-object-taken-expected.txt: Added.
* js/regress/sinkable-new-object-taken.html: Added.
* js/regress/sinkable-new-object.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureSeth">trunk/Source/JavaScriptCore/bytecode/StructureSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAvailabilityh">trunk/Source/JavaScriptCore/dfg/DFGAvailability.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockcpp">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockh">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFlushedAtcpp">trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFlushedAth">trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGHeapLocationcpp">trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGHeapLocationh">trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGInsertionSeth">trunk/Source/JavaScriptCore/dfg/DFGInsertionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGMayExitcpp">trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhaseh">trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomCanonicalizationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSSACalculatorcpp">trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSSACalculatorh">trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGValidatecpp">trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExitValuecpp">trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExitValueh">trunk/Source/JavaScriptCore/ftl/FTLExitValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExith">trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLSwitchCaseh">trunk/Source/JavaScriptCore/ftl/FTLSwitchCase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructurecpp">trunk/Source/JavaScriptCore/runtime/Structure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureh">trunk/Source/JavaScriptCore/runtime/Structure.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfBagh">trunk/Source/WTF/wtf/Bag.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsmathdenormhtml">trunk/LayoutTests/js/math-denorm.html</a></li>
<li><a href="#trunkLayoutTestsjsregresselidablenewobjectdagexpectedtxt">trunk/LayoutTests/js/regress/elidable-new-object-dag-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresselidablenewobjectdaghtml">trunk/LayoutTests/js/regress/elidable-new-object-dag.html</a></li>
<li><a href="#trunkLayoutTestsjsregresselidablenewobjectroflcopterexpectedtxt">trunk/LayoutTests/js/regress/elidable-new-object-roflcopter-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresselidablenewobjectroflcopterhtml">trunk/LayoutTests/js/regress/elidable-new-object-roflcopter.html</a></li>
<li><a href="#trunkLayoutTestsjsregresselidablenewobjecttreeexpectedtxt">trunk/LayoutTests/js/regress/elidable-new-object-tree-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresselidablenewobjecttreehtml">trunk/LayoutTests/js/regress/elidable-new-object-tree.html</a></li>
<li><a href="#trunkLayoutTestsjsregressobvioussinkpathologyexpectedtxt">trunk/LayoutTests/js/regress/obvious-sink-pathology-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressobvioussinkpathologytakenexpectedtxt">trunk/LayoutTests/js/regress/obvious-sink-pathology-taken-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressobvioussinkpathologytakenhtml">trunk/LayoutTests/js/regress/obvious-sink-pathology-taken.html</a></li>
<li><a href="#trunkLayoutTestsjsregressobvioussinkpathologyhtml">trunk/LayoutTests/js/regress/obvious-sink-pathology.html</a></li>
<li><a href="#trunkLayoutTestsjsregressobviouslyelidablenewobjectexpectedtxt">trunk/LayoutTests/js/regress/obviously-elidable-new-object-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressobviouslyelidablenewobjecthtml">trunk/LayoutTests/js/regress/obviously-elidable-new-object.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestselidablenewobjectdagjs">trunk/LayoutTests/js/regress/script-tests/elidable-new-object-dag.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestselidablenewobjectroflcopterjs">trunk/LayoutTests/js/regress/script-tests/elidable-new-object-roflcopter.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestselidablenewobjecttreejs">trunk/LayoutTests/js/regress/script-tests/elidable-new-object-tree.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsobvioussinkpathologytakenjs">trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology-taken.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsobvioussinkpathologyjs">trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsobviouslyelidablenewobjectjs">trunk/LayoutTests/js/regress/script-tests/obviously-elidable-new-object.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssinkablenewobjectdagjs">trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-dag.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssinkablenewobjecttakenjs">trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-taken.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssinkablenewobjectjs">trunk/LayoutTests/js/regress/script-tests/sinkable-new-object.js</a></li>
<li><a href="#trunkLayoutTestsjsregresssinkablenewobjectdagexpectedtxt">trunk/LayoutTests/js/regress/sinkable-new-object-dag-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssinkablenewobjectdaghtml">trunk/LayoutTests/js/regress/sinkable-new-object-dag.html</a></li>
<li><a href="#trunkLayoutTestsjsregresssinkablenewobjectexpectedtxt">trunk/LayoutTests/js/regress/sinkable-new-object-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssinkablenewobjecttakenexpectedtxt">trunk/LayoutTests/js/regress/sinkable-new-object-taken-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssinkablenewobjecttakenhtml">trunk/LayoutTests/js/regress/sinkable-new-object-taken.html</a></li>
<li><a href="#trunkLayoutTestsjsregresssinkablenewobjecthtml">trunk/LayoutTests/js/regress/sinkable-new-object.html</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAvailabilityMapcpp">trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAvailabilityMaph">trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGInsertOSRHintsForUpdatecpp">trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGInsertOSRHintsForUpdateh">trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhaseh">trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectMaterializationDatacpp">trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectMaterializationDatah">trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhiChildrencpp">trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhiChildrenh">trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPrePostNumberingcpp">trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPrePostNumberingh">trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPromoteHeapAccessh">trunk/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPromotedHeapLocationcpp">trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPromotedHeapLocationh">trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExitPropertyValuecpp">trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExitPropertyValueh">trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExitTimeObjectMaterializationcpp">trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExitTimeObjectMaterializationh">trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOperationscpp">trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOperationsh">trunk/Source/JavaScriptCore/ftl/FTLOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresselidablenewobjectroflcopterthenexitjs">trunk/Source/JavaScriptCore/tests/stress/elidable-new-object-roflcopter-then-exit.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresselidenewobjectdagthenexitjs">trunk/Source/JavaScriptCore/tests/stress/elide-new-object-dag-then-exit.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressobviouslyelidablenewobjectthenexitjs">trunk/Source/JavaScriptCore/tests/stress/obviously-elidable-new-object-then-exit.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/LayoutTests/ChangeLog        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2014-09-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL should sink object allocations
+        https://bugs.webkit.org/show_bug.cgi?id=136330
+
+        Reviewed by Oliver Hunt.
+
+        * js/math-denorm.html: Added.
+        * js/regress/elidable-new-object-dag-expected.txt: Added.
+        * js/regress/elidable-new-object-dag.html: Added.
+        * js/regress/elidable-new-object-roflcopter-expected.txt: Added.
+        * js/regress/elidable-new-object-roflcopter.html: Added.
+        * js/regress/elidable-new-object-tree-expected.txt: Added.
+        * js/regress/elidable-new-object-tree.html: Added.
+        * js/regress/obvious-sink-pathology-expected.txt: Added.
+        * js/regress/obvious-sink-pathology-taken-expected.txt: Added.
+        * js/regress/obvious-sink-pathology-taken.html: Added.
+        * js/regress/obvious-sink-pathology.html: Added.
+        * js/regress/obviously-elidable-new-object-expected.txt: Added.
+        * js/regress/obviously-elidable-new-object.html: Added.
+        * js/regress/script-tests/elidable-new-object-dag.js: Added.
+        (sumOfArithSeries):
+        (foo):
+        * js/regress/script-tests/elidable-new-object-roflcopter.js: Added.
+        (sumOfArithSeries):
+        (foo):
+        * js/regress/script-tests/elidable-new-object-tree.js: Added.
+        (sumOfArithSeries):
+        (foo):
+        * js/regress/script-tests/obvious-sink-pathology-taken.js: Added.
+        (sumOfArithSeries):
+        (bar):
+        (foo):
+        * js/regress/script-tests/obvious-sink-pathology.js: Added.
+        (sumOfArithSeries):
+        (bar):
+        (foo):
+        * js/regress/script-tests/obviously-elidable-new-object.js: Added.
+        (sumOfArithSeries):
+        (foo):
+        * js/regress/script-tests/sinkable-new-object-dag.js: Added.
+        (sumOfArithSeries):
+        (verify):
+        (foo):
+        * js/regress/script-tests/sinkable-new-object-taken.js: Added.
+        (sumOfArithSeries):
+        (bar):
+        (foo):
+        * js/regress/script-tests/sinkable-new-object.js: Added.
+        (sumOfArithSeries):
+        (bar):
+        (foo):
+        * js/regress/sinkable-new-object-dag-expected.txt: Added.
+        * js/regress/sinkable-new-object-dag.html: Added.
+        * js/regress/sinkable-new-object-expected.txt: Added.
+        * js/regress/sinkable-new-object-taken-expected.txt: Added.
+        * js/regress/sinkable-new-object-taken.html: Added.
+        * js/regress/sinkable-new-object.html: Added.
+
</ins><span class="cx"> 2014-09-25  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: FunctionCall timeline records omit profile data if the debugger has paused
</span></span></pre></div>
<a id="trunkLayoutTestsjsmathdenormhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/math-denorm.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/math-denorm.html                                (rev 0)
+++ trunk/LayoutTests/js/math-denorm.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;script-tests/math-denorm.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresselidablenewobjectdagexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/elidable-new-object-dag-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/elidable-new-object-dag-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/elidable-new-object-dag-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/elidable-new-object-dag
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresselidablenewobjectdaghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/elidable-new-object-dag.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/elidable-new-object-dag.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/elidable-new-object-dag.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/elidable-new-object-dag.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresselidablenewobjectroflcopterexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/elidable-new-object-roflcopter-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/elidable-new-object-roflcopter-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/elidable-new-object-roflcopter-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/elidable-new-object-roflcopter
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresselidablenewobjectroflcopterhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/elidable-new-object-roflcopter.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/elidable-new-object-roflcopter.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/elidable-new-object-roflcopter.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/elidable-new-object-roflcopter.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresselidablenewobjecttreeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/elidable-new-object-tree-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/elidable-new-object-tree-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/elidable-new-object-tree-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/elidable-new-object-tree
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresselidablenewobjecttreehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/elidable-new-object-tree.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/elidable-new-object-tree.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/elidable-new-object-tree.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/elidable-new-object-tree.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressobvioussinkpathologyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/obvious-sink-pathology-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/obvious-sink-pathology-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/obvious-sink-pathology-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/obvious-sink-pathology
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressobvioussinkpathologytakenexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/obvious-sink-pathology-taken-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/obvious-sink-pathology-taken-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/obvious-sink-pathology-taken-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/obvious-sink-pathology-taken
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressobvioussinkpathologytakenhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/obvious-sink-pathology-taken.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/obvious-sink-pathology-taken.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/obvious-sink-pathology-taken.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/obvious-sink-pathology-taken.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressobvioussinkpathologyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/obvious-sink-pathology.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/obvious-sink-pathology.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/obvious-sink-pathology.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/obvious-sink-pathology.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressobviouslyelidablenewobjectexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/obviously-elidable-new-object-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/obviously-elidable-new-object-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/obviously-elidable-new-object-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/obviously-elidable-new-object
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressobviouslyelidablenewobjecthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/obviously-elidable-new-object.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/obviously-elidable-new-object.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/obviously-elidable-new-object.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/obviously-elidable-new-object.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestselidablenewobjectdagjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/elidable-new-object-dag.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/elidable-new-object-dag.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/elidable-new-object-dag.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var leaf = {f:i};
+        var o = {f:leaf};
+        var p = {f:leaf};
+        var q = {f:o, g:p};
+        result += q.f.f.f;
+    }
+    return result;
+}
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestselidablenewobjectroflcopterjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/elidable-new-object-roflcopter.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/elidable-new-object-roflcopter.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/elidable-new-object-roflcopter.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 500000;
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: i}}}}}}}}}}}}}}}}}}};
+        var p = {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: i + 1}}}}}}}}}}}}}}}}}}};
+        result += o.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f + p.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f;
+    }
+    return result;
+}
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestselidablenewobjecttreejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/elidable-new-object-tree.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/elidable-new-object-tree.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/elidable-new-object-tree.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: {f:i}};
+        var p = {f: {f:i + 1}};
+        result += o.f.f + p.f.f;
+    }
+    return result;
+}
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsobvioussinkpathologytakenjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology-taken.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology-taken.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology-taken.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        if (!(i % 100))
+            bar(o, p);
+        result += o.f + p.f;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsobvioussinkpathologyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/obvious-sink-pathology.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function foo(b) {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        if (b)
+            bar(o, p);
+        result += o.f + p.f;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+var result = foo(false);
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsobviouslyelidablenewobjectjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/obviously-elidable-new-object.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/obviously-elidable-new-object.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/obviously-elidable-new-object.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        result += o.f + p.f;
+    }
+    return result;
+}
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssinkablenewobjectdagjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-dag.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-dag.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-dag.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function verify(q, i) {
+    if (q.f == q.g)
+        throw &quot;Error: q.f == q.g&quot;;
+    if (q.f.f != q.g.f)
+        throw &quot;Error: q.f.f != q.g.f&quot;;
+    if (q.f.f.f != i)
+        throw &quot;Error: q.f.f.f != i&quot;;
+}
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var leaf = {f:i};
+        var o = {f:leaf};
+        var p = {f:leaf};
+        var q = {f:o, g:p};
+        result += q.f.f.f;
+        if (!(i % 100))
+            verify(q, i);
+    }
+    return result;
+}
+
+noInline(foo);
+noInline(verify);
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssinkablenewobjecttakenjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-taken.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-taken.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/sinkable-new-object-taken.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        result += o.f + p.f;
+        if (!(i % 100))
+            bar(o, p);
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssinkablenewobjectjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/sinkable-new-object.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/sinkable-new-object.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/sinkable-new-object.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function foo(b) {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        if (b) {
+            bar(o, p);
+            return;
+        }
+        result += o.f + p.f;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+var result = foo(false);
+if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssinkablenewobjectdagexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/sinkable-new-object-dag-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/sinkable-new-object-dag-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/sinkable-new-object-dag-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/sinkable-new-object-dag
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssinkablenewobjectdaghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/sinkable-new-object-dag.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/sinkable-new-object-dag.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/sinkable-new-object-dag.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/sinkable-new-object-dag.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssinkablenewobjectexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/sinkable-new-object-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/sinkable-new-object-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/sinkable-new-object-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/sinkable-new-object
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssinkablenewobjecttakenexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/sinkable-new-object-taken-expected.txt (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/sinkable-new-object-taken-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/sinkable-new-object-taken-expected.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/sinkable-new-object-taken
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssinkablenewobjecttakenhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/sinkable-new-object-taken.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/sinkable-new-object-taken.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/sinkable-new-object-taken.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/sinkable-new-object-taken.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssinkablenewobjecthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/sinkable-new-object.html (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/sinkable-new-object.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/sinkable-new-object.html        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/sinkable-new-object.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -122,6 +122,7 @@
</span><span class="cx">     dfg/DFGArrayMode.cpp
</span><span class="cx">     dfg/DFGAtTailAbstractState.cpp
</span><span class="cx">     dfg/DFGAvailability.cpp
</span><ins>+    dfg/DFGAvailabilityMap.cpp
</ins><span class="cx">     dfg/DFGBackwardsPropagationPhase.cpp
</span><span class="cx">     dfg/DFGBasicBlock.cpp
</span><span class="cx">     dfg/DFGBinarySwitch.cpp
</span><span class="lines">@@ -164,6 +165,7 @@
</span><span class="cx">     dfg/DFGGraphSafepoint.cpp
</span><span class="cx">     dfg/DFGHeapLocation.cpp
</span><span class="cx">     dfg/DFGInPlaceAbstractState.cpp
</span><ins>+    dfg/DFGInsertOSRHintsForUpdate.cpp
</ins><span class="cx">     dfg/DFGIntegerCheckCombiningPhase.cpp
</span><span class="cx">     dfg/DFGInvalidationPointInjectionPhase.cpp
</span><span class="cx">     dfg/DFGJITCode.cpp
</span><span class="lines">@@ -192,13 +194,18 @@
</span><span class="cx">     dfg/DFGOSRExitCompilerCommon.cpp
</span><span class="cx">     dfg/DFGOSRExitJumpPlaceholder.cpp
</span><span class="cx">     dfg/DFGOSRExitPreparation.cpp
</span><ins>+    dfg/DFGObjectAllocationSinkingPhase.cpp
+    dfg/DFGObjectMaterializationData.cpp
</ins><span class="cx">     dfg/DFGOperations.cpp
</span><span class="cx">     dfg/DFGPhantomCanonicalizationPhase.cpp
</span><span class="cx">     dfg/DFGPhantomRemovalPhase.cpp
</span><span class="cx">     dfg/DFGPhase.cpp
</span><ins>+    dfg/DFGPhiChildren.cpp
</ins><span class="cx">     dfg/DFGPlan.cpp
</span><ins>+    dfg/DFGPrePostNumbering.cpp
</ins><span class="cx">     dfg/DFGPredictionInjectionPhase.cpp
</span><span class="cx">     dfg/DFGPredictionPropagationPhase.cpp
</span><ins>+    dfg/DFGPromotedHeapLocation.cpp
</ins><span class="cx">     dfg/DFGPureValue.cpp
</span><span class="cx">     dfg/DFGResurrectionForValidationPhase.cpp
</span><span class="cx">     dfg/DFGSSACalculator.cpp
</span><span class="lines">@@ -774,7 +781,9 @@
</span><span class="cx">         ftl/FTLDataSection.cpp
</span><span class="cx">         ftl/FTLExitArgument.cpp
</span><span class="cx">         ftl/FTLExitArgumentForOperand.cpp
</span><ins>+        ftl/FTLExitPropertyValue.cpp
</ins><span class="cx">         ftl/FTLExitThunkGenerator.cpp
</span><ins>+        ftl/FTLExitTimeObjectMaterialization.cpp
</ins><span class="cx">         ftl/FTLExitValue.cpp
</span><span class="cx">         ftl/FTLFail.cpp
</span><span class="cx">         ftl/FTLForOSREntryJITCode.cpp
</span><span class="lines">@@ -789,6 +798,7 @@
</span><span class="cx">         ftl/FTLOSREntry.cpp
</span><span class="cx">         ftl/FTLOSRExitCompiler.cpp
</span><span class="cx">         ftl/FTLOSRExit.cpp
</span><ins>+        ftl/FTLOperations.cpp
</ins><span class="cx">         ftl/FTLOutput.cpp
</span><span class="cx">         ftl/FTLRecoveryOpcode.cpp
</span><span class="cx">         ftl/FTLRegisterAtOffset.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1,3 +1,302 @@
</span><ins>+2014-09-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL should sink object allocations
+        https://bugs.webkit.org/show_bug.cgi?id=136330
+
+        Reviewed by Oliver Hunt.
+        
+        This adds a comprehensive infrastructure for sinking object allocations in DFG SSA form. The
+        ultimate goal of sinking is to sink an allocation &quot;past the points of its death&quot; - i.e. to
+        eliminate it completely. The way sinking reasons about the CFG means that it resembles a
+        partial escape analysis: we create paths through a function where some allocation(s) don't
+        have to be done at all even if there are other paths along which those allocations still have
+        to happen. But it also produces other side benefits. Even if an allocation isn't eliminated
+        along any path, the act of sinking reduces the number of barriers that have to execute.
+        
+        Because this was a fairly ambituous SSA analysis and transformation, I added a bunch of C++11
+        sugar to the DFG's internal APIs to allow for easier iteration over blocks, nodes, and
+        successors; and to add more functor goodness to allow for more lambdas.
+        
+        This is just the beginning. The bug has a bunch of other bugs that depend on it. So far this
+        is a spectacular speed-up on microbenchmarks but it's still too limited to affect big
+        benchmarks. For example, doing o == p makes the sinking phase think that o and p escape.
+        That's just an omission and there are likely others; we can easily fix them. I think it's
+        best to land it in its current form and then to worry about the big benchmarks in subsequent
+        work (see bug 137126).
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/StructureSet.h:
+        (JSC::StructureSet::iterator::iterator):
+        (JSC::StructureSet::iterator::operator*):
+        (JSC::StructureSet::iterator::operator++):
+        (JSC::StructureSet::iterator::operator==):
+        (JSC::StructureSet::iterator::operator!=):
+        (JSC::StructureSet::begin):
+        (JSC::StructureSet::end):
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::phiChildren):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::AbstractInterpreter):
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::startExecuting):
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::execute):
+        * dfg/DFGAvailability.h:
+        (JSC::DFG::Availability::shouldUseNode):
+        (JSC::DFG::Availability::isFlushUseful):
+        (JSC::DFG::Availability::isDead):
+        (JSC::DFG::Availability::operator!=):
+        * dfg/DFGAvailabilityMap.cpp: Added.
+        (JSC::DFG::AvailabilityMap::prune):
+        (JSC::DFG::AvailabilityMap::clear):
+        (JSC::DFG::AvailabilityMap::dump):
+        (JSC::DFG::AvailabilityMap::operator==):
+        (JSC::DFG::AvailabilityMap::merge):
+        * dfg/DFGAvailabilityMap.h: Added.
+        (JSC::DFG::AvailabilityMap::forEachAvailability):
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::SSAData::SSAData):
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::begin):
+        (JSC::DFG::BasicBlock::end):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::SuccessorsIterable):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::iterator):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator*):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator++):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator==):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator!=):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::begin):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::end):
+        (JSC::DFG::BasicBlock::successors):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFlushedAt.cpp:
+        (JSC::DFG::FlushedAt::dump):
+        * dfg/DFGFlushedAt.h:
+        (JSC::DFG::FlushedAt::FlushedAt):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::dumpBlockHeader):
+        (JSC::DFG::Graph::mergeRelevantToOSR):
+        (JSC::DFG::Graph::invalidateCFG):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::NaturalBlockIterable::NaturalBlockIterable):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::iterator):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator*):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator++):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator==):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator!=):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::findNext):
+        (JSC::DFG::Graph::NaturalBlockIterable::begin):
+        (JSC::DFG::Graph::NaturalBlockIterable::end):
+        (JSC::DFG::Graph::blocksInNaturalOrder):
+        (JSC::DFG::Graph::doToChildrenWithNode):
+        (JSC::DFG::Graph::doToChildren):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGInsertOSRHintsForUpdate.cpp: Added.
+        (JSC::DFG::insertOSRHintsForUpdate):
+        * dfg/DFGInsertOSRHintsForUpdate.h: Added.
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::graph):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPutByOffsetHint):
+        (JSC::DFG::Node::convertToPutStructureHint):
+        (JSC::DFG::Node::convertToPhantomNewObject):
+        (JSC::DFG::Node::isCellConstant):
+        (JSC::DFG::Node::castConstant):
+        (JSC::DFG::Node::hasIdentifier):
+        (JSC::DFG::Node::hasStorageAccessData):
+        (JSC::DFG::Node::hasObjectMaterializationData):
+        (JSC::DFG::Node::objectMaterializationData):
+        (JSC::DFG::Node::isPhantomObjectAllocation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::endBlock):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGOSRAvailabilityAnalysisPhase.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp: Added.
+        (JSC::DFG::ObjectAllocationSinkingPhase::ObjectAllocationSinkingPhase):
+        (JSC::DFG::ObjectAllocationSinkingPhase::run):
+        (JSC::DFG::ObjectAllocationSinkingPhase::performSinking):
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        (JSC::DFG::ObjectAllocationSinkingPhase::resolve):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
+        (JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
+        (JSC::DFG::performObjectAllocationSinking):
+        * dfg/DFGObjectAllocationSinkingPhase.h: Added.
+        * dfg/DFGObjectMaterializationData.cpp: Added.
+        (JSC::DFG::PhantomPropertyValue::dump):
+        (JSC::DFG::ObjectMaterializationData::dump):
+        (JSC::DFG::ObjectMaterializationData::oneWaySimilarityScore):
+        (JSC::DFG::ObjectMaterializationData::similarityScore):
+        * dfg/DFGObjectMaterializationData.h: Added.
+        (JSC::DFG::PhantomPropertyValue::PhantomPropertyValue):
+        (JSC::DFG::PhantomPropertyValue::operator==):
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPhiChildren.cpp: Added.
+        (JSC::DFG::PhiChildren::PhiChildren):
+        (JSC::DFG::PhiChildren::~PhiChildren):
+        (JSC::DFG::PhiChildren::upsilonsOf):
+        * dfg/DFGPhiChildren.h: Added.
+        (JSC::DFG::PhiChildren::forAllIncomingValues):
+        (JSC::DFG::PhiChildren::forAllTransitiveIncomingValues):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPrePostNumbering.cpp: Added.
+        (JSC::DFG::PrePostNumbering::PrePostNumbering):
+        (JSC::DFG::PrePostNumbering::~PrePostNumbering):
+        (JSC::DFG::PrePostNumbering::compute):
+        (WTF::printInternal):
+        * dfg/DFGPrePostNumbering.h: Added.
+        (JSC::DFG::PrePostNumbering::preNumber):
+        (JSC::DFG::PrePostNumbering::postNumber):
+        (JSC::DFG::PrePostNumbering::isStrictAncestorOf):
+        (JSC::DFG::PrePostNumbering::isAncestorOf):
+        (JSC::DFG::PrePostNumbering::isStrictDescendantOf):
+        (JSC::DFG::PrePostNumbering::isDescendantOf):
+        (JSC::DFG::PrePostNumbering::edgeKind):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPromoteHeapAccess.h: Added.
+        (JSC::DFG::promoteHeapAccess):
+        * dfg/DFGPromotedHeapLocation.cpp: Added.
+        (JSC::DFG::PromotedLocationDescriptor::dump):
+        (JSC::DFG::PromotedHeapLocation::createHint):
+        (JSC::DFG::PromotedHeapLocation::dump):
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h: Added.
+        (JSC::DFG::PromotedLocationDescriptor::PromotedLocationDescriptor):
+        (JSC::DFG::PromotedLocationDescriptor::operator!):
+        (JSC::DFG::PromotedLocationDescriptor::kind):
+        (JSC::DFG::PromotedLocationDescriptor::info):
+        (JSC::DFG::PromotedLocationDescriptor::hash):
+        (JSC::DFG::PromotedLocationDescriptor::operator==):
+        (JSC::DFG::PromotedLocationDescriptor::operator!=):
+        (JSC::DFG::PromotedLocationDescriptor::isHashTableDeletedValue):
+        (JSC::DFG::PromotedHeapLocation::PromotedHeapLocation):
+        (JSC::DFG::PromotedHeapLocation::operator!):
+        (JSC::DFG::PromotedHeapLocation::kind):
+        (JSC::DFG::PromotedHeapLocation::base):
+        (JSC::DFG::PromotedHeapLocation::info):
+        (JSC::DFG::PromotedHeapLocation::descriptor):
+        (JSC::DFG::PromotedHeapLocation::hash):
+        (JSC::DFG::PromotedHeapLocation::operator==):
+        (JSC::DFG::PromotedHeapLocation::isHashTableDeletedValue):
+        (JSC::DFG::PromotedHeapLocationHash::hash):
+        (JSC::DFG::PromotedHeapLocationHash::equal):
+        * dfg/DFGSSACalculator.cpp:
+        (JSC::DFG::SSACalculator::reset):
+        * dfg/DFGSSACalculator.h:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLExitPropertyValue.cpp: Added.
+        (JSC::FTL::ExitPropertyValue::dump):
+        * ftl/FTLExitPropertyValue.h: Added.
+        (JSC::FTL::ExitPropertyValue::ExitPropertyValue):
+        (JSC::FTL::ExitPropertyValue::operator!):
+        (JSC::FTL::ExitPropertyValue::location):
+        (JSC::FTL::ExitPropertyValue::value):
+        * ftl/FTLExitTimeObjectMaterialization.cpp: Added.
+        (JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
+        (JSC::FTL::ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization):
+        (JSC::FTL::ExitTimeObjectMaterialization::add):
+        (JSC::FTL::ExitTimeObjectMaterialization::get):
+        (JSC::FTL::ExitTimeObjectMaterialization::dump):
+        * ftl/FTLExitTimeObjectMaterialization.h: Added.
+        (JSC::FTL::ExitTimeObjectMaterialization::type):
+        (JSC::FTL::ExitTimeObjectMaterialization::properties):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::materializeNewObject):
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::isObjectMaterialization):
+        (JSC::FTL::ExitValue::objectMaterialization):
+        (JSC::FTL::ExitValue::withVirtualRegister):
+        (JSC::FTL::ExitValue::valueFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileNewObject):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructureImmediate):
+        (JSC::FTL::LowerDFGToLLVM::compileMaterializeNewObject):
+        (JSC::FTL::LowerDFGToLLVM::checkStructure):
+        (JSC::FTL::LowerDFGToLLVM::allocateCell):
+        (JSC::FTL::LowerDFGToLLVM::storeStructure):
+        (JSC::FTL::LowerDFGToLLVM::allocateObject):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::weakStructureID):
+        (JSC::FTL::LowerDFGToLLVM::weakStructure):
+        (JSC::FTL::LowerDFGToLLVM::availabilityMap):
+        (JSC::FTL::LowerDFGToLLVM::availability): Deleted.
+        * ftl/FTLOSRExit.h:
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileRecovery):
+        (JSC::FTL::compileStub):
+        * ftl/FTLOperations.cpp: Added.
+        (JSC::FTL::operationNewObjectWithButterfly):
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * ftl/FTLOperations.h: Added.
+        * ftl/FTLSwitchCase.h:
+        (JSC::FTL::SwitchCase::SwitchCase):
+        * runtime/JSObject.h:
+        (JSC::JSObject::finishCreation):
+        (JSC::JSFinalObject::JSFinalObject):
+        (JSC::JSFinalObject::create):
+        * runtime/Structure.cpp:
+        (JSC::Structure::canUseForAllocationsOf):
+        * runtime/Structure.h:
+        * tests/stress/elidable-new-object-roflcopter-then-exit.js: Added.
+        (sumOfArithSeries):
+        (foo):
+        * tests/stress/elide-new-object-dag-then-exit.js: Added.
+        (sumOfArithSeries):
+        (bar):
+        (verify):
+        (foo):
+        * tests/stress/obviously-elidable-new-object-then-exit.js: Added.
+        (sumOfArithSeries):
+        (foo):
+
</ins><span class="cx"> 2014-09-25  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Replay: Check event loop input extents during replaying too
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
</del><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
</ins><span class="cx"> &lt;Project DefaultTargets=&quot;Build&quot; ToolsVersion=&quot;12.0&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;
</span><span class="cx">   &lt;ItemGroup Label=&quot;ProjectConfigurations&quot;&gt;
</span><span class="cx">     &lt;ProjectConfiguration Include=&quot;DebugSuffix|Win32&quot;&gt;
</span><span class="lines">@@ -368,6 +368,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGArrayMode.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGAtTailAbstractState.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGAvailability.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGAvailabilityMap.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGBackwardsPropagationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGBasicBlock.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGBinarySwitch.cpp&quot; /&gt;
</span><span class="lines">@@ -410,6 +411,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGGraphSafepoint.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGHeapLocation.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGInPlaceAbstractState.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGInsertOSRHintsForUpdate.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGIntegerCheckCombiningPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGInvalidationPointInjectionPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGJITCode.cpp&quot; /&gt;
</span><span class="lines">@@ -439,12 +441,17 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGOSRExitCompilerCommon.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGOSRExitJumpPlaceholder.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGOSRExitPreparation.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGObjectAllocationSinkingPhase.cpp&quot; /&gt;
+    &lt;ClCompile Include=&quot;..\dfg\DFGObjectMaterializationData.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPhantomCanonicalizationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPhantomRemovalPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPhase.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGPhiChildren.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPlan.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGPrePostNumbering.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPredictionInjectionPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPredictionPropagationPhase.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGPromotedHeapLocation.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPureValue.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGResurrectionForValidationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGSafepoint.cpp&quot; /&gt;
</span><span class="lines">@@ -493,7 +500,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLDWARFRegister.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLExitArgument.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLExitArgumentForOperand.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\ftl\FTLExitPropertyValue.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLExitThunkGenerator.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\ftl\FTLExitTimeObjectMaterialization.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLExitValue.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLFail.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLForOSREntryJITCode.cpp&quot; /&gt;
</span><span class="lines">@@ -508,6 +517,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLOSREntry.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLOSRExit.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLOSRExitCompiler.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\ftl\FTLOperations.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLOutput.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLRecoveryOpcode.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\ftl\FTLRegisterAtOffset.cpp&quot; /&gt;
</span><span class="lines">@@ -993,6 +1003,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGArrayMode.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGAtTailAbstractState.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGAvailability.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGAvailabilityMap.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGBackwardsPropagationPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGBasicBlock.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGBasicBlockInlines.h&quot; /&gt;
</span><span class="lines">@@ -1049,6 +1060,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGGraphSafepoint.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGHeapLocation.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGInPlaceAbstractState.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGInsertOSRHintsForUpdate.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGInsertionSet.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGIntegerCheckCombiningPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGInvalidationPointInjectionPhase.h&quot; /&gt;
</span><span class="lines">@@ -1073,6 +1085,8 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGNodeFlags.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGNodeOrigin.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGNodeType.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGObjectAllocationSinkingPhase.h&quot; /&gt;
+    &lt;ClInclude Include=&quot;..\dfg\DFGObjectMaterializationData.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGOperations.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGOSRAvailabilityAnalysisPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGOSREntry.h&quot; /&gt;
</span><span class="lines">@@ -1087,9 +1101,13 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPhantomCanonicalizationPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPhantomRemovalPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPhase.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGPhiChildren.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPlan.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGPrePostNumbering.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPredictionInjectionPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPredictionPropagationPhase.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGPromoteHeapAccess.h&quot; /&gt;
+    &lt;ClInclude Include=&quot;..\dfg\DFGPromotedHeapLocation.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPureValue.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGRegisterBank.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGRegisterSet.h&quot; /&gt;
</span><span class="lines">@@ -1150,7 +1168,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLExitArgument.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLExitArgumentForOperand.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLExitArgumentList.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\ftl\FTLExitPropertyValue.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLExitThunkGenerator.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\ftl\FTLExitTimeObjectMaterialization.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLExitValue.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLFail.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLFormattedValue.h&quot; /&gt;
</span><span class="lines">@@ -1170,6 +1190,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLOSRExit.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLOSRExitCompilationInfo.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLOSRExitCompiler.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\ftl\FTLOperations.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLOutput.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLRecoveryOpcode.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\ftl\FTLRegisterAtOffset.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -209,6 +209,24 @@
</span><span class="cx">                 0F2B670917B6B5AB00A7AE3F /* TypedArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F2B670A17B6B5AB00A7AE3F /* TypedArrayType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */; };
</span><span class="cx">                 0F2B670B17B6B5AB00A7AE3F /* TypedArrayType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */; };
+                0F2B9CE319D0BA7D00B1D1B5 /* DFGAvailabilityMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */; };
+                0F2B9CE519D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CE619D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */; };
+                0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CE819D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */; };
+                0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CEA19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */; };
+                0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */; };
+                0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */; };
+                0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */; };
+                0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */; };
+                0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
</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 */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -272,6 +290,8 @@
</span><span class="cx">                 0F3B7E2D19A12AAE00D9BC56 /* CallEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */; };
</span><span class="cx">                 0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */; };
</span><span class="cx">                 0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */; };
+                0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3E01A919D353A500F61B7F /* DFGPrePostNumbering.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -443,6 +463,7 @@
</span><span class="cx">                 0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8E918B413C80052371D /* Reg.cpp */; };
</span><span class="cx">                 0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */; };
</span><ins>+                0FAA3E0919D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
</span><span class="cx">                 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105821675480C00F8AB6E /* ExitKind.cpp */; };
</span><span class="lines">@@ -1831,6 +1852,24 @@
</span><span class="cx">                 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrays.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypedArrayType.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailabilityMap.cpp; path = dfg/DFGAvailabilityMap.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAvailabilityMap.h; path = dfg/DFGAvailabilityMap.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInsertOSRHintsForUpdate.cpp; path = dfg/DFGInsertOSRHintsForUpdate.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertOSRHintsForUpdate.h; path = dfg/DFGInsertOSRHintsForUpdate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGObjectAllocationSinkingPhase.cpp; path = dfg/DFGObjectAllocationSinkingPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGObjectAllocationSinkingPhase.h; path = dfg/DFGObjectAllocationSinkingPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGObjectMaterializationData.cpp; path = dfg/DFGObjectMaterializationData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGObjectMaterializationData.h; path = dfg/DFGObjectMaterializationData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhiChildren.cpp; path = dfg/DFGPhiChildren.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhiChildren.h; path = dfg/DFGPhiChildren.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPromotedHeapLocation.cpp; path = dfg/DFGPromotedHeapLocation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPromotedHeapLocation.h; path = dfg/DFGPromotedHeapLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitPropertyValue.cpp; path = ftl/FTLExitPropertyValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitPropertyValue.h; path = ftl/FTLExitPropertyValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitTimeObjectMaterialization.cpp; path = ftl/FTLExitTimeObjectMaterialization.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitTimeObjectMaterialization.h; path = ftl/FTLExitTimeObjectMaterialization.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLOperations.cpp; path = ftl/FTLOperations.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOperations.h; path = ftl/FTLOperations.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">@@ -1892,6 +1931,8 @@
</span><span class="cx">                 0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdge.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantStructureCheck.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantStructureCheck.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPrePostNumbering.cpp; path = dfg/DFGPrePostNumbering.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F3E01A919D353A500F61B7F /* DFGPrePostNumbering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPrePostNumbering.h; path = dfg/DFGPrePostNumbering.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2062,6 +2103,7 @@
</span><span class="cx">                 0FA7A8E918B413C80052371D /* Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchRegisterAllocator.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPromoteHeapAccess.h; path = dfg/DFGPromoteHeapAccess.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB105821675480C00F8AB6E /* ExitKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3471,8 +3513,12 @@
</span><span class="cx">                                 0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */,
</span><span class="cx">                                 0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */,
</span><span class="cx">                                 0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */,
</span><ins>+                                0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */,
+                                0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */,
</ins><span class="cx">                                 0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */,
</span><span class="cx">                                 0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */,
</span><ins>+                                0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */,
+                                0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */,
</ins><span class="cx">                                 0F235BC417178E1C00690C7F /* FTLExitValue.cpp */,
</span><span class="cx">                                 0F235BC517178E1C00690C7F /* FTLExitValue.h */,
</span><span class="cx">                                 A7F2996917A0BB670010417A /* FTLFail.cpp */,
</span><span class="lines">@@ -3499,6 +3545,8 @@
</span><span class="cx">                                 0FEA0A04170513DB00BB722C /* FTLLowerDFGToLLVM.cpp */,
</span><span class="cx">                                 0FEA0A05170513DB00BB722C /* FTLLowerDFGToLLVM.h */,
</span><span class="cx">                                 A7D89D0117A0B90400773AD8 /* FTLLoweredNodeValue.h */,
</span><ins>+                                0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */,
+                                0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */,
</ins><span class="cx">                                 0FD8A31717D51F2200CA2C40 /* FTLOSREntry.cpp */,
</span><span class="cx">                                 0FD8A31817D51F2200CA2C40 /* FTLOSREntry.h */,
</span><span class="cx">                                 0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */,
</span><span class="lines">@@ -4528,6 +4576,8 @@
</span><span class="cx">                                 A7D9A29017A0BC7400EE2618 /* DFGAtTailAbstractState.h */,
</span><span class="cx">                                 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */,
</span><span class="cx">                                 0F666EC31835672B00D017F1 /* DFGAvailability.h */,
</span><ins>+                                0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */,
+                                0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */,
</ins><span class="cx">                                 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */,
</span><span class="cx">                                 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */,
</span><span class="cx">                                 A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */,
</span><span class="lines">@@ -4626,6 +4676,8 @@
</span><span class="cx">                                 A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */,
</span><span class="cx">                                 A704D90117A0BAA8006BA554 /* DFGInPlaceAbstractState.h */,
</span><span class="cx">                                 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */,
</span><ins>+                                0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */,
+                                0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */,
</ins><span class="cx">                                 0F300B7918AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp */,
</span><span class="cx">                                 0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */,
</span><span class="cx">                                 0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */,
</span><span class="lines">@@ -4666,6 +4718,10 @@
</span><span class="cx">                                 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
</span><span class="cx">                                 0F300B7718AB051100A6D72E /* DFGNodeOrigin.h */,
</span><span class="cx">                                 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */,
</span><ins>+                                0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */,
+                                0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */,
+                                0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */,
+                                0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */,
</ins><span class="cx">                                 86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */,
</span><span class="cx">                                 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */,
</span><span class="cx">                                 A7D89CEE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp */,
</span><span class="lines">@@ -4695,12 +4751,19 @@
</span><span class="cx">                                 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */,
</span><span class="cx">                                 0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
</span><span class="cx">                                 0FFFC95014EF909500C72532 /* DFGPhase.h */,
</span><ins>+                                0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */,
+                                0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */,
</ins><span class="cx">                                 A78A9772179738B8009DF744 /* DFGPlan.cpp */,
</span><span class="cx">                                 A78A9773179738B8009DF744 /* DFGPlan.h */,
</span><span class="cx">                                 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */,
</span><span class="cx">                                 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
</span><span class="cx">                                 0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
</span><span class="cx">                                 0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
</span><ins>+                                0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */,
+                                0F3E01A919D353A500F61B7F /* DFGPrePostNumbering.h */,
+                                0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */,
+                                0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */,
+                                0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */,
</ins><span class="cx">                                 0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */,
</span><span class="cx">                                 0FB1765F196B8F9E0091052A /* DFGPureValue.h */,
</span><span class="cx">                                 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
</span><span class="lines">@@ -5281,6 +5344,7 @@
</span><span class="cx">                                 A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
</span><span class="cx">                                 A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */,
</span><span class="cx">                                 A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */,
</span><ins>+                                0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */,
</ins><span class="cx">                                 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
</span><span class="cx">                                 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
</span><span class="cx">                                 C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
</span><span class="lines">@@ -5339,6 +5403,7 @@
</span><span class="cx">                                 2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
</span><span class="cx">                                 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
</span><span class="cx">                                 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
</span><ins>+                                0F2B9CE519D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h in Headers */,
</ins><span class="cx">                                 0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
</span><span class="cx">                                 BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
</span><span class="cx">                                 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
</span><span class="lines">@@ -5426,10 +5491,12 @@
</span><span class="cx">                                 A78A9779179738B8009DF744 /* DFGJITFinalizer.h in Headers */,
</span><span class="cx">                                 0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */,
</span><span class="cx">                                 A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */,
</span><ins>+                                0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */,
</ins><span class="cx">                                 A7D9A29817A0BC7400EE2618 /* DFGLICMPhase.h in Headers */,
</span><span class="cx">                                 A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
</span><span class="cx">                                 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
</span><span class="cx">                                 A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
</span><ins>+                                0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */,
</ins><span class="cx">                                 A704D90717A0BAA8006BA554 /* DFGMergeMode.h in Headers */,
</span><span class="cx">                                 0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
</span><span class="cx">                                 0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
</span><span class="lines">@@ -5486,6 +5553,7 @@
</span><span class="cx">                                 0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
</span><span class="cx">                                 0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
</span><span class="cx">                                 0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
</span><ins>+                                0FAA3E0919D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h in Headers */,
</ins><span class="cx">                                 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
</span><span class="cx">                                 0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
</span><span class="cx">                                 0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
</span><span class="lines">@@ -5623,6 +5691,7 @@
</span><span class="cx">                                 0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */,
</span><span class="cx">                                 99E45A2718A1B2590026D88F /* InputCursor.h in Headers */,
</span><span class="cx">                                 A593CF7F1840362C00BFCE27 /* InspectorAgentBase.h in Headers */,
</span><ins>+                                0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */,
</ins><span class="cx">                                 A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
</span><span class="cx">                                 A593CF7D1840360300BFCE27 /* InspectorBackendDispatcher.h in Headers */,
</span><span class="cx">                                 A5FD0082189B191A00633231 /* InspectorConsoleAgent.h in Headers */,
</span><span class="lines">@@ -5647,6 +5716,7 @@
</span><span class="cx">                                 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
</span><span class="cx">                                 860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
</span><span class="cx">                                 BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */,
</span><ins>+                                0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */,
</ins><span class="cx">                                 A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */,
</span><span class="cx">                                 BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
</span><span class="cx">                                 BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
</span><span class="lines">@@ -5690,6 +5760,7 @@
</span><span class="cx">                                 657CF45919BF6662004ACBF2 /* JSCallee.h in Headers */,
</span><span class="cx">                                 BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */,
</span><span class="cx">                                 BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */,
</span><ins>+                                0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */,
</ins><span class="cx">                                 BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
</span><span class="cx">                                 BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
</span><span class="cx">                                 A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */,
</span><span class="lines">@@ -5790,6 +5861,7 @@
</span><span class="cx">                                 BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
</span><span class="cx">                                 86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
</span><span class="cx">                                 86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
</span><ins>+                                0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */,
</ins><span class="cx">                                 A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
</span><span class="cx">                                 A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
</span><span class="cx">                                 A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
</span><span class="lines">@@ -5904,6 +5976,7 @@
</span><span class="cx">                                 0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */,
</span><span class="cx">                                 0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */,
</span><span class="cx">                                 0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */,
</span><ins>+                                0F2B9CE319D0BA7D00B1D1B5 /* DFGAvailabilityMap.h in Headers */,
</ins><span class="cx">                                 0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */,
</span><span class="cx">                                 0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */,
</span><span class="cx">                                 2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
</span><span class="lines">@@ -6011,6 +6084,7 @@
</span><span class="cx">                                 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
</span><span class="cx">                                 C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
</span><span class="cx">                                 C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
</span><ins>+                                0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */,
</ins><span class="cx">                                 0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
</span><span class="cx">                                 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
</span><span class="cx">                                 BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
</span><span class="lines">@@ -6579,6 +6653,7 @@
</span><span class="cx">                                 1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
</span><span class="cx">                                 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
</span><span class="cx">                                 0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
</span><ins>+                                0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */,
</ins><span class="cx">                                 0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
</span><span class="cx">                                 969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
</span><span class="cx">                                 0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
</span><span class="lines">@@ -6623,12 +6698,14 @@
</span><span class="cx">                                 A7D9A29417A0BC7400EE2618 /* DFGAtTailAbstractState.cpp in Sources */,
</span><span class="cx">                                 0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */,
</span><span class="cx">                                 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
</span><ins>+                                0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */,
</ins><span class="cx">                                 A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
</span><span class="cx">                                 A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */,
</span><span class="cx">                                 2A88067819107D5500CB0BBB /* DFGFunctionWhitelist.cpp in Sources */,
</span><span class="cx">                                 A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
</span><span class="cx">                                 86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
</span><span class="cx">                                 0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
</span><ins>+                                0F2B9CE619D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp in Sources */,
</ins><span class="cx">                                 0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
</span><span class="cx">                                 0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
</span><span class="cx">                                 A77A423F17A0BBFD00A8DB81 /* DFGClobberize.cpp in Sources */,
</span><span class="lines">@@ -6651,6 +6728,8 @@
</span><span class="cx">                                 0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */,
</span><span class="cx">                                 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
</span><span class="cx">                                 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
</span><ins>+                                0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */,
+                                0F2B9CE819D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp in Sources */,
</ins><span class="cx">                                 0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
</span><span class="cx">                                 0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
</span><span class="cx">                                 0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */,
</span><span class="lines">@@ -6767,6 +6846,7 @@
</span><span class="cx">                                 0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */,
</span><span class="cx">                                 0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
</span><span class="cx">                                 A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
</span><ins>+                                0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */,
</ins><span class="cx">                                 0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
</span><span class="cx">                                 0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */,
</span><span class="cx">                                 0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */,
</span><span class="lines">@@ -6818,6 +6898,7 @@
</span><span class="cx">                                 0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */,
</span><span class="cx">                                 A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */,
</span><span class="cx">                                 A593CF86184038CA00BFCE27 /* InspectorAgentRegistry.cpp in Sources */,
</span><ins>+                                0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */,
</ins><span class="cx">                                 A593CF7C1840360300BFCE27 /* InspectorBackendDispatcher.cpp in Sources */,
</span><span class="cx">                                 2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */,
</span><span class="cx">                                 A5FD0081189B191A00633231 /* InspectorConsoleAgent.cpp in Sources */,
</span><span class="lines">@@ -6997,6 +7078,7 @@
</span><span class="cx">                                 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
</span><span class="cx">                                 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
</span><span class="cx">                                 95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
</span><ins>+                                0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */,
</ins><span class="cx">                                 95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
</span><span class="cx">                                 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
</span><span class="cx">                                 0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */,
</span><span class="lines">@@ -7019,6 +7101,7 @@
</span><span class="cx">                                 65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */,
</span><span class="cx">                                 1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */,
</span><span class="cx">                                 0F9332A314CA7DD70085F3C6 /* PutByIdStatus.cpp in Sources */,
</span><ins>+                                0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */,
</ins><span class="cx">                                 0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */,
</span><span class="cx">                                 0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */,
</span><span class="cx">                                 14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
</span><span class="lines">@@ -7088,6 +7171,7 @@
</span><span class="cx">                                 0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
</span><span class="cx">                                 0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
</span><span class="cx">                                 0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */,
</span><ins>+                                0F2B9CEA19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp in Sources */,
</ins><span class="cx">                                 0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
</span><span class="cx">                                 A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
</span><span class="cx">                                 B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureSet.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureSet.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/bytecode/StructureSet.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -166,6 +166,37 @@
</span><span class="cx">         return structureList()-&gt;list()[structureList()-&gt;m_length - 1];
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    class iterator {
+    public:
+        iterator()
+            : m_set(nullptr)
+            , m_index(0)
+        {
+        }
+        
+        iterator(const StructureSet* set, size_t index)
+            : m_set(set)
+            , m_index(index)
+        {
+        }
+        
+        Structure* operator*() const { return m_set-&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 StructureSet* m_set;
+        size_t m_index;
+    };
+    
+    iterator begin() const { return iterator(this, 0); }
+    iterator end() const { return iterator(this, size()); }
+    
</ins><span class="cx">     bool operator==(const StructureSet&amp; other) const;
</span><span class="cx">     
</span><span class="cx">     SpeculatedType speculationFromStructures() const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGBranchDirection.h&quot;
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><ins>+#include &quot;DFGPhiChildren.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><span class="lines">@@ -80,18 +81,15 @@
</span><span class="cx">     //
</span><span class="cx">     // This is guaranteed to be equivalent to doing:
</span><span class="cx">     //
</span><del>-    // if (state.startExecuting(index)) {
-    //     state.executeEdges(index);
-    //     result = state.executeEffects(index);
-    // } else
-    //     result = true;
</del><ins>+    // state.startExecuting()
+    // state.executeEdges(index);
+    // result = state.executeEffects(index);
</ins><span class="cx">     bool execute(unsigned indexInBlock);
</span><span class="cx">     bool execute(Node*);
</span><span class="cx">     
</span><del>-    // Indicate the start of execution of the node. It resets any state in the node
</del><ins>+    // Indicate the start of execution of a node. It resets any state in the node
</ins><span class="cx">     // that is progressively built up by executeEdges() and executeEffects().
</span><del>-    bool startExecuting(Node*);
-    bool startExecuting(unsigned indexInBlock);
</del><ins>+    void startExecuting();
</ins><span class="cx">     
</span><span class="cx">     // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
</span><span class="cx">     // on all edges of the node. You can skip this step, if you have already used
</span><span class="lines">@@ -146,6 +144,8 @@
</span><span class="cx">     FiltrationResult filter(AbstractValue&amp;, SpeculatedType);
</span><span class="cx">     FiltrationResult filterByValue(AbstractValue&amp;, FrozenValue);
</span><span class="cx">     
</span><ins>+    PhiChildren* phiChildren() { return m_phiChildren.get(); }
+    
</ins><span class="cx"> private:
</span><span class="cx">     void clobberWorld(const CodeOrigin&amp;, unsigned indexInBlock);
</span><span class="cx">     void clobberCapturedVars(const CodeOrigin&amp;);
</span><span class="lines">@@ -195,6 +195,7 @@
</span><span class="cx">     CodeBlock* m_codeBlock;
</span><span class="cx">     Graph&amp; m_graph;
</span><span class="cx">     AbstractStateType&amp; m_state;
</span><ins>+    std::unique_ptr&lt;PhiChildren&gt; m_phiChildren;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -43,6 +43,8 @@
</span><span class="cx">     , m_graph(graph)
</span><span class="cx">     , m_state(state)
</span><span class="cx"> {
</span><ins>+    if (m_graph.m_form == SSA)
+        m_phiChildren = std::make_unique&lt;PhiChildren&gt;(m_graph);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="lines">@@ -81,23 +83,15 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><del>-bool AbstractInterpreter&lt;AbstractStateType&gt;::startExecuting(Node* node)
</del><ins>+void AbstractInterpreter&lt;AbstractStateType&gt;::startExecuting()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_state.block());
</span><span class="cx">     ASSERT(m_state.isValid());
</span><span class="cx">     
</span><span class="cx">     m_state.setDidClobber(false);
</span><del>-    
-    return node-&gt;shouldGenerate();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><del>-bool AbstractInterpreter&lt;AbstractStateType&gt;::startExecuting(unsigned indexInBlock)
-{
-    return startExecuting(m_state.block()-&gt;at(indexInBlock));
-}
-
-template&lt;typename AbstractStateType&gt;
</del><span class="cx"> void AbstractInterpreter&lt;AbstractStateType&gt;::executeEdges(Node* node)
</span><span class="cx"> {
</span><span class="cx">     DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
</span><span class="lines">@@ -1260,6 +1254,29 @@
</span><span class="cx">         forNode(node).set(m_graph, node-&gt;structure());
</span><span class="cx">         break;
</span><span class="cx">         
</span><ins>+    case PhantomNewObject:
+    case BottomValue:
+        m_state.setDidClobber(true); // Prevent constant folding.
+        // This claims to return bottom.
+        break;
+        
+    case PutByOffsetHint:
+    case PutStructureHint:
+        break;
+        
+    case MaterializeNewObject: {
+        StructureSet set;
+        
+        m_phiChildren-&gt;forAllTransitiveIncomingValues(
+            m_graph.varArgChild(node, 0).node(),
+            [&amp;] (Node* incoming) {
+                set.add(incoming-&gt;castConstant&lt;Structure*&gt;());
+            });
+        
+        forNode(node).set(m_graph, set);
+        break;
+    }
+        
</ins><span class="cx">     case CreateActivation:
</span><span class="cx">         forNode(node).set(
</span><span class="cx">             m_graph, m_codeBlock-&gt;globalObjectFor(node-&gt;origin.semantic)-&gt;activationStructure());
</span><span class="lines">@@ -1459,7 +1476,6 @@
</span><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case CheckStructure: {
</span><del>-        // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
</del><span class="cx">         AbstractValue&amp; value = forNode(node-&gt;child1());
</span><span class="cx">         ASSERT(!(value.m_type &amp; ~SpecCell)); // Edge filtering should have already ensured this.
</span><span class="cx"> 
</span><span class="lines">@@ -1478,6 +1494,50 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><ins>+    case CheckStructureImmediate: {
+        // FIXME: This currently can only reason about one structure at a time.
+        // https://bugs.webkit.org/show_bug.cgi?id=136988
+        
+        AbstractValue&amp; value = forNode(node-&gt;child1());
+        StructureSet&amp; set = node-&gt;structureSet();
+        
+        if (value.value()) {
+            if (Structure* structure = jsDynamicCast&lt;Structure*&gt;(value.value())) {
+                if (set.contains(structure)) {
+                    m_state.setFoundConstants(true);
+                    break;
+                }
+            }
+            m_state.setIsValid(false);
+            break;
+        }
+        
+        if (m_phiChildren) {
+            bool allGood = true;
+            m_phiChildren-&gt;forAllTransitiveIncomingValues(
+                node,
+                [&amp;] (Node* incoming) {
+                    if (Structure* structure = incoming-&gt;dynamicCastConstant&lt;Structure*&gt;()) {
+                        if (set.contains(structure))
+                            return;
+                    }
+                    allGood = false;
+                });
+            if (allGood) {
+                m_state.setFoundConstants(true);
+                break;
+            }
+        }
+            
+        if (Structure* structure = set.onlyStructure()) {
+            filterByValue(node-&gt;child1(), *m_graph.freeze(structure));
+            break;
+        }
+        
+        // Aw shucks, we can't do anything!
+        break;
+    }
+        
</ins><span class="cx">     case PutStructure:
</span><span class="cx">         if (!forNode(node-&gt;child1()).m_structure.isClear()) {
</span><span class="cx">             if (forNode(node-&gt;child1()).m_structure.onlyStructure() == node-&gt;transition()-&gt;next)
</span><span class="lines">@@ -1957,15 +2017,13 @@
</span><span class="cx"> 
</span><span class="cx">     case CheckTierUpAndOSREnter:
</span><span class="cx">     case LoopHint:
</span><del>-        // We pretend that it can exit because it may want to get all state.
</del><ins>+    case ZombieHint:
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case ZombieHint:
</del><span class="cx">     case Unreachable:
</span><span class="cx">     case LastNodeType:
</span><span class="cx">     case ArithIMul:
</span><span class="cx">     case FiatInt52:
</span><del>-    case BottomValue:
</del><span class="cx">         DFG_CRASH(m_graph, node, &quot;Unexpected node type&quot;);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -1983,9 +2041,8 @@
</span><span class="cx"> bool AbstractInterpreter&lt;AbstractStateType&gt;::execute(unsigned indexInBlock)
</span><span class="cx"> {
</span><span class="cx">     Node* node = m_state.block()-&gt;at(indexInBlock);
</span><del>-    if (!startExecuting(node))
-        return true;
</del><span class="cx">     
</span><ins>+    startExecuting();
</ins><span class="cx">     executeEdges(node);
</span><span class="cx">     return executeEffects(indexInBlock, node);
</span><span class="cx"> }
</span><span class="lines">@@ -1993,9 +2050,7 @@
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="cx"> bool AbstractInterpreter&lt;AbstractStateType&gt;::execute(Node* node)
</span><span class="cx"> {
</span><del>-    if (!startExecuting(node))
-        return true;
-    
</del><ins>+    startExecuting();
</ins><span class="cx">     executeEdges(node);
</span><span class="cx">     return executeEffects(UINT_MAX, node);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAvailabilityh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAvailability.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAvailability.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGAvailability.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -85,6 +85,7 @@
</span><span class="cx">     bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
</span><span class="cx">     
</span><span class="cx">     bool hasNode() const { return !nodeIsUndecided() &amp;&amp; !nodeIsUnavailable(); }
</span><ins>+    bool shouldUseNode() const { return !isFlushUseful() &amp;&amp; hasNode(); }
</ins><span class="cx">     
</span><span class="cx">     Node* node() const
</span><span class="cx">     {
</span><span class="lines">@@ -94,7 +95,13 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     FlushedAt flushedAt() const { return m_flushedAt; }
</span><ins>+    bool isFlushUseful() const
+    {
+        return flushedAt().format() != DeadFlush &amp;&amp; flushedAt().format() != ConflictingFlush;
+    }
</ins><span class="cx">     
</span><ins>+    bool isDead() const { return !isFlushUseful() &amp;&amp; !hasNode(); }
+    
</ins><span class="cx">     bool operator!() const { return nodeIsUnavailable() &amp;&amp; flushedAt().format() == ConflictingFlush; }
</span><span class="cx"> 
</span><span class="cx">     bool operator==(const Availability&amp; other) const
</span><span class="lines">@@ -103,6 +110,11 @@
</span><span class="cx">             &amp;&amp; m_flushedAt == other.m_flushedAt;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool operator!=(const Availability&amp; other) const
+    {
+        return !(*this == other);
+    }
+    
</ins><span class="cx">     Availability merge(const Availability&amp; other) const
</span><span class="cx">     {
</span><span class="cx">         return Availability(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAvailabilityMapcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGAvailabilityMap.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;OperandsInlines.h&quot;
+#include &lt;wtf/ListDump.h&gt;
+
+namespace JSC { namespace DFG {
+
+void AvailabilityMap::prune()
+{
+    if (m_heap.isEmpty())
+        return;
+    
+    HashSet&lt;Node*&gt; possibleNodes;
+    
+    for (unsigned i = m_locals.size(); i--;) {
+        if (m_locals[i].hasNode())
+            possibleNodes.add(m_locals[i].node());
+    }
+
+    int oldPossibleNodesSize;
+    do {
+        oldPossibleNodesSize = possibleNodes.size();
+        for (auto pair : m_heap) {
+            if (pair.value.hasNode() &amp;&amp; possibleNodes.contains(pair.key.base()))
+                possibleNodes.add(pair.value.node());
+        }
+    } while (oldPossibleNodesSize != possibleNodes.size());
+    
+    HashMap&lt;PromotedHeapLocation, Availability&gt; newHeap;
+    for (auto pair : m_heap) {
+        if (possibleNodes.contains(pair.key.base()))
+            newHeap.add(pair.key, pair.value);
+    }
+    m_heap = newHeap;
+}
+
+void AvailabilityMap::clear()
+{
+    m_locals.fill(Availability());
+    m_heap.clear();
+}
+
+void AvailabilityMap::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;{locals = &quot;, m_locals, &quot;; heap = &quot;, mapDump(m_heap), &quot;}&quot;);
+}
+
+bool AvailabilityMap::operator==(const AvailabilityMap&amp; other) const
+{
+    return m_locals == other.m_locals
+        &amp;&amp; m_heap == other.m_heap;
+}
+
+void AvailabilityMap::merge(const AvailabilityMap&amp; other)
+{
+    for (unsigned i = other.m_locals.size(); i--;)
+        m_locals[i] = other.m_locals[i].merge(m_locals[i]);
+    
+    for (auto pair : other.m_heap) {
+        auto result = m_heap.add(pair.key, Availability());
+        result.iterator-&gt;value = pair.value.merge(result.iterator-&gt;value);
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAvailabilityMaph"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGAvailabilityMap_h
+#define DFGAvailabilityMap_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGAvailability.h&quot;
+#include &quot;DFGPromotedHeapLocation.h&quot;
+
+namespace JSC { namespace DFG {
+
+struct AvailabilityMap {
+    void prune();
+    void clear();
+    
+    void dump(PrintStream&amp; out) const;
+    
+    bool operator==(const AvailabilityMap&amp; other) const;
+    
+    void merge(const AvailabilityMap&amp; other);
+    
+    template&lt;typename Functor&gt;
+    void forEachAvailability(const Functor&amp; functor)
+    {
+        for (unsigned i = m_locals.size(); i--;)
+            functor(m_locals[i]);
+        for (auto pair : m_heap)
+            functor(pair.value);
+    }
+    
+    Operands&lt;Availability&gt; m_locals;
+    HashMap&lt;PromotedHeapLocation, Availability&gt; m_heap;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGAvailabilityMap_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -118,9 +118,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BasicBlock::SSAData::SSAData(BasicBlock* block)
</span><del>-    : availabilityAtHead(OperandsLike, block-&gt;variablesAtHead)
-    , availabilityAtTail(OperandsLike, block-&gt;variablesAtHead)
</del><span class="cx"> {
</span><ins>+    availabilityAtHead.m_locals = Operands&lt;Availability&gt;(OperandsLike, block-&gt;variablesAtHead);
+    availabilityAtTail.m_locals = Operands&lt;Availability&gt;(OperandsLike, block-&gt;variablesAtHead);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BasicBlock::SSAData::~SSAData() { }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGAbstractValue.h&quot;
</span><span class="cx"> #include &quot;DFGAvailability.h&quot;
</span><ins>+#include &quot;DFGAvailabilityMap.h&quot;
</ins><span class="cx"> #include &quot;DFGBranchDirection.h&quot;
</span><span class="cx"> #include &quot;DFGFlushedAt.h&quot;
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="lines">@@ -46,6 +47,7 @@
</span><span class="cx"> class InsertionSet;
</span><span class="cx"> 
</span><span class="cx"> typedef Vector&lt;BasicBlock*, 2&gt; PredecessorList;
</span><ins>+typedef Vector&lt;Node*, 8&gt; BlockNodeList;
</ins><span class="cx"> 
</span><span class="cx"> struct BasicBlock : RefCounted&lt;BasicBlock&gt; {
</span><span class="cx">     BasicBlock(
</span><span class="lines">@@ -85,6 +87,9 @@
</span><span class="cx">     bool isInPhis(Node* node) const;
</span><span class="cx">     bool isInBlock(Node* myNode) const;
</span><span class="cx">     
</span><ins>+    BlockNodeList::iterator begin() { return m_nodes.begin(); }
+    BlockNodeList::iterator end() { return m_nodes.end(); }
+    
</ins><span class="cx">     unsigned numSuccessors() { return last()-&gt;numSuccessors(); }
</span><span class="cx">     
</span><span class="cx">     BasicBlock*&amp; successor(unsigned index)
</span><span class="lines">@@ -96,6 +101,76 @@
</span><span class="cx">         return last()-&gt;successorForCondition(condition);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    class SuccessorsIterable {
+    public:
+        SuccessorsIterable()
+            : m_block(nullptr)
+        {
+        }
+        
+        SuccessorsIterable(BasicBlock* block)
+            : m_block(block)
+        {
+        }
+        
+        class iterator {
+        public:
+            iterator()
+                : m_block(nullptr)
+                , m_index(UINT_MAX)
+            {
+            }
+            
+            iterator(BasicBlock* block, unsigned index)
+                : m_block(block)
+                , m_index(index)
+            {
+            }
+            
+            BasicBlock* operator*()
+            {
+                return m_block-&gt;successor(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:
+            BasicBlock* m_block;
+            unsigned m_index;
+        };
+        
+        iterator begin()
+        {
+            return iterator(m_block, 0);
+        }
+        
+        iterator end()
+        {
+            return iterator(m_block, m_block-&gt;numSuccessors());
+        }
+        
+    private:
+        BasicBlock* m_block;
+    };
+    
+    SuccessorsIterable successors()
+    {
+        return SuccessorsIterable(this);
+    }
+    
</ins><span class="cx">     void removePredecessor(BasicBlock* block);
</span><span class="cx">     void replacePredecessor(BasicBlock* from, BasicBlock* to);
</span><span class="cx"> 
</span><span class="lines">@@ -169,8 +244,9 @@
</span><span class="cx">     unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];
</span><span class="cx"> 
</span><span class="cx">     struct SSAData {
</span><del>-        Operands&lt;Availability&gt; availabilityAtHead;
-        Operands&lt;Availability&gt; availabilityAtTail;
</del><ins>+        AvailabilityMap availabilityAtHead;
+        AvailabilityMap availabilityAtTail;
+        
</ins><span class="cx">         HashSet&lt;Node*&gt; liveAtHead;
</span><span class="cx">         HashSet&lt;Node*&gt; liveAtTail;
</span><span class="cx">         HashMap&lt;Node*, AbstractValue&gt; valuesAtHead;
</span><span class="lines">@@ -183,7 +259,7 @@
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     friend class InsertionSet;
</span><del>-    Vector&lt;Node*, 8&gt; m_nodes;
</del><ins>+    BlockNodeList m_nodes;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> typedef Vector&lt;BasicBlock*, 5&gt; BlockList;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -109,6 +109,7 @@
</span><span class="cx">     case HardPhantom:
</span><span class="cx">     case Check:
</span><span class="cx">     case ExtractOSREntryLocal:
</span><ins>+    case CheckStructureImmediate:
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case BitAnd:
</span><span class="lines">@@ -273,6 +274,8 @@
</span><span class="cx">     case ProfileDidCall:
</span><span class="cx">     case StoreBarrier:
</span><span class="cx">     case StoreBarrierWithNullCheck:
</span><ins>+    case PutByOffsetHint:
+    case PutStructureHint:
</ins><span class="cx">         write(SideState);
</span><span class="cx">         return;
</span><span class="cx">         
</span><span class="lines">@@ -787,17 +790,15 @@
</span><span class="cx">     case NewObject:
</span><span class="cx">     case NewRegexp:
</span><span class="cx">     case NewStringObject:
</span><del>-        read(HeapObjectCount);
-        write(HeapObjectCount);
-        return;
-        
</del><ins>+    case PhantomNewObject:
+    case MaterializeNewObject:
</ins><span class="cx">     case NewFunctionNoCheck:
</span><span class="cx">     case NewFunction:
</span><span class="cx">     case NewFunctionExpression:
</span><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><del>-
</del><ins>+        
</ins><span class="cx">     case RegExpExec:
</span><span class="cx">     case RegExpTest:
</span><span class="cx">         read(RegExpState);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -124,6 +124,42 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><ins>+            case CheckStructureImmediate: {
+                AbstractValue&amp; value = m_state.forNode(node-&gt;child1());
+                StructureSet&amp; set = node-&gt;structureSet();
+                
+                if (value.value()) {
+                    if (Structure* structure = jsDynamicCast&lt;Structure*&gt;(value.value())) {
+                        if (set.contains(structure)) {
+                            m_interpreter.execute(indexInBlock);
+                            node-&gt;convertToPhantom();
+                            eliminated = true;
+                            break;
+                        }
+                    }
+                }
+                
+                if (PhiChildren* phiChildren = m_interpreter.phiChildren()) {
+                    bool allGood = true;
+                    phiChildren-&gt;forAllTransitiveIncomingValues(
+                        node,
+                        [&amp;] (Node* incoming) {
+                            if (Structure* structure = incoming-&gt;dynamicCastConstant&lt;Structure*&gt;()) {
+                                if (set.contains(structure))
+                                    return;
+                            }
+                            allGood = false;
+                        });
+                    if (allGood) {
+                        m_interpreter.execute(indexInBlock);
+                        node-&gt;convertToPhantom();
+                        eliminated = true;
+                        break;
+                    }
+                }
+                break;
+            }
+                
</ins><span class="cx">             case CheckArray:
</span><span class="cx">             case Arrayify: {
</span><span class="cx">                 if (!node-&gt;arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node-&gt;child1())))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -199,6 +199,10 @@
</span><span class="cx">     case BooleanToNumber:
</span><span class="cx">     case CheckBadCell:
</span><span class="cx">     case BottomValue:
</span><ins>+    case PhantomNewObject:
+    case PutByOffsetHint:
+    case CheckStructureImmediate:
+    case PutStructureHint:
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     case CreateActivation:
</span><span class="lines">@@ -225,6 +229,7 @@
</span><span class="cx">     case GetGenericPropertyEnumerator:
</span><span class="cx">     case GetEnumeratorPname:
</span><span class="cx">     case ToIndexString:
</span><ins>+    case MaterializeNewObject:
</ins><span class="cx">         return true;
</span><span class="cx">         
</span><span class="cx">     case MultiPutByOffset:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1013,6 +1013,11 @@
</span><span class="cx">         case Int52Constant:
</span><span class="cx">         case Identity: // This should have been cleaned up.
</span><span class="cx">         case BooleanToNumber:
</span><ins>+        case PhantomNewObject:
+        case PutByOffsetHint:
+        case CheckStructureImmediate:
+        case PutStructureHint:
+        case MaterializeNewObject:
</ins><span class="cx">             // These are just nodes that we don't currently expect to see during fixup.
</span><span class="cx">             // If we ever wanted to insert them prior to fixup, then we just have to create
</span><span class="cx">             // fixup rules for them.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFlushedAtcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -36,8 +36,10 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_format == DeadFlush || m_format == ConflictingFlush)
</span><span class="cx">         out.print(m_format);
</span><ins>+    else if (m_virtualRegister.isValid())
+        out.print(&quot;r&quot;, m_virtualRegister, &quot;:&quot;, m_format);
</ins><span class="cx">     else
</span><del>-        out.print(&quot;r&quot;, m_virtualRegister, &quot;:&quot;, m_format);
</del><ins>+        out.print(m_format);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void FlushedAt::dumpInContext(PrintStream&amp; out, DumpContext*) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFlushedAth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGFlushedAt.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -52,8 +52,6 @@
</span><span class="cx">     {
</span><span class="cx">         if (format == DeadFlush)
</span><span class="cx">             ASSERT(!virtualRegister.isValid());
</span><del>-        else
-            ASSERT(virtualRegister.isValid());
</del><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool operator!() const { return m_format == DeadFlush; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -323,6 +323,8 @@
</span><span class="cx">         out.print(comma, inContext(JSValue(node-&gt;typedArray()), context));
</span><span class="cx">     if (node-&gt;hasStoragePointer())
</span><span class="cx">         out.print(comma, RawPointer(node-&gt;storagePointer()));
</span><ins>+    if (node-&gt;hasObjectMaterializationData())
+        out.print(comma, node-&gt;objectMaterializationData());
</ins><span class="cx">     if (node-&gt;isConstant())
</span><span class="cx">         out.print(comma, pointerDumpInContext(node-&gt;constant(), context));
</span><span class="cx">     if (node-&gt;isJump())
</span><span class="lines">@@ -368,12 +370,21 @@
</span><span class="cx">     for (size_t i = 0; i &lt; block-&gt;predecessors.size(); ++i)
</span><span class="cx">         out.print(&quot; &quot;, *block-&gt;predecessors[i]);
</span><span class="cx">     out.print(&quot;\n&quot;);
</span><ins>+    out.print(prefix, &quot;  Successors:&quot;);
+    for (BasicBlock* successor : block-&gt;successors()) {
+        out.print(&quot; &quot;, *successor);
+        if (m_prePostNumbering.isValid())
+            out.print(&quot; (&quot;, m_prePostNumbering.edgeKind(block, successor), &quot;)&quot;);
+    }
+    out.print(&quot;\n&quot;);
</ins><span class="cx">     if (m_dominators.isValid()) {
</span><span class="cx">         out.print(prefix, &quot;  Dominated by: &quot;, m_dominators.dominatorsOf(block), &quot;\n&quot;);
</span><span class="cx">         out.print(prefix, &quot;  Dominates: &quot;, m_dominators.blocksDominatedBy(block), &quot;\n&quot;);
</span><span class="cx">         out.print(prefix, &quot;  Dominance Frontier: &quot;, m_dominators.dominanceFrontierOf(block), &quot;\n&quot;);
</span><span class="cx">         out.print(prefix, &quot;  Iterated Dominance Frontier: &quot;, m_dominators.iteratedDominanceFrontierOf(BlockList(1, block)), &quot;\n&quot;);
</span><span class="cx">     }
</span><ins>+    if (m_prePostNumbering.isValid())
+        out.print(prefix, &quot;  Pre/Post Numbering: &quot;, m_prePostNumbering.preNumber(block), &quot;/&quot;, m_prePostNumbering.postNumber(block), &quot;\n&quot;);
</ins><span class="cx">     if (m_naturalLoops.isValid()) {
</span><span class="cx">         if (const NaturalLoop* loop = m_naturalLoops.headerOf(block)) {
</span><span class="cx">             out.print(prefix, &quot;  Loop header, contains:&quot;);
</span><span class="lines">@@ -562,6 +573,27 @@
</span><span class="cx">     determineReachability();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Graph::mergeRelevantToOSR()
+{
+    for (BasicBlock* block : blocksInNaturalOrder()) {
+        for (Node* node : *block) {
+            switch (node-&gt;op()) {
+            case MovHint:
+                node-&gt;child1()-&gt;mergeFlags(NodeRelevantToOSR);
+                break;
+                
+            case PutStructureHint:
+            case PutByOffsetHint:
+                node-&gt;child2()-&gt;mergeFlags(NodeRelevantToOSR);
+                break;
+                
+            default:
+                break;
+            }
+        }
+    }
+}
+
</ins><span class="cx"> namespace {
</span><span class="cx"> 
</span><span class="cx"> class RefCountCalculator {
</span><span class="lines">@@ -707,6 +739,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_dominators.invalidate();
</span><span class="cx">     m_naturalLoops.invalidate();
</span><ins>+    m_prePostNumbering.invalidate();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Graph::substituteGetLocal(BasicBlock&amp; block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="cx"> #include &quot;DFGNodeAllocator.h&quot;
</span><span class="cx"> #include &quot;DFGPlan.h&quot;
</span><ins>+#include &quot;DFGPrePostNumbering.h&quot;
</ins><span class="cx"> #include &quot;DFGScannable.h&quot;
</span><span class="cx"> #include &quot;JSStack.h&quot;
</span><span class="cx"> #include &quot;MethodOfGettingAValueProfile.h&quot;
</span><span class="lines">@@ -55,6 +56,47 @@
</span><span class="cx"> 
</span><span class="cx"> namespace DFG {
</span><span class="cx"> 
</span><ins>+#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
+        Node* _node = (node);                                           \
+        if (_node-&gt;flags() &amp; NodeHasVarArgs) {                          \
+            for (unsigned _childIdx = _node-&gt;firstChild();              \
+                _childIdx &lt; _node-&gt;firstChild() + _node-&gt;numChildren(); \
+                _childIdx++) {                                          \
+                if (!!(graph).m_varArgChildren[_childIdx])              \
+                    thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
+            }                                                           \
+        } else {                                                        \
+            if (!_node-&gt;child1()) {                                     \
+                ASSERT(                                                 \
+                    !_node-&gt;child2()                                    \
+                    &amp;&amp; !_node-&gt;child3());                               \
+                break;                                                  \
+            }                                                           \
+            thingToDo(_node, _node-&gt;child1());                          \
+                                                                        \
+            if (!_node-&gt;child2()) {                                     \
+                ASSERT(!_node-&gt;child3());                               \
+                break;                                                  \
+            }                                                           \
+            thingToDo(_node, _node-&gt;child2());                          \
+                                                                        \
+            if (!_node-&gt;child3())                                       \
+                break;                                                  \
+            thingToDo(_node, _node-&gt;child3());                          \
+        }                                                               \
+    } while (false)
+
+#define DFG_ASSERT(graph, node, assertion) do {                         \
+        if (!!(assertion))                                              \
+            break;                                                      \
+        (graph).handleAssertionFailure(                                 \
+            (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
+    } while (false)
+
+#define DFG_CRASH(graph, node, reason)                                  \
+    (graph).handleAssertionFailure(                                     \
+        (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason));
+
</ins><span class="cx"> struct InlineVariableData {
</span><span class="cx">     InlineCallFrame* inlineCallFrame;
</span><span class="cx">     unsigned argumentPositionStart;
</span><span class="lines">@@ -565,6 +607,8 @@
</span><span class="cx">     void determineReachability();
</span><span class="cx">     void resetReachability();
</span><span class="cx">     
</span><ins>+    void mergeRelevantToOSR();
+    
</ins><span class="cx">     void computeRefCounts();
</span><span class="cx">     
</span><span class="cx">     unsigned varArgNumChildren(Node* node)
</span><span class="lines">@@ -676,6 +720,100 @@
</span><span class="cx">     BlockList blocksInPreOrder();
</span><span class="cx">     BlockList blocksInPostOrder();
</span><span class="cx">     
</span><ins>+    class NaturalBlockIterable {
+    public:
+        NaturalBlockIterable()
+            : m_graph(nullptr)
+        {
+        }
+        
+        NaturalBlockIterable(Graph&amp; graph)
+            : m_graph(&amp;graph)
+        {
+        }
+        
+        class iterator {
+        public:
+            iterator()
+                : m_graph(nullptr)
+                , m_index(0)
+            {
+            }
+            
+            iterator(Graph&amp; graph, BlockIndex index)
+                : m_graph(&amp;graph)
+                , m_index(findNext(index))
+            {
+            }
+            
+            BasicBlock *operator*()
+            {
+                return m_graph-&gt;block(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:
+            BlockIndex findNext(BlockIndex index)
+            {
+                while (index &lt; m_graph-&gt;numBlocks() &amp;&amp; !m_graph-&gt;block(index))
+                    index++;
+                return index;
+            }
+            
+            Graph* m_graph;
+            BlockIndex m_index;
+        };
+        
+        iterator begin()
+        {
+            return iterator(*m_graph, 0);
+        }
+        
+        iterator end()
+        {
+            return iterator(*m_graph, m_graph-&gt;numBlocks());
+        }
+        
+    private:
+        Graph* m_graph;
+    };
+    
+    NaturalBlockIterable blocksInNaturalOrder()
+    {
+        return NaturalBlockIterable(*this);
+    }
+    
+    template&lt;typename ChildFunctor&gt;
+    void doToChildrenWithNode(Node* node, const ChildFunctor&amp; functor)
+    {
+        DFG_NODE_DO_TO_CHILDREN(*this, node, functor);
+    }
+    
+    template&lt;typename ChildFunctor&gt;
+    void doToChildren(Node* node, const ChildFunctor&amp; functor)
+    {
+        doToChildrenWithNode(
+            node,
+            [&amp;functor] (Node*, Edge&amp; edge) {
+                functor(edge);
+            });
+    }
+    
</ins><span class="cx">     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
</span><span class="cx">     
</span><span class="cx">     DesiredIdentifiers&amp; identifiers() { return m_plan.identifiers; }
</span><span class="lines">@@ -736,12 +874,14 @@
</span><span class="cx">     Bag&lt;SwitchData&gt; m_switchData;
</span><span class="cx">     Bag&lt;MultiGetByOffsetData&gt; m_multiGetByOffsetData;
</span><span class="cx">     Bag&lt;MultiPutByOffsetData&gt; m_multiPutByOffsetData;
</span><ins>+    Bag&lt;ObjectMaterializationData&gt; m_objectMaterializationData;
</ins><span class="cx">     Vector&lt;InlineVariableData, 4&gt; m_inlineVariableData;
</span><span class="cx">     HashMap&lt;CodeBlock*, std::unique_ptr&lt;FullBytecodeLiveness&gt;&gt; m_bytecodeLiveness;
</span><span class="cx">     bool m_hasArguments;
</span><span class="cx">     HashSet&lt;ExecutableBase*&gt; m_executablesWhoseArgumentsEscaped;
</span><span class="cx">     BitVector m_lazyVars;
</span><span class="cx">     Dominators m_dominators;
</span><ins>+    PrePostNumbering m_prePostNumbering;
</ins><span class="cx">     NaturalLoops m_naturalLoops;
</span><span class="cx">     unsigned m_localVars;
</span><span class="cx">     unsigned m_nextMachineLocal;
</span><span class="lines">@@ -786,47 +926,6 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
-        Node* _node = (node);                                           \
-        if (_node-&gt;flags() &amp; NodeHasVarArgs) {                          \
-            for (unsigned _childIdx = _node-&gt;firstChild();              \
-                _childIdx &lt; _node-&gt;firstChild() + _node-&gt;numChildren(); \
-                _childIdx++) {                                          \
-                if (!!(graph).m_varArgChildren[_childIdx])              \
-                    thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
-            }                                                           \
-        } else {                                                        \
-            if (!_node-&gt;child1()) {                                     \
-                ASSERT(                                                 \
-                    !_node-&gt;child2()                                    \
-                    &amp;&amp; !_node-&gt;child3());                               \
-                break;                                                  \
-            }                                                           \
-            thingToDo(_node, _node-&gt;child1());                          \
-                                                                        \
-            if (!_node-&gt;child2()) {                                     \
-                ASSERT(!_node-&gt;child3());                               \
-                break;                                                  \
-            }                                                           \
-            thingToDo(_node, _node-&gt;child2());                          \
-                                                                        \
-            if (!_node-&gt;child3())                                       \
-                break;                                                  \
-            thingToDo(_node, _node-&gt;child3());                          \
-        }                                                               \
-    } while (false)
-
-#define DFG_ASSERT(graph, node, assertion) do {                         \
-        if (!!(assertion))                                              \
-            break;                                                      \
-        (graph).handleAssertionFailure(                                 \
-            (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
-    } while (false)
-
-#define DFG_CRASH(graph, node, reason)                                  \
-    (graph).handleAssertionFailure(                                     \
-        (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason));
-
</del><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGHeapLocationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -147,6 +147,10 @@
</span><span class="cx">     case AllocationProfileWatchpointLoc:
</span><span class="cx">         out.print(&quot;AllocationProfileWatchpointLoc&quot;);
</span><span class="cx">         return;
</span><ins>+        
+    case StructureLoc:
+        out.print(&quot;StructureLoc&quot;);
+        return;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGHeapLocationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx">     MyArgumentsLengthLoc,
</span><span class="cx">     NamedPropertyLoc,
</span><span class="cx">     SetterLoc,
</span><ins>+    StructureLoc,
</ins><span class="cx">     TypeOfLoc,
</span><span class="cx">     TypedArrayByteOffsetLoc,
</span><span class="cx">     VarInjectionWatchpointLoc,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInsertOSRHintsForUpdatecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGInsertOSRHintsForUpdate.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+void insertOSRHintsForUpdate(
+    InsertionSet&amp; insertionSet, unsigned nodeIndex, NodeOrigin origin,
+    AvailabilityMap&amp; availability, Node* originalNode, Node* newNode)
+{
+    for (unsigned i = availability.m_locals.size(); i--;) {
+        int operand = availability.m_locals.operandForIndex(i);
+        
+        if (availability.m_locals[i].hasNode() &amp;&amp; availability.m_locals[i].node() == originalNode) {
+            insertionSet.insertNode(
+                nodeIndex, SpecNone, MovHint, origin, OpInfo(operand),
+                newNode-&gt;defaultEdge());
+        }
+    }
+    
+    for (auto pair : availability.m_heap) {
+        if (pair.value.hasNode() &amp;&amp; pair.value.node() == originalNode) {
+            insertionSet.insert(
+                nodeIndex, pair.key.createHint(insertionSet.graph(), origin, newNode));
+        }
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInsertOSRHintsForUpdateh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGInsertOSRHintsForUpdate_h
+#define DFGInsertOSRHintsForUpdate_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGAvailabilityMap.h&quot;
+#include &quot;DFGInsertionSet.h&quot;
+
+namespace JSC { namespace DFG {
+
+void insertOSRHintsForUpdate(
+    InsertionSet&amp;, unsigned nodeIndex, NodeOrigin, AvailabilityMap&amp;,
+    Node* originalNode, Node* newNode);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGInsertOSRHintsForUpdate_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInsertionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGInsertionSet.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInsertionSet.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGInsertionSet.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -43,6 +43,8 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    Graph&amp; graph() { return m_graph; }
+    
</ins><span class="cx">     Node* insert(const Insertion&amp; insertion)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(!m_insertions.size() || m_insertions.last().index() &lt;= insertion.index());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGMayExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -75,6 +75,10 @@
</span><span class="cx">     case Phi:
</span><span class="cx">     case Upsilon:
</span><span class="cx">     case ZombieHint:
</span><ins>+    case BottomValue:
+    case PutStructureHint:
+    case PutByOffsetHint:
+    case PhantomNewObject:
</ins><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;DFGNodeFlags.h&quot;
</span><span class="cx"> #include &quot;DFGNodeOrigin.h&quot;
</span><span class="cx"> #include &quot;DFGNodeType.h&quot;
</span><ins>+#include &quot;DFGObjectMaterializationData.h&quot;
</ins><span class="cx"> #include &quot;DFGTransition.h&quot;
</span><span class="cx"> #include &quot;DFGUseKind.h&quot;
</span><span class="cx"> #include &quot;DFGVariableAccessData.h&quot;
</span><span class="lines">@@ -500,6 +501,35 @@
</span><span class="cx">         m_flags &amp;= ~NodeClobbersWorld;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void convertToPutByOffsetHint()
+    {
+        ASSERT(m_op == PutByOffset);
+        m_opInfo = storageAccessData().identifierNumber;
+        m_op = PutByOffsetHint;
+        child1() = child2();
+        child2() = child3();
+        child3() = Edge();
+    }
+    
+    void convertToPutStructureHint(Node* structure)
+    {
+        ASSERT(m_op == PutStructure);
+        ASSERT(structure-&gt;castConstant&lt;Structure*&gt;() == transition()-&gt;next);
+        m_op = PutStructureHint;
+        m_opInfo = 0;
+        child2() = Edge(structure, KnownCellUse);
+    }
+    
+    void convertToPhantomNewObject()
+    {
+        ASSERT(m_op == NewObject || m_op == MaterializeNewObject);
+        m_op = PhantomNewObject;
+        m_flags &amp;= ~NodeHasVarArgs;
+        m_opInfo = 0;
+        m_opInfo2 = 0;
+        children = AdjacencyList();
+    }
+    
</ins><span class="cx">     void convertToPhantomLocal()
</span><span class="cx">     {
</span><span class="cx">         ASSERT(m_op == Phantom &amp;&amp; (child1()-&gt;op() == Phi || child1()-&gt;op() == SetLocal || child1()-&gt;op() == SetArgument));
</span><span class="lines">@@ -580,7 +610,7 @@
</span><span class="cx">      
</span><span class="cx">     bool isCellConstant()
</span><span class="cx">     {
</span><del>-        return isConstant() &amp;&amp; constant()-&gt;value().isCell();
</del><ins>+        return isConstant() &amp;&amp; constant()-&gt;value() &amp;&amp; constant()-&gt;value().isCell();
</ins><span class="cx">     }
</span><span class="cx">      
</span><span class="cx">     JSCell* asCell()
</span><span class="lines">@@ -595,6 +625,14 @@
</span><span class="cx">             return nullptr;
</span><span class="cx">         return jsDynamicCast&lt;T&gt;(asCell());
</span><span class="cx">     }
</span><ins>+    
+    template&lt;typename T&gt;
+    T castConstant()
+    {
+        T result = dynamicCastConstant&lt;T&gt;();
+        RELEASE_ASSERT(result);
+        return result;
+    }
</ins><span class="cx">      
</span><span class="cx">     bool containsMovHint()
</span><span class="cx">     {
</span><span class="lines">@@ -704,6 +742,7 @@
</span><span class="cx">         case PutById:
</span><span class="cx">         case PutByIdFlush:
</span><span class="cx">         case PutByIdDirect:
</span><ins>+        case PutByOffsetHint:
</ins><span class="cx">             return true;
</span><span class="cx">         default:
</span><span class="cx">             return false;
</span><span class="lines">@@ -1155,7 +1194,14 @@
</span><span class="cx">     
</span><span class="cx">     bool hasStorageAccessData()
</span><span class="cx">     {
</span><del>-        return op() == GetByOffset || op() == GetGetterSetterByOffset || op() == PutByOffset;
</del><ins>+        switch (op()) {
+        case GetByOffset:
+        case PutByOffset:
+        case GetGetterSetterByOffset:
+            return true;
+        default:
+            return false;
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     StorageAccessData&amp; storageAccessData()
</span><span class="lines">@@ -1184,6 +1230,26 @@
</span><span class="cx">         return *reinterpret_cast&lt;MultiPutByOffsetData*&gt;(m_opInfo);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool hasObjectMaterializationData()
+    {
+        return op() == MaterializeNewObject;
+    }
+    
+    ObjectMaterializationData&amp; objectMaterializationData()
+    {
+        return *reinterpret_cast&lt;ObjectMaterializationData*&gt;(m_opInfo);
+    }
+    
+    bool isPhantomObjectAllocation()
+    {
+        switch (op()) {
+        case PhantomNewObject:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
</ins><span class="cx">     bool hasFunctionDeclIndex()
</span><span class="cx">     {
</span><span class="cx">         return op() == NewFunction
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -228,6 +228,13 @@
</span><span class="cx">     macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \
</span><span class="cx">     macro(NewRegexp, NodeResultJS) \
</span><span class="cx">     \
</span><ins>+    /* Support for allocation sinking. */\
+    macro(PhantomNewObject, NodeResultJS) \
+    macro(PutByOffsetHint, NodeMustGenerate) \
+    macro(CheckStructureImmediate, NodeMustGenerate) \
+    macro(PutStructureHint, NodeMustGenerate) \
+    macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
+    \
</ins><span class="cx">     /* Nodes for misc operations. */\
</span><span class="cx">     macro(Breakpoint, NodeMustGenerate) \
</span><span class="cx">     macro(ProfileWillCall, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;DFGInsertionSet.h&quot;
</span><span class="cx"> #include &quot;DFGPhase.h&quot;
</span><ins>+#include &quot;DFGPromoteHeapAccess.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -51,25 +52,18 @@
</span><span class="cx">             BasicBlock* block = m_graph.block(blockIndex);
</span><span class="cx">             if (!block)
</span><span class="cx">                 continue;
</span><del>-            block-&gt;ssa-&gt;availabilityAtHead.fill(Availability());
-            block-&gt;ssa-&gt;availabilityAtTail.fill(Availability());
</del><ins>+            block-&gt;ssa-&gt;availabilityAtHead.clear();
+            block-&gt;ssa-&gt;availabilityAtTail.clear();
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         BasicBlock* root = m_graph.block(0);
</span><del>-        for (unsigned argument = root-&gt;ssa-&gt;availabilityAtHead.numberOfArguments(); argument--;) {
-            root-&gt;ssa-&gt;availabilityAtHead.argument(argument) =
</del><ins>+        root-&gt;ssa-&gt;availabilityAtHead.m_locals.fill(Availability::unavailable());
+        for (unsigned argument = root-&gt;ssa-&gt;availabilityAtHead.m_locals.numberOfArguments(); argument--;) {
+            root-&gt;ssa-&gt;availabilityAtHead.m_locals.argument(argument) =
</ins><span class="cx">                 Availability::unavailable().withFlush(
</span><span class="cx">                     FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (m_graph.m_plan.mode == FTLForOSREntryMode) {
-            for (unsigned local = m_graph.m_profiledBlock-&gt;m_numCalleeRegisters; local--;)
-                root-&gt;ssa-&gt;availabilityAtHead.local(local) = Availability::unavailable();
-        } else {
-            for (unsigned local = root-&gt;ssa-&gt;availabilityAtHead.numberOfLocals(); local--;)
-                root-&gt;ssa-&gt;availabilityAtHead.local(local) = Availability::unavailable();
-        }
-        
</del><span class="cx">         // This could be made more efficient by processing blocks in reverse postorder.
</span><span class="cx">         
</span><span class="cx">         LocalOSRAvailabilityCalculator calculator;
</span><span class="lines">@@ -87,6 +81,8 @@
</span><span class="cx">                 for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex)
</span><span class="cx">                     calculator.executeNode(block-&gt;at(nodeIndex));
</span><span class="cx">                 
</span><ins>+                calculator.m_availability.prune();
+                
</ins><span class="cx">                 if (calculator.m_availability == block-&gt;ssa-&gt;availabilityAtTail)
</span><span class="cx">                     continue;
</span><span class="cx">                 
</span><span class="lines">@@ -95,11 +91,7 @@
</span><span class="cx">                 
</span><span class="cx">                 for (unsigned successorIndex = block-&gt;numSuccessors(); successorIndex--;) {
</span><span class="cx">                     BasicBlock* successor = block-&gt;successor(successorIndex);
</span><del>-                    for (unsigned i = calculator.m_availability.size(); i--;) {
-                        successor-&gt;ssa-&gt;availabilityAtHead[i] =
-                            calculator.m_availability[i].merge(
-                                successor-&gt;ssa-&gt;availabilityAtHead[i]);
-                    }
</del><ins>+                    successor-&gt;ssa-&gt;availabilityAtHead.merge(calculator.m_availability);
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">         } while (changed);
</span><span class="lines">@@ -127,38 +119,50 @@
</span><span class="cx">     m_availability = block-&gt;ssa-&gt;availabilityAtHead;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void LocalOSRAvailabilityCalculator::endBlock(BasicBlock* block)
+{
+    m_availability = block-&gt;ssa-&gt;availabilityAtTail;
+}
+
</ins><span class="cx"> void LocalOSRAvailabilityCalculator::executeNode(Node* node)
</span><span class="cx"> {
</span><span class="cx">     switch (node-&gt;op()) {
</span><span class="cx">     case SetLocal: {
</span><span class="cx">         VariableAccessData* variable = node-&gt;variableAccessData();
</span><del>-        m_availability.operand(variable-&gt;local()) =
</del><ins>+        m_availability.m_locals.operand(variable-&gt;local()) =
</ins><span class="cx">             Availability(node-&gt;child1().node(), variable-&gt;flushedAt());
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case GetArgument: {
</span><span class="cx">         VariableAccessData* variable = node-&gt;variableAccessData();
</span><del>-        m_availability.operand(variable-&gt;local()) =
</del><ins>+        m_availability.m_locals.operand(variable-&gt;local()) =
</ins><span class="cx">             Availability(node, variable-&gt;flushedAt());
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case MovHint: {
</span><del>-        m_availability.operand(node-&gt;unlinkedLocal()) =
</del><ins>+        m_availability.m_locals.operand(node-&gt;unlinkedLocal()) =
</ins><span class="cx">             Availability(node-&gt;child1().node());
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case ZombieHint: {
</span><del>-        m_availability.operand(node-&gt;unlinkedLocal()) =
</del><ins>+        m_availability.m_locals.operand(node-&gt;unlinkedLocal()) =
</ins><span class="cx">             Availability::unavailable();
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-
</del><ins>+        
</ins><span class="cx">     default:
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+    
+    promoteHeapAccess(
+        node,
+        [&amp;] (PromotedHeapLocation location, Edge value) {
+            m_availability.m_heap.set(location, Availability(value.node()));
+        },
+        [&amp;] (PromotedHeapLocation) { });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -37,7 +37,9 @@
</span><span class="cx"> 
</span><span class="cx"> // Computes BasicBlock::ssa-&gt;availabiltiyAtHead/Tail. This is a forward flow type inference
</span><span class="cx"> // over MovHints and SetLocals. This analysis is run directly by the Plan for preparing for
</span><del>-// lowering to LLVM IR, but it can also be used as a utility.
</del><ins>+// lowering to LLVM IR, but it can also be used as a utility. Note that if you run it before
+// stack layout, all of the flush availability will omit the virtual register - but it will
+// tell you the format.
</ins><span class="cx"> 
</span><span class="cx"> bool performOSRAvailabilityAnalysis(Graph&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -49,9 +51,10 @@
</span><span class="cx">     ~LocalOSRAvailabilityCalculator();
</span><span class="cx">     
</span><span class="cx">     void beginBlock(BasicBlock*);
</span><ins>+    void endBlock(BasicBlock*); // Useful if you want to get data for the end of the block. You don't need to call this if you did beginBlock() and then executeNode() for every node.
</ins><span class="cx">     void executeNode(Node*);
</span><span class="cx">     
</span><del>-    Operands&lt;Availability&gt; m_availability;
</del><ins>+    AvailabilityMap m_availability;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,812 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGObjectAllocationSinkingPhase.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGAbstractHeap.h&quot;
+#include &quot;DFGBlockMapInlines.h&quot;
+#include &quot;DFGClobberize.h&quot;
+#include &quot;DFGGraph.h&quot;
+#include &quot;DFGInsertOSRHintsForUpdate.h&quot;
+#include &quot;DFGInsertionSet.h&quot;
+#include &quot;DFGLivenessAnalysisPhase.h&quot;
+#include &quot;DFGOSRAvailabilityAnalysisPhase.h&quot;
+#include &quot;DFGPhase.h&quot;
+#include &quot;DFGPromoteHeapAccess.h&quot;
+#include &quot;DFGSSACalculator.h&quot;
+#include &quot;DFGValidate.h&quot;
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+static bool verbose = false;
+
+class ObjectAllocationSinkingPhase : public Phase {
+public:
+    ObjectAllocationSinkingPhase(Graph&amp; graph)
+        : Phase(graph, &quot;object allocation sinking&quot;)
+        , m_ssaCalculator(graph)
+        , m_insertionSet(graph)
+    {
+    }
+    
+    bool run()
+    {
+        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
+        
+        m_graph.m_dominators.computeIfNecessary(m_graph);
+        
+        // Logically we wish to consider every NewObject and sink it. However it's probably not
+        // profitable to sink a NewObject that will always escape. So, first we do a very simple
+        // forward flow analysis that determines the set of NewObject nodes that have any chance
+        // of benefiting from object allocation sinking. Then we fixpoint the following rules:
+        //
+        // - For each NewObject, we turn the original NewObject into a PhantomNewObject and then
+        //   we insert MaterializeNewObject just before those escaping sites that come before any
+        //   other escaping sites - that is, there is no path between the allocation and those sites
+        //   that would see any other escape. Note that Upsilons constitute escaping sites. Then we
+        //   insert additional MaterializeNewObject nodes on Upsilons that feed into Phis that mix
+        //   materializations and the original PhantomNewObject. We then turn each PutByOffset over a
+        //   PhantomNewObject into a PutByOffsetHint.
+        //
+        // - We perform the same optimization for MaterializeNewObject. This allows us to cover
+        //   cases where we had MaterializeNewObject flowing into a PutByOffsetHint.
+        //
+        // We could also add this rule:
+        //
+        // - If all of the Upsilons of a Phi have a MaterializeNewObject that isn't used by anyone
+        //   else, then replace the Phi with the MaterializeNewObject.
+        //
+        //   FIXME: Implement this. Note that this totally doable but it requires some gnarly
+        //   code, and to be effective the pruner needs to be aware of it. Currently any Upsilon
+        //   is considered to be an escape even by the pruner, so it's unlikely that we'll see
+        //   many cases of Phi over Materializations.
+        //   https://bugs.webkit.org/show_bug.cgi?id=136927
+        
+        if (!performSinking())
+            return false;
+        
+        while (performSinking()) { }
+        
+        if (verbose) {
+            dataLog(&quot;Graph after sinking:\n&quot;);
+            m_graph.dump();
+        }
+        
+        return true;
+    }
+
+private:
+    bool performSinking()
+    {
+        m_graph.computeRefCounts();
+        performLivenessAnalysis(m_graph);
+        performOSRAvailabilityAnalysis(m_graph);
+        
+        CString graphBeforeSinking;
+        if (Options::verboseValidationFailure() &amp;&amp; Options::validateGraphAtEachPhase()) {
+            StringPrintStream out;
+            m_graph.dump(out);
+            graphBeforeSinking = out.toCString();
+        }
+        
+        if (verbose) {
+            dataLog(&quot;Graph before sinking:\n&quot;);
+            m_graph.dump();
+        }
+        
+        determineMaterializationPoints();
+        if (m_sinkCandidates.isEmpty())
+            return false;
+        
+        // At this point we are committed to sinking the sinking candidates.
+        placeMaterializationPoints();
+        lowerNonReadingOperationsOnPhantomAllocations();
+        promoteSunkenFields();
+        
+        if (Options::validateGraphAtEachPhase())
+            validate(m_graph, DumpGraph, graphBeforeSinking);
+        
+        if (verbose)
+            dataLog(&quot;Sinking iteration changed the graph.\n&quot;);
+        return true;
+    }
+    
+    void determineMaterializationPoints()
+    {
+        // The premise of this pass is that if there exists a point in the program where some
+        // path from a phantom allocation site to that point causes materialization, then *all*
+        // paths cause materialization. This should mean that there are never any redundant
+        // materializations.
+        
+        m_sinkCandidates.clear();
+        m_edgeToMaterializationPoint.clear();
+        
+        BlockMap&lt;HashMap&lt;Node*, bool&gt;&gt; materializedAtHead(m_graph);
+        BlockMap&lt;HashMap&lt;Node*, bool&gt;&gt; materializedAtTail(m_graph);
+        
+        bool changed;
+        do {
+            if (verbose)
+                dataLog(&quot;Doing iteration of materialization point placement.\n&quot;);
+            changed = false;
+            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+                HashMap&lt;Node*, bool&gt; materialized = materializedAtHead[block];
+                for (Node* node : *block) {
+                    handleNode(
+                        node,
+                        [&amp;] () {
+                            materialized.add(node, false);
+                        },
+                        [&amp;] (Node* escapee) {
+                            auto iter = materialized.find(escapee);
+                            if (iter != materialized.end())
+                                iter-&gt;value = true;
+                        });
+                }
+                
+                if (verbose)
+                    dataLog(&quot;    Materialized at tail of &quot;, pointerDump(block), &quot;: &quot;, mapDump(materialized), &quot;\n&quot;);
+                
+                if (materialized == materializedAtTail[block])
+                    continue;
+                
+                materializedAtTail[block] = materialized;
+                changed = true;
+                
+                // Only propagate things to our successors if they are alive in all successors.
+                // So, we prune materialized-at-tail to only include things that are live.
+                Vector&lt;Node*&gt; toRemove;
+                for (auto pair : materialized) {
+                    if (!block-&gt;ssa-&gt;liveAtTail.contains(pair.key))
+                        toRemove.append(pair.key);
+                }
+                for (Node* key : toRemove)
+                    materialized.remove(key);
+                
+                for (BasicBlock* successorBlock : block-&gt;successors()) {
+                    for (auto pair : materialized) {
+                        materializedAtHead[successorBlock].add(
+                            pair.key, false).iterator-&gt;value |= pair.value;
+                    }
+                }
+            }
+        } while (changed);
+        
+        // Determine the sink candidates. Broadly, a sink candidate is a node that handleNode()
+        // believes is sinkable, and one of the following is true:
+        //
+        // 1) There exists a basic block with only backward outgoing edges (or no outgoing edges)
+        //    in which the node wasn't materialized. This is meant to catch effectively-infinite
+        //    loops in which we don't need to have allocated the object.
+        //
+        // 2) There exists a basic block at the tail of which the node is not materialized and the
+        //    node is dead.
+        //
+        // 3) The sum of execution counts of the materializations is less than the sum of
+        //    execution counts of the original node.
+        //
+        // We currently implement only rule #2.
+        // FIXME: Implement the two other rules.
+        // https://bugs.webkit.org/show_bug.cgi?id=137073 (rule #1)
+        // https://bugs.webkit.org/show_bug.cgi?id=137074 (rule #3)
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (auto pair : materializedAtTail[block]) {
+                if (pair.value)
+                    continue; // It was materialized.
+                
+                if (block-&gt;ssa-&gt;liveAtTail.contains(pair.key))
+                    continue; // It might still get materialized in all of the successors.
+                
+                // We know that it died in this block and it wasn't materialized. That means that
+                // if we sink this allocation, then *this* will be a path along which we never
+                // have to allocate. Profit!
+                m_sinkCandidates.add(pair.key);
+            }
+        }
+        
+        if (m_sinkCandidates.isEmpty())
+            return;
+        
+        // A materialization edge exists at any point where a node escapes but hasn't been
+        // materialized yet.
+        //
+        // FIXME: This can create duplicate allocations when we really only needed to perform one.
+        // For example:
+        //
+        //     var o = new Object();
+        //     if (rare) {
+        //         if (stuff)
+        //             call(o); // o escapes here.
+        //         return;
+        //     }
+        //     // o doesn't escape down here.
+        //
+        // In this example, we would place a materialization point at call(o) and then we would find
+        // ourselves having to insert another one at the implicit else case of that if statement
+        // ('cause we've broken critical edges). We would instead really like to just have one
+        // materialization point right at the top of the then case of &quot;if (rare)&quot;. To do this, we can
+        // find the LCA of the various materializations in the dom tree.
+        // https://bugs.webkit.org/show_bug.cgi?id=137124
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            HashSet&lt;Node*&gt; materialized;
+            for (auto pair : materializedAtHead[block]) {
+                if (pair.value &amp;&amp; m_sinkCandidates.contains(pair.key))
+                    materialized.add(pair.key);
+            }
+            
+            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                Node* node = block-&gt;at(nodeIndex);
+                
+                handleNode(
+                    node,
+                    [&amp;] () { },
+                    [&amp;] (Node* escapee) {
+                        if (!m_sinkCandidates.contains(escapee))
+                            return;
+                        
+                        if (!materialized.add(escapee).isNewEntry)
+                            return;
+                        
+                        Node* materialize = createMaterialize(escapee, node-&gt;origin);
+                        if (verbose)
+                            dataLog(&quot;Adding materialization point: &quot;, node, &quot;-&gt;&quot;, escapee, &quot; = &quot;, materialize, &quot;\n&quot;);
+                        m_edgeToMaterializationPoint.add(
+                            std::make_pair(node, escapee), materialize);
+                    });
+            }
+        }
+    }
+    
+    void placeMaterializationPoints()
+    {
+        m_ssaCalculator.reset();
+        
+        HashMap&lt;Node*, SSACalculator::Variable*&gt; nodeToVariable;
+        Vector&lt;Node*&gt; indexToNode;
+        
+        for (Node* node : m_sinkCandidates) {
+            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
+            nodeToVariable.add(node, variable);
+            ASSERT(indexToNode.size() == variable-&gt;index());
+            indexToNode.append(node);
+        }
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                if (SSACalculator::Variable* variable = nodeToVariable.get(node))
+                    m_ssaCalculator.newDef(variable, block, node);
+                
+                m_graph.doToChildren(
+                    node,
+                    [&amp;] (Edge edge) {
+                        Node* materialize =
+                            m_edgeToMaterializationPoint.get(std::make_pair(node, edge.node()));
+                        if (!materialize)
+                            return;
+                        
+                        m_ssaCalculator.newDef(
+                            nodeToVariable.get(edge.node()), block, materialize);
+                    });
+            }
+        }
+        
+        m_ssaCalculator.computePhis(
+            [&amp;] (SSACalculator::Variable* variable, BasicBlock* block) -&gt; Node* {
+                Node* allocation = indexToNode[variable-&gt;index()];
+                if (!block-&gt;ssa-&gt;liveAtHead.contains(allocation))
+                    return nullptr;
+                
+                Node* phiNode = m_graph.addNode(allocation-&gt;prediction(), Phi, NodeOrigin());
+                phiNode-&gt;mergeFlags(NodeResultJS);
+                return phiNode;
+            });
+        
+        // Place Phis in the right places. Replace all uses of any allocation with the appropriate
+        // materialization. Create the appropriate Upsilon nodes.
+        LocalOSRAvailabilityCalculator availabilityCalculator;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            HashMap&lt;Node*, Node*&gt; mapping;
+            
+            for (Node* candidate : block-&gt;ssa-&gt;liveAtHead) {
+                SSACalculator::Variable* variable = nodeToVariable.get(candidate);
+                if (!variable)
+                    continue;
+                
+                SSACalculator::Def* def = m_ssaCalculator.reachingDefAtHead(block, variable);
+                if (!def)
+                    continue;
+                
+                mapping.set(indexToNode[variable-&gt;index()], def-&gt;value());
+            }
+            
+            availabilityCalculator.beginBlock(block);
+            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
+                m_insertionSet.insert(0, phiDef-&gt;value());
+                
+                Node* originalNode = indexToNode[phiDef-&gt;variable()-&gt;index()];
+                insertOSRHintsForUpdate(
+                    m_insertionSet, 0, NodeOrigin(), availabilityCalculator.m_availability,
+                    originalNode, phiDef-&gt;value());
+
+                mapping.set(originalNode, phiDef-&gt;value());
+            }
+            
+            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                Node* node = block-&gt;at(nodeIndex);
+
+                m_graph.doToChildren(
+                    node,
+                    [&amp;] (Edge edge) {
+                        Node* materialize = m_edgeToMaterializationPoint.get(
+                            std::make_pair(node, edge.node()));
+                        if (materialize) {
+                            m_insertionSet.insert(nodeIndex, materialize);
+                            insertOSRHintsForUpdate(
+                                m_insertionSet, nodeIndex, node-&gt;origin,
+                                availabilityCalculator.m_availability, edge.node(), materialize);
+                            mapping.set(edge.node(), materialize);
+                        }
+                    });
+
+                availabilityCalculator.executeNode(node);
+                
+                m_graph.doToChildren(
+                    node,
+                    [&amp;] (Edge&amp; edge) {
+                        if (Node* materialize = mapping.get(edge.node()))
+                            edge.setNode(materialize);
+                    });
+            }
+            
+            size_t upsilonInsertionPoint = block-&gt;size() - 1;
+            NodeOrigin upsilonOrigin = block-&gt;last()-&gt;origin;
+            for (BasicBlock* successorBlock : block-&gt;successors()) {
+                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
+                    Node* phiNode = phiDef-&gt;value();
+                    SSACalculator::Variable* variable = phiDef-&gt;variable();
+                    Node* allocation = indexToNode[variable-&gt;index()];
+                    
+                    Node* originalIncoming = mapping.get(allocation);
+                    Node* incoming;
+                    if (originalIncoming == allocation) {
+                        // If we have a Phi that combines materializations with the original
+                        // phantom object, then the path with the phantom object must materialize.
+                        
+                        incoming = createMaterialize(allocation, upsilonOrigin);
+                        m_insertionSet.insert(upsilonInsertionPoint, incoming);
+                        insertOSRHintsForUpdate(
+                            m_insertionSet, upsilonInsertionPoint, upsilonOrigin,
+                            availabilityCalculator.m_availability, originalIncoming, incoming);
+                    } else
+                        incoming = originalIncoming;
+                    
+                    Node* upsilon = m_insertionSet.insertNode(
+                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
+                        OpInfo(phiNode), incoming-&gt;defaultEdge());
+                    
+                    if (originalIncoming == allocation) {
+                        m_edgeToMaterializationPoint.add(
+                            std::make_pair(upsilon, allocation), incoming);
+                    }
+                }
+            }
+            
+            m_insertionSet.execute(block);
+        }
+        
+        // At this point we have dummy materialization nodes along with edges to them. This means
+        // that the part of the control flow graph that prefers to see actual object allocations
+        // is completely fixed up, except for the materializations themselves.
+    }
+    
+    void lowerNonReadingOperationsOnPhantomAllocations()
+    {
+        // Lower everything but reading operations on phantom allocations. We absolutely have to
+        // lower all writes so as to reveal them to the SSA calculator. We cannot lower reads
+        // because the whole point is that those go away completely.
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                Node* node = block-&gt;at(nodeIndex);
+                switch (node-&gt;op()) {
+                case PutByOffset: {
+                    if (m_sinkCandidates.contains(node-&gt;child2().node()))
+                        node-&gt;convertToPutByOffsetHint();
+                    break;
+                }
+                    
+                case PutStructure: {
+                    if (m_sinkCandidates.contains(node-&gt;child1().node())) {
+                        Node* structure = m_insertionSet.insertConstant(
+                            nodeIndex, node-&gt;origin, JSValue(node-&gt;transition()-&gt;next));
+                        node-&gt;convertToPutStructureHint(structure);
+                    }
+                    break;
+                }
+                    
+                case NewObject: {
+                    if (m_sinkCandidates.contains(node)) {
+                        Node* structure = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node-&gt;origin, JSValue(node-&gt;structure()));
+                        m_insertionSet.insertNode(
+                            nodeIndex + 1, SpecNone, PutStructureHint, node-&gt;origin,
+                            Edge(node, KnownCellUse), Edge(structure, KnownCellUse));
+                        node-&gt;convertToPhantomNewObject();
+                    }
+                    break;
+                }
+                    
+                case MaterializeNewObject: {
+                    if (m_sinkCandidates.contains(node)) {
+                        m_insertionSet.insertNode(
+                            nodeIndex + 1, SpecNone, PutStructureHint, node-&gt;origin,
+                            Edge(node, KnownCellUse), m_graph.varArgChild(node, 0));
+                        for (unsigned i = 0; i &lt; node-&gt;objectMaterializationData().m_properties.size(); ++i) {
+                            m_insertionSet.insertNode(
+                                nodeIndex + 1, SpecNone, PutByOffsetHint, node-&gt;origin,
+                                Edge(node, KnownCellUse), m_graph.varArgChild(node, i + 1));
+                        }
+                        node-&gt;convertToPhantomNewObject();
+                    }
+                    break;
+                }
+                    
+                case StoreBarrier:
+                case StoreBarrierWithNullCheck: {
+                    if (m_sinkCandidates.contains(node-&gt;child1().node()))
+                        node-&gt;convertToPhantom();
+                    break;
+                }
+                    
+                default:
+                    break;
+                }
+                
+                m_graph.doToChildren(
+                    node,
+                    [&amp;] (Edge&amp; edge) {
+                        if (m_sinkCandidates.contains(edge.node()))
+                            edge.setUseKind(KnownCellUse);
+                    });
+            }
+            m_insertionSet.execute(block);
+        }
+    }
+    
+    void promoteSunkenFields()
+    {
+        // Henceforth when we encounter a materialization point, we will want to ask *who* it is
+        // a materialization for. Invert the map to be able to answer such questions.
+        m_materializationPointToEscapee.clear();
+        for (auto pair : m_edgeToMaterializationPoint)
+            m_materializationPointToEscapee.add(pair.value, pair.key.second);
+        
+        // Collect the set of heap locations that we will be operating over.
+        HashSet&lt;PromotedHeapLocation&gt; locations;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                promoteHeapAccess(
+                    node,
+                    [&amp;] (PromotedHeapLocation location, Edge) {
+                        locations.add(location);
+                    },
+                    [&amp;] (PromotedHeapLocation location) {
+                        locations.add(location);
+                    });
+            }
+        }
+        
+        // Figure out which locations belong to which allocations.
+        m_locationsForAllocation.clear();
+        for (PromotedHeapLocation location : locations) {
+            auto result = m_locationsForAllocation.add(location.base(), Vector&lt;PromotedHeapLocation&gt;());
+            ASSERT(!result.iterator-&gt;value.contains(location));
+            result.iterator-&gt;value.append(location);
+        }
+        
+        // For each sunken thingy, make sure we create Bottom values for all of its fields.
+        // Note that this has the hilarious slight inefficiency of creating redundant hints for
+        // things that were previously materializations. This should only impact compile times and
+        // not code quality, and it's necessary for soundness without some data structure hackage.
+        // For example, a MaterializeNewObject that we choose to sink may have new fields added to
+        // it conditionally. That would necessitate Bottoms.
+        Node* bottom = nullptr;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            if (block == m_graph.block(0))
+                bottom = m_insertionSet.insertNode(0, SpecNone, BottomValue, NodeOrigin());
+            
+            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                Node* node = block-&gt;at(nodeIndex);
+                for (PromotedHeapLocation location : m_locationsForAllocation.get(node)) {
+                    m_insertionSet.insert(
+                        nodeIndex + 1, location.createHint(m_graph, node-&gt;origin, bottom));
+                }
+            }
+            m_insertionSet.execute(block);
+        }
+
+        m_ssaCalculator.reset();
+
+        // Collect the set of &quot;variables&quot; that we will be sinking.
+        m_locationToVariable.clear();
+        m_indexToLocation.clear();
+        for (PromotedHeapLocation location : locations) {
+            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
+            m_locationToVariable.add(location, variable);
+            ASSERT(m_indexToLocation.size() == variable-&gt;index());
+            m_indexToLocation.append(location);
+        }
+        
+        // Create Defs from the existing hints.
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                promoteHeapAccess(
+                    node,
+                    [&amp;] (PromotedHeapLocation location, Edge value) {
+                        SSACalculator::Variable* variable = m_locationToVariable.get(location);
+                        m_ssaCalculator.newDef(variable, block, value.node());
+                    },
+                    [&amp;] (PromotedHeapLocation) { });
+            }
+        }
+        
+        // OMG run the SSA calculator to create Phis!
+        m_ssaCalculator.computePhis(
+            [&amp;] (SSACalculator::Variable* variable, BasicBlock* block) -&gt; Node* {
+                PromotedHeapLocation location = m_indexToLocation[variable-&gt;index()];
+                if (!block-&gt;ssa-&gt;liveAtHead.contains(location.base()))
+                    return nullptr;
+                
+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
+                phiNode-&gt;mergeFlags(NodeResultJS);
+                return phiNode;
+            });
+        
+        // Place Phis in the right places, replace all uses of any load with the appropriate
+        // value, and create the appropriate Upsilon nodes.
+        m_graph.clearReplacements();
+        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
+            // This mapping table is intended to be lazy. If something is omitted from the table,
+            // it means that there haven't been any local stores to that promoted heap location.
+            m_localMapping.clear();
+            
+            // Insert the Phi functions that we had previously created.
+            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
+                PromotedHeapLocation location = m_indexToLocation[phiDef-&gt;variable()-&gt;index()];
+                
+                m_insertionSet.insert(
+                    0, phiDef-&gt;value());
+                m_insertionSet.insert(
+                    0, location.createHint(m_graph, NodeOrigin(), phiDef-&gt;value()));
+                m_localMapping.add(location, phiDef-&gt;value());
+            }
+            
+            if (verbose)
+                dataLog(&quot;Local mapping at &quot;, pointerDump(block), &quot;: &quot;, mapDump(m_localMapping), &quot;\n&quot;);
+            
+            // Process the block and replace all uses of loads with the promoted value.
+            for (Node* node : *block) {
+                m_graph.performSubstitution(node);
+                
+                if (Node* escapee = m_materializationPointToEscapee.get(node))
+                    populateMaterialize(block, node, escapee);
+                
+                promoteHeapAccess(
+                    node,
+                    [&amp;] (PromotedHeapLocation location, Edge value) {
+                        m_localMapping.set(location, value.node());
+                    },
+                    [&amp;] (PromotedHeapLocation location) {
+                        node-&gt;replaceWith(resolve(block, location));
+                    });
+            }
+            
+            // Gotta drop some Upsilons.
+            size_t upsilonInsertionPoint = block-&gt;size() - 1;
+            NodeOrigin upsilonOrigin = block-&gt;last()-&gt;origin;
+            for (BasicBlock* successorBlock : block-&gt;successors()) {
+                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
+                    Node* phiNode = phiDef-&gt;value();
+                    SSACalculator::Variable* variable = phiDef-&gt;variable();
+                    PromotedHeapLocation location = m_indexToLocation[variable-&gt;index()];
+                    Node* incoming = resolve(block, location);
+                    
+                    m_insertionSet.insertNode(
+                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
+                        OpInfo(phiNode), incoming-&gt;defaultEdge());
+                }
+            }
+            
+            m_insertionSet.execute(block);
+        }
+    }
+    
+    Node* resolve(BasicBlock* block, PromotedHeapLocation location)
+    {
+        if (Node* result = m_localMapping.get(location))
+            return result;
+        
+        // This implies that there is no local mapping. Find a non-local mapping.
+        SSACalculator::Def* def = m_ssaCalculator.nonLocalReachingDef(
+            block, m_locationToVariable.get(location));
+        ASSERT(def);
+        ASSERT(def-&gt;value());
+        m_localMapping.add(location, def-&gt;value());
+        return def-&gt;value();
+    }
+
+    template&lt;typename SinkCandidateFunctor, typename EscapeFunctor&gt;
+    void handleNode(
+        Node* node,
+        const SinkCandidateFunctor&amp; sinkCandidate,
+        const EscapeFunctor&amp; escape)
+    {
+        switch (node-&gt;op()) {
+        case NewObject:
+        case MaterializeNewObject:
+            sinkCandidate();
+            m_graph.doToChildren(
+                node,
+                [&amp;] (Edge edge) {
+                    escape(edge.node());
+                });
+            break;
+            
+        case CheckStructure:
+        case GetByOffset:
+        case MultiGetByOffset:
+        case PutStructure:
+        case GetGetterSetterByOffset:
+        case MovHint:
+        case Phantom:
+        case Check:
+        case HardPhantom:
+        case StoreBarrier:
+        case StoreBarrierWithNullCheck:
+        case PutByOffsetHint:
+            break;
+            
+        case PutByOffset:
+            escape(node-&gt;child3().node());
+            break;
+            
+        case MultiPutByOffset:
+            // FIXME: In the future we should be able to handle this. It's just a matter of
+            // building the appropriate *Hint variant of this instruction, along with a
+            // PhantomStructureSelect node - since this transforms the Structure in a conditional
+            // way.
+            // https://bugs.webkit.org/show_bug.cgi?id=136924
+            escape(node-&gt;child1().node());
+            escape(node-&gt;child2().node());
+            break;
+
+        default:
+            m_graph.doToChildren(
+                node,
+                [&amp;] (Edge edge) {
+                    escape(edge.node());
+                });
+            break;
+        }
+    }
+    
+    Node* createMaterialize(Node* escapee, const NodeOrigin whereOrigin)
+    {
+        switch (escapee-&gt;op()) {
+        case NewObject:
+        case MaterializeNewObject: {
+            ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
+            
+            Node* result = m_graph.addNode(
+                escapee-&gt;prediction(), Node::VarArg, MaterializeNewObject,
+                NodeOrigin(
+                    escapee-&gt;origin.semantic,
+                    whereOrigin.forExit),
+                OpInfo(data), OpInfo(), 0, 0);
+            return result;
+        }
+            
+        default:
+            DFG_CRASH(m_graph, escapee, &quot;Bad escapee op&quot;);
+            return nullptr;
+        }
+    }
+    
+    void populateMaterialize(BasicBlock* block, Node* node, Node* escapee)
+    {
+        switch (node-&gt;op()) {
+        case MaterializeNewObject: {
+            ObjectMaterializationData&amp; data = node-&gt;objectMaterializationData();
+            unsigned firstChild = m_graph.m_varArgChildren.size();
+            
+            Vector&lt;PromotedHeapLocation&gt; locations = m_locationsForAllocation.get(escapee);
+            
+            PromotedHeapLocation structure(StructurePLoc, escapee);
+            ASSERT(locations.contains(structure));
+            
+            m_graph.m_varArgChildren.append(Edge(resolve(block, structure), KnownCellUse));
+            
+            for (unsigned i = 0; i &lt; locations.size(); ++i) {
+                switch (locations[i].kind()) {
+                case StructurePLoc: {
+                    ASSERT(locations[i] == structure);
+                    break;
+                }
+                    
+                case NamedPropertyPLoc: {
+                    Node* value = resolve(block, locations[i]);
+                    if (value-&gt;op() == BottomValue) {
+                        // We can skip Bottoms entirely.
+                        break;
+                    }
+                    
+                    data.m_properties.append(PhantomPropertyValue(locations[i].info()));
+                    m_graph.m_varArgChildren.append(value);
+                    break;
+                }
+                    
+                default:
+                    DFG_CRASH(m_graph, node, &quot;Bad location kind&quot;);
+                }
+            }
+            
+            node-&gt;children = AdjacencyList(
+                AdjacencyList::Variable,
+                firstChild, m_graph.m_varArgChildren.size() - firstChild);
+            break;
+        }
+            
+        default:
+            DFG_CRASH(m_graph, node, &quot;Bad materialize op&quot;);
+            break;
+        }
+    }
+    
+    SSACalculator m_ssaCalculator;
+    HashSet&lt;Node*&gt; m_sinkCandidates;
+    HashMap&lt;std::pair&lt;Node*, Node*&gt;, Node*&gt; m_edgeToMaterializationPoint;
+    HashMap&lt;Node*, Node*&gt; m_materializationPointToEscapee;
+    HashMap&lt;Node*, Vector&lt;PromotedHeapLocation&gt;&gt; m_locationsForAllocation;
+    HashMap&lt;PromotedHeapLocation, SSACalculator::Variable*&gt; m_locationToVariable;
+    Vector&lt;PromotedHeapLocation&gt; m_indexToLocation;
+    HashMap&lt;PromotedHeapLocation, Node*&gt; m_localMapping;
+    InsertionSet m_insertionSet;
+};
+    
+bool performObjectAllocationSinking(Graph&amp; graph)
+{
+    SamplingRegion samplingRegion(&quot;DFG Object Allocation Sinking Phase&quot;);
+    return runPhase&lt;ObjectAllocationSinkingPhase&gt;(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGObjectAllocationSinkingPhase_h
+#define DFGObjectAllocationSinkingPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Sinks object allocations down to their uses. This will sink the allocations over OSR exits, by
+// replacing all stores to those objects with store hints so that OSR exit can materialize the
+// object. This may sink allocations past returns, creating control flow paths along which the
+// objects are not allocated at all. Replaces all uses of the objects' fields with SSA data flow.
+
+bool performObjectAllocationSinking(Graph&amp;);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGObjectAllocationSinkingPhase_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGObjectMaterializationDatacpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGObjectMaterializationData.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &lt;wtf/ListDump.h&gt;
+
+namespace JSC { namespace DFG {
+
+void PhantomPropertyValue::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;id&quot;, m_identifierNumber);
+}
+
+void ObjectMaterializationData::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;[&quot;, listDump(m_properties), &quot;]&quot;);
+}
+
+float ObjectMaterializationData::oneWaySimilarityScore(
+    const ObjectMaterializationData&amp; other) const
+{
+    unsigned numHits = 0;
+    for (PhantomPropertyValue value : m_properties) {
+        if (other.m_properties.contains(value))
+            numHits++;
+    }
+    return static_cast&lt;float&gt;(numHits) / static_cast&lt;float&gt;(m_properties.size());
+}
+
+float ObjectMaterializationData::similarityScore(const ObjectMaterializationData&amp; other) const
+{
+    return std::min(oneWaySimilarityScore(other), other.oneWaySimilarityScore(*this));
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGObjectMaterializationDatah"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectMaterializationData.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGObjectMaterializationData_h
+#define DFGObjectMaterializationData_h
+
+#if ENABLE(DFG_JIT)
+
+#include &lt;limits.h&gt;
+#include &lt;wtf/MathExtras.h&gt;
+#include &lt;wtf/PrintStream.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC { namespace DFG {
+
+struct PhantomPropertyValue {
+    PhantomPropertyValue()
+        : m_identifierNumber(UINT_MAX)
+    {
+    }
+    
+    PhantomPropertyValue(unsigned identifierNumber)
+        : m_identifierNumber(identifierNumber)
+    {
+    }
+    
+    unsigned m_identifierNumber;
+    
+    bool operator==(const PhantomPropertyValue&amp; other) const
+    {
+        return m_identifierNumber == other.m_identifierNumber;
+    }
+    
+    void dump(PrintStream&amp;) const;
+};
+
+struct ObjectMaterializationData {
+    // Determines the meaning of the passed nodes.
+    Vector&lt;PhantomPropertyValue&gt; m_properties;
+    
+    void dump(PrintStream&amp;) const;
+    
+    // The fraction of my properties that the other data has.
+    float oneWaySimilarityScore(const ObjectMaterializationData&amp;) const;
+    
+    // The minimum of the two possible one-way scores.
+    float similarityScore(const ObjectMaterializationData&amp;) const;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGObjectMaterializationData_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomCanonicalizationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -52,24 +52,13 @@
</span><span class="cx">         ASSERT(m_graph.m_form == SSA);
</span><span class="cx">         
</span><span class="cx">         m_graph.clearFlagsOnAllNodes(NodeNeedsPhantom | NodeNeedsHardPhantom | NodeRelevantToOSR);
</span><ins>+        m_graph.mergeRelevantToOSR();
</ins><span class="cx">         
</span><span class="cx">         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
</span><span class="cx">             BasicBlock* block = m_graph.block(blockIndex);
</span><span class="cx">             if (!block)
</span><span class="cx">                 continue;
</span><span class="cx">             
</span><del>-            for (unsigned i = block-&gt;size(); i--;) {
-                Node* node = block-&gt;at(i);
-                if (node-&gt;op() == MovHint)
-                    node-&gt;child1()-&gt;mergeFlags(NodeRelevantToOSR);
-            }
-        }
-        
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            
</del><span class="cx">             unsigned sourceIndex = 0;
</span><span class="cx">             unsigned targetIndex = 0;
</span><span class="cx">             while (sourceIndex &lt; block-&gt;size()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -74,17 +74,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            
-            for (unsigned i = block-&gt;size(); i--;) {
-                Node* node = block-&gt;at(i);
-                if (node-&gt;op() == MovHint)
-                    node-&gt;child1()-&gt;mergeFlags(NodeRelevantToOSR);
-            }
-        }
</del><ins>+        m_graph.mergeRelevantToOSR();
</ins><span class="cx">         
</span><span class="cx">         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
</span><span class="cx">             BasicBlock* block = m_graph.block(blockIndex);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhiChildrencpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGPhiChildren.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGGraph.h&quot;
+
+namespace JSC { namespace DFG {
+
+PhiChildren::PhiChildren()
+{
+}
+
+PhiChildren::PhiChildren(Graph&amp; graph)
+{
+    for (BasicBlock* block : graph.blocksInNaturalOrder()) {
+        for (Node* node : *block) {
+            if (node-&gt;op() != Upsilon)
+                continue;
+            
+            m_children.add(node-&gt;phi(), List()).iterator-&gt;value.append(node);
+        }
+    }
+}
+
+PhiChildren::~PhiChildren()
+{
+}
+
+const PhiChildren::List&amp; PhiChildren::upsilonsOf(Node* node) const
+{
+    ASSERT(node-&gt;op() == Phi);
+    return m_children.find(node)-&gt;value;
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhiChildrenh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhiChildren.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGPhiChildren_h
+#define DFGPhiChildren_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGNode.h&quot;
+#include &lt;wtf/HashSet.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class PhiChildren {
+public:
+    typedef Vector&lt;Node*, 3&gt; List;
+    
+    PhiChildren();
+    PhiChildren(Graph&amp;);
+    ~PhiChildren();
+    
+    // The list of Upsilons that point to the children of the Phi.
+    const List&amp; upsilonsOf(Node*) const;
+    
+    template&lt;typename Functor&gt;
+    void forAllIncomingValues(Node* node, const Functor&amp; functor)
+    {
+        for (Node* upsilon : upsilonsOf(node))
+            functor(upsilon-&gt;child1().node());
+    }
+    
+    // This walks the Phi graph.
+    template&lt;typename Functor&gt;
+    void forAllTransitiveIncomingValues(Node* node, const Functor&amp; functor)
+    {
+        if (node-&gt;op() != Phi) {
+            functor(node);
+            return;
+        }
+        HashSet&lt;Node*&gt; seen;
+        Vector&lt;Node*&gt; worklist;
+        seen.add(node);
+        worklist.append(node);
+        while (!worklist.isEmpty()) {
+            Node* currentNode = worklist.takeLast();
+            forAllIncomingValues(
+                currentNode,
+                [&amp;] (Node* incomingNode) {
+                    if (incomingNode-&gt;op() == Phi) {
+                        if (seen.add(incomingNode).isNewEntry)
+                            worklist.append(incomingNode);
+                    } else
+                        functor(incomingNode);
+                });
+        }
+    }
+    
+private:
+    HashMap&lt;Node*, List&gt; m_children;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPhiChildren_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #include &quot;DFGLoopPreHeaderCreationPhase.h&quot;
</span><span class="cx"> #include &quot;DFGOSRAvailabilityAnalysisPhase.h&quot;
</span><span class="cx"> #include &quot;DFGOSREntrypointCreationPhase.h&quot;
</span><ins>+#include &quot;DFGObjectAllocationSinkingPhase.h&quot;
</ins><span class="cx"> #include &quot;DFGPhantomCanonicalizationPhase.h&quot;
</span><span class="cx"> #include &quot;DFGPhantomRemovalPhase.h&quot;
</span><span class="cx"> #include &quot;DFGPredictionInjectionPhase.h&quot;
</span><span class="lines">@@ -277,6 +278,7 @@
</span><span class="cx">     if (validationEnabled()) {
</span><span class="cx">         dfg.m_dominators.computeIfNecessary(dfg);
</span><span class="cx">         dfg.m_naturalLoops.computeIfNecessary(dfg);
</span><ins>+        dfg.m_prePostNumbering.computeIfNecessary(dfg);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     switch (mode) {
</span><span class="lines">@@ -325,11 +327,16 @@
</span><span class="cx">         performCFA(dfg);
</span><span class="cx">         performConstantFolding(dfg);
</span><span class="cx">         performPhantomCanonicalization(dfg); // Reduce the graph size a lot.
</span><del>-        if (performStrengthReduction(dfg)) {
</del><ins>+        changed = false;
+        changed |= performStrengthReduction(dfg);
+        changed |= performCriticalEdgeBreaking(dfg);
+        changed |= performObjectAllocationSinking(dfg);
+        if (changed) {
</ins><span class="cx">             // State-at-tail and state-at-head will be invalid if we did strength reduction since
</span><span class="cx">             // it might increase live ranges.
</span><span class="cx">             performLivenessAnalysis(dfg);
</span><span class="cx">             performCFA(dfg);
</span><ins>+            performConstantFolding(dfg);
</ins><span class="cx">         }
</span><span class="cx">         performLICM(dfg);
</span><span class="cx">         performPhantomCanonicalization(dfg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPrePostNumberingcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,89 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGPrePostNumbering.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGBlockMapInlines.h&quot;
+#include &quot;DFGBlockWorklist.h&quot;
+#include &quot;DFGGraph.h&quot;
+
+namespace JSC { namespace DFG {
+
+PrePostNumbering::PrePostNumbering() { }
+PrePostNumbering::~PrePostNumbering() { }
+
+void PrePostNumbering::compute(Graph&amp; graph)
+{
+    m_map = BlockMap&lt;Numbering&gt;(graph);
+    
+    PostOrderBlockWorklist worklist;
+    worklist.push(graph.block(0));
+    unsigned nextPreNumber = 0;
+    unsigned nextPostNumber = 0;
+    while (BlockWithOrder item = worklist.pop()) {
+        switch (item.order) {
+        case PreOrder:
+            m_map[item.block].m_preNumber = nextPreNumber++;
+            worklist.pushPost(item.block);
+            for (BasicBlock* successor : item.block-&gt;successors())
+                worklist.push(successor);
+            break;
+        case PostOrder:
+            m_map[item.block].m_postNumber = nextPostNumber++;
+            break;
+        }
+    }
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream&amp; out, EdgeKind kind)
+{
+    switch (kind) {
+    case ForwardEdge:
+        out.print(&quot;ForwardEdge&quot;);
+        return;
+    case CrossEdge:
+        out.print(&quot;CrossEdge&quot;);
+        return;
+    case BackEdge:
+        out.print(&quot;BackEdge&quot;);
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPrePostNumberingh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPrePostNumbering.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGPrePostNumbering_h
+#define DFGPrePostNumbering_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGAnalysis.h&quot;
+#include &quot;DFGBasicBlock.h&quot;
+#include &quot;DFGBlockMap.h&quot;
+
+namespace JSC { namespace DFG {
+
+enum EdgeKind {
+    ForwardEdge,
+    CrossEdge,
+    BackEdge
+};
+
+class PrePostNumbering : public Analysis&lt;PrePostNumbering&gt; {
+public:
+    PrePostNumbering();
+    ~PrePostNumbering();
+
+    void compute(Graph&amp;);
+    
+    unsigned preNumber(BasicBlock* block) const { return m_map[block].m_preNumber; }
+    unsigned postNumber(BasicBlock* block) const { return m_map[block].m_postNumber; }
+    
+    // Is from a strict ancestor of to?
+    bool isStrictAncestorOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return preNumber(from) &lt; preNumber(to)
+            &amp;&amp; postNumber(from) &gt; postNumber(to);
+    }
+    
+    bool isAncestorOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return from == to || isStrictAncestorOf(from, to);
+    }
+    
+    bool isStrictDescendantOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return isStrictAncestorOf(to, from);
+    }
+    
+    bool isDescendantOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return isAncestorOf(to, from);
+    }
+    
+    // This will give a bogus answer if there is actually no such edge. If you want to determine
+    // if there is any such edge, you have to do it yourself.
+    EdgeKind edgeKind(BasicBlock* from, BasicBlock* to) const
+    {
+        if (isStrictDescendantOf(to, from))
+            return ForwardEdge;
+        
+        if (isAncestorOf(to, from))
+            return BackEdge;
+        
+        return CrossEdge;
+    }
+    
+private:
+    struct Numbering {
+        unsigned m_preNumber;
+        unsigned m_postNumber;
+    };
+    
+    BlockMap&lt;Numbering&gt; m_map;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&amp;, JSC::DFG::EdgeKind);
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPrePostNumbering_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -560,7 +560,12 @@
</span><span class="cx">         case DoubleConstant:
</span><span class="cx">         case Int52Constant:
</span><span class="cx">         case Identity:
</span><del>-        case BooleanToNumber: {
</del><ins>+        case BooleanToNumber:
+        case PhantomNewObject:
+        case PutByOffsetHint:
+        case CheckStructureImmediate:
+        case PutStructureHint:
+        case MaterializeNewObject: {
</ins><span class="cx">             // This node should never be visible at this stage of compilation. It is
</span><span class="cx">             // inserted by fixup(), which follows this phase.
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPromoteHeapAccessh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGPromoteHeapAccess_h
+#define DFGPromoteHeapAccess_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGNode.h&quot;
+#include &quot;DFGPromotedHeapLocation.h&quot;
+
+namespace JSC { namespace DFG {
+
+// Note that the write functor is really the useful thing here. The read functor is only useful
+// for the object allocation sinking phase.
+template&lt;typename WriteFunctor, typename ReadFunctor&gt;
+void promoteHeapAccess(Node* node, const WriteFunctor&amp; write, const ReadFunctor&amp; read)
+{
+    switch (node-&gt;op()) {
+    case CheckStructure: {
+        if (node-&gt;child1()-&gt;isPhantomObjectAllocation())
+            read(PromotedHeapLocation(StructurePLoc, node-&gt;child1()));
+        break;
+    }
+    
+    case GetByOffset:
+    case GetGetterSetterByOffset: {
+        if (node-&gt;child2()-&gt;isPhantomObjectAllocation()) {
+            unsigned identifierNumber = node-&gt;storageAccessData().identifierNumber;
+            read(PromotedHeapLocation(NamedPropertyPLoc, node-&gt;child2(), identifierNumber));
+        }
+        break;
+    }
+
+    case MultiGetByOffset: {
+        if (node-&gt;child1()-&gt;isPhantomObjectAllocation()) {
+            unsigned identifierNumber = node-&gt;multiGetByOffsetData().identifierNumber;
+            read(PromotedHeapLocation(NamedPropertyPLoc, node-&gt;child1(), identifierNumber));
+        }
+        break;
+    }
+
+    case PutStructureHint: {
+        ASSERT(node-&gt;child1()-&gt;isPhantomObjectAllocation());
+        write(PromotedHeapLocation(StructurePLoc, node-&gt;child1()), node-&gt;child2());
+        break;
+    }
+
+    case PutByOffsetHint: {
+        ASSERT(node-&gt;child1()-&gt;isPhantomObjectAllocation());
+        unsigned identifierNumber = node-&gt;identifierNumber();
+        write(
+            PromotedHeapLocation(NamedPropertyPLoc, node-&gt;child1(), identifierNumber),
+            node-&gt;child2());
+        break;
+    }
+
+    default:
+        break;
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPromoteHeapAccess_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPromotedHeapLocationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,95 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;DFGPromotedHeapLocation.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGGraph.h&quot;
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+void PromotedLocationDescriptor::dump(PrintStream&amp; out) const
+{
+    out.print(m_kind, &quot;(&quot;, m_info, &quot;)&quot;);
+}
+
+Node* PromotedHeapLocation::createHint(Graph&amp; graph, NodeOrigin origin, Node* value)
+{
+    switch (kind()) {
+    case StructurePLoc:
+        return graph.addNode(
+            SpecNone, PutStructureHint, origin,
+            Edge(base(), KnownCellUse), Edge(value, KnownCellUse));
+        
+    case NamedPropertyPLoc:
+        return graph.addNode(
+            SpecNone, PutByOffsetHint, origin,
+            OpInfo(info()), Edge(base(), KnownCellUse), Edge(value, UntypedUse));
+        
+    case InvalidPromotedLocationKind:
+        return nullptr;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+void PromotedHeapLocation::dump(PrintStream&amp; out) const
+{
+    out.print(kind(), &quot;(&quot;, m_base, &quot;, &quot;, info(), &quot;)&quot;);
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream&amp; out, PromotedLocationKind kind)
+{
+    switch (kind) {
+    case InvalidPromotedLocationKind:
+        out.print(&quot;InvalidPromotedLocationKind&quot;);
+        return;
+        
+    case StructurePLoc:
+        out.print(&quot;StructurePLoc&quot;);
+        return;
+        
+    case NamedPropertyPLoc:
+        out.print(&quot;NamedPropertyPLoc&quot;);
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF;
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPromotedHeapLocationh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,172 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 DFGPromotedHeapLocation_h
+#define DFGPromotedHeapLocation_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGNode.h&quot;
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace DFG {
+
+enum PromotedLocationKind {
+    InvalidPromotedLocationKind,
+    
+    StructurePLoc,
+    NamedPropertyPLoc
+};
+
+class PromotedLocationDescriptor {
+public:
+    PromotedLocationDescriptor(
+        PromotedLocationKind kind = InvalidPromotedLocationKind, unsigned info = 0)
+        : m_kind(kind)
+        , m_info(info)
+    {
+    }
+    
+    bool operator!() const { return m_kind == InvalidPromotedLocationKind; }
+    
+    PromotedLocationKind kind() const { return m_kind; }
+    unsigned info() const { return m_info; }
+    
+    unsigned hash() const
+    {
+        return m_kind + m_info;
+    }
+    
+    bool operator==(const PromotedLocationDescriptor&amp; other) const
+    {
+        return m_kind == other.m_kind
+            &amp;&amp; m_info == other.m_info;
+    }
+    
+    bool operator!=(const PromotedLocationDescriptor&amp; other) const
+    {
+        return !(*this == other);
+    }
+
+    bool isHashTableDeletedValue() const
+    {
+        return m_kind == InvalidPromotedLocationKind &amp;&amp; m_info;
+    }
+    
+    void dump(PrintStream&amp; out) const;
+
+private:
+    PromotedLocationKind m_kind;
+    unsigned m_info;
+};
+
+class PromotedHeapLocation {
+public:
+    PromotedHeapLocation(
+        PromotedLocationKind kind = InvalidPromotedLocationKind,
+        Node* base = nullptr, unsigned info = 0)
+        : m_base(base)
+        , m_meta(kind, info)
+    {
+    }
+    
+    PromotedHeapLocation(
+        PromotedLocationKind kind, Edge base, unsigned info = 0)
+        : PromotedHeapLocation(kind, base.node(), info)
+    {
+    }
+    
+    PromotedHeapLocation(Node* base, PromotedLocationDescriptor meta)
+        : m_base(base)
+        , m_meta(meta)
+    {
+    }
+    
+    PromotedHeapLocation(WTF::HashTableDeletedValueType)
+        : m_base(nullptr)
+        , m_meta(InvalidPromotedLocationKind, 1)
+    {
+    }
+    
+    Node* createHint(Graph&amp;, NodeOrigin, Node* value);
+    
+    bool operator!() const { return kind() == InvalidPromotedLocationKind; }
+    
+    PromotedLocationKind kind() const { return m_meta.kind(); }
+    Node* base() const { return m_base; }
+    unsigned info() const { return m_meta.info(); }
+    PromotedLocationDescriptor descriptor() const { return m_meta; }
+    
+    unsigned hash() const
+    {
+        return m_meta.hash() + WTF::PtrHash&lt;Node*&gt;::hash(m_base);
+    }
+    
+    bool operator==(const PromotedHeapLocation&amp; other) const
+    {
+        return m_base == other.m_base
+            &amp;&amp; m_meta == other.m_meta;
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_meta.isHashTableDeletedValue();
+    }
+    
+    void dump(PrintStream&amp; out) const;
+    
+private:
+    Node* m_base;
+    PromotedLocationDescriptor m_meta;
+};
+
+struct PromotedHeapLocationHash {
+    static unsigned hash(const PromotedHeapLocation&amp; key) { return key.hash(); }
+    static bool equal(const PromotedHeapLocation&amp; a, const PromotedHeapLocation&amp; b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&amp;, JSC::DFG::PromotedLocationKind);
+
+template&lt;typename T&gt; struct DefaultHash;
+template&lt;&gt; struct DefaultHash&lt;JSC::DFG::PromotedHeapLocation&gt; {
+    typedef JSC::DFG::PromotedHeapLocationHash Hash;
+};
+
+template&lt;typename T&gt; struct HashTraits;
+template&lt;&gt; struct HashTraits&lt;JSC::DFG::PromotedHeapLocation&gt; : SimpleClassHashTraits&lt;JSC::DFG::PromotedHeapLocation&gt; {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPromotedHeapLocation_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSSACalculatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -66,6 +66,17 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SSACalculator::reset()
+{
+    m_variables.clear();
+    m_defs.clear();
+    m_phis.clear();
+    for (BlockIndex blockIndex = m_data.size(); blockIndex--;) {
+        m_data[blockIndex].m_defs.clear();
+        m_data[blockIndex].m_phis.clear();
+    }
+}
+
</ins><span class="cx"> SSACalculator::Variable* SSACalculator::newVariable()
</span><span class="cx"> {
</span><span class="cx">     return &amp;m_variables.alloc(Variable(m_variables.size()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSSACalculatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSSACalculator.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -105,6 +105,8 @@
</span><span class="cx">     SSACalculator(Graph&amp;);
</span><span class="cx">     ~SSACalculator();
</span><span class="cx">     
</span><ins>+    void reset();
+    
</ins><span class="cx">     class Variable {
</span><span class="cx">     public:
</span><span class="cx">         unsigned index() const { return m_index; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -270,6 +270,11 @@
</span><span class="cx">     case GetGenericPropertyEnumerator:
</span><span class="cx">     case GetEnumeratorPname:
</span><span class="cx">     case ToIndexString:
</span><ins>+    case PhantomNewObject:
+    case PutByOffsetHint:
+    case CheckStructureImmediate:
+    case PutStructureHint:
+    case MaterializeNewObject:
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     case NativeCall:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1415,7 +1415,7 @@
</span><span class="cx">         else
</span><span class="cx">             m_canExit = mayExit(m_jit.graph(), m_currentNode);
</span><span class="cx">         
</span><del>-        bool shouldExecuteEffects = m_interpreter.startExecuting(m_currentNode);
</del><ins>+        m_interpreter.startExecuting();
</ins><span class="cx">         m_jit.setForNode(m_currentNode);
</span><span class="cx">         m_codeOriginForExitTarget = m_currentNode-&gt;origin.forExit;
</span><span class="cx">         m_codeOriginForExitProfile = m_currentNode-&gt;origin.semantic;
</span><span class="lines">@@ -1472,8 +1472,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         // Make sure that the abstract state is rematerialized for the next node.
</span><del>-        if (shouldExecuteEffects)
-            m_interpreter.executeEffects(m_indexInBlock);
</del><ins>+        m_interpreter.executeEffects(m_indexInBlock);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Perform the most basic verification that children have been used correctly.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -4912,6 +4912,11 @@
</span><span class="cx">     case NativeConstruct:
</span><span class="cx">     case CheckBadCell:
</span><span class="cx">     case BottomValue:
</span><ins>+    case PhantomNewObject:
+    case PutByOffsetHint:
+    case CheckStructureImmediate:
+    case PutStructureHint:
+    case MaterializeNewObject:
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -4982,6 +4982,11 @@
</span><span class="cx">     case FiatInt52:
</span><span class="cx">     case CheckBadCell:
</span><span class="cx">     case BottomValue:
</span><ins>+    case PhantomNewObject:
+    case PutByOffsetHint:
+    case CheckStructureImmediate:
+    case PutStructureHint:
+    case MaterializeNewObject:
</ins><span class="cx">         DFG_CRASH(m_jit.graph(), node, &quot;Unexpected node&quot;);
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">         // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
</span><span class="cx">         // have to watch these because there is no way to transition away from it, but they are
</span><span class="cx">         // watchable and so we will assert if they aren't watched.
</span><ins>+        registerStructure(m_graph.m_vm.structureStructure.get());
</ins><span class="cx">         registerStructure(m_graph.m_vm.stringStructure.get());
</span><span class="cx">         registerStructure(m_graph.m_vm.getterSetterStructure.get());
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -187,8 +187,6 @@
</span><span class="cx">                 Node* node = block-&gt;node(i);
</span><span class="cx">                 if (m_graph.m_refCountState == ExactRefCount)
</span><span class="cx">                     V_EQUAL((node), m_myRefCounts.get(node), node-&gt;adjustedRefCount());
</span><del>-                else
-                    V_EQUAL((node), node-&gt;refCount(), 1);
</del><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             for (size_t i = 0 ; i &lt; block-&gt;size() - 1; ++i) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -168,6 +168,11 @@
</span><span class="cx">     case GetEnumeratorPname:
</span><span class="cx">     case ToIndexString:
</span><span class="cx">     case BottomValue:
</span><ins>+    case PhantomNewObject:
+    case PutByOffsetHint:
+    case CheckStructureImmediate:
+    case PutStructureHint:
+    case MaterializeNewObject:
</ins><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="cx">     case ProfiledCall:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExitPropertyValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;FTLExitPropertyValue.h&quot;
+
+#if ENABLE(FTL_JIT)
+
+namespace JSC { namespace FTL {
+
+void ExitPropertyValue::dump(PrintStream&amp; out) const
+{
+    out.print(m_location, &quot; =&gt; &quot;, m_value);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExitPropertyValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 FTLExitPropertyValue_h
+#define FTLExitPropertyValue_h
+
+#if ENABLE(FTL_JIT)
+
+#include &quot;DFGPromotedHeapLocation.h&quot;
+#include &quot;FTLExitValue.h&quot;
+
+namespace JSC { namespace FTL {
+
+class ExitPropertyValue {
+public:
+    ExitPropertyValue()
+    {
+    }
+    
+    ExitPropertyValue(DFG::PromotedLocationDescriptor location, const ExitValue&amp; value)
+        : m_location(location)
+        , m_value(value)
+    {
+        ASSERT(!!location == !!value);
+    }
+    
+    bool operator!() const { return !m_location; }
+    
+    DFG::PromotedLocationDescriptor location() const { return m_location; }
+    const ExitValue&amp; value() const { return m_value; }
+    
+    void dump(PrintStream&amp; out) const;
+
+private:
+    DFG::PromotedLocationDescriptor m_location;
+    ExitValue m_value;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLExitPropertyValue_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExitTimeObjectMaterializationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;FTLExitTimeObjectMaterialization.h&quot;
+
+#if ENABLE(FTL_JIT)
+
+#include &quot;DFGGraph.h&quot;
+
+namespace JSC { namespace FTL {
+
+using namespace JSC::DFG;
+
+ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type)
+    : m_type(type)
+{
+}
+
+ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization()
+{
+}
+
+void ExitTimeObjectMaterialization::add(
+    PromotedLocationDescriptor location, const ExitValue&amp; value)
+{
+    m_properties.append(ExitPropertyValue(location, value));
+}
+
+ExitValue ExitTimeObjectMaterialization::get(PromotedLocationDescriptor location) const
+{
+    for (ExitPropertyValue value : m_properties) {
+        if (value.location() == location)
+            return value.value();
+    }
+    return ExitValue();
+}
+
+void ExitTimeObjectMaterialization::dump(PrintStream&amp; out) const
+{
+    out.print(RawPointer(this), &quot;:&quot;, Graph::opName(m_type), &quot;(&quot;, listDump(m_properties), &quot;)&quot;);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExitTimeObjectMaterializationh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 FTLExitTimeObjectMaterialization_h
+#define FTLExitTimeObjectMaterialization_h
+
+#if ENABLE(FTL_JIT)
+
+#include &quot;DFGNodeType.h&quot;
+#include &quot;FTLExitPropertyValue.h&quot;
+#include &quot;FTLExitValue.h&quot;
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace JSC { namespace FTL {
+
+class ExitTimeObjectMaterialization {
+    WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
+public:
+    ExitTimeObjectMaterialization(DFG::NodeType);
+    ~ExitTimeObjectMaterialization();
+    
+    void add(DFG::PromotedLocationDescriptor, const ExitValue&amp;);
+    
+    DFG::NodeType type() const { return m_type; }
+    
+    ExitValue get(DFG::PromotedLocationDescriptor) const;
+    const Vector&lt;ExitPropertyValue&gt;&amp; properties() const { return m_properties; }
+    
+    void dump(PrintStream&amp; out) const;
+    
+private:
+    DFG::NodeType m_type;
+    Vector&lt;ExitPropertyValue&gt; m_properties;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLExitTimeObjectMaterialization_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExitValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -28,10 +28,19 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;FTLExitTimeObjectMaterialization.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><ins>+ExitValue ExitValue::materializeNewObject(ExitTimeObjectMaterialization* data)
+{
+    ExitValue result;
+    result.m_kind = ExitValueMaterializeNewObject;
+    result.u.newObjectMaterializationData = data;
+    return result;
+}
+
</ins><span class="cx"> void ExitValue::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><span class="cx">     switch (kind()) {
</span><span class="lines">@@ -65,6 +74,9 @@
</span><span class="cx">     case ExitValueRecovery:
</span><span class="cx">         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
</span><span class="cx">         return;
</span><ins>+    case ExitValueMaterializeNewObject:
+        out.print(&quot;Materialize(&quot;, pointerDump(objectMaterialization()), &quot;)&quot;);
+        return;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExitValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLExitValue.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExitValue.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLExitValue.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -52,9 +52,12 @@
</span><span class="cx">     ExitValueInJSStackAsInt52,
</span><span class="cx">     ExitValueInJSStackAsDouble,
</span><span class="cx">     ExitValueArgumentsObjectThatWasNotCreated,
</span><del>-    ExitValueRecovery
</del><ins>+    ExitValueRecovery,
+    ExitValueMaterializeNewObject
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class ExitTimeObjectMaterialization;
+
</ins><span class="cx"> class ExitValue {
</span><span class="cx"> public:
</span><span class="cx">     ExitValue()
</span><span class="lines">@@ -137,6 +140,8 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    static ExitValue materializeNewObject(ExitTimeObjectMaterialization*);
+    
</ins><span class="cx">     ExitValueKind kind() const { return m_kind; }
</span><span class="cx">     
</span><span class="cx">     bool isDead() const { return kind() == ExitValueDead; }
</span><span class="lines">@@ -156,6 +161,7 @@
</span><span class="cx">     bool isArgument() const { return kind() == ExitValueArgument; }
</span><span class="cx">     bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
</span><span class="cx">     bool isRecovery() const { return kind() == ExitValueRecovery; }
</span><ins>+    bool isObjectMaterialization() const { return kind() == ExitValueMaterializeNewObject; }
</ins><span class="cx">     
</span><span class="cx">     ExitArgument exitArgument() const
</span><span class="cx">     {
</span><span class="lines">@@ -199,15 +205,21 @@
</span><span class="cx">         return VirtualRegister(u.virtualRegister);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ExitValue withVirtualRegister(VirtualRegister virtualRegister)
</del><ins>+    ExitTimeObjectMaterialization* objectMaterialization() const
</ins><span class="cx">     {
</span><ins>+        ASSERT(isObjectMaterialization());
+        return u.newObjectMaterializationData;
+    }
+
+    ExitValue withVirtualRegister(VirtualRegister virtualRegister) const
+    {
</ins><span class="cx">         ASSERT(isInJSStackSomehow());
</span><span class="cx">         ExitValue result;
</span><span class="cx">         result.m_kind = m_kind;
</span><span class="cx">         result.u.virtualRegister = virtualRegister.offset();
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><del>-
</del><ins>+    
</ins><span class="cx">     // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
</span><span class="cx">     // that is compatible with exitArgument().format(). If it's a constant or it's dead, it
</span><span class="cx">     // will claim to be a JSValue. If it's an argument then it will tell you the argument's
</span><span class="lines">@@ -223,6 +235,7 @@
</span><span class="cx">         case ExitValueConstant:
</span><span class="cx">         case ExitValueInJSStack:
</span><span class="cx">         case ExitValueArgumentsObjectThatWasNotCreated:
</span><ins>+        case ExitValueMaterializeNewObject:
</ins><span class="cx">             return ValueFormatJSValue;
</span><span class="cx">             
</span><span class="cx">         case ExitValueArgument:
</span><span class="lines">@@ -260,6 +273,7 @@
</span><span class="cx">             uint16_t opcode;
</span><span class="cx">             uint16_t format;
</span><span class="cx">         } recovery;
</span><ins>+        ExitTimeObjectMaterialization* newObjectMaterializationData;
</ins><span class="cx">     } u;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;FTLFormattedValue.h&quot;
</span><span class="cx"> #include &quot;FTLInlineCacheSize.h&quot;
</span><span class="cx"> #include &quot;FTLLoweredNodeValue.h&quot;
</span><ins>+#include &quot;FTLOperations.h&quot;
</ins><span class="cx"> #include &quot;FTLOutput.h&quot;
</span><span class="cx"> #include &quot;FTLThunks.h&quot;
</span><span class="cx"> #include &quot;FTLWeightedTarget.h&quot;
</span><span class="lines">@@ -341,7 +342,7 @@
</span><span class="cx">         
</span><span class="cx">         m_availableRecoveries.resize(0);
</span><span class="cx">         
</span><del>-        bool shouldExecuteEffects = m_interpreter.startExecuting(m_node);
</del><ins>+        m_interpreter.startExecuting();
</ins><span class="cx">         
</span><span class="cx">         switch (m_node-&gt;op()) {
</span><span class="cx">         case Upsilon:
</span><span class="lines">@@ -725,6 +726,12 @@
</span><span class="cx">         case ToIndexString:
</span><span class="cx">             compileToIndexString();
</span><span class="cx">             break;
</span><ins>+        case CheckStructureImmediate:
+            compileCheckStructureImmediate();
+            break;
+        case MaterializeNewObject:
+            compileMaterializeNewObject();
+            break;
</ins><span class="cx"> 
</span><span class="cx">         case PhantomLocal:
</span><span class="cx">         case SetArgument:
</span><span class="lines">@@ -735,6 +742,10 @@
</span><span class="cx">         case AllocationProfileWatchpoint:
</span><span class="cx">         case MovHint:
</span><span class="cx">         case ZombieHint:
</span><ins>+        case PhantomNewObject:
+        case PutByOffsetHint:
+        case PutStructureHint:
+        case BottomValue:
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             DFG_CRASH(m_graph, m_node, &quot;Unrecognized node in FTL backend&quot;);
</span><span class="lines">@@ -742,10 +753,8 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         m_availabilityCalculator.executeNode(m_node);
</span><ins>+        m_interpreter.executeEffects(nodeIndex);
</ins><span class="cx">         
</span><del>-        if (shouldExecuteEffects)
-            m_interpreter.executeEffects(nodeIndex);
-        
</del><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1704,30 +1713,7 @@
</span><span class="cx">         
</span><span class="cx">         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
</span><span class="cx">         
</span><del>-        if (m_node-&gt;structureSet().size() == 1) {
-            speculate(
-                exitKind, jsValueValue(cell), 0,
-                m_out.notEqual(structureID, weakStructure(m_node-&gt;structureSet()[0])));
-            return;
-        }
-        
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;CheckStructure continuation&quot;));
-        
-        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
-        for (unsigned i = 0; i &lt; m_node-&gt;structureSet().size() - 1; ++i) {
-            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, (&quot;CheckStructure nextStructure&quot;));
-            m_out.branch(
-                m_out.equal(structureID, weakStructure(m_node-&gt;structureSet()[i])),
-                unsure(continuation), unsure(nextStructure));
-            m_out.appendTo(nextStructure);
-        }
-        
-        speculate(
-            exitKind, jsValueValue(cell), 0,
-            m_out.notEqual(structureID, weakStructure(m_node-&gt;structureSet().last())));
-        
-        m_out.jump(continuation);
-        m_out.appendTo(continuation, lastNext);
</del><ins>+        checkStructure(structureID, jsValueValue(cell), exitKind, m_node-&gt;structureSet());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileCheckCell()
</span><span class="lines">@@ -1762,7 +1748,7 @@
</span><span class="cx">         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
</span><span class="cx">         
</span><span class="cx">         m_out.branch(
</span><del>-            m_out.notEqual(structureID, weakStructure(m_node-&gt;structure())),
</del><ins>+            m_out.notEqual(structureID, weakStructureID(m_node-&gt;structure())),
</ins><span class="cx">             rarely(unexpectedStructure), usually(continuation));
</span><span class="cx">         
</span><span class="cx">         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
</span><span class="lines">@@ -1806,7 +1792,7 @@
</span><span class="cx">         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
</span><span class="cx">         speculate(
</span><span class="cx">             BadIndexingType, jsValueValue(cell), 0,
</span><del>-            m_out.notEqual(structureID, weakStructure(m_node-&gt;structure())));
</del><ins>+            m_out.notEqual(structureID, weakStructureID(m_node-&gt;structure())));
</ins><span class="cx">         m_out.jump(continuation);
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -1824,7 +1810,7 @@
</span><span class="cx"> 
</span><span class="cx">         LValue cell = lowCell(m_node-&gt;child1()); 
</span><span class="cx">         m_out.store32(
</span><del>-            weakStructure(newStructure),
</del><ins>+            weakStructureID(newStructure),
</ins><span class="cx">             cell, m_heaps.JSCell_structureID);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -2649,28 +2635,7 @@
</span><span class="cx">     
</span><span class="cx">     void compileNewObject()
</span><span class="cx">     {
</span><del>-        Structure* structure = m_node-&gt;structure();
-        size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
-        MarkedAllocator* allocator = &amp;vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
-        
-        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, (&quot;NewObject slow path&quot;));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;NewObject continuation&quot;));
-        
-        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
-        
-        ValueFromBlock fastResult = m_out.anchor(allocateObject(
-            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
-        
-        m_out.jump(continuation);
-        
-        m_out.appendTo(slowPath, continuation);
-        
-        ValueFromBlock slowResult = m_out.anchor(vmCall(
-            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
-        m_out.jump(continuation);
-        
-        m_out.appendTo(continuation, lastNext);
-        setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
</del><ins>+        setJSValue(allocateObject(m_node-&gt;structure()));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileNewArray()
</span><span class="lines">@@ -3290,7 +3255,7 @@
</span><span class="cx">             GetByIdVariant variant = data.variants[i];
</span><span class="cx">             for (unsigned j = variant.structureSet().size(); j--;) {
</span><span class="cx">                 cases.append(SwitchCase(
</span><del>-                    weakStructure(variant.structureSet()[j]), blocks[i], Weight(1)));
</del><ins>+                    weakStructureID(variant.structureSet()[j]), blocks[i], Weight(1)));
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         m_out.switchInstruction(
</span><span class="lines">@@ -3361,7 +3326,7 @@
</span><span class="cx">             PutByIdVariant variant = data.variants[i];
</span><span class="cx">             for (unsigned j = variant.oldStructure().size(); j--;) {
</span><span class="cx">                 cases.append(
</span><del>-                    SwitchCase(weakStructure(variant.oldStructure()[j]), blocks[i], Weight(1)));
</del><ins>+                    SwitchCase(weakStructureID(variant.oldStructure()[j]), blocks[i], Weight(1)));
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         m_out.switchInstruction(
</span><span class="lines">@@ -3370,7 +3335,7 @@
</span><span class="cx">         LBasicBlock lastNext = m_out.m_nextBlock;
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = data.variants.size(); i--;) {
</span><del>-            m_out.appendTo(blocks[i], i  + 1 &lt; data.variants.size() ? blocks[i + 1] : exit);
</del><ins>+            m_out.appendTo(blocks[i], i + 1 &lt; data.variants.size() ? blocks[i + 1] : exit);
</ins><span class="cx">             
</span><span class="cx">             PutByIdVariant variant = data.variants[i];
</span><span class="cx">             
</span><span class="lines">@@ -3393,7 +3358,7 @@
</span><span class="cx">                 ASSERT(variant.oldStructureForTransition()-&gt;typeInfo().inlineTypeFlags() == variant.newStructure()-&gt;typeInfo().inlineTypeFlags());
</span><span class="cx">                 ASSERT(variant.oldStructureForTransition()-&gt;typeInfo().type() == variant.newStructure()-&gt;typeInfo().type());
</span><span class="cx">                 m_out.store32(
</span><del>-                    weakStructure(variant.newStructure()), base, m_heaps.JSCell_structureID);
</del><ins>+                    weakStructureID(variant.newStructure()), base, m_heaps.JSCell_structureID);
</ins><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             storeProperty(value, storage, data.identifierNumber, variant.offset());
</span><span class="lines">@@ -3953,12 +3918,13 @@
</span><span class="cx">     void compileInvalidationPoint()
</span><span class="cx">     {
</span><span class="cx">         if (verboseCompilationEnabled())
</span><del>-            dataLog(&quot;    Invalidation point with availability: &quot;, availability(), &quot;\n&quot;);
</del><ins>+            dataLog(&quot;    Invalidation point with availability: &quot;, availabilityMap(), &quot;\n&quot;);
</ins><span class="cx">         
</span><span class="cx">         m_ftlState.jitCode-&gt;osrExit.append(OSRExit(
</span><span class="cx">             UncountableInvalidation, InvalidValueFormat, MethodOfGettingAValueProfile(),
</span><span class="cx">             m_codeOriginForExitTarget, m_codeOriginForExitProfile,
</span><del>-            availability().numberOfArguments(), availability().numberOfLocals()));
</del><ins>+            availabilityMap().m_locals.numberOfArguments(),
+            availabilityMap().m_locals.numberOfLocals()));
</ins><span class="cx">         m_ftlState.finalizer-&gt;osrExit.append(OSRExitCompilationInfo());
</span><span class="cx">         
</span><span class="cx">         OSRExit&amp; exit = m_ftlState.jitCode-&gt;osrExit.last();
</span><span class="lines">@@ -4360,7 +4326,121 @@
</span><span class="cx">         LValue index = lowInt32(m_node-&gt;child1());
</span><span class="cx">         setJSValue(vmCall(m_out.operation(operationToIndexString), m_callFrame, index));
</span><span class="cx">     }
</span><ins>+    
+    void compileCheckStructureImmediate()
+    {
+        LValue structureID = lowCell(m_node-&gt;child1());
+        checkStructure(structureID, noValue(), BadCache, m_node-&gt;structureSet());
+    }
+    
+    void compileMaterializeNewObject()
+    {
+        ObjectMaterializationData&amp; data = m_node-&gt;objectMaterializationData();
+        
+        // Lower the values first, to avoid creating values inside a control flow diamond.
+        
+        Vector&lt;LValue, 8&gt; values;
+        for (unsigned i = 0; i &lt; data.m_properties.size(); ++i)
+            values.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
+        
+        StructureSet set;
+        m_interpreter.phiChildren()-&gt;forAllTransitiveIncomingValues(
+            m_graph.varArgChild(m_node, 0).node(),
+            [&amp;] (Node* incoming) {
+                set.add(incoming-&gt;castConstant&lt;Structure*&gt;());
+            });
+        
+        Vector&lt;LBasicBlock, 1&gt; blocks(set.size());
+        for (unsigned i = set.size(); i--;)
+            blocks[i] = FTL_NEW_BLOCK(m_out, (&quot;MaterializeNewObject case &quot;, i));
+        LBasicBlock dummyDefault = FTL_NEW_BLOCK(m_out, (&quot;MaterializeNewObject default case&quot;));
+        LBasicBlock outerContinuation = FTL_NEW_BLOCK(m_out, (&quot;MaterializeNewObject continuation&quot;));
+        
+        Vector&lt;SwitchCase, 1&gt; cases(set.size());
+        for (unsigned i = set.size(); i--;)
+            cases[i] = SwitchCase(weakStructure(set[i]), blocks[i], Weight(1));
+        m_out.switchInstruction(
+            lowCell(m_graph.varArgChild(m_node, 0)), cases, dummyDefault, Weight(0));
+        
+        LBasicBlock outerLastNext = m_out.m_nextBlock;
+        
+        Vector&lt;ValueFromBlock, 1&gt; results;
+        
+        for (unsigned i = set.size(); i--;) {
+            m_out.appendTo(blocks[i], i + 1 &lt; set.size() ? blocks[i + 1] : dummyDefault);
+            
+            Structure* structure = set[i];
+            
+            LValue object;
+            LValue butterfly;
+            
+            if (structure-&gt;outOfLineCapacity()) {
+                size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
+                MarkedAllocator* allocator = &amp;vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
+                
+                LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, (&quot;MaterializeNewObject complex object allocation slow path&quot;));
+                LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;MaterializeNewObject complex object allocation continuation&quot;));
+                
+                LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+                
+                LValue endOfStorage = allocateBasicStorageAndGetEnd(
+                    m_out.constIntPtr(structure-&gt;outOfLineCapacity() * sizeof(JSValue)),
+                    slowPath);
+                
+                LValue fastButterflyValue = m_out.add(
+                    m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage);
+                
+                LValue fastObjectValue = allocateObject(
+                    m_out.constIntPtr(allocator), structure, fastButterflyValue, slowPath);
</ins><span class="cx"> 
</span><ins>+                ValueFromBlock fastObject = m_out.anchor(fastObjectValue);
+                ValueFromBlock fastButterfly = m_out.anchor(fastButterflyValue);
+                m_out.jump(continuation);
+                
+                m_out.appendTo(slowPath, continuation);
+                
+                ValueFromBlock slowObject = m_out.anchor(vmCall(
+                    m_out.operation(operationNewObjectWithButterfly),
+                    m_callFrame, m_out.constIntPtr(structure)));
+                ValueFromBlock slowButterfly = m_out.anchor(
+                    m_out.loadPtr(slowObject.value(), m_heaps.JSObject_butterfly));
+                
+                m_out.jump(continuation);
+                
+                m_out.appendTo(continuation, lastNext);
+                
+                object = m_out.phi(m_out.intPtr, fastObject, slowObject);
+                butterfly = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
+            } else {
+                // In the easy case where we can do a one-shot allocation, we simply allocate the
+                // object to directly have the desired structure.
+                object = allocateObject(structure);
+                butterfly = nullptr; // Don't have one, don't need one.
+            }
+            
+            for (PropertyMapEntry entry : structure-&gt;getPropertiesConcurrently()) {
+                for (unsigned i = data.m_properties.size(); i--;) {
+                    PhantomPropertyValue value = data.m_properties[i];
+                    if (m_graph.identifiers()[value.m_identifierNumber] != entry.key)
+                        continue;
+                    
+                    LValue base = isInlineOffset(entry.offset) ? object : butterfly;
+                    storeProperty(values[i], base, value.m_identifierNumber, entry.offset);
+                    break;
+                }
+            }
+            
+            results.append(m_out.anchor(object));
+            m_out.jump(outerContinuation);
+        }
+        
+        m_out.appendTo(dummyDefault, outerContinuation);
+        m_out.unreachable();
+        
+        m_out.appendTo(outerContinuation, outerLastNext);
+        setJSValue(m_out.phi(m_out.intPtr, results));
+    }
+
</ins><span class="cx"> #if ENABLE(FTL_NATIVE_CALL_INLINING)
</span><span class="cx">     LValue getFunctionBySymbol(const CString symbol)
</span><span class="cx">     {
</span><span class="lines">@@ -4525,6 +4605,36 @@
</span><span class="cx">         return m_out.booleanFalse;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void checkStructure(
+        LValue structureID, const FormattedValue&amp; formattedValue, ExitKind exitKind,
+        const StructureSet&amp; set)
+    {
+        if (set.size() == 1) {
+            speculate(
+                exitKind, formattedValue, 0,
+                m_out.notEqual(structureID, weakStructureID(set[0])));
+            return;
+        }
+        
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;checkStructure continuation&quot;));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
+        for (unsigned i = 0; i &lt; set.size() - 1; ++i) {
+            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, (&quot;checkStructure nextStructure&quot;));
+            m_out.branch(
+                m_out.equal(structureID, weakStructureID(set[i])),
+                unsure(continuation), unsure(nextStructure));
+            m_out.appendTo(nextStructure);
+        }
+        
+        speculate(
+            exitKind, formattedValue, 0,
+            m_out.notEqual(structureID, weakStructureID(set.last())));
+        
+        m_out.jump(continuation);
+        m_out.appendTo(continuation, lastNext);
+    }
+    
</ins><span class="cx">     LValue numberOrNotCellToInt32(Edge edge, LValue value)
</span><span class="cx">     {
</span><span class="cx">         LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;ValueToInt32 int case&quot;));
</span><span class="lines">@@ -4831,7 +4941,7 @@
</span><span class="cx">         setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
</del><ins>+    LValue allocateCell(LValue allocator, LBasicBlock slowPath)
</ins><span class="cx">     {
</span><span class="cx">         LBasicBlock success = FTL_NEW_BLOCK(m_out, (&quot;object allocation success&quot;));
</span><span class="cx">         
</span><span class="lines">@@ -4846,12 +4956,21 @@
</span><span class="cx">             m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
</span><span class="cx">             allocator, m_heaps.MarkedAllocator_freeListHead);
</span><span class="cx">         
</span><del>-        m_out.store32(m_out.constInt32(structure-&gt;id()), result, m_heaps.JSCell_structureID);
-        
</del><ins>+        return result;
+    }
+    
+    void storeStructure(LValue object, Structure* structure)
+    {
+        m_out.store32(m_out.constInt32(structure-&gt;id()), object, m_heaps.JSCell_structureID);
</ins><span class="cx">         m_out.store32(
</span><span class="cx">             m_out.constInt32(structure-&gt;objectInitializationBlob()),
</span><del>-            result, m_heaps.JSCell_usefulBytes);
-        
</del><ins>+            object, m_heaps.JSCell_usefulBytes);
+    }
+
+    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
+    {
+        LValue result = allocateCell(allocator, slowPath);
+        storeStructure(result, structure);
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -4898,6 +5017,31 @@
</span><span class="cx">             m_out.loadPtr(m_out.absolute(&amp;allocator.m_currentPayloadEnd)), newRemaining);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue allocateObject(Structure* structure)
+    {
+        size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
+        MarkedAllocator* allocator = &amp;vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
+        
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, (&quot;allocateObject slow path&quot;));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;allocateObject continuation&quot;));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+        
+        ValueFromBlock fastResult = m_out.anchor(allocateObject(
+            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
+        
+        m_out.jump(continuation);
+        
+        m_out.appendTo(slowPath, continuation);
+        
+        ValueFromBlock slowResult = m_out.anchor(vmCall(
+            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        return m_out.phi(m_out.intPtr, fastResult, slowResult);
+    }
+    
</ins><span class="cx">     struct ArrayValues {
</span><span class="cx">         ArrayValues()
</span><span class="cx">             : array(0)
</span><span class="lines">@@ -6107,7 +6251,7 @@
</span><span class="cx">         
</span><span class="cx">         speculate(
</span><span class="cx">             NotStringObject, noValue(), 0,
</span><del>-            m_out.notEqual(structureID, weakStructure(stringObjectStructure)));
</del><ins>+            m_out.notEqual(structureID, weakStructureID(stringObjectStructure)));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void speculateNonNullObject(Edge edge, LValue cell)
</span><span class="lines">@@ -6334,7 +6478,7 @@
</span><span class="cx">         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
</span><span class="cx">     {
</span><span class="cx">         if (verboseCompilationEnabled()) {
</span><del>-            dataLog(&quot;    OSR exit #&quot;, m_ftlState.jitCode-&gt;osrExit.size(), &quot; with availability: &quot;, availability(), &quot;\n&quot;);
</del><ins>+            dataLog(&quot;    OSR exit #&quot;, m_ftlState.jitCode-&gt;osrExit.size(), &quot; with availability: &quot;, availabilityMap(), &quot;\n&quot;);
</ins><span class="cx">             if (!m_availableRecoveries.isEmpty())
</span><span class="cx">                 dataLog(&quot;        Available recoveries: &quot;, listDump(m_availableRecoveries), &quot;\n&quot;);
</span><span class="cx">         }
</span><span class="lines">@@ -6344,7 +6488,8 @@
</span><span class="cx">         m_ftlState.jitCode-&gt;osrExit.append(OSRExit(
</span><span class="cx">             kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
</span><span class="cx">             m_codeOriginForExitTarget, m_codeOriginForExitProfile,
</span><del>-            availability().numberOfArguments(), availability().numberOfLocals()));
</del><ins>+            availabilityMap().m_locals.numberOfArguments(),
+            availabilityMap().m_locals.numberOfLocals()));
</ins><span class="cx">         m_ftlState.finalizer-&gt;osrExit.append(OSRExitCompilationInfo());
</span><span class="cx">         
</span><span class="cx">         OSRExit&amp; exit = m_ftlState.jitCode-&gt;osrExit.last();
</span><span class="lines">@@ -6384,58 +6529,54 @@
</span><span class="cx">         if (!!lowValue)
</span><span class="cx">             arguments.append(lowValue.value());
</span><span class="cx">         
</span><ins>+        AvailabilityMap availabilityMap = this-&gt;availabilityMap();
+        
</ins><span class="cx">         for (unsigned i = 0; i &lt; exit.m_values.size(); ++i) {
</span><span class="cx">             int operand = exit.m_values.operandForIndex(i);
</span><span class="cx">             bool isLive = m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin);
</span><del>-            if (!isLive) {
-                exit.m_values[i] = ExitValue::dead();
-                continue;
-            }
-            
-            Availability availability = this-&gt;availability()[i];
-            FlushedAt flush = availability.flushedAt();
-            switch (flush.format()) {
-            case DeadFlush:
-            case ConflictingFlush:
-                if (availability.hasNode()) {
-                    exit.m_values[i] = exitValueForNode(arguments, availability.node());
-                    break;
-                }
</del><ins>+            if (!isLive)
+                availabilityMap.m_locals[i] = Availability();
+        }
+        
+        availabilityMap.prune();
+        
+        HashMap&lt;Node*, ExitTimeObjectMaterialization*&gt; map;
+        availabilityMap.forEachAvailability(
+            [&amp;] (Availability availability) {
+                if (!availability.shouldUseNode())
+                    return;
</ins><span class="cx">                 
</span><del>-                if (Options::validateFTLOSRExitLiveness())
-                    DFG_CRASH(m_graph, m_node, toCString(&quot;Expected r&quot;, operand, &quot; to be available but it wasn't.&quot;).data());
</del><ins>+                Node* node = availability.node();
+                if (!node-&gt;isPhantomObjectAllocation())
+                    return;
</ins><span class="cx">                 
</span><del>-                // This means that the DFG's DCE proved that the value is dead in bytecode
-                // even though the bytecode liveness analysis thinks it's live. This is
-                // acceptable since the DFG's DCE is by design more aggressive while still
-                // being sound.
-                exit.m_values[i] = ExitValue::dead();
-                break;
-
-            case FlushedJSValue:
-            case FlushedCell:
-            case FlushedBoolean:
-                exit.m_values[i] = ExitValue::inJSStack(flush.virtualRegister());
-                break;
-                
-            case FlushedInt32:
-                exit.m_values[i] = ExitValue::inJSStackAsInt32(flush.virtualRegister());
-                break;
-                
-            case FlushedInt52:
-                exit.m_values[i] = ExitValue::inJSStackAsInt52(flush.virtualRegister());
-                break;
-                
-            case FlushedDouble:
-                exit.m_values[i] = ExitValue::inJSStackAsDouble(flush.virtualRegister());
-                break;
-                
-            case FlushedArguments:
-                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
-                break;
</del><ins>+                auto result = map.add(node, nullptr);
+                if (result.isNewEntry)
+                    result.iterator-&gt;value = exit.m_materializations.add(node-&gt;op());
+            });
+        
+        for (unsigned i = 0; i &lt; exit.m_values.size(); ++i) {
+            int operand = exit.m_values.operandForIndex(i);
+            
+            Availability availability = availabilityMap.m_locals[i];
+            
+            if (Options::validateFTLOSRExitLiveness()) {
+                DFG_ASSERT(
+                    m_graph, m_node,
+                    !(availability.isDead() &amp;&amp; m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin)));
</ins><span class="cx">             }
</span><ins>+            
+            exit.m_values[i] = exitValueForAvailability(arguments, map, availability);
</ins><span class="cx">         }
</span><span class="cx">         
</span><ins>+        for (auto heapPair : availabilityMap.m_heap) {
+            Node* node = heapPair.key.base();
+            ExitTimeObjectMaterialization* materialization = map.get(node);
+            materialization-&gt;add(
+                heapPair.key.descriptor(),
+                exitValueForAvailability(arguments, map, heapPair.value));
+        }
+        
</ins><span class="cx">         if (verboseCompilationEnabled())
</span><span class="cx">             dataLog(&quot;        Exit values: &quot;, exit.m_values, &quot;\n&quot;);
</span><span class="cx">     }
</span><span class="lines">@@ -6449,13 +6590,57 @@
</span><span class="cx">         m_out.call(m_out.stackmapIntrinsic(), arguments);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ExitValue exitValueForNode(ExitArgumentList&amp; arguments, Node* node)
</del><ins>+    ExitValue exitValueForAvailability(
+        ExitArgumentList&amp; arguments, const HashMap&lt;Node*, ExitTimeObjectMaterialization*&gt;&amp; map,
+        Availability availability)
</ins><span class="cx">     {
</span><ins>+        FlushedAt flush = availability.flushedAt();
+        switch (flush.format()) {
+        case DeadFlush:
+        case ConflictingFlush:
+            if (availability.hasNode())
+                return exitValueForNode(arguments, map, availability.node());
+            
+            // This means that the value is dead. It could be dead in bytecode or it could have
+            // been killed by our DCE, which can sometimes kill things even if they were live in
+            // bytecode.
+            return ExitValue::dead();
+
+        case FlushedJSValue:
+        case FlushedCell:
+        case FlushedBoolean:
+            return ExitValue::inJSStack(flush.virtualRegister());
+                
+        case FlushedInt32:
+            return ExitValue::inJSStackAsInt32(flush.virtualRegister());
+                
+        case FlushedInt52:
+            return ExitValue::inJSStackAsInt52(flush.virtualRegister());
+                
+        case FlushedDouble:
+            return ExitValue::inJSStackAsDouble(flush.virtualRegister());
+                
+        case FlushedArguments:
+            return ExitValue::argumentsObjectThatWasNotCreated();
+        }
+        
+        DFG_CRASH(m_graph, m_node, &quot;Invalid flush format&quot;);
+    }
+    
+    ExitValue exitValueForNode(
+        ExitArgumentList&amp; arguments, const HashMap&lt;Node*, ExitTimeObjectMaterialization*&gt;&amp; map,
+        Node* node)
+    {
</ins><span class="cx">         ASSERT(node-&gt;shouldGenerate());
</span><span class="cx">         ASSERT(node-&gt;hasResult());
</span><span class="cx"> 
</span><span class="cx">         if (node) {
</span><span class="cx">             switch (node-&gt;op()) {
</span><ins>+            case BottomValue:
+                // This might arise in object materializations. I actually doubt that it would,
+                // but it seems worthwhile to be conservative.
+                return ExitValue::dead();
+                
</ins><span class="cx">             case JSConstant:
</span><span class="cx">             case Int52Constant:
</span><span class="cx">             case DoubleConstant:
</span><span class="lines">@@ -6464,6 +6649,9 @@
</span><span class="cx">             case PhantomArguments:
</span><span class="cx">                 return ExitValue::argumentsObjectThatWasNotCreated();
</span><span class="cx">                 
</span><ins>+            case PhantomNewObject:
+                return ExitValue::materializeNewObject(map.get(node));
+                
</ins><span class="cx">             default:
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -6647,12 +6835,17 @@
</span><span class="cx">         return m_out.constIntPtr(pointer);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LValue weakStructure(Structure* structure)
</del><ins>+    LValue weakStructureID(Structure* structure)
</ins><span class="cx">     {
</span><span class="cx">         addWeakReference(structure);
</span><span class="cx">         return m_out.constInt32(structure-&gt;id());
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue weakStructure(Structure* structure)
+    {
+        return weakPointer(structure);
+    }
+    
</ins><span class="cx">     TypedPointer addressFor(LValue base, int operand, ptrdiff_t offset = 0)
</span><span class="cx">     {
</span><span class="cx">         return m_out.address(base, m_heaps.variables[operand], offset);
</span><span class="lines">@@ -6711,7 +6904,7 @@
</span><span class="cx">         m_out.unreachable();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Operands&lt;Availability&gt;&amp; availability() { return m_availabilityCalculator.m_availability; }
</del><ins>+    AvailabilityMap&amp; availabilityMap() { return m_availabilityCalculator.m_availability; }
</ins><span class="cx">     
</span><span class="cx">     VM&amp; vm() { return m_graph.m_vm; }
</span><span class="cx">     CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExith"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 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">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;DFGOSRExitBase.h&quot;
</span><span class="cx"> #include &quot;FTLAbbreviations.h&quot;
</span><span class="cx"> #include &quot;FTLExitArgumentList.h&quot;
</span><ins>+#include &quot;FTLExitTimeObjectMaterialization.h&quot;
</ins><span class="cx"> #include &quot;FTLExitValue.h&quot;
</span><span class="cx"> #include &quot;FTLFormattedValue.h&quot;
</span><span class="cx"> #include &quot;MethodOfGettingAValueProfile.h&quot;
</span><span class="lines">@@ -160,6 +161,7 @@
</span><span class="cx">     unsigned m_patchableCodeOffset;
</span><span class="cx">     
</span><span class="cx">     Operands&lt;ExitValue&gt; m_values;
</span><ins>+    Bag&lt;ExitTimeObjectMaterialization&gt; m_materializations;
</ins><span class="cx">     
</span><span class="cx">     uint32_t m_stackmapID;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;FTLExitArgumentForOperand.h&quot;
</span><span class="cx"> #include &quot;FTLJITCode.h&quot;
</span><span class="cx"> #include &quot;FTLOSRExit.h&quot;
</span><ins>+#include &quot;FTLOperations.h&quot;
</ins><span class="cx"> #include &quot;FTLState.h&quot;
</span><span class="cx"> #include &quot;FTLSaveRestore.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="lines">@@ -46,6 +47,87 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace DFG;
</span><span class="cx"> 
</span><ins>+static void compileRecovery(
+    CCallHelpers&amp; jit, const ExitValue&amp; value, StackMaps::Record* record, StackMaps&amp; stackmaps,
+    char* registerScratch,
+    const HashMap&lt;ExitTimeObjectMaterialization*, EncodedJSValue*&gt;&amp; materializationToPointer)
+{
+    switch (value.kind()) {
+    case ExitValueDead:
+        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
+        break;
+            
+    case ExitValueConstant:
+        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
+        break;
+            
+    case ExitValueArgument:
+        record-&gt;locations[value.exitArgument().argument()].restoreInto(
+            jit, stackmaps, registerScratch, GPRInfo::regT0);
+        break;
+            
+    case ExitValueInJSStack:
+    case ExitValueInJSStackAsInt32:
+    case ExitValueInJSStackAsInt52:
+    case ExitValueInJSStackAsDouble:
+        jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
+        break;
+            
+    case ExitValueArgumentsObjectThatWasNotCreated:
+        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
+        break;
+            
+    case ExitValueRecovery:
+        record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
+            jit, stackmaps, registerScratch, GPRInfo::regT1);
+        record-&gt;locations[value.leftRecoveryArgument()].restoreInto(
+            jit, stackmaps, registerScratch, GPRInfo::regT0);
+        switch (value.recoveryOpcode()) {
+        case AddRecovery:
+            switch (value.recoveryFormat()) {
+            case ValueFormatInt32:
+                jit.add32(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            case ValueFormatInt52:
+                jit.add64(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            break;
+        case SubRecovery:
+            switch (value.recoveryFormat()) {
+            case ValueFormatInt32:
+                jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            case ValueFormatInt52:
+                jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+        break;
+        
+    case ExitValueMaterializeNewObject:
+        jit.loadPtr(materializationToPointer.get(value.objectMaterialization()), GPRInfo::regT0);
+        break;
+            
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+        
+    reboxAccordingToFormat(
+        value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
+}
+
</ins><span class="cx"> static void compileStub(
</span><span class="cx">     unsigned exitID, JITCode* jitCode, OSRExit&amp; exit, VM* vm, CodeBlock* codeBlock)
</span><span class="cx"> {
</span><span class="lines">@@ -64,13 +146,39 @@
</span><span class="cx"> 
</span><span class="cx">     CCallHelpers jit(vm, codeBlock);
</span><span class="cx">     
</span><del>-    // We need scratch space to save all registers and to build up the JSStack.
-    // Use a scratch buffer to transfer all values.
-    ScratchBuffer* scratchBuffer = vm-&gt;scratchBufferForSize(sizeof(EncodedJSValue) * exit.m_values.size() + requiredScratchMemorySizeInBytes() + jitCode-&gt;unwindInfo.m_registers.size() * sizeof(uint64_t));
</del><ins>+    // We need scratch space to save all registers, to build up the JS stack, to deal with unwind
+    // fixup, pointers to all of the objects we materialize, and the elements inside those objects
+    // that we materialize.
+    
+    // Figure out how much space we need for those object allocations.
+    unsigned numMaterializations = 0;
+    size_t maxMaterializationNumArguments = 0;
+    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
+        numMaterializations++;
+        
+        maxMaterializationNumArguments = std::max(
+            maxMaterializationNumArguments,
+            materialization-&gt;properties().size());
+    }
+    
+    ScratchBuffer* scratchBuffer = vm-&gt;scratchBufferForSize(
+        sizeof(EncodedJSValue) * (
+            exit.m_values.size() + numMaterializations + maxMaterializationNumArguments) +
+        requiredScratchMemorySizeInBytes() +
+        jitCode-&gt;unwindInfo.m_registers.size() * sizeof(uint64_t));
</ins><span class="cx">     EncodedJSValue* scratch = scratchBuffer ? static_cast&lt;EncodedJSValue*&gt;(scratchBuffer-&gt;dataBuffer()) : 0;
</span><del>-    char* registerScratch = bitwise_cast&lt;char*&gt;(scratch + exit.m_values.size());
</del><ins>+    EncodedJSValue* materializationPointers = scratch + exit.m_values.size();
+    EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
+    char* registerScratch = bitwise_cast&lt;char*&gt;(materializationArguments + maxMaterializationNumArguments);
</ins><span class="cx">     uint64_t* unwindScratch = bitwise_cast&lt;uint64_t*&gt;(registerScratch + requiredScratchMemorySizeInBytes());
</span><span class="cx">     
</span><ins>+    HashMap&lt;ExitTimeObjectMaterialization*, EncodedJSValue*&gt; materializationToPointer;
+    unsigned materializationCount = 0;
+    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
+        materializationToPointer.add(
+            materialization, materializationPointers + materializationCount++);
+    }
+    
</ins><span class="cx">     // Note that we come in here, the stack used to be as LLVM left it except that someone called pushToSave().
</span><span class="cx">     // We don't care about the value they saved. But, we do appreciate the fact that they did it, because we use
</span><span class="cx">     // that slot for saveAllRegisters().
</span><span class="lines">@@ -120,86 +228,69 @@
</span><span class="cx">         if (!!exit.m_valueProfile)
</span><span class="cx">             jit.store64(GPRInfo::regT0, exit.m_valueProfile.getSpecFailBucket(0));
</span><span class="cx">     }
</span><del>-
-    // Save all state from wherever the exit data tells us it was, into the appropriate place in
-    // the scratch buffer. This also does the reboxing.
</del><span class="cx">     
</span><del>-    for (unsigned index = exit.m_values.size(); index--;) {
-        ExitValue value = exit.m_values[index];
</del><ins>+    // Materialize all objects. Don't materialize an object until all of the objects it needs
+    // have been materialized.
+    HashSet&lt;ExitTimeObjectMaterialization*&gt; toMaterialize;
+    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+        toMaterialize.add(materialization);
+    
+    while (!toMaterialize.isEmpty()) {
+        int previousToMaterializeSize = toMaterialize.size();
</ins><span class="cx">         
</span><del>-        switch (value.kind()) {
-        case ExitValueDead:
-            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
-            break;
-            
-        case ExitValueConstant:
-            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
-            break;
-            
-        case ExitValueArgument:
-            record-&gt;locations[value.exitArgument().argument()].restoreInto(
-                jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT0);
-            break;
-            
-        case ExitValueInJSStack:
-        case ExitValueInJSStackAsInt32:
-        case ExitValueInJSStackAsInt52:
-        case ExitValueInJSStackAsDouble:
-            jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
-            break;
-            
-        case ExitValueArgumentsObjectThatWasNotCreated:
-            // We can't actually recover this yet, but we can make the stack look sane. This is
-            // a prerequisite to running the actual arguments recovery.
-            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
-            break;
-            
-        case ExitValueRecovery:
-            record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
-                jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
-            record-&gt;locations[value.leftRecoveryArgument()].restoreInto(
-                jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT0);
-            switch (value.recoveryOpcode()) {
-            case AddRecovery:
-                switch (value.recoveryFormat()) {
-                case ValueFormatInt32:
-                    jit.add32(GPRInfo::regT1, GPRInfo::regT0);
</del><ins>+        Vector&lt;ExitTimeObjectMaterialization*&gt; worklist;
+        worklist.appendRange(toMaterialize.begin(), toMaterialize.end());
+        for (ExitTimeObjectMaterialization* materialization : worklist) {
+            // Check if we can do anything about this right now.
+            bool allGood = true;
+            for (ExitPropertyValue value : materialization-&gt;properties()) {
+                if (!value.value().isObjectMaterialization())
+                    continue;
+                if (toMaterialize.contains(value.value().objectMaterialization())) {
+                    // Gotta skip this one, since one of its fields points to a materialization
+                    // that hasn't been materialized.
+                    allGood = false;
</ins><span class="cx">                     break;
</span><del>-                case ValueFormatInt52:
-                    jit.add64(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
-                    break;
</del><span class="cx">                 }
</span><del>-                break;
-            case SubRecovery:
-                switch (value.recoveryFormat()) {
-                case ValueFormatInt32:
-                    jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                case ValueFormatInt52:
-                    jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
-                    break;
-                }
-                break;
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
</del><span class="cx">             }
</span><del>-            break;
</del><ins>+            if (!allGood)
+                continue;
</ins><span class="cx">             
</span><del>-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
</del><ins>+            // All systems go for materializing the object. First we recover the values of all of
+            // its fields and then we call a function to actually allocate the beast.
+            for (unsigned propertyIndex = materialization-&gt;properties().size(); propertyIndex--;) {
+                const ExitValue&amp; value = materialization-&gt;properties()[propertyIndex].value();
+                compileRecovery(
+                    jit, value, record, jitCode-&gt;stackmaps, registerScratch,
+                    materializationToPointer);
+                jit.storePtr(GPRInfo::regT0, materializationArguments + propertyIndex);
+            }
+            
+            // This call assumes that we don't pass arguments on the stack.
+            jit.setupArgumentsWithExecState(
+                CCallHelpers::TrustedImmPtr(materialization),
+                CCallHelpers::TrustedImmPtr(materializationArguments));
+            jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast&lt;void*&gt;(operationMaterializeObjectInOSR)), GPRInfo::nonArgGPR0);
+            jit.call(GPRInfo::nonArgGPR0);
+            jit.storePtr(GPRInfo::returnValueGPR, materializationToPointer.get(materialization));
+            
+            // Let everyone know that we're done.
+            toMaterialize.remove(materialization);
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        reboxAccordingToFormat(
-            value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
-        
</del><ins>+        // We expect progress! This ensures that we crash rather than looping infinitely if there
+        // is something broken about this fixpoint. Or, this could happen if we ever violate the
+        // &quot;materializations form a DAG&quot; rule.
+        RELEASE_ASSERT(toMaterialize.size() &lt; previousToMaterializeSize);
+    }
+
+    // Save all state from wherever the exit data tells us it was, into the appropriate place in
+    // the scratch buffer. This also does the reboxing.
+    
+    for (unsigned index = exit.m_values.size(); index--;) {
+        compileRecovery(
+            jit, exit.m_values[index], record, jitCode-&gt;stackmaps, registerScratch,
+            materializationToPointer);
</ins><span class="cx">         jit.store64(GPRInfo::regT0, scratch + index);
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOperationscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;FTLOperations.h&quot;
+
+#if ENABLE(FTL_JIT)
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace FTL {
+
+using namespace JSC::DFG;
+
+extern &quot;C&quot; JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    
+    Butterfly* butterfly = Butterfly::create(
+        vm, nullptr, 0, structure-&gt;outOfLineCapacity(), false, IndexingHeader(), 0);
+    
+    return JSFinalObject::create(exec, structure, butterfly);
+}
+
+extern &quot;C&quot; JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
+    ExecState* exec, ExitTimeObjectMaterialization* materialization, EncodedJSValue* values)
+{
+    VM&amp; vm = exec-&gt;vm();
+    CodeBlock* codeBlock = exec-&gt;codeBlock();
+
+    // We cannot GC. We've got pointers in evil places.
+    DeferGCForAWhile deferGC(vm.heap);
+    
+    // In the future, we may have many different kinds of materializations. For now we just
+    // materialize NewObject.
+    RELEASE_ASSERT(materialization-&gt;type() == PhantomNewObject);
+    
+    // First figure out what the structure is.
+    Structure* structure = nullptr;
+    for (unsigned i = materialization-&gt;properties().size(); i--;) {
+        const ExitPropertyValue&amp; property = materialization-&gt;properties()[i];
+        if (property.location() != PromotedLocationDescriptor(StructurePLoc))
+            continue;
+        
+        structure = jsCast&lt;Structure*&gt;(JSValue::decode(values[i]));
+    }
+    RELEASE_ASSERT(structure);
+    
+    // Let's create that object!
+    JSFinalObject* result = JSFinalObject::create(vm, structure);
+    
+    // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
+    // because that happens to be lower-level and more convenient. It doesn't change the
+    // materialization of the property table. We want to have minimal visible effects on the
+    // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
+    // exit.
+    for (PropertyMapEntry entry : structure-&gt;getPropertiesConcurrently()) {
+        for (unsigned i = materialization-&gt;properties().size(); i--;) {
+            const ExitPropertyValue&amp; property = materialization-&gt;properties()[i];
+            if (property.location().kind() != NamedPropertyPLoc)
+                continue;
+            if (codeBlock-&gt;identifier(property.location().info()).impl() != entry.key)
+                continue;
+            
+            result-&gt;putDirect(vm, entry.offset, JSValue::decode(values[i]));
+        }
+    }
+    
+    return result;
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOperationsh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/ftl/FTLOperations.h (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOperations.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/ftl/FTLOperations.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2014 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 FTLOperations_h
+#define FTLOperations_h
+
+#if ENABLE(FTL_JIT)
+
+#include &quot;DFGOperations.h&quot;
+#include &quot;FTLExitTimeObjectMaterialization.h&quot;
+
+namespace JSC { namespace FTL {
+
+extern &quot;C&quot; {
+
+JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure*) WTF_INTERNAL;
+
+JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
+    ExecState*, ExitTimeObjectMaterialization*, EncodedJSValue*) WTF_INTERNAL;
+
+} // extern &quot;C&quot;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLOperations_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLSwitchCaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLSwitchCase.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLSwitchCase.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/ftl/FTLSwitchCase.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -35,6 +35,12 @@
</span><span class="cx"> 
</span><span class="cx"> class SwitchCase {
</span><span class="cx"> public:
</span><ins>+    SwitchCase()
+        : m_value(nullptr)
+        , m_target(nullptr)
+    {
+    }
+
</ins><span class="cx">     SwitchCase(LValue value, LBasicBlock target, Weight weight)
</span><span class="cx">         : m_value(value)
</span><span class="cx">         , m_target(target)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -724,8 +724,6 @@
</span><span class="cx">     {
</span><span class="cx">         Base::finishCreation(vm);
</span><span class="cx">         ASSERT(inherits(info()));
</span><del>-        ASSERT(!structure()-&gt;outOfLineCapacity());
-        ASSERT(structure()-&gt;isEmpty());
</del><span class="cx">         ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
</span><span class="cx">         ASSERT(structure()-&gt;isObject());
</span><span class="cx">         ASSERT(classInfo());
</span><span class="lines">@@ -1052,7 +1050,7 @@
</span><span class="cx">         return (maxSize - allocationSize(0)) / sizeof(WriteBarrier&lt;Unknown&gt;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static JSFinalObject* create(ExecState*, Structure*);
</del><ins>+    static JSFinalObject* create(ExecState*, Structure*, Butterfly* = nullptr);
</ins><span class="cx">     static JSFinalObject* create(VM&amp;, Structure*);
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype, unsigned inlineCapacity)
</span><span class="cx">     {
</span><span class="lines">@@ -1076,15 +1074,16 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> 
</span><del>-    explicit JSFinalObject(VM&amp; vm, Structure* structure)
-        : JSObject(vm, structure)
</del><ins>+    explicit JSFinalObject(VM&amp; vm, Structure* structure, Butterfly* butterfly = nullptr)
+        : JSObject(vm, structure, butterfly)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static const unsigned StructureFlags = JSObject::StructureFlags;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure)
</del><ins>+inline JSFinalObject* JSFinalObject::create(
+    ExecState* exec, Structure* structure, Butterfly* butterfly)
</ins><span class="cx"> {
</span><span class="cx">     JSFinalObject* finalObject = new (
</span><span class="cx">         NotNull, 
</span><span class="lines">@@ -1092,7 +1091,7 @@
</span><span class="cx">             *exec-&gt;heap(),
</span><span class="cx">             allocationSize(structure-&gt;inlineCapacity())
</span><span class="cx">         )
</span><del>-    ) JSFinalObject(exec-&gt;vm(), structure);
</del><ins>+    ) JSFinalObject(exec-&gt;vm(), structure, butterfly);
</ins><span class="cx">     finalObject-&gt;finishCreation(exec-&gt;vm());
</span><span class="cx">     return finalObject;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.cpp (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.cpp        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/runtime/Structure.cpp        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1105,6 +1105,13 @@
</span><span class="cx">     return baseShape.release();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Structure::canUseForAllocationsOf(Structure* other)
+{
+    return inlineCapacity() == other-&gt;inlineCapacity()
+        &amp;&amp; storedPrototype() == other-&gt;storedPrototype()
+        &amp;&amp; objectInitializationBlob() == other-&gt;objectInitializationBlob();
+}
+
</ins><span class="cx"> void Structure::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     out.print(RawPointer(this), &quot;:[&quot;, classInfo()-&gt;className, &quot;, {&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/JavaScriptCore/runtime/Structure.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -433,6 +433,10 @@
</span><span class="cx"> 
</span><span class="cx">     PassRefPtr&lt;StructureShape&gt; toStructureShape(JSValue);
</span><span class="cx">     
</span><ins>+    // Determines if the two structures match enough that this one could be used for allocations
+    // of the other one.
+    bool canUseForAllocationsOf(Structure*);
+    
</ins><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span><span class="cx">     void dumpBrief(PrintStream&amp;, const CString&amp;) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresselidablenewobjectroflcopterthenexitjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/elidable-new-object-roflcopter-then-exit.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/elidable-new-object-roflcopter-then-exit.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/elidable-new-object-roflcopter-then-exit.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 1000000;
+
+var array = [42, &quot;hello&quot;];
+
+function foo() {
+    var result = 0;
+    var q;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: i}}}}}}}}}}}}}}}}}}};
+        var p = {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: i + 1}}}}}}}}}}}}}}}}}}};
+        q = array[(i &gt; n - 100) | 0] + 1;
+        result += o.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f + p.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f;
+    }
+    return q + result;
+}
+
+var result = foo();
+if (result != &quot;hello&quot; + 1 + (sumOfArithSeries(n - 1) + sumOfArithSeries(n)))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresselidenewobjectdagthenexitjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/elide-new-object-dag-then-exit.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/elide-new-object-dag-then-exit.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/elide-new-object-dag-then-exit.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function verify(q, i) {
+    if (q.f == q.g)
+        throw &quot;Error: q.f == q.g&quot;;
+    if (q.f.f != q.g.f)
+        throw &quot;Error: q.f.f != q.g.f&quot;;
+    if (q.f.f.f != i)
+        throw &quot;Error: q.f.f.f != i&quot;;
+}
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        var leaf = {f:i};
+        var o = {f:leaf};
+        var p = {f:leaf};
+        var q = {f:o, g:p};
+        result += q.f.f.f;
+        if (i &gt;= n - 100) {
+            // We want the materialization to happen in the exit. So, before calling the thing that
+            // causes the materialization, we call bar(). We've never profiled this call at the time
+            // of FTL compilation, so this should be an exit.
+            bar();
+            verify(q, i);
+        }
+    }
+    return result;
+}
+
+noInline(foo);
+noInline(verify);
+noInline(bar);
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressobviouslyelidablenewobjectthenexitjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/obviously-elidable-new-object-then-exit.js (0 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/obviously-elidable-new-object-then-exit.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/obviously-elidable-new-object-then-exit.js        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+var array = [1, &quot;hello&quot;];
+
+function foo() {
+    var result = 0;
+    var q;
+    for (var i = 0; i &lt; n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        q = array[(i &gt;= n - 100) | 0] + 1;
+        result += o.f + p.f;
+    }
+    return q + result;
+}
+
+var result = foo();
+if (result != &quot;hello&quot; + 1 + (sumOfArithSeries(n - 1) + sumOfArithSeries(n)))
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/WTF/ChangeLog        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-09-24  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL should sink object allocations
+        https://bugs.webkit.org/show_bug.cgi?id=136330
+
+        Reviewed by Oliver Hunt.
+        
+        Make it possible to reset a Bag.
+
+        * wtf/Bag.h:
+        (WTF::Bag::Bag):
+        (WTF::Bag::~Bag):
+        (WTF::Bag::clear):
+
</ins><span class="cx"> 2014-09-25  Roger Fong  &lt;roger_fong@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Windows] Unreviewed build fix. Ensure that python2.7 is used for Windows builds.
</span></span></pre></div>
<a id="trunkSourceWTFwtfBagh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bag.h (173992 => 173993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bag.h        2014-09-26 02:29:50 UTC (rev 173992)
+++ trunk/Source/WTF/wtf/Bag.h        2014-09-26 03:59:33 UTC (rev 173993)
</span><span class="lines">@@ -46,17 +46,23 @@
</span><span class="cx">     
</span><span class="cx"> public:
</span><span class="cx">     Bag()
</span><del>-        : m_head(0)
</del><ins>+        : m_head(nullptr)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     ~Bag()
</span><span class="cx">     {
</span><ins>+        clear();
+    }
+    
+    void clear()
+    {
</ins><span class="cx">         while (m_head) {
</span><span class="cx">             Node* current = m_head;
</span><span class="cx">             m_head = current-&gt;m_next;
</span><span class="cx">             delete current;
</span><span class="cx">         }
</span><ins>+        m_head = nullptr;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename... Args&gt;
</span></span></pre>
</div>
</div>

</body>
</html>