<!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>[171380] 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/171380">171380</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-07-22 18:19:50 -0700 (Tue, 22 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/169148">r169148</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169185">r169185</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169188">r169188</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169578">r169578</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169582">r169582</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169584">r169584</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169588">r169588</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/169753">r169753</a> from ftlopt.

Source/JavaScriptCore: 
        
Note that <a href="http://trac.webkit.org/projects/webkit/changeset/169753">r169753</a> is merged out of order because it fixes a bug in <a href="http://trac.webkit.org/projects/webkit/changeset/169588">r169588</a>.

    2014-06-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Structure::dfgShouldWatchIfPossible() is unsound
    https://bugs.webkit.org/show_bug.cgi?id=133624
    
    Reviewed by Mark Hahnenberg.
    
    * runtime/Structure.h:
    (JSC::Structure::dfgShouldWatchIfPossible): Make it sound and add some verbiage.
    
    2014-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] AI should be able track structure sets larger than 1
    https://bugs.webkit.org/show_bug.cgi?id=128073
    
    Reviewed by Oliver Hunt.
            
    This makes two major changes to how AI (abstract interpreter) proves that a value has
    some structure:
            
    - StructureAbstractValue can now track an arbitrary number of structures. A set whose
      size is greater than one means that the value may have any of the structures, and we
      don't know which - but we do know that it cannot be any structure not in the set. The
      structure abstract value can still be TOP, which means the set of all structures. We
      artificially limit the set size to StructureAbstractValue::polymorphismLimit to guard
      memory explosion on pathological programs. This limit is big enough that it wouldn't
      kick in for normal code, since we have other heuristics that limit the number of
      structures that we would allow an inline cache to know about.
            
    - We eagerly set watchpoints on all watchable structures and then we assume that
      watchable structures are being watched, and that the watchpoint will jettison the code.
      This allows tracking of watchable structures to be far simpler than before. Previously,
      a structure being tracked as &quot;future possible&quot; was predicated on it being watchable but
      we might not actually watch it. This makes algebra over sets of future possible
      structures quite weird. But watching all watchable structures means that we simple say
      that a structure set can be in the following states: unclobbered, which means it's just
      a set of structures and it doesn't matter what is watchable or what isn't because we've
      proven that the value must have one of these structures right now; and clobbered, which
      means that we have a set of structures, plus all possible structures temporarily, with
      invalidation removing the &quot;plus all possible structures&quot;. Clobbering a set means that
      if any of its structures are unwatchable, the set just becomes TOP; but if all
      structures in the set are watchable then we just set the clobbered bit to add the &quot;plus
      all possible structures temporarily&quot; thing. This precisely tracks the exact meaning of
      watchability and invalidation points.
            
    Slight SunSpider slow-down, neutral on Octane, slight AsmBench speed-up. I believe that
    we will ultimately undo the SunSpider slow-down by making further improvements to the set
    representation. I believe that Octane perfromance will ultimately improve once we remove
    remaining singleton special-cases. The ultimate goal of this is to remove the need to
    try quite so desperately hard to make everything monomorphic as we do currently.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * bytecode/StructureSet.cpp:
    (JSC::StructureSet::clear):
    (JSC::StructureSet::remove):
    (JSC::StructureSet::filter):
    (JSC::StructureSet::copyFromOutOfLine):
    (JSC::StructureSet::StructureSet): Deleted.
    (JSC::StructureSet::operator=): Deleted.
    (JSC::StructureSet::copyFrom): Deleted.
    * bytecode/StructureSet.h:
    (JSC::StructureSet::StructureSet):
    (JSC::StructureSet::operator=):
    (JSC::StructureSet::isEmpty):
    (JSC::StructureSet::genericFilter):
    (JSC::StructureSet::ContainsOutOfLine::ContainsOutOfLine):
    (JSC::StructureSet::ContainsOutOfLine::operator()):
    (JSC::StructureSet::copyFrom):
    (JSC::StructureSet::deleteStructureListIfNecessary):
    (JSC::StructureSet::setEmpty):
    (JSC::StructureSet::getReservedFlag):
    (JSC::StructureSet::setReservedFlag):
    * dfg/DFGAbstractInterpreter.h:
    (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::booleanResult):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::verifyEdge):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::clobberCapturedVars):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::forAllValues):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::clobberStructures):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::observeTransition):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::observeTransitions):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::setDidClobber):
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::dump):
    * dfg/DFGAbstractValue.cpp:
    (JSC::DFG::AbstractValue::observeTransitions):
    (JSC::DFG::AbstractValue::setMostSpecific):
    (JSC::DFG::AbstractValue::set):
    (JSC::DFG::AbstractValue::filter):
    (JSC::DFG::AbstractValue::shouldBeClear):
    (JSC::DFG::AbstractValue::normalizeClarity):
    (JSC::DFG::AbstractValue::checkConsistency):
    (JSC::DFG::AbstractValue::assertIsWatched):
    (JSC::DFG::AbstractValue::dumpInContext):
    (JSC::DFG::AbstractValue::setFuturePossibleStructure): Deleted.
    * dfg/DFGAbstractValue.h:
    (JSC::DFG::AbstractValue::clear):
    (JSC::DFG::AbstractValue::clobberStructures):
    (JSC::DFG::AbstractValue::clobberStructuresFor):
    (JSC::DFG::AbstractValue::observeInvalidationPoint):
    (JSC::DFG::AbstractValue::observeInvalidationPointFor):
    (JSC::DFG::AbstractValue::observeTransition):
    (JSC::DFG::AbstractValue::TransitionObserver::TransitionObserver):
    (JSC::DFG::AbstractValue::TransitionObserver::operator()):
    (JSC::DFG::AbstractValue::TransitionsObserver::TransitionsObserver):
    (JSC::DFG::AbstractValue::TransitionsObserver::operator()):
    (JSC::DFG::AbstractValue::isHeapTop):
    (JSC::DFG::AbstractValue::setType):
    (JSC::DFG::AbstractValue::operator==):
    (JSC::DFG::AbstractValue::merge):
    (JSC::DFG::AbstractValue::validate):
    (JSC::DFG::AbstractValue::hasClobberableState):
    (JSC::DFG::AbstractValue::assertIsWatched):
    (JSC::DFG::AbstractValue::observeIndexingTypeTransition):
    (JSC::DFG::AbstractValue::makeTop):
    (JSC::DFG::AbstractValue::bestProvenStructure): Deleted.
    * dfg/DFGAllocator.h:
    * dfg/DFGArgumentsSimplificationPhase.cpp:
    (JSC::DFG::ArgumentsSimplificationPhase::run):
    * dfg/DFGArrayMode.cpp:
    (JSC::DFG::ArrayMode::alreadyChecked):
    * dfg/DFGAtTailAbstractState.h:
    (JSC::DFG::AtTailAbstractState::structureClobberState):
    (JSC::DFG::AtTailAbstractState::setStructureClobberState):
    (JSC::DFG::AtTailAbstractState::setFoundConstants):
    (JSC::DFG::AtTailAbstractState::haveStructures): Deleted.
    (JSC::DFG::AtTailAbstractState::setHaveStructures): Deleted.
    * dfg/DFGBasicBlock.cpp:
    (JSC::DFG::BasicBlock::BasicBlock):
    * dfg/DFGBasicBlock.h:
    * dfg/DFGBranchDirection.h:
    (JSC::DFG::branchDirectionToString):
    (WTF::printInternal):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::handlePutById):
    * dfg/DFGCFAPhase.cpp:
    (JSC::DFG::CFAPhase::performBlockCFA):
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::CSEPhase::checkStructureElimination):
    (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
    (JSC::DFG::CSEPhase::performNodeCSE):
    * dfg/DFGClobberize.h:
    (JSC::DFG::clobberize):
    * dfg/DFGCommon.cpp:
    (JSC::DFG::startCrashing):
    (JSC::DFG::isCrashing):
    * dfg/DFGCommon.h:
    * dfg/DFGCommonData.cpp:
    (JSC::DFG::CommonData::notifyCompilingStructureTransition):
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::foldConstants):
    (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
    (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
    (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
    * dfg/DFGDesiredWatchpoints.cpp:
    (JSC::DFG::DesiredWatchpoints::consider):
    (JSC::DFG::DesiredWatchpoints::addLazily): Deleted.
    * dfg/DFGDesiredWatchpoints.h:
    (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
    (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
    (JSC::DFG::GenericDesiredWatchpoints::isWatched):
    (JSC::DFG::DesiredWatchpoints::isWatched):
    (JSC::DFG::WatchpointForGenericWatchpointSet::WatchpointForGenericWatchpointSet): Deleted.
    (JSC::DFG::GenericDesiredWatchpoints::addLazily): Deleted.
    (JSC::DFG::GenericDesiredWatchpoints::isStillValid): Deleted.
    (JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState): Deleted.
    (JSC::DFG::GenericDesiredWatchpoints::isValidOrMixed): Deleted.
    (JSC::DFG::DesiredWatchpoints::isStillValid): Deleted.
    (JSC::DFG::DesiredWatchpoints::shouldAssumeMixedState): Deleted.
    (JSC::DFG::DesiredWatchpoints::isValidOrMixed): Deleted.
    * dfg/DFGDoesGC.cpp:
    (JSC::DFG::doesGC):
    * dfg/DFGFixupPhase.cpp:
    (JSC::DFG::FixupPhase::fixupNode):
    (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
    (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::~Graph):
    (JSC::DFG::Graph::dump):
    (JSC::DFG::Graph::dumpBlockHeader):
    (JSC::DFG::Graph::tryGetFoldableView):
    (JSC::DFG::Graph::visitChildren):
    (JSC::DFG::Graph::assertIsWatched):
    (JSC::DFG::Graph::handleAssertionFailure):
    * dfg/DFGGraph.h:
    (JSC::DFG::Graph::convertToConstant):
    (JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
    (JSC::DFG::Graph::addStructureTransitionData): Deleted.
    * dfg/DFGInPlaceAbstractState.cpp:
    (JSC::DFG::InPlaceAbstractState::beginBasicBlock):
    (JSC::DFG::InPlaceAbstractState::initialize):
    (JSC::DFG::InPlaceAbstractState::endBasicBlock):
    (JSC::DFG::InPlaceAbstractState::reset):
    (JSC::DFG::InPlaceAbstractState::merge):
    * dfg/DFGInPlaceAbstractState.h:
    (JSC::DFG::InPlaceAbstractState::structureClobberState):
    (JSC::DFG::InPlaceAbstractState::setStructureClobberState):
    (JSC::DFG::InPlaceAbstractState::setFoundConstants):
    (JSC::DFG::InPlaceAbstractState::haveStructures): Deleted.
    (JSC::DFG::InPlaceAbstractState::setHaveStructures): Deleted.
    * dfg/DFGLivenessAnalysisPhase.cpp:
    (JSC::DFG::LivenessAnalysisPhase::run):
    * dfg/DFGNode.h:
    (JSC::DFG::Node::hasTransition):
    (JSC::DFG::Node::transition):
    (JSC::DFG::Node::hasStructure):
    (JSC::DFG::StructureTransitionData::StructureTransitionData): Deleted.
    (JSC::DFG::Node::convertToStructureTransitionWatchpoint): Deleted.
    (JSC::DFG::Node::hasStructureTransitionData): Deleted.
    (JSC::DFG::Node::structureTransitionData): Deleted.
    * dfg/DFGNodeType.h:
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::compileInThreadImpl):
    * dfg/DFGPredictionPropagationPhase.cpp:
    (JSC::DFG::PredictionPropagationPhase::propagate):
    * dfg/DFGSafeToExecute.h:
    (JSC::DFG::safeToExecute):
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
    (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
    * dfg/DFGSpeculativeJIT.h:
    (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
    * dfg/DFGSpeculativeJIT32_64.cpp:
    (JSC::DFG::SpeculativeJIT::compile):
    * dfg/DFGSpeculativeJIT64.cpp:
    (JSC::DFG::SpeculativeJIT::compile):
    * dfg/DFGStructureAbstractValue.cpp: Added.
    (JSC::DFG::StructureAbstractValue::assertIsWatched):
    (JSC::DFG::StructureAbstractValue::clobber):
    (JSC::DFG::StructureAbstractValue::observeTransition):
    (JSC::DFG::StructureAbstractValue::observeTransitions):
    (JSC::DFG::StructureAbstractValue::add):
    (JSC::DFG::StructureAbstractValue::merge):
    (JSC::DFG::StructureAbstractValue::mergeSlow):
    (JSC::DFG::StructureAbstractValue::mergeNotTop):
    (JSC::DFG::StructureAbstractValue::filter):
    (JSC::DFG::StructureAbstractValue::filterSlow):
    (JSC::DFG::StructureAbstractValue::contains):
    (JSC::DFG::StructureAbstractValue::isSubsetOf):
    (JSC::DFG::StructureAbstractValue::isSupersetOf):
    (JSC::DFG::StructureAbstractValue::overlaps):
    (JSC::DFG::StructureAbstractValue::equalsSlow):
    (JSC::DFG::StructureAbstractValue::dumpInContext):
    (JSC::DFG::StructureAbstractValue::dump):
    * dfg/DFGStructureAbstractValue.h:
    (JSC::DFG::StructureAbstractValue::StructureAbstractValue):
    (JSC::DFG::StructureAbstractValue::operator=):
    (JSC::DFG::StructureAbstractValue::clear):
    (JSC::DFG::StructureAbstractValue::makeTop):
    (JSC::DFG::StructureAbstractValue::assertIsWatched):
    (JSC::DFG::StructureAbstractValue::observeInvalidationPoint):
    (JSC::DFG::StructureAbstractValue::top):
    (JSC::DFG::StructureAbstractValue::isClear):
    (JSC::DFG::StructureAbstractValue::isTop):
    (JSC::DFG::StructureAbstractValue::isNeitherClearNorTop):
    (JSC::DFG::StructureAbstractValue::isClobbered):
    (JSC::DFG::StructureAbstractValue::merge):
    (JSC::DFG::StructureAbstractValue::filter):
    (JSC::DFG::StructureAbstractValue::operator==):
    (JSC::DFG::StructureAbstractValue::size):
    (JSC::DFG::StructureAbstractValue::at):
    (JSC::DFG::StructureAbstractValue::operator[]):
    (JSC::DFG::StructureAbstractValue::onlyStructure):
    (JSC::DFG::StructureAbstractValue::isSupersetOf):
    (JSC::DFG::StructureAbstractValue::makeTopWhenThin):
    (JSC::DFG::StructureAbstractValue::setClobbered):
    (JSC::DFG::StructureAbstractValue::add): Deleted.
    (JSC::DFG::StructureAbstractValue::addAll): Deleted.
    (JSC::DFG::StructureAbstractValue::contains): Deleted.
    (JSC::DFG::StructureAbstractValue::isSubsetOf): Deleted.
    (JSC::DFG::StructureAbstractValue::doesNotContainAnyOtherThan): Deleted.
    (JSC::DFG::StructureAbstractValue::isClearOrTop): Deleted.
    (JSC::DFG::StructureAbstractValue::last): Deleted.
    (JSC::DFG::StructureAbstractValue::speculationFromStructures): Deleted.
    (JSC::DFG::StructureAbstractValue::isValidOffset): Deleted.
    (JSC::DFG::StructureAbstractValue::hasSingleton): Deleted.
    (JSC::DFG::StructureAbstractValue::singleton): Deleted.
    (JSC::DFG::StructureAbstractValue::dumpInContext): Deleted.
    (JSC::DFG::StructureAbstractValue::dump): Deleted.
    (JSC::DFG::StructureAbstractValue::topValue): Deleted.
    * dfg/DFGStructureClobberState.h: Added.
    (JSC::DFG::merge):
    (WTF::printInternal):
    * dfg/DFGTransition.cpp: Added.
    (JSC::DFG::Transition::dumpInContext):
    (JSC::DFG::Transition::dump):
    * dfg/DFGTransition.h: Added.
    (JSC::DFG::Transition::Transition):
    * dfg/DFGTypeCheckHoistingPhase.cpp:
    (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
    (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
    * dfg/DFGWatchableStructureWatchingPhase.cpp: Added.
    (JSC::DFG::WatchableStructureWatchingPhase::WatchableStructureWatchingPhase):
    (JSC::DFG::WatchableStructureWatchingPhase::run):
    (JSC::DFG::WatchableStructureWatchingPhase::tryWatch):
    (JSC::DFG::performWatchableStructureWatching):
    * dfg/DFGWatchableStructureWatchingPhase.h: Added.
    * dfg/DFGWatchpointCollectionPhase.cpp:
    (JSC::DFG::WatchpointCollectionPhase::handle):
    (JSC::DFG::WatchpointCollectionPhase::handleEdge): Deleted.
    * ftl/FTLCapabilities.cpp:
    (JSC::FTL::canCompile):
    * ftl/FTLIntrinsicRepository.h:
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::ftlUnreachable):
    (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
    (JSC::FTL::LowerDFGToLLVM::compileBlock):
    (JSC::FTL::LowerDFGToLLVM::compileNode):
    (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
    (JSC::FTL::LowerDFGToLLVM::compilePhi):
    (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
    (JSC::FTL::LowerDFGToLLVM::compileValueRep):
    (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
    (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
    (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
    (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
    (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
    (JSC::FTL::LowerDFGToLLVM::compileArithMul):
    (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
    (JSC::FTL::LowerDFGToLLVM::compileArithMod):
    (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
    (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
    (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
    (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
    (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
    (JSC::FTL::LowerDFGToLLVM::compileGetById):
    (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
    (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
    (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
    (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
    (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
    (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
    (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
    (JSC::FTL::LowerDFGToLLVM::compileNewArray):
    (JSC::FTL::LowerDFGToLLVM::compileNewArrayBuffer):
    (JSC::FTL::LowerDFGToLLVM::compileAllocatePropertyStorage):
    (JSC::FTL::LowerDFGToLLVM::compileReallocatePropertyStorage):
    (JSC::FTL::LowerDFGToLLVM::compileToString):
    (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
    (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
    (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
    (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
    (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
    (JSC::FTL::LowerDFGToLLVM::compileSwitch):
    (JSC::FTL::LowerDFGToLLVM::compare):
    (JSC::FTL::LowerDFGToLLVM::boolify):
    (JSC::FTL::LowerDFGToLLVM::terminate):
    (JSC::FTL::LowerDFGToLLVM::lowInt32):
    (JSC::FTL::LowerDFGToLLVM::lowInt52):
    (JSC::FTL::LowerDFGToLLVM::opposite):
    (JSC::FTL::LowerDFGToLLVM::lowCell):
    (JSC::FTL::LowerDFGToLLVM::lowBoolean):
    (JSC::FTL::LowerDFGToLLVM::lowDouble):
    (JSC::FTL::LowerDFGToLLVM::lowJSValue):
    (JSC::FTL::LowerDFGToLLVM::speculate):
    (JSC::FTL::LowerDFGToLLVM::isArrayType):
    (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
    (JSC::FTL::LowerDFGToLLVM::callCheck):
    (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
    (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
    (JSC::FTL::LowerDFGToLLVM::setInt52):
    (JSC::FTL::LowerDFGToLLVM::crash):
    (JSC::FTL::LowerDFGToLLVM::compileStructureTransitionWatchpoint): Deleted.
    * ftl/FTLOutput.cpp:
    (JSC::FTL::Output::crashNonTerminal): Deleted.
    * ftl/FTLOutput.h:
    (JSC::FTL::Output::crash): Deleted.
    * jit/JITOperations.h:
    * jsc.cpp:
    (WTF::jscExit):
    (functionQuit):
    (main):
    (printUsageStatement):
    (CommandLine::parseArguments):
    * runtime/Structure.h:
    (JSC::Structure::dfgShouldWatchIfPossible):
    (JSC::Structure::dfgShouldWatch):
    * tests/stress/arrayify-to-structure-contradiction.js: Added.
    (foo):
    * tests/stress/ftl-getmyargumentslength-inline.js: Added.
    (foo):
    * tests/stress/multi-put-by-offset-multiple-transitions.js: Added.
    (foo):
    (Foo):
    * tests/stress/throw-from-ftl-in-loop.js: Added.
    * tests/stress/throw-from-ftl.js: Added.
    (foo):
    
    2014-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Unreviewed, roll out <a href="http://trac.webkit.org/projects/webkit/changeset/169578">r169578</a>. The build system needs some more love.
    
    * InlineRuntimeSymbolTable.h: Removed.
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * build-symbol-table-index.py:
    * build-symbol-table-index.sh:
    * copy-llvm-ir-to-derived-sources.sh:
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::handleCall):
    * dfg/DFGNode.h:
    (JSC::DFG::Node::canBeKnownFunction): Deleted.
    (JSC::DFG::Node::hasKnownFunction): Deleted.
    (JSC::DFG::Node::knownFunction): Deleted.
    (JSC::DFG::Node::giveKnownFunction): Deleted.
    * ftl/FTLAbbreviatedTypes.h:
    * ftl/FTLCompile.cpp:
    (JSC::FTL::compile):
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
    (JSC::FTL::LowerDFGToLLVM::lower):
    (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
    (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Deleted.
    (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Deleted.
    (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Deleted.
    (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Deleted.
    * ftl/FTLState.cpp:
    (JSC::FTL::State::State):
    * ftl/FTLState.h:
    * heap/HandleStack.h:
    * llvm/InitializeLLVM.h:
    * llvm/InitializeLLVMMac.cpp: Removed.
    * llvm/InitializeLLVMMac.mm: Added.
    (JSC::initializeLLVMImpl):
    * llvm/LLVMAPIFunctions.h:
    * llvm/LLVMHeaders.h:
    * runtime/BundlePath.h: Removed.
    * runtime/BundlePath.mm: Removed.
    * runtime/DateConversion.h:
    * runtime/DateInstance.h:
    * runtime/ExceptionHelpers.h:
    * runtime/JSArray.h:
    * runtime/JSCJSValue.h:
    (JSC::JSValue::toFloat):
    * runtime/JSDateMath.h:
    * runtime/JSObject.h:
    * runtime/JSWrapperObject.h:
    * runtime/Options.h:
    * runtime/RegExp.h:
    * runtime/StringObject.h:
    * runtime/Structure.h:
    * tested-symbols.symlst: Removed.
    
    2014-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] FTL native inlining tests take far too long
    https://bugs.webkit.org/show_bug.cgi?id=133498
    
    Unreviewed test gardening.
            
    Added a new exceptions test since the other one appears to not work.
    
    * tests/stress/ftl-library-exception.js:
    * tests/stress/ftl-library-inline-gettimezoneoffset.js: Added.
    (foo):
    * tests/stress/ftl-library-inlining-exceptions-dataview.js: Added.
    (foo):
    * tests/stress/ftl-library-inlining-exceptions.js: Copied from LayoutTests/js/regress/script-tests/ftl-library-inlining-exceptions.js.
    * tests/stress/ftl-library-inlining-loops.js: Copied from LayoutTests/js/regress/script-tests/ftl-library-inlining-loops.js.
    * tests/stress/ftl-library-inlining-random.js:
    * tests/stress/ftl-library-substring.js:
    
    2014-06-03  Matthew Mirman  &lt;mmirman@apple.com&gt;
    
    [ftlopt] Added system for inlining native functions via the FTL.
    https://bugs.webkit.org/show_bug.cgi?id=131515
    
    Reviewed by Filip Pizlo.
    
    Also fixed the build to not compress the bitcode and to 
    include all of the relevant runtime. With GCC_GENERATE_DEBUGGING_SYMBOLS = NO, 
    the produced bitcode files are a 100th the size they were before.  
    Now we can include all of the relevant runtime files with only a 3mb overhead. 
    This is the same overhead as for two compressed files before, 
    but done more efficiently (on both ends) and with less code.
            
    Deciding whether to inline native functions is left up to LLVM. 
    The entire module containing the function is linked into the current 
    compiled JS so that inlining the native functions shouldn't make them smaller.
            
    Rather than loading Runtime.symtbl at runtime FTLState.cpp now includes a file 
    InlineRuntimeSymbolTable.h which statically builds the symbol table hash table.  
    Currently build-symbol-table-index.py updates this file from the 
    contents of tested-symbols.symlst when done building as a matter of convenience.  
    However, in order to include the new contents of the file in the build
    you'd need to build twice.  This will be fixed in future versions.
    
    * JavaScriptCore.xcodeproj/project.pbxproj: Added back runtime files to compile.
    * build-symbol-table-index.py: Changed bitcode suffix. 
    Added inclusion of only tested symbols.  
    Added output to InlineRuntimeSymbolTable.h. 
    * build-symbol-table-index.sh: Changed bitcode suffix.
    * copy-llvm-ir-to-derived-sources.sh: Removed gzip compression.
    * tested-symbols.symlst: Added.
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::handleCall):  
    Now sets the knownFunction of the call node if such a function exists 
    and emits a check that during runtime the callee is in fact known.
    * dfg/DFGNode.h:
    Added functions to set the known function of a call node.
    (JSC::DFG::Node::canBeKnownFunction): Added.
    (JSC::DFG::Node::hasKnownFunction): Added.
    (JSC::DFG::Node::knownFunction): Added.
    (JSC::DFG::Node::giveKnownFunction): Added.
    * ftl/FTLAbbreviatedTypes.h: Added a typedef for LLVMMemoryBufferRef
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Added. Hardcoded threshold to 275.
    (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Added.
    (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Added.
    (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Added.
    (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):  
    Added call to possiblyCompileInlineableNativeCall
    * ftl/FTLOutput.h:
    (JSC::FTL::Output::allocaName):  Added. Useful for debugging.
    * ftl/FTLState.cpp:
    (JSC::FTL::State::State): Added an include for InlineRuntimeSymbolTable.h
    * ftl/FTLState.h: Added symbol table hash table.
    * ftl/FTLCompile.cpp:
    (JSC::FTL::compile): Added inlining and dead function elimination passes.
    * heap/HandleStack.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
    * InlineRuntimeSymbolTable.h: Added.  
    * llvm/InitializeLLVMMac.mm: Deleted.
    * llvm/InitializeLLVMMac.cpp: Added.
    * llvm/LLVMAPIFunctions.h: Added macros to include Bitcode parsing and linking functions.
    * llvm/LLVMHeaders.h: Added includes for Bitcode parsing and linking.
    * runtime/BundlePath.h: Added.
    * runtime/BundlePath.mm: Added.
    * runtime/DateInstance.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
    * runtime/DateInstance.h: ditto.
    * runtime/DateConversion.h: ditto.
    * runtime/ExceptionHelpers.h: ditto.
    * runtime/JSCJSValue.h: ditto.
    * runtime/JSArray.h: ditto.
    * runtime/JSDateMath.h: ditto.
    * runtime/JSObject.h: ditto.
    * runtime/JSObject.h: ditto.
    * runtime/RegExp.h: ditto.
    * runtime/Structure.h: ditto.
    * runtime/Options.h:  Added maximumLLVMInstructionCountForNativeInlining.
    * tests/stress/ftl-library-inlining-random.js: Added.
    * tests/stress/ftl-library-substring.js: Added.
    
    2014-05-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] DFG::clobberize should be blind to the effects of GC
    https://bugs.webkit.org/show_bug.cgi?id=133166
    
    Reviewed by Goeffrey Garen.
            
    Move the computation of where GCs happen to DFG::doesGC().
            
    Large (&gt;5x) speed-up on programs that do loop-invariant string concatenations.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * dfg/DFGAbstractHeap.h:
    * dfg/DFGClobberize.h:
    (JSC::DFG::clobberize):
    (JSC::DFG::clobberizeForAllocation): Deleted.
    * dfg/DFGDoesGC.cpp: Added.
    (JSC::DFG::doesGC):
    * dfg/DFGDoesGC.h: Added.
    * dfg/DFGStoreBarrierElisionPhase.cpp:
    (JSC::DFG::StoreBarrierElisionPhase::handleNode):
    (JSC::DFG::StoreBarrierElisionPhase::couldCauseGC): Deleted.
    
    2014-05-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] A StructureSet with one element should only require one word and no allocation
    https://bugs.webkit.org/show_bug.cgi?id=133014
    
    Reviewed by Oliver Hunt.
            
    This makes it more efficient to use StructureSet in situations where the common case is
    just one structure.
            
    I also took the opportunity to use the same set terminology we use in BitVector: merge,
    filter, exclude, contains, etc.
            
    Eventually, this will be used to implement StructureAbstractValue as well.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * bytecode/StructureSet.cpp: Added.
    (JSC::StructureSet::StructureSet):
    (JSC::StructureSet::operator=):
    (JSC::StructureSet::clear):
    (JSC::StructureSet::add):
    (JSC::StructureSet::remove):
    (JSC::StructureSet::contains):
    (JSC::StructureSet::merge):
    (JSC::StructureSet::filter):
    (JSC::StructureSet::exclude):
    (JSC::StructureSet::isSubsetOf):
    (JSC::StructureSet::overlaps):
    (JSC::StructureSet::operator==):
    (JSC::StructureSet::speculationFromStructures):
    (JSC::StructureSet::arrayModesFromStructures):
    (JSC::StructureSet::dumpInContext):
    (JSC::StructureSet::dump):
    (JSC::StructureSet::addOutOfLine):
    (JSC::StructureSet::containsOutOfLine):
    (JSC::StructureSet::copyFrom):
    (JSC::StructureSet::OutOfLineList::create):
    (JSC::StructureSet::OutOfLineList::destroy):
    * bytecode/StructureSet.h:
    (JSC::StructureSet::StructureSet):
    (JSC::StructureSet::~StructureSet):
    (JSC::StructureSet::onlyStructure):
    (JSC::StructureSet::isEmpty):
    (JSC::StructureSet::size):
    (JSC::StructureSet::at):
    (JSC::StructureSet::operator[]):
    (JSC::StructureSet::last):
    (JSC::StructureSet::OutOfLineList::list):
    (JSC::StructureSet::OutOfLineList::OutOfLineList):
    (JSC::StructureSet::deleteStructureListIfNecessary):
    (JSC::StructureSet::isThin):
    (JSC::StructureSet::pointer):
    (JSC::StructureSet::singleStructure):
    (JSC::StructureSet::structureList):
    (JSC::StructureSet::set):
    (JSC::StructureSet::clear): Deleted.
    (JSC::StructureSet::add): Deleted.
    (JSC::StructureSet::addAll): Deleted.
    (JSC::StructureSet::remove): Deleted.
    (JSC::StructureSet::contains): Deleted.
    (JSC::StructureSet::containsOnly): Deleted.
    (JSC::StructureSet::isSubsetOf): Deleted.
    (JSC::StructureSet::overlaps): Deleted.
    (JSC::StructureSet::singletonStructure): Deleted.
    (JSC::StructureSet::speculationFromStructures): Deleted.
    (JSC::StructureSet::arrayModesFromStructures): Deleted.
    (JSC::StructureSet::operator==): Deleted.
    (JSC::StructureSet::dumpInContext): Deleted.
    (JSC::StructureSet::dump): Deleted.
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
    (JSC::DFG::ByteCodeParser::handleGetById):
    (JSC::DFG::ByteCodeParser::parseBlock):
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
    * dfg/DFGNode.h:
    (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
    * dfg/DFGTypeCheckHoistingPhase.cpp:
    (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck):

Source/WTF: 

    2014-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] AI should be able track structure sets larger than 1
    https://bugs.webkit.org/show_bug.cgi?id=128073
    
    Reviewed by Oliver Hunt.
    
    * wtf/Bag.h:
    (WTF::Bag::Node::Node):
    (WTF::Bag::add):

LayoutTests: 

    2014-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] AI should be able track structure sets larger than 1
    https://bugs.webkit.org/show_bug.cgi?id=128073
    
    Reviewed by Oliver Hunt.
    
    * js/regress/get-by-id-bimorphic-check-structure-elimination-expected.txt: Added.
    * js/regress/get-by-id-bimorphic-check-structure-elimination-simple-expected.txt: Added.
    * js/regress/get-by-id-bimorphic-check-structure-elimination-simple.html: Added.
    * js/regress/get-by-id-bimorphic-check-structure-elimination.html: Added.
    * js/regress/get-by-id-check-structure-elimination-expected.txt: Added.
    * js/regress/get-by-id-check-structure-elimination.html: Added.
    * js/regress/get-by-id-quadmorphic-check-structure-elimination-simple-expected.txt: Added.
    * js/regress/get-by-id-quadmorphic-check-structure-elimination-simple.html: Added.
    * js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination-simple.js: Added.
    * js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination.js: Added.
    * js/regress/script-tests/get-by-id-check-structure-elimination.js: Added.
    * js/regress/script-tests/get-by-id-quadmorphic-check-structure-elimination-simple.js: Added.
    
    2014-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] FTL native inlining tests take far too long
    https://bugs.webkit.org/show_bug.cgi?id=133498
    
    Unreviewed test gardening.
            
    Move long-running tests that focus on correctness into JSC/tests/stress.
    Speed up the performance tests by reducing allocation and call overhead.
    
    * js/regress/ftl-library-inlining-exceptions-expected.txt: Removed.
    * js/regress/ftl-library-inlining-exceptions.html: Removed.
    * js/regress/ftl-library-inlining-folding-expected.txt: Removed.
    * js/regress/ftl-library-inlining-folding.html: Removed.
    * js/regress/ftl-library-inlining-loops-expected.txt: Removed.
    * js/regress/ftl-library-inlining-loops.html: Removed.
    * js/regress/script-tests/ftl-library-inlining-dataview.js:
    (foo): Deleted.
    * js/regress/script-tests/ftl-library-inlining-exceptions.js: Removed.
    * js/regress/script-tests/ftl-library-inlining-folding.js: Removed.
    * js/regress/script-tests/ftl-library-inlining-loops.js: Removed.
    * js/regress/script-tests/ftl-library-inlining.js:
    (foo): Deleted.
    
    2014-06-03  Matthew Mirman  &lt;mmirman@apple.com&gt;
    
    [ftlopt] Added system for inlining native functions via the FTL.
    https://bugs.webkit.org/show_bug.cgi?id=131515
    
    Reviewed by Filip Pizlo.
    
    Adds microbenchmarks. 
    
    * js/regress/script-tests/ftl-library-inlining.js: Added.
    * js/regress/ftl-library-inlining-expected.txt: Added.
    * js/regress/ftl-library-inlining.html: Added.
    * js/regress/script-tests/ftl-library-inlining-dataview.js: Added.
    * js/regress/ftl-library-inlining-dataview-expected.txt: Added.
    * js/regress/ftl-library-inlining-dataview.html: Added.
    * js/regress/script-tests/ftl-library-inlining-exceptions.js: Added.
    * js/regress/ftl-library-inlining-exceptions-expected.txt: Added.        
    * js/regress/ftl-library-inlining-exceptions.html: Added.                
    * js/regress/script-tests/ftl-library-inlining-folding.js: Added.
    * js/regress/ftl-library-inlining-folding-expected.txt: Added.        
    * js/regress/ftl-library-inlining-folding-expected.html: Added.                
    * js/regress/script-tests/ftl-library-inlining-loops.js: Added.
    * js/regress/ftl-library-inlining-loops-expected.txt: Added.        
    * js/regress/ftl-library-inlining-loops.html: Added.                
            
    2014-05-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] DFG::clobberize should be blind to the effects of GC
    https://bugs.webkit.org/show_bug.cgi?id=133166
    
    Reviewed by Geoffrey Garen.
    
    * js/regress/hoist-make-rope-expected.txt: Added.
    * js/regress/hoist-make-rope.html: Added.
    * js/regress/script-tests/hoist-make-rope.js: Added.
    (foo):</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="#trunkSourceJavaScriptCoredfgDFGAbstractHeaph">trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.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="#trunkSourceJavaScriptCoredfgDFGAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAllocatorh">trunk/Source/JavaScriptCore/dfg/DFGAllocator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArgumentsSimplificationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModecpp">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAtTailAbstractStateh">trunk/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.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="#trunkSourceJavaScriptCoredfgDFGBranchDirectionh">trunk/Source/JavaScriptCore/dfg/DFGBranchDirection.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCFAPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCSEPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommoncpp">trunk/Source/JavaScriptCore/dfg/DFGCommon.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommonh">trunk/Source/JavaScriptCore/dfg/DFGCommon.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommonDatacpp">trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDesiredWatchpointscpp">trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDesiredWatchpointsh">trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</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="#trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp">trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStateh">trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLivenessAnalysisPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.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="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</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="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</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="#trunkSourceJavaScriptCoredfgDFGStoreBarrierElisionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOutputcpp">trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOutputh">trunk/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.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="#trunkLayoutTestsjsregressftllibraryinliningdataviewexpectedtxt">trunk/LayoutTests/js/regress/ftl-library-inlining-dataview-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressftllibraryinliningdataviewhtml">trunk/LayoutTests/js/regress/ftl-library-inlining-dataview.html</a></li>
<li><a href="#trunkLayoutTestsjsregressftllibraryinliningexpectedtxt">trunk/LayoutTests/js/regress/ftl-library-inlining-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressftllibraryinlininghtml">trunk/LayoutTests/js/regress/ftl-library-inlining.html</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationexpectedtxt">trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationsimpleexpectedtxt">trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationsimplehtml">trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple.html</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationhtml">trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination.html</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidcheckstructureeliminationexpectedtxt">trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidcheckstructureeliminationhtml">trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination.html</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidquadmorphiccheckstructureeliminationsimpleexpectedtxt">trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgetbyidquadmorphiccheckstructureeliminationsimplehtml">trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple.html</a></li>
<li><a href="#trunkLayoutTestsjsregresshoistmakeropeexpectedtxt">trunk/LayoutTests/js/regress/hoist-make-rope-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresshoistmakeropehtml">trunk/LayoutTests/js/regress/hoist-make-rope.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsftllibraryinliningdataviewjs">trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining-dataview.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsftllibraryinliningjs">trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgetbyidbimorphiccheckstructureeliminationsimplejs">trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination-simple.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgetbyidbimorphiccheckstructureeliminationjs">trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgetbyidcheckstructureeliminationjs">trunk/LayoutTests/js/regress/script-tests/get-by-id-check-structure-elimination.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgetbyidquadmorphiccheckstructureeliminationsimplejs">trunk/LayoutTests/js/regress/script-tests/get-by-id-quadmorphic-check-structure-elimination-simple.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestshoistmakeropejs">trunk/LayoutTests/js/regress/script-tests/hoist-make-rope.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureSetcpp">trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCh">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureClobberStateh">trunk/Source/JavaScriptCore/dfg/DFGStructureClobberState.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTransitioncpp">trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTransitionh">trunk/Source/JavaScriptCore/dfg/DFGTransition.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhaseh">trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayifytostructurecontradictionjs">trunk/Source/JavaScriptCore/tests/stress/arrayify-to-structure-contradiction.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftlgetmyargumentslengthinlinejs">trunk/Source/JavaScriptCore/tests/stress/ftl-getmyargumentslength-inline.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibraryexceptionjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-exception.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibraryinlinegettimezoneoffsetjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-inline-gettimezoneoffset.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibraryinliningexceptionsdataviewjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions-dataview.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibraryinliningexceptionsjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibraryinliningloopsjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-loops.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibraryinliningrandomjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-random.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftllibrarysubstringjs">trunk/Source/JavaScriptCore/tests/stress/ftl-library-substring.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmultiputbyoffsetmultipletransitionsjs">trunk/Source/JavaScriptCore/tests/stress/multi-put-by-offset-multiple-transitions.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressthrowfromftlinloopjs">trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-in-loop.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressthrowfromftljs">trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/LayoutTests/ChangeLog        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,3 +1,88 @@
</span><ins>+2014-07-22  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Merge r169148, r169185, r169188, r169578, r169582, r169584, r169588, r169753 from ftlopt.
+
+    2014-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] AI should be able track structure sets larger than 1
+            https://bugs.webkit.org/show_bug.cgi?id=128073
+    
+            Reviewed by Oliver Hunt.
+    
+            * js/regress/get-by-id-bimorphic-check-structure-elimination-expected.txt: Added.
+            * js/regress/get-by-id-bimorphic-check-structure-elimination-simple-expected.txt: Added.
+            * js/regress/get-by-id-bimorphic-check-structure-elimination-simple.html: Added.
+            * js/regress/get-by-id-bimorphic-check-structure-elimination.html: Added.
+            * js/regress/get-by-id-check-structure-elimination-expected.txt: Added.
+            * js/regress/get-by-id-check-structure-elimination.html: Added.
+            * js/regress/get-by-id-quadmorphic-check-structure-elimination-simple-expected.txt: Added.
+            * js/regress/get-by-id-quadmorphic-check-structure-elimination-simple.html: Added.
+            * js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination-simple.js: Added.
+            * js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination.js: Added.
+            * js/regress/script-tests/get-by-id-check-structure-elimination.js: Added.
+            * js/regress/script-tests/get-by-id-quadmorphic-check-structure-elimination-simple.js: Added.
+    
+    2014-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] FTL native inlining tests take far too long
+            https://bugs.webkit.org/show_bug.cgi?id=133498
+    
+            Unreviewed test gardening.
+            
+            Move long-running tests that focus on correctness into JSC/tests/stress.
+            Speed up the performance tests by reducing allocation and call overhead.
+    
+            * js/regress/ftl-library-inlining-exceptions-expected.txt: Removed.
+            * js/regress/ftl-library-inlining-exceptions.html: Removed.
+            * js/regress/ftl-library-inlining-folding-expected.txt: Removed.
+            * js/regress/ftl-library-inlining-folding.html: Removed.
+            * js/regress/ftl-library-inlining-loops-expected.txt: Removed.
+            * js/regress/ftl-library-inlining-loops.html: Removed.
+            * js/regress/script-tests/ftl-library-inlining-dataview.js:
+            (foo): Deleted.
+            * js/regress/script-tests/ftl-library-inlining-exceptions.js: Removed.
+            * js/regress/script-tests/ftl-library-inlining-folding.js: Removed.
+            * js/regress/script-tests/ftl-library-inlining-loops.js: Removed.
+            * js/regress/script-tests/ftl-library-inlining.js:
+            (foo): Deleted.
+    
+    2014-06-03  Matthew Mirman  &lt;mmirman@apple.com&gt;
+    
+            [ftlopt] Added system for inlining native functions via the FTL.
+            https://bugs.webkit.org/show_bug.cgi?id=131515
+    
+            Reviewed by Filip Pizlo.
+    
+            Adds microbenchmarks. 
+    
+            * js/regress/script-tests/ftl-library-inlining.js: Added.
+            * js/regress/ftl-library-inlining-expected.txt: Added.
+            * js/regress/ftl-library-inlining.html: Added.
+            * js/regress/script-tests/ftl-library-inlining-dataview.js: Added.
+            * js/regress/ftl-library-inlining-dataview-expected.txt: Added.
+            * js/regress/ftl-library-inlining-dataview.html: Added.
+            * js/regress/script-tests/ftl-library-inlining-exceptions.js: Added.
+            * js/regress/ftl-library-inlining-exceptions-expected.txt: Added.        
+            * js/regress/ftl-library-inlining-exceptions.html: Added.                
+            * js/regress/script-tests/ftl-library-inlining-folding.js: Added.
+            * js/regress/ftl-library-inlining-folding-expected.txt: Added.        
+            * js/regress/ftl-library-inlining-folding-expected.html: Added.                
+            * js/regress/script-tests/ftl-library-inlining-loops.js: Added.
+            * js/regress/ftl-library-inlining-loops-expected.txt: Added.        
+            * js/regress/ftl-library-inlining-loops.html: Added.                
+            
+    2014-05-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] DFG::clobberize should be blind to the effects of GC
+            https://bugs.webkit.org/show_bug.cgi?id=133166
+    
+            Reviewed by Geoffrey Garen.
+    
+            * js/regress/hoist-make-rope-expected.txt: Added.
+            * js/regress/hoist-make-rope.html: Added.
+            * js/regress/script-tests/hoist-make-rope.js: Added.
+            (foo):
+    
</ins><span class="cx"> 2014-07-22  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix window-inactive css selectors when using querySelector.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressftllibraryinliningdataviewexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/ftl-library-inlining-dataview-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/ftl-library-inlining-dataview-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/ftl-library-inlining-dataview-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/ftl-library-inlining-dataview
+
+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="trunkLayoutTestsjsregressftllibraryinliningdataviewhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/ftl-library-inlining-dataview.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/ftl-library-inlining-dataview.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/ftl-library-inlining-dataview.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/ftl-library-inlining-dataview.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="trunkLayoutTestsjsregressftllibraryinliningexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/ftl-library-inlining-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/ftl-library-inlining-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/ftl-library-inlining-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/ftl-library-inlining
+
+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="trunkLayoutTestsjsregressftllibraryinlininghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/ftl-library-inlining.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/ftl-library-inlining.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/ftl-library-inlining.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/ftl-library-inlining.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="trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/get-by-id-bimorphic-check-structure-elimination
+
+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="trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationsimpleexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/get-by-id-bimorphic-check-structure-elimination-simple
+
+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="trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationsimplehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination-simple.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/get-by-id-bimorphic-check-structure-elimination-simple.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="trunkLayoutTestsjsregressgetbyidbimorphiccheckstructureeliminationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-bimorphic-check-structure-elimination.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/get-by-id-bimorphic-check-structure-elimination.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="trunkLayoutTestsjsregressgetbyidcheckstructureeliminationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/get-by-id-check-structure-elimination
+
+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="trunkLayoutTestsjsregressgetbyidcheckstructureeliminationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-check-structure-elimination.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/get-by-id-check-structure-elimination.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="trunkLayoutTestsjsregressgetbyidquadmorphiccheckstructureeliminationsimpleexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/get-by-id-quadmorphic-check-structure-elimination-simple
+
+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="trunkLayoutTestsjsregressgetbyidquadmorphiccheckstructureeliminationsimplehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-id-quadmorphic-check-structure-elimination-simple.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/get-by-id-quadmorphic-check-structure-elimination-simple.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="trunkLayoutTestsjsregresshoistmakeropeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/hoist-make-rope-expected.txt (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/hoist-make-rope-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/hoist-make-rope-expected.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/hoist-make-rope
+
+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="trunkLayoutTestsjsregresshoistmakeropehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/hoist-make-rope.html (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/hoist-make-rope.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/hoist-make-rope.html        2014-07-23 01:19:50 UTC (rev 171380)
</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/hoist-make-rope.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="trunkLayoutTestsjsregressscripttestsftllibraryinliningdataviewjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining-dataview.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining-dataview.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining-dataview.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+(function() {
+    var result = 0;
+    var d = new DataView(new ArrayBuffer(5));
+    for (var i = 0; i &lt; 1000000; i++) {
+        d.setInt8(0, 4);
+        d.setInt8(1, 2);
+        d.setInt8(2, 6);
+        d.setInt16(0, 20);
+        result += d.getInt8(2) + d.getInt8(0);
+    }
+    if (result != 6000000) 
+        throw &quot;Bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsftllibraryinliningjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/ftl-library-inlining.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+(function() {
+    for (var i = 0 ; i &lt; 10000000; i++)
+        Math.random();
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsgetbyidbimorphiccheckstructureeliminationsimplejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination-simple.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination-simple.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination-simple.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+(function() {
+    var o = {a:1};
+    var p = {a:2, l:13};
+    var result = 0;
+    for (var i = 0; i &lt; 1000000; ++i) {
+        result ^= o.a;
+        var tmp = o;
+        o = p;
+        p = tmp;
+    }
+    if (result != 0)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsgetbyidbimorphiccheckstructureeliminationjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/get-by-id-bimorphic-check-structure-elimination.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+(function() {
+    var o = {a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11};
+    var p = {a:2, b:3, c:4, d:5, e:6, f:7, g:8, h:9, i:10, j:11, k:12, l:13};
+    var result = 0;
+    for (var i = 0; i &lt; 1000000; ++i) {
+        result += o.a ^ o.b ^ o.c ^ o.d ^ o.e ^ o.f ^ o.g ^ o.h ^ o.i ^ o.j ^ o.k;
+        var tmp = o;
+        o = p;
+        p = tmp;
+    }
+    if (result != 6500000)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsgetbyidcheckstructureeliminationjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/get-by-id-check-structure-elimination.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/get-by-id-check-structure-elimination.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/get-by-id-check-structure-elimination.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+(function() {
+    var o = {a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11};
+    var result = 0;
+    for (var i = 0; i &lt; 1000000; ++i)
+        result += o.a ^ o.b | o.c ^ o.d &amp; o.e ^ o.f | o.g ^ o.h &amp; o.i ^ o.j | o.k;
+    if (result != 15000000)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsgetbyidquadmorphiccheckstructureeliminationsimplejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/get-by-id-quadmorphic-check-structure-elimination-simple.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/get-by-id-quadmorphic-check-structure-elimination-simple.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/get-by-id-quadmorphic-check-structure-elimination-simple.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+(function() {
+    var o = {a:1};
+    var p = {a:2, l:13};
+    var q = {a:3, b:3};
+    var r = {a:4, c:5};
+    var result = 0;
+    for (var i = 0; i &lt; 1000000; ++i) {
+        result ^= o.a;
+        var tmp = o;
+        o = p;
+        p = q;
+        q = r;
+        r = tmp;
+    }
+    if (result != 0)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestshoistmakeropejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/hoist-make-rope.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/hoist-make-rope.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/hoist-make-rope.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function foo(a, b) {
+    var result;
+    for (var i = 0; i &lt; 10000; ++i)
+        result = a + b;
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 500; ++i) {
+    var result = foo(&quot;hello &quot;, &quot;world!&quot;);
+    if (result != &quot;hello world!&quot;)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -90,6 +90,7 @@
</span><span class="cx">     bytecode/SamplingTool.cpp
</span><span class="cx">     bytecode/SpecialPointer.cpp
</span><span class="cx">     bytecode/SpeculatedType.cpp
</span><ins>+    bytecode/StructureSet.cpp
</ins><span class="cx">     bytecode/StructureStubClearingWatchpoint.cpp
</span><span class="cx">     bytecode/StructureStubInfo.cpp
</span><span class="cx">     bytecode/UnlinkedCodeBlock.cpp
</span><span class="lines">@@ -137,6 +138,7 @@
</span><span class="cx">     dfg/DFGDesiredWeakReferences.cpp
</span><span class="cx">     dfg/DFGDesiredWriteBarriers.cpp
</span><span class="cx">     dfg/DFGDisassembler.cpp
</span><ins>+    dfg/DFGDoesGC.cpp
</ins><span class="cx">     dfg/DFGDominators.cpp
</span><span class="cx">     dfg/DFGDriver.cpp
</span><span class="cx">     dfg/DFGEdge.cpp
</span><span class="lines">@@ -191,9 +193,11 @@
</span><span class="cx">     dfg/DFGStaticExecutionCountEstimationPhase.cpp
</span><span class="cx">     dfg/DFGStoreBarrierElisionPhase.cpp
</span><span class="cx">     dfg/DFGStrengthReductionPhase.cpp
</span><ins>+    dfg/DFGStructureAbstractValue.cpp
</ins><span class="cx">     dfg/DFGThreadData.cpp
</span><span class="cx">     dfg/DFGThunks.cpp
</span><span class="cx">     dfg/DFGTierUpCheckInjectionPhase.cpp
</span><ins>+    dfg/DFGTransition.cpp
</ins><span class="cx">     dfg/DFGTypeCheckHoistingPhase.cpp
</span><span class="cx">     dfg/DFGUnificationPhase.cpp
</span><span class="cx">     dfg/DFGUseKind.cpp
</span><span class="lines">@@ -204,6 +208,7 @@
</span><span class="cx">     dfg/DFGVariableEvent.cpp
</span><span class="cx">     dfg/DFGVariableEventStream.cpp
</span><span class="cx">     dfg/DFGVirtualRegisterAllocationPhase.cpp
</span><ins>+    dfg/DFGWatchableStructureWatchingPhase.cpp
</ins><span class="cx">     dfg/DFGWatchpointCollectionPhase.cpp
</span><span class="cx">     dfg/DFGWorklist.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,3 +1,662 @@
</span><ins>+2014-07-22  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Merge r169148, r169185, r169188, r169578, r169582, r169584, r169588, r169753 from ftlopt.
+        
+        Note that r169753 is merged out of order because it fixes a bug in r169588.
+
+    2014-06-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Structure::dfgShouldWatchIfPossible() is unsound
+            https://bugs.webkit.org/show_bug.cgi?id=133624
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * runtime/Structure.h:
+            (JSC::Structure::dfgShouldWatchIfPossible): Make it sound and add some verbiage.
+    
+    2014-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] AI should be able track structure sets larger than 1
+            https://bugs.webkit.org/show_bug.cgi?id=128073
+    
+            Reviewed by Oliver Hunt.
+            
+            This makes two major changes to how AI (abstract interpreter) proves that a value has
+            some structure:
+            
+            - StructureAbstractValue can now track an arbitrary number of structures. A set whose
+              size is greater than one means that the value may have any of the structures, and we
+              don't know which - but we do know that it cannot be any structure not in the set. The
+              structure abstract value can still be TOP, which means the set of all structures. We
+              artificially limit the set size to StructureAbstractValue::polymorphismLimit to guard
+              memory explosion on pathological programs. This limit is big enough that it wouldn't
+              kick in for normal code, since we have other heuristics that limit the number of
+              structures that we would allow an inline cache to know about.
+            
+            - We eagerly set watchpoints on all watchable structures and then we assume that
+              watchable structures are being watched, and that the watchpoint will jettison the code.
+              This allows tracking of watchable structures to be far simpler than before. Previously,
+              a structure being tracked as &quot;future possible&quot; was predicated on it being watchable but
+              we might not actually watch it. This makes algebra over sets of future possible
+              structures quite weird. But watching all watchable structures means that we simple say
+              that a structure set can be in the following states: unclobbered, which means it's just
+              a set of structures and it doesn't matter what is watchable or what isn't because we've
+              proven that the value must have one of these structures right now; and clobbered, which
+              means that we have a set of structures, plus all possible structures temporarily, with
+              invalidation removing the &quot;plus all possible structures&quot;. Clobbering a set means that
+              if any of its structures are unwatchable, the set just becomes TOP; but if all
+              structures in the set are watchable then we just set the clobbered bit to add the &quot;plus
+              all possible structures temporarily&quot; thing. This precisely tracks the exact meaning of
+              watchability and invalidation points.
+            
+            Slight SunSpider slow-down, neutral on Octane, slight AsmBench speed-up. I believe that
+            we will ultimately undo the SunSpider slow-down by making further improvements to the set
+            representation. I believe that Octane perfromance will ultimately improve once we remove
+            remaining singleton special-cases. The ultimate goal of this is to remove the need to
+            try quite so desperately hard to make everything monomorphic as we do currently.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/StructureSet.cpp:
+            (JSC::StructureSet::clear):
+            (JSC::StructureSet::remove):
+            (JSC::StructureSet::filter):
+            (JSC::StructureSet::copyFromOutOfLine):
+            (JSC::StructureSet::StructureSet): Deleted.
+            (JSC::StructureSet::operator=): Deleted.
+            (JSC::StructureSet::copyFrom): Deleted.
+            * bytecode/StructureSet.h:
+            (JSC::StructureSet::StructureSet):
+            (JSC::StructureSet::operator=):
+            (JSC::StructureSet::isEmpty):
+            (JSC::StructureSet::genericFilter):
+            (JSC::StructureSet::ContainsOutOfLine::ContainsOutOfLine):
+            (JSC::StructureSet::ContainsOutOfLine::operator()):
+            (JSC::StructureSet::copyFrom):
+            (JSC::StructureSet::deleteStructureListIfNecessary):
+            (JSC::StructureSet::setEmpty):
+            (JSC::StructureSet::getReservedFlag):
+            (JSC::StructureSet::setReservedFlag):
+            * dfg/DFGAbstractInterpreter.h:
+            (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::booleanResult):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::verifyEdge):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::clobberCapturedVars):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::forAllValues):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::clobberStructures):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::observeTransition):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::observeTransitions):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::setDidClobber):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::dump):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::observeTransitions):
+            (JSC::DFG::AbstractValue::setMostSpecific):
+            (JSC::DFG::AbstractValue::set):
+            (JSC::DFG::AbstractValue::filter):
+            (JSC::DFG::AbstractValue::shouldBeClear):
+            (JSC::DFG::AbstractValue::normalizeClarity):
+            (JSC::DFG::AbstractValue::checkConsistency):
+            (JSC::DFG::AbstractValue::assertIsWatched):
+            (JSC::DFG::AbstractValue::dumpInContext):
+            (JSC::DFG::AbstractValue::setFuturePossibleStructure): Deleted.
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::clear):
+            (JSC::DFG::AbstractValue::clobberStructures):
+            (JSC::DFG::AbstractValue::clobberStructuresFor):
+            (JSC::DFG::AbstractValue::observeInvalidationPoint):
+            (JSC::DFG::AbstractValue::observeInvalidationPointFor):
+            (JSC::DFG::AbstractValue::observeTransition):
+            (JSC::DFG::AbstractValue::TransitionObserver::TransitionObserver):
+            (JSC::DFG::AbstractValue::TransitionObserver::operator()):
+            (JSC::DFG::AbstractValue::TransitionsObserver::TransitionsObserver):
+            (JSC::DFG::AbstractValue::TransitionsObserver::operator()):
+            (JSC::DFG::AbstractValue::isHeapTop):
+            (JSC::DFG::AbstractValue::setType):
+            (JSC::DFG::AbstractValue::operator==):
+            (JSC::DFG::AbstractValue::merge):
+            (JSC::DFG::AbstractValue::validate):
+            (JSC::DFG::AbstractValue::hasClobberableState):
+            (JSC::DFG::AbstractValue::assertIsWatched):
+            (JSC::DFG::AbstractValue::observeIndexingTypeTransition):
+            (JSC::DFG::AbstractValue::makeTop):
+            (JSC::DFG::AbstractValue::bestProvenStructure): Deleted.
+            * dfg/DFGAllocator.h:
+            * dfg/DFGArgumentsSimplificationPhase.cpp:
+            (JSC::DFG::ArgumentsSimplificationPhase::run):
+            * dfg/DFGArrayMode.cpp:
+            (JSC::DFG::ArrayMode::alreadyChecked):
+            * dfg/DFGAtTailAbstractState.h:
+            (JSC::DFG::AtTailAbstractState::structureClobberState):
+            (JSC::DFG::AtTailAbstractState::setStructureClobberState):
+            (JSC::DFG::AtTailAbstractState::setFoundConstants):
+            (JSC::DFG::AtTailAbstractState::haveStructures): Deleted.
+            (JSC::DFG::AtTailAbstractState::setHaveStructures): Deleted.
+            * dfg/DFGBasicBlock.cpp:
+            (JSC::DFG::BasicBlock::BasicBlock):
+            * dfg/DFGBasicBlock.h:
+            * dfg/DFGBranchDirection.h:
+            (JSC::DFG::branchDirectionToString):
+            (WTF::printInternal):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            * dfg/DFGCFAPhase.cpp:
+            (JSC::DFG::CFAPhase::performBlockCFA):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::checkStructureElimination):
+            (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGCommon.cpp:
+            (JSC::DFG::startCrashing):
+            (JSC::DFG::isCrashing):
+            * dfg/DFGCommon.h:
+            * dfg/DFGCommonData.cpp:
+            (JSC::DFG::CommonData::notifyCompilingStructureTransition):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+            * dfg/DFGDesiredWatchpoints.cpp:
+            (JSC::DFG::DesiredWatchpoints::consider):
+            (JSC::DFG::DesiredWatchpoints::addLazily): Deleted.
+            * dfg/DFGDesiredWatchpoints.h:
+            (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
+            (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
+            (JSC::DFG::GenericDesiredWatchpoints::isWatched):
+            (JSC::DFG::DesiredWatchpoints::isWatched):
+            (JSC::DFG::WatchpointForGenericWatchpointSet::WatchpointForGenericWatchpointSet): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::addLazily): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::isStillValid): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::isValidOrMixed): Deleted.
+            (JSC::DFG::DesiredWatchpoints::isStillValid): Deleted.
+            (JSC::DFG::DesiredWatchpoints::shouldAssumeMixedState): Deleted.
+            (JSC::DFG::DesiredWatchpoints::isValidOrMixed): Deleted.
+            * dfg/DFGDoesGC.cpp:
+            (JSC::DFG::doesGC):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+            (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::~Graph):
+            (JSC::DFG::Graph::dump):
+            (JSC::DFG::Graph::dumpBlockHeader):
+            (JSC::DFG::Graph::tryGetFoldableView):
+            (JSC::DFG::Graph::visitChildren):
+            (JSC::DFG::Graph::assertIsWatched):
+            (JSC::DFG::Graph::handleAssertionFailure):
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::convertToConstant):
+            (JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
+            (JSC::DFG::Graph::addStructureTransitionData): Deleted.
+            * dfg/DFGInPlaceAbstractState.cpp:
+            (JSC::DFG::InPlaceAbstractState::beginBasicBlock):
+            (JSC::DFG::InPlaceAbstractState::initialize):
+            (JSC::DFG::InPlaceAbstractState::endBasicBlock):
+            (JSC::DFG::InPlaceAbstractState::reset):
+            (JSC::DFG::InPlaceAbstractState::merge):
+            * dfg/DFGInPlaceAbstractState.h:
+            (JSC::DFG::InPlaceAbstractState::structureClobberState):
+            (JSC::DFG::InPlaceAbstractState::setStructureClobberState):
+            (JSC::DFG::InPlaceAbstractState::setFoundConstants):
+            (JSC::DFG::InPlaceAbstractState::haveStructures): Deleted.
+            (JSC::DFG::InPlaceAbstractState::setHaveStructures): Deleted.
+            * dfg/DFGLivenessAnalysisPhase.cpp:
+            (JSC::DFG::LivenessAnalysisPhase::run):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasTransition):
+            (JSC::DFG::Node::transition):
+            (JSC::DFG::Node::hasStructure):
+            (JSC::DFG::StructureTransitionData::StructureTransitionData): Deleted.
+            (JSC::DFG::Node::convertToStructureTransitionWatchpoint): Deleted.
+            (JSC::DFG::Node::hasStructureTransitionData): Deleted.
+            (JSC::DFG::Node::structureTransitionData): Deleted.
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+            (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+            * dfg/DFGSpeculativeJIT.h:
+            (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStructureAbstractValue.cpp: Added.
+            (JSC::DFG::StructureAbstractValue::assertIsWatched):
+            (JSC::DFG::StructureAbstractValue::clobber):
+            (JSC::DFG::StructureAbstractValue::observeTransition):
+            (JSC::DFG::StructureAbstractValue::observeTransitions):
+            (JSC::DFG::StructureAbstractValue::add):
+            (JSC::DFG::StructureAbstractValue::merge):
+            (JSC::DFG::StructureAbstractValue::mergeSlow):
+            (JSC::DFG::StructureAbstractValue::mergeNotTop):
+            (JSC::DFG::StructureAbstractValue::filter):
+            (JSC::DFG::StructureAbstractValue::filterSlow):
+            (JSC::DFG::StructureAbstractValue::contains):
+            (JSC::DFG::StructureAbstractValue::isSubsetOf):
+            (JSC::DFG::StructureAbstractValue::isSupersetOf):
+            (JSC::DFG::StructureAbstractValue::overlaps):
+            (JSC::DFG::StructureAbstractValue::equalsSlow):
+            (JSC::DFG::StructureAbstractValue::dumpInContext):
+            (JSC::DFG::StructureAbstractValue::dump):
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::StructureAbstractValue):
+            (JSC::DFG::StructureAbstractValue::operator=):
+            (JSC::DFG::StructureAbstractValue::clear):
+            (JSC::DFG::StructureAbstractValue::makeTop):
+            (JSC::DFG::StructureAbstractValue::assertIsWatched):
+            (JSC::DFG::StructureAbstractValue::observeInvalidationPoint):
+            (JSC::DFG::StructureAbstractValue::top):
+            (JSC::DFG::StructureAbstractValue::isClear):
+            (JSC::DFG::StructureAbstractValue::isTop):
+            (JSC::DFG::StructureAbstractValue::isNeitherClearNorTop):
+            (JSC::DFG::StructureAbstractValue::isClobbered):
+            (JSC::DFG::StructureAbstractValue::merge):
+            (JSC::DFG::StructureAbstractValue::filter):
+            (JSC::DFG::StructureAbstractValue::operator==):
+            (JSC::DFG::StructureAbstractValue::size):
+            (JSC::DFG::StructureAbstractValue::at):
+            (JSC::DFG::StructureAbstractValue::operator[]):
+            (JSC::DFG::StructureAbstractValue::onlyStructure):
+            (JSC::DFG::StructureAbstractValue::isSupersetOf):
+            (JSC::DFG::StructureAbstractValue::makeTopWhenThin):
+            (JSC::DFG::StructureAbstractValue::setClobbered):
+            (JSC::DFG::StructureAbstractValue::add): Deleted.
+            (JSC::DFG::StructureAbstractValue::addAll): Deleted.
+            (JSC::DFG::StructureAbstractValue::contains): Deleted.
+            (JSC::DFG::StructureAbstractValue::isSubsetOf): Deleted.
+            (JSC::DFG::StructureAbstractValue::doesNotContainAnyOtherThan): Deleted.
+            (JSC::DFG::StructureAbstractValue::isClearOrTop): Deleted.
+            (JSC::DFG::StructureAbstractValue::last): Deleted.
+            (JSC::DFG::StructureAbstractValue::speculationFromStructures): Deleted.
+            (JSC::DFG::StructureAbstractValue::isValidOffset): Deleted.
+            (JSC::DFG::StructureAbstractValue::hasSingleton): Deleted.
+            (JSC::DFG::StructureAbstractValue::singleton): Deleted.
+            (JSC::DFG::StructureAbstractValue::dumpInContext): Deleted.
+            (JSC::DFG::StructureAbstractValue::dump): Deleted.
+            (JSC::DFG::StructureAbstractValue::topValue): Deleted.
+            * dfg/DFGStructureClobberState.h: Added.
+            (JSC::DFG::merge):
+            (WTF::printInternal):
+            * dfg/DFGTransition.cpp: Added.
+            (JSC::DFG::Transition::dumpInContext):
+            (JSC::DFG::Transition::dump):
+            * dfg/DFGTransition.h: Added.
+            (JSC::DFG::Transition::Transition):
+            * dfg/DFGTypeCheckHoistingPhase.cpp:
+            (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+            (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+            * dfg/DFGWatchableStructureWatchingPhase.cpp: Added.
+            (JSC::DFG::WatchableStructureWatchingPhase::WatchableStructureWatchingPhase):
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            (JSC::DFG::WatchableStructureWatchingPhase::tryWatch):
+            (JSC::DFG::performWatchableStructureWatching):
+            * dfg/DFGWatchableStructureWatchingPhase.h: Added.
+            * dfg/DFGWatchpointCollectionPhase.cpp:
+            (JSC::DFG::WatchpointCollectionPhase::handle):
+            (JSC::DFG::WatchpointCollectionPhase::handleEdge): Deleted.
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLIntrinsicRepository.h:
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::ftlUnreachable):
+            (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
+            (JSC::FTL::LowerDFGToLLVM::compileBlock):
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
+            (JSC::FTL::LowerDFGToLLVM::compilePhi):
+            (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+            (JSC::FTL::LowerDFGToLLVM::compileValueRep):
+            (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+            (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
+            (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
+            (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
+            (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+            (JSC::FTL::LowerDFGToLLVM::compileArithMul):
+            (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
+            (JSC::FTL::LowerDFGToLLVM::compileArithMod):
+            (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
+            (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
+            (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+            (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+            (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
+            (JSC::FTL::LowerDFGToLLVM::compileGetById):
+            (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
+            (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+            (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
+            (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+            (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+            (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+            (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+            (JSC::FTL::LowerDFGToLLVM::compileNewArray):
+            (JSC::FTL::LowerDFGToLLVM::compileNewArrayBuffer):
+            (JSC::FTL::LowerDFGToLLVM::compileAllocatePropertyStorage):
+            (JSC::FTL::LowerDFGToLLVM::compileReallocatePropertyStorage):
+            (JSC::FTL::LowerDFGToLLVM::compileToString):
+            (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+            (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+            (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+            (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+            (JSC::FTL::LowerDFGToLLVM::compare):
+            (JSC::FTL::LowerDFGToLLVM::boolify):
+            (JSC::FTL::LowerDFGToLLVM::terminate):
+            (JSC::FTL::LowerDFGToLLVM::lowInt32):
+            (JSC::FTL::LowerDFGToLLVM::lowInt52):
+            (JSC::FTL::LowerDFGToLLVM::opposite):
+            (JSC::FTL::LowerDFGToLLVM::lowCell):
+            (JSC::FTL::LowerDFGToLLVM::lowBoolean):
+            (JSC::FTL::LowerDFGToLLVM::lowDouble):
+            (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+            (JSC::FTL::LowerDFGToLLVM::speculate):
+            (JSC::FTL::LowerDFGToLLVM::isArrayType):
+            (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
+            (JSC::FTL::LowerDFGToLLVM::callCheck):
+            (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+            (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
+            (JSC::FTL::LowerDFGToLLVM::setInt52):
+            (JSC::FTL::LowerDFGToLLVM::crash):
+            (JSC::FTL::LowerDFGToLLVM::compileStructureTransitionWatchpoint): Deleted.
+            * ftl/FTLOutput.cpp:
+            (JSC::FTL::Output::crashNonTerminal): Deleted.
+            * ftl/FTLOutput.h:
+            (JSC::FTL::Output::crash): Deleted.
+            * jit/JITOperations.h:
+            * jsc.cpp:
+            (WTF::jscExit):
+            (functionQuit):
+            (main):
+            (printUsageStatement):
+            (CommandLine::parseArguments):
+            * runtime/Structure.h:
+            (JSC::Structure::dfgShouldWatchIfPossible):
+            (JSC::Structure::dfgShouldWatch):
+            * tests/stress/arrayify-to-structure-contradiction.js: Added.
+            (foo):
+            * tests/stress/ftl-getmyargumentslength-inline.js: Added.
+            (foo):
+            * tests/stress/multi-put-by-offset-multiple-transitions.js: Added.
+            (foo):
+            (Foo):
+            * tests/stress/throw-from-ftl-in-loop.js: Added.
+            * tests/stress/throw-from-ftl.js: Added.
+            (foo):
+    
+    2014-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Unreviewed, roll out r169578. The build system needs some more love.
+    
+            * InlineRuntimeSymbolTable.h: Removed.
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * build-symbol-table-index.py:
+            * build-symbol-table-index.sh:
+            * copy-llvm-ir-to-derived-sources.sh:
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::canBeKnownFunction): Deleted.
+            (JSC::DFG::Node::hasKnownFunction): Deleted.
+            (JSC::DFG::Node::knownFunction): Deleted.
+            (JSC::DFG::Node::giveKnownFunction): Deleted.
+            * ftl/FTLAbbreviatedTypes.h:
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::compile):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+            (JSC::FTL::LowerDFGToLLVM::lower):
+            (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
+            (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Deleted.
+            (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Deleted.
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Deleted.
+            (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Deleted.
+            * ftl/FTLState.cpp:
+            (JSC::FTL::State::State):
+            * ftl/FTLState.h:
+            * heap/HandleStack.h:
+            * llvm/InitializeLLVM.h:
+            * llvm/InitializeLLVMMac.cpp: Removed.
+            * llvm/InitializeLLVMMac.mm: Added.
+            (JSC::initializeLLVMImpl):
+            * llvm/LLVMAPIFunctions.h:
+            * llvm/LLVMHeaders.h:
+            * runtime/BundlePath.h: Removed.
+            * runtime/BundlePath.mm: Removed.
+            * runtime/DateConversion.h:
+            * runtime/DateInstance.h:
+            * runtime/ExceptionHelpers.h:
+            * runtime/JSArray.h:
+            * runtime/JSCJSValue.h:
+            (JSC::JSValue::toFloat):
+            * runtime/JSDateMath.h:
+            * runtime/JSObject.h:
+            * runtime/JSWrapperObject.h:
+            * runtime/Options.h:
+            * runtime/RegExp.h:
+            * runtime/StringObject.h:
+            * runtime/Structure.h:
+            * tested-symbols.symlst: Removed.
+    
+    2014-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] FTL native inlining tests take far too long
+            https://bugs.webkit.org/show_bug.cgi?id=133498
+    
+            Unreviewed test gardening.
+            
+            Added a new exceptions test since the other one appears to not work.
+    
+            * tests/stress/ftl-library-exception.js:
+            * tests/stress/ftl-library-inline-gettimezoneoffset.js: Added.
+            (foo):
+            * tests/stress/ftl-library-inlining-exceptions-dataview.js: Added.
+            (foo):
+            * tests/stress/ftl-library-inlining-exceptions.js: Copied from LayoutTests/js/regress/script-tests/ftl-library-inlining-exceptions.js.
+            * tests/stress/ftl-library-inlining-loops.js: Copied from LayoutTests/js/regress/script-tests/ftl-library-inlining-loops.js.
+            * tests/stress/ftl-library-inlining-random.js:
+            * tests/stress/ftl-library-substring.js:
+    
+    2014-06-03  Matthew Mirman  &lt;mmirman@apple.com&gt;
+    
+            [ftlopt] Added system for inlining native functions via the FTL.
+            https://bugs.webkit.org/show_bug.cgi?id=131515
+    
+            Reviewed by Filip Pizlo.
+    
+            Also fixed the build to not compress the bitcode and to 
+            include all of the relevant runtime. With GCC_GENERATE_DEBUGGING_SYMBOLS = NO, 
+            the produced bitcode files are a 100th the size they were before.  
+            Now we can include all of the relevant runtime files with only a 3mb overhead. 
+            This is the same overhead as for two compressed files before, 
+            but done more efficiently (on both ends) and with less code.
+            
+            Deciding whether to inline native functions is left up to LLVM. 
+            The entire module containing the function is linked into the current 
+            compiled JS so that inlining the native functions shouldn't make them smaller.
+            
+            Rather than loading Runtime.symtbl at runtime FTLState.cpp now includes a file 
+            InlineRuntimeSymbolTable.h which statically builds the symbol table hash table.  
+            Currently build-symbol-table-index.py updates this file from the 
+            contents of tested-symbols.symlst when done building as a matter of convenience.  
+            However, in order to include the new contents of the file in the build
+            you'd need to build twice.  This will be fixed in future versions.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj: Added back runtime files to compile.
+            * build-symbol-table-index.py: Changed bitcode suffix. 
+            Added inclusion of only tested symbols.  
+            Added output to InlineRuntimeSymbolTable.h. 
+            * build-symbol-table-index.sh: Changed bitcode suffix.
+            * copy-llvm-ir-to-derived-sources.sh: Removed gzip compression.
+            * tested-symbols.symlst: Added.
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall):  
+            Now sets the knownFunction of the call node if such a function exists 
+            and emits a check that during runtime the callee is in fact known.
+            * dfg/DFGNode.h:
+            Added functions to set the known function of a call node.
+            (JSC::DFG::Node::canBeKnownFunction): Added.
+            (JSC::DFG::Node::hasKnownFunction): Added.
+            (JSC::DFG::Node::knownFunction): Added.
+            (JSC::DFG::Node::giveKnownFunction): Added.
+            * ftl/FTLAbbreviatedTypes.h: Added a typedef for LLVMMemoryBufferRef
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Added. Hardcoded threshold to 275.
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Added.
+            (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Added.
+            (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Added.
+            (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):  
+            Added call to possiblyCompileInlineableNativeCall
+            * ftl/FTLOutput.h:
+            (JSC::FTL::Output::allocaName):  Added. Useful for debugging.
+            * ftl/FTLState.cpp:
+            (JSC::FTL::State::State): Added an include for InlineRuntimeSymbolTable.h
+            * ftl/FTLState.h: Added symbol table hash table.
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::compile): Added inlining and dead function elimination passes.
+            * heap/HandleStack.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
+            * InlineRuntimeSymbolTable.h: Added.  
+            * llvm/InitializeLLVMMac.mm: Deleted.
+            * llvm/InitializeLLVMMac.cpp: Added.
+            * llvm/LLVMAPIFunctions.h: Added macros to include Bitcode parsing and linking functions.
+            * llvm/LLVMHeaders.h: Added includes for Bitcode parsing and linking.
+            * runtime/BundlePath.h: Added.
+            * runtime/BundlePath.mm: Added.
+            * runtime/DateInstance.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
+            * runtime/DateInstance.h: ditto.
+            * runtime/DateConversion.h: ditto.
+            * runtime/ExceptionHelpers.h: ditto.
+            * runtime/JSCJSValue.h: ditto.
+            * runtime/JSArray.h: ditto.
+            * runtime/JSDateMath.h: ditto.
+            * runtime/JSObject.h: ditto.
+            * runtime/JSObject.h: ditto.
+            * runtime/RegExp.h: ditto.
+            * runtime/Structure.h: ditto.
+            * runtime/Options.h:  Added maximumLLVMInstructionCountForNativeInlining.
+            * tests/stress/ftl-library-inlining-random.js: Added.
+            * tests/stress/ftl-library-substring.js: Added.
+    
+    2014-05-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] DFG::clobberize should be blind to the effects of GC
+            https://bugs.webkit.org/show_bug.cgi?id=133166
+    
+            Reviewed by Goeffrey Garen.
+            
+            Move the computation of where GCs happen to DFG::doesGC().
+            
+            Large (&gt;5x) speed-up on programs that do loop-invariant string concatenations.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractHeap.h:
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            (JSC::DFG::clobberizeForAllocation): Deleted.
+            * dfg/DFGDoesGC.cpp: Added.
+            (JSC::DFG::doesGC):
+            * dfg/DFGDoesGC.h: Added.
+            * dfg/DFGStoreBarrierElisionPhase.cpp:
+            (JSC::DFG::StoreBarrierElisionPhase::handleNode):
+            (JSC::DFG::StoreBarrierElisionPhase::couldCauseGC): Deleted.
+    
+    2014-05-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] A StructureSet with one element should only require one word and no allocation
+            https://bugs.webkit.org/show_bug.cgi?id=133014
+    
+            Reviewed by Oliver Hunt.
+            
+            This makes it more efficient to use StructureSet in situations where the common case is
+            just one structure.
+            
+            I also took the opportunity to use the same set terminology we use in BitVector: merge,
+            filter, exclude, contains, etc.
+            
+            Eventually, this will be used to implement StructureAbstractValue as well.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/StructureSet.cpp: Added.
+            (JSC::StructureSet::StructureSet):
+            (JSC::StructureSet::operator=):
+            (JSC::StructureSet::clear):
+            (JSC::StructureSet::add):
+            (JSC::StructureSet::remove):
+            (JSC::StructureSet::contains):
+            (JSC::StructureSet::merge):
+            (JSC::StructureSet::filter):
+            (JSC::StructureSet::exclude):
+            (JSC::StructureSet::isSubsetOf):
+            (JSC::StructureSet::overlaps):
+            (JSC::StructureSet::operator==):
+            (JSC::StructureSet::speculationFromStructures):
+            (JSC::StructureSet::arrayModesFromStructures):
+            (JSC::StructureSet::dumpInContext):
+            (JSC::StructureSet::dump):
+            (JSC::StructureSet::addOutOfLine):
+            (JSC::StructureSet::containsOutOfLine):
+            (JSC::StructureSet::copyFrom):
+            (JSC::StructureSet::OutOfLineList::create):
+            (JSC::StructureSet::OutOfLineList::destroy):
+            * bytecode/StructureSet.h:
+            (JSC::StructureSet::StructureSet):
+            (JSC::StructureSet::~StructureSet):
+            (JSC::StructureSet::onlyStructure):
+            (JSC::StructureSet::isEmpty):
+            (JSC::StructureSet::size):
+            (JSC::StructureSet::at):
+            (JSC::StructureSet::operator[]):
+            (JSC::StructureSet::last):
+            (JSC::StructureSet::OutOfLineList::list):
+            (JSC::StructureSet::OutOfLineList::OutOfLineList):
+            (JSC::StructureSet::deleteStructureListIfNecessary):
+            (JSC::StructureSet::isThin):
+            (JSC::StructureSet::pointer):
+            (JSC::StructureSet::singleStructure):
+            (JSC::StructureSet::structureList):
+            (JSC::StructureSet::set):
+            (JSC::StructureSet::clear): Deleted.
+            (JSC::StructureSet::add): Deleted.
+            (JSC::StructureSet::addAll): Deleted.
+            (JSC::StructureSet::remove): Deleted.
+            (JSC::StructureSet::contains): Deleted.
+            (JSC::StructureSet::containsOnly): Deleted.
+            (JSC::StructureSet::isSubsetOf): Deleted.
+            (JSC::StructureSet::overlaps): Deleted.
+            (JSC::StructureSet::singletonStructure): Deleted.
+            (JSC::StructureSet::speculationFromStructures): Deleted.
+            (JSC::StructureSet::arrayModesFromStructures): Deleted.
+            (JSC::StructureSet::operator==): Deleted.
+            (JSC::StructureSet::dumpInContext): Deleted.
+            (JSC::StructureSet::dump): Deleted.
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
+            * dfg/DFGTypeCheckHoistingPhase.cpp:
+            (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck):
+    
</ins><span class="cx"> 2014-07-22  Ryuan Choi  &lt;ryuan.choi@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix attempt on the EFL port after r171362.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -343,6 +343,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\SamplingTool.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\SpecialPointer.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\SpeculatedType.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\bytecode\StructureSet.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\StructureStubClearingWatchpoint.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\StructureStubInfo.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\UnlinkedCodeBlock.cpp&quot; /&gt;
</span><span class="lines">@@ -387,6 +388,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGDesiredWeakReferences.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGDesiredWriteBarriers.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGDisassembler.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGDoesGC.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGDominators.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGDriver.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGEdge.cpp&quot; /&gt;
</span><span class="lines">@@ -441,11 +443,13 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGStaticExecutionCountEstimationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGStoreBarrierElisionPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGStrengthReductionPhase.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGStructureAbstractValue.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGThreadData.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGThunks.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGTierUpCheckInjectionPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGToFTLDeferredCompilationCallback.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGToFTLForOSREntryDeferredCompilationCallback.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGTransition.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGTypeCheckHoistingPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGUnificationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGUseKind.cpp&quot; /&gt;
</span><span class="lines">@@ -457,6 +461,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGVariableEventStream.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGVirtualRegisterAllocationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGWatchpointCollectionPhase.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGWatchableStructureWatchingPhase.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGWorklist.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\disassembler\Disassembler.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\disassembler\LLVMDisassembler.cpp&quot; /&gt;
</span><span class="lines">@@ -989,6 +994,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGDesiredWeakReferences.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGDesiredWriteBarriers.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGDisassembler.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGDoesGC.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGDominators.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGDoubleFormatState.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGDriver.h&quot; /&gt;
</span><span class="lines">@@ -1064,11 +1070,13 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGStoreBarrierElisionPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGStrengthReductionPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGStructureAbstractValue.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGStructureClobberState.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGThreadData.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGThunks.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGTierUpCheckInjectionPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGToFTLDeferredCompilationCallback.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGToFTLForOSREntryDeferredCompilationCallback.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGTransition.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGTypeCheckHoistingPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGUnificationPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGUseKind.h&quot; /&gt;
</span><span class="lines">@@ -1081,6 +1089,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGVariableEventStream.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGVariadicFunction.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGVirtualRegisterAllocationPhase.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGWatchableStructureWatchingPhase.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGWatchpointCollectionPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGWorklist.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\disassembler\Disassembler.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -282,6 +282,7 @@
</span><span class="cx">                 0F4CED5F18CEA7AB00802FE0 /* PolymorphicGetByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
</span><span class="cx">                 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
</span><span class="cx">                 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55989717C86C5600A1E543 /* ToNativeFromValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -292,6 +293,8 @@
</span><span class="cx">                 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */; };
</span><span class="cx">                 0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5780A118FE1E98001E72D9 /* PureNaN.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F5A1273192D9FDF008764A3 /* DFGDoesGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */; };
+                0F5A1274192D9FDF008764A3 /* DFGDoesGC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A52CF17ADD717008ECB2D /* CopyToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */; };
</span><span class="cx">                 0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A6282188C98D40072C9DF /* FTLValueRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -354,6 +357,7 @@
</span><span class="cx">                 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */; };
</ins><span class="cx">                 0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F2B93172E049E007DBDA5 /* FTLLink.cpp */; };
</span><span class="cx">                 0F8F2B96172E04A3007DBDA5 /* FTLLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8F2B94172E049E007DBDA5 /* FTLLink.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */; };
</span><span class="lines">@@ -419,6 +423,7 @@
</span><span class="cx">                 0FB14E1F18124ACE009B6B4D /* JITInlineCacheGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FB14E211812570B009B6B4D /* DFGInlineCacheWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FB14E2318130955009B6B4D /* DFGInlineCacheWrapperInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */; };
</ins><span class="cx">                 0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
</span><span class="cx">                 0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -495,6 +500,8 @@
</span><span class="cx">                 0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFADD180738C000472CE4 /* FTLLocation.cpp */; };
</span><span class="cx">                 0FCEFAE0180738C000472CE4 /* FTLLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFADE180738C000472CE4 /* FTLLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2C92316D01EE900C7803F /* StructureInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FD2D4FE192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD2D4FC192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp */; };
+                0FD2D4FF192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2D4FD192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */; };
</span><span class="cx">                 0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3C82214115D0E00FD81CB /* DFGDriver.h */; };
</span><span class="cx">                 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */; };
</span><span class="lines">@@ -528,6 +535,8 @@
</span><span class="cx">                 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FE228ED1436AB2700196C48 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
</span><ins>+                0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE7211B193B9C590031F6ED /* DFGTransition.cpp */; };
+                0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE7211C193B9C590031F6ED /* DFGTransition.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */; };
</span><span class="cx">                 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FE95F7918B5694700B531FB /* FTLDataSection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE95F7718B5694700B531FB /* FTLDataSection.cpp */; };
</span><span class="lines">@@ -2094,6 +2103,7 @@
</span><span class="cx">                 0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicGetByIdList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F55989717C86C5600A1E543 /* ToNativeFromValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToNativeFromValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2104,6 +2114,8 @@
</span><span class="cx">                 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionCounter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5780A118FE1E98001E72D9 /* PureNaN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PureNaN.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDoesGC.cpp; path = dfg/DFGDoesGC.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDoesGC.h; path = dfg/DFGDoesGC.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F5A52CF17ADD717008ECB2D /* CopyToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyToken.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueRange.cpp; path = ftl/FTLValueRange.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5A6282188C98D40072C9DF /* FTLValueRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueRange.h; path = ftl/FTLValueRange.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2164,6 +2176,7 @@
</span><span class="cx">                 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeUseDef.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureAbstractValue.cpp; path = dfg/DFGStructureAbstractValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F8F2B93172E049E007DBDA5 /* FTLLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLink.cpp; path = ftl/FTLLink.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8F2B94172E049E007DBDA5 /* FTLLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FTLLink.h; path = ftl/FTLLink.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredIdentifiers.cpp; path = dfg/DFGDesiredIdentifiers.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2229,6 +2242,7 @@
</span><span class="cx">                 0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineCacheGenerator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapper.h; path = dfg/DFGInlineCacheWrapper.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapperInlines.h; path = dfg/DFGInlineCacheWrapperInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB4B51916B62772003F696B /* DFGAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAllocator.h; path = dfg/DFGAllocator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB4B51A16B62772003F696B /* DFGCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCommon.cpp; path = dfg/DFGCommon.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2316,6 +2330,8 @@
</span><span class="cx">                 0FCEFADD180738C000472CE4 /* FTLLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLocation.cpp; path = ftl/FTLLocation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCEFADE180738C000472CE4 /* FTLLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLocation.h; path = ftl/FTLLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FD2C92316D01EE900C7803F /* StructureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FD2D4FC192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGWatchableStructureWatchingPhase.cpp; path = dfg/DFGWatchableStructureWatchingPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FD2D4FD192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGWatchableStructureWatchingPhase.h; path = dfg/DFGWatchableStructureWatchingPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDriver.cpp; path = dfg/DFGDriver.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FD3C82214115D0E00FD81CB /* DFGDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDriver.h; path = dfg/DFGDriver.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlockInlines.h; path = dfg/DFGBasicBlockInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2351,6 +2367,8 @@
</span><span class="cx">                 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE228EA1436AB2300196C48 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Options.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FE7211B193B9C590031F6ED /* DFGTransition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTransition.cpp; path = dfg/DFGTransition.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE7211C193B9C590031F6ED /* DFGTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTransition.h; path = dfg/DFGTransition.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredWatchpoints.cpp; path = dfg/DFGDesiredWatchpoints.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredWatchpoints.h; path = dfg/DFGDesiredWatchpoints.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE95F7718B5694700B531FB /* FTLDataSection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLDataSection.cpp; path = ftl/FTLDataSection.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4689,6 +4707,8 @@
</span><span class="cx">                                 C2981FDB17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.h */,
</span><span class="cx">                                 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */,
</span><span class="cx">                                 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */,
</span><ins>+                                0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */,
+                                0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */,
</ins><span class="cx">                                 0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */,
</span><span class="cx">                                 0FD81AD0154FB4EB00983E72 /* DFGDominators.h */,
</span><span class="cx">                                 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */,
</span><span class="lines">@@ -4709,6 +4729,8 @@
</span><span class="cx">                                 0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */,
</span><span class="cx">                                 A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
</span><span class="cx">                                 A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
</span><ins>+                                2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
+                                2A88067719107D5500CB0BBB /* DFGFunctionWhitelist.h */,
</ins><span class="cx">                                 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */,
</span><span class="cx">                                 86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */,
</span><span class="cx">                                 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */,
</span><span class="lines">@@ -4813,7 +4835,9 @@
</span><span class="cx">                                 2ACCF3DD185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h */,
</span><span class="cx">                                 0FC20CB31852E2C600C9E954 /* DFGStrengthReductionPhase.cpp */,
</span><span class="cx">                                 0FC20CB41852E2C600C9E954 /* DFGStrengthReductionPhase.h */,
</span><ins>+                                0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */,
</ins><span class="cx">                                 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */,
</span><ins>+                                0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */,
</ins><span class="cx">                                 0F2FCCF718A60070001A27F8 /* DFGThreadData.cpp */,
</span><span class="cx">                                 0F2FCCF818A60070001A27F8 /* DFGThreadData.h */,
</span><span class="cx">                                 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
</span><span class="lines">@@ -4824,6 +4848,8 @@
</span><span class="cx">                                 0FD8A32217D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h */,
</span><span class="cx">                                 0FD8A32317D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp */,
</span><span class="cx">                                 0FD8A32417D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h */,
</span><ins>+                                0FE7211B193B9C590031F6ED /* DFGTransition.cpp */,
+                                0FE7211C193B9C590031F6ED /* DFGTransition.h */,
</ins><span class="cx">                                 0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */,
</span><span class="cx">                                 0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */,
</span><span class="cx">                                 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */,
</span><span class="lines">@@ -4845,12 +4871,12 @@
</span><span class="cx">                                 0F2BDC431522801700CD8910 /* DFGVariableEventStream.h */,
</span><span class="cx">                                 0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */,
</span><span class="cx">                                 0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */,
</span><ins>+                                0FD2D4FC192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp */,
+                                0FD2D4FD192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h */,
</ins><span class="cx">                                 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */,
</span><span class="cx">                                 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */,
</span><span class="cx">                                 0FDB2CE5174830A2007B3C1B /* DFGWorklist.cpp */,
</span><span class="cx">                                 0FDB2CE6174830A2007B3C1B /* DFGWorklist.h */,
</span><del>-                                2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
-                                2A88067719107D5500CB0BBB /* DFGFunctionWhitelist.h */,
</del><span class="cx">                         );
</span><span class="cx">                         name = dfg;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -5036,6 +5062,7 @@
</span><span class="cx">                                 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */,
</span><span class="cx">                                 0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
</span><span class="cx">                                 0FD82E4F141DAEA100179C94 /* SpeculatedType.h */,
</span><ins>+                                0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */,
</ins><span class="cx">                                 0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
</span><span class="cx">                                 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */,
</span><span class="cx">                                 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */,
</span><span class="lines">@@ -5787,6 +5814,7 @@
</span><span class="cx">                                 0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
</span><span class="cx">                                 0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
</span><span class="cx">                                 0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */,
</span><ins>+                                0FD2D4FF192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h in Headers */,
</ins><span class="cx">                                 0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */,
</span><span class="cx">                                 0FE95F7A18B5694700B531FB /* FTLDataSection.h in Headers */,
</span><span class="cx">                                 2AC922BC18A16182003CE0FB /* FTLDWARFDebugLineInfo.h in Headers */,
</span><span class="lines">@@ -5828,6 +5856,7 @@
</span><span class="cx">                                 0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */,
</span><span class="cx">                                 0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */,
</span><span class="cx">                                 0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
</span><ins>+                                0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */,
</ins><span class="cx">                                 0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */,
</span><span class="cx">                                 0F0332C618B53FA9005F979A /* FTLWeight.h in Headers */,
</span><span class="cx">                                 0F0332C818B546EC005F979A /* FTLWeightedTarget.h in Headers */,
</span><span class="lines">@@ -5978,6 +6007,7 @@
</span><span class="cx">                                 0F2B66F217B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h in Headers */,
</span><span class="cx">                                 0F2B66F317B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructorInlines.h in Headers */,
</span><span class="cx">                                 0F2B66F417B6B5AB00A7AE3F /* JSGenericTypedArrayViewInlines.h in Headers */,
</span><ins>+                                0F5A1274192D9FDF008764A3 /* DFGDoesGC.h in Headers */,
</ins><span class="cx">                                 0F2B66F517B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototype.h in Headers */,
</span><span class="cx">                                 0F2B66F617B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototypeInlines.h in Headers */,
</span><span class="cx">                                 BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
</span><span class="lines">@@ -6196,6 +6226,7 @@
</span><span class="cx">                                 0F6B1CBA1861244C00845D97 /* RegisterPreservationMode.h in Headers */,
</span><span class="cx">                                 0F6B1CBE1861246A00845D97 /* RegisterPreservationWrapperGenerator.h in Headers */,
</span><span class="cx">                                 0FC314121814559100033232 /* RegisterSet.h in Headers */,
</span><ins>+                                0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */,
</ins><span class="cx">                                 A57D23EE1891B5540031C7FA /* RegularExpression.h in Headers */,
</span><span class="cx">                                 0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */,
</span><span class="cx">                                 A5BA15E8182340B300A82E69 /* RemoteInspector.h in Headers */,
</span><span class="lines">@@ -6969,6 +7000,7 @@
</span><span class="cx">                                 0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */,
</span><span class="cx">                                 A767B5B517A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp in Sources */,
</span><span class="cx">                                 0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */,
</span><ins>+                                0FD2D4FE192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp in Sources */,
</ins><span class="cx">                                 A737810D1799EA2E00817533 /* DFGNaturalLoops.cpp in Sources */,
</span><span class="cx">                                 0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */,
</span><span class="cx">                                 0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
</span><span class="lines">@@ -6998,6 +7030,7 @@
</span><span class="cx">                                 0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */,
</span><span class="cx">                                 0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */,
</span><span class="cx">                                 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */,
</span><ins>+                                0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */,
</ins><span class="cx">                                 2ACCF3DE185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp in Sources */,
</span><span class="cx">                                 0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */,
</span><span class="cx">                                 0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */,
</span><span class="lines">@@ -7070,6 +7103,7 @@
</span><span class="cx">                                 0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */,
</span><span class="cx">                                 0F6B1CC51862C47800845D97 /* FTLUnwindInfo.cpp in Sources */,
</span><span class="cx">                                 0F235BE317178E1C00690C7F /* FTLValueFormat.cpp in Sources */,
</span><ins>+                                0F5A1273192D9FDF008764A3 /* DFGDoesGC.cpp in Sources */,
</ins><span class="cx">                                 A53CE08718BC1A5600BEDF76 /* JSConsole.cpp in Sources */,
</span><span class="cx">                                 0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */,
</span><span class="cx">                                 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */,
</span><span class="lines">@@ -7187,6 +7221,7 @@
</span><span class="cx">                                 95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */,
</span><span class="cx">                                 7C184E1A17BEDBD3007CB63A /* JSPromise.cpp in Sources */,
</span><span class="cx">                                 7C184E2217BEE240007CB63A /* JSPromiseConstructor.cpp in Sources */,
</span><ins>+                                0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */,
</ins><span class="cx">                                 7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */,
</span><span class="cx">                                 7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */,
</span><span class="cx">                                 7C184E1E17BEE22E007CB63A /* JSPromisePrototype.cpp in Sources */,
</span><span class="lines">@@ -7202,6 +7237,7 @@
</span><span class="cx">                                 2A83638918D7D0FE0000EBCC /* FullGCActivityCallback.cpp in Sources */,
</span><span class="cx">                                 1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
</span><span class="cx">                                 147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
</span><ins>+                                0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */,
</ins><span class="cx">                                 2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
</span><span class="cx">                                 1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
</span><span class="cx">                                 146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureSetcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,317 @@
</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;StructureSet.h&quot;
+
+#include &lt;wtf/CommaPrinter.h&gt;
+
+namespace JSC {
+
+void StructureSet::clear()
+{
+    deleteStructureListIfNecessary();
+    setEmpty();
+}
+
+bool StructureSet::add(Structure* structure)
+{
+    ASSERT(structure);
+    if (isThin()) {
+        if (singleStructure() == structure)
+            return false;
+        if (!singleStructure()) {
+            set(structure);
+            return true;
+        }
+        OutOfLineList* list = OutOfLineList::create(defaultStartingSize);
+        list-&gt;m_length = 2;
+        list-&gt;list()[0] = singleStructure();
+        list-&gt;list()[1] = structure;
+        set(list);
+        return true;
+    }
+    
+    return addOutOfLine(structure);
+}
+
+bool StructureSet::remove(Structure* structure)
+{
+    if (isThin()) {
+        if (singleStructure() == structure) {
+            setEmpty();
+            return true;
+        }
+        return false;
+    }
+    
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+        if (list-&gt;list()[i] != structure)
+            continue;
+        list-&gt;list()[i] = list-&gt;list()[--list-&gt;m_length];
+        if (!list-&gt;m_length) {
+            OutOfLineList::destroy(list);
+            setEmpty();
+        }
+        return true;
+    }
+    return false;
+}
+
+bool StructureSet::contains(Structure* structure) const
+{
+    if (isThin())
+        return singleStructure() == structure;
+
+    return containsOutOfLine(structure);
+}
+
+bool StructureSet::merge(const StructureSet&amp; other)
+{
+    if (other.isThin()) {
+        if (other.singleStructure())
+            return add(other.singleStructure());
+        return false;
+    }
+    
+    OutOfLineList* list = other.structureList();
+    if (list-&gt;m_length &gt;= 2) {
+        if (isThin()) {
+            OutOfLineList* myNewList = OutOfLineList::create(
+                list-&gt;m_length + !!singleStructure());
+            if (singleStructure()) {
+                myNewList-&gt;m_length = 1;
+                myNewList-&gt;list()[0] = singleStructure();
+            }
+            set(myNewList);
+        }
+        bool changed = false;
+        for (unsigned i = 0; i &lt; list-&gt;m_length; ++i)
+            changed |= addOutOfLine(list-&gt;list()[i]);
+        return changed;
+    }
+    
+    ASSERT(list-&gt;m_length);
+    return add(list-&gt;list()[0]);
+}
+
+void StructureSet::filter(const StructureSet&amp; other)
+{
+    if (other.isThin()) {
+        if (!other.singleStructure() || !contains(other.singleStructure()))
+            clear();
+        else {
+            clear();
+            set(other.singleStructure());
+        }
+        return;
+    }
+    
+    ContainsOutOfLine containsOutOfLine(other);
+    genericFilter(containsOutOfLine);
+}
+
+void StructureSet::exclude(const StructureSet&amp; other)
+{
+    if (other.isThin()) {
+        if (other.singleStructure())
+            remove(other.singleStructure());
+        return;
+    }
+    
+    if (isThin()) {
+        if (!singleStructure())
+            return;
+        if (other.contains(singleStructure()))
+            clear();
+        return;
+    }
+    
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+        if (!other.containsOutOfLine(list-&gt;list()[i]))
+            continue;
+        list-&gt;list()[i--] = list-&gt;list()[--list-&gt;m_length];
+    }
+    if (!list-&gt;m_length)
+        clear();
+}
+
+bool StructureSet::isSubsetOf(const StructureSet&amp; other) const
+{
+    if (isThin()) {
+        if (!singleStructure())
+            return true;
+        return other.contains(singleStructure());
+    }
+    
+    if (other.isThin()) {
+        if (!other.singleStructure())
+            return false;
+        OutOfLineList* list = structureList();
+        if (list-&gt;m_length &gt;= 2)
+            return false;
+        if (list-&gt;list()[0] == other.singleStructure())
+            return true;
+        return false;
+    }
+    
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+        if (!other.containsOutOfLine(list-&gt;list()[i]))
+            return false;
+    }
+    return true;
+}
+
+bool StructureSet::overlaps(const StructureSet&amp; other) const
+{
+    if (isThin()) {
+        if (!singleStructure())
+            return false;
+        return other.contains(singleStructure());
+    }
+    
+    if (other.isThin()) {
+        if (!other.singleStructure())
+            return false;
+        return containsOutOfLine(other.singleStructure());
+    }
+    
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+        if (other.containsOutOfLine(list-&gt;list()[i]))
+            return true;
+    }
+    return false;
+}
+
+bool StructureSet::operator==(const StructureSet&amp; other) const
+{
+    if (size() != other.size())
+        return false;
+    return isSubsetOf(other);
+}
+
+SpeculatedType StructureSet::speculationFromStructures() const
+{
+    if (isThin()) {
+        if (!singleStructure())
+            return SpecNone;
+        return speculationFromStructure(singleStructure());
+    }
+    
+    SpeculatedType result = SpecNone;
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i)
+        mergeSpeculation(result, speculationFromStructure(list-&gt;list()[i]));
+    return result;
+}
+
+ArrayModes StructureSet::arrayModesFromStructures() const
+{
+    if (isThin()) {
+        if (!singleStructure())
+            return 0;
+        return asArrayModes(singleStructure()-&gt;indexingType());
+    }
+    
+    ArrayModes result = 0;
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i)
+        mergeArrayModes(result, asArrayModes(list-&gt;list()[i]-&gt;indexingType()));
+    return result;
+}
+
+void StructureSet::dumpInContext(PrintStream&amp; out, DumpContext* context) const
+{
+    CommaPrinter comma;
+    out.print(&quot;[&quot;);
+    for (size_t i = 0; i &lt; size(); ++i)
+        out.print(comma, inContext(*at(i), context));
+    out.print(&quot;]&quot;);
+}
+
+void StructureSet::dump(PrintStream&amp; out) const
+{
+    dumpInContext(out, nullptr);
+}
+
+bool StructureSet::addOutOfLine(Structure* structure)
+{
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+        if (list-&gt;list()[i] == structure)
+            return false;
+    }
+    
+    if (list-&gt;m_length &lt; list-&gt;m_capacity) {
+        list-&gt;list()[list-&gt;m_length++] = structure;
+        return true;
+    }
+    
+    OutOfLineList* newList = OutOfLineList::create(list-&gt;m_capacity * 2);
+    newList-&gt;m_length = list-&gt;m_length + 1;
+    for (unsigned i = list-&gt;m_length; i--;)
+        newList-&gt;list()[i] = list-&gt;list()[i];
+    newList-&gt;list()[list-&gt;m_length] = structure;
+    set(newList);
+    return true;
+}
+
+bool StructureSet::containsOutOfLine(Structure* structure) const
+{
+    OutOfLineList* list = structureList();
+    for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+        if (list-&gt;list()[i] == structure)
+            return true;
+    }
+    return false;
+}
+
+void StructureSet::copyFromOutOfLine(const StructureSet&amp; other)
+{
+    ASSERT(!other.isThin() &amp;&amp; other.m_pointer != reservedValue);
+    OutOfLineList* otherList = other.structureList();
+    OutOfLineList* myList = OutOfLineList::create(otherList-&gt;m_length);
+    myList-&gt;m_length = otherList-&gt;m_length;
+    for (unsigned i = otherList-&gt;m_length; i--;)
+        myList-&gt;list()[i] = otherList-&gt;list()[i];
+    set(myList);
+}
+
+StructureSet::OutOfLineList* StructureSet::OutOfLineList::create(unsigned capacity)
+{
+    return new (NotNull, fastMalloc(sizeof(OutOfLineList) + capacity * sizeof(Structure*))) OutOfLineList(0, capacity);
+}
+
+void StructureSet::OutOfLineList::destroy(OutOfLineList* list)
+{
+    fastFree(list);
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureSet.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureSet.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/bytecode/StructureSet.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 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">@@ -30,8 +30,6 @@
</span><span class="cx"> #include &quot;SpeculatedType.h&quot;
</span><span class="cx"> #include &quot;Structure.h&quot;
</span><span class="cx"> #include &quot;DumpContext.h&quot;
</span><del>-#include &lt;wtf/CommaPrinter.h&gt;
-#include &lt;wtf/Vector.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -41,156 +39,238 @@
</span><span class="cx"> 
</span><span class="cx"> class StructureSet {
</span><span class="cx"> public:
</span><del>-    StructureSet() { }
-    
-    StructureSet(Structure* structure)
</del><ins>+    StructureSet()
</ins><span class="cx">     {
</span><del>-        ASSERT(structure);
-        m_structures.append(structure);
</del><ins>+        setEmpty();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void clear()
</del><ins>+    StructureSet(Structure* structure)
</ins><span class="cx">     {
</span><del>-        m_structures.clear();
</del><ins>+        set(structure);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void add(Structure* structure)
</del><ins>+    ALWAYS_INLINE StructureSet(const StructureSet&amp; other)
</ins><span class="cx">     {
</span><del>-        ASSERT(structure);
-        ASSERT(!contains(structure));
-        m_structures.append(structure);
</del><ins>+        copyFrom(other);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool addAll(const StructureSet&amp; other)
</del><ins>+    ALWAYS_INLINE StructureSet&amp; operator=(const StructureSet&amp; other)
</ins><span class="cx">     {
</span><del>-        bool changed = false;
-        for (size_t i = 0; i &lt; other.size(); ++i) {
-            if (contains(other[i]))
-                continue;
-            add(other[i]);
-            changed = true;
-        }
-        return changed;
</del><ins>+        if (this == &amp;other)
+            return *this;
+        deleteStructureListIfNecessary();
+        copyFrom(other);
+        return *this;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void remove(Structure* structure)
</del><ins>+    ~StructureSet()
</ins><span class="cx">     {
</span><del>-        for (size_t i = 0; i &lt; m_structures.size(); ++i) {
-            if (m_structures[i] != structure)
-                continue;
-            
-            m_structures[i] = m_structures.last();
-            m_structures.removeLast();
-            return;
-        }
</del><ins>+        deleteStructureListIfNecessary();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool contains(Structure* structure) const
</del><ins>+    void clear();
+    
+    Structure* onlyStructure() const
</ins><span class="cx">     {
</span><del>-        for (size_t i = 0; i &lt; m_structures.size(); ++i) {
-            if (m_structures[i] == structure)
-                return true;
</del><ins>+        if (isThin()) {
+            ASSERT(singleStructure());
+            return singleStructure();
</ins><span class="cx">         }
</span><del>-        return false;
</del><ins>+        ASSERT(structureList()-&gt;m_length == 1);
+        return structureList()-&gt;list()[0];
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool containsOnly(Structure* structure) const
</del><ins>+    bool isEmpty() const
</ins><span class="cx">     {
</span><del>-        if (size() != 1)
-            return false;
-        return singletonStructure() == structure;
</del><ins>+        bool result = isThin() &amp;&amp; !singleStructure();
+        if (result)
+            ASSERT(m_pointer != reservedValue);
+        return result;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isSubsetOf(const StructureSet&amp; other) const
</del><ins>+    bool add(Structure*);
+    bool remove(Structure*);
+    bool contains(Structure*) const;
+    
+    bool merge(const StructureSet&amp;);
+    void filter(const StructureSet&amp;);
+    void exclude(const StructureSet&amp;);
+    
+    template&lt;typename Functor&gt;
+    void genericFilter(Functor&amp; functor)
</ins><span class="cx">     {
</span><del>-        for (size_t i = 0; i &lt; m_structures.size(); ++i) {
-            if (!other.contains(m_structures[i]))
-                return false;
</del><ins>+        if (isThin()) {
+            if (!singleStructure())
+                return;
+            if (functor(singleStructure()))
+                return;
+            clear();
+            return;
</ins><span class="cx">         }
</span><del>-        return true;
</del><ins>+        
+        OutOfLineList* list = structureList();
+        for (unsigned i = 0; i &lt; list-&gt;m_length; ++i) {
+            if (functor(list-&gt;list()[i]))
+                continue;
+            list-&gt;list()[i--] = list-&gt;list()[--list-&gt;m_length];
+        }
+        if (!list-&gt;m_length)
+            clear();
</ins><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool isSubsetOf(const StructureSet&amp;) const;
</ins><span class="cx">     bool isSupersetOf(const StructureSet&amp; other) const
</span><span class="cx">     {
</span><span class="cx">         return other.isSubsetOf(*this);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool overlaps(const StructureSet&amp; other) const
</del><ins>+    bool overlaps(const StructureSet&amp;) const;
+    
+    size_t size() const
</ins><span class="cx">     {
</span><del>-        for (size_t i = 0; i &lt; m_structures.size(); ++i) {
-            if (other.contains(m_structures[i]))
-                return true;
</del><ins>+        if (isThin())
+            return !!singleStructure();
+        return structureList()-&gt;m_length;
+    }
+    
+    Structure* at(size_t i) const
+    {
+        if (isThin()) {
+            ASSERT(!i);
+            ASSERT(singleStructure());
+            return singleStructure();
</ins><span class="cx">         }
</span><del>-        return false;
</del><ins>+        ASSERT(i &lt; structureList()-&gt;m_length);
+        return structureList()-&gt;list()[i];
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    size_t size() const { return m_structures.size(); }
</del><ins>+    Structure* operator[](size_t i) const { return at(i); }
</ins><span class="cx">     
</span><del>-    // Call this if you know that the structure set must consist of exactly
-    // one structure.
-    Structure* singletonStructure() const
</del><ins>+    Structure* last() const
</ins><span class="cx">     {
</span><del>-        ASSERT(m_structures.size() == 1);
-        return m_structures[0];
</del><ins>+        if (isThin()) {
+            ASSERT(singleStructure());
+            return singleStructure();
+        }
+        return structureList()-&gt;list()[structureList()-&gt;m_length - 1];
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    Structure* at(size_t i) const { return m_structures.at(i); }
</del><ins>+    bool operator==(const StructureSet&amp; other) const;
</ins><span class="cx">     
</span><del>-    Structure* operator[](size_t i) const { return at(i); }
</del><ins>+    SpeculatedType speculationFromStructures() const;
+    ArrayModes arrayModesFromStructures() const;
</ins><span class="cx">     
</span><del>-    Structure* last() const { return m_structures.last(); }
</del><ins>+    void dumpInContext(PrintStream&amp;, DumpContext*) const;
+    void dump(PrintStream&amp;) const;
+    
+private:
+    friend class DFG::StructureAbstractValue;
+    
+    static const uintptr_t thinFlag = 1;
+    static const uintptr_t reservedFlag = 2;
+    static const uintptr_t flags = thinFlag | reservedFlag;
+    static const uintptr_t reservedValue = 4;
</ins><span class="cx"> 
</span><del>-    SpeculatedType speculationFromStructures() const
</del><ins>+    static const unsigned defaultStartingSize = 4;
+    
+    bool addOutOfLine(Structure*);
+    bool containsOutOfLine(Structure*) const;
+    
+    class ContainsOutOfLine {
+    public:
+        ContainsOutOfLine(const StructureSet&amp; set)
+            : m_set(set)
+        {
+        }
+        
+        bool operator()(Structure* structure)
+        {
+            return m_set.containsOutOfLine(structure);
+        }
+    private:
+        const StructureSet&amp; m_set;
+    };
+
+    ALWAYS_INLINE void copyFrom(const StructureSet&amp; other)
</ins><span class="cx">     {
</span><del>-        SpeculatedType result = SpecNone;
</del><ins>+        if (other.isThin() || other.m_pointer == reservedValue) {
+            bool value = getReservedFlag();
+            m_pointer = other.m_pointer;
+            setReservedFlag(value);
+            return;
+        }
+        copyFromOutOfLine(other);
+    }
+    void copyFromOutOfLine(const StructureSet&amp; other);
+    
+    class OutOfLineList {
+    public:
+        static OutOfLineList* create(unsigned capacity);
+        static void destroy(OutOfLineList*);
</ins><span class="cx">         
</span><del>-        for (size_t i = 0; i &lt; m_structures.size(); ++i)
-            mergeSpeculation(result, speculationFromStructure(m_structures[i]));
</del><ins>+        Structure** list() { return bitwise_cast&lt;Structure**&gt;(this + 1); }
</ins><span class="cx">         
</span><del>-        return result;
</del><ins>+        OutOfLineList(unsigned length, unsigned capacity)
+            : m_length(length)
+            , m_capacity(capacity)
+        {
+        }
+
+        unsigned m_length;
+        unsigned m_capacity;
+    };
+    
+    ALWAYS_INLINE void deleteStructureListIfNecessary()
+    {
+        if (!isThin() &amp;&amp; m_pointer != reservedValue)
+            OutOfLineList::destroy(structureList());
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    ArrayModes arrayModesFromStructures() const
</del><ins>+    bool isThin() const { return m_pointer &amp; thinFlag; }
+    
+    void* pointer() const
</ins><span class="cx">     {
</span><del>-        ArrayModes result = 0;
-        
-        for (size_t i = 0; i &lt; m_structures.size(); ++i)
-            mergeArrayModes(result, asArrayModes(m_structures[i]-&gt;indexingType()));
-        
-        return result;
</del><ins>+        return bitwise_cast&lt;void*&gt;(m_pointer &amp; ~flags);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool operator==(const StructureSet&amp; other) const
</del><ins>+    Structure* singleStructure() const
</ins><span class="cx">     {
</span><del>-        if (m_structures.size() != other.m_structures.size())
-            return false;
-        
-        for (size_t i = 0; i &lt; m_structures.size(); ++i) {
-            if (!other.contains(m_structures[i]))
-                return false;
-        }
-        
-        return true;
</del><ins>+        ASSERT(isThin());
+        return static_cast&lt;Structure*&gt;(pointer());
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void dumpInContext(PrintStream&amp; out, DumpContext* context) const
</del><ins>+    OutOfLineList* structureList() const
</ins><span class="cx">     {
</span><del>-        CommaPrinter comma;
-        out.print(&quot;[&quot;);
-        for (size_t i = 0; i &lt; m_structures.size(); ++i)
-            out.print(comma, inContext(*m_structures[i], context));
-        out.print(&quot;]&quot;);
</del><ins>+        ASSERT(!isThin());
+        return static_cast&lt;OutOfLineList*&gt;(pointer());
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void dump(PrintStream&amp; out) const
</del><ins>+    void set(Structure* structure)
</ins><span class="cx">     {
</span><del>-        dumpInContext(out, 0);
</del><ins>+        set(bitwise_cast&lt;uintptr_t&gt;(structure), true);
</ins><span class="cx">     }
</span><del>-    
-private:
-    friend class DFG::StructureAbstractValue;
-    
-    Vector&lt;Structure*, 2&gt; m_structures;
</del><ins>+    void set(OutOfLineList* structures)
+    {
+        set(bitwise_cast&lt;uintptr_t&gt;(structures), false);
+    }
+    void setEmpty()
+    {
+        set(0, true);
+    }
+    void set(uintptr_t pointer, bool singleStructure)
+    {
+        m_pointer = pointer | (singleStructure ? thinFlag : 0) | (m_pointer &amp; reservedFlag);
+    }
+    bool getReservedFlag() const { return m_pointer &amp; reservedFlag; }
+    void setReservedFlag(bool value)
+    {
+        if (value)
+            m_pointer |= reservedFlag;
+        else
+            m_pointer &amp;= ~reservedFlag;
+    }
+
+    uintptr_t m_pointer;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -70,8 +70,7 @@
</span><span class="cx">     macro(ArrayStorageProperties) \
</span><span class="cx">     macro(Variables) \
</span><span class="cx">     macro(TypedArrayProperties) \
</span><del>-    macro(GCState) \
-    macro(BarrierState) \
</del><ins>+    macro(HeapObjectCount) /* Used to reflect the fact that some allocations reveal object identity */\
</ins><span class="cx">     macro(RegExpState) \
</span><span class="cx">     macro(InternalState) \
</span><span class="cx">     macro(Absolute) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -114,6 +114,7 @@
</span><span class="cx">     bool executeEffects(unsigned indexInBlock);
</span><span class="cx">     bool executeEffects(unsigned clobberLimit, Node*);
</span><span class="cx">     
</span><ins>+    void dump(PrintStream&amp; out) const;
</ins><span class="cx">     void dump(PrintStream&amp; out);
</span><span class="cx">     
</span><span class="cx">     template&lt;typename T&gt;
</span><span class="lines">@@ -148,7 +149,14 @@
</span><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><ins>+    
+    template&lt;typename Functor&gt;
+    void forAllValues(unsigned indexInBlock, Functor&amp;);
+    
</ins><span class="cx">     void clobberStructures(unsigned indexInBlock);
</span><ins>+    void observeTransition(unsigned indexInBlock, Structure* from, Structure* to);
+    void observeTransitions(unsigned indexInBlock, const TransitionVector&amp;);
+    void setDidClobber();
</ins><span class="cx">     
</span><span class="cx">     enum BooleanResult {
</span><span class="cx">         UnknownBooleanResult,
</span><span class="lines">@@ -160,7 +168,7 @@
</span><span class="cx">     void setBuiltInConstant(Node* node, JSValue value)
</span><span class="cx">     {
</span><span class="cx">         AbstractValue&amp; abstractValue = forNode(node);
</span><del>-        abstractValue.set(m_graph, value);
</del><ins>+        abstractValue.set(m_graph, value, m_state.structureClobberState());
</ins><span class="cx">         abstractValue.fixTypeForRepresentation(node);
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -62,11 +62,17 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
</span><del>-    if (isCellSpeculation(value.m_type)
-        &amp;&amp; value.m_currentKnownStructure.hasSingleton()) {
-        Structure* structure = value.m_currentKnownStructure.singleton();
-        if (!structure-&gt;masqueradesAsUndefined(m_codeBlock-&gt;globalObjectFor(node-&gt;origin.semantic))
-            &amp;&amp; structure-&gt;typeInfo().type() != StringType)
</del><ins>+    if (isCellSpeculation(value.m_type) &amp;&amp; !value.m_structure.isTop()) {
+        bool allTrue = true;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if (structure-&gt;masqueradesAsUndefined(m_codeBlock-&gt;globalObjectFor(node-&gt;origin.semantic))
+                || structure-&gt;typeInfo().type() == StringType) {
+                allTrue = false;
+                break;
+            }
+        }
+        if (allTrue)
</ins><span class="cx">             return DefinitelyTrue;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -105,9 +111,12 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><del>-void AbstractInterpreter&lt;AbstractStateType&gt;::verifyEdge(Node*, Edge edge)
</del><ins>+void AbstractInterpreter&lt;AbstractStateType&gt;::verifyEdge(Node* node, Edge edge)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT(!(forNode(edge).m_type &amp; ~typeFilterFor(edge.useKind())));
</del><ins>+    if (!(forNode(edge).m_type &amp; ~typeFilterFor(edge.useKind())))
+        return;
+    
+    DFG_CRASH(m_graph, node, toCString(&quot;Edge verification error: &quot;, node, &quot;-&gt;&quot;, edge, &quot; was expected to have type &quot;, SpeculationDump(typeFilterFor(edge.useKind())), &quot; but has type &quot;, SpeculationDump(forNode(edge).m_type)).data());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="lines">@@ -1273,7 +1282,6 @@
</span><span class="cx">         forNode(node).set(
</span><span class="cx">             m_graph,
</span><span class="cx">             m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case NewArrayBuffer:
</span><span class="lines">@@ -1281,13 +1289,11 @@
</span><span class="cx">         forNode(node).set(
</span><span class="cx">             m_graph,
</span><span class="cx">             m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case NewArrayWithSize:
</span><span class="cx">         node-&gt;setCanExit(true);
</span><span class="cx">         forNode(node).setType(SpecArray);
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case NewTypedArray:
</span><span class="lines">@@ -1305,12 +1311,10 @@
</span><span class="cx">             m_graph,
</span><span class="cx">             m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;typedArrayStructure(
</span><span class="cx">                 node-&gt;typedArrayType()));
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">             
</span><span class="cx">     case NewRegexp:
</span><span class="cx">         forNode(node).set(m_graph, m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;regExpStructure());
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">             
</span><span class="cx">     case ToThis: {
</span><span class="lines">@@ -1338,13 +1342,11 @@
</span><span class="cx">     case NewObject:
</span><span class="cx">         ASSERT(node-&gt;structure());
</span><span class="cx">         forNode(node).set(m_graph, node-&gt;structure());
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">         
</span><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><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case FunctionReentryWatchpoint:
</span><span class="lines">@@ -1377,8 +1379,9 @@
</span><span class="cx">         // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
</span><span class="cx">         // We perform further optimizations on this later on.
</span><span class="cx">         if (node-&gt;origin.semantic.inlineCallFrame) {
</span><del>-            forNode(node).set(
-                m_graph, jsNumber(node-&gt;origin.semantic.inlineCallFrame-&gt;arguments.size() - 1));
</del><ins>+            setConstant(
+                node, jsNumber(node-&gt;origin.semantic.inlineCallFrame-&gt;arguments.size() - 1));
+            m_state.setDidClobber(true); // Pretend that we clobbered to prevent constant folding.
</ins><span class="cx">         } else
</span><span class="cx">             forNode(node).setType(SpecInt32);
</span><span class="cx">         node-&gt;setCanExit(
</span><span class="lines">@@ -1474,7 +1477,12 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         if (isCellSpeculation(node-&gt;child1()-&gt;prediction())) {
</span><del>-            if (Structure* structure = forNode(node-&gt;child1()).bestProvenStructure()) {
</del><ins>+            // This use of onlyStructure() should be replaced by giving GetByIdStatus the ability
+            // to compute things based on a StructureSet, and then to factor ByteCodeParser's
+            // ability to generate code based on a GetByIdStatus out of ByteCodeParser so that
+            // ConstantFoldingPhase can use it.
+            // https://bugs.webkit.org/show_bug.cgi?id=133229
+            if (Structure* structure = forNode(node-&gt;child1()).m_structure.onlyStructure()) {
</ins><span class="cx">                 GetByIdStatus status = GetByIdStatus::computeFor(
</span><span class="cx">                     m_graph.m_vm, structure,
</span><span class="cx">                     m_graph.identifiers()[node-&gt;identifierNumber()]);
</span><span class="lines">@@ -1484,14 +1492,17 @@
</span><span class="cx">                     ASSERT(status[0].structureSet().size() == 1);
</span><span class="cx">                     ASSERT(!status[0].chain());
</span><span class="cx">                     
</span><del>-                    if (status[0].specificValue())
</del><ins>+                    if (status[0].specificValue()) {
+                        if (status[0].specificValue().isCell()) {
+                            Structure* structure = status[0].specificValue().asCell()-&gt;structure();
+                            m_graph.watchpoints().consider(structure);
+                        }
</ins><span class="cx">                         setConstant(node, status[0].specificValue());
</span><del>-                    else
</del><ins>+                    } else
</ins><span class="cx">                         forNode(node).makeHeapTop();
</span><span class="cx">                     filter(node-&gt;child1(), status[0].structureSet());
</span><span class="cx">                     
</span><span class="cx">                     m_state.setFoundConstants(true);
</span><del>-                    m_state.setHaveStructures(true);
</del><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="lines">@@ -1520,44 +1531,28 @@
</span><span class="cx">         ASSERT(!(value.m_type &amp; ~SpecCell)); // Edge filtering should have already ensured this.
</span><span class="cx"> 
</span><span class="cx">         StructureSet&amp; set = node-&gt;structureSet();
</span><del>-
-        if (value.m_currentKnownStructure.isSubsetOf(set)) {
</del><ins>+        
+        // It's interesting that we could have proven that the object has a larger structure set
+        // that includes the set we're testing. In that case we could make the structure check
+        // more efficient. We currently don't.
+        
+        if (value.m_structure.isSubsetOf(set)) {
</ins><span class="cx">             m_state.setFoundConstants(true);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         node-&gt;setCanExit(true);
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx"> 
</span><del>-        // If this structure check is attempting to prove knowledge already held in
-        // the futurePossibleStructure set then the constant folding phase should
-        // turn this into a watchpoint instead.
-        if (value.m_futurePossibleStructure.isSubsetOf(set)
-            &amp;&amp; value.m_futurePossibleStructure.hasSingleton()) {
-            m_state.setFoundConstants(true);
-            filter(value, value.m_futurePossibleStructure.singleton());
-            break;
-        }
-
</del><span class="cx">         filter(value, set);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case StructureTransitionWatchpoint: {
-        AbstractValue&amp; value = forNode(node-&gt;child1());
-
-        filter(value, node-&gt;structure());
-        m_state.setHaveStructures(true);
-        node-&gt;setCanExit(true);
-        break;
-    }
-            
</del><span class="cx">     case PutStructure:
</span><span class="cx">     case PhantomPutStructure:
</span><del>-        if (!forNode(node-&gt;child1()).m_currentKnownStructure.isClear()) {
-            clobberStructures(clobberLimit);
-            forNode(node-&gt;child1()).set(m_graph, node-&gt;structureTransitionData().newStructure);
-            m_state.setHaveStructures(true);
</del><ins>+        if (!forNode(node-&gt;child1()).m_structure.isClear()) {
+            observeTransition(
+                clobberLimit, node-&gt;transition()-&gt;previous, node-&gt;transition()-&gt;next);
+            forNode(node-&gt;child1()).set(m_graph, node-&gt;transition()-&gt;next);
</ins><span class="cx">         }
</span><span class="cx">         break;
</span><span class="cx">     case GetButterfly:
</span><span class="lines">@@ -1616,7 +1611,6 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         filterArrayModes(node-&gt;child1(), node-&gt;arrayMode().arrayModesThatPassFiltering());
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case Arrayify: {
</span><span class="lines">@@ -1629,19 +1623,43 @@
</span><span class="cx">         node-&gt;setCanExit(true);
</span><span class="cx">         clobberStructures(clobberLimit);
</span><span class="cx">         filterArrayModes(node-&gt;child1(), node-&gt;arrayMode().arrayModesThatPassFiltering());
</span><del>-        m_state.setHaveStructures(true);
</del><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case ArrayifyToStructure: {
</span><span class="cx">         AbstractValue&amp; value = forNode(node-&gt;child1());
</span><del>-        StructureSet set = node-&gt;structure();
-        if (value.m_futurePossibleStructure.isSubsetOf(set)
-            || value.m_currentKnownStructure.isSubsetOf(set))
</del><ins>+        if (value.m_structure.isSubsetOf(StructureSet(node-&gt;structure())))
</ins><span class="cx">             m_state.setFoundConstants(true);
</span><span class="cx">         node-&gt;setCanExit(true);
</span><span class="cx">         clobberStructures(clobberLimit);
</span><del>-        filter(value, set);
-        m_state.setHaveStructures(true);
</del><ins>+        
+        // We have a bunch of options of how to express the abstract set at this point. Let set S
+        // be the set of structures that the value had before clobbering and assume that all of
+        // them are watchable. The new value should be the least expressible upper bound of the
+        // intersection of &quot;values that currently have structure = node-&gt;structure()&quot; and &quot;values
+        // that have structure in S plus any structure transition-reachable from S&quot;. Assume that
+        // node-&gt;structure() is not in S but it is transition-reachable from S. Then we would
+        // like to say that the result is &quot;values that have structure = node-&gt;structure() until
+        // we invalidate&quot;, but there is no way to express this using the AbstractValue syntax. So
+        // we must choose between:
+        //
+        // 1) &quot;values that currently have structure = node-&gt;structure()&quot;. This is a valid
+        //    superset of the value that we really want, and it's specific enough to satisfy the
+        //    preconditions of the array access that this is guarding. It's also specific enough
+        //    to allow relevant optimizations in the case that we didn't have a contradiction
+        //    like in this example. Notice that in the abscence of any contradiction, this result
+        //    is precise rather than being a conservative LUB.
+        //
+        // 2) &quot;values that currently hava structure in S plus any structure transition-reachable
+        //    from S&quot;. This is also a valid superset of the value that we really want, but it's
+        //    not specific enough to satisfy the preconditions of the array access that this is
+        //    guarding - so playing such shenanigans would preclude us from having assertions on
+        //    the typing preconditions of any array accesses. This would also not be a desirable
+        //    answer in the absence of a contradiction.
+        //
+        // Note that it's tempting to simply say that the resulting value is BOTTOM because of
+        // the contradiction. That would be wrong, since we haven't hit an invalidation point,
+        // yet.
+        value.set(m_graph, node-&gt;structure());
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case GetIndexedPropertyStorage:
</span><span class="lines">@@ -1669,7 +1687,11 @@
</span><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><del>-        if (Structure* structure = value.bestProvenStructure()) {
</del><ins>+        // This should just filter down the cases in MultiGetByOffset. If that results in all
+        // cases having the same offset then we should strength reduce it to a CheckStructure +
+        // GetByOffset.
+        // https://bugs.webkit.org/show_bug.cgi?id=133229
+        if (Structure* structure = value.m_structure.onlyStructure()) {
</ins><span class="cx">             bool done = false;
</span><span class="cx">             for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;) {
</span><span class="cx">                 const GetByIdVariant&amp; variant = node-&gt;multiGetByOffsetData().variants[i];
</span><span class="lines">@@ -1691,7 +1713,7 @@
</span><span class="cx">         
</span><span class="cx">         StructureSet set;
</span><span class="cx">         for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;)
</span><del>-            set.addAll(node-&gt;multiGetByOffsetData().variants[i].structureSet());
</del><ins>+            set.merge(node-&gt;multiGetByOffsetData().variants[i].structureSet());
</ins><span class="cx">         
</span><span class="cx">         filter(node-&gt;child1(), set);
</span><span class="cx">         forNode(node).makeHeapTop();
</span><span class="lines">@@ -1706,7 +1728,12 @@
</span><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><del>-        if (Structure* structure = value.bestProvenStructure()) {
</del><ins>+        // This should just filter down the cases in MultiPutByOffset. If that results in either
+        // one case, or nothing but replace cases and they have the same offset, then we should
+        // just strength reduce it to the appropriate combination of CheckStructure,
+        // [Re]AllocatePropertyStorage, PutStructure, and PutByOffset.
+        // https://bugs.webkit.org/show_bug.cgi?id=133229
+        if (Structure* structure = value.m_structure.onlyStructure()) {
</ins><span class="cx">             bool done = false;
</span><span class="cx">             for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
</span><span class="cx">                 const PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
</span><span class="lines">@@ -1716,7 +1743,6 @@
</span><span class="cx">                 if (variant.kind() == PutByIdVariant::Replace) {
</span><span class="cx">                     filter(node-&gt;child1(), structure);
</span><span class="cx">                     m_state.setFoundConstants(true);
</span><del>-                    m_state.setHaveStructures(true);
</del><span class="cx">                     done = true;
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="lines">@@ -1725,7 +1751,6 @@
</span><span class="cx">                 clobberStructures(clobberLimit);
</span><span class="cx">                 forNode(node-&gt;child1()).set(m_graph, variant.newStructure());
</span><span class="cx">                 m_state.setFoundConstants(true);
</span><del>-                m_state.setHaveStructures(true);
</del><span class="cx">                 done = true;
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -1733,25 +1758,24 @@
</span><span class="cx">                 break;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        clobberStructures(clobberLimit);
-        
</del><ins>+        StructureSet oldSet;
</ins><span class="cx">         StructureSet newSet;
</span><ins>+        TransitionVector transitions;
</ins><span class="cx">         for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
</span><span class="cx">             const PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
</span><del>-            if (variant.kind() == PutByIdVariant::Replace) {
-                if (value.m_currentKnownStructure.contains(variant.structure()))
-                    newSet.addAll(variant.structure());
-                continue;
</del><ins>+            oldSet.add(variant.oldStructure());
+            if (variant.kind() == PutByIdVariant::Transition) {
+                transitions.append(Transition(variant.oldStructure(), variant.newStructure()));
+                newSet.add(variant.newStructure());
+            } else {
+                ASSERT(variant.kind() == PutByIdVariant::Replace);
+                newSet.add(variant.oldStructure());
</ins><span class="cx">             }
</span><del>-            ASSERT(variant.kind() == PutByIdVariant::Transition);
-            if (value.m_currentKnownStructure.contains(variant.oldStructure()))
-                newSet.addAll(variant.newStructure());
</del><span class="cx">         }
</span><span class="cx">         
</span><del>-        // Use filter(value, set) as a way of setting the structure set. This works because
-        // we would have already made the set be TOP before this. Filtering top is another 
-        // way of setting.
-        filter(node-&gt;child1(), newSet);
</del><ins>+        filter(node-&gt;child1(), oldSet);
+        observeTransitions(clobberLimit, transitions);
+        forNode(node-&gt;child1()).set(m_graph, newSet);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1785,7 +1809,12 @@
</span><span class="cx">     case PutByIdFlush:
</span><span class="cx">     case PutByIdDirect:
</span><span class="cx">         node-&gt;setCanExit(true);
</span><del>-        if (Structure* structure = forNode(node-&gt;child1()).bestProvenStructure()) {
</del><ins>+        // This use of onlyStructure() should be replaced by giving PutByIdStatus the ability
+        // to compute things based on a StructureSet, and then to factor ByteCodeParser's
+        // ability to generate code based on a PutByIdStatus out of ByteCodeParser so that
+        // ConstantFoldingPhase can use it.
+        // https://bugs.webkit.org/show_bug.cgi?id=133229
+        if (Structure* structure = forNode(node-&gt;child1()).m_structure.onlyStructure()) {
</ins><span class="cx">             PutByIdStatus status = PutByIdStatus::computeFor(
</span><span class="cx">                 m_graph.m_vm,
</span><span class="cx">                 m_graph.globalObjectFor(node-&gt;origin.semantic),
</span><span class="lines">@@ -1796,13 +1825,13 @@
</span><span class="cx">                 if (status[0].kind() == PutByIdVariant::Replace) {
</span><span class="cx">                     filter(node-&gt;child1(), structure);
</span><span class="cx">                     m_state.setFoundConstants(true);
</span><del>-                    m_state.setHaveStructures(true);
</del><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                if (status[0].kind() == PutByIdVariant::Transition) {
</del><ins>+                if (status[0].kind() == PutByIdVariant::Transition
+                    &amp;&amp; structure-&gt;transitionWatchpointSetHasBeenInvalidated()) {
+                    m_graph.watchpoints().consider(status[0].newStructure());
</ins><span class="cx">                     clobberStructures(clobberLimit);
</span><span class="cx">                     forNode(node-&gt;child1()).set(m_graph, status[0].newStructure());
</span><del>-                    m_state.setHaveStructures(true);
</del><span class="cx">                     m_state.setFoundConstants(true);
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="lines">@@ -1849,7 +1878,7 @@
</span><span class="cx">         
</span><span class="cx">     case Upsilon: {
</span><span class="cx">         m_state.createValueForNode(node-&gt;phi());
</span><del>-        AbstractValue&amp; value = forNode(node-&gt;child1());
</del><ins>+        AbstractValue value = forNode(node-&gt;child1());
</ins><span class="cx">         forNode(node) = value;
</span><span class="cx">         forNode(node-&gt;phi()) = value;
</span><span class="cx">         break;
</span><span class="lines">@@ -1873,6 +1902,8 @@
</span><span class="cx">         
</span><span class="cx">     case InvalidationPoint:
</span><span class="cx">         node-&gt;setCanExit(true);
</span><ins>+        forAllValues(clobberLimit, AbstractValue::observeInvalidationPointFor);
+        m_state.setStructureClobberState(StructuresAreWatched);
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case CheckWatchdogTimer:
</span><span class="lines">@@ -1955,6 +1986,7 @@
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="cx"> void AbstractInterpreter&lt;AbstractStateType&gt;::clobberCapturedVars(const CodeOrigin&amp; codeOrigin)
</span><span class="cx"> {
</span><ins>+    SamplingRegion samplingRegion(&quot;DFG AI Clobber Captured Vars&quot;);
</ins><span class="cx">     if (codeOrigin.inlineCallFrame) {
</span><span class="cx">         const BitVector&amp; capturedVars = codeOrigin.inlineCallFrame-&gt;capturedVars;
</span><span class="cx">         for (size_t i = capturedVars.size(); i--;) {
</span><span class="lines">@@ -1976,40 +2008,80 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><del>-void AbstractInterpreter&lt;AbstractStateType&gt;::clobberStructures(unsigned clobberLimit)
</del><ins>+template&lt;typename Functor&gt;
+void AbstractInterpreter&lt;AbstractStateType&gt;::forAllValues(
+    unsigned clobberLimit, Functor&amp; functor)
</ins><span class="cx"> {
</span><del>-    if (!m_state.haveStructures())
-        return;
</del><ins>+    SamplingRegion samplingRegion(&quot;DFG AI For All Values&quot;);
</ins><span class="cx">     if (clobberLimit &gt;= m_state.block()-&gt;size())
</span><span class="cx">         clobberLimit = m_state.block()-&gt;size();
</span><span class="cx">     else
</span><span class="cx">         clobberLimit++;
</span><span class="cx">     ASSERT(clobberLimit &lt;= m_state.block()-&gt;size());
</span><span class="cx">     for (size_t i = clobberLimit; i--;)
</span><del>-        forNode(m_state.block()-&gt;at(i)).clobberStructures();
</del><ins>+        functor(forNode(m_state.block()-&gt;at(i)));
</ins><span class="cx">     if (m_graph.m_form == SSA) {
</span><span class="cx">         HashSet&lt;Node*&gt;::iterator iter = m_state.block()-&gt;ssa-&gt;liveAtHead.begin();
</span><span class="cx">         HashSet&lt;Node*&gt;::iterator end = m_state.block()-&gt;ssa-&gt;liveAtHead.end();
</span><span class="cx">         for (; iter != end; ++iter)
</span><del>-            forNode(*iter).clobberStructures();
</del><ins>+            functor(forNode(*iter));
</ins><span class="cx">     }
</span><span class="cx">     for (size_t i = m_state.variables().numberOfArguments(); i--;)
</span><del>-        m_state.variables().argument(i).clobberStructures();
</del><ins>+        functor(m_state.variables().argument(i));
</ins><span class="cx">     for (size_t i = m_state.variables().numberOfLocals(); i--;)
</span><del>-        m_state.variables().local(i).clobberStructures();
-    m_state.setHaveStructures(true);
</del><ins>+        functor(m_state.variables().local(i));
+}
+
+template&lt;typename AbstractStateType&gt;
+void AbstractInterpreter&lt;AbstractStateType&gt;::clobberStructures(unsigned clobberLimit)
+{
+    SamplingRegion samplingRegion(&quot;DFG AI Clobber Structures&quot;);
+    forAllValues(clobberLimit, AbstractValue::clobberStructuresFor);
+    setDidClobber();
+}
+
+template&lt;typename AbstractStateType&gt;
+void AbstractInterpreter&lt;AbstractStateType&gt;::observeTransition(
+    unsigned clobberLimit, Structure* from, Structure* to)
+{
+    AbstractValue::TransitionObserver transitionObserver(from, to);
+    forAllValues(clobberLimit, transitionObserver);
+    setDidClobber();
+}
+
+template&lt;typename AbstractStateType&gt;
+void AbstractInterpreter&lt;AbstractStateType&gt;::observeTransitions(
+    unsigned clobberLimit, const TransitionVector&amp; vector)
+{
+    AbstractValue::TransitionsObserver transitionsObserver(vector);
+    forAllValues(clobberLimit, transitionsObserver);
+    setDidClobber();
+}
+
+template&lt;typename AbstractStateType&gt;
+void AbstractInterpreter&lt;AbstractStateType&gt;::setDidClobber()
+{
</ins><span class="cx">     m_state.setDidClobber(true);
</span><ins>+    m_state.setStructureClobberState(StructuresAreClobbered);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><ins>+void AbstractInterpreter&lt;AbstractStateType&gt;::dump(PrintStream&amp; out) const
+{
+    const_cast&lt;AbstractInterpreter&lt;AbstractStateType&gt;*&gt;(this)-&gt;dump(out);
+}
+
+template&lt;typename AbstractStateType&gt;
</ins><span class="cx"> void AbstractInterpreter&lt;AbstractStateType&gt;::dump(PrintStream&amp; out)
</span><span class="cx"> {
</span><span class="cx">     CommaPrinter comma(&quot; &quot;);
</span><ins>+    HashSet&lt;Node*&gt; seen;
</ins><span class="cx">     if (m_graph.m_form == SSA) {
</span><span class="cx">         HashSet&lt;Node*&gt;::iterator iter = m_state.block()-&gt;ssa-&gt;liveAtHead.begin();
</span><span class="cx">         HashSet&lt;Node*&gt;::iterator end = m_state.block()-&gt;ssa-&gt;liveAtHead.end();
</span><span class="cx">         for (; iter != end; ++iter) {
</span><span class="cx">             Node* node = *iter;
</span><ins>+            seen.add(node);
</ins><span class="cx">             AbstractValue&amp; value = forNode(node);
</span><span class="cx">             if (value.isClear())
</span><span class="cx">                 continue;
</span><span class="lines">@@ -2018,11 +2090,25 @@
</span><span class="cx">     }
</span><span class="cx">     for (size_t i = 0; i &lt; m_state.block()-&gt;size(); ++i) {
</span><span class="cx">         Node* node = m_state.block()-&gt;at(i);
</span><ins>+        seen.add(node);
</ins><span class="cx">         AbstractValue&amp; value = forNode(node);
</span><span class="cx">         if (value.isClear())
</span><span class="cx">             continue;
</span><span class="cx">         out.print(comma, node, &quot;:&quot;, value);
</span><span class="cx">     }
</span><ins>+    if (m_graph.m_form == SSA) {
+        HashSet&lt;Node*&gt;::iterator iter = m_state.block()-&gt;ssa-&gt;liveAtTail.begin();
+        HashSet&lt;Node*&gt;::iterator end = m_state.block()-&gt;ssa-&gt;liveAtTail.end();
+        for (; iter != end; ++iter) {
+            Node* node = *iter;
+            if (seen.contains(node))
+                continue;
+            AbstractValue&amp; value = forNode(node);
+            if (value.isClear())
+                continue;
+            out.print(comma, node, &quot;:&quot;, value);
+        }
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -33,16 +33,29 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><ins>+void AbstractValue::observeTransitions(const TransitionVector&amp; vector)
+{
+    if (m_type &amp; SpecCell) {
+        m_structure.observeTransitions(vector);
+        ArrayModes newModes = 0;
+        for (unsigned i = vector.size(); i--;) {
+            if (m_arrayModes &amp; asArrayModes(vector[i].previous-&gt;indexingType()))
+                newModes |= asArrayModes(vector[i].next-&gt;indexingType());
+        }
+        m_arrayModes |= newModes;
+    }
+    checkConsistency();
+}
+
</ins><span class="cx"> void AbstractValue::setMostSpecific(Graph&amp; graph, JSValue value)
</span><span class="cx"> {
</span><span class="cx">     if (!!value &amp;&amp; value.isCell()) {
</span><span class="cx">         Structure* structure = value.asCell()-&gt;structure();
</span><del>-        m_currentKnownStructure = structure;
-        setFuturePossibleStructure(graph, structure);
</del><ins>+        graph.watchpoints().consider(structure);
+        m_structure = structure;
</ins><span class="cx">         m_arrayModes = asArrayModes(structure-&gt;indexingType());
</span><span class="cx">     } else {
</span><del>-        m_currentKnownStructure.clear();
-        m_futurePossibleStructure.clear();
</del><ins>+        m_structure.clear();
</ins><span class="cx">         m_arrayModes = 0;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -50,19 +63,30 @@
</span><span class="cx">     m_value = value;
</span><span class="cx">         
</span><span class="cx">     checkConsistency();
</span><ins>+    assertIsWatched(graph);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AbstractValue::set(Graph&amp; graph, JSValue value)
</del><ins>+void AbstractValue::set(Graph&amp; graph, JSValue value, StructureClobberState clobberState)
</ins><span class="cx"> {
</span><span class="cx">     if (!!value &amp;&amp; value.isCell()) {
</span><del>-        m_currentKnownStructure.makeTop();
</del><span class="cx">         Structure* structure = value.asCell()-&gt;structure();
</span><del>-        setFuturePossibleStructure(graph, structure);
-        m_arrayModes = asArrayModes(structure-&gt;indexingType());
-        clobberArrayModes();
</del><ins>+        if (graph.watchpoints().consider(structure)) {
+            // We should be able to assume that the watchpoint for this has already been set.
+            // But we can't because our view of what structure a value has keeps changing. That's
+            // why we call consider().
+            // https://bugs.webkit.org/show_bug.cgi?id=133426
+            m_structure = structure;
+            if (clobberState == StructuresAreClobbered) {
+                m_arrayModes = ALL_ARRAY_MODES;
+                m_structure.clobber();
+            } else
+                m_arrayModes = asArrayModes(structure-&gt;indexingType());
+        } else {
+            m_structure.makeTop();
+            m_arrayModes = ALL_ARRAY_MODES;
+        }
</ins><span class="cx">     } else {
</span><del>-        m_currentKnownStructure.clear();
-        m_futurePossibleStructure.clear();
</del><ins>+        m_structure.clear();
</ins><span class="cx">         m_arrayModes = 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -70,19 +94,31 @@
</span><span class="cx">     m_value = value;
</span><span class="cx">     
</span><span class="cx">     checkConsistency();
</span><ins>+    assertIsWatched(graph);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AbstractValue::set(Graph&amp; graph, Structure* structure)
</span><span class="cx"> {
</span><del>-    m_currentKnownStructure = structure;
-    setFuturePossibleStructure(graph, structure);
</del><ins>+    m_structure = structure;
</ins><span class="cx">     m_arrayModes = asArrayModes(structure-&gt;indexingType());
</span><span class="cx">     m_type = speculationFromStructure(structure);
</span><span class="cx">     m_value = JSValue();
</span><span class="cx">     
</span><span class="cx">     checkConsistency();
</span><ins>+    assertIsWatched(graph);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void AbstractValue::set(Graph&amp; graph, const StructureSet&amp; set)
+{
+    m_structure = set;
+    m_arrayModes = set.arrayModesFromStructures();
+    m_type = set.speculationFromStructures();
+    m_value = JSValue();
+    
+    checkConsistency();
+    assertIsWatched(graph);
+}
+
</ins><span class="cx"> void AbstractValue::fixTypeForRepresentation(NodeFlags representation)
</span><span class="cx"> {
</span><span class="cx">     if (representation == NodeResultDouble) {
</span><span class="lines">@@ -141,21 +177,18 @@
</span><span class="cx">     
</span><span class="cx">     m_type &amp;= other.speculationFromStructures();
</span><span class="cx">     m_arrayModes &amp;= other.arrayModesFromStructures();
</span><del>-    m_currentKnownStructure.filter(other);
</del><ins>+    m_structure.filter(other);
</ins><span class="cx">     
</span><span class="cx">     // It's possible that prior to the above two statements we had (Foo, TOP), where
</span><span class="cx">     // Foo is a SpeculatedType that is disjoint with the passed StructureSet. In that
</span><span class="cx">     // case, we will now have (None, [someStructure]). In general, we need to make
</span><span class="cx">     // sure that new information gleaned from the SpeculatedType needs to be fed back
</span><span class="cx">     // into the information gleaned from the StructureSet.
</span><del>-    m_currentKnownStructure.filter(m_type);
</del><ins>+    m_structure.filter(m_type);
</ins><span class="cx">     
</span><del>-    if (m_currentKnownStructure.hasSingleton())
-        setFuturePossibleStructure(graph, m_currentKnownStructure.singleton());
-        
</del><span class="cx">     filterArrayModesByType();
</span><span class="cx">     filterValueByType();
</span><del>-    return normalizeClarity();
</del><ins>+    return normalizeClarity(graph);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FiltrationResult AbstractValue::filterArrayModes(ArrayModes arrayModes)
</span><span class="lines">@@ -175,14 +208,26 @@
</span><span class="cx">     if ((m_type &amp; type) == m_type)
</span><span class="cx">         return FiltrationOK;
</span><span class="cx">     
</span><ins>+    // Fast path for the case that we don't even have a cell.
+    if (!(m_type &amp; SpecCell)) {
+        m_type &amp;= type;
+        FiltrationResult result;
+        if (m_type == SpecNone) {
+            clear();
+            result = Contradiction;
+        } else
+            result = FiltrationOK;
+        checkConsistency();
+        return result;
+    }
+    
</ins><span class="cx">     m_type &amp;= type;
</span><span class="cx">     
</span><span class="cx">     // It's possible that prior to this filter() call we had, say, (Final, TOP), and
</span><span class="cx">     // the passed type is Array. At this point we'll have (None, TOP). The best way
</span><span class="cx">     // to ensure that the structure filtering does the right thing is to filter on
</span><span class="cx">     // the new type (None) rather than the one passed (Array).
</span><del>-    m_currentKnownStructure.filter(m_type);
-    m_futurePossibleStructure.filter(m_type);
</del><ins>+    m_structure.filter(type);
</ins><span class="cx">     filterArrayModesByType();
</span><span class="cx">     filterValueByType();
</span><span class="cx">     return normalizeClarity();
</span><span class="lines">@@ -196,15 +241,6 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AbstractValue::setFuturePossibleStructure(Graph&amp; graph, Structure* structure)
-{
-    ASSERT(structure);
-    if (graph.watchpoints().isStillValid(structure-&gt;transitionWatchpointSet()))
-        m_futurePossibleStructure = structure;
-    else
-        m_futurePossibleStructure.makeTop();
-}
-
</del><span class="cx"> void AbstractValue::filterValueByType()
</span><span class="cx"> {
</span><span class="cx">     // We could go further, and ensure that if the futurePossibleStructure contravenes
</span><span class="lines">@@ -250,8 +286,7 @@
</span><span class="cx">         return true;
</span><span class="cx">     
</span><span class="cx">     if (!(m_type &amp; ~SpecCell)
</span><del>-        &amp;&amp; (!m_arrayModes
-            || m_currentKnownStructure.isClear()))
</del><ins>+        &amp;&amp; (!m_arrayModes || m_structure.isClear()))
</ins><span class="cx">         return true;
</span><span class="cx">     
</span><span class="cx">     return false;
</span><span class="lines">@@ -275,12 +310,18 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FiltrationResult AbstractValue::normalizeClarity(Graph&amp; graph)
+{
+    FiltrationResult result = normalizeClarity();
+    assertIsWatched(graph);
+    return result;
+}
+
</ins><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx"> void AbstractValue::checkConsistency() const
</span><span class="cx"> {
</span><span class="cx">     if (!(m_type &amp; SpecCell)) {
</span><del>-        ASSERT(m_currentKnownStructure.isClear());
-        ASSERT(m_futurePossibleStructure.isClear());
</del><ins>+        ASSERT(m_structure.isClear());
</ins><span class="cx">         ASSERT(!m_arrayModes);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -301,6 +342,11 @@
</span><span class="cx">     // we don't want to get pedantic about this as it would only increase the computational
</span><span class="cx">     // complexity of the code.
</span><span class="cx"> }
</span><ins>+
+void AbstractValue::assertIsWatched(Graph&amp; graph) const
+{
+    m_structure.assertIsWatched(graph);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void AbstractValue::dump(PrintStream&amp; out) const
</span><span class="lines">@@ -314,8 +360,7 @@
</span><span class="cx">     if (m_type &amp; SpecCell) {
</span><span class="cx">         out.print(
</span><span class="cx">             &quot;, &quot;, ArrayModesDump(m_arrayModes), &quot;, &quot;,
</span><del>-            inContext(m_currentKnownStructure, context), &quot;, &quot;,
-            inContext(m_futurePossibleStructure, context));
</del><ins>+            inContext(m_structure, context));
</ins><span class="cx">     }
</span><span class="cx">     if (!!m_value)
</span><span class="cx">         out.print(&quot;, &quot;, inContext(m_value, context));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGFiltrationResult.h&quot;
</span><span class="cx"> #include &quot;DFGNodeFlags.h&quot;
</span><span class="cx"> #include &quot;DFGStructureAbstractValue.h&quot;
</span><ins>+#include &quot;DFGStructureClobberState.h&quot;
</ins><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="cx"> #include &quot;SpeculatedType.h&quot;
</span><span class="cx"> #include &quot;DumpContext.h&quot;
</span><span class="lines">@@ -53,8 +54,7 @@
</span><span class="cx">     {
</span><span class="cx">         m_type = SpecNone;
</span><span class="cx">         m_arrayModes = 0;
</span><del>-        m_currentKnownStructure.clear();
-        m_futurePossibleStructure.clear();
</del><ins>+        m_structure.clear();
</ins><span class="cx">         m_value = JSValue();
</span><span class="cx">         checkConsistency();
</span><span class="cx">     }
</span><span class="lines">@@ -75,15 +75,74 @@
</span><span class="cx">     void clobberStructures()
</span><span class="cx">     {
</span><span class="cx">         if (m_type &amp; SpecCell) {
</span><del>-            m_currentKnownStructure.makeTop();
</del><ins>+            m_structure.clobber();
</ins><span class="cx">             clobberArrayModes();
</span><span class="cx">         } else {
</span><del>-            ASSERT(m_currentKnownStructure.isClear());
</del><ins>+            ASSERT(m_structure.isClear());
</ins><span class="cx">             ASSERT(!m_arrayModes);
</span><span class="cx">         }
</span><span class="cx">         checkConsistency();
</span><span class="cx">     }
</span><ins>+    
+    static void clobberStructuresFor(AbstractValue&amp; value)
+    {
+        value.clobberStructures();
+    }
+    
+    void observeInvalidationPoint()
+    {
+        m_structure.observeInvalidationPoint();
+        checkConsistency();
+    }
+    
+    static void observeInvalidationPointFor(AbstractValue&amp; value)
+    {
+        value.observeInvalidationPoint();
+    }
+    
+    void observeTransition(Structure* from, Structure* to)
+    {
+        if (m_type &amp; SpecCell) {
+            m_structure.observeTransition(from, to);
+            observeIndexingTypeTransition(from-&gt;indexingType(), to-&gt;indexingType());
+        }
+        checkConsistency();
+    }
+    
+    void observeTransitions(const TransitionVector&amp; vector);
+    
+    class TransitionObserver {
+    public:
+        TransitionObserver(Structure* from, Structure* to)
+            : m_from(from)
+            , m_to(to)
+        {
+        }
</ins><span class="cx">         
</span><ins>+        void operator()(AbstractValue&amp; value)
+        {
+            value.observeTransition(m_from, m_to);
+        }
+    private:
+        Structure* m_from;
+        Structure* m_to;
+    };
+    
+    class TransitionsObserver {
+    public:
+        TransitionsObserver(const TransitionVector&amp; vector)
+            : m_vector(vector)
+        {
+        }
+        
+        void operator()(AbstractValue&amp; value)
+        {
+            value.observeTransitions(m_vector);
+        }
+    private:
+        const TransitionVector&amp; m_vector;
+    };
+    
</ins><span class="cx">     void clobberValue()
</span><span class="cx">     {
</span><span class="cx">         m_value = JSValue();
</span><span class="lines">@@ -91,7 +150,10 @@
</span><span class="cx">     
</span><span class="cx">     bool isHeapTop() const
</span><span class="cx">     {
</span><del>-        return (m_type | SpecHeapTop) == m_type &amp;&amp; m_currentKnownStructure.isTop() &amp;&amp; m_futurePossibleStructure.isTop();
</del><ins>+        return (m_type | SpecHeapTop) == m_type
+            &amp;&amp; m_structure.isTop()
+            &amp;&amp; m_arrayModes == ALL_ARRAY_MODES
+            &amp;&amp; !m_value;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool valueIsTop() const
</span><span class="lines">@@ -112,18 +174,17 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void setMostSpecific(Graph&amp;, JSValue);
</span><del>-    void set(Graph&amp;, JSValue);
</del><ins>+    void set(Graph&amp;, JSValue, StructureClobberState);
</ins><span class="cx">     void set(Graph&amp;, Structure*);
</span><ins>+    void set(Graph&amp;, const StructureSet&amp;);
</ins><span class="cx">     
</span><span class="cx">     void setType(SpeculatedType type)
</span><span class="cx">     {
</span><span class="cx">         if (type &amp; SpecCell) {
</span><del>-            m_currentKnownStructure.makeTop();
-            m_futurePossibleStructure.makeTop();
</del><ins>+            m_structure.makeTop();
</ins><span class="cx">             m_arrayModes = ALL_ARRAY_MODES;
</span><span class="cx">         } else {
</span><del>-            m_currentKnownStructure.clear();
-            m_futurePossibleStructure.clear();
</del><ins>+            m_structure.clear();
</ins><span class="cx">             m_arrayModes = 0;
</span><span class="cx">         }
</span><span class="cx">         m_type = type;
</span><span class="lines">@@ -138,8 +199,7 @@
</span><span class="cx">     {
</span><span class="cx">         return m_type == other.m_type
</span><span class="cx">             &amp;&amp; m_arrayModes == other.m_arrayModes
</span><del>-            &amp;&amp; m_currentKnownStructure == other.m_currentKnownStructure
-            &amp;&amp; m_futurePossibleStructure == other.m_futurePossibleStructure
</del><ins>+            &amp;&amp; m_structure == other.m_structure
</ins><span class="cx">             &amp;&amp; m_value == other.m_value;
</span><span class="cx">     }
</span><span class="cx">     bool operator!=(const AbstractValue&amp; other) const
</span><span class="lines">@@ -162,8 +222,7 @@
</span><span class="cx">         } else {
</span><span class="cx">             result |= mergeSpeculation(m_type, other.m_type);
</span><span class="cx">             result |= mergeArrayModes(m_arrayModes, other.m_arrayModes);
</span><del>-            result |= m_currentKnownStructure.addAll(other.m_currentKnownStructure);
-            result |= m_futurePossibleStructure.addAll(other.m_futurePossibleStructure);
</del><ins>+            result |= m_structure.merge(other.m_structure);
</ins><span class="cx">             if (m_value != other.m_value) {
</span><span class="cx">                 result |= !!m_value;
</span><span class="cx">                 m_value = JSValue();
</span><span class="lines">@@ -179,8 +238,7 @@
</span><span class="cx">         mergeSpeculation(m_type, type);
</span><span class="cx">         
</span><span class="cx">         if (type &amp; SpecCell) {
</span><del>-            m_currentKnownStructure.makeTop();
-            m_futurePossibleStructure.makeTop();
</del><ins>+            m_structure.makeTop();
</ins><span class="cx">             m_arrayModes = ALL_ARRAY_MODES;
</span><span class="cx">         }
</span><span class="cx">         m_value = JSValue();
</span><span class="lines">@@ -225,75 +283,30 @@
</span><span class="cx">         if (!!value &amp;&amp; value.isCell()) {
</span><span class="cx">             ASSERT(m_type &amp; SpecCell);
</span><span class="cx">             Structure* structure = value.asCell()-&gt;structure();
</span><del>-            return m_currentKnownStructure.contains(structure)
-                &amp;&amp; m_futurePossibleStructure.contains(structure)
</del><ins>+            return m_structure.contains(structure)
</ins><span class="cx">                 &amp;&amp; (m_arrayModes &amp; asArrayModes(structure-&gt;indexingType()));
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Structure* bestProvenStructure() const
-    {
-        if (m_currentKnownStructure.hasSingleton())
-            return m_currentKnownStructure.singleton();
-        if (m_futurePossibleStructure.hasSingleton())
-            return m_futurePossibleStructure.singleton();
-        return 0;
-    }
-    
</del><span class="cx">     bool hasClobberableState() const
</span><span class="cx">     {
</span><del>-        return m_currentKnownStructure.isNeitherClearNorTop()
</del><ins>+        return m_structure.isNeitherClearNorTop()
</ins><span class="cx">             || !arrayModesAreClearOrTop(m_arrayModes);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> #if ASSERT_DISABLED
</span><span class="cx">     void checkConsistency() const { }
</span><ins>+    void assertIsWatched(Graph&amp;) const { }
</ins><span class="cx"> #else
</span><span class="cx">     void checkConsistency() const;
</span><ins>+    void assertIsWatched(Graph&amp;) const;
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     
</span><del>-    // A great way to think about the difference between m_currentKnownStructure and
-    // m_futurePossibleStructure is to consider these four examples:
-    //
-    // 1) x = foo();
-    //
-    //    In this case x's m_currentKnownStructure and m_futurePossibleStructure will
-    //    both be TOP, since we don't know anything about x for sure, yet.
-    //
-    // 2) x = foo();
-    //    y = x.f;
-    //
-    //    Where x will later have a new property added to it, 'g'. Because of the
-    //    known but not-yet-executed property addition, x's current structure will
-    //    not be watchpointable; hence we have no way of statically bounding the set
-    //    of possible structures that x may have if a clobbering event happens. So,
-    //    x's m_currentKnownStructure will be whatever structure we check to get
-    //    property 'f', and m_futurePossibleStructure will be TOP.
-    //
-    // 3) x = foo();
-    //    y = x.f;
-    //
-    //    Where x has a terminal structure that is still watchpointable. In this case,
-    //    x's m_currentKnownStructure and m_futurePossibleStructure will both be
-    //    whatever structure we checked for when getting 'f'.
-    //
-    // 4) x = foo();
-    //    y = x.f;
-    //    bar();
-    //
-    //    Where x has a terminal structure that is still watchpointable. In this
-    //    case, m_currentKnownStructure will be TOP because bar() may potentially
-    //    change x's structure and we have no way of proving otherwise, but
-    //    x's m_futurePossibleStructure will be whatever structure we had checked
-    //    when getting property 'f'.
-    
-    // NB. All fields in this struct must have trivial destructors.
-
</del><span class="cx">     // This is a proven constraint on the structures that this value can have right
</span><span class="cx">     // now. The structure of the current value must belong to this set. The set may
</span><span class="cx">     // be TOP, indicating that it is the set of all possible structures, in which
</span><span class="lines">@@ -301,30 +314,13 @@
</span><span class="cx">     // in which case this value cannot be a cell. This is all subject to change
</span><span class="cx">     // anytime a new value is assigned to this one, anytime there is a control flow
</span><span class="cx">     // merge, or most crucially, anytime a side-effect or structure check happens.
</span><del>-    // In case of a side-effect, we typically must assume that any value may have
-    // had its structure changed, hence contravening our proof. We make the proof
-    // valid again by switching this to TOP (i.e. claiming that we have proved that
-    // this value may have any structure). Of note is that the proof represented by
-    // this field is not subject to structure transition watchpoints - even if one
-    // fires, we can be sure that this proof is still valid.
-    StructureAbstractValue m_currentKnownStructure;
</del><ins>+    // In case of a side-effect, we must assume that any value with a structure that
+    // isn't being watched may have had its structure changed, hence contravening
+    // our proof. In such a case we make the proof valid again by switching this to
+    // TOP (i.e. claiming that we have proved that this value may have any
+    // structure).
+    StructureAbstractValue m_structure;
</ins><span class="cx">     
</span><del>-    // This is a proven constraint on the structures that this value can have now
-    // or any time in the future subject to the structure transition watchpoints of
-    // all members of this set not having fired. This set is impervious to side-
-    // effects; even if one happens the side-effect can only cause the value to
-    // change to at worst another structure that is also a member of this set. But,
-    // the theorem being proved by this field is predicated upon there not being
-    // any new structure transitions introduced into any members of this set. In
-    // cases where there is no way for us to guard this happening, the set must be
-    // TOP. But in cases where we can guard new structure transitions (all members
-    // of the set have still-valid structure transition watchpoints) then this set
-    // will be finite. Anytime that we make use of the finite nature of this set,
-    // we must first issue a structure transition watchpoint, which will effectively
-    // result in m_currentKnownStructure being filtered according to
-    // m_futurePossibleStructure.
-    StructureAbstractValue m_futurePossibleStructure;
-    
</del><span class="cx">     // This is a proven constraint on the possible types that this value can have
</span><span class="cx">     // now or any time in the future, unless it is reassigned. This field is
</span><span class="cx">     // impervious to side-effects unless the side-effect can reassign the value
</span><span class="lines">@@ -332,11 +328,11 @@
</span><span class="cx">     // between this field, and the structure fields above, is as follows. The
</span><span class="cx">     // fields above constraint the structures that a cell may have, but they say
</span><span class="cx">     // nothing about whether or not the value is known to be a cell. More formally,
</span><del>-    // the m_currentKnownStructure is itself an abstract value that consists of the
</del><ins>+    // the m_structure is itself an abstract value that consists of the
</ins><span class="cx">     // union of the set of all non-cell values and the set of cell values that have
</span><span class="cx">     // the given structure. This abstract value is then the intersection of the
</span><del>-    // m_currentKnownStructure and the set of values whose type is m_type. So, for
-    // example if m_type is SpecFinal|SpecInt32 and m_currentKnownStructure is
</del><ins>+    // m_structure and the set of values whose type is m_type. So, for
+    // example if m_type is SpecFinal|SpecInt32 and m_structure is
</ins><span class="cx">     // [0x12345] then this abstract value corresponds to the set of all integers
</span><span class="cx">     // unified with the set of all objects with structure 0x12345.
</span><span class="cx">     SpeculatedType m_type;
</span><span class="lines">@@ -364,6 +360,12 @@
</span><span class="cx">         m_arrayModes = ALL_ARRAY_MODES;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void observeIndexingTypeTransition(IndexingType from, IndexingType to)
+    {
+        if (m_arrayModes &amp; asArrayModes(from))
+            m_arrayModes |= asArrayModes(to);
+    }
+    
</ins><span class="cx">     bool validateType(JSValue value) const
</span><span class="cx">     {
</span><span class="cx">         if (isHeapTop())
</span><span class="lines">@@ -391,19 +393,17 @@
</span><span class="cx">     {
</span><span class="cx">         m_type |= top;
</span><span class="cx">         m_arrayModes = ALL_ARRAY_MODES;
</span><del>-        m_currentKnownStructure.makeTop();
-        m_futurePossibleStructure.makeTop();
</del><ins>+        m_structure.makeTop();
</ins><span class="cx">         m_value = JSValue();
</span><span class="cx">         checkConsistency();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void setFuturePossibleStructure(Graph&amp;, Structure*);
-
</del><span class="cx">     void filterValueByType();
</span><span class="cx">     void filterArrayModesByType();
</span><span class="cx">     
</span><span class="cx">     bool shouldBeClear() const;
</span><span class="cx">     FiltrationResult normalizeClarity();
</span><ins>+    FiltrationResult normalizeClarity(Graph&amp;);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAllocatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAllocator.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAllocator.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAllocator.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx">     void* allocate(); // Use placement new to allocate, and avoid using this method.
</span><span class="cx">     void free(T*); // Call this method to delete; never use 'delete' directly.
</span><span class="cx">     
</span><del>-    void freeAll(); // Only call this if T has a trivial destructor.
</del><ins>+    void freeAll(); // Only call this if you've either freed everything or if T has a trivial destructor.
</ins><span class="cx">     void reset(); // Like freeAll(), but also returns all memory to the OS.
</span><span class="cx">     
</span><span class="cx">     unsigned indexOf(const T*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArgumentsSimplificationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -325,7 +325,6 @@
</span><span class="cx">                     break;
</span><span class="cx">                     
</span><span class="cx">                 case CheckStructure:
</span><del>-                case StructureTransitionWatchpoint:
</del><span class="cx">                 case CheckArray:
</span><span class="cx">                     // We don't care about these because if we get uses of the relevant
</span><span class="cx">                     // variable then we can safely get rid of these, too. This of course
</span><span class="lines">@@ -441,7 +440,6 @@
</span><span class="cx">                 }
</span><span class="cx">                     
</span><span class="cx">                 case CheckStructure:
</span><del>-                case StructureTransitionWatchpoint:
</del><span class="cx">                 case CheckArray: {
</span><span class="cx">                     // We can just get rid of this node, if it references a phantom argument.
</span><span class="cx">                     if (!isOKToOptimize(node-&gt;child1().node()))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -289,25 +289,48 @@
</span><span class="cx"> bool ArrayMode::alreadyChecked(Graph&amp; graph, Node* node, AbstractValue&amp; value, IndexingType shape) const
</span><span class="cx"> {
</span><span class="cx">     switch (arrayClass()) {
</span><del>-    case Array::OriginalArray:
-        return value.m_currentKnownStructure.hasSingleton()
-            &amp;&amp; (value.m_currentKnownStructure.singleton()-&gt;indexingType() &amp; IndexingShapeMask) == shape
-            &amp;&amp; (value.m_currentKnownStructure.singleton()-&gt;indexingType() &amp; IsArray)
-            &amp;&amp; graph.globalObjectFor(node-&gt;origin.semantic)-&gt;isOriginalArrayStructure(value.m_currentKnownStructure.singleton());
</del><ins>+    case Array::OriginalArray: {
+        if (value.m_structure.isTop())
+            return false;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if ((structure-&gt;indexingType() &amp; IndexingShapeMask) != shape)
+                return false;
+            if (!(structure-&gt;indexingType() &amp; IsArray))
+                return false;
+            if (!graph.globalObjectFor(node-&gt;origin.semantic)-&gt;isOriginalArrayStructure(structure))
+                return false;
+        }
+        return true;
+    }
</ins><span class="cx">         
</span><del>-    case Array::Array:
</del><ins>+    case Array::Array: {
</ins><span class="cx">         if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray)))
</span><span class="cx">             return true;
</span><del>-        return value.m_currentKnownStructure.hasSingleton()
-            &amp;&amp; (value.m_currentKnownStructure.singleton()-&gt;indexingType() &amp; IndexingShapeMask) == shape
-            &amp;&amp; (value.m_currentKnownStructure.singleton()-&gt;indexingType() &amp; IsArray);
</del><ins>+        if (value.m_structure.isTop())
+            return false;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if ((structure-&gt;indexingType() &amp; IndexingShapeMask) != shape)
+                return false;
+            if (!(structure-&gt;indexingType() &amp; IsArray))
+                return false;
+        }
+        return true;
+    }
</ins><span class="cx">         
</span><del>-    default:
</del><ins>+    default: {
</ins><span class="cx">         if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape) | asArrayModes(shape | IsArray)))
</span><span class="cx">             return true;
</span><del>-        return value.m_currentKnownStructure.hasSingleton()
-            &amp;&amp; (value.m_currentKnownStructure.singleton()-&gt;indexingType() &amp; IndexingShapeMask) == shape;
-    }
</del><ins>+        if (value.m_structure.isTop())
+            return false;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if ((structure-&gt;indexingType() &amp; IndexingShapeMask) != shape)
+                return false;
+        }
+        return true;
+    } }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ArrayMode::alreadyChecked(Graph&amp; graph, Node* node, AbstractValue&amp; value) const
</span><span class="lines">@@ -336,23 +359,38 @@
</span><span class="cx">         
</span><span class="cx">     case Array::SlowPutArrayStorage:
</span><span class="cx">         switch (arrayClass()) {
</span><del>-        case Array::OriginalArray:
</del><ins>+        case Array::OriginalArray: {
</ins><span class="cx">             CRASH();
</span><span class="cx">             return false;
</span><ins>+        }
</ins><span class="cx">         
</span><del>-        case Array::Array:
</del><ins>+        case Array::Array: {
</ins><span class="cx">             if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
</span><span class="cx">                 return true;
</span><del>-            return value.m_currentKnownStructure.hasSingleton()
-                &amp;&amp; hasAnyArrayStorage(value.m_currentKnownStructure.singleton()-&gt;indexingType())
-                &amp;&amp; (value.m_currentKnownStructure.singleton()-&gt;indexingType() &amp; IsArray);
</del><ins>+            if (value.m_structure.isTop())
+                return false;
+            for (unsigned i = value.m_structure.size(); i--;) {
+                Structure* structure = value.m_structure[i];
+                if (!hasAnyArrayStorage(structure-&gt;indexingType()))
+                    return false;
+                if (!(structure-&gt;indexingType() &amp; IsArray))
+                    return false;
+            }
+            return true;
+        }
</ins><span class="cx">         
</span><del>-        default:
</del><ins>+        default: {
</ins><span class="cx">             if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
</span><span class="cx">                 return true;
</span><del>-            return value.m_currentKnownStructure.hasSingleton()
-                &amp;&amp; hasAnyArrayStorage(value.m_currentKnownStructure.singleton()-&gt;indexingType());
-        }
</del><ins>+            if (value.m_structure.isTop())
+                return false;
+            for (unsigned i = value.m_structure.size(); i--;) {
+                Structure* structure = value.m_structure[i];
+                if (!hasAnyArrayStorage(structure-&gt;indexingType()))
+                    return false;
+            }
+            return true;
+        } }
</ins><span class="cx">         
</span><span class="cx">     case Array::Arguments:
</span><span class="cx">         return speculationChecked(value.m_type, SpecArguments);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAtTailAbstractStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -54,12 +54,13 @@
</span><span class="cx">     
</span><span class="cx">     bool isValid() { return m_block-&gt;cfaDidFinish; }
</span><span class="cx">     
</span><ins>+    StructureClobberState structureClobberState() const { return m_block-&gt;cfaStructureClobberStateAtTail; }
+    
</ins><span class="cx">     void setDidClobber(bool) { }
</span><ins>+    void setStructureClobberState(StructureClobberState state) { RELEASE_ASSERT(state == m_block-&gt;cfaStructureClobberStateAtTail); }
</ins><span class="cx">     void setIsValid(bool isValid) { m_block-&gt;cfaDidFinish = isValid; }
</span><span class="cx">     void setBranchDirection(BranchDirection) { }
</span><span class="cx">     void setFoundConstants(bool) { }
</span><del>-    bool haveStructures() const { return true; } // It's always safe to return true.
-    void setHaveStructures(bool) { }
</del><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     BasicBlock* m_block;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -41,6 +41,8 @@
</span><span class="cx">     , cfaShouldRevisit(false)
</span><span class="cx">     , cfaFoundConstants(false)
</span><span class="cx">     , cfaDidFinish(true)
</span><ins>+    , cfaStructureClobberStateAtHead(StructuresAreWatched)
+    , cfaStructureClobberStateAtTail(StructuresAreWatched)
</ins><span class="cx">     , cfaBranchDirection(InvalidBranchDirection)
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     , isLinked(false)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><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><ins>+#include &quot;DFGStructureClobberState.h&quot;
</ins><span class="cx"> #include &quot;Operands.h&quot;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="lines">@@ -116,6 +117,8 @@
</span><span class="cx">     bool cfaShouldRevisit;
</span><span class="cx">     bool cfaFoundConstants;
</span><span class="cx">     bool cfaDidFinish;
</span><ins>+    StructureClobberState cfaStructureClobberStateAtHead;
+    StructureClobberState cfaStructureClobberStateAtTail;
</ins><span class="cx">     BranchDirection cfaBranchDirection;
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     bool isLinked;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBranchDirectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBranchDirection.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBranchDirection.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGBranchDirection.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 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">@@ -50,7 +50,7 @@
</span><span class="cx"> {
</span><span class="cx">     switch (branchDirection) {
</span><span class="cx">     case InvalidBranchDirection:
</span><del>-        return &quot;Invalid&quot;;
</del><ins>+        return &quot;InvalidBranchDirection&quot;;
</ins><span class="cx">     case TakeTrue:
</span><span class="cx">         return &quot;TakeTrue&quot;;
</span><span class="cx">     case TakeFalse:
</span><span class="lines">@@ -81,6 +81,15 @@
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><ins>+namespace WTF {
+
+inline void printInternal(PrintStream&amp; out, JSC::DFG::BranchDirection direction)
+{
+    out.print(JSC::DFG::branchDirectionToString(direction));
+}
+
+} // namespace WTF
+
</ins><span class="cx"> #endif // ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><span class="cx"> #endif // DFGBranchDirection_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1921,6 +1921,7 @@
</span><span class="cx"> Node* ByteCodeParser::emitPrototypeChecks(
</span><span class="cx">     Structure* structure, IntendedStructureChain* chain)
</span><span class="cx"> {
</span><ins>+    ASSERT(structure);
</ins><span class="cx">     Node* base = 0;
</span><span class="cx">     m_graph.chains().addLazily(chain);
</span><span class="cx">     Structure* currentStructure = structure;
</span><span class="lines">@@ -1962,7 +1963,7 @@
</span><span class="cx">         for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) {
</span><span class="cx">             if (getByIdStatus[variantIndex].chain()) {
</span><span class="cx">                 emitPrototypeChecks(
</span><del>-                    getByIdStatus[variantIndex].structureSet().singletonStructure(),
</del><ins>+                    getByIdStatus[variantIndex].structureSet().onlyStructure(),
</ins><span class="cx">                     getByIdStatus[variantIndex].chain());
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -1988,7 +1989,7 @@
</span><span class="cx">     
</span><span class="cx">     if (variant.chain()) {
</span><span class="cx">         base = emitPrototypeChecks(
</span><del>-            variant.structureSet().singletonStructure(), variant.chain());
</del><ins>+            variant.structureSet().onlyStructure(), variant.chain());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
</span><span class="lines">@@ -2131,8 +2132,8 @@
</span><span class="cx">     ASSERT(variant.oldStructure()-&gt;transitionWatchpointSetHasBeenInvalidated());
</span><span class="cx">     
</span><span class="cx">     Node* propertyStorage;
</span><del>-    StructureTransitionData* transitionData = m_graph.addStructureTransitionData(
-        StructureTransitionData(variant.oldStructure(), variant.newStructure()));
</del><ins>+    Transition* transition = m_graph.m_transitions.add(
+        variant.oldStructure(), variant.newStructure());
</ins><span class="cx"> 
</span><span class="cx">     if (variant.oldStructure()-&gt;outOfLineCapacity()
</span><span class="cx">         != variant.newStructure()-&gt;outOfLineCapacity()) {
</span><span class="lines">@@ -2143,10 +2144,10 @@
</span><span class="cx"> 
</span><span class="cx">         if (!variant.oldStructure()-&gt;outOfLineCapacity()) {
</span><span class="cx">             propertyStorage = addToGraph(
</span><del>-                AllocatePropertyStorage, OpInfo(transitionData), base);
</del><ins>+                AllocatePropertyStorage, OpInfo(transition), base);
</ins><span class="cx">         } else {
</span><span class="cx">             propertyStorage = addToGraph(
</span><del>-                ReallocatePropertyStorage, OpInfo(transitionData),
</del><ins>+                ReallocatePropertyStorage, OpInfo(transition),
</ins><span class="cx">                 base, addToGraph(GetButterfly, base));
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="lines">@@ -2156,7 +2157,7 @@
</span><span class="cx">             propertyStorage = addToGraph(GetButterfly, base);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    addToGraph(PutStructure, OpInfo(transitionData), base);
</del><ins>+    addToGraph(PutStructure, OpInfo(transition), base);
</ins><span class="cx"> 
</span><span class="cx">     addToGraph(
</span><span class="cx">         PutByOffset,
</span><span class="lines">@@ -3131,7 +3132,7 @@
</span><span class="cx">                     set(VirtualRegister(dst), addToGraph(GetByIdFlush, OpInfo(identifierNumber), OpInfo(prediction), get(VirtualRegister(scope))));
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().singletonStructure());
</del><ins>+                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().onlyStructure());
</ins><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx">                 if (JSValue specificValue = status[0].specificValue())
</span><span class="cx">                     set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCFAPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 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">@@ -92,8 +92,11 @@
</span><span class="cx">         if (m_verbose)
</span><span class="cx">             dataLog(&quot;   Block &quot;, *block, &quot;:\n&quot;);
</span><span class="cx">         m_state.beginBasicBlock(block);
</span><del>-        if (m_verbose)
</del><ins>+        if (m_verbose) {
</ins><span class="cx">             dataLog(&quot;      head vars: &quot;, block-&gt;valuesAtHead, &quot;\n&quot;);
</span><ins>+            if (m_graph.m_form == SSA)
+                dataLog(&quot;      head regs: &quot;, mapDump(block-&gt;ssa-&gt;valuesAtHead), &quot;\n&quot;);
+        }
</ins><span class="cx">         for (unsigned i = 0; i &lt; block-&gt;size(); ++i) {
</span><span class="cx">             if (m_verbose) {
</span><span class="cx">                 Node* node = block-&gt;at(i);
</span><span class="lines">@@ -102,10 +105,8 @@
</span><span class="cx">                 if (!safeToExecute(m_state, m_graph, node))
</span><span class="cx">                     dataLog(&quot;(UNSAFE) &quot;);
</span><span class="cx">                 
</span><del>-                m_interpreter.dump(WTF::dataFile());
</del><ins>+                dataLog(m_state.variables(), &quot; &quot;, m_interpreter);
</ins><span class="cx">                 
</span><del>-                if (m_state.haveStructures())
-                    dataLog(&quot; (Have Structures)&quot;);
</del><span class="cx">                 dataLogF(&quot;\n&quot;);
</span><span class="cx">             }
</span><span class="cx">             if (!m_interpreter.execute(i)) {
</span><span class="lines">@@ -121,8 +122,11 @@
</span><span class="cx">         }
</span><span class="cx">         m_changed |= m_state.endBasicBlock(MergeToSuccessors);
</span><span class="cx">         
</span><del>-        if (m_verbose)
</del><ins>+        if (m_verbose) {
</ins><span class="cx">             dataLog(&quot;      tail vars: &quot;, block-&gt;valuesAtTail, &quot;\n&quot;);
</span><ins>+            if (m_graph.m_form == SSA)
+                dataLog(&quot;      head regs: &quot;, mapDump(block-&gt;ssa-&gt;valuesAtTail), &quot;\n&quot;);
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void performForwardCFA()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCSEPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -460,17 +460,11 @@
</span><span class="cx">                     return true;
</span><span class="cx">                 break;
</span><span class="cx">                 
</span><del>-            case StructureTransitionWatchpoint:
-                if (node-&gt;child1() == child1
-                    &amp;&amp; structureSet.contains(node-&gt;structure()))
-                    return true;
-                break;
-                
</del><span class="cx">             case PutStructure:
</span><span class="cx">                 if (node-&gt;child1() == child1
</span><del>-                    &amp;&amp; structureSet.contains(node-&gt;structureTransitionData().newStructure))
</del><ins>+                    &amp;&amp; structureSet.contains(node-&gt;transition()-&gt;next))
</ins><span class="cx">                     return true;
</span><del>-                if (structureSet.contains(node-&gt;structureTransitionData().previousStructure))
</del><ins>+                if (structureSet.contains(node-&gt;transition()-&gt;previous))
</ins><span class="cx">                     return false;
</span><span class="cx">                 break;
</span><span class="cx">                 
</span><span class="lines">@@ -519,12 +513,12 @@
</span><span class="cx">             switch (node-&gt;op()) {
</span><span class="cx">             case CheckStructure:
</span><span class="cx">                 if (node-&gt;child1() == child1
</span><del>-                    &amp;&amp; node-&gt;structureSet().containsOnly(structure))
</del><ins>+                    &amp;&amp; node-&gt;structureSet().isSubsetOf(StructureSet(structure)))
</ins><span class="cx">                     return true;
</span><span class="cx">                 break;
</span><span class="cx">                 
</span><span class="cx">             case PutStructure:
</span><del>-                ASSERT(node-&gt;structureTransitionData().previousStructure != structure);
</del><ins>+                ASSERT(node-&gt;transition()-&gt;previous != structure);
</ins><span class="cx">                 break;
</span><span class="cx">                 
</span><span class="cx">             case PutByOffset:
</span><span class="lines">@@ -547,11 +541,6 @@
</span><span class="cx">                 }
</span><span class="cx">                 return false;
</span><span class="cx">                 
</span><del>-            case StructureTransitionWatchpoint:
-                if (node-&gt;structure() == structure &amp;&amp; node-&gt;child1() == child1)
-                    return true;
-                break;
-                
</del><span class="cx">             case Arrayify:
</span><span class="cx">             case ArrayifyToStructure:
</span><span class="cx">                 // We could check if the arrayification could affect our structures.
</span><span class="lines">@@ -1423,13 +1412,6 @@
</span><span class="cx">                 eliminate();
</span><span class="cx">             break;
</span><span class="cx">             
</span><del>-        case StructureTransitionWatchpoint:
-            if (cseMode == StoreElimination)
-                break;
-            if (structureTransitionWatchpointElimination(node-&gt;structure(), node-&gt;child1().node()))
-                eliminate();
-            break;
-            
</del><span class="cx">         case PutStructure:
</span><span class="cx">             if (cseMode == NormalCSE)
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -35,15 +35,6 @@
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename ReadFunctor, typename WriteFunctor&gt;
</span><del>-void clobberizeForAllocation(ReadFunctor&amp; read, WriteFunctor&amp; write)
-{
-    read(GCState);
-    read(BarrierState);
-    write(GCState);
-    write(BarrierState);
-}
-
-template&lt;typename ReadFunctor, typename WriteFunctor&gt;
</del><span class="cx"> void clobberize(Graph&amp; graph, Node* node, ReadFunctor&amp; read, WriteFunctor&amp; write)
</span><span class="cx"> {
</span><span class="cx">     // Some notes:
</span><span class="lines">@@ -133,6 +124,7 @@
</span><span class="cx">     case Int52Rep:
</span><span class="cx">     case BooleanToNumber:
</span><span class="cx">     case FiatInt52:
</span><ins>+    case MakeRope:
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case MovHint:
</span><span class="lines">@@ -158,6 +150,8 @@
</span><span class="cx">     case Breakpoint:
</span><span class="cx">     case ProfileWillCall:
</span><span class="cx">     case ProfileDidCall:
</span><ins>+    case StoreBarrier:
+    case StoreBarrierWithNullCheck:
</ins><span class="cx">         write(SideState);
</span><span class="cx">         return;
</span><span class="cx">         
</span><span class="lines">@@ -174,7 +168,8 @@
</span><span class="cx"> 
</span><span class="cx">     case CreateActivation:
</span><span class="cx">     case CreateArguments:
</span><del>-        clobberizeForAllocation(read, write);
</del><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
</ins><span class="cx">         write(SideState);
</span><span class="cx">         write(Watchpoint_fire);
</span><span class="cx">         return;
</span><span class="lines">@@ -186,7 +181,8 @@
</span><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span><span class="cx">         read(MiscFields);
</span><del>-        clobberizeForAllocation(read, write);
</del><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case VarInjectionWatchpoint:
</span><span class="lines">@@ -424,7 +420,6 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case CheckStructure:
</span><del>-    case StructureTransitionWatchpoint:
</del><span class="cx">     case InstanceOf:
</span><span class="cx">         read(JSCell_structureID);
</span><span class="cx">         return;
</span><span class="lines">@@ -453,13 +448,11 @@
</span><span class="cx">         
</span><span class="cx">     case AllocatePropertyStorage:
</span><span class="cx">         write(JSObject_butterfly);
</span><del>-        clobberizeForAllocation(read, write);
</del><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case ReallocatePropertyStorage:
</span><span class="cx">         read(JSObject_butterfly);
</span><span class="cx">         write(JSObject_butterfly);
</span><del>-        clobberizeForAllocation(read, write);
</del><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetButterfly:
</span><span class="lines">@@ -475,7 +468,6 @@
</span><span class="cx">         write(JSCell_indexingType);
</span><span class="cx">         write(JSObject_butterfly);
</span><span class="cx">         write(Watchpoint_fire);
</span><del>-        clobberizeForAllocation(read, write);
</del><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetIndexedPropertyStorage:
</span><span class="lines">@@ -508,10 +500,8 @@
</span><span class="cx">         write(AbstractHeap(NamedProperties, node-&gt;multiPutByOffsetData().identifierNumber));
</span><span class="cx">         if (node-&gt;multiPutByOffsetData().writesStructures())
</span><span class="cx">             write(JSCell_structureID);
</span><del>-        if (node-&gt;multiPutByOffsetData().reallocatesStorage()) {
</del><ins>+        if (node-&gt;multiPutByOffsetData().reallocatesStorage())
</ins><span class="cx">             write(JSObject_butterfly);
</span><del>-            clobberizeForAllocation(read, write);
-        }
</del><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case PutByOffset:
</span><span class="lines">@@ -577,15 +567,16 @@
</span><span class="cx">     case NewArrayBuffer:
</span><span class="cx">     case NewRegexp:
</span><span class="cx">     case NewStringObject:
</span><del>-    case MakeRope:
</del><span class="cx">     case NewFunctionNoCheck:
</span><span class="cx">     case NewFunction:
</span><span class="cx">     case NewFunctionExpression:
</span><del>-        clobberizeForAllocation(read, write);
</del><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case NewTypedArray:
</span><del>-        clobberizeForAllocation(read, write);
</del><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
</ins><span class="cx">         switch (node-&gt;child1().useKind()) {
</span><span class="cx">         case Int32Use:
</span><span class="cx">             return;
</span><span class="lines">@@ -663,7 +654,8 @@
</span><span class="cx"> 
</span><span class="cx">     case ThrowReferenceError:
</span><span class="cx">         write(SideState);
</span><del>-        clobberizeForAllocation(read, write);
</del><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case CountExecution:
</span><span class="lines">@@ -671,12 +663,6 @@
</span><span class="cx">         read(InternalState);
</span><span class="cx">         write(InternalState);
</span><span class="cx">         return;
</span><del>-
-    case StoreBarrier:
-    case StoreBarrierWithNullCheck:
-        read(BarrierState);
-        write(BarrierState);
-        return;
</del><span class="cx">         
</span><span class="cx">     case LastNodeType:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCommoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommon.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommon.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommon.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -33,15 +33,23 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><ins>+static unsigned crashLock;
+
</ins><span class="cx"> void startCrashing()
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(COMPARE_AND_SWAP)
</span><del>-    static unsigned lock;
-    while (!WTF::weakCompareAndSwap(&amp;lock, 0, 1))
</del><ins>+    while (!WTF::weakCompareAndSwap(&amp;crashLock, 0, 1))
</ins><span class="cx">         std::this_thread::yield();
</span><ins>+#else
+    crashLock = 1;
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool isCrashing()
+{
+    return !!crashLock;
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCommonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommon.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommon.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommon.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -259,6 +259,8 @@
</span><span class="cx"> // when you're forcing a crash with diagnostics.
</span><span class="cx"> void startCrashing();
</span><span class="cx"> 
</span><ins>+JS_EXPORT_PRIVATE bool isCrashing();
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCommonDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -41,8 +41,8 @@
</span><span class="cx">     plan.transitions.addLazily(
</span><span class="cx">         codeBlock,
</span><span class="cx">         node-&gt;origin.semantic.codeOriginOwner(),
</span><del>-        node-&gt;structureTransitionData().previousStructure,
-        node-&gt;structureTransitionData().newStructure);
</del><ins>+        node-&gt;transition()-&gt;previous,
+        node-&gt;transition()-&gt;next);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned CommonData::addCodeOrigin(CodeOrigin codeOrigin)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -104,27 +104,12 @@
</span><span class="cx">                     set = node-&gt;structure();
</span><span class="cx">                 else
</span><span class="cx">                     set = node-&gt;structureSet();
</span><del>-                if (value.m_currentKnownStructure.isSubsetOf(set)) {
</del><ins>+                if (value.m_structure.isSubsetOf(set)) {
</ins><span class="cx">                     m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
</span><span class="cx">                     node-&gt;convertToPhantom();
</span><span class="cx">                     eliminated = true;
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                StructureAbstractValue&amp; structureValue = value.m_futurePossibleStructure;
-                if (structureValue.isSubsetOf(set)
-                    &amp;&amp; structureValue.hasSingleton()) {
-                    Structure* structure = structureValue.singleton();
-                    m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
-                    AdjacencyList children = node-&gt;children;
-                    children.removeEdge(0);
-                    if (!!children.child1())
-                        m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node-&gt;origin, children);
-                    node-&gt;children.setChild2(Edge());
-                    node-&gt;children.setChild3(Edge());
-                    node-&gt;convertToStructureTransitionWatchpoint(structure);
-                    eliminated = true;
-                    break;
-                }
</del><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="lines">@@ -163,7 +148,7 @@
</span><span class="cx">                 Node* child = childEdge.node();
</span><span class="cx">                 MultiGetByOffsetData&amp; data = node-&gt;multiGetByOffsetData();
</span><span class="cx"> 
</span><del>-                Structure* structure = m_state.forNode(child).bestProvenStructure();
</del><ins>+                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
</ins><span class="cx">                 if (!structure)
</span><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="lines">@@ -187,7 +172,7 @@
</span><span class="cx">                 Node* child = childEdge.node();
</span><span class="cx">                 MultiPutByOffsetData&amp; data = node-&gt;multiPutByOffsetData();
</span><span class="cx"> 
</span><del>-                Structure* structure = m_state.forNode(child).bestProvenStructure();
</del><ins>+                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
</ins><span class="cx">                 if (!structure)
</span><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="lines">@@ -212,7 +197,7 @@
</span><span class="cx">                 if (childEdge.useKind() != CellUse)
</span><span class="cx">                     break;
</span><span class="cx">                 
</span><del>-                Structure* structure = m_state.forNode(child).bestProvenStructure();
</del><ins>+                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
</ins><span class="cx">                 if (!structure)
</span><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="lines">@@ -239,7 +224,7 @@
</span><span class="cx">                 
</span><span class="cx">                 ASSERT(childEdge.useKind() == CellUse);
</span><span class="cx">                 
</span><del>-                Structure* structure = m_state.forNode(child).bestProvenStructure();
</del><ins>+                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
</ins><span class="cx">                 if (!structure)
</span><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="lines">@@ -305,7 +290,7 @@
</span><span class="cx">             // then we refuse to fold.
</span><span class="cx">             AbstractValue oldValue = m_state.forNode(node);
</span><span class="cx">             AbstractValue constantValue;
</span><del>-            constantValue.set(m_graph, value);
</del><ins>+            constantValue.set(m_graph, value, m_state.structureClobberState());
</ins><span class="cx">             constantValue.fixTypeForRepresentation(node);
</span><span class="cx">             if (oldValue.merge(constantValue))
</span><span class="cx">                 continue;
</span><span class="lines">@@ -336,23 +321,18 @@
</span><span class="cx">         Edge childEdge = node-&gt;child1();
</span><span class="cx">         Node* child = childEdge.node();
</span><span class="cx"> 
</span><del>-        bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
</del><span class="cx">         bool needsCellCheck = m_state.forNode(child).m_type &amp; ~SpecCell;
</span><span class="cx">         
</span><span class="cx">         ASSERT(!variant.chain());
</span><del>-        ASSERT(variant.structureSet().contains(structure));
</del><ins>+        ASSERT_UNUSED(structure, variant.structureSet().contains(structure));
</ins><span class="cx">         
</span><span class="cx">         // Now before we do anything else, push the CFA forward over the GetById
</span><span class="cx">         // and make sure we signal to the loop that it should continue and not
</span><span class="cx">         // do any eliminations.
</span><span class="cx">         m_interpreter.execute(indexInBlock);
</span><span class="cx">         
</span><del>-        if (needsWatchpoint) {
</del><ins>+        if (needsCellCheck) {
</ins><span class="cx">             m_insertionSet.insertNode(
</span><del>-                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
-                OpInfo(structure), childEdge);
-        } else if (needsCellCheck) {
-            m_insertionSet.insertNode(
</del><span class="cx">                 indexInBlock, SpecNone, Phantom, origin, childEdge);
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -388,7 +368,6 @@
</span><span class="cx"> 
</span><span class="cx">         ASSERT(variant.oldStructure() == structure);
</span><span class="cx">         
</span><del>-        bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
</del><span class="cx">         bool needsCellCheck = m_state.forNode(child).m_type &amp; ~SpecCell;
</span><span class="cx">         
</span><span class="cx">         // Now before we do anything else, push the CFA forward over the PutById
</span><span class="lines">@@ -396,21 +375,16 @@
</span><span class="cx">         // do any eliminations.
</span><span class="cx">         m_interpreter.execute(indexInBlock);
</span><span class="cx"> 
</span><del>-        if (needsWatchpoint) {
</del><ins>+        if (needsCellCheck) {
</ins><span class="cx">             m_insertionSet.insertNode(
</span><del>-                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
-                OpInfo(structure), childEdge);
-        } else if (needsCellCheck) {
-            m_insertionSet.insertNode(
</del><span class="cx">                 indexInBlock, SpecNone, Phantom, origin, childEdge);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         childEdge.setUseKind(KnownCellUse);
</span><span class="cx"> 
</span><del>-        StructureTransitionData* transitionData = 0;
</del><ins>+        Transition* transition = 0;
</ins><span class="cx">         if (variant.kind() == PutByIdVariant::Transition) {
</span><del>-            transitionData = m_graph.addStructureTransitionData(
-                StructureTransitionData(structure, variant.newStructure()));
</del><ins>+            transition = m_graph.m_transitions.add(structure, variant.newStructure());
</ins><span class="cx"> 
</span><span class="cx">             if (node-&gt;op() == PutById) {
</span><span class="cx">                 if (!structure-&gt;storedPrototype().isNull()) {
</span><span class="lines">@@ -446,7 +420,7 @@
</span><span class="cx">             ASSERT(!isInlineOffset(variant.offset()));
</span><span class="cx">             Node* allocatePropertyStorage = m_insertionSet.insertNode(
</span><span class="cx">                 indexInBlock, SpecNone, AllocatePropertyStorage,
</span><del>-                origin, OpInfo(transitionData), childEdge);
</del><ins>+                origin, OpInfo(transition), childEdge);
</ins><span class="cx">             m_insertionSet.insertNode(indexInBlock, SpecNone, StoreBarrier, origin, Edge(node-&gt;child1().node(), KnownCellUse));
</span><span class="cx">             propertyStorage = Edge(allocatePropertyStorage);
</span><span class="cx">         } else {
</span><span class="lines">@@ -456,7 +430,7 @@
</span><span class="cx"> 
</span><span class="cx">             Node* reallocatePropertyStorage = m_insertionSet.insertNode(
</span><span class="cx">                 indexInBlock, SpecNone, ReallocatePropertyStorage, origin,
</span><del>-                OpInfo(transitionData), childEdge,
</del><ins>+                OpInfo(transition), childEdge,
</ins><span class="cx">                 Edge(m_insertionSet.insertNode(
</span><span class="cx">                     indexInBlock, SpecNone, GetButterfly, origin, childEdge)));
</span><span class="cx">             m_insertionSet.insertNode(indexInBlock, SpecNone, StoreBarrier, origin, Edge(node-&gt;child1().node(), KnownCellUse));
</span><span class="lines">@@ -464,7 +438,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (variant.kind() == PutByIdVariant::Transition) {
</span><del>-            Node* putStructure = m_graph.addNode(SpecNone, PutStructure, origin, OpInfo(transitionData), childEdge);
</del><ins>+            Node* putStructure = m_graph.addNode(SpecNone, PutStructure, origin, OpInfo(transition), childEdge);
</ins><span class="cx">             m_insertionSet.insertNode(indexInBlock, SpecNone, StoreBarrier, origin, Edge(node-&gt;child1().node(), KnownCellUse));
</span><span class="cx">             m_insertionSet.insert(indexInBlock, putStructure);
</span><span class="cx">         }
</span><span class="lines">@@ -482,16 +456,12 @@
</span><span class="cx"> 
</span><span class="cx">     void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell)
</span><span class="cx">     {
</span><ins>+        if (m_graph.watchpoints().consider(cell-&gt;structure()))
+            return;
+
</ins><span class="cx">         Node* weakConstant = m_insertionSet.insertNode(
</span><span class="cx">             indexInBlock, speculationFromValue(cell), WeakJSConstant, origin, OpInfo(cell));
</span><span class="cx">         
</span><del>-        if (m_graph.watchpoints().isStillValid(cell-&gt;structure()-&gt;transitionWatchpointSet())) {
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
-                OpInfo(cell-&gt;structure()), Edge(weakConstant, CellUse));
-            return;
-        }
-
</del><span class="cx">         m_insertionSet.insertNode(
</span><span class="cx">             indexInBlock, SpecNone, CheckStructure, origin,
</span><span class="cx">             OpInfo(m_graph.addStructureSet(cell-&gt;structure())), Edge(weakConstant, CellUse));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWatchpointscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</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">@@ -62,16 +62,14 @@
</span><span class="cx">     m_bufferViews.addLazily(view);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSet* set)
</del><ins>+bool DesiredWatchpoints::consider(Structure* structure)
</ins><span class="cx"> {
</span><del>-    m_sets.addLazily(codeOrigin, exitKind, set);
</del><ins>+    if (!structure-&gt;dfgShouldWatch())
+        return false;
+    addLazily(structure-&gt;transitionWatchpointSet());
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, InlineWatchpointSet&amp; set)
-{
-    m_inlineSets.addLazily(codeOrigin, exitKind, &amp;set);
-}
-
</del><span class="cx"> void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, CommonData&amp; commonData)
</span><span class="cx"> {
</span><span class="cx">     m_sets.reallyAdd(codeBlock, commonData);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWatchpointsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h        2014-07-23 01:19:50 UTC (rev 171380)
</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">@@ -39,26 +39,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><del>-template&lt;typename WatchpointSetType&gt;
-struct WatchpointForGenericWatchpointSet {
-    WatchpointForGenericWatchpointSet()
-        : m_exitKind(ExitKindUnset)
-        , m_set(0)
-    {
-    }
-    
-    WatchpointForGenericWatchpointSet(
-        CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSetType* set)
-        : m_codeOrigin(codeOrigin)
-        , m_exitKind(exitKind)
-        , m_set(set)
-    {
-    }
-    
-    CodeOrigin m_codeOrigin;
-    ExitKind m_exitKind;
-    WatchpointSetType* m_set;
-};
</del><ins>+class Graph;
</ins><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> struct GenericSetAdaptor {
</span><span class="lines">@@ -95,12 +76,6 @@
</span><span class="cx">         m_sets.add(set);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSetType* set)
-    {
-        m_profiledWatchpoints.append(
-            WatchpointForGenericWatchpointSet&lt;WatchpointSetType&gt;(codeOrigin, exitKind, set));
-    }
-    
</del><span class="cx">     void reallyAdd(CodeBlock* codeBlock, CommonData&amp; common)
</span><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(!m_reallyAdded);
</span><span class="lines">@@ -112,14 +87,6 @@
</span><span class="cx">             Adaptor::add(codeBlock, *iter, &amp;common.watchpoints.last());
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        for (unsigned i = m_profiledWatchpoints.size(); i--;) {
-            WatchpointForGenericWatchpointSet&lt;WatchpointSetType&gt; watchpoint =
-                m_profiledWatchpoints[i];
-            common.profiledWatchpoints.append(
-                ProfiledCodeBlockJettisoningWatchpoint(watchpoint.m_codeOrigin, watchpoint.m_exitKind, codeBlock));
-            Adaptor::add(codeBlock, watchpoint.m_set, &amp;common.profiledWatchpoints.last());
-        }
-        
</del><span class="cx">         m_reallyAdded = true;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -132,53 +99,16 @@
</span><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        for (unsigned i = m_profiledWatchpoints.size(); i--;) {
-            if (Adaptor::hasBeenInvalidated(m_profiledWatchpoints[i].m_set))
-                return false;
-        }
-        
</del><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-#if ASSERT_DISABLED
-    bool isStillValid(WatchpointSetType* set)
</del><ins>+    bool isWatched(WatchpointSetType* set) const
</ins><span class="cx">     {
</span><del>-        return !Adaptor::hasBeenInvalidated(set);
</del><ins>+        return m_sets.contains(set);
</ins><span class="cx">     }
</span><del>-    
-    bool shouldAssumeMixedState(WatchpointSetType*)
-    {
-        return true;
-    }
-#else
-    bool isStillValid(WatchpointSetType* set)
-    {
-        bool result = !Adaptor::hasBeenInvalidated(set);
-        m_firstKnownState.add(set, result);
-        return result;
-    }
-    
-    bool shouldAssumeMixedState(WatchpointSetType* set)
-    {
-        typename StateMap::iterator iter = m_firstKnownState.find(set);
-        if (iter == m_firstKnownState.end())
-            return false;
-        
-        return iter-&gt;value != !Adaptor::hasBeenInvalidated(set);
-    }
-#endif
-    
-    bool isValidOrMixed(WatchpointSetType* set)
-    {
-        return isStillValid(set) || shouldAssumeMixedState(set);
-    }
</del><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    Vector&lt;WatchpointForGenericWatchpointSet&lt;WatchpointSetType&gt;&gt; m_profiledWatchpoints;
</del><span class="cx">     HashSet&lt;WatchpointSetType*&gt; m_sets;
</span><del>-#if !ASSERT_DISABLED
-    StateMap m_firstKnownState;
-#endif
</del><span class="cx">     bool m_reallyAdded;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -190,49 +120,25 @@
</span><span class="cx">     void addLazily(WatchpointSet*);
</span><span class="cx">     void addLazily(InlineWatchpointSet&amp;);
</span><span class="cx">     void addLazily(JSArrayBufferView*);
</span><del>-    void addLazily(CodeOrigin, ExitKind, WatchpointSet*);
-    void addLazily(CodeOrigin, ExitKind, InlineWatchpointSet&amp;);
</del><span class="cx">     
</span><ins>+    bool consider(Structure*);
+    
</ins><span class="cx">     void reallyAdd(CodeBlock*, CommonData&amp;);
</span><span class="cx">     
</span><span class="cx">     bool areStillValid() const;
</span><span class="cx">     
</span><del>-    bool isStillValid(WatchpointSet* set)
</del><ins>+    bool isWatched(WatchpointSet* set)
</ins><span class="cx">     {
</span><del>-        return m_sets.isStillValid(set);
</del><ins>+        return m_sets.isWatched(set);
</ins><span class="cx">     }
</span><del>-    bool isStillValid(InlineWatchpointSet&amp; set)
</del><ins>+    bool isWatched(InlineWatchpointSet&amp; set)
</ins><span class="cx">     {
</span><del>-        return m_inlineSets.isStillValid(&amp;set);
</del><ins>+        return m_inlineSets.isWatched(&amp;set);
</ins><span class="cx">     }
</span><del>-    bool isStillValid(JSArrayBufferView* view)
</del><ins>+    bool isWatched(JSArrayBufferView* view)
</ins><span class="cx">     {
</span><del>-        return m_bufferViews.isStillValid(view);
</del><ins>+        return m_bufferViews.isWatched(view);
</ins><span class="cx">     }
</span><del>-    bool shouldAssumeMixedState(WatchpointSet* set)
-    {
-        return m_sets.shouldAssumeMixedState(set);
-    }
-    bool shouldAssumeMixedState(InlineWatchpointSet&amp; set)
-    {
-        return m_inlineSets.shouldAssumeMixedState(&amp;set);
-    }
-    bool shouldAssumeMixedState(JSArrayBufferView* view)
-    {
-        return m_bufferViews.shouldAssumeMixedState(view);
-    }
-    bool isValidOrMixed(WatchpointSet* set)
-    {
-        return m_sets.isValidOrMixed(set);
-    }
-    bool isValidOrMixed(InlineWatchpointSet&amp; set)
-    {
-        return m_inlineSets.isValidOrMixed(&amp;set);
-    }
-    bool isValidOrMixed(JSArrayBufferView* view)
-    {
-        return m_bufferViews.isValidOrMixed(view);
-    }
</del><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     GenericDesiredWatchpoints&lt;WatchpointSet&gt; m_sets;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,232 @@
</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;DFGDoesGC.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGGraph.h&quot;
+#include &quot;DFGNode.h&quot;
+#include &quot;Operations.h&quot;
+
+namespace JSC { namespace DFG {
+
+bool doesGC(Graph&amp; graph, Node* node)
+{
+    if (graph.clobbersWorld(node))
+        return true;
+    
+    // Now consider nodes that don't clobber the world but that still may GC. This includes all
+    // nodes. By convention we put world-clobbering nodes in the block of &quot;false&quot; cases but we can
+    // put them anywhere.
+    switch (node-&gt;op()) {
+    case JSConstant:
+    case DoubleConstant:
+    case Int52Constant:
+    case WeakJSConstant:
+    case Identity:
+    case GetCallee:
+    case GetLocal:
+    case SetLocal:
+    case MovHint:
+    case ZombieHint:
+    case GetArgument:
+    case Phantom:
+    case HardPhantom:
+    case Upsilon:
+    case Phi:
+    case Flush:
+    case PhantomLocal:
+    case GetLocalUnlinked:
+    case SetArgument:
+    case BitAnd:
+    case BitOr:
+    case BitXor:
+    case BitLShift:
+    case BitRShift:
+    case BitURShift:
+    case ValueToInt32:
+    case UInt32ToNumber:
+    case DoubleAsInt32:
+    case ArithAdd:
+    case ArithSub:
+    case ArithNegate:
+    case ArithMul:
+    case ArithIMul:
+    case ArithDiv:
+    case ArithMod:
+    case ArithAbs:
+    case ArithMin:
+    case ArithMax:
+    case ArithSqrt:
+    case ArithFRound:
+    case ArithSin:
+    case ArithCos:
+    case ValueAdd:
+    case GetById:
+    case GetByIdFlush:
+    case PutById:
+    case PutByIdFlush:
+    case PutByIdDirect:
+    case CheckStructure:
+    case CheckExecutable:
+    case GetButterfly:
+    case CheckArray:
+    case GetScope:
+    case GetMyScope:
+    case SkipTopScope:
+    case SkipScope:
+    case GetClosureRegisters:
+    case GetClosureVar:
+    case PutClosureVar:
+    case GetGlobalVar:
+    case PutGlobalVar:
+    case VariableWatchpoint:
+    case VarInjectionWatchpoint:
+    case CheckFunction:
+    case AllocationProfileWatchpoint:
+    case RegExpExec:
+    case RegExpTest:
+    case CompareLess:
+    case CompareLessEq:
+    case CompareGreater:
+    case CompareGreaterEq:
+    case CompareEq:
+    case CompareEqConstant:
+    case CompareStrictEq:
+    case Call:
+    case Construct:
+    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
+    case CheckHasInstance:
+    case InstanceOf:
+    case IsUndefined:
+    case IsBoolean:
+    case IsNumber:
+    case IsString:
+    case IsObject:
+    case IsFunction:
+    case TypeOf:
+    case LogicalNot:
+    case ToPrimitive:
+    case ToString:
+    case In:
+    case TearOffActivation:
+    case PhantomArguments:
+    case TearOffArguments:
+    case GetMyArgumentsLength:
+    case GetMyArgumentByVal:
+    case GetMyArgumentsLengthSafe:
+    case GetMyArgumentByValSafe:
+    case CheckArgumentsNotCreated:
+    case Jump:
+    case Branch:
+    case Switch:
+    case Return:
+    case Throw:
+    case CountExecution:
+    case ForceOSRExit:
+    case CheckWatchdogTimer:
+    case StringFromCharCode:
+    case Unreachable:
+    case ExtractOSREntryLocal:
+    case CheckTierUpInLoop:
+    case CheckTierUpAtReturn:
+    case CheckTierUpAndOSREnter:
+    case LoopHint:
+    case StoreBarrier:
+    case StoreBarrierWithNullCheck:
+    case InvalidationPoint:
+    case NotifyWrite:
+    case FunctionReentryWatchpoint:
+    case TypedArrayWatchpoint:
+    case CheckInBounds:
+    case ConstantStoragePointer:
+    case Check:
+    case MultiGetByOffset:
+    case ValueRep:
+    case DoubleRep:
+    case Int52Rep:
+    case GetGetter:
+    case GetSetter:
+    case GetByVal:
+    case GetIndexedPropertyStorage:
+    case GetArrayLength:
+    case ArrayPush:
+    case ArrayPop:
+    case StringCharAt:
+    case StringCharCodeAt:
+    case GetTypedArrayByteOffset:
+    case PutByValDirect:
+    case PutByVal:
+    case PutByValAlias:
+    case PutStructure:
+    case PhantomPutStructure:
+    case GetByOffset:
+    case GetGetterSetterByOffset:
+    case PutByOffset:
+    case FiatInt52:
+    case BooleanToNumber:
+        return false;
+
+    case CreateActivation:
+    case CreateArguments:
+    case ToThis:
+    case CreateThis:
+    case AllocatePropertyStorage:
+    case ReallocatePropertyStorage:
+    case Arrayify:
+    case ArrayifyToStructure:
+    case NewObject:
+    case NewArray:
+    case NewArrayWithSize:
+    case NewArrayBuffer:
+    case NewRegexp:
+    case NewStringObject:
+    case MakeRope:
+    case NewFunctionNoCheck:
+    case NewFunction:
+    case NewFunctionExpression:
+    case NewTypedArray:
+    case ThrowReferenceError:
+        return true;
+        
+    case MultiPutByOffset:
+        return node-&gt;multiPutByOffsetData().reallocatesStorage();
+
+    case LastNodeType:
+        RELEASE_ASSERT_NOT_REACHED();
+        return true;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return true;
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.h (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,43 @@
</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 DFGDoesGC_h
+#define DFGDoesGC_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+struct Node;
+
+bool doesGC(Graph&amp;, Node*);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGDoesGC_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -927,7 +927,6 @@
</span><span class="cx"> 
</span><span class="cx">         case CheckExecutable:
</span><span class="cx">         case CheckStructure:
</span><del>-        case StructureTransitionWatchpoint:
</del><span class="cx">         case CheckFunction:
</span><span class="cx">         case CheckHasInstance:
</span><span class="cx">         case CreateThis:
</span><span class="lines">@@ -1357,7 +1356,7 @@
</span><span class="cx">         
</span><span class="cx">         JSObject* stringPrototypeObject = asObject(stringObjectStructure-&gt;storedPrototype());
</span><span class="cx">         Structure* stringPrototypeStructure = stringPrototypeObject-&gt;structure();
</span><del>-        if (!m_graph.watchpoints().isStillValid(stringPrototypeStructure-&gt;transitionWatchpointSet()))
</del><ins>+        if (!m_graph.watchpoints().consider(stringPrototypeStructure))
</ins><span class="cx">             return false;
</span><span class="cx">         
</span><span class="cx">         if (stringPrototypeStructure-&gt;isDictionary())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -77,6 +77,16 @@
</span><span class="cx"> 
</span><span class="cx"> Graph::~Graph()
</span><span class="cx"> {
</span><ins>+    for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
+        BasicBlock* block = this-&gt;block(blockIndex);
+        if (!block)
+            continue;
+
+        for (unsigned phiIndex = block-&gt;phis.size(); phiIndex--;)
+            m_allocator.free(block-&gt;phis[phiIndex]);
+        for (unsigned nodeIndex = block-&gt;size(); nodeIndex--;)
+            m_allocator.free(block-&gt;at(nodeIndex));
+    }
</ins><span class="cx">     m_allocator.freeAll();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -211,8 +221,8 @@
</span><span class="cx">         out.print(comma, inContext(node-&gt;structureSet(), context));
</span><span class="cx">     if (node-&gt;hasStructure())
</span><span class="cx">         out.print(comma, inContext(*node-&gt;structure(), context));
</span><del>-    if (node-&gt;hasStructureTransitionData())
-        out.print(comma, inContext(*node-&gt;structureTransitionData().previousStructure, context), &quot; -&gt; &quot;, inContext(*node-&gt;structureTransitionData().newStructure, context));
</del><ins>+    if (node-&gt;hasTransition())
+        out.print(comma, pointerDumpInContext(node-&gt;transition(), context));
</ins><span class="cx">     if (node-&gt;hasFunction()) {
</span><span class="cx">         out.print(comma, &quot;function(&quot;, RawPointer(node-&gt;function()), &quot;, &quot;);
</span><span class="cx">         if (node-&gt;function()-&gt;inherits(JSFunction::info())) {
</span><span class="lines">@@ -338,9 +348,11 @@
</span><span class="cx">         out.print(comma, &quot;R:&quot;, sortedListDump(reads.direct(), &quot;,&quot;));
</span><span class="cx">     if (!writes.isEmpty())
</span><span class="cx">         out.print(comma, &quot;W:&quot;, sortedListDump(writes.direct(), &quot;,&quot;));
</span><del>-    out.print(comma, &quot;bc#&quot;, node-&gt;origin.semantic.bytecodeIndex);
-    if (node-&gt;origin.semantic != node-&gt;origin.forExit)
-        out.print(comma, &quot;exit: &quot;, node-&gt;origin.forExit);
</del><ins>+    if (node-&gt;origin.isSet()) {
+        out.print(comma, &quot;bc#&quot;, node-&gt;origin.semantic.bytecodeIndex);
+        if (node-&gt;origin.semantic != node-&gt;origin.forExit)
+            out.print(comma, &quot;exit: &quot;, node-&gt;origin.forExit);
+    }
</ins><span class="cx">     
</span><span class="cx">     out.print(&quot;)&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -356,7 +368,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Graph::dumpBlockHeader(PrintStream&amp; out, const char* prefix, BasicBlock* block, PhiNodeDumpMode phiNodeDumpMode, DumpContext* context)
</span><span class="cx"> {
</span><del>-    out.print(prefix, &quot;Block &quot;, *block, &quot; (&quot;, inContext(block-&gt;at(0)-&gt;origin.semantic, context), &quot;): &quot;, block-&gt;isReachable ? &quot;&quot; : &quot;(skipped)&quot;, block-&gt;isOSRTarget ? &quot; (OSR target)&quot; : &quot;&quot;, &quot;\n&quot;);
</del><ins>+    out.print(prefix, &quot;Block &quot;, *block, &quot; (&quot;, inContext(block-&gt;at(0)-&gt;origin.semantic, context), &quot;):&quot;, block-&gt;isReachable ? &quot;&quot; : &quot; (skipped)&quot;, block-&gt;isOSRTarget ? &quot; (OSR target)&quot; : &quot;&quot;, block-&gt;cfaHasVisited ? &quot;&quot; : &quot; (CFA-unreachable)&quot;, &quot;\n&quot;);
</ins><span class="cx">     if (block-&gt;executionCount == block-&gt;executionCount)
</span><span class="cx">         out.print(prefix, &quot;  Execution count: &quot;, block-&gt;executionCount, &quot;\n&quot;);
</span><span class="cx">     out.print(prefix, &quot;  Predecessors:&quot;);
</span><span class="lines">@@ -439,16 +451,17 @@
</span><span class="cx">         if (!block)
</span><span class="cx">             continue;
</span><span class="cx">         dumpBlockHeader(out, &quot;&quot;, block, DumpAllPhis, context);
</span><ins>+        out.print(&quot;  States: &quot;, block-&gt;cfaStructureClobberStateAtHead, &quot;\n&quot;);
</ins><span class="cx">         switch (m_form) {
</span><span class="cx">         case LoadStore:
</span><span class="cx">         case ThreadedCPS: {
</span><del>-            out.print(&quot;  vars before: &quot;);
</del><ins>+            out.print(&quot;  Vars Before: &quot;);
</ins><span class="cx">             if (block-&gt;cfaHasVisited)
</span><span class="cx">                 out.print(inContext(block-&gt;valuesAtHead, context));
</span><span class="cx">             else
</span><span class="cx">                 out.print(&quot;&lt;empty&gt;&quot;);
</span><span class="cx">             out.print(&quot;\n&quot;);
</span><del>-            out.print(&quot;  var links: &quot;, block-&gt;variablesAtHead, &quot;\n&quot;);
</del><ins>+            out.print(&quot;  Var Links: &quot;, block-&gt;variablesAtHead, &quot;\n&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="lines">@@ -464,16 +477,17 @@
</span><span class="cx">             dump(out, &quot;&quot;, block-&gt;at(i), context);
</span><span class="cx">             lastNode = block-&gt;at(i);
</span><span class="cx">         }
</span><ins>+        out.print(&quot;  States: &quot;, block-&gt;cfaBranchDirection, &quot;, &quot;, block-&gt;cfaStructureClobberStateAtTail, &quot;\n&quot;);
</ins><span class="cx">         switch (m_form) {
</span><span class="cx">         case LoadStore:
</span><span class="cx">         case ThreadedCPS: {
</span><del>-            out.print(&quot;  vars after: &quot;);
</del><ins>+            out.print(&quot;  Vars After: &quot;);
</ins><span class="cx">             if (block-&gt;cfaHasVisited)
</span><span class="cx">                 out.print(inContext(block-&gt;valuesAtTail, context));
</span><span class="cx">             else
</span><span class="cx">                 out.print(&quot;&lt;empty&gt;&quot;);
</span><span class="cx">             out.print(&quot;\n&quot;);
</span><del>-            out.print(&quot;  var links: &quot;, block-&gt;variablesAtTail, &quot;\n&quot;);
</del><ins>+            out.print(&quot;  Var Links: &quot;, block-&gt;variablesAtTail, &quot;\n&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="lines">@@ -800,8 +814,9 @@
</span><span class="cx">     JSArrayBufferView* view = jsDynamicCast&lt;JSArrayBufferView*&gt;(valueOfJSConstant(node));
</span><span class="cx">     if (!view)
</span><span class="cx">         return 0;
</span><del>-    if (!watchpoints().isStillValid(view))
</del><ins>+    if (!view-&gt;length())
</ins><span class="cx">         return 0;
</span><ins>+    WTF::loadLoadFence();
</ins><span class="cx">     return view;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -846,7 +861,6 @@
</span><span class="cx">                     visitor.appendUnbarrieredReadOnlyPointer(node-&gt;structureSet()[i]);
</span><span class="cx">                 break;
</span><span class="cx">                 
</span><del>-            case StructureTransitionWatchpoint:
</del><span class="cx">             case NewObject:
</span><span class="cx">             case ArrayifyToStructure:
</span><span class="cx">             case NewStringObject:
</span><span class="lines">@@ -858,11 +872,36 @@
</span><span class="cx">             case AllocatePropertyStorage:
</span><span class="cx">             case ReallocatePropertyStorage:
</span><span class="cx">                 visitor.appendUnbarrieredReadOnlyPointer(
</span><del>-                    node-&gt;structureTransitionData().previousStructure);
</del><ins>+                    node-&gt;transition()-&gt;previous);
</ins><span class="cx">                 visitor.appendUnbarrieredReadOnlyPointer(
</span><del>-                    node-&gt;structureTransitionData().newStructure);
</del><ins>+                    node-&gt;transition()-&gt;next);
</ins><span class="cx">                 break;
</span><span class="cx">                 
</span><ins>+            case MultiGetByOffset:
+                for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;) {
+                    GetByIdVariant&amp; variant = node-&gt;multiGetByOffsetData().variants[i];
+                    visitor.appendUnbarrieredReadOnlyValue(variant.specificValue());
+                    const StructureSet&amp; set = variant.structureSet();
+                    for (unsigned j = set.size(); j--;)
+                        visitor.appendUnbarrieredReadOnlyPointer(set[j]);
+
+                    // Don't need to mark anything in the structure chain because that would
+                    // have been decomposed into CheckStructure's. Don't need to mark the
+                    // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
+                    // variants did that.
+                    ASSERT(!variant.callLinkStatus());
+                }
+                break;
+                    
+            case MultiPutByOffset:
+                for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
+                    PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
+                    visitor.appendUnbarrieredReadOnlyPointer(variant.oldStructure());
+                    if (variant.kind() == PutByIdVariant::Transition)
+                        visitor.appendUnbarrieredReadOnlyPointer(variant.newStructure());
+                }
+                break;
+                
</ins><span class="cx">             default:
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -870,6 +909,35 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Graph::assertIsWatched(Structure* structure)
+{
+    if (!structure-&gt;dfgShouldWatch())
+        return;
+    if (watchpoints().isWatched(structure-&gt;transitionWatchpointSet()))
+        return;
+    
+    DFG_CRASH(*this, nullptr, toCString(&quot;Structure &quot;, pointerDump(structure), &quot; is watchable but isn't being watched.&quot;).data());
+}
+
+void Graph::handleAssertionFailure(
+    Node* node, const char* file, int line, const char* function, const char* assertion)
+{
+    startCrashing();
+    dataLog(&quot;DFG ASSERTION FAILED: &quot;, assertion, &quot;\n&quot;);
+    dataLog(file, &quot;(&quot;, line, &quot;) : &quot;, function, &quot;\n&quot;);
+    dataLog(&quot;\n&quot;);
+    if (node) {
+        dataLog(&quot;While handling node &quot;, node, &quot;\n&quot;);
+        dataLog(&quot;\n&quot;);
+    }
+    dataLog(&quot;Graph at time of failure:\n&quot;);
+    dump();
+    dataLog(&quot;\n&quot;);
+    dataLog(&quot;DFG ASSERTION FAILED: &quot;, assertion, &quot;\n&quot;);
+    dataLog(file, &quot;(&quot;, line, &quot;) : &quot;, function, &quot;\n&quot;);
+    CRASH();
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -170,8 +170,12 @@
</span><span class="cx">         return constantRegister;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void assertIsWatched(Structure* structure);
+    
</ins><span class="cx">     void convertToConstant(Node* node, JSValue value)
</span><span class="cx">     {
</span><ins>+        if (value.isCell())
+            assertIsWatched(value.asCell()-&gt;structure());
</ins><span class="cx">         if (value.isObject())
</span><span class="cx">             node-&gt;convertToWeakConstant(value.asCell());
</span><span class="cx">         else
</span><span class="lines">@@ -406,12 +410,6 @@
</span><span class="cx">         return &amp;m_structureSet.last();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StructureTransitionData* addStructureTransitionData(const StructureTransitionData&amp; structureTransitionData)
-    {
-        m_structureTransitionData.append(structureTransitionData);
-        return &amp;m_structureTransitionData.last();
-    }
-    
</del><span class="cx">     JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin)
</span><span class="cx">     {
</span><span class="cx">         return m_codeBlock-&gt;globalObjectFor(codeOrigin);
</span><span class="lines">@@ -462,8 +460,7 @@
</span><span class="cx">     
</span><span class="cx">     bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin&amp; codeOrigin)
</span><span class="cx">     {
</span><del>-        return m_plan.watchpoints.isStillValid(
-            globalObjectFor(codeOrigin)-&gt;masqueradesAsUndefinedWatchpoint());
</del><ins>+        return globalObjectFor(codeOrigin)-&gt;masqueradesAsUndefinedWatchpoint()-&gt;isStillValid();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasGlobalExitSite(const CodeOrigin&amp; codeOrigin, ExitKind exitKind)
</span><span class="lines">@@ -823,6 +820,10 @@
</span><span class="cx">     
</span><span class="cx">     virtual void visitChildren(SlotVisitor&amp;) override;
</span><span class="cx">     
</span><ins>+    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
+        Node* node, const char* file, int line, const char* function,
+        const char* assertion);
+    
</ins><span class="cx">     VM&amp; m_vm;
</span><span class="cx">     Plan&amp; m_plan;
</span><span class="cx">     CodeBlock* m_codeBlock;
</span><span class="lines">@@ -839,7 +840,7 @@
</span><span class="cx">     SegmentedVector&lt;VariableAccessData, 16&gt; m_variableAccessData;
</span><span class="cx">     SegmentedVector&lt;ArgumentPosition, 8&gt; m_argumentPositions;
</span><span class="cx">     SegmentedVector&lt;StructureSet, 16&gt; m_structureSet;
</span><del>-    SegmentedVector&lt;StructureTransitionData, 8&gt; m_structureTransitionData;
</del><ins>+    Bag&lt;Transition&gt; m_transitions;
</ins><span class="cx">     SegmentedVector&lt;NewArrayBufferData, 4&gt; m_newArrayBufferData;
</span><span class="cx">     Bag&lt;BranchData&gt; m_branchData;
</span><span class="cx">     Bag&lt;SwitchData&gt; m_switchData;
</span><span class="lines">@@ -925,6 +926,17 @@
</span><span class="cx">         }                                                               \
</span><span class="cx">     } while (false)
</span><span class="cx"> 
</span><ins>+#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"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -37,6 +37,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><ins>+static const bool verbose = false;
+
</ins><span class="cx"> InPlaceAbstractState::InPlaceAbstractState(Graph&amp; graph)
</span><span class="cx">     : m_graph(graph)
</span><span class="cx">     , m_variables(m_graph.m_codeBlock-&gt;numParameters(), graph.m_localVars)
</span><span class="lines">@@ -58,36 +60,20 @@
</span><span class="cx">         forNode(basicBlock-&gt;at(i)).clear();
</span><span class="cx"> 
</span><span class="cx">     m_variables = basicBlock-&gt;valuesAtHead;
</span><del>-    m_haveStructures = false;
-    for (size_t i = 0; i &lt; m_variables.numberOfArguments(); ++i) {
-        if (m_variables.argument(i).hasClobberableState()) {
-            m_haveStructures = true;
-            break;
-        }
-    }
-    for (size_t i = 0; i &lt; m_variables.numberOfLocals(); ++i) {
-        if (m_variables.local(i).hasClobberableState()) {
-            m_haveStructures = true;
-            break;
-        }
-    }
</del><span class="cx">     
</span><span class="cx">     if (m_graph.m_form == SSA) {
</span><span class="cx">         HashMap&lt;Node*, AbstractValue&gt;::iterator iter = basicBlock-&gt;ssa-&gt;valuesAtHead.begin();
</span><span class="cx">         HashMap&lt;Node*, AbstractValue&gt;::iterator end = basicBlock-&gt;ssa-&gt;valuesAtHead.end();
</span><del>-        for (; iter != end; ++iter) {
</del><ins>+        for (; iter != end; ++iter)
</ins><span class="cx">             forNode(iter-&gt;key) = iter-&gt;value;
</span><del>-            if (iter-&gt;value.hasClobberableState())
-                m_haveStructures = true;
-        }
</del><span class="cx">     }
</span><del>-    
</del><span class="cx">     basicBlock-&gt;cfaShouldRevisit = false;
</span><span class="cx">     basicBlock-&gt;cfaHasVisited = true;
</span><span class="cx">     m_block = basicBlock;
</span><span class="cx">     m_isValid = true;
</span><span class="cx">     m_foundConstants = false;
</span><span class="cx">     m_branchDirection = InvalidBranchDirection;
</span><ins>+    m_structureClobberState = basicBlock-&gt;cfaStructureClobberStateAtHead;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void setLiveValues(HashMap&lt;Node*, AbstractValue&gt;&amp; values, HashSet&lt;Node*&gt;&amp; live)
</span><span class="lines">@@ -106,6 +92,8 @@
</span><span class="cx">     root-&gt;cfaShouldRevisit = true;
</span><span class="cx">     root-&gt;cfaHasVisited = false;
</span><span class="cx">     root-&gt;cfaFoundConstants = false;
</span><ins>+    root-&gt;cfaStructureClobberStateAtHead = StructuresAreWatched;
+    root-&gt;cfaStructureClobberStateAtTail = StructuresAreWatched;
</ins><span class="cx">     for (size_t i = 0; i &lt; root-&gt;valuesAtHead.numberOfArguments(); ++i) {
</span><span class="cx">         root-&gt;valuesAtTail.argument(i).clear();
</span><span class="cx">         if (m_graph.m_form == SSA) {
</span><span class="lines">@@ -147,6 +135,8 @@
</span><span class="cx">         block-&gt;cfaShouldRevisit = false;
</span><span class="cx">         block-&gt;cfaHasVisited = false;
</span><span class="cx">         block-&gt;cfaFoundConstants = false;
</span><ins>+        block-&gt;cfaStructureClobberStateAtHead = StructuresAreWatched;
+        block-&gt;cfaStructureClobberStateAtTail = StructuresAreWatched;
</ins><span class="cx">         for (size_t i = 0; i &lt; block-&gt;valuesAtHead.numberOfArguments(); ++i) {
</span><span class="cx">             block-&gt;valuesAtHead.argument(i).clear();
</span><span class="cx">             block-&gt;valuesAtTail.argument(i).clear();
</span><span class="lines">@@ -204,6 +194,8 @@
</span><span class="cx">     bool changed = false;
</span><span class="cx">     
</span><span class="cx">     if (mergeMode != DontMerge || !ASSERT_DISABLED) {
</span><ins>+        changed |= checkAndSet(block-&gt;cfaStructureClobberStateAtTail, m_structureClobberState);
+    
</ins><span class="cx">         switch (m_graph.m_form) {
</span><span class="cx">         case ThreadedCPS: {
</span><span class="cx">             for (size_t argument = 0; argument &lt; block-&gt;variablesAtTail.numberOfArguments(); ++argument) {
</span><span class="lines">@@ -251,6 +243,7 @@
</span><span class="cx">     m_block = 0;
</span><span class="cx">     m_isValid = false;
</span><span class="cx">     m_branchDirection = InvalidBranchDirection;
</span><ins>+    m_structureClobberState = StructuresAreWatched;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool InPlaceAbstractState::mergeStateAtTail(AbstractValue&amp; destination, AbstractValue&amp; inVariable, Node* node)
</span><span class="lines">@@ -311,11 +304,17 @@
</span><span class="cx"> 
</span><span class="cx"> bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to)
</span><span class="cx"> {
</span><ins>+    if (verbose)
+        dataLog(&quot;   Merging from &quot;, pointerDump(from), &quot; to &quot;, pointerDump(to), &quot;\n&quot;);
</ins><span class="cx">     ASSERT(from-&gt;variablesAtTail.numberOfArguments() == to-&gt;variablesAtHead.numberOfArguments());
</span><span class="cx">     ASSERT(from-&gt;variablesAtTail.numberOfLocals() == to-&gt;variablesAtHead.numberOfLocals());
</span><span class="cx">     
</span><span class="cx">     bool changed = false;
</span><span class="cx">     
</span><ins>+    changed |= checkAndSet(
+        to-&gt;cfaStructureClobberStateAtHead,
+        DFG::merge(from-&gt;cfaStructureClobberStateAtTail, to-&gt;cfaStructureClobberStateAtHead));
+    
</ins><span class="cx">     switch (m_graph.m_form) {
</span><span class="cx">     case ThreadedCPS: {
</span><span class="cx">         for (size_t argument = 0; argument &lt; from-&gt;variablesAtTail.numberOfArguments(); ++argument) {
</span><span class="lines">@@ -338,8 +337,12 @@
</span><span class="cx">         HashSet&lt;Node*&gt;::iterator end = to-&gt;ssa-&gt;liveAtHead.end();
</span><span class="cx">         for (; iter != end; ++iter) {
</span><span class="cx">             Node* node = *iter;
</span><ins>+            if (verbose)
+                dataLog(&quot;      Merging for &quot;, node, &quot;: from &quot;, from-&gt;ssa-&gt;valuesAtTail.find(node)-&gt;value, &quot; to &quot;, to-&gt;ssa-&gt;valuesAtHead.find(node)-&gt;value, &quot;\n&quot;);
</ins><span class="cx">             changed |= to-&gt;ssa-&gt;valuesAtHead.find(node)-&gt;value.merge(
</span><span class="cx">                 from-&gt;ssa-&gt;valuesAtTail.find(node)-&gt;value);
</span><ins>+            if (verbose)
+                dataLog(&quot;         Result: &quot;, to-&gt;ssa-&gt;valuesAtHead.find(node)-&gt;value, &quot;\n&quot;);
</ins><span class="cx">         }
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -352,6 +355,8 @@
</span><span class="cx">     if (!to-&gt;cfaHasVisited)
</span><span class="cx">         changed = true;
</span><span class="cx">     
</span><ins>+    if (verbose)
+        dataLog(&quot;      Will revisit: &quot;, changed, &quot;\n&quot;);
</ins><span class="cx">     to-&gt;cfaShouldRevisit |= changed;
</span><span class="cx">     
</span><span class="cx">     return changed;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -103,6 +103,9 @@
</span><span class="cx">     // Did the last executed node clobber the world?
</span><span class="cx">     bool didClobber() const { return m_didClobber; }
</span><span class="cx">     
</span><ins>+    // Are structures currently clobbered?
+    StructureClobberState structureClobberState() const { return m_structureClobberState; }
+    
</ins><span class="cx">     // Is the execution state still valid? This will be false if execute() has
</span><span class="cx">     // returned false previously.
</span><span class="cx">     bool isValid() const { return m_isValid; }
</span><span class="lines">@@ -122,11 +125,10 @@
</span><span class="cx">     
</span><span class="cx">     // Methods intended to be called from AbstractInterpreter.
</span><span class="cx">     void setDidClobber(bool didClobber) { m_didClobber = didClobber; }
</span><ins>+    void setStructureClobberState(StructureClobberState value) { m_structureClobberState = value; }
</ins><span class="cx">     void setIsValid(bool isValid) { m_isValid = isValid; }
</span><span class="cx">     void setBranchDirection(BranchDirection branchDirection) { m_branchDirection = branchDirection; }
</span><span class="cx">     void setFoundConstants(bool foundConstants) { m_foundConstants = foundConstants; }
</span><del>-    bool haveStructures() const { return m_haveStructures; } // It's always safe to return true.
-    void setHaveStructures(bool haveStructures) { m_haveStructures = haveStructures; }
</del><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     bool mergeStateAtTail(AbstractValue&amp; destination, AbstractValue&amp; inVariable, Node*);
</span><span class="lines">@@ -138,11 +140,11 @@
</span><span class="cx">     Operands&lt;AbstractValue&gt; m_variables;
</span><span class="cx">     BasicBlock* m_block;
</span><span class="cx">     
</span><del>-    bool m_haveStructures;
</del><span class="cx">     bool m_foundConstants;
</span><span class="cx">     
</span><span class="cx">     bool m_isValid;
</span><span class="cx">     bool m_didClobber;
</span><ins>+    StructureClobberState m_structureClobberState;
</ins><span class="cx">     
</span><span class="cx">     BranchDirection m_branchDirection; // This is only set for blocks that end in Branch and that execute to completion (i.e. m_isValid == true).
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLivenessAnalysisPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -68,13 +68,11 @@
</span><span class="cx">         } while (m_changed);
</span><span class="cx">         
</span><span class="cx">         if (!m_graph.block(0)-&gt;ssa-&gt;liveAtHead.isEmpty()) {
</span><del>-            startCrashing();
-            dataLog(
-                &quot;Bad liveness analysis result: live at root is not empty: &quot;,
-                nodeListDump(m_graph.block(0)-&gt;ssa-&gt;liveAtHead), &quot;\n&quot;);
-            dataLog(&quot;IR at time of error:\n&quot;);
-            m_graph.dump();
-            CRASH();
</del><ins>+            DFG_CRASH(
+                m_graph, nullptr,
+                toCString(
+                    &quot;Bad liveness analysis result: live at root is not empty: &quot;,
+                    nodeListDump(m_graph.block(0)-&gt;ssa-&gt;liveAtHead)).data());
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         return true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-07-23 01:19:50 UTC (rev 171380)
</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;DFGTransition.h&quot;
</ins><span class="cx"> #include &quot;DFGUseKind.h&quot;
</span><span class="cx"> #include &quot;DFGVariableAccessData.h&quot;
</span><span class="cx"> #include &quot;GetByIdVariant.h&quot;
</span><span class="lines">@@ -67,19 +68,6 @@
</span><span class="cx">     bool reallocatesStorage() const;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-struct StructureTransitionData {
-    Structure* previousStructure;
-    Structure* newStructure;
-    
-    StructureTransitionData() { }
-    
-    StructureTransitionData(Structure* previousStructure, Structure* newStructure)
-        : previousStructure(previousStructure)
-        , newStructure(newStructure)
-    {
-    }
-};
-
</del><span class="cx"> struct NewArrayBufferData {
</span><span class="cx">     unsigned startConstant;
</span><span class="cx">     unsigned numConstants;
</span><span class="lines">@@ -485,20 +473,6 @@
</span><span class="cx">         children.reset();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void convertToStructureTransitionWatchpoint(Structure* structure)
-    {
-        ASSERT(m_op == CheckStructure || m_op == ArrayifyToStructure);
-        ASSERT(!child2());
-        ASSERT(!child3());
-        m_opInfo = bitwise_cast&lt;uintptr_t&gt;(structure);
-        m_op = StructureTransitionWatchpoint;
-    }
-    
-    void convertToStructureTransitionWatchpoint()
-    {
-        convertToStructureTransitionWatchpoint(structureSet().singletonStructure());
-    }
-    
</del><span class="cx">     void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
</span><span class="lines">@@ -1101,7 +1075,7 @@
</span><span class="cx">         return reinterpret_cast&lt;void*&gt;(m_opInfo);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool hasStructureTransitionData()
</del><ins>+    bool hasTransition()
</ins><span class="cx">     {
</span><span class="cx">         switch (op()) {
</span><span class="cx">         case PutStructure:
</span><span class="lines">@@ -1114,10 +1088,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StructureTransitionData&amp; structureTransitionData()
</del><ins>+    Transition* transition()
</ins><span class="cx">     {
</span><del>-        ASSERT(hasStructureTransitionData());
-        return *reinterpret_cast&lt;StructureTransitionData*&gt;(m_opInfo);
</del><ins>+        ASSERT(hasTransition());
+        return reinterpret_cast&lt;Transition*&gt;(m_opInfo);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasStructureSet()
</span><span class="lines">@@ -1139,7 +1113,6 @@
</span><span class="cx">     bool hasStructure()
</span><span class="cx">     {
</span><span class="cx">         switch (op()) {
</span><del>-        case StructureTransitionWatchpoint:
</del><span class="cx">         case ArrayifyToStructure:
</span><span class="cx">         case NewObject:
</span><span class="cx">         case NewStringObject:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -158,18 +158,6 @@
</span><span class="cx">     macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
</span><span class="cx">     macro(CheckStructure, NodeMustGenerate) \
</span><span class="cx">     macro(CheckExecutable, NodeMustGenerate) \
</span><del>-    /* Transition watchpoints are a contract between the party setting the watchpoint */\
-    /* and the runtime system, where the party promises that the child object once had */\
-    /* the structure being watched, and the runtime system in turn promises that the */\
-    /* watchpoint will be turned into an OSR exit if any object with that structure */\
-    /* ever transitions to a different structure. Hence, the child object must have */\
-    /* previously had a CheckStructure executed on it or we're dealing with an object */\
-    /* constant (WeakJSConstant) and the object was known to have that structure at */\
-    /* compile-time. In the latter case this means that no structure checks have to be */\
-    /* performed for this object by JITted code. In the former case this means that*/\
-    /* the object's structure does not need to be rechecked due to side-effecting */\
-    /* (clobbering) operations. */\
-    macro(StructureTransitionWatchpoint, NodeMustGenerate) \
</del><span class="cx">     macro(PutStructure, NodeMustGenerate) \
</span><span class="cx">     macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
</span><span class="cx">     macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx"> #include &quot;DFGUnificationPhase.h&quot;
</span><span class="cx"> #include &quot;DFGValidate.h&quot;
</span><span class="cx"> #include &quot;DFGVirtualRegisterAllocationPhase.h&quot;
</span><ins>+#include &quot;DFGWatchableStructureWatchingPhase.h&quot;
</ins><span class="cx"> #include &quot;DFGWatchpointCollectionPhase.h&quot;
</span><span class="cx"> #include &quot;Debugger.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -234,6 +235,7 @@
</span><span class="cx">     performBackwardsPropagation(dfg);
</span><span class="cx">     performPredictionPropagation(dfg);
</span><span class="cx">     performFixup(dfg);
</span><ins>+    performWatchableStructureWatching(dfg);
</ins><span class="cx">     performInvalidationPointInjection(dfg);
</span><span class="cx">     performTypeCheckHoisting(dfg);
</span><span class="cx">     
</span><span class="lines">@@ -311,6 +313,11 @@
</span><span class="cx">         performSSAConversion(dfg);
</span><span class="cx">         performSSALowering(dfg);
</span><span class="cx">         performCSE(dfg);
</span><ins>+        
+        // At this point we're not allowed to do any further code motion because our reasoning
+        // about code motion assumes that it's OK to insert GC points in random places.
+        
+        performStoreBarrierElision(dfg);
</ins><span class="cx">         performLivenessAnalysis(dfg);
</span><span class="cx">         performCFA(dfg);
</span><span class="cx">         performLICM(dfg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -610,7 +610,6 @@
</span><span class="cx">         case SetArgument:
</span><span class="cx">         case CheckStructure:
</span><span class="cx">         case CheckExecutable:
</span><del>-        case StructureTransitionWatchpoint:
</del><span class="cx">         case CheckFunction:
</span><span class="cx">         case PutStructure:
</span><span class="cx">         case TearOffActivation:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -279,22 +279,26 @@
</span><span class="cx">         return node-&gt;arrayMode().modeForPut().alreadyChecked(
</span><span class="cx">             graph, node, state.forNode(graph.varArgChild(node, 0)));
</span><span class="cx"> 
</span><del>-    case StructureTransitionWatchpoint:
-        return state.forNode(node-&gt;child1()).m_futurePossibleStructure.isSubsetOf(
-            StructureSet(node-&gt;structure()));
-        
</del><span class="cx">     case PutStructure:
</span><span class="cx">     case PhantomPutStructure:
</span><span class="cx">     case AllocatePropertyStorage:
</span><span class="cx">     case ReallocatePropertyStorage:
</span><del>-        return state.forNode(node-&gt;child1()).m_currentKnownStructure.isSubsetOf(
-            StructureSet(node-&gt;structureTransitionData().previousStructure));
</del><ins>+        return state.forNode(node-&gt;child1()).m_structure.isSubsetOf(
+            StructureSet(node-&gt;transition()-&gt;previous));
</ins><span class="cx">         
</span><span class="cx">     case GetByOffset:
</span><span class="cx">     case GetGetterSetterByOffset:
</span><del>-    case PutByOffset:
-        return state.forNode(node-&gt;child1()).m_currentKnownStructure.isValidOffset(
-            graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].offset);
</del><ins>+    case PutByOffset: {
+        StructureAbstractValue&amp; value = state.forNode(node-&gt;child1()).m_structure;
+        if (value.isTop())
+            return false;
+        PropertyOffset offset = graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].offset;
+        for (unsigned i = value.size(); i--;) {
+            if (!value[i]-&gt;isValidOffset(offset))
+                return false;
+        }
+        return true;
+    }
</ins><span class="cx">         
</span><span class="cx">     case LastNodeType:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -4220,7 +4220,7 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileAllocatePropertyStorage(Node* node)
</span><span class="cx"> {
</span><del>-    if (node-&gt;structureTransitionData().previousStructure-&gt;couldHaveIndexingHeader()) {
</del><ins>+    if (node-&gt;transition()-&gt;previous-&gt;couldHaveIndexingHeader()) {
</ins><span class="cx">         SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="cx">         
</span><span class="cx">         GPRReg baseGPR = base.gpr();
</span><span class="lines">@@ -4240,8 +4240,8 @@
</span><span class="cx">     GPRReg baseGPR = base.gpr();
</span><span class="cx">     GPRReg scratchGPR1 = scratch1.gpr();
</span><span class="cx">         
</span><del>-    ASSERT(!node-&gt;structureTransitionData().previousStructure-&gt;outOfLineCapacity());
-    ASSERT(initialOutOfLineCapacity == node-&gt;structureTransitionData().newStructure-&gt;outOfLineCapacity());
</del><ins>+    ASSERT(!node-&gt;transition()-&gt;previous-&gt;outOfLineCapacity());
+    ASSERT(initialOutOfLineCapacity == node-&gt;transition()-&gt;next-&gt;outOfLineCapacity());
</ins><span class="cx">     
</span><span class="cx">     JITCompiler::Jump slowPath =
</span><span class="cx">         emitAllocateBasicStorage(
</span><span class="lines">@@ -4259,11 +4259,11 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileReallocatePropertyStorage(Node* node)
</span><span class="cx"> {
</span><del>-    size_t oldSize = node-&gt;structureTransitionData().previousStructure-&gt;outOfLineCapacity() * sizeof(JSValue);
</del><ins>+    size_t oldSize = node-&gt;transition()-&gt;previous-&gt;outOfLineCapacity() * sizeof(JSValue);
</ins><span class="cx">     size_t newSize = oldSize * outOfLineGrowthFactor;
</span><del>-    ASSERT(newSize == node-&gt;structureTransitionData().newStructure-&gt;outOfLineCapacity() * sizeof(JSValue));
</del><ins>+    ASSERT(newSize == node-&gt;transition()-&gt;next-&gt;outOfLineCapacity() * sizeof(JSValue));
</ins><span class="cx"> 
</span><del>-    if (node-&gt;structureTransitionData().previousStructure-&gt;couldHaveIndexingHeader()) {
</del><ins>+    if (node-&gt;transition()-&gt;previous-&gt;couldHaveIndexingHeader()) {
</ins><span class="cx">         SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="cx">         
</span><span class="cx">         GPRReg baseGPR = base.gpr();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -3130,7 +3130,7 @@
</span><span class="cx">     Structure* stringObjectStructure =
</span><span class="cx">         m_jit.globalObjectFor(m_currentNode-&gt;origin.semantic)-&gt;stringObjectStructure();
</span><span class="cx">     
</span><del>-    if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(stringObjectStructure))) {
</del><ins>+    if (!m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure))) {
</ins><span class="cx">         speculationCheck(
</span><span class="cx">             NotStringObject, JSValueRegs(), 0,
</span><span class="cx">             m_jit.branchStructurePtr(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -3739,29 +3739,6 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case StructureTransitionWatchpoint: {
-        // There is a fascinating question here of what to do about array profiling.
-        // We *could* try to tell the OSR exit about where the base of the access is.
-        // The DFG will have kept it alive, though it may not be in a register, and
-        // we shouldn't really load it since that could be a waste. For now though,
-        // we'll just rely on the fact that when a watchpoint fires then that's
-        // quite a hint already.
-        
-        m_jit.addWeakReference(node-&gt;structure());
-        
-#if !ASSERT_DISABLED
-        SpeculateCellOperand op1(this, node-&gt;child1());
-        JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureIDOffset()), TrustedImmPtr(node-&gt;structure()));
-        m_jit.abortWithReason(DFGIneffectiveWatchpoint);
-        isOK.link(&amp;m_jit);
-#else
-        speculateCell(node-&gt;child1());
-#endif
-
-        noResult(node);
-        break;
-    }
-        
</del><span class="cx">     case PhantomPutStructure: {
</span><span class="cx">         ASSERT(isKnownCell(node-&gt;child1().node()));
</span><span class="cx">         m_jit.jitCode()-&gt;common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -3852,32 +3852,6 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case StructureTransitionWatchpoint: {
-        // There is a fascinating question here of what to do about array profiling.
-        // We *could* try to tell the OSR exit about where the base of the access is.
-        // The DFG will have kept it alive, though it may not be in a register, and
-        // we shouldn't really load it since that could be a waste. For now though,
-        // we'll just rely on the fact that when a watchpoint fires then that's
-        // quite a hint already.
-
-        m_jit.addWeakReference(node-&gt;structure());
-
-#if !ASSERT_DISABLED
-        SpeculateCellOperand op1(this, node-&gt;child1());
-        JITCompiler::Jump isOK = m_jit.branchStructurePtr(
-            JITCompiler::Equal, 
-            JITCompiler::Address(op1.gpr(), JSCell::structureIDOffset()), 
-            node-&gt;structure());
-        m_jit.abortWithReason(DFGIneffectiveWatchpoint);
-        isOK.link(&amp;m_jit);
-#else
-        speculateCell(node-&gt;child1());
-#endif
-        
-        noResult(node);
-        break;
-    }
-        
</del><span class="cx">     case PhantomPutStructure: {
</span><span class="cx">         ASSERT(isKnownCell(node-&gt;child1().node()));
</span><span class="cx">         m_jit.jitCode()-&gt;common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
</span><span class="lines">@@ -3886,8 +3860,8 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case PutStructure: {
</span><del>-        Structure* oldStructure = node-&gt;structureTransitionData().previousStructure;
-        Structure* newStructure = node-&gt;structureTransitionData().newStructure;
</del><ins>+        Structure* oldStructure = node-&gt;transition()-&gt;previous;
+        Structure* newStructure = node-&gt;transition()-&gt;next;
</ins><span class="cx"> 
</span><span class="cx">         m_jit.jitCode()-&gt;common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStoreBarrierElisionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGBasicBlock.h&quot;
</span><span class="cx"> #include &quot;DFGClobberize.h&quot;
</span><ins>+#include &quot;DFGDoesGC.h&quot;
</ins><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;DFGPhase.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -58,11 +59,6 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool couldCauseGC(Node* node)
-    {
-        return writesOverlap(m_graph, node, GCState);
-    }
-
</del><span class="cx">     bool allocatesFreshObject(Node* node)
</span><span class="cx">     {
</span><span class="cx">         switch (node-&gt;op()) {
</span><span class="lines">@@ -104,7 +100,7 @@
</span><span class="cx"> 
</span><span class="cx">     void handleNode(HashSet&lt;Node*&gt;&amp; dontNeedBarriers, Node* node)
</span><span class="cx">     {
</span><del>-        if (couldCauseGC(node))
</del><ins>+        if (doesGC(m_graph, node))
</ins><span class="cx">             dontNeedBarriers.clear();
</span><span class="cx"> 
</span><span class="cx">         if (allocatesFreshObject(node))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureAbstractValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,413 @@
</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;DFGStructureAbstractValue.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGGraph.h&quot;
+
+namespace JSC { namespace DFG {
+
+// Comment out the empty SAMPLE() definition, and uncomment the one that uses SamplingRegion, if
+// you want extremely fine-grained profiling in this code.
+#define SAMPLE(name) 
+//#define SAMPLE(name) SamplingRegion samplingRegion(name)
+
+#if !ASSERT_DISABLED
+void StructureAbstractValue::assertIsWatched(Graph&amp; graph) const
+{
+    SAMPLE(&quot;StructureAbstractValue assertIsWatched&quot;);
+
+    if (isTop())
+        return;
+    
+    for (unsigned i = size(); i--;)
+        graph.assertIsWatched(at(i));
+}
+#endif // !ASSERT_DISABLED
+
+void StructureAbstractValue::clobber()
+{
+    SAMPLE(&quot;StructureAbstractValue clobber&quot;);
+
+    // The premise of this approach to clobbering is that anytime we introduce
+    // a watchable structure into an abstract value, we watchpoint it. You can assert
+    // that this holds by calling assertIsWatched().
+        
+    if (isTop())
+        return;
+
+    setClobbered(true);
+        
+    if (m_set.isThin()) {
+        if (!m_set.singleStructure())
+            return;
+        if (!m_set.singleStructure()-&gt;dfgShouldWatch())
+            makeTopWhenThin();
+        return;
+    }
+        
+    StructureSet::OutOfLineList* list = m_set.structureList();
+    for (unsigned i = list-&gt;m_length; i--;) {
+        if (!list-&gt;list()[i]-&gt;dfgShouldWatch()) {
+            makeTop();
+            return;
+        }
+    }
+}
+
+void StructureAbstractValue::observeTransition(Structure* from, Structure* to)
+{
+    SAMPLE(&quot;StructureAbstractValue observeTransition&quot;);
+
+    if (isTop())
+        return;
+    
+    if (!m_set.contains(from))
+        return;
+    
+    if (from-&gt;dfgShouldWatch()) {
+        setClobbered(true);
+        return;
+    }
+    
+    if (!m_set.add(to))
+        return;
+    
+    if (m_set.size() &gt; polymorphismLimit)
+        makeTop();
+}
+
+void StructureAbstractValue::observeTransitions(const TransitionVector&amp; vector)
+{
+    SAMPLE(&quot;StructureAbstractValue observeTransitions&quot;);
+
+    if (isTop())
+        return;
+    
+    StructureSet newStructures;
+    for (unsigned i = vector.size(); i--;) {
+        if (!m_set.contains(vector[i].previous))
+            continue;
+        
+        if (vector[i].previous-&gt;dfgShouldWatch())
+            setClobbered(true);
+        else
+            newStructures.add(vector[i].next);
+    }
+    
+    if (!m_set.merge(newStructures))
+        return;
+    
+    if (m_set.size() &gt; polymorphismLimit)
+        makeTop();
+}
+
+bool StructureAbstractValue::add(Structure* structure)
+{
+    SAMPLE(&quot;StructureAbstractValue add&quot;);
+
+    if (isTop())
+        return false;
+    
+    if (!m_set.add(structure))
+        return false;
+    
+    if (m_set.size() &gt; polymorphismLimit)
+        makeTop();
+    
+    return true;
+}
+
+bool StructureAbstractValue::merge(const StructureSet&amp; other)
+{
+    SAMPLE(&quot;StructureAbstractValue merge set&quot;);
+
+    if (isTop())
+        return false;
+    
+    return mergeNotTop(other);
+}
+
+bool StructureAbstractValue::mergeSlow(const StructureAbstractValue&amp; other)
+{
+    SAMPLE(&quot;StructureAbstractValue merge value slow&quot;);
+
+    // It isn't immediately obvious that the code below is doing the right thing, so let's go
+    // through it.
+    //
+    // This not clobbered, other not clobbered: Clearly, we don't want to make anything clobbered
+    // since we just have two sets and we are merging them. mergeNotTop() can handle this just
+    // fine.
+    //
+    // This clobbered, other clobbered: Clobbered means that we have a set of things, plus we
+    // temporarily have the set of all things but the latter will go away once we hit the next
+    // invalidation point. This allows us to merge two clobbered sets the natural way. For now
+    // the set will still be TOP (and so we keep the clobbered bit set), but we know that after
+    // invalidation, we will have the union of the this and other.
+    //
+    // This clobbered, other not clobbered: It's safe to merge in other for both before and after
+    // invalidation, so long as we leave the clobbered bit set. Before invalidation this has no
+    // effect since the set will still appear to have all things in it. The way to think about
+    // what invalidation would do is imagine if we had a set A that was clobbered and a set B
+    // that wasn't and we considered the following two cases. Note that we expect A to be the
+    // same at the end in both cases:
+    //
+    //            A.merge(B)                             InvalidationPoint
+    //            InvalidationPoint                      A.merge(B)
+    //
+    // The fact that we expect A to be the same in both cases means that we want to merge other
+    // into this but keep the clobbered bit.
+    //
+    // This not clobbered, other clobbered: This is just the converse of the previous case. We
+    // want to merge other into this and set the clobbered bit.
+    
+    bool changed = false;
+    
+    if (!isClobbered() &amp;&amp; other.isClobbered()) {
+        setClobbered(true);
+        changed = true;
+    }
+    
+    changed |= mergeNotTop(other.m_set);
+    
+    return changed;
+}
+
+bool StructureAbstractValue::mergeNotTop(const StructureSet&amp; other)
+{
+    SAMPLE(&quot;StructureAbstractValue merge not top&quot;);
+
+    if (!m_set.merge(other))
+        return false;
+    
+    if (m_set.size() &gt; polymorphismLimit)
+        makeTop();
+    
+    return true;
+}
+
+void StructureAbstractValue::filter(const StructureSet&amp; other)
+{
+    SAMPLE(&quot;StructureAbstractValue filter set&quot;);
+
+    if (isTop()) {
+        m_set = other;
+        return;
+    }
+    
+    if (isClobbered()) {
+        // We have two choices here:
+        //
+        // Do nothing: It's legal to keep our set intact, which would essentially mean that for
+        // now, our set would behave like TOP but after the next invalidation point it wold be
+        // a finite set again. This may be a good choice if 'other' is much bigger than our
+        // m_set.
+        //
+        // Replace m_set with other and clear the clobber bit: This is also legal, and means that
+        // we're no longer clobbered. This is usually better because it immediately gives us a
+        // smaller set.
+        //
+        // This scenario should come up rarely. We usually don't do anything to an abstract value
+        // after it is clobbered. But we apply some heuristics.
+        
+        if (other.size() &gt; m_set.size() + clobberedSupremacyThreshold)
+            return; // Keep the clobbered set.
+        
+        m_set = other;
+        setClobbered(false);
+        return;
+    }
+    
+    m_set.filter(other);
+}
+
+void StructureAbstractValue::filter(const StructureAbstractValue&amp; other)
+{
+    SAMPLE(&quot;StructureAbstractValue filter value&quot;);
+
+    if (other.isTop())
+        return;
+    
+    if (other.isClobbered()) {
+        if (isTop())
+            return;
+        
+        if (!isClobbered()) {
+            // See justification in filter(const StructureSet&amp;), above. An unclobbered set is
+            // almost always better.
+            if (m_set.size() &gt; other.m_set.size() + clobberedSupremacyThreshold)
+                *this = other; // Keep the clobbered set.
+            return;
+        }
+
+        m_set.filter(other.m_set);
+        return;
+    }
+    
+    filter(other.m_set);
+}
+
+namespace {
+
+class ConformsToType {
+public:
+    ConformsToType(SpeculatedType type)
+        : m_type(type)
+    {
+    }
+    
+    bool operator()(Structure* structure)
+    {
+        return !!(speculationFromStructure(structure) &amp; m_type);
+    }
+private:
+    SpeculatedType m_type;
+};
+
+} // anonymous namespace
+
+void StructureAbstractValue::filterSlow(SpeculatedType type)
+{
+    SAMPLE(&quot;StructureAbstractValue filter type slow&quot;);
+
+    if (!(type &amp; SpecCell)) {
+        clear();
+        return;
+    }
+    
+    ASSERT(!isTop());
+    
+    ConformsToType conformsToType(type);
+    m_set.genericFilter(conformsToType);
+}
+
+bool StructureAbstractValue::contains(Structure* structure) const
+{
+    SAMPLE(&quot;StructureAbstractValue contains&quot;);
+
+    if (isTop() || isClobbered())
+        return true;
+    
+    return m_set.contains(structure);
+}
+
+bool StructureAbstractValue::isSubsetOf(const StructureSet&amp; other) const
+{
+    SAMPLE(&quot;StructureAbstractValue isSubsetOf set&quot;);
+
+    if (isTop() || isClobbered())
+        return false;
+    
+    return m_set.isSubsetOf(other);
+}
+
+bool StructureAbstractValue::isSubsetOf(const StructureAbstractValue&amp; other) const
+{
+    SAMPLE(&quot;StructureAbstractValue isSubsetOf value&quot;);
+
+    if (isTop())
+        return false;
+    
+    if (other.isTop())
+        return true;
+    
+    if (isClobbered() == other.isClobbered())
+        return m_set.isSubsetOf(other.m_set);
+    
+    // Here it gets tricky. If in doubt, return false!
+    
+    if (isClobbered())
+        return false; // A clobbered set is never a subset of an unclobbered set.
+    
+    // An unclobbered set is currently a subset of a clobbered set, but it may not be so after
+    // invalidation.
+    return m_set.isSubsetOf(other.m_set);
+}
+
+bool StructureAbstractValue::isSupersetOf(const StructureSet&amp; other) const
+{
+    SAMPLE(&quot;StructureAbstractValue isSupersetOf set&quot;);
+
+    if (isTop() || isClobbered())
+        return true;
+    
+    return m_set.isSupersetOf(other);
+}
+
+bool StructureAbstractValue::overlaps(const StructureSet&amp; other) const
+{
+    SAMPLE(&quot;StructureAbstractValue overlaps set&quot;);
+
+    if (isTop() || isClobbered())
+        return true;
+    
+    return m_set.overlaps(other);
+}
+
+bool StructureAbstractValue::overlaps(const StructureAbstractValue&amp; other) const
+{
+    SAMPLE(&quot;StructureAbstractValue overlaps value&quot;);
+
+    if (other.isTop() || other.isClobbered())
+        return true;
+    
+    return overlaps(other.m_set);
+}
+
+bool StructureAbstractValue::equalsSlow(const StructureAbstractValue&amp; other) const
+{
+    SAMPLE(&quot;StructureAbstractValue equalsSlow&quot;);
+
+    ASSERT(m_set.m_pointer != other.m_set.m_pointer);
+    ASSERT(!isTop());
+    ASSERT(!other.isTop());
+    
+    return m_set == other.m_set
+        &amp;&amp; isClobbered() == other.isClobbered();
+}
+
+void StructureAbstractValue::dumpInContext(PrintStream&amp; out, DumpContext* context) const
+{
+    if (isClobbered())
+        out.print(&quot;Clobbered:&quot;);
+    
+    if (isTop())
+        out.print(&quot;TOP&quot;);
+    else
+        out.print(inContext(m_set, context));
+}
+
+void StructureAbstractValue::dump(PrintStream&amp; out) const
+{
+    dumpInContext(out, 0);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2012, 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">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;DFGTransition.h&quot;
</ins><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="cx"> #include &quot;SpeculatedType.h&quot;
</span><span class="cx"> #include &quot;DumpContext.h&quot;
</span><span class="lines">@@ -37,300 +38,190 @@
</span><span class="cx"> 
</span><span class="cx"> class StructureAbstractValue {
</span><span class="cx"> public:
</span><del>-    StructureAbstractValue()
-        : m_structure(0)
</del><ins>+    StructureAbstractValue() { }
+    StructureAbstractValue(Structure* structure)
+        : m_set(structure)
</ins><span class="cx">     {
</span><ins>+        setClobbered(false);
</ins><span class="cx">     }
</span><del>-    
-    StructureAbstractValue(Structure* structure)
-        : m_structure(structure)
</del><ins>+    StructureAbstractValue(const StructureSet&amp; other)
+        : m_set(other)
</ins><span class="cx">     {
</span><ins>+        setClobbered(false);
</ins><span class="cx">     }
</span><ins>+    ALWAYS_INLINE StructureAbstractValue(const StructureAbstractValue&amp; other)
+        : m_set(other.m_set)
+    {
+        setClobbered(other.isClobbered());
+    }
</ins><span class="cx">     
</span><del>-    StructureAbstractValue(const StructureSet&amp; set)
</del><ins>+    ALWAYS_INLINE StructureAbstractValue&amp; operator=(const StructureAbstractValue&amp; other)
</ins><span class="cx">     {
</span><del>-        switch (set.size()) {
-        case 0:
-            m_structure = 0;
-            break;
-            
-        case 1:
-            m_structure = set[0];
-            break;
-            
-        default:
-            m_structure = topValue();
-            break;
-        }
</del><ins>+        m_set = other.m_set;
+        setClobbered(other.isClobbered());
+        return *this;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void clear()
</span><span class="cx">     {
</span><del>-        m_structure = 0;
</del><ins>+        m_set.clear();
+        setClobbered(false);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void makeTop()
</span><span class="cx">     {
</span><del>-        m_structure = topValue();
</del><ins>+        m_set.deleteStructureListIfNecessary();
+        m_set.m_pointer = topValue;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    static StructureAbstractValue top()
-    {
-        StructureAbstractValue value;
-        value.makeTop();
-        return value;
-    }
</del><ins>+#if ASSERT_DISABLED
+    void assertIsWatched(Graph&amp;) const { }
+#else
+    void assertIsWatched(Graph&amp;) const;
+#endif
</ins><span class="cx">     
</span><del>-    void add(Structure* structure)
-    {
-        ASSERT(!contains(structure) &amp;&amp; !isTop());
-        if (m_structure)
-            makeTop();
-        else
-            m_structure = structure;
-    }
</del><ins>+    void clobber();
+    void observeInvalidationPoint() { setClobbered(false); }
</ins><span class="cx">     
</span><del>-    bool addAll(const StructureSet&amp; other)
-    {
-        if (isTop() || !other.size())
-            return false;
-        if (other.size() &gt; 1) {
-            makeTop();
-            return true;
-        }
-        if (!m_structure) {
-            m_structure = other[0];
-            return true;
-        }
-        if (m_structure == other[0])
-            return false;
-        makeTop();
-        return true;
-    }
</del><ins>+    void observeTransition(Structure* from, Structure* to);
+    void observeTransitions(const TransitionVector&amp;);
</ins><span class="cx">     
</span><del>-    bool addAll(const StructureAbstractValue&amp; other)
</del><ins>+    static StructureAbstractValue top()
</ins><span class="cx">     {
</span><del>-        if (!other.m_structure)
-            return false;
-        if (isTop())
-            return false;
-        if (other.isTop()) {
-            makeTop();
-            return true;
-        }
-        if (m_structure) {
-            if (m_structure == other.m_structure)
-                return false;
-            makeTop();
-            return true;
-        }
-        m_structure = other.m_structure;
-        return true;
</del><ins>+        StructureAbstractValue result;
+        result.m_set.m_pointer = topValue;
+        return result;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool contains(Structure* structure) const
-    {
-        if (isTop())
-            return true;
-        if (m_structure == structure)
-            return true;
-        return false;
-    }
</del><ins>+    bool isClear() const { return m_set.isEmpty(); }
+    bool isTop() const { return m_set.m_pointer == topValue; }
+    bool isNeitherClearNorTop() const { return !isClear() &amp;&amp; !isTop(); }
</ins><span class="cx">     
</span><del>-    bool isSubsetOf(const StructureSet&amp; other) const
-    {
-        if (isTop())
-            return false;
-        if (!m_structure)
-            return true;
-        return other.contains(m_structure);
-    }
</del><ins>+    // A clobbered abstract value means that the set currently contains the m_set set of
+    // structures plus TOP, except that the &quot;plus TOP&quot; will go away at the next invalidation
+    // point. Note that it's tempting to think of this as &quot;the set of structures in m_set plus
+    // the set of structures transition-reachable from m_set&quot; - but this isn't really correct,
+    // since if we add an unwatchable structure after clobbering, the two definitions are not
+    // equivalent. If we do this, the new unwatchable structure will be added to m_set.
+    // Invalidation points do not try to &quot;clip&quot; the set of transition-reachable structures from
+    // m_set by looking at reachability as this would mean that the new set is TOP. Instead they
+    // literally assume that the set is just m_set rather than m_set plus TOP.
+    bool isClobbered() const { return m_set.getReservedFlag(); }
</ins><span class="cx">     
</span><del>-    bool doesNotContainAnyOtherThan(Structure* structure) const
-    {
-        if (isTop())
-            return false;
-        if (!m_structure)
-            return true;
-        return m_structure == structure;
-    }
</del><ins>+    bool add(Structure* structure);
</ins><span class="cx">     
</span><del>-    bool isSupersetOf(const StructureSet&amp; other) const
-    {
-        if (isTop())
-            return true;
-        if (!other.size())
-            return true;
-        if (other.size() &gt; 1)
-            return false;
-        return m_structure == other[0];
-    }
</del><ins>+    bool merge(const StructureSet&amp; other);
</ins><span class="cx">     
</span><del>-    bool isSubsetOf(const StructureAbstractValue&amp; other) const
</del><ins>+    ALWAYS_INLINE bool merge(const StructureAbstractValue&amp; other)
</ins><span class="cx">     {
</span><del>-        if (other.isTop())
-            return true;
</del><ins>+        if (other.isClear())
+            return false;
+        
</ins><span class="cx">         if (isTop())
</span><span class="cx">             return false;
</span><del>-        if (m_structure) {
-            if (other.m_structure)
-                return m_structure == other.m_structure;
-            return false;
-        }
-        return true;
-    }
-    
-    bool isSupersetOf(const StructureAbstractValue&amp; other) const
-    {
-        return other.isSubsetOf(*this);
-    }
-    
-    void filter(const StructureSet&amp; other)
-    {
-        if (!m_structure)
-            return;
</del><span class="cx">         
</span><del>-        if (isTop()) {
-            switch (other.size()) {
-            case 0:
-                m_structure = 0;
-                return;
-                
-            case 1:
-                m_structure = other[0];
-                return;
-                
-            default:
-                return;
-            }
</del><ins>+        if (other.isTop()) {
+            makeTop();
+            return true;
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (other.contains(m_structure))
-            return;
-        
-        m_structure = 0;
</del><ins>+        return mergeSlow(other);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void filter(const StructureAbstractValue&amp; other)
-    {
-        if (isTop()) {
-            m_structure = other.m_structure;
-            return;
-        }
-        if (m_structure == other.m_structure)
-            return;
-        if (other.isTop())
-            return;
-        m_structure = 0;
-    }
</del><ins>+    void filter(const StructureSet&amp; other);
+    void filter(const StructureAbstractValue&amp; other);
</ins><span class="cx">     
</span><del>-    void filter(SpeculatedType other)
</del><ins>+    ALWAYS_INLINE void filter(SpeculatedType type)
</ins><span class="cx">     {
</span><del>-        if (!(other &amp; SpecCell)) {
</del><ins>+        if (!(type &amp; SpecCell)) {
</ins><span class="cx">             clear();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        
-        if (isClearOrTop())
-            return;
-
-        if (!(speculationFromStructure(m_structure) &amp; other))
-            m_structure = 0;
</del><ins>+        if (isNeitherClearNorTop())
+            filterSlow(type);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isClear() const
</del><ins>+    ALWAYS_INLINE bool operator==(const StructureAbstractValue&amp; other) const
</ins><span class="cx">     {
</span><del>-        return !m_structure;
</del><ins>+        if ((m_set.isThin() &amp;&amp; other.m_set.isThin()) || isTop() || other.isTop())
+            return m_set.m_pointer == other.m_set.m_pointer;
+        
+        return equalsSlow(other);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isTop() const { return m_structure == topValue(); }
-    
-    bool isClearOrTop() const { return m_structure &lt;= topValue(); }
-    bool isNeitherClearNorTop() const { return !isClearOrTop(); }
-    
</del><span class="cx">     size_t size() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(!isTop());
</span><del>-        return !!m_structure;
</del><ins>+        return m_set.size();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Structure* at(size_t i) const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(!isTop());
</span><del>-        ASSERT(m_structure);
-        ASSERT_UNUSED(i, !i);
-        return m_structure;
</del><ins>+        return m_set.at(i);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    Structure* operator[](size_t i) const
-    {
-        return at(i);
-    }
</del><ins>+    Structure* operator[](size_t i) const { return at(i); }
</ins><span class="cx">     
</span><del>-    Structure* last() const
</del><ins>+    // FIXME: Eliminate all uses of this method. There shouldn't be any
+    // special-casing for the one-structure case.
+    // https://bugs.webkit.org/show_bug.cgi?id=133229
+    Structure* onlyStructure() const
</ins><span class="cx">     {
</span><ins>+        if (isTop() || size() != 1)
+            return nullptr;
</ins><span class="cx">         return at(0);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    SpeculatedType speculationFromStructures() const
-    {
-        if (isTop())
-            return SpecCell;
-        if (isClear())
-            return SpecNone;
-        return speculationFromStructure(m_structure);
-    }
</del><ins>+    void dumpInContext(PrintStream&amp;, DumpContext*) const;
+    void dump(PrintStream&amp;) const;
</ins><span class="cx">     
</span><del>-    bool isValidOffset(PropertyOffset offset)
-    {
-        if (isTop())
-            return false;
-        if (isClear())
-            return true;
-        return m_structure-&gt;isValidOffset(offset);
-    }
</del><ins>+    // The methods below are all conservative and err on the side of making 'this' appear bigger
+    // than it is. For example, contains() may return true if the set is clobbered or TOP.
+    // isSubsetOf() may return false in case of ambiguities. Therefore you should only perform
+    // optimizations as a consequence of the &quot;this is smaller&quot; return value - so false for
+    // contains(), true for isSubsetOf(), false for isSupersetOf(), and false for overlaps().
+
+    bool contains(Structure* structure) const;
</ins><span class="cx">     
</span><del>-    bool hasSingleton() const
-    {
-        return isNeitherClearNorTop();
-    }
</del><ins>+    bool isSubsetOf(const StructureSet&amp; other) const;
+    bool isSubsetOf(const StructureAbstractValue&amp; other) const;
</ins><span class="cx">     
</span><del>-    Structure* singleton() const
</del><ins>+    bool isSupersetOf(const StructureSet&amp; other) const;
+    bool isSupersetOf(const StructureAbstractValue&amp; other) const
</ins><span class="cx">     {
</span><del>-        ASSERT(isNeitherClearNorTop());
-        return m_structure;
</del><ins>+        return other.isSubsetOf(*this);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool operator==(const StructureAbstractValue&amp; other) const
</del><ins>+    bool overlaps(const StructureSet&amp; other) const;
+    bool overlaps(const StructureAbstractValue&amp; other) const;
+    
+private:
+    static const uintptr_t clobberedFlag = StructureSet::reservedFlag;
+    static const uintptr_t topValue = StructureSet::reservedValue;
+    static const unsigned polymorphismLimit = 10;
+    static const unsigned clobberedSupremacyThreshold = 2;
+    
+    void filterSlow(SpeculatedType type);
+    bool mergeSlow(const StructureAbstractValue&amp; other);
+    
+    bool equalsSlow(const StructureAbstractValue&amp; other) const;
+    
+    void makeTopWhenThin()
</ins><span class="cx">     {
</span><del>-        return m_structure == other.m_structure;
</del><ins>+        ASSERT(m_set.isThin());
+        m_set.m_pointer = topValue;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void dumpInContext(PrintStream&amp; out, DumpContext* context) const
</del><ins>+    bool mergeNotTop(const StructureSet&amp; other);
+    
+    void setClobbered(bool clobbered)
</ins><span class="cx">     {
</span><del>-        if (isTop()) {
-            out.print(&quot;TOP&quot;);
-            return;
-        }
-        
-        out.print(&quot;[&quot;);
-        if (m_structure)
-            out.print(inContext(*m_structure, context));
-        out.print(&quot;]&quot;);
</del><ins>+        ASSERT(!isTop() || !clobbered);
+        m_set.setReservedFlag(clobbered);
</ins><span class="cx">     }
</span><del>-
-    void dump(PrintStream&amp; out) const
-    {
-        dumpInContext(out, 0);
-    }
-
-private:
-    static Structure* topValue() { return reinterpret_cast&lt;Structure*&gt;(1); }
</del><span class="cx">     
</span><del>-    // NB. This must have a trivial destructor.
-    
-    // This can only remember one structure at a time.
-    Structure* m_structure;
</del><ins>+    StructureSet m_set;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureClobberStateh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGStructureClobberState.h (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureClobberState.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureClobberState.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,72 @@
</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 DFGStructureClobberState_h
+#define DFGStructureClobberState_h
+
+#if ENABLE(DFG_JIT)
+
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace DFG {
+
+enum StructureClobberState {
+    StructuresAreWatched, // Constants with watchable structures must have those structures.
+    StructuresAreClobbered // Constants with watchable structures could have any structure.
+};
+
+inline StructureClobberState merge(StructureClobberState a, StructureClobberState b)
+{
+    switch (a) {
+    case StructuresAreWatched:
+        return b;
+    case StructuresAreClobbered:
+        return StructuresAreClobbered;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+inline void printInternal(PrintStream&amp; out, JSC::DFG::StructureClobberState state)
+{
+    switch (state) {
+    case JSC::DFG::StructuresAreWatched:
+        out.print(&quot;StructuresAreWatched&quot;);
+        return;
+    case JSC::DFG::StructuresAreClobbered:
+        out.print(&quot;StructuresAreClobbered&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGStructureClobberState_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGTransitioncpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,48 @@
</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;DFGTransition.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+void Transition::dumpInContext(PrintStream&amp; out, DumpContext* context) const
+{
+    out.print(pointerDumpInContext(previous, context), &quot; -&gt; &quot;, pointerDumpInContext(next, context));
+}
+
+void Transition::dump(PrintStream&amp; out) const
+{
+    dumpInContext(out, 0);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGTransitionh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGTransition.h (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTransition.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGTransition.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,68 @@
</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 DFGTransition_h
+#define DFGTransition_h
+
+#if ENABLE(DFG_JIT)
+
+#include &lt;wtf/PrintStream.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+class Structure;
+struct DumpContext;
+
+namespace DFG {
+
+struct Transition {
+    Structure* previous;
+    Structure* next;
+    
+    Transition()
+        : previous(nullptr)
+        , next(nullptr)
+    {
+    }
+    
+    Transition(Structure* previous, Structure* next)
+        : previous(previous)
+        , next(next)
+    {
+    }
+    
+    void dumpInContext(PrintStream&amp;, DumpContext*) const;
+    void dump(PrintStream&amp;) const;
+};
+
+typedef Vector&lt;Transition, 3&gt; TransitionVector;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGTransition_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -215,8 +215,7 @@
</span><span class="cx">             for (unsigned indexInBlock = 0; indexInBlock &lt; block-&gt;size(); ++indexInBlock) {
</span><span class="cx">                 Node* node = block-&gt;at(indexInBlock);
</span><span class="cx">                 switch (node-&gt;op()) {
</span><del>-                case CheckStructure:
-                case StructureTransitionWatchpoint: {
</del><ins>+                case CheckStructure: {
</ins><span class="cx">                     Node* child = node-&gt;child1().node();
</span><span class="cx">                     if (child-&gt;op() != GetLocal)
</span><span class="cx">                         break;
</span><span class="lines">@@ -285,13 +284,6 @@
</span><span class="cx">                             noticeStructureCheck(variable, subNode-&gt;structureSet());
</span><span class="cx">                             break;
</span><span class="cx">                         }
</span><del>-                        case StructureTransitionWatchpoint: {
-                            if (subNode-&gt;child1() != source)
-                                break;
-                            
-                            noticeStructureCheck(variable, subNode-&gt;structure());
-                            break;
-                        }
</del><span class="cx">                         default:
</span><span class="cx">                             break;
</span><span class="cx">                         }
</span><span class="lines">@@ -331,7 +323,6 @@
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 case CheckStructure:
</span><del>-                case StructureTransitionWatchpoint:
</del><span class="cx">                 case GetByOffset:
</span><span class="cx">                 case PutByOffset:
</span><span class="cx">                 case PutStructure:
</span><span class="lines">@@ -386,13 +377,6 @@
</span><span class="cx">                             noticeStructureCheckAccountingForArrayMode(variable, subNode-&gt;structureSet());
</span><span class="cx">                             break;
</span><span class="cx">                         }
</span><del>-                        case StructureTransitionWatchpoint: {
-                            if (subNode-&gt;child1() != source)
-                                break;
-                            
-                            noticeStructureCheckAccountingForArrayMode(variable, subNode-&gt;structure());
-                            break;
-                        }
</del><span class="cx">                         case CheckArray: {
</span><span class="cx">                             if (subNode-&gt;child1() != source)
</span><span class="cx">                                 break;
</span><span class="lines">@@ -503,7 +487,7 @@
</span><span class="cx">             noticeStructureCheck(variable, 0);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        noticeStructureCheck(variable, set.singletonStructure());
</del><ins>+        noticeStructureCheck(variable, set.onlyStructure());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void noticeCheckArray(VariableAccessData* variable, ArrayMode arrayMode)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,179 @@
</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;DFGWatchableStructureWatchingPhase.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGBasicBlockInlines.h&quot;
+#include &quot;DFGGraph.h&quot;
+#include &quot;DFGPhase.h&quot;
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+class WatchableStructureWatchingPhase : public Phase {
+public:
+    WatchableStructureWatchingPhase(Graph&amp; graph)
+        : Phase(graph, &quot;watchable structure watching&quot;)
+    {
+    }
+    
+    bool run()
+    {
+        // These are pretty dumb, but needed to placate subsequent assertions. We con't actually
+        // have to watch these because there is no way to transition away from it, but they are
+        // watchable and so we will assert if they aren't watched.
+        tryWatch(m_graph.m_vm.stringStructure.get()); 
+        tryWatch(m_graph.m_vm.getterSetterStructure.get());
+        
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+        
+            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                Node* node = block-&gt;at(nodeIndex);
+            
+                switch (node-&gt;op()) {
+                case JSConstant:
+                case WeakJSConstant:
+                    tryWatch(m_graph.valueOfJSConstant(node));
+                    break;
+                
+                case CheckFunction:
+                    tryWatch(node-&gt;function());
+                    break;
+                
+                case CheckExecutable:
+                    tryWatch(node-&gt;executable());
+                    break;
+                
+                case CheckStructure:
+                    tryWatch(node-&gt;structureSet());
+                    break;
+                
+                case NewObject:
+                case ArrayifyToStructure:
+                case NewStringObject:
+                    tryWatch(node-&gt;structure());
+                    break;
+                
+                case PutStructure:
+                case PhantomPutStructure:
+                case AllocatePropertyStorage:
+                case ReallocatePropertyStorage:
+                    RELEASE_ASSERT(node-&gt;transition()-&gt;previous-&gt;transitionWatchpointSetHasBeenInvalidated());
+                    tryWatch(node-&gt;transition()-&gt;next);
+                    break;
+                    
+                case MultiGetByOffset:
+                    for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;) {
+                        GetByIdVariant&amp; variant = node-&gt;multiGetByOffsetData().variants[i];
+                        tryWatch(variant.specificValue());
+                        tryWatch(variant.structureSet());
+                        // Don't need to watch anything in the structure chain because that would
+                        // have been decomposed into CheckStructure's. Don't need to watch the
+                        // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
+                        // variants did that.
+                        ASSERT(!variant.callLinkStatus());
+                    }
+                    break;
+                    
+                case MultiPutByOffset:
+                    for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
+                        PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
+                        tryWatch(variant.oldStructure());
+                        if (variant.kind() == PutByIdVariant::Transition)
+                            tryWatch(variant.newStructure());
+                    }
+                    break;
+                    
+                case NewArray:
+                case NewArrayBuffer:
+                    tryWatch(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
+                    break;
+                    
+                case NewTypedArray:
+                    tryWatch(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;typedArrayStructure(node-&gt;typedArrayType()));
+                    break;
+                    
+                case ToString:
+                    tryWatch(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;stringObjectStructure());
+                    break;
+                    
+                case CreateActivation:
+                    tryWatch(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;activationStructure());
+                    break;
+                    
+                case NewRegexp:
+                    tryWatch(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;regExpStructure());
+                    break;
+                    
+                default:
+                    break;
+                }
+            }
+        }
+        
+        return true;
+    }
+
+private:
+    void tryWatch(JSValue value)
+    {
+        if (value.isCell())
+            tryWatch(value.asCell());
+    }
+    
+    void tryWatch(JSCell* cell)
+    {
+        if (cell)
+            tryWatch(cell-&gt;structure());
+    }
+    
+    void tryWatch(const StructureSet&amp; set)
+    {
+        for (unsigned i = set.size(); i--;)
+            tryWatch(set[i]);
+    }
+    
+    void tryWatch(Structure* structure)
+    {
+        m_graph.watchpoints().consider(structure);
+    }
+};
+
+bool performWatchableStructureWatching(Graph&amp; graph)
+{
+    SamplingRegion samplingRegion(&quot;DFG Watchable Structure Watching&quot;);
+    return runPhase&lt;WatchableStructureWatchingPhase&gt;(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,53 @@
</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 DFGWatchableStructureWatchingPhase_h
+#define DFGWatchableStructureWatchingPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Set watchpoints on any structures that we know of that are currently watchable. It's
+// somewhat counterintuitive, but this ends up being the cleanest and most effective way
+// of reducing structure checks on terminal structures:
+//
+// - We used to only set watchpoints on watchable structures if we knew that this would
+//   remove a structure check. Experiments show that switching from that, to blindly
+//   setting watchpoints on all watchable structures, was not a regression.
+//
+// - It makes abstract interpretation a whole lot easier. We just assume that watchable
+//   structures are unclobberable without having to do any other logic.
+
+bool performWatchableStructureWatching(Graph&amp;);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGWatchableStructureWatchingPhase_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -64,8 +64,6 @@
</span><span class="cx"> private:
</span><span class="cx">     void handle()
</span><span class="cx">     {
</span><del>-        DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, handleEdge);
-        
</del><span class="cx">         switch (m_node-&gt;op()) {
</span><span class="cx">         case CompareEqConstant:
</span><span class="cx">         case IsUndefined:
</span><span class="lines">@@ -119,13 +117,6 @@
</span><span class="cx">             addLazily(jsCast&lt;JSFunction*&gt;(m_node-&gt;function())-&gt;allocationProfileWatchpointSet());
</span><span class="cx">             break;
</span><span class="cx">             
</span><del>-        case StructureTransitionWatchpoint:
-            m_graph.watchpoints().addLazily(
-                m_node-&gt;origin.semantic,
-                m_node-&gt;child1()-&gt;op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint,
-                m_node-&gt;structure()-&gt;transitionWatchpointSet());
-            break;
-            
</del><span class="cx">         case VariableWatchpoint:
</span><span class="cx">             addLazily(m_node-&gt;variableWatchpointSet());
</span><span class="cx">             break;
</span><span class="lines">@@ -147,26 +138,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void handleEdge(Node*, Edge edge)
-    {
-        switch (edge.useKind()) {
-        case StringObjectUse:
-        case StringOrStringObjectUse: {
-            Structure* stringObjectStructure = globalObject()-&gt;stringObjectStructure();
-            Structure* stringPrototypeStructure = stringObjectStructure-&gt;storedPrototype().asCell()-&gt;structure();
-            ASSERT(m_graph.watchpoints().isValidOrMixed(stringPrototypeStructure-&gt;transitionWatchpointSet()));
-            
-            m_graph.watchpoints().addLazily(
-                m_node-&gt;origin.semantic, NotStringObject,
-                stringPrototypeStructure-&gt;transitionWatchpointSet());
-            break;
-        }
-            
-        default:
-            break;
-        }
-    }
-    
</del><span class="cx">     void handleMasqueradesAsUndefined()
</span><span class="cx">     {
</span><span class="cx">         if (m_graph.masqueradesAsUndefinedWatchpointIsStillValid(m_node-&gt;origin.semantic))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -63,7 +63,6 @@
</span><span class="cx">     case BitLShift:
</span><span class="cx">     case BitURShift:
</span><span class="cx">     case CheckStructure:
</span><del>-    case StructureTransitionWatchpoint:
</del><span class="cx">     case ArrayifyToStructure:
</span><span class="cx">     case PutStructure:
</span><span class="cx">     case PhantomPutStructure:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -91,6 +91,8 @@
</span><span class="cx">     macro(V_JITOperation_EC, functionType(voidType, intPtr, intPtr)) \
</span><span class="cx">     macro(V_JITOperation_ECb, functionType(voidType, intPtr, intPtr)) \
</span><span class="cx">     macro(V_JITOperation_EVwsJ, functionType(voidType, intPtr, intPtr, int64)) \
</span><ins>+    macro(V_JITOperation_J, functionType(voidType, int64)) \
+    macro(V_JITOperation_Z, functionType(voidType, int32)) \
</ins><span class="cx">     macro(Z_JITOperation_D, functionType(int32, doubleType))
</span><span class="cx"> 
</span><span class="cx"> class IntrinsicRepository : public CommonValues {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -52,6 +52,24 @@
</span><span class="cx"> 
</span><span class="cx"> static std::atomic&lt;int&gt; compileCounter;
</span><span class="cx"> 
</span><ins>+#if ASSERT_DISABLED
+NO_RETURN_DUE_TO_CRASH static void ftlUnreachable()
+{
+    CRASH();
+}
+#else
+NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
+    CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
+{
+    
+    dataLog(&quot;Crashing in thought-to-be-unreachable FTL-generated code for &quot;, pointerDump(codeBlock), &quot; at basic block #&quot;, blockIndex);
+    if (nodeIndex != UINT_MAX)
+        dataLog(&quot;, node @&quot;, nodeIndex);
+    dataLog(&quot;.\n&quot;);
+    CRASH();
+}
+#endif
+
</ins><span class="cx"> // Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
</span><span class="cx"> // significantly less dead code.
</span><span class="cx"> #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \
</span><span class="lines">@@ -201,7 +219,7 @@
</span><span class="cx">                     type = m_out.int64;
</span><span class="cx">                     break;
</span><span class="cx">                 default:
</span><del>-                    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                    DFG_CRASH(m_graph, node, &quot;Bad Phi node result type&quot;);
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 m_phis.add(node, buildAlloca(m_out.m_builder, type));
</span><span class="lines">@@ -236,10 +254,12 @@
</span><span class="cx">         m_out.appendTo(lowBlock, m_nextLowBlock);
</span><span class="cx">         
</span><span class="cx">         if (Options::ftlCrashes())
</span><del>-            m_out.crashNonTerminal();
</del><ins>+            m_out.trap();
</ins><span class="cx">         
</span><span class="cx">         if (!m_highBlock-&gt;cfaHasVisited) {
</span><del>-            m_out.crash();
</del><ins>+            if (verboseCompilationEnabled())
+                dataLog(&quot;Bailing because CFA didn't reach.\n&quot;);
+            crash(m_highBlock-&gt;index, UINT_MAX);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -257,7 +277,26 @@
</span><span class="cx">     bool compileNode(unsigned nodeIndex)
</span><span class="cx">     {
</span><span class="cx">         if (!m_state.isValid()) {
</span><del>-            m_out.unreachable();
</del><ins>+            if (verboseCompilationEnabled())
+                dataLog(&quot;Bailing.\n&quot;);
+            crash(m_highBlock-&gt;index, m_node-&gt;index());
+            
+            // Invalidate dominated blocks. Under normal circumstances we would expect
+            // them to be invalidated already. But you can have the CFA become more
+            // precise over time because the structures of objects change on the main
+            // thread. Failing to do this would result in weird crashes due to a value
+            // being used but not defined. Race conditions FTW!
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* target = m_graph.block(blockIndex);
+                if (!target)
+                    continue;
+                if (m_graph.m_dominators.dominates(m_highBlock, target)) {
+                    if (verboseCompilationEnabled())
+                        dataLog(&quot;Block &quot;, *target, &quot; will bail also.\n&quot;);
+                    target-&gt;cfaHasVisited = false;
+                }
+            }
+            
</ins><span class="cx">             return false;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -401,9 +440,6 @@
</span><span class="cx">         case CheckStructure:
</span><span class="cx">             compileCheckStructure();
</span><span class="cx">             break;
</span><del>-        case StructureTransitionWatchpoint:
-            compileStructureTransitionWatchpoint();
-            break;
</del><span class="cx">         case CheckFunction:
</span><span class="cx">             compileCheckFunction();
</span><span class="cx">             break;
</span><span class="lines">@@ -638,12 +674,7 @@
</span><span class="cx">         case AllocationProfileWatchpoint:
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            dataLog(&quot;Unrecognized node in FTL backend:\n&quot;);
-            m_graph.dump(WTF::dataFile(), &quot;    &quot;, m_node);
-            dataLog(&quot;\n&quot;);
-            dataLog(&quot;Full graph dump:\n&quot;);
-            m_graph.dump();
-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Unrecognized node in FTL backend&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -677,7 +708,7 @@
</span><span class="cx">             m_out.set(lowJSValue(m_node-&gt;child1()), destination);
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -703,7 +734,7 @@
</span><span class="cx">             setJSValue(m_out.get(source));
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -746,7 +777,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -771,7 +802,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -834,7 +865,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -876,7 +907,7 @@
</span><span class="cx">     {
</span><span class="cx">         VariableAccessData* variable = m_node-&gt;variableAccessData();
</span><span class="cx">         VirtualRegister operand = variable-&gt;machineLocal();
</span><del>-        RELEASE_ASSERT(operand.isArgument());
</del><ins>+        DFG_ASSERT(m_graph, m_node, operand.isArgument());
</ins><span class="cx"> 
</span><span class="cx">         LValue jsValue = m_out.load64(addressFor(operand));
</span><span class="cx"> 
</span><span class="lines">@@ -897,7 +928,7 @@
</span><span class="cx">             setJSValue(jsValue);
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -916,7 +947,7 @@
</span><span class="cx">         VariableAccessData* variable = m_node-&gt;variableAccessData();
</span><span class="cx">         AbstractValue&amp; value = m_state.variables().operand(variable-&gt;local());
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT(variable-&gt;isCaptured());
</del><ins>+        DFG_ASSERT(m_graph, m_node, variable-&gt;isCaptured());
</ins><span class="cx">         
</span><span class="cx">         if (isInt32Speculation(value.m_type))
</span><span class="cx">             setInt32(m_out.load32(payloadFor(variable-&gt;machineLocal())));
</span><span class="lines">@@ -968,7 +999,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad flush format&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -1144,7 +1175,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1218,7 +1249,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1321,7 +1352,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1419,7 +1450,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1470,7 +1501,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1496,7 +1527,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1563,7 +1594,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1655,12 +1686,6 @@
</span><span class="cx">         m_out.appendTo(continuation, lastNext);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void compileStructureTransitionWatchpoint()
-    {
-        addWeakReference(m_node-&gt;structure());
-        speculateCell(m_node-&gt;child1());
-    }
-    
</del><span class="cx">     void compileCheckFunction()
</span><span class="cx">     {
</span><span class="cx">         LValue cell = lowCell(m_node-&gt;child1());
</span><span class="lines">@@ -1729,7 +1754,7 @@
</span><span class="cx">             vmCall(m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -1746,8 +1771,8 @@
</span><span class="cx">     {
</span><span class="cx">         m_ftlState.jitCode-&gt;common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
</span><span class="cx"> 
</span><del>-        Structure* oldStructure = m_node-&gt;structureTransitionData().previousStructure;
-        Structure* newStructure = m_node-&gt;structureTransitionData().newStructure;
</del><ins>+        Structure* oldStructure = m_node-&gt;transition()-&gt;previous;
+        Structure* newStructure = m_node-&gt;transition()-&gt;next;
</ins><span class="cx">         ASSERT_UNUSED(oldStructure, oldStructure-&gt;indexingType() == newStructure-&gt;indexingType());
</span><span class="cx">         ASSERT(oldStructure-&gt;typeInfo().inlineTypeFlags() == newStructure-&gt;typeInfo().inlineTypeFlags());
</span><span class="cx">         ASSERT(oldStructure-&gt;typeInfo().type() == newStructure-&gt;typeInfo().type());
</span><span class="lines">@@ -1803,7 +1828,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1929,7 +1954,7 @@
</span><span class="cx">     {
</span><span class="cx">         checkArgumentsNotCreated();
</span><span class="cx"> 
</span><del>-        RELEASE_ASSERT(!m_node-&gt;origin.semantic.inlineCallFrame);
</del><ins>+        DFG_ASSERT(m_graph, m_node, !m_node-&gt;origin.semantic.inlineCallFrame);
</ins><span class="cx">         setInt32(m_out.add(m_out.load32NonNegative(payloadFor(JSStack::ArgumentCount)), m_out.constInt32(-1)));
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1955,7 +1980,7 @@
</span><span class="cx">             // FIXME: FTL should support activations.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=129576
</span><span class="cx">             
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Unimplemented&quot;);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         TypedPointer base;
</span><span class="lines">@@ -1992,7 +2017,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -2142,7 +2167,7 @@
</span><span class="cx">                         result = m_out.load32(pointer);
</span><span class="cx">                         break;
</span><span class="cx">                     default:
</span><del>-                        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                        DFG_CRASH(m_graph, m_node, &quot;Bad element size&quot;);
</ins><span class="cx">                     }
</span><span class="cx">                     
</span><span class="cx">                     if (elementSize(type) &lt; 4) {
</span><span class="lines">@@ -2186,14 +2211,14 @@
</span><span class="cx">                     result = m_out.loadDouble(pointer);
</span><span class="cx">                     break;
</span><span class="cx">                 default:
</span><del>-                    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                    DFG_CRASH(m_graph, m_node, &quot;Bad typed array type&quot;);
</ins><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 setDouble(result);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             return;
</span><span class="cx">         } }
</span><span class="cx">     }
</span><span class="lines">@@ -2299,7 +2324,7 @@
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="cx">             default:
</span><del>-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             m_out.jump(continuation);
</span><span class="lines">@@ -2392,7 +2417,7 @@
</span><span class="cx">                     }
</span><span class="cx">                         
</span><span class="cx">                     default:
</span><del>-                        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                        DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">                     }
</span><span class="cx">                     
</span><span class="cx">                     switch (elementSize(type)) {
</span><span class="lines">@@ -2409,7 +2434,7 @@
</span><span class="cx">                         refType = m_out.ref32;
</span><span class="cx">                         break;
</span><span class="cx">                     default:
</span><del>-                        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                        DFG_CRASH(m_graph, m_node, &quot;Bad element size&quot;);
</ins><span class="cx">                     }
</span><span class="cx">                 } else /* !isInt(type) */ {
</span><span class="cx">                     LValue value = lowDouble(child3);
</span><span class="lines">@@ -2423,7 +2448,7 @@
</span><span class="cx">                         refType = m_out.refDouble;
</span><span class="cx">                         break;
</span><span class="cx">                     default:
</span><del>-                        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                        DFG_CRASH(m_graph, m_node, &quot;Bad typed array type&quot;);
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="lines">@@ -2447,7 +2472,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -2519,7 +2544,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -2577,7 +2602,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -2622,7 +2647,7 @@
</span><span class="cx">         Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
</span><span class="cx">             m_node-&gt;indexingType());
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT(structure-&gt;indexingType() == m_node-&gt;indexingType());
</del><ins>+        DFG_ASSERT(m_graph, m_node, structure-&gt;indexingType() == m_node-&gt;indexingType());
</ins><span class="cx">         
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(m_node-&gt;indexingType())) {
</span><span class="cx">             unsigned numElements = m_node-&gt;numChildren();
</span><span class="lines">@@ -2635,7 +2660,7 @@
</span><span class="cx">                 switch (m_node-&gt;indexingType()) {
</span><span class="cx">                 case ALL_BLANK_INDEXING_TYPES:
</span><span class="cx">                 case ALL_UNDECIDED_INDEXING_TYPES:
</span><del>-                    CRASH();
</del><ins>+                    DFG_CRASH(m_graph, m_node, &quot;Bad indexing type&quot;);
</ins><span class="cx">                     break;
</span><span class="cx">                     
</span><span class="cx">                 case ALL_DOUBLE_INDEXING_TYPES:
</span><span class="lines">@@ -2653,7 +2678,8 @@
</span><span class="cx">                     break;
</span><span class="cx">                     
</span><span class="cx">                 default:
</span><del>-                    CRASH();
</del><ins>+                    DFG_CRASH(m_graph, m_node, &quot;Corrupt indexing type&quot;);
+                    break;
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -2699,7 +2725,7 @@
</span><span class="cx">         Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
</span><span class="cx">             m_node-&gt;indexingType());
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT(structure-&gt;indexingType() == m_node-&gt;indexingType());
</del><ins>+        DFG_ASSERT(m_graph, m_node, structure-&gt;indexingType() == m_node-&gt;indexingType());
</ins><span class="cx">         
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(m_node-&gt;indexingType())) {
</span><span class="cx">             unsigned numElements = m_node-&gt;numConstants();
</span><span class="lines">@@ -2837,21 +2863,19 @@
</span><span class="cx">     
</span><span class="cx">     void compileAllocatePropertyStorage()
</span><span class="cx">     {
</span><del>-        StructureTransitionData&amp; data = m_node-&gt;structureTransitionData();
</del><span class="cx">         LValue object = lowCell(m_node-&gt;child1());
</span><del>-        
-        setStorage(allocatePropertyStorage(object, data.previousStructure));
</del><ins>+        setStorage(allocatePropertyStorage(object, m_node-&gt;transition()-&gt;previous));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void compileReallocatePropertyStorage()
</span><span class="cx">     {
</span><del>-        StructureTransitionData&amp; data = m_node-&gt;structureTransitionData();
</del><ins>+        Transition* transition = m_node-&gt;transition();
</ins><span class="cx">         LValue object = lowCell(m_node-&gt;child1());
</span><span class="cx">         LValue oldStorage = lowStorage(m_node-&gt;child2());
</span><span class="cx">         
</span><span class="cx">         setStorage(
</span><span class="cx">             reallocatePropertyStorage(
</span><del>-                object, oldStorage, data.previousStructure, data.newStructure));
</del><ins>+                object, oldStorage, transition-&gt;previous, transition-&gt;next));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileToString()
</span><span class="lines">@@ -2936,7 +2960,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -3028,7 +3052,7 @@
</span><span class="cx">                 m_out.operation(operationMakeRope3), m_callFrame, kids[0], kids[1], kids[2]));
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad number of children&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         m_out.jump(continuation);
</span><span class="lines">@@ -3253,7 +3277,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(exit, continuation);
</span><del>-        terminate(BadCache);
</del><ins>+        speculate(BadCache, noValue(), nullptr, m_out.booleanTrue);
</ins><span class="cx">         m_out.unreachable();
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -3325,7 +3349,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(exit, continuation);
</span><del>-        terminate(BadCache);
</del><ins>+        speculate(BadCache, noValue(), nullptr, m_out.booleanTrue);
</ins><span class="cx">         m_out.unreachable();
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -3444,7 +3468,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Bad use kinds&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileCompareEqConstant()
</span><span class="lines">@@ -3537,7 +3561,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Bad use kinds&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileCompareStrictEqConstant()
</span><span class="lines">@@ -3673,7 +3697,7 @@
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="cx">             default:
</span><del>-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -3719,7 +3743,7 @@
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="cx">             default:
</span><del>-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -3772,11 +3796,11 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         case SwitchString:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Unimplemented&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Bad switch kind&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileReturn()
</span><span class="lines">@@ -3958,7 +3982,7 @@
</span><span class="cx">         speculate(m_node-&gt;child1());
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><del>-
</del><ins>+    
</ins><span class="cx">     LValue didOverflowStack()
</span><span class="cx">     {
</span><span class="cx">         // This does a very simple leaf function analysis. The invariant of FTL call
</span><span class="lines">@@ -4233,7 +4257,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Bad use kinds&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compareEqObjectOrOtherToObject(Edge leftChild, Edge rightChild)
</span><span class="lines">@@ -4512,7 +4536,7 @@
</span><span class="cx">             return m_out.phi(m_out.boolean, fastResult, slowResult);
</span><span class="cx">         }
</span><span class="cx">         default:
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">             return 0;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -4759,7 +4783,8 @@
</span><span class="cx">     
</span><span class="cx">     void terminate(ExitKind kind)
</span><span class="cx">     {
</span><del>-        speculate(kind, noValue(), 0, m_out.booleanTrue);
</del><ins>+        speculate(kind, noValue(), nullptr, m_out.booleanTrue);
+        m_state.setIsValid(false);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void typeCheck(
</span><span class="lines">@@ -4815,7 +4840,7 @@
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        RELEASE_ASSERT(!(m_state.forNode(edge).m_type &amp; SpecInt32));
</del><ins>+        DFG_ASSERT(m_graph, m_node, !(m_state.forNode(edge).m_type &amp; SpecInt32));
</ins><span class="cx">         terminate(Uncountable);
</span><span class="cx">         return m_out.int32Zero;
</span><span class="cx">     }
</span><span class="lines">@@ -4823,7 +4848,7 @@
</span><span class="cx">     enum Int52Kind { StrictInt52, Int52 };
</span><span class="cx">     LValue lowInt52(Edge edge, Int52Kind kind)
</span><span class="cx">     {
</span><del>-        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
</del><ins>+        DFG_ASSERT(m_graph, m_node, edge.useKind() == Int52RepUse);
</ins><span class="cx">         
</span><span class="cx">         LoweredNodeValue value;
</span><span class="cx">         
</span><span class="lines">@@ -4849,7 +4874,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
</del><ins>+        DFG_ASSERT(m_graph, m_node, !m_state.forNode(edge).m_type);
</ins><span class="cx">         terminate(Uncountable);
</span><span class="cx">         return m_out.int64Zero;
</span><span class="cx">     }
</span><span class="lines">@@ -4885,7 +4910,7 @@
</span><span class="cx">         case StrictInt52:
</span><span class="cx">             return Int52;
</span><span class="cx">         }
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</ins><span class="cx">         return Int52;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -4916,7 +4941,7 @@
</span><span class="cx">             return uncheckedValue;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT(!(m_state.forNode(edge).m_type &amp; SpecCell));
</del><ins>+        DFG_ASSERT(m_graph, m_node, !(m_state.forNode(edge).m_type &amp; SpecCell));
</ins><span class="cx">         terminate(Uncountable);
</span><span class="cx">         return m_out.intPtrZero;
</span><span class="cx">     }
</span><span class="lines">@@ -4985,20 +5010,19 @@
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT(!(m_state.forNode(edge).m_type &amp; SpecBoolean));
</del><ins>+        DFG_ASSERT(m_graph, m_node, !(m_state.forNode(edge).m_type &amp; SpecBoolean));
</ins><span class="cx">         terminate(Uncountable);
</span><span class="cx">         return m_out.booleanFalse;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     LValue lowDouble(Edge edge)
</span><span class="cx">     {
</span><del>-        RELEASE_ASSERT(isDouble(edge.useKind()));
</del><ins>+        DFG_ASSERT(m_graph, m_node, isDouble(edge.useKind()));
</ins><span class="cx">         
</span><span class="cx">         LoweredNodeValue value = m_doubleValues.get(edge.node());
</span><span class="cx">         if (isValid(value))
</span><span class="cx">             return value.value();
</span><del>-        
-        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
</del><ins>+        DFG_ASSERT(m_graph, m_node, !m_state.forNode(edge).m_type);
</ins><span class="cx">         terminate(Uncountable);
</span><span class="cx">         return m_out.doubleZero;
</span><span class="cx">     }
</span><span class="lines">@@ -5006,8 +5030,8 @@
</span><span class="cx">     LValue lowJSValue(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
</span><span class="cx">     {
</span><span class="cx">         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
</span><del>-        RELEASE_ASSERT(!isDouble(edge.useKind()));
-        RELEASE_ASSERT(edge.useKind() != Int52RepUse);
</del><ins>+        DFG_ASSERT(m_graph, m_node, !isDouble(edge.useKind()));
+        DFG_ASSERT(m_graph, m_node, edge.useKind() != Int52RepUse);
</ins><span class="cx">         
</span><span class="cx">         if (edge-&gt;hasConstant())
</span><span class="cx">             return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node())));
</span><span class="lines">@@ -5030,7 +5054,7 @@
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Value not defined&quot;);
</ins><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -5342,8 +5366,7 @@
</span><span class="cx">             speculateMisc(edge);
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            dataLog(&quot;Unsupported speculation use kind: &quot;, edge.useKind(), &quot;\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Unsupported speculation use kind&quot;);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -5404,7 +5427,7 @@
</span><span class="cx">             
</span><span class="cx">             switch (arrayMode.arrayClass()) {
</span><span class="cx">             case Array::OriginalArray:
</span><del>-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                DFG_CRASH(m_graph, m_node, &quot;Unexpected original array&quot;);
</ins><span class="cx">                 return 0;
</span><span class="cx">                 
</span><span class="cx">             case Array::Array:
</span><span class="lines">@@ -5424,7 +5447,7 @@
</span><span class="cx">                     m_out.constInt8(arrayMode.shapeMask()));
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            DFG_CRASH(m_graph, m_node, &quot;Corrupt array class&quot;);
</ins><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><span class="lines">@@ -5567,7 +5590,7 @@
</span><span class="cx">         Structure* stringObjectStructure =
</span><span class="cx">             m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;stringObjectStructure();
</span><span class="cx">         
</span><del>-        if (m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(stringObjectStructure)))
</del><ins>+        if (m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure)))
</ins><span class="cx">             return;
</span><span class="cx">         
</span><span class="cx">         speculate(
</span><span class="lines">@@ -5782,9 +5805,10 @@
</span><span class="cx">         
</span><span class="cx">         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;Exception check continuation&quot;));
</span><span class="cx">         
</span><ins>+        LValue exception = m_out.load64(m_out.absolute(vm().addressOfException()));
+        
</ins><span class="cx">         m_out.branch(
</span><del>-            m_out.notZero64(m_out.load64(m_out.absolute(vm().addressOfException()))),
-            rarely(m_handleExceptions), usually(continuation));
</del><ins>+            m_out.notZero64(exception), rarely(m_handleExceptions), usually(continuation));
</ins><span class="cx">         
</span><span class="cx">         m_out.appendTo(continuation);
</span><span class="cx">     }
</span><span class="lines">@@ -5871,10 +5895,8 @@
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 
</span><del>-                if (Options::validateFTLOSRExitLiveness()) {
-                    dataLog(&quot;Expected r&quot;, operand, &quot; to be available but it wasn't.\n&quot;);
-                    RELEASE_ASSERT_NOT_REACHED();
-                }
</del><ins>+                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());
</ins><span class="cx">                 
</span><span class="cx">                 // This means that the DFG's DCE proved that the value is dead in bytecode
</span><span class="cx">                 // even though the bytecode liveness analysis thinks it's live. This is
</span><span class="lines">@@ -5979,10 +6001,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        startCrashing();
-        dataLog(&quot;Cannot find value for node: &quot;, node, &quot; while compiling exit at &quot;, exit.m_codeOrigin, &quot; in node &quot;, m_node, &quot;\n&quot;);
-        m_graph.dump();
-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, toCString(&quot;Cannot find value for node: &quot;, node).data());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool tryToSetConstantExitArgument(OSRExit&amp; exit, unsigned index, Node* node)
</span><span class="lines">@@ -6060,7 +6079,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        DFG_CRASH(m_graph, m_node, &quot;Corrupt int52 kind&quot;);
</ins><span class="cx">     }
</span><span class="cx">     void setJSValue(Node* node, LValue value)
</span><span class="cx">     {
</span><span class="lines">@@ -6187,6 +6206,25 @@
</span><span class="cx">         return addressFor(operand, TagOffset);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void crash(BlockIndex blockIndex, unsigned nodeIndex)
+    {
+#if ASSERT_DISABLED
+        m_out.call(m_out.operation(ftlUnreachable));
+        UNUSED_PARAM(blockIndex);
+        UNUSED_PARAM(nodeIndex);
+#else
+        m_out.call(
+            m_out.intToPtr(
+                m_out.constIntPtr(ftlUnreachable),
+                pointerType(
+                    functionType(
+                        m_out.voidType, m_out.intPtr, m_out.int32, m_out.int32))),
+            m_out.constIntPtr(codeBlock()), m_out.constInt32(blockIndex),
+            m_out.constInt32(nodeIndex));
+#endif
+        m_out.unreachable();
+    }
+    
</ins><span class="cx">     VM&amp; vm() { return m_graph.m_vm; }
</span><span class="cx">     CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</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">@@ -138,11 +138,6 @@
</span><span class="cx">             constInt32(notTakenWeight.scaleToTotal(total))));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Output::crashNonTerminal()
-{
-    call(intToPtr(constIntPtr(abort), pointerType(functionType(voidType))));
-}
-
</del><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -401,14 +401,6 @@
</span><span class="cx">         call(trapIntrinsic());
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void crashNonTerminal();
-
-    void crash()
-    {
-        crashNonTerminal();
-        unreachable();
-    }
-    
</del><span class="cx">     ValueFromBlock anchor(LValue value)
</span><span class="cx">     {
</span><span class="cx">         return ValueFromBlock(value, m_block);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -171,6 +171,8 @@
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EVwsJ)(ExecState*, VariableWatchpointSet*, EncodedJSValue);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EZ)(ExecState*, int32_t);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EVm)(ExecState*, VM*);
</span><ins>+typedef void JIT_OPERATION (*V_JITOperation_J)(EncodedJSValue);
+typedef void JIT_OPERATION (*V_JITOperation_Z)(int32_t);
</ins><span class="cx"> typedef char* JIT_OPERATION (*P_JITOperation_E)(ExecState*);
</span><span class="cx"> typedef char* JIT_OPERATION (*P_JITOperation_EC)(ExecState*, JSCell*);
</span><span class="cx"> typedef char* JIT_OPERATION (*P_JITOperation_ECli)(ExecState*, CallLinkInfo*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -94,6 +94,17 @@
</span><span class="cx"> 
</span><span class="cx"> namespace {
</span><span class="cx"> 
</span><ins>+NO_RETURN_WITH_VALUE static void jscExit(int status)
+{
+#if ENABLE(DFG_JIT)
+    if (DFG::isCrashing()) {
+        for (;;)
+            pause();
+    }
+#endif // ENABLE(DFG_JIT)
+    exit(status);
+}
+
</ins><span class="cx"> class Element;
</span><span class="cx"> class ElementHandleOwner;
</span><span class="cx"> class Masuqerader;
</span><span class="lines">@@ -890,7 +901,7 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*)
</span><span class="cx"> {
</span><del>-    exit(EXIT_SUCCESS);
</del><ins>+    jscExit(EXIT_SUCCESS);
</ins><span class="cx"> 
</span><span class="cx"> #if COMPILER(MSVC) &amp;&amp; OS(WINCE)
</span><span class="cx">     // Without this, Visual Studio will complain that this method does not return a value.
</span><span class="lines">@@ -1010,7 +1021,7 @@
</span><span class="cx">     ecore_shutdown();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    return res;
</del><ins>+    jscExit(res);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static bool runWithScripts(GlobalObject* globalObject, const Vector&lt;Script&gt;&amp; scripts, bool dump)
</span><span class="lines">@@ -1154,7 +1165,7 @@
</span><span class="cx">     fprintf(stderr, &quot;  --&lt;jsc VM option&gt;=&lt;value&gt;  Sets the specified JSC VM option\n&quot;);
</span><span class="cx">     fprintf(stderr, &quot;\n&quot;);
</span><span class="cx"> 
</span><del>-    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
</del><ins>+    jscExit(help ? EXIT_SUCCESS : EXIT_FAILURE);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CommandLine::parseArguments(int argc, char** argv)
</span><span class="lines">@@ -1243,7 +1254,7 @@
</span><span class="cx">     if (needToDumpOptions)
</span><span class="cx">         JSC::Options::dumpAllOptions(stderr);
</span><span class="cx">     if (needToExit)
</span><del>-        exit(EXIT_SUCCESS);
</del><ins>+        jscExit(EXIT_SUCCESS);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> int jscmain(int argc, char** argv)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/JavaScriptCore/runtime/Structure.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2009, 2012, 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">@@ -370,6 +370,22 @@
</span><span class="cx">     {
</span><span class="cx">         return m_transitionWatchpointSet.isStillValid();
</span><span class="cx">     }
</span><ins>+    
+    bool dfgShouldWatchIfPossible() const
+    {
+        // FIXME: We would like to not watch things that are unprofitable to watch, like
+        // dictionaries. Unfortunately, we can't do such things: a dictionary could get flattened,
+        // in which case it will start to appear watchable and so the DFG will think that it is
+        // watching it. We should come up with a comprehensive story for not watching things that
+        // aren't profitable to watch.
+        // https://bugs.webkit.org/show_bug.cgi?id=133625
+        return true;
+    }
+    
+    bool dfgShouldWatch() const
+    {
+        return dfgShouldWatchIfPossible() &amp;&amp; transitionWatchpointSetIsStillValid();
+    }
</ins><span class="cx">         
</span><span class="cx">     void addTransitionWatchpoint(Watchpoint* watchpoint) const
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayifytostructurecontradictionjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/arrayify-to-structure-contradiction.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/arrayify-to-structure-contradiction.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/arrayify-to-structure-contradiction.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(array, v, p) {
+    array[0] = 10;
+    if (p)
+        v = &quot;hello&quot;;
+    array[0] = v;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var array = [42];
+    foo(array, 43, false);
+    if (array[0] != 43)
+        throw &quot;Error: bad result: &quot; + array;
+}
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftlgetmyargumentslengthinlinejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-getmyargumentslength-inline.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-getmyargumentslength-inline.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-getmyargumentslength-inline.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+function foo(){
+    return arguments.length;
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var r = foo(11, 12, 13, 18, 19, 20);
+    if (r != 6) throw &quot;Error: &quot;+r;
+}
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibraryexceptionjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-exception.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-exception.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-exception.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function foo(d){
+    return Date.prototype.getTimezoneOffset.call(d);
+}
+
+noInline(foo);
+
+var x;
+var count = 100000;
+var z = 0;
+for (var i = 0 ; i &lt; count; i++){
+    try { 
+        var q = foo(i &lt; count - 10 ? new Date() : &quot;a&quot;);
+        x = false;
+        z = q;
+    } catch (e) {
+        x = true;
+    }
+}
+
+if (!x)
+    throw &quot;bad result: &quot;+ x;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibraryinlinegettimezoneoffsetjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-inline-gettimezoneoffset.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-inline-gettimezoneoffset.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-inline-gettimezoneoffset.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(x, d){
+    return x + d.getTimezoneOffset();
+}
+
+noInline(foo);
+
+var d = new Date();
+var expected = foo(0, d);
+var count = 1000000;
+var result = 0;
+for (var i = 0 ; i &lt; count; i++){
+    result += foo(0, d);
+}
+
+if (result != count * expected)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibraryinliningexceptionsdataviewjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions-dataview.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions-dataview.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions-dataview.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function foo(d){
+    return d.getInt8(42);
+}
+
+noInline(foo);
+
+var d = new DataView(new ArrayBuffer(43));
+d.setInt8(42, 43);
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo(d);
+    if (result != 43)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+for (var i = 0; i &lt; 10; ++i) {
+    var didThrow = false;
+    try {
+        foo(new DataView(new ArrayBuffer(42)));
+    } catch (e) {
+        didThrow = true;
+        if (e.message.indexOf(&quot;Out of bounds&quot;) &lt; 0)
+            throw &quot;Error: bad exception: &quot; + e.message;
+    }
+    if (!didThrow)
+        throw &quot;Error: did not throw&quot;;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibraryinliningexceptionsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-exceptions.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function foo(d){
+    return Date.prototype.getTimezoneOffset.call(d);
+}
+
+noInline(foo);
+
+var x;
+var count = 100000;
+for (var i = 0 ; i &lt; count; i++){
+    try { 
+        foo(i &lt; count - 1000 ? new Date() : &quot;a&quot;);
+        x = false;
+    } catch (e) {
+        x = true;
+    }
+}
+
+if (!x)
+    throw &quot;bad result: &quot;+ x;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibraryinliningloopsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-loops.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-loops.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-loops.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+function foo(){
+    var count = 100;
+    var d = new DataView(new ArrayBuffer(count));
+
+    for (var i = 0; i &lt; count / 4; i++){
+        d.setInt32(i, i);
+    }
+
+    for (var i = 0; i &lt; count; i++){
+        d.setInt8(i, i);
+    }
+    var result = 0;
+    for (var i = 0; i &lt; count; i++){
+        result += d.getInt8(i);
+    }
+    return result;
+}
+
+noInline(foo);
+
+var r = 0;
+for (var i = 0 ; i &lt; 50000; i++){
+    r += foo();
+}
+
+if (r != 247500000)
+    throw &quot;Bad result: &quot; + r;
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibraryinliningrandomjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-random.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-random.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-inlining-random.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function foo(x){
+    return Math.random(x);
+}
+
+noInline(foo);
+
+var x = 0;
+
+for (var i = 0 ; i &lt; 100000; i++){
+    x = foo(i);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftllibrarysubstringjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-library-substring.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-library-substring.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-library-substring.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(i, x){
+    return x.substring( 2 , 5);
+}
+
+noInline(foo);
+
+var x = &quot;&quot;;
+
+for (var i = 0 ; i &lt; 100000; i++){
+    x = foo(i, &quot;lkajsx&quot;);
+}
+
+if (x != &quot;ajs&quot;)
+    throw &quot;Error: bad substring: &quot;+ x;
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmultiputbyoffsetmultipletransitionsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/multi-put-by-offset-multiple-transitions.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/multi-put-by-offset-multiple-transitions.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/multi-put-by-offset-multiple-transitions.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+function foo(o) {
+    o.x = 1;
+    o.y = 2;
+    o.a = 3;
+    o.b = 4;
+    o.c = 5;
+    o.d = 6;
+    o.e = 7;
+    o.f = 8;
+    o.g = 9;
+    o.h = 10;
+    o.i = 11;
+}
+
+noInline(foo);
+
+function Foo() {
+    foo(this);
+}
+
+var result = 0;
+
+for (var i = 0; i &lt; 100000; ++i) {
+    foo({f:42});
+    result += (new Foo()).x;
+}
+
+if (result != 100000)
+    throw &quot;Bad result: &quot; + result;
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressthrowfromftlinloopjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-in-loop.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-in-loop.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl-in-loop.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+var didThrow = false;
+try {
+    (function() {
+        for (var i = 0; i &lt; 1000000; ++i) { }
+        throw 42;
+    })();
+} catch (e) {
+    if (e != 42)
+        throw &quot;Error: bad result: &quot; + e;
+    didThrow = true;
+}
+if (!didThrow)
+    throw &quot;Error: should have thrown but didn't.&quot;;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressthrowfromftljs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl.js (0 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/throw-from-ftl.js        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+function foo(p) {
+    var o = {f:42};
+    if (p)
+        throw o;
+    return o;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var o = foo(false);
+    if (o.f != 42)
+        throw &quot;Error: bad result: &quot; + o.f;
+}
+
+var didThrow = false;
+try {
+    foo(true);
+} catch (e) {
+    if (e.f != 42)
+        throw &quot;Error: bad result in catch: &quot; + o.f;
+    didThrow = true;
+}
+if (!didThrow)
+    throw &quot;Error: should have thrown but didn't.&quot;;
</ins></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/WTF/ChangeLog        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -1,5 +1,20 @@
</span><span class="cx"> 2014-07-22  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r169148, r169185, r169188, r169578, r169582, r169584, r169588, r169753 from ftlopt.
+
+    2014-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] AI should be able track structure sets larger than 1
+            https://bugs.webkit.org/show_bug.cgi?id=128073
+    
+            Reviewed by Oliver Hunt.
+    
+            * wtf/Bag.h:
+            (WTF::Bag::Node::Node):
+            (WTF::Bag::add):
+    
+2014-07-22  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         Merge r168635, r168780, r169005, r169014, and r169143 from ftlopt.
</span><span class="cx"> 
</span><span class="cx">     2014-05-20  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span></span></pre></div>
<a id="trunkSourceWTFwtfBagh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bag.h (171379 => 171380)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bag.h        2014-07-23 01:12:32 UTC (rev 171379)
+++ trunk/Source/WTF/wtf/Bag.h        2014-07-23 01:19:50 UTC (rev 171380)
</span><span class="lines">@@ -34,6 +34,12 @@
</span><span class="cx">     class Node {
</span><span class="cx">         WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     public:
</span><ins>+        template&lt;typename... Args&gt;
+        Node(Args... args)
+            : m_item(args...)
+        {
+        }
+        
</ins><span class="cx">         T m_item;
</span><span class="cx">         Node* m_next;
</span><span class="cx">     };
</span><span class="lines">@@ -53,9 +59,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    T* add()
</del><ins>+    template&lt;typename... Args&gt;
+    T* add(Args... args)
</ins><span class="cx">     {
</span><del>-        Node* newNode = new Node;
</del><ins>+        Node* newNode = new Node(args...);
</ins><span class="cx">         newNode-&gt;m_next = m_head;
</span><span class="cx">         m_head = newNode;
</span><span class="cx">         return &amp;newNode-&gt;m_item;
</span></span></pre>
</div>
</div>

</body>
</html>