<!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>[172129] 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/172129">172129</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-08-05 22:27:46 -0700 (Tue, 05 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/170564">r170564</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170571">r170571</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170604">r170604</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170628">r170628</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170672">r170672</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170680">r170680</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170724">r170724</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170728">r170728</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170729">r170729</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170819">r170819</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170821">r170821</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170836">r170836</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170855">r170855</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170860">r170860</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170890">r170890</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170907">r170907</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/170929">r170929</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/171052">r171052</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/171106">r171106</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/171152">r171152</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/171153">r171153</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/171214">r171214</a> from ftlopt.

Source/JavaScriptCore:

This part of the merge delivers roughly a 2% across-the-board performance
improvement, mostly due to immutable property inference and DFG-side GCSE. It also
almost completely resolves accessor performance issues; in the common case the DFG
will compile a getter/setter access into code that is just as efficient as a normal
property access.
        
Another major highlight of this part of the merge is the work to add a type profiler
to the inspector. This work is still on-going but this greatly increases coverage.

Note that this merge fixes a minor bug in the GetterSetter refactoring from
http://trac.webkit.org/changeset/170729 (https://bugs.webkit.org/show_bug.cgi?id=134518).
It also adds a new tests to tests/stress to cover that bug. That bug was previously only
covered by layout tests.

    2014-07-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw (merge trunk <a href="http://trac.webkit.org/projects/webkit/changeset/171190">r171190</a>)
    https://bugs.webkit.org/show_bug.cgi?id=135019
    
    Reviewed by Oliver Hunt.
            
    Behaviorally, this is just a merge of trunk <a href="http://trac.webkit.org/projects/webkit/changeset/171190">r171190</a>, except that the relevant functionality
    has moved to StrengthReductionPhase and is written in a different style. Same algorithm,
    different code.
    
    * dfg/DFGNodeType.h:
    * dfg/DFGStrengthReductionPhase.cpp:
    (JSC::DFG::StrengthReductionPhase::handleNode):
    * tests/stress/capture-escape-and-throw.js: Added.
    (foo.f):
    (foo):
    * tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
    (foo):
    (bar):
    
    2014-07-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Constant fold GetGetter and GetSetter if the GetterSetter is a constant
    https://bugs.webkit.org/show_bug.cgi?id=134962
    
    Reviewed by Oliver Hunt.
            
    This removes yet another steady-state-throughput implication of using getters and setters:
    if your accessor call is monomorphic then you'll just get a structure check, nothing more.
    No more loads to get to the GetterSetter object or the accessor function object.
    
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
    * runtime/GetterSetter.h:
    (JSC::GetterSetter::getterConcurrently):
    (JSC::GetterSetter::setGetter):
    (JSC::GetterSetter::setterConcurrently):
    (JSC::GetterSetter::setSetter):
    
    2014-07-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Identity replacement in CSE shouldn't create a Phantom over the Identity's children
    https://bugs.webkit.org/show_bug.cgi?id=134893
    
    Reviewed by Oliver Hunt.
            
    Replace Identity with Check instead of Phantom. Phantom means that the child of the
    Identity should be unconditionally live. The liveness semantics of Identity are such that
    if the parents of Identity are live then the child is live. Removing the Identity entirely
    preserves such liveness semantics. So, the only thing that should be left behind is the
    type check on the child, which is what Check means: do the check but don't keep the child
    alive if the check isn't needed.
    
    * dfg/DFGCSEPhase.cpp:
    * dfg/DFGNode.h:
    (JSC::DFG::Node::convertToCheck):
    
    2014-07-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] DFG should be able to do GCSE in SSA and this should be unified with the CSE in CPS, and both of these things should use abstract heaps for reasoning about effects
    https://bugs.webkit.org/show_bug.cgi?id=134677
    
    Reviewed by Sam Weinig.
            
    This removes the old local CSE phase, which was based on manually written backward-search 
    rules for all of the different kinds of things we cared about, and adds a new local/global
    CSE (local for CPS and global for SSA) that leaves the node semantics almost entirely up to
    clobberize(). Thus, the CSE phase itself just worries about the algorithms and data
    structures used for storing sets of available values. This results in a large reduction in
    code size in CSEPhase.cpp while greatly increasing the phase's power (since it now does
    global CSE) and reducing compile time (since local CSE is now rewritten to use smarter data
    structures). Even though LLVM was already running GVN, the extra GCSE at DFG IR level means
    that this is a significant (~0.7%) throughput improvement.
            
    This work is based on the concept of &quot;def&quot; to clobberize(). If clobberize() calls def(), it
    means that the node being analyzed makes available some value in some DFG node, and that
    future attempts to compute that value can simply use that node. In other words, it
    establishes an available value mapping of the form value=&gt;node. There are two kinds of
    values that can be passed to def():
            
    PureValue. This captures everything needed to determine whether two pure nodes - nodes that
        neither read nor write, and produce a value that is a CSE candidate - are identical. It
        carries the NodeType, an AdjacencyList, and one word of meta-data. The meta-data is
        usually used for things like the arithmetic mode or constant pointer. Passing a
        PureValue to def() means that the node produces a value that is valid anywhere that the
        node dominates.
            
    HeapLocation. This describes a location in the heap that could be written to or read from.
        Both stores and loads can def() a HeapLocation. HeapLocation carries around an abstract
        heap that both serves as part of the &quot;name&quot; of the heap location (together with the
        other fields of HeapLocation) and also tells us what write()'s to watch for. If someone
        write()'s to an abstract heap that overlaps the heap associated with the HeapLocation,
        then it means that the values for that location are no longer available.
            
    This approach is sufficiently clever that the CSEPhase itself can focus on the mechanism of
    tracking the PureValue=&gt;node and HeapLocation=&gt;node maps, without having to worry about
    interpreting the semantics of different DFG node types - that is now almost entirely in
    clobberize(). The only things we special-case inside CSEPhase are the Identity node, which
    CSE is traditionally responsible for eliminating even though it has nothing to do with CSE,
    and the LocalCSE rule for turning PutByVal into PutByValAlias.
            
    This is a slight Octane, SunSpider, and Kraken speed-up - all somewhere arond 0.7% . It's
    not a bigger win because LLVM was already giving us most of what we needed in its GVN.
    Also, the SunSpider speed-up isn't from GCSE as much as it's a clean-up of local CSE - that
    is no longer O(n^2). Basically this is purely good: it reduces the amount of LLVM IR we
    generate, it removes the old CSE's heap modeling (which was a constant source of bugs), and
    it improves both the quality of the code we generate and the speed with which we generate
    it. Also, any future optimizations that depend on GCSE will now be easier to implement.
            
    During the development of this patch I also rationalized some other stuff, like Graph's
    ordered traversals - we now have preorder and postorder rather than just &quot;depth first&quot;.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * dfg/DFGAbstractHeap.h:
    * dfg/DFGAdjacencyList.h:
    (JSC::DFG::AdjacencyList::hash):
    (JSC::DFG::AdjacencyList::operator==):
    * dfg/DFGBasicBlock.h:
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::performLocalCSE):
    (JSC::DFG::performGlobalCSE):
    (JSC::DFG::CSEPhase::CSEPhase): Deleted.
    (JSC::DFG::CSEPhase::run): Deleted.
    (JSC::DFG::CSEPhase::endIndexForPureCSE): Deleted.
    (JSC::DFG::CSEPhase::pureCSE): Deleted.
    (JSC::DFG::CSEPhase::constantCSE): Deleted.
    (JSC::DFG::CSEPhase::constantStoragePointerCSE): Deleted.
    (JSC::DFG::CSEPhase::getCalleeLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::getArrayLengthElimination): Deleted.
    (JSC::DFG::CSEPhase::globalVarLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::scopedVarLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::varInjectionWatchpointElimination): Deleted.
    (JSC::DFG::CSEPhase::getByValLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::checkFunctionElimination): Deleted.
    (JSC::DFG::CSEPhase::checkExecutableElimination): Deleted.
    (JSC::DFG::CSEPhase::checkStructureElimination): Deleted.
    (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): Deleted.
    (JSC::DFG::CSEPhase::getByOffsetLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::getGetterSetterByOffsetLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::checkArrayElimination): Deleted.
    (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::getInternalFieldLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::getMyScopeLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::getLocalLoadElimination): Deleted.
    (JSC::DFG::CSEPhase::invalidationPointElimination): Deleted.
    (JSC::DFG::CSEPhase::setReplacement): Deleted.
    (JSC::DFG::CSEPhase::eliminate): Deleted.
    (JSC::DFG::CSEPhase::performNodeCSE): Deleted.
    (JSC::DFG::CSEPhase::performBlockCSE): Deleted.
    (JSC::DFG::performCSE): Deleted.
    * dfg/DFGCSEPhase.h:
    * dfg/DFGClobberSet.cpp:
    (JSC::DFG::addReads):
    (JSC::DFG::addWrites):
    (JSC::DFG::addReadsAndWrites):
    (JSC::DFG::readsOverlap):
    (JSC::DFG::writesOverlap):
    * dfg/DFGClobberize.cpp:
    (JSC::DFG::doesWrites):
    (JSC::DFG::accessesOverlap):
    (JSC::DFG::writesOverlap):
    * dfg/DFGClobberize.h:
    (JSC::DFG::clobberize):
    (JSC::DFG::NoOpClobberize::operator()):
    (JSC::DFG::CheckClobberize::operator()):
    (JSC::DFG::ReadMethodClobberize::ReadMethodClobberize):
    (JSC::DFG::ReadMethodClobberize::operator()):
    (JSC::DFG::WriteMethodClobberize::WriteMethodClobberize):
    (JSC::DFG::WriteMethodClobberize::operator()):
    (JSC::DFG::DefMethodClobberize::DefMethodClobberize):
    (JSC::DFG::DefMethodClobberize::operator()):
    * dfg/DFGDCEPhase.cpp:
    (JSC::DFG::DCEPhase::run):
    (JSC::DFG::DCEPhase::fixupBlock):
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::getBlocksInPreOrder):
    (JSC::DFG::Graph::getBlocksInPostOrder):
    (JSC::DFG::Graph::addForDepthFirstSort): Deleted.
    (JSC::DFG::Graph::getBlocksInDepthFirstOrder): Deleted.
    * dfg/DFGGraph.h:
    * dfg/DFGHeapLocation.cpp: Added.
    (JSC::DFG::HeapLocation::dump):
    (WTF::printInternal):
    * dfg/DFGHeapLocation.h: Added.
    (JSC::DFG::HeapLocation::HeapLocation):
    (JSC::DFG::HeapLocation::operator!):
    (JSC::DFG::HeapLocation::kind):
    (JSC::DFG::HeapLocation::heap):
    (JSC::DFG::HeapLocation::base):
    (JSC::DFG::HeapLocation::index):
    (JSC::DFG::HeapLocation::hash):
    (JSC::DFG::HeapLocation::operator==):
    (JSC::DFG::HeapLocation::isHashTableDeletedValue):
    (JSC::DFG::HeapLocationHash::hash):
    (JSC::DFG::HeapLocationHash::equal):
    * dfg/DFGLICMPhase.cpp:
    (JSC::DFG::LICMPhase::run):
    * dfg/DFGNode.h:
    (JSC::DFG::Node::replaceWith):
    (JSC::DFG::Node::convertToPhantomUnchecked): Deleted.
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::compileInThreadImpl):
    * dfg/DFGPureValue.cpp: Added.
    (JSC::DFG::PureValue::dump):
    * dfg/DFGPureValue.h: Added.
    (JSC::DFG::PureValue::PureValue):
    (JSC::DFG::PureValue::operator!):
    (JSC::DFG::PureValue::op):
    (JSC::DFG::PureValue::children):
    (JSC::DFG::PureValue::info):
    (JSC::DFG::PureValue::hash):
    (JSC::DFG::PureValue::operator==):
    (JSC::DFG::PureValue::isHashTableDeletedValue):
    (JSC::DFG::PureValueHash::hash):
    (JSC::DFG::PureValueHash::equal):
    * dfg/DFGSSAConversionPhase.cpp:
    (JSC::DFG::SSAConversionPhase::run):
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::LowerDFGToLLVM::lower):
    
    2014-07-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    Unreviewed, revert unintended change in <a href="http://trac.webkit.org/projects/webkit/changeset/171051">r171051</a>.
    
    * dfg/DFGCSEPhase.cpp:
    
    2014-07-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Move Flush(SetLocal) store elimination to StrengthReductionPhase
    https://bugs.webkit.org/show_bug.cgi?id=134739
    
    Reviewed by Mark Hahnenberg.
            
    I'm going to streamline CSE around clobberize() as part of
    https://bugs.webkit.org/show_bug.cgi?id=134677, and so Flush(SetLocal) store
    elimination wouldn't belong in CSE anymore. It doesn't quite belong anywhere, which
    means that it belongs in StrengthReductionPhase, since that's intended to be our
    dumping ground.
            
    To do this I had to add some missing smarts to clobberize(). Previously clobberize()
    could play a bit loose with reads of Variables because it wasn't used for store
    elimination. The main client of read() was LICM, but it would only use it to
    determine hoistability and anything that did a write() was not hoistable - so, we had
    benign (but still wrong) missing read() calls in places that did write()s. This fixes
    a bunch of those cases.
    
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::CSEPhase::performNodeCSE):
    (JSC::DFG::CSEPhase::setLocalStoreElimination): Deleted.
    * dfg/DFGClobberize.cpp:
    (JSC::DFG::accessesOverlap):
    * dfg/DFGClobberize.h:
    (JSC::DFG::clobberize): Make clobberize() smart enough for detecting when this store elimination would be sound.
    * dfg/DFGStrengthReductionPhase.cpp:
    (JSC::DFG::StrengthReductionPhase::handleNode): Implement the store elimination in terms of clobberize().
    
    2014-07-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Phantom simplification should be in its own phase
    https://bugs.webkit.org/show_bug.cgi?id=134742
    
    Reviewed by Geoffrey Garen.
            
    This moves Phantom simplification out of CSE, which greatly simplifies CSE and gives it
    more focus. Also this finally adds a phase that removes empty Phantoms. We sort of had
    this in CPSRethreading, but that phase runs too infrequently and doesn't run at all for
    SSA.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * dfg/DFGAdjacencyList.h:
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::CSEPhase::run):
    (JSC::DFG::CSEPhase::setReplacement):
    (JSC::DFG::CSEPhase::eliminate):
    (JSC::DFG::CSEPhase::performNodeCSE):
    (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren): Deleted.
    * dfg/DFGPhantomRemovalPhase.cpp: Added.
    (JSC::DFG::PhantomRemovalPhase::PhantomRemovalPhase):
    (JSC::DFG::PhantomRemovalPhase::run):
    (JSC::DFG::performCleanUp):
    * dfg/DFGPhantomRemovalPhase.h: Added.
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::compileInThreadImpl):
    
    2014-07-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Get rid of Node::misc by moving the fields out of the union so that you can use replacement and owner simultaneously
    https://bugs.webkit.org/show_bug.cgi?id=134730
    
    Reviewed by Mark Lam.
            
    This will allow for a better GCSE implementation.
    
    * dfg/DFGCPSRethreadingPhase.cpp:
    (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::CSEPhase::setReplacement):
    * dfg/DFGEdgeDominates.h:
    (JSC::DFG::EdgeDominates::operator()):
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::clearReplacements):
    (JSC::DFG::Graph::initializeNodeOwners):
    * dfg/DFGGraph.h:
    (JSC::DFG::Graph::performSubstitutionForEdge):
    * dfg/DFGLICMPhase.cpp:
    (JSC::DFG::LICMPhase::attemptHoist):
    * dfg/DFGNode.h:
    (JSC::DFG::Node::Node):
    * dfg/DFGSSAConversionPhase.cpp:
    (JSC::DFG::SSAConversionPhase::run):
    
    2014-07-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Infer immutable object properties
    https://bugs.webkit.org/show_bug.cgi?id=134567
    
    Reviewed by Mark Hahnenberg.
            
    This introduces a new way of inferring immutable object properties. A property is said to
    be immutable if after its creation (i.e. the transition that creates it), we never
    overwrite it (i.e. replace it) or delete it. Immutability is a property of an &quot;own
    property&quot; - so if we say that &quot;f&quot; is immutable at &quot;o&quot; then we are implying that &quot;o&quot; has &quot;f&quot;
    directly and not on a prototype. More specifically, the immutability inference will prove
    that a property on some structure is immutable. This means that, for example, we may have a
    structure S1 with property &quot;f&quot; where we claim that &quot;f&quot; at S1 is immutable, but S1 has a
    transition to S2 that adds a new property &quot;g&quot; and we may claim that &quot;f&quot; at S2 is actually
    mutable. This is mainly for convenience; it allows us to decouple immutability logic from
    transition logic. Immutability can be used to constant-fold accesses to objects at
    DFG-time. The DFG needs to prove the following to constant-fold the access:
            
    - The base of the access must be a constant object pointer. We prove that a property at a
      structure is immutable, but that says nothing of its value; each actual instance of that
      property may have a different value. So, a constant object pointer is needed to get an
      actual constant instance of the immutable value.
            
    - A check (or watchpoint) must have been emitted proving that the object has a structure
      that allows loading the property in question.
            
    - The replacement watchpoint set of the property in the structure that we've proven the
      object to have is still valid and we add a watchpoint to it lazily. The replacement
      watchpoint set is the key new mechanism that this change adds. It's possible that we have
      proven that the object has one of many structures, in which case each of those structures
      needs a valid replacement watchpoint set.
            
    The replacement watchpoint set is created the first time that any access to the property is
    cached. A put replace cache will create, and immediately invalidate, the watchpoint set. A
    get cache will create the watchpoint set and make it start watching. Any non-cached put
    access will invalidate the watchpoint set if one had been created; the underlying algorithm
    ensures that checking for the existence of a replacement watchpoint set is very fast in the
    common case. This algorithm ensures that no cached access needs to ever do any work to
    invalidate, or check the validity of, any replacement watchpoint sets. It also has some
    other nice properties:
            
    - It's very robust in its definition of immutability. The strictest that it will ever be is
      that for any instance of the object, the property must be written to only once,
      specifically at the time that the property is created. But it's looser than this in
      practice. For example, the property may be written to any number of times before we add
      the final property that the object will have before anyone reads the property; this works
      since for optimization purposes we only care if we detect immutability on the structure
      that the object will have when it is most frequently read from, not any previous
      structure that the object had. Also, we may write to the property any number of times
      before anyone caches accesses to it.
            
    - It is mostly orthogonal to structure transitions. No new structures need to be created to
      track the immutability of a property. Hence, there is no risk from this feature causing
      more polymorphism. This is different from the previous &quot;specificValue&quot; constant
      inference, which did cause additional structures to be created and sometimes those
      structures led to fake polymorphism. This feature does leverage existing transitions to
      do some of the watchpointing: property deletions don't fire the replacement watchpoint
      set because that would cause a new structure and so the mandatory structure check would
      fail. Also, this feature is guaranteed to never kick in for uncacheable dictionaries
      because those wouldn't allow for cacheable accesses - and it takes a cacheable access for
      this feature to be enabled.
            
    - No memory overhead is incurred except when accesses to the property are cached.
      Dictionary properties will typically have no meta-data for immutability. The number of
      replacement watchpoint sets we allocate is proportional to the number of inline caches in
      the program, which is typically must smaller than the number of structures or even the
      number of objects.
            
    This inference is far more powerful than the previous &quot;specificValue&quot; inference, so this
    change also removes all of that code. It's interesting that the amount of code that is
    changed to remove that feature is almost as big as the amount of code added to support the
    new inference - and that's if you include the new tests in the tally. Without new tests,
    it appears that the new feature actually touches less code!
            
    There is one corner case where the previous &quot;specificValue&quot; inference was more powerful.
    You can imagine someone creating objects with functions as self properties on those
    objects, such that each object instance had the same function pointers - essentially,
    someone might be trying to create a vtable but failing at the whole &quot;one vtable for many
    instances&quot; concept. The &quot;specificValue&quot; inference would do very well for such programs,
    because a structure check would be sufficient to prove a constant value for all of the
    function properties. This new inference will fail because it doesn't track the constant
    values of constant properties; instead it detects the immutability of otherwise variable
    properties (in the sense that each instance of the property may have a different value).
    So, the new inference requires having a particular object instance to actually get the
    constant value. I think it's OK to lose this antifeature. It took a lot of code to support
    and was a constant source of grief in our transition logic, and there doesn't appear to be
    any real evidence that programs benefited from that particular kind of inference since
    usually it's the singleton prototype instance that has all of the functions.
            
    This change is a speed-up on everything. date-format-xparb and both SunSpider/raytrace and
    V8/raytrace seem to be the biggest winners among the macrobenchmarks; they see &gt;5%
    speed-ups. Many of our microbenchmarks see very large performance improvements, even 80% in
    one case.
    
    * bytecode/ComplexGetStatus.cpp:
    (JSC::ComplexGetStatus::computeFor):
    * bytecode/GetByIdStatus.cpp:
    (JSC::GetByIdStatus::computeFromLLInt):
    (JSC::GetByIdStatus::computeForStubInfo):
    (JSC::GetByIdStatus::computeFor):
    * bytecode/GetByIdVariant.cpp:
    (JSC::GetByIdVariant::GetByIdVariant):
    (JSC::GetByIdVariant::operator=):
    (JSC::GetByIdVariant::attemptToMerge):
    (JSC::GetByIdVariant::dumpInContext):
    * bytecode/GetByIdVariant.h:
    (JSC::GetByIdVariant::alternateBase):
    (JSC::GetByIdVariant::specificValue): Deleted.
    * bytecode/PutByIdStatus.cpp:
    (JSC::PutByIdStatus::computeForStubInfo):
    (JSC::PutByIdStatus::computeFor):
    * bytecode/PutByIdVariant.cpp:
    (JSC::PutByIdVariant::operator=):
    (JSC::PutByIdVariant::setter):
    (JSC::PutByIdVariant::dumpInContext):
    * bytecode/PutByIdVariant.h:
    (JSC::PutByIdVariant::specificValue): Deleted.
    * bytecode/Watchpoint.cpp:
    (JSC::WatchpointSet::fireAllSlow):
    (JSC::WatchpointSet::fireAll): Deleted.
    * bytecode/Watchpoint.h:
    (JSC::WatchpointSet::fireAll):
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::handleGetByOffset):
    (JSC::DFG::ByteCodeParser::handleGetById):
    (JSC::DFG::ByteCodeParser::handlePutById):
    (JSC::DFG::ByteCodeParser::parseBlock):
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
    * dfg/DFGFixupPhase.cpp:
    (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
    (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::tryGetConstantProperty):
    (JSC::DFG::Graph::visitChildren):
    * dfg/DFGGraph.h:
    * dfg/DFGWatchableStructureWatchingPhase.cpp:
    (JSC::DFG::WatchableStructureWatchingPhase::run):
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
    * jit/JITOperations.cpp:
    * jit/Repatch.cpp:
    (JSC::repatchByIdSelfAccess):
    (JSC::generateByIdStub):
    (JSC::tryCacheGetByID):
    (JSC::tryCachePutByID):
    (JSC::tryBuildPutByIdList):
    * llint/LLIntSlowPaths.cpp:
    (JSC::LLInt::LLINT_SLOW_PATH_DECL):
    (JSC::LLInt::putToScopeCommon):
    * runtime/CommonSlowPaths.h:
    (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
    * runtime/IntendedStructureChain.cpp:
    (JSC::IntendedStructureChain::mayInterceptStoreTo):
    * runtime/JSCJSValue.cpp:
    (JSC::JSValue::putToPrimitive):
    * runtime/JSGlobalObject.cpp:
    (JSC::JSGlobalObject::reset):
    * runtime/JSObject.cpp:
    (JSC::JSObject::put):
    (JSC::JSObject::putDirectNonIndexAccessor):
    (JSC::JSObject::deleteProperty):
    (JSC::JSObject::defaultValue):
    (JSC::getCallableObjectSlow): Deleted.
    (JSC::JSObject::getPropertySpecificValue): Deleted.
    * runtime/JSObject.h:
    (JSC::JSObject::getDirect):
    (JSC::JSObject::getDirectOffset):
    (JSC::JSObject::inlineGetOwnPropertySlot):
    (JSC::JSObject::putDirectInternal):
    (JSC::JSObject::putOwnDataProperty):
    (JSC::JSObject::putDirect):
    (JSC::JSObject::putDirectWithoutTransition):
    (JSC::getCallableObject): Deleted.
    * runtime/JSScope.cpp:
    (JSC::abstractAccess):
    * runtime/PropertyMapHashTable.h:
    (JSC::PropertyMapEntry::PropertyMapEntry):
    (JSC::PropertyTable::copy):
    * runtime/PropertyTable.cpp:
    (JSC::PropertyTable::clone):
    (JSC::PropertyTable::PropertyTable):
    (JSC::PropertyTable::visitChildren): Deleted.
    * runtime/Structure.cpp:
    (JSC::Structure::Structure):
    (JSC::Structure::materializePropertyMap):
    (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
    (JSC::Structure::addPropertyTransitionToExistingStructure):
    (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
    (JSC::Structure::addPropertyTransition):
    (JSC::Structure::changePrototypeTransition):
    (JSC::Structure::attributeChangeTransition):
    (JSC::Structure::toDictionaryTransition):
    (JSC::Structure::preventExtensionsTransition):
    (JSC::Structure::takePropertyTableOrCloneIfPinned):
    (JSC::Structure::nonPropertyTransition):
    (JSC::Structure::addPropertyWithoutTransition):
    (JSC::Structure::allocateRareData):
    (JSC::Structure::ensurePropertyReplacementWatchpointSet):
    (JSC::Structure::startWatchingPropertyForReplacements):
    (JSC::Structure::didCachePropertyReplacement):
    (JSC::Structure::startWatchingInternalProperties):
    (JSC::Structure::copyPropertyTable):
    (JSC::Structure::copyPropertyTableForPinning):
    (JSC::Structure::getConcurrently):
    (JSC::Structure::get):
    (JSC::Structure::add):
    (JSC::Structure::visitChildren):
    (JSC::Structure::prototypeChainMayInterceptStoreTo):
    (JSC::Structure::dump):
    (JSC::Structure::despecifyDictionaryFunction): Deleted.
    (JSC::Structure::despecifyFunctionTransition): Deleted.
    (JSC::Structure::despecifyFunction): Deleted.
    (JSC::Structure::despecifyAllFunctions): Deleted.
    (JSC::Structure::putSpecificValue): Deleted.
    * runtime/Structure.h:
    (JSC::Structure::startWatchingPropertyForReplacements):
    (JSC::Structure::startWatchingInternalPropertiesIfNecessary):
    (JSC::Structure::startWatchingInternalPropertiesIfNecessaryForEntireChain):
    (JSC::Structure::transitionDidInvolveSpecificValue): Deleted.
    (JSC::Structure::disableSpecificFunctionTracking): Deleted.
    * runtime/StructureInlines.h:
    (JSC::Structure::getConcurrently):
    (JSC::Structure::didReplaceProperty):
    (JSC::Structure::propertyReplacementWatchpointSet):
    * runtime/StructureRareData.cpp:
    (JSC::StructureRareData::destroy):
    * runtime/StructureRareData.h:
    * tests/stress/infer-constant-global-property.js: Added.
    (foo.Math.sin):
    (foo):
    * tests/stress/infer-constant-property.js: Added.
    (foo):
    * tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js: Added.
    (foo):
    (bar):
    * tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js: Added.
    (foo):
    (bar):
    * tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js: Added.
    (foo):
    (bar):
    * tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js: Added.
    (foo):
    (bar):
    * tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js: Added.
    (foo):
    (bar):
    * tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js: Added.
    (foo):
    (bar):
    
    2014-07-03  Saam Barati  &lt;sbarati@apple.com&gt;
    
    Add more coverage for the profile_types_with_high_fidelity op code.
    https://bugs.webkit.org/show_bug.cgi?id=134616
    
    Reviewed by Filip Pizlo.
    
    More operations are now being recorded by the profile_types_with_high_fidelity 
    opcode. Specifically: function parameters, function return values,
    function 'this' value, get_by_id, get_by_value, resolve nodes, function return 
    values at the call site. Added more flags to the profile_types_with_high_fidelity
    opcode so more focused tasks can take place when the instruction is
    being linked in CodeBlock. Re-worked the type profiler to search 
    through character offset ranges when asked for the type of an expression
    at a given offset. Removed redundant calls to Structure::toStructureShape
    in HighFidelityLog and TypeSet by caching calls based on StructureID.
    
    * bytecode/BytecodeList.json:
    * bytecode/BytecodeUseDef.h:
    (JSC::computeUsesForBytecodeOffset):
    (JSC::computeDefsForBytecodeOffset):
    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::CodeBlock):
    (JSC::CodeBlock::finalizeUnconditionally):
    (JSC::CodeBlock::scopeDependentProfile):
    * bytecode/CodeBlock.h:
    (JSC::CodeBlock::returnStatementTypeSet):
    * bytecode/TypeLocation.h:
    * bytecode/UnlinkedCodeBlock.cpp:
    (JSC::UnlinkedCodeBlock::highFidelityTypeProfileExpressionInfoForBytecodeOffset):
    (JSC::UnlinkedCodeBlock::addHighFidelityTypeProfileExpressionInfo):
    * bytecode/UnlinkedCodeBlock.h:
    * bytecompiler/BytecodeGenerator.cpp:
    (JSC::BytecodeGenerator::emitMove):
    (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
    (JSC::BytecodeGenerator::emitGetFromScopeWithProfile):
    (JSC::BytecodeGenerator::emitPutToScope):
    (JSC::BytecodeGenerator::emitPutToScopeWithProfile):
    (JSC::BytecodeGenerator::emitPutById):
    (JSC::BytecodeGenerator::emitPutByVal):
    * bytecompiler/BytecodeGenerator.h:
    (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
    * bytecompiler/NodesCodegen.cpp:
    (JSC::ResolveNode::emitBytecode):
    (JSC::BracketAccessorNode::emitBytecode):
    (JSC::DotAccessorNode::emitBytecode):
    (JSC::FunctionCallValueNode::emitBytecode):
    (JSC::FunctionCallResolveNode::emitBytecode):
    (JSC::FunctionCallBracketNode::emitBytecode):
    (JSC::FunctionCallDotNode::emitBytecode):
    (JSC::CallFunctionCallDotNode::emitBytecode):
    (JSC::ApplyFunctionCallDotNode::emitBytecode):
    (JSC::PostfixNode::emitResolve):
    (JSC::PostfixNode::emitBracket):
    (JSC::PostfixNode::emitDot):
    (JSC::PrefixNode::emitResolve):
    (JSC::PrefixNode::emitBracket):
    (JSC::PrefixNode::emitDot):
    (JSC::ReadModifyResolveNode::emitBytecode):
    (JSC::AssignResolveNode::emitBytecode):
    (JSC::AssignDotNode::emitBytecode):
    (JSC::ReadModifyDotNode::emitBytecode):
    (JSC::AssignBracketNode::emitBytecode):
    (JSC::ReadModifyBracketNode::emitBytecode):
    (JSC::ReturnNode::emitBytecode):
    (JSC::FunctionBodyNode::emitBytecode):
    * inspector/agents/InspectorRuntimeAgent.cpp:
    (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset):
    (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange): Deleted.
    * inspector/agents/InspectorRuntimeAgent.h:
    * inspector/protocol/Runtime.json:
    * llint/LLIntSlowPaths.cpp:
    (JSC::LLInt::getFromScopeCommon):
    (JSC::LLInt::LLINT_SLOW_PATH_DECL):
    * llint/LLIntSlowPaths.h:
    * llint/LowLevelInterpreter.asm:
    * runtime/HighFidelityLog.cpp:
    (JSC::HighFidelityLog::processHighFidelityLog):
    (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
    (JSC::HighFidelityLog::recordTypeInformationForLocation): Deleted.
    * runtime/HighFidelityLog.h:
    (JSC::HighFidelityLog::recordTypeInformationForLocation):
    * runtime/HighFidelityTypeProfiler.cpp:
    (JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset):
    (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset):
    (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset):
    (JSC::HighFidelityTypeProfiler::insertNewLocation):
    (JSC::HighFidelityTypeProfiler::findLocation):
    (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange): Deleted.
    (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange): Deleted.
    (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange): Deleted.
    (JSC::HighFidelityTypeProfiler::getLocationBasedHash): Deleted.
    * runtime/HighFidelityTypeProfiler.h:
    (JSC::LocationKey::LocationKey): Deleted.
    (JSC::LocationKey::hash): Deleted.
    (JSC::LocationKey::operator==): Deleted.
    * runtime/Structure.cpp:
    (JSC::Structure::toStructureShape):
    * runtime/Structure.h:
    * runtime/TypeSet.cpp:
    (JSC::TypeSet::TypeSet):
    (JSC::TypeSet::addTypeForValue):
    (JSC::TypeSet::seenTypes):
    (JSC::TypeSet::removeDuplicatesInStructureHistory): Deleted.
    * runtime/TypeSet.h:
    (JSC::StructureShape::setConstructorName):
    * runtime/VM.cpp:
    (JSC::VM::getTypesForVariableAtOffset):
    (JSC::VM::dumpHighFidelityProfilingTypes):
    (JSC::VM::getTypesForVariableInRange): Deleted.
    * runtime/VM.h:
    
    2014-07-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt][REGRESSION] debug tests fail because PutByIdDirect is now implemented in terms of In
    https://bugs.webkit.org/show_bug.cgi?id=134642
    
    Rubber stamped by Andreas Kling.
    
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::LowerDFGToLLVM::compileNode):
    
    2014-07-01  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Allocate a new GetterSetter if we change the value of any of its entries other than when they were previously null, so that if we constant-infer an accessor slot then we immediately get the function constant for free
    https://bugs.webkit.org/show_bug.cgi?id=134518
    
    Reviewed by Mark Hahnenberg.
            
    This has no real effect right now, particularly since almost all uses of
    setSetter/setGetter were already allocating a branch new GetterSetter. But once we start
    doing more aggressive constant property inference, this change will allow us to remove
    all runtime checks from getter/setter calls.
    
    * runtime/GetterSetter.cpp:
    (JSC::GetterSetter::withGetter):
    (JSC::GetterSetter::withSetter):
    * runtime/GetterSetter.h:
    (JSC::GetterSetter::setGetter):
    (JSC::GetterSetter::setSetter):
    * runtime/JSObject.cpp:
    (JSC::JSObject::defineOwnNonIndexProperty):
    
    2014-07-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Rename notifyTransitionFromThisStructure to didTransitionFromThisStructure
    
    Rubber stamped by Mark Hahnenberg.
    
    * runtime/Structure.cpp:
    (JSC::Structure::Structure):
    (JSC::Structure::nonPropertyTransition):
    (JSC::Structure::didTransitionFromThisStructure):
    (JSC::Structure::notifyTransitionFromThisStructure): Deleted.
    * runtime/Structure.h:
    
    2014-07-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Remove the functionality for cloning StructureRareData since we never do that anymore.
    
    Rubber stamped by Mark Hahnenberg.
    
    * runtime/Structure.cpp:
    (JSC::Structure::Structure):
    (JSC::Structure::cloneRareDataFrom): Deleted.
    * runtime/Structure.h:
    * runtime/StructureRareData.cpp:
    (JSC::StructureRareData::clone): Deleted.
    (JSC::StructureRareData::StructureRareData): Deleted.
    * runtime/StructureRareData.h:
    (JSC::StructureRareData::needsCloning): Deleted.
    
    2014-07-01  Mark Lam  &lt;mark.lam@apple.com&gt;
    
    [ftlopt] DebuggerCallFrame::scope() should return a DebuggerScope.
    &lt;https://webkit.org/b/134420&gt;
    
    Reviewed by Geoffrey Garen.
    
    Previously, DebuggerCallFrame::scope() returns a JSActivation (and relevant
    peers) which the WebInspector will use to introspect CallFrame variables.
    Instead, we should be returning a DebuggerScope as an abstraction layer that
    provides the introspection functionality that the WebInspector needs.  This
    is the first step towards not forcing every frame to have a JSActivation
    object just because the debugger is enabled.
    
    1. Instantiate the debuggerScopeStructure as a member of the JSGlobalObject
       instead of the VM.  This allows JSObject::globalObject() to be able to
       return the global object for the DebuggerScope.
    
    2. On the DebuggerScope's life-cycle management:
    
       The DebuggerCallFrame is designed to be &quot;valid&quot; only during a debugging session
       (while the debugger is broken) through the use of a DebuggerCallFrameScope in
       Debugger::pauseIfNeeded().  Once the debugger resumes from the break, the
       DebuggerCallFrameScope destructs, and the DebuggerCallFrame will be invalidated.
       We can't guarantee (from this code alone) that the Inspector code isn't still
       holding a ref to the DebuggerCallFrame (though they shouldn't), but by contract,
       the frame will be invalidated, and any attempt to query it will return null values.
       This is pre-existing behavior.
    
       Now, we're adding the DebuggerScope into the picture.  While a single debugger
       pause session is in progress, the Inspector may request the scope from the
       DebuggerCallFrame.  While the DebuggerCallFrame is still valid, we want
       DebuggerCallFrame::scope() to always return the same DebuggerScope object.
       This is why we hold on to the DebuggerScope with a strong ref.
    
       If we use a weak ref instead, the following cooky behavior can manifest:
       1. The Inspector calls Debugger::scope() to get the top scope.
       2. The Inspector iterates down the scope chain and is now only holding a
          reference to a parent scope.  It is no longer referencing the top scope.
       3. A GC occurs, and the DebuggerCallFrame's weak m_scope ref to the top scope
          gets cleared.
       4. The Inspector calls DebuggerCallFrame::scope() to get the top scope again but gets
          a different DebuggerScope instance.
       5. The Inspector iterates down the scope chain but never sees the parent scope
          instance that retained a ref to in step 2 above.  This is because when iterating
          this new DebuggerScope instance (which has no knowledge of the previous parent
          DebuggerScope instance), a new DebuggerScope instance will get created for the
          same parent scope. 
    
       Since the DebuggerScope is a JSObject, it's liveness is determined by its reachability.
       However, it's &quot;validity&quot; is determined by the life-cycle of its owner DebuggerCallFrame.
       When the owner DebuggerCallFrame gets invalidated, its debugger scope chain (if
       instantiated) will also get invalidated.  This is why we need the
       DebuggerScope::invalidateChain() method.  The Inspector should not be using the
       DebuggerScope instance after its owner DebuggerCallFrame is invalidated.  If it does,
       those methods will do nothing or returned a failed status.
    
    * debugger/Debugger.h:
    * debugger/DebuggerCallFrame.cpp:
    (JSC::DebuggerCallFrame::scope):
    (JSC::DebuggerCallFrame::evaluate):
    (JSC::DebuggerCallFrame::invalidate):
    (JSC::DebuggerCallFrame::vm):
    (JSC::DebuggerCallFrame::lexicalGlobalObject):
    * debugger/DebuggerCallFrame.h:
    * debugger/DebuggerScope.cpp:
    (JSC::DebuggerScope::DebuggerScope):
    (JSC::DebuggerScope::finishCreation):
    (JSC::DebuggerScope::visitChildren):
    (JSC::DebuggerScope::className):
    (JSC::DebuggerScope::getOwnPropertySlot):
    (JSC::DebuggerScope::put):
    (JSC::DebuggerScope::deleteProperty):
    (JSC::DebuggerScope::getOwnPropertyNames):
    (JSC::DebuggerScope::defineOwnProperty):
    (JSC::DebuggerScope::next):
    (JSC::DebuggerScope::invalidateChain):
    (JSC::DebuggerScope::isWithScope):
    (JSC::DebuggerScope::isGlobalScope):
    (JSC::DebuggerScope::isFunctionScope):
    * debugger/DebuggerScope.h:
    (JSC::DebuggerScope::create):
    (JSC::DebuggerScope::Iterator::Iterator):
    (JSC::DebuggerScope::Iterator::get):
    (JSC::DebuggerScope::Iterator::operator++):
    (JSC::DebuggerScope::Iterator::operator==):
    (JSC::DebuggerScope::Iterator::operator!=):
    (JSC::DebuggerScope::isValid):
    (JSC::DebuggerScope::jsScope):
    (JSC::DebuggerScope::begin):
    (JSC::DebuggerScope::end):
    * inspector/JSJavaScriptCallFrame.cpp:
    (Inspector::JSJavaScriptCallFrame::scopeType):
    (Inspector::JSJavaScriptCallFrame::scopeChain):
    * inspector/JavaScriptCallFrame.h:
    (Inspector::JavaScriptCallFrame::scopeChain):
    * inspector/ScriptDebugServer.cpp:
    * runtime/JSGlobalObject.cpp:
    (JSC::JSGlobalObject::reset):
    (JSC::JSGlobalObject::visitChildren):
    * runtime/JSGlobalObject.h:
    (JSC::JSGlobalObject::debuggerScopeStructure):
    * runtime/JSObject.h:
    (JSC::JSObject::isWithScope):
    * runtime/JSScope.h:
    * runtime/VM.cpp:
    (JSC::VM::VM):
    * runtime/VM.h:
    
    2014-07-01  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] DFG bytecode parser should turn PutById with nothing but a Setter stub as stuff+handleCall, and handleCall should be allowed to inline if it wants to
    https://bugs.webkit.org/show_bug.cgi?id=130756
    
    Reviewed by Oliver Hunt.
            
    The enables exposing the call to setters in the DFG, and then inlining it. Previously we
    already supproted inlined-cached calls to setters from within put_by_id inline caches,
    and the DFG could certainly emit such IC's. Now, if an IC had a setter call, then the DFG
    will either emit the GetGetterSetterByOffset/GetSetter/Call combo, or it will do one
    better and inline the call.
            
    A lot of the core functionality was already available from the previous work to inline
    getters. So, there are some refactorings in this patch that move preexisting
    functionality around. For example, the work to figure out how the DFG should go about
    getting to what we call the &quot;loaded value&quot; - i.e. the GetterSetter object reference in
    the case of accessors - is now shared in ComplexGetStatus, and both GetByIdStatus and
    PutByIdStatus use it. This means that we can keep the safety checks common.  This patch
    also does additional refactorings in DFG::ByteCodeParser so that we can continue to reuse
    handleCall() for all of the various kinds of calls we can now emit.
            
    83% speed-up on getter-richards, 2% speed-up on box2d.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * bytecode/ComplexGetStatus.cpp: Added.
    (JSC::ComplexGetStatus::computeFor):
    * bytecode/ComplexGetStatus.h: Added.
    (JSC::ComplexGetStatus::ComplexGetStatus):
    (JSC::ComplexGetStatus::skip):
    (JSC::ComplexGetStatus::takesSlowPath):
    (JSC::ComplexGetStatus::kind):
    (JSC::ComplexGetStatus::attributes):
    (JSC::ComplexGetStatus::specificValue):
    (JSC::ComplexGetStatus::offset):
    (JSC::ComplexGetStatus::chain):
    * bytecode/GetByIdStatus.cpp:
    (JSC::GetByIdStatus::computeForStubInfo):
    * bytecode/GetByIdVariant.cpp:
    (JSC::GetByIdVariant::GetByIdVariant):
    * bytecode/PolymorphicPutByIdList.h:
    (JSC::PutByIdAccess::PutByIdAccess):
    (JSC::PutByIdAccess::setter):
    (JSC::PutByIdAccess::structure):
    (JSC::PutByIdAccess::chainCount):
    * bytecode/PutByIdStatus.cpp:
    (JSC::PutByIdStatus::computeFromLLInt):
    (JSC::PutByIdStatus::computeFor):
    (JSC::PutByIdStatus::computeForStubInfo):
    (JSC::PutByIdStatus::makesCalls):
    * bytecode/PutByIdStatus.h:
    (JSC::PutByIdStatus::makesCalls): Deleted.
    * bytecode/PutByIdVariant.cpp:
    (JSC::PutByIdVariant::PutByIdVariant):
    (JSC::PutByIdVariant::operator=):
    (JSC::PutByIdVariant::replace):
    (JSC::PutByIdVariant::transition):
    (JSC::PutByIdVariant::setter):
    (JSC::PutByIdVariant::writesStructures):
    (JSC::PutByIdVariant::reallocatesStorage):
    (JSC::PutByIdVariant::makesCalls):
    (JSC::PutByIdVariant::dumpInContext):
    * bytecode/PutByIdVariant.h:
    (JSC::PutByIdVariant::PutByIdVariant):
    (JSC::PutByIdVariant::structure):
    (JSC::PutByIdVariant::oldStructure):
    (JSC::PutByIdVariant::alternateBase):
    (JSC::PutByIdVariant::specificValue):
    (JSC::PutByIdVariant::callLinkStatus):
    (JSC::PutByIdVariant::replace): Deleted.
    (JSC::PutByIdVariant::transition): Deleted.
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
    (JSC::DFG::ByteCodeParser::addCall):
    (JSC::DFG::ByteCodeParser::handleCall):
    (JSC::DFG::ByteCodeParser::handleInlining):
    (JSC::DFG::ByteCodeParser::handleGetById):
    (JSC::DFG::ByteCodeParser::handlePutById):
    (JSC::DFG::ByteCodeParser::parseBlock):
    * jit/Repatch.cpp:
    (JSC::tryCachePutByID):
    (JSC::tryBuildPutByIdList):
    * runtime/IntendedStructureChain.cpp:
    (JSC::IntendedStructureChain::takesSlowPathInDFGForImpureProperty):
    * runtime/IntendedStructureChain.h:
    * tests/stress/exit-from-setter.js: Added.
    * tests/stress/poly-chain-setter.js: Added.
    (Cons):
    (foo):
    (test):
    * tests/stress/poly-chain-then-setter.js: Added.
    (Cons1):
    (Cons2):
    (foo):
    (test):
    * tests/stress/poly-setter-combo.js: Added.
    (Cons1):
    (Cons2):
    (foo):
    (test):
    (.test):
    * tests/stress/poly-setter-then-self.js: Added.
    (foo):
    (test):
    (.test):
    * tests/stress/weird-setter-counter.js: Added.
    (foo):
    (test):
    * tests/stress/weird-setter-counter-syntactic.js: Added.
    (foo):
    (test):
    
    2014-07-01  Matthew Mirman  &lt;mmirman@apple.com&gt;
    
    Added an implementation of the &quot;in&quot; check to FTL.
    https://bugs.webkit.org/show_bug.cgi?id=134508
    
    Reviewed by Filip Pizlo.
    
    * ftl/FTLCapabilities.cpp: enabled compilation for &quot;in&quot;
    (JSC::FTL::canCompile): ditto
    * ftl/FTLCompile.cpp:
    (JSC::FTL::generateCheckInICFastPath): added.
    (JSC::FTL::fixFunctionBasedOnStackMaps): added case for CheckIn descriptors.
    * ftl/FTLInlineCacheDescriptor.h:
    (JSC::FTL::CheckInGenerator::CheckInGenerator): added.
    (JSC::FTL::CheckInDescriptor::CheckInDescriptor): added.
    * ftl/FTLInlineCacheSize.cpp: 
    (JSC::FTL::sizeOfCheckIn): added. Currently larger than necessary.
    * ftl/FTLInlineCacheSize.h: ditto
    * ftl/FTLIntrinsicRepository.h: Added function type for operationInGeneric
    * ftl/FTLLowerDFGToLLVM.cpp: 
    (JSC::FTL::LowerDFGToLLVM::compileNode): added case for In.
    (JSC::FTL::LowerDFGToLLVM::compileIn): added.
    * ftl/FTLSlowPathCall.cpp: Added a callOperation for operationIn
    (JSC::FTL::callOperation): ditto
    * ftl/FTLSlowPathCall.h: ditto
    * ftl/FTLState.h: Added a vector to hold CheckIn descriptors.
    * jit/JITOperations.h: made operationIns internal.
    * tests/stress/ftl-checkin.js: Added.
    * tests/stress/ftl-checkin-variable.js: Added.
    
    2014-06-30  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
    
    CodeBlock::stronglyVisitWeakReferences should mark DFG::CommonData::weakStructureReferences
    https://bugs.webkit.org/show_bug.cgi?id=134455
    
    Reviewed by Geoffrey Garen.
    
    Otherwise we get hanging pointers which can cause us to die later.
    
    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::stronglyVisitWeakReferences):
    
    2014-06-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Reduce the GC's influence on optimization decisions
    https://bugs.webkit.org/show_bug.cgi?id=134427
    
    Reviewed by Oliver Hunt.
            
    This is a slight speed-up on some platforms, that arises from a bunch of fixes that I made
    while trying to make the GC keep more structures alive
    (https://bugs.webkit.org/show_bug.cgi?id=128072).
            
    The fixes are, roughly:
            
    - If the GC clears an inline cache, then this no longer causes the IC to be forever
      polymorphic.
            
    - If we exit in inlined code into a function that tries to OSR enter, then we jettison
      sooner.
            
    - Some variables being uninitialized led to rage-recompilations.
            
    This is a pretty strong step in the direction of keeping more Structures alive and not
    blowing away code just because a Structure died. But, it seems like there is still a slight
    speed-up to be had from blowing away code that references dead Structures.
    
    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::dumpAssumingJITType):
    (JSC::shouldMarkTransition):
    (JSC::CodeBlock::propagateTransitions):
    (JSC::CodeBlock::determineLiveness):
    * bytecode/GetByIdStatus.cpp:
    (JSC::GetByIdStatus::computeForStubInfo):
    * bytecode/PutByIdStatus.cpp:
    (JSC::PutByIdStatus::computeForStubInfo):
    * dfg/DFGCapabilities.cpp:
    (JSC::DFG::isSupportedForInlining):
    (JSC::DFG::mightInlineFunctionForCall):
    (JSC::DFG::mightInlineFunctionForClosureCall):
    (JSC::DFG::mightInlineFunctionForConstruct):
    * dfg/DFGCapabilities.h:
    * dfg/DFGCommonData.h:
    * dfg/DFGDesiredWeakReferences.cpp:
    (JSC::DFG::DesiredWeakReferences::reallyAdd):
    * dfg/DFGOSREntry.cpp:
    (JSC::DFG::prepareOSREntry):
    * dfg/DFGOSRExitCompilerCommon.cpp:
    (JSC::DFG::handleExitCounts):
    * dfg/DFGOperations.cpp:
    * dfg/DFGOperations.h:
    * ftl/FTLForOSREntryJITCode.cpp:
    (JSC::FTL::ForOSREntryJITCode::ForOSREntryJITCode): These variables being uninitialized is benign in terms of correctness but can sometimes cause rage-recompilations. For some reason it took this patch to reveal this.
    * ftl/FTLOSREntry.cpp:
    (JSC::FTL::prepareOSREntry):
    * runtime/Executable.cpp:
    (JSC::ExecutableBase::destroy):
    (JSC::NativeExecutable::destroy):
    (JSC::ScriptExecutable::ScriptExecutable):
    (JSC::ScriptExecutable::destroy):
    (JSC::ScriptExecutable::installCode):
    (JSC::EvalExecutable::EvalExecutable):
    (JSC::ProgramExecutable::ProgramExecutable):
    * runtime/Executable.h:
    (JSC::ScriptExecutable::setDidTryToEnterInLoop):
    (JSC::ScriptExecutable::didTryToEnterInLoop):
    (JSC::ScriptExecutable::addressOfDidTryToEnterInLoop):
    (JSC::ScriptExecutable::ScriptExecutable): Deleted.
    * runtime/StructureInlines.h:
    (JSC::Structure::storedPrototypeObject):
    (JSC::Structure::storedPrototypeStructure):
    
    2014-06-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
    https://bugs.webkit.org/show_bug.cgi?id=134333
    
    Reviewed by Geoffrey Garen.
            
    This is engineered to provide loads of information to the profiler without incurring any
    costs when the profiler is disabled. It's the oldest trick in the book: the thing that
    fires the watchpoint doesn't actually create anything to describe the reason why it was
    fired; instead it creates a stack-allocated FireDetail subclass instance. Only if the
    FireDetail::dump() virtual method is called does anything happen.
            
    Currently we use this to produce very fine-grained data for Structure watchpoints and
    some cases of variable watchpoints. For all other situations, the given reason is just a
    string constant, by using StringFireDetail. If we find a situation where that string
    constant is insufficient to diagnose an issue then we can change it to provide more
    fine-grained information.
    
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::CodeBlock):
    (JSC::CodeBlock::jettison):
    * bytecode/CodeBlock.h:
    * bytecode/CodeBlockJettisoningWatchpoint.cpp:
    (JSC::CodeBlockJettisoningWatchpoint::fireInternal):
    * bytecode/CodeBlockJettisoningWatchpoint.h:
    * bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp: Removed.
    * bytecode/ProfiledCodeBlockJettisoningWatchpoint.h: Removed.
    * bytecode/StructureStubClearingWatchpoint.cpp:
    (JSC::StructureStubClearingWatchpoint::fireInternal):
    * bytecode/StructureStubClearingWatchpoint.h:
    * bytecode/VariableWatchpointSet.h:
    (JSC::VariableWatchpointSet::invalidate):
    (JSC::VariableWatchpointSet::finalizeUnconditionally):
    * bytecode/VariableWatchpointSetInlines.h:
    (JSC::VariableWatchpointSet::notifyWrite):
    * bytecode/Watchpoint.cpp:
    (JSC::StringFireDetail::dump):
    (JSC::WatchpointSet::fireAll):
    (JSC::WatchpointSet::fireAllSlow):
    (JSC::WatchpointSet::fireAllWatchpoints):
    (JSC::InlineWatchpointSet::fireAll):
    * bytecode/Watchpoint.h:
    (JSC::FireDetail::FireDetail):
    (JSC::FireDetail::~FireDetail):
    (JSC::StringFireDetail::StringFireDetail):
    (JSC::Watchpoint::fire):
    (JSC::WatchpointSet::fireAll):
    (JSC::WatchpointSet::touch):
    (JSC::WatchpointSet::invalidate):
    (JSC::InlineWatchpointSet::fireAll):
    (JSC::InlineWatchpointSet::touch):
    * dfg/DFGCommonData.h:
    * dfg/DFGOperations.cpp:
    * interpreter/Interpreter.cpp:
    (JSC::Interpreter::execute):
    * jsc.cpp:
    (WTF::Masquerader::create):
    * profiler/ProfilerCompilation.cpp:
    (JSC::Profiler::Compilation::setJettisonReason):
    (JSC::Profiler::Compilation::toJS):
    * profiler/ProfilerCompilation.h:
    (JSC::Profiler::Compilation::setJettisonReason): Deleted.
    * runtime/ArrayBuffer.cpp:
    (JSC::ArrayBuffer::transfer):
    * runtime/ArrayBufferNeuteringWatchpoint.cpp:
    (JSC::ArrayBufferNeuteringWatchpoint::fireAll):
    * runtime/ArrayBufferNeuteringWatchpoint.h:
    * runtime/CommonIdentifiers.h:
    * runtime/CommonSlowPaths.cpp:
    (JSC::SLOW_PATH_DECL):
    * runtime/Identifier.cpp:
    (JSC::Identifier::dump):
    * runtime/Identifier.h:
    * runtime/JSFunction.cpp:
    (JSC::JSFunction::put):
    (JSC::JSFunction::defineOwnProperty):
    * runtime/JSGlobalObject.cpp:
    (JSC::JSGlobalObject::addFunction):
    (JSC::JSGlobalObject::haveABadTime):
    * runtime/JSSymbolTableObject.cpp:
    (JSC::VariableWriteFireDetail::dump):
    * runtime/JSSymbolTableObject.h:
    (JSC::VariableWriteFireDetail::VariableWriteFireDetail):
    (JSC::symbolTablePut):
    (JSC::symbolTablePutWithAttributes):
    * runtime/PropertyName.h:
    (JSC::PropertyName::dump):
    * runtime/Structure.cpp:
    (JSC::Structure::notifyTransitionFromThisStructure):
    * runtime/Structure.h:
    (JSC::Structure::notifyTransitionFromThisStructure): Deleted.
    * runtime/SymbolTable.cpp:
    (JSC::SymbolTableEntry::notifyWriteSlow):
    (JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally):
    * runtime/SymbolTable.h:
    (JSC::SymbolTableEntry::notifyWrite):
    * runtime/VM.cpp:
    (JSC::VM::addImpureProperty):

Source/WebCore:

    2014-07-01  Mark Lam  &lt;mark.lam@apple.com&gt;
    
    [ftlopt] DebuggerCallFrame::scope() should return a DebuggerScope.
    &lt;https://webkit.org/b/134420&gt;
    
    Reviewed by Geoffrey Garen.
    
    No new tests.
    
    * ForwardingHeaders/debugger/DebuggerCallFrame.h: Removed.
    - This is not in use.  Hence, we can remove it.
    * bindings/js/ScriptController.cpp:
    (WebCore::ScriptController::attachDebugger):
    - We should acquire the JSLock before modifying a JS global object.
    
    2014-06-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
    https://bugs.webkit.org/show_bug.cgi?id=134333
    
    Reviewed by Geoffrey Garen.
    
    No new tests because no change in behavior.
    
    * bindings/scripts/CodeGeneratorJS.pm:
    (GenerateHeader):

Tools:

    2014-06-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
    https://bugs.webkit.org/show_bug.cgi?id=134333
    
    Reviewed by Geoffrey Garen.
    
    * Scripts/display-profiler-output:

LayoutTests:

    2014-07-16  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
    
    sputnik/Implementation_Diagnostics/S12.6.4_D1.html depends on undefined behavior
    https://bugs.webkit.org/show_bug.cgi?id=135007
    
    Reviewed by Filip Pizlo.
    
    EcmaScript 5.1 specifies that during for-in enumeration newly added properties may or may not be 
    visited during the current enumeration. Specifically, in section 12.6.4 the spec states:
    
    &quot;If new properties are added to the object being enumerated during enumeration, the newly added properties 
    are not guaranteed to be visited in the active enumeration.&quot;
    
    The sputnik/Implementation_Diagnostics/S12.6.4_D1.html layout test is from before sputnik was added 
    to the test262 suite. I believe it has since been removed, so it would probably be okay to remove it 
    from our layout test suite.
    
    * sputnik/Implementation_Diagnostics/S12.6.4_D1-expected.txt: Removed.
    * sputnik/Implementation_Diagnostics/S12.6.4_D1.html: Removed.
    
    2014-07-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] DFG should be able to do GCSE in SSA and this should be unified with the CSE in CPS, and both of these things should use abstract heaps for reasoning about effects
    https://bugs.webkit.org/show_bug.cgi?id=134677
    
    Reviewed by Sam Weinig.
    
    * js/regress/gcse-expected.txt: Added.
    * js/regress/gcse-poly-get-expected.txt: Added.
    * js/regress/gcse-poly-get-less-obvious-expected.txt: Added.
    * js/regress/gcse-poly-get-less-obvious.html: Added.
    * js/regress/gcse-poly-get.html: Added.
    * js/regress/gcse.html: Added.
    * js/regress/script-tests/gcse-poly-get-less-obvious.js: Added.
    * js/regress/script-tests/gcse-poly-get.js: Added.
    * js/regress/script-tests/gcse.js: Added.
    
    2014-07-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
    
    [ftlopt] Infer immutable object properties
    https://bugs.webkit.org/show_bug.cgi?id=134567
    
    Reviewed by Mark Hahnenberg.
    
    * js/regress/infer-constant-global-property-expected.txt: Added.
    * js/regress/infer-constant-global-property.html: Added.
    * js/regress/infer-constant-property-expected.txt: Added.
    * js/regress/infer-constant-property.html: Added.
    * js/regress/script-tests/infer-constant-global-property.js: Added.
    * js/regress/script-tests/infer-constant-property.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockJettisoningWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockJettisoningWatchpointh">trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdVariantcpp">trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdVarianth">trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicPutByIdListh">trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdStatush">trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdVariantcpp">trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdVarianth">trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointh">trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeTypeLocationh">trunk/Source/JavaScriptCore/bytecode/TypeLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh">trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWatchpointSeth">trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWatchpointSetInlinesh">trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointh">trunk/Source/JavaScriptCore/bytecode/Watchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerh">trunk/Source/JavaScriptCore/debugger/Debugger.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerCallFramecpp">trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerCallFrameh">trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopecpp">trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerScopeh">trunk/Source/JavaScriptCore/debugger/DebuggerScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractHeaph">trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAdjacencyListh">trunk/Source/JavaScriptCore/dfg/DFGAdjacencyList.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockh">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCPSRethreadingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCSEPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCSEPhaseh">trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiesh">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberSetcpp">trunk/Source/JavaScriptCore/dfg/DFGClobberSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizecpp">trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommonDatah">trunk/Source/JavaScriptCore/dfg/DFGCommonData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDCEPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDesiredWeakReferencescpp">trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGEdgeDominatesh">trunk/Source/JavaScriptCore/dfg/DFGEdgeDominates.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="#trunkSourceJavaScriptCoredfgDFGLICMPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSREntrycpp">trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSSAConversionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLForOSREntryJITCodecpp">trunk/Source/JavaScriptCore/ftl/FTLForOSREntryJITCode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLInlineCacheDescriptorh">trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLInlineCacheSizecpp">trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLInlineCacheSizeh">trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h</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="#trunkSourceJavaScriptCoreftlFTLOSREntrycpp">trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLSlowPathCallcpp">trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLSlowPathCallh">trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStateh">trunk/Source/JavaScriptCore/ftl/FTLState.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramecpp">trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJavaScriptCallFrameh">trunk/Source/JavaScriptCore/inspector/JavaScriptCallFrame.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptDebugServercpp">trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolRuntimejson">trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerProfilerCompilationcpp">trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerProfilerCompilationh">trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBuffercpp">trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointcpp">trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointh">trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonIdentifiersh">trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutablecpp">trunk/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutableh">trunk/Source/JavaScriptCore/runtime/Executable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeGetterSettercpp">trunk/Source/JavaScriptCore/runtime/GetterSetter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeGetterSetterh">trunk/Source/JavaScriptCore/runtime/GetterSetter.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityLogcpp">trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityLogh">trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp">trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh">trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIdentifiercpp">trunk/Source/JavaScriptCore/runtime/Identifier.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIdentifierh">trunk/Source/JavaScriptCore/runtime/Identifier.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIndexingHeaderh">trunk/Source/JavaScriptCore/runtime/IndexingHeader.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntendedStructureChaincpp">trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntendedStructureChainh">trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSActivationcpp">trunk/Source/JavaScriptCore/runtime/JSActivation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCJSValuecpp">trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctioncpp">trunk/Source/JavaScriptCore/runtime/JSFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopecpp">trunk/Source/JavaScriptCore/runtime/JSScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopeh">trunk/Source/JavaScriptCore/runtime/JSScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSSymbolTableObjecth">trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePropertyMapHashTableh">trunk/Source/JavaScriptCore/runtime/PropertyMapHashTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePropertyNameh">trunk/Source/JavaScriptCore/runtime/PropertyName.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePropertyTablecpp">trunk/Source/JavaScriptCore/runtime/PropertyTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructurecpp">trunk/Source/JavaScriptCore/runtime/Structure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureh">trunk/Source/JavaScriptCore/runtime/Structure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureInlinesh">trunk/Source/JavaScriptCore/runtime/StructureInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDatacpp">trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDatah">trunk/Source/JavaScriptCore/runtime/StructureRareData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTablecpp">trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTableh">trunk/Source/JavaScriptCore/runtime/SymbolTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeSetcpp">trunk/Source/JavaScriptCore/runtime/TypeSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeSeth">trunk/Source/JavaScriptCore/runtime/TypeSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceWTFwtfPrintStreamh">trunk/Source/WTF/wtf/PrintStream.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMWindowBasecpp">trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsScriptControllercpp">trunk/Source/WebCore/bindings/js/ScriptController.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsdisplayprofileroutput">trunk/Tools/Scripts/display-profiler-output</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressgcseexpectedtxt">trunk/LayoutTests/js/regress/gcse-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgcsepolygetexpectedtxt">trunk/LayoutTests/js/regress/gcse-poly-get-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgcsepolygetlessobviousexpectedtxt">trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressgcsepolygetlessobvioushtml">trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious.html</a></li>
<li><a href="#trunkLayoutTestsjsregressgcsepolygethtml">trunk/LayoutTests/js/regress/gcse-poly-get.html</a></li>
<li><a href="#trunkLayoutTestsjsregressgcsehtml">trunk/LayoutTests/js/regress/gcse.html</a></li>
<li><a href="#trunkLayoutTestsjsregressinferconstantglobalpropertyexpectedtxt">trunk/LayoutTests/js/regress/infer-constant-global-property-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressinferconstantglobalpropertyhtml">trunk/LayoutTests/js/regress/infer-constant-global-property.html</a></li>
<li><a href="#trunkLayoutTestsjsregressinferconstantpropertyexpectedtxt">trunk/LayoutTests/js/regress/infer-constant-property-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressinferconstantpropertyhtml">trunk/LayoutTests/js/regress/infer-constant-property.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgcsepolygetlessobviousjs">trunk/LayoutTests/js/regress/script-tests/gcse-poly-get-less-obvious.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgcsepolygetjs">trunk/LayoutTests/js/regress/script-tests/gcse-poly-get.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsgcsejs">trunk/LayoutTests/js/regress/script-tests/gcse.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsinferconstantglobalpropertyjs">trunk/LayoutTests/js/regress/script-tests/infer-constant-global-property.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsinferconstantpropertyjs">trunk/LayoutTests/js/regress/script-tests/infer-constant-property.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeComplexGetStatuscpp">trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeComplexGetStatush">trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWatchpointSetcpp">trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGHeapLocationcpp">trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGHeapLocationh">trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhaseh">trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPureValuecpp">trunk/Source/JavaScriptCore/dfg/DFGPureValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPureValueh">trunk/Source/JavaScriptCore/dfg/DFGPureValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresscachedprototypesetterjs">trunk/Source/JavaScriptCore/tests/stress/cached-prototype-setter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressexitfromsetterjs">trunk/Source/JavaScriptCore/tests/stress/exit-from-setter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftlcheckinvariablejs">trunk/Source/JavaScriptCore/tests/stress/ftl-checkin-variable.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressftlcheckinjs">trunk/Source/JavaScriptCore/tests/stress/ftl-checkin.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressinferconstantglobalpropertyjs">trunk/Source/JavaScriptCore/tests/stress/infer-constant-global-property.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressinferconstantpropertyjs">trunk/Source/JavaScriptCore/tests/stress/infer-constant-property.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressjitcachepolyreplacethencachegetandfoldtheninvalidatejs">trunk/Source/JavaScriptCore/tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressjitcachereplacethencachegetandfoldtheninvalidatejs">trunk/Source/JavaScriptCore/tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressjitputtoscopeglobalcachewatchpointinvalidatejs">trunk/Source/JavaScriptCore/tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressllintcachereplacethencachegetandfoldtheninvalidatejs">trunk/Source/JavaScriptCore/tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressllintputtoscopeglobalcachewatchpointinvalidatejs">trunk/Source/JavaScriptCore/tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolychainsetterjs">trunk/Source/JavaScriptCore/tests/stress/poly-chain-setter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolychainthensetterjs">trunk/Source/JavaScriptCore/tests/stress/poly-chain-then-setter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolysettercombojs">trunk/Source/JavaScriptCore/tests/stress/poly-setter-combo.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolysetterthenselfjs">trunk/Source/JavaScriptCore/tests/stress/poly-setter-then-self.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressrepeatputtoscopeglobalwithsamevaluewatchpointinvalidatejs">trunk/Source/JavaScriptCore/tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressweirdsettercountersyntacticjs">trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter-syntactic.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressweirdsettercounterjs">trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestssputnikImplementation_DiagnosticsS1264_D1expectedtxt">trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1-expected.txt</a></li>
<li><a href="#trunkLayoutTestssputnikImplementation_DiagnosticsS1264_D1html">trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1.html</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeProfiledCodeBlockJettisoningWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeProfiledCodeBlockJettisoningWatchpointh">trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersdebuggerDebuggerCallFrameh">trunk/Source/WebCore/ForwardingHeaders/debugger/DebuggerCallFrame.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/LayoutTests/ChangeLog        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,3 +1,58 @@
</span><ins>+2014-07-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Merge r170564, r170571, r170604, r170628, r170672, r170680, r170724, r170728, r170729, r170819, r170821, r170836, r170855, r170860, r170890, r170907, r170929, r171052, r171106, r171152, r171153, r171214 from ftlopt.
+
+    2014-07-16  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+    
+            sputnik/Implementation_Diagnostics/S12.6.4_D1.html depends on undefined behavior
+            https://bugs.webkit.org/show_bug.cgi?id=135007
+    
+            Reviewed by Filip Pizlo.
+    
+            EcmaScript 5.1 specifies that during for-in enumeration newly added properties may or may not be 
+            visited during the current enumeration. Specifically, in section 12.6.4 the spec states:
+    
+            &quot;If new properties are added to the object being enumerated during enumeration, the newly added properties 
+            are not guaranteed to be visited in the active enumeration.&quot;
+    
+            The sputnik/Implementation_Diagnostics/S12.6.4_D1.html layout test is from before sputnik was added 
+            to the test262 suite. I believe it has since been removed, so it would probably be okay to remove it 
+            from our layout test suite.
+    
+            * sputnik/Implementation_Diagnostics/S12.6.4_D1-expected.txt: Removed.
+            * sputnik/Implementation_Diagnostics/S12.6.4_D1.html: Removed.
+    
+    2014-07-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] DFG should be able to do GCSE in SSA and this should be unified with the CSE in CPS, and both of these things should use abstract heaps for reasoning about effects
+            https://bugs.webkit.org/show_bug.cgi?id=134677
+    
+            Reviewed by Sam Weinig.
+    
+            * js/regress/gcse-expected.txt: Added.
+            * js/regress/gcse-poly-get-expected.txt: Added.
+            * js/regress/gcse-poly-get-less-obvious-expected.txt: Added.
+            * js/regress/gcse-poly-get-less-obvious.html: Added.
+            * js/regress/gcse-poly-get.html: Added.
+            * js/regress/gcse.html: Added.
+            * js/regress/script-tests/gcse-poly-get-less-obvious.js: Added.
+            * js/regress/script-tests/gcse-poly-get.js: Added.
+            * js/regress/script-tests/gcse.js: Added.
+    
+    2014-07-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Infer immutable object properties
+            https://bugs.webkit.org/show_bug.cgi?id=134567
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * js/regress/infer-constant-global-property-expected.txt: Added.
+            * js/regress/infer-constant-global-property.html: Added.
+            * js/regress/infer-constant-property-expected.txt: Added.
+            * js/regress/infer-constant-property.html: Added.
+            * js/regress/script-tests/infer-constant-global-property.js: Added.
+            * js/regress/script-tests/infer-constant-property.js: Added.
+    
</ins><span class="cx"> 2014-08-05  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r172099.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressgcseexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/gcse-expected.txt (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/gcse-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/gcse-expected.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/gcse
+
+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="trunkLayoutTestsjsregressgcsepolygetexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/gcse-poly-get-expected.txt (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/gcse-poly-get-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/gcse-poly-get-expected.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/gcse-poly-get
+
+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="trunkLayoutTestsjsregressgcsepolygetlessobviousexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious-expected.txt (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious-expected.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/gcse-poly-get-less-obvious
+
+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="trunkLayoutTestsjsregressgcsepolygetlessobvioushtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious.html (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/gcse-poly-get-less-obvious.html        2014-08-06 05:27:46 UTC (rev 172129)
</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/gcse-poly-get-less-obvious.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="trunkLayoutTestsjsregressgcsepolygethtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/gcse-poly-get.html (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/gcse-poly-get.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/gcse-poly-get.html        2014-08-06 05:27:46 UTC (rev 172129)
</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/gcse-poly-get.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="trunkLayoutTestsjsregressgcsehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/gcse.html (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/gcse.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/gcse.html        2014-08-06 05:27:46 UTC (rev 172129)
</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/gcse.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="trunkLayoutTestsjsregressinferconstantglobalpropertyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/infer-constant-global-property-expected.txt (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/infer-constant-global-property-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/infer-constant-global-property-expected.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/infer-constant-global-property
+
+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="trunkLayoutTestsjsregressinferconstantglobalpropertyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/infer-constant-global-property.html (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/infer-constant-global-property.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/infer-constant-global-property.html        2014-08-06 05:27:46 UTC (rev 172129)
</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/infer-constant-global-property.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="trunkLayoutTestsjsregressinferconstantpropertyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/infer-constant-property-expected.txt (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/infer-constant-property-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/infer-constant-property-expected.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/infer-constant-property
+
+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="trunkLayoutTestsjsregressinferconstantpropertyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/infer-constant-property.html (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/infer-constant-property.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/infer-constant-property.html        2014-08-06 05:27:46 UTC (rev 172129)
</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/infer-constant-property.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="trunkLayoutTestsjsregressscripttestsgcsepolygetlessobviousjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/gcse-poly-get-less-obvious.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/gcse-poly-get-less-obvious.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/gcse-poly-get-less-obvious.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+(function(o, p) {
+    var result = 0;
+    var n = 1000000;
+    for (var i = 0 ; i &lt; n; ++i) {
+        var a = o.f;
+        var b = o.f;
+        var c = o.f;
+        var d = o.f;
+        if (d) {
+            var e = o.f;
+            var f = o.f;
+            var g = o.f;
+            var h = o.f;
+            if (h) {
+                var j = o.f;
+                var k = o.f;
+                var l = o.f;
+                var m = o.f;
+                if (m) {
+                    var q = o.f;
+                    var r = o.f;
+                    var s = o.f;
+                    var t = o.f;
+                    if (t)
+                        result += r;
+                }
+            }
+        }
+        var tmp = o;
+        o = p;
+        p = tmp;
+    }
+    if (result != (n / 2) * o.f + (n / 2) * p.f)
+        throw &quot;Error: bad result: &quot; + result;
+})({f:42, g:0}, {g:0, f:43});
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsgcsepolygetjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/gcse-poly-get.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/gcse-poly-get.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/gcse-poly-get.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+(function(){
+    var o = {f:42, g:0};
+    var p = {g:0, f:43};
+    var result = 0;
+    var n = 1000000;
+    for (var i = 0 ; i &lt; n; ++i) {
+        var a = o.f;
+        var b = o.f;
+        var c = o.f;
+        var d = o.f;
+        if (d) {
+            var e = o.f;
+            var f = o.f;
+            var g = o.f;
+            var h = o.f;
+            if (h) {
+                var j = o.f;
+                var k = o.f;
+                var l = o.f;
+                var m = o.f;
+                if (m) {
+                    var q = o.f;
+                    var r = o.f;
+                    var s = o.f;
+                    var t = o.f;
+                    if (t)
+                        result += r;
+                }
+            }
+        }
+        var tmp = o;
+        o = p;
+        p = tmp;
+    }
+    if (result != (n / 2) * o.f + (n / 2) * p.f)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsgcsejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/gcse.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/gcse.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/gcse.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+(function(){
+    var o = {f:42};
+    var p = {f:43};
+    var result = 0;
+    var n = 1000000;
+    for (var i = 0 ; i &lt; n; ++i) {
+        var a = o.f;
+        var b = o.f;
+        var c = o.f;
+        var d = o.f;
+        if (d) {
+            var e = o.f;
+            var f = o.f;
+            var g = o.f;
+            var h = o.f;
+            if (h) {
+                var j = o.f;
+                var k = o.f;
+                var l = o.f;
+                var m = o.f;
+                if (m) {
+                    var q = o.f;
+                    var r = o.f;
+                    var s = o.f;
+                    var t = o.f;
+                    if (t)
+                        result += r;
+                }
+            }
+        }
+        var tmp = o;
+        o = p;
+        p = tmp;
+    }
+    if (result != (n / 2) * o.f + (n / 2) * p.f)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsinferconstantglobalpropertyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/infer-constant-global-property.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/infer-constant-global-property.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/infer-constant-global-property.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+(function() {
+    var result = 0;
+    for (var i = 0; i &lt; 1000000; ++i) {
+        result += Math.sin(Math.PI);
+    }
+    if (Math.abs(result) &gt; 1e-8)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsinferconstantpropertyjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/infer-constant-property.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/infer-constant-property.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/infer-constant-property.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+var o = {f:{f:{f:{f:{f:{f:{f:42}}}}}}};
+(function() {
+    var n = 1000000;
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i)
+        result += o.f.f.f.f.f.f.f;
+    
+    if (result != n * 42)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestssputnikImplementation_DiagnosticsS1264_D1expectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1-expected.txt (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1-expected.txt        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1-expected.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,6 +0,0 @@
</span><del>-S12.6.4_D1
-
-FAIL SputnikError: #1: the newly added properties to be visited in the active enumeration
-
-TEST COMPLETE
-
</del></span></pre></div>
<a id="trunkLayoutTestssputnikImplementation_DiagnosticsS1264_D1html"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1.html (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1.html        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/LayoutTests/sputnik/Implementation_Diagnostics/S12.6.4_D1.html        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,130 +0,0 @@
</span><del>-&lt;html&gt;
-&lt;head&gt;
-&lt;meta charset='utf-8'&gt;
-&lt;style&gt;
-.pass {
-    font-weight: bold;
-    color: green;
-}
-.fail {
-    font-weight: bold;
-    color: red;
-}
-&lt;/style&gt;
-
-&lt;script&gt;
-if (window.testRunner)
-    testRunner.dumpAsText();
-
-function SputnikError(message)
-{
-    this.message = message;
-}
-
-SputnikError.prototype.toString = function ()
-{
-    return 'SputnikError: ' + this.message;
-};
-
-var sputnikException;
-
-function testPrint(msg)
-{
-    var span = document.createElement(&quot;span&quot;);
-    document.getElementById(&quot;console&quot;).appendChild(span); // insert it first so XHTML knows the namespace 
-    span.innerHTML = msg + '&lt;br /&gt;';
-}
-
-function escapeHTML(text)
-{
-    return text.toString().replace(/&amp;/g, &quot;&amp;amp;&quot;).replace(/&lt;/g, &quot;&amp;lt;&quot;);
-}
-
-function printTestPassed(msg)
-{
-    testPrint('&lt;span&gt;&lt;span class=&quot;pass&quot;&gt;PASS&lt;/span&gt; ' + escapeHTML(msg) + '&lt;/span&gt;');
-}
-
-function printTestFailed(msg)
-{
-    testPrint('&lt;span&gt;&lt;span class=&quot;fail&quot;&gt;FAIL&lt;/span&gt; ' + escapeHTML(msg) + '&lt;/span&gt;');
-}
-
-function testFailed(msg)
-{
-    throw new SputnikError(msg);
-}
-
-var successfullyParsed = false;
-&lt;/script&gt;
-
-&lt;/head&gt;
-&lt;body&gt;
-&lt;p&gt;S12.6.4_D1&lt;/p&gt;
-&lt;div id='console'&gt;&lt;/div&gt;
-&lt;script&gt;
-try {
-
-/**
-* @name: S12.6.4_D1;
-* @section: 12.6.4;
-* @assertion: If new properties are added to the object being
-* enumerated during enumeration, the newly added properties to be visited in the active
-* enumeration;
-*/
-
-__obj={aa:1,ba:2,ca:3};
-__source={sra:9,srb:8,src:7};
-
-__accum=&quot;&quot;;
-
-for (__key in __obj){
-        
-        __accum+=(__key+__obj[__key]);
-        
-        add2hash(__obj,__source);
-        
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-//CHECK#1
-if (!(
-(__accum.indexOf(&quot;aa1&quot;)!==-1)&amp;&amp;
-(__accum.indexOf(&quot;ba2&quot;)!==-1)&amp;&amp;
-(__accum.indexOf(&quot;ca3&quot;)!==-1)&amp;&amp;
-(__accum.indexOf(&quot;sra9&quot;)!==-1)&amp;&amp;
-(__accum.indexOf(&quot;srb8&quot;)!==-1)&amp;&amp;
-(__accum.indexOf(&quot;src7&quot;)!==-1)
-)) {
-        testFailed('#1: the newly added properties to be visited in the active enumeration');
-}
-//
-//////////////////////////////////////////////////////////////////////////////
-
-function add2hash(hash_map_target, hash_map_be_added){
-    if (added) return;
-        for (key in hash_map_be_added){
-                        hash_map_target[key] = hash_map_be_added[key];
-        }
-        var added = true;
-}
-
-} catch (ex) {
-    sputnikException = ex;
-}
-
-var successfullyParsed = true;
-&lt;/script&gt;
-
-&lt;script&gt;
-if (!successfullyParsed)
-    printTestFailed('successfullyParsed is not set');
-else if (sputnikException)
-    printTestFailed(sputnikException);
-else
-    printTestPassed(&quot;&quot;);
-testPrint('&lt;br /&gt;&lt;span class=&quot;pass&quot;&gt;TEST COMPLETE&lt;/span&gt;');
-&lt;/script&gt;
-&lt;/body&gt;
-&lt;/html&gt;
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx">     bytecode/CodeBlockJettisoningWatchpoint.cpp
</span><span class="cx">     bytecode/CodeOrigin.cpp
</span><span class="cx">     bytecode/CodeType.cpp
</span><ins>+    bytecode/ComplerGetStatus.cpp
</ins><span class="cx">     bytecode/ConstantStructureCheck.cpp
</span><span class="cx">     bytecode/DFGExitProfile.cpp
</span><span class="cx">     bytecode/DeferredCompilationCallback.cpp
</span><span class="lines">@@ -155,6 +156,7 @@
</span><span class="cx">     dfg/DFGFunctionWhitelist.cpp
</span><span class="cx">     dfg/DFGGraph.cpp
</span><span class="cx">     dfg/DFGGraphSafepoint.cpp
</span><ins>+    dfg/DFGHeapLocation.cpp
</ins><span class="cx">     dfg/DFGInPlaceAbstractState.cpp
</span><span class="cx">     dfg/DFGIntegerCheckCombiningPhase.cpp
</span><span class="cx">     dfg/DFGInvalidationPointInjectionPhase.cpp
</span><span class="lines">@@ -184,10 +186,12 @@
</span><span class="cx">     dfg/DFGOSRExitJumpPlaceholder.cpp
</span><span class="cx">     dfg/DFGOSRExitPreparation.cpp
</span><span class="cx">     dfg/DFGOperations.cpp
</span><ins>+    dfg/DFGPhantomRemovalPhase.cpp
</ins><span class="cx">     dfg/DFGPhase.cpp
</span><span class="cx">     dfg/DFGPlan.cpp
</span><span class="cx">     dfg/DFGPredictionInjectionPhase.cpp
</span><span class="cx">     dfg/DFGPredictionPropagationPhase.cpp
</span><ins>+    dfg/DFGPureValue.cpp
</ins><span class="cx">     dfg/DFGResurrectionForValidationPhase.cpp
</span><span class="cx">     dfg/DFGSSAConversionPhase.cpp
</span><span class="cx">     dfg/DFGSSALoweringPhase.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,3 +1,1201 @@
</span><ins>+2014-07-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Merge r170564, r170571, r170604, r170628, r170672, r170680, r170724, r170728, r170729, r170819, r170821, r170836, r170855, r170860, r170890, r170907, r170929, r171052, r171106, r171152, r171153, r171214 from ftlopt.
+
+        This part of the merge delivers roughly a 2% across-the-board performance
+        improvement, mostly due to immutable property inference and DFG-side GCSE. It also
+        almost completely resolves accessor performance issues; in the common case the DFG
+        will compile a getter/setter access into code that is just as efficient as a normal
+        property access.
+        
+        Another major highlight of this part of the merge is the work to add a type profiler
+        to the inspector. This work is still on-going but this greatly increases coverage.
+
+        Note that this merge fixes a minor bug in the GetterSetter refactoring from
+        http://trac.webkit.org/changeset/170729 (https://bugs.webkit.org/show_bug.cgi?id=134518).
+        It also adds a new tests to tests/stress to cover that bug. That bug was previously only
+        covered by layout tests.
+
+    2014-07-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw (merge trunk r171190)
+            https://bugs.webkit.org/show_bug.cgi?id=135019
+    
+            Reviewed by Oliver Hunt.
+            
+            Behaviorally, this is just a merge of trunk r171190, except that the relevant functionality
+            has moved to StrengthReductionPhase and is written in a different style. Same algorithm,
+            different code.
+    
+            * dfg/DFGNodeType.h:
+            * dfg/DFGStrengthReductionPhase.cpp:
+            (JSC::DFG::StrengthReductionPhase::handleNode):
+            * tests/stress/capture-escape-and-throw.js: Added.
+            (foo.f):
+            (foo):
+            * tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
+            (foo):
+            (bar):
+    
+    2014-07-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Constant fold GetGetter and GetSetter if the GetterSetter is a constant
+            https://bugs.webkit.org/show_bug.cgi?id=134962
+    
+            Reviewed by Oliver Hunt.
+            
+            This removes yet another steady-state-throughput implication of using getters and setters:
+            if your accessor call is monomorphic then you'll just get a structure check, nothing more.
+            No more loads to get to the GetterSetter object or the accessor function object.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+            * runtime/GetterSetter.h:
+            (JSC::GetterSetter::getterConcurrently):
+            (JSC::GetterSetter::setGetter):
+            (JSC::GetterSetter::setterConcurrently):
+            (JSC::GetterSetter::setSetter):
+    
+    2014-07-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Identity replacement in CSE shouldn't create a Phantom over the Identity's children
+            https://bugs.webkit.org/show_bug.cgi?id=134893
+    
+            Reviewed by Oliver Hunt.
+            
+            Replace Identity with Check instead of Phantom. Phantom means that the child of the
+            Identity should be unconditionally live. The liveness semantics of Identity are such that
+            if the parents of Identity are live then the child is live. Removing the Identity entirely
+            preserves such liveness semantics. So, the only thing that should be left behind is the
+            type check on the child, which is what Check means: do the check but don't keep the child
+            alive if the check isn't needed.
+    
+            * dfg/DFGCSEPhase.cpp:
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToCheck):
+    
+    2014-07-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] DFG should be able to do GCSE in SSA and this should be unified with the CSE in CPS, and both of these things should use abstract heaps for reasoning about effects
+            https://bugs.webkit.org/show_bug.cgi?id=134677
+    
+            Reviewed by Sam Weinig.
+            
+            This removes the old local CSE phase, which was based on manually written backward-search 
+            rules for all of the different kinds of things we cared about, and adds a new local/global
+            CSE (local for CPS and global for SSA) that leaves the node semantics almost entirely up to
+            clobberize(). Thus, the CSE phase itself just worries about the algorithms and data
+            structures used for storing sets of available values. This results in a large reduction in
+            code size in CSEPhase.cpp while greatly increasing the phase's power (since it now does
+            global CSE) and reducing compile time (since local CSE is now rewritten to use smarter data
+            structures). Even though LLVM was already running GVN, the extra GCSE at DFG IR level means
+            that this is a significant (~0.7%) throughput improvement.
+            
+            This work is based on the concept of &quot;def&quot; to clobberize(). If clobberize() calls def(), it
+            means that the node being analyzed makes available some value in some DFG node, and that
+            future attempts to compute that value can simply use that node. In other words, it
+            establishes an available value mapping of the form value=&gt;node. There are two kinds of
+            values that can be passed to def():
+            
+            PureValue. This captures everything needed to determine whether two pure nodes - nodes that
+                neither read nor write, and produce a value that is a CSE candidate - are identical. It
+                carries the NodeType, an AdjacencyList, and one word of meta-data. The meta-data is
+                usually used for things like the arithmetic mode or constant pointer. Passing a
+                PureValue to def() means that the node produces a value that is valid anywhere that the
+                node dominates.
+            
+            HeapLocation. This describes a location in the heap that could be written to or read from.
+                Both stores and loads can def() a HeapLocation. HeapLocation carries around an abstract
+                heap that both serves as part of the &quot;name&quot; of the heap location (together with the
+                other fields of HeapLocation) and also tells us what write()'s to watch for. If someone
+                write()'s to an abstract heap that overlaps the heap associated with the HeapLocation,
+                then it means that the values for that location are no longer available.
+            
+            This approach is sufficiently clever that the CSEPhase itself can focus on the mechanism of
+            tracking the PureValue=&gt;node and HeapLocation=&gt;node maps, without having to worry about
+            interpreting the semantics of different DFG node types - that is now almost entirely in
+            clobberize(). The only things we special-case inside CSEPhase are the Identity node, which
+            CSE is traditionally responsible for eliminating even though it has nothing to do with CSE,
+            and the LocalCSE rule for turning PutByVal into PutByValAlias.
+            
+            This is a slight Octane, SunSpider, and Kraken speed-up - all somewhere arond 0.7% . It's
+            not a bigger win because LLVM was already giving us most of what we needed in its GVN.
+            Also, the SunSpider speed-up isn't from GCSE as much as it's a clean-up of local CSE - that
+            is no longer O(n^2). Basically this is purely good: it reduces the amount of LLVM IR we
+            generate, it removes the old CSE's heap modeling (which was a constant source of bugs), and
+            it improves both the quality of the code we generate and the speed with which we generate
+            it. Also, any future optimizations that depend on GCSE will now be easier to implement.
+            
+            During the development of this patch I also rationalized some other stuff, like Graph's
+            ordered traversals - we now have preorder and postorder rather than just &quot;depth first&quot;.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractHeap.h:
+            * dfg/DFGAdjacencyList.h:
+            (JSC::DFG::AdjacencyList::hash):
+            (JSC::DFG::AdjacencyList::operator==):
+            * dfg/DFGBasicBlock.h:
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::performLocalCSE):
+            (JSC::DFG::performGlobalCSE):
+            (JSC::DFG::CSEPhase::CSEPhase): Deleted.
+            (JSC::DFG::CSEPhase::run): Deleted.
+            (JSC::DFG::CSEPhase::endIndexForPureCSE): Deleted.
+            (JSC::DFG::CSEPhase::pureCSE): Deleted.
+            (JSC::DFG::CSEPhase::constantCSE): Deleted.
+            (JSC::DFG::CSEPhase::constantStoragePointerCSE): Deleted.
+            (JSC::DFG::CSEPhase::getCalleeLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getArrayLengthElimination): Deleted.
+            (JSC::DFG::CSEPhase::globalVarLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::scopedVarLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::varInjectionWatchpointElimination): Deleted.
+            (JSC::DFG::CSEPhase::getByValLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkFunctionElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkExecutableElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkStructureElimination): Deleted.
+            (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): Deleted.
+            (JSC::DFG::CSEPhase::getByOffsetLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getGetterSetterByOffsetLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkArrayElimination): Deleted.
+            (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getInternalFieldLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getMyScopeLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getLocalLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::invalidationPointElimination): Deleted.
+            (JSC::DFG::CSEPhase::setReplacement): Deleted.
+            (JSC::DFG::CSEPhase::eliminate): Deleted.
+            (JSC::DFG::CSEPhase::performNodeCSE): Deleted.
+            (JSC::DFG::CSEPhase::performBlockCSE): Deleted.
+            (JSC::DFG::performCSE): Deleted.
+            * dfg/DFGCSEPhase.h:
+            * dfg/DFGClobberSet.cpp:
+            (JSC::DFG::addReads):
+            (JSC::DFG::addWrites):
+            (JSC::DFG::addReadsAndWrites):
+            (JSC::DFG::readsOverlap):
+            (JSC::DFG::writesOverlap):
+            * dfg/DFGClobberize.cpp:
+            (JSC::DFG::doesWrites):
+            (JSC::DFG::accessesOverlap):
+            (JSC::DFG::writesOverlap):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            (JSC::DFG::NoOpClobberize::operator()):
+            (JSC::DFG::CheckClobberize::operator()):
+            (JSC::DFG::ReadMethodClobberize::ReadMethodClobberize):
+            (JSC::DFG::ReadMethodClobberize::operator()):
+            (JSC::DFG::WriteMethodClobberize::WriteMethodClobberize):
+            (JSC::DFG::WriteMethodClobberize::operator()):
+            (JSC::DFG::DefMethodClobberize::DefMethodClobberize):
+            (JSC::DFG::DefMethodClobberize::operator()):
+            * dfg/DFGDCEPhase.cpp:
+            (JSC::DFG::DCEPhase::run):
+            (JSC::DFG::DCEPhase::fixupBlock):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::getBlocksInPreOrder):
+            (JSC::DFG::Graph::getBlocksInPostOrder):
+            (JSC::DFG::Graph::addForDepthFirstSort): Deleted.
+            (JSC::DFG::Graph::getBlocksInDepthFirstOrder): Deleted.
+            * dfg/DFGGraph.h:
+            * dfg/DFGHeapLocation.cpp: Added.
+            (JSC::DFG::HeapLocation::dump):
+            (WTF::printInternal):
+            * dfg/DFGHeapLocation.h: Added.
+            (JSC::DFG::HeapLocation::HeapLocation):
+            (JSC::DFG::HeapLocation::operator!):
+            (JSC::DFG::HeapLocation::kind):
+            (JSC::DFG::HeapLocation::heap):
+            (JSC::DFG::HeapLocation::base):
+            (JSC::DFG::HeapLocation::index):
+            (JSC::DFG::HeapLocation::hash):
+            (JSC::DFG::HeapLocation::operator==):
+            (JSC::DFG::HeapLocation::isHashTableDeletedValue):
+            (JSC::DFG::HeapLocationHash::hash):
+            (JSC::DFG::HeapLocationHash::equal):
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::run):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::replaceWith):
+            (JSC::DFG::Node::convertToPhantomUnchecked): Deleted.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * dfg/DFGPureValue.cpp: Added.
+            (JSC::DFG::PureValue::dump):
+            * dfg/DFGPureValue.h: Added.
+            (JSC::DFG::PureValue::PureValue):
+            (JSC::DFG::PureValue::operator!):
+            (JSC::DFG::PureValue::op):
+            (JSC::DFG::PureValue::children):
+            (JSC::DFG::PureValue::info):
+            (JSC::DFG::PureValue::hash):
+            (JSC::DFG::PureValue::operator==):
+            (JSC::DFG::PureValue::isHashTableDeletedValue):
+            (JSC::DFG::PureValueHash::hash):
+            (JSC::DFG::PureValueHash::equal):
+            * dfg/DFGSSAConversionPhase.cpp:
+            (JSC::DFG::SSAConversionPhase::run):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::lower):
+    
+    2014-07-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            Unreviewed, revert unintended change in r171051.
+    
+            * dfg/DFGCSEPhase.cpp:
+    
+    2014-07-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Move Flush(SetLocal) store elimination to StrengthReductionPhase
+            https://bugs.webkit.org/show_bug.cgi?id=134739
+    
+            Reviewed by Mark Hahnenberg.
+            
+            I'm going to streamline CSE around clobberize() as part of
+            https://bugs.webkit.org/show_bug.cgi?id=134677, and so Flush(SetLocal) store
+            elimination wouldn't belong in CSE anymore. It doesn't quite belong anywhere, which
+            means that it belongs in StrengthReductionPhase, since that's intended to be our
+            dumping ground.
+            
+            To do this I had to add some missing smarts to clobberize(). Previously clobberize()
+            could play a bit loose with reads of Variables because it wasn't used for store
+            elimination. The main client of read() was LICM, but it would only use it to
+            determine hoistability and anything that did a write() was not hoistable - so, we had
+            benign (but still wrong) missing read() calls in places that did write()s. This fixes
+            a bunch of those cases.
+    
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::setLocalStoreElimination): Deleted.
+            * dfg/DFGClobberize.cpp:
+            (JSC::DFG::accessesOverlap):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize): Make clobberize() smart enough for detecting when this store elimination would be sound.
+            * dfg/DFGStrengthReductionPhase.cpp:
+            (JSC::DFG::StrengthReductionPhase::handleNode): Implement the store elimination in terms of clobberize().
+    
+    2014-07-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Phantom simplification should be in its own phase
+            https://bugs.webkit.org/show_bug.cgi?id=134742
+    
+            Reviewed by Geoffrey Garen.
+            
+            This moves Phantom simplification out of CSE, which greatly simplifies CSE and gives it
+            more focus. Also this finally adds a phase that removes empty Phantoms. We sort of had
+            this in CPSRethreading, but that phase runs too infrequently and doesn't run at all for
+            SSA.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAdjacencyList.h:
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::run):
+            (JSC::DFG::CSEPhase::setReplacement):
+            (JSC::DFG::CSEPhase::eliminate):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren): Deleted.
+            * dfg/DFGPhantomRemovalPhase.cpp: Added.
+            (JSC::DFG::PhantomRemovalPhase::PhantomRemovalPhase):
+            (JSC::DFG::PhantomRemovalPhase::run):
+            (JSC::DFG::performCleanUp):
+            * dfg/DFGPhantomRemovalPhase.h: Added.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+    
+    2014-07-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Get rid of Node::misc by moving the fields out of the union so that you can use replacement and owner simultaneously
+            https://bugs.webkit.org/show_bug.cgi?id=134730
+    
+            Reviewed by Mark Lam.
+            
+            This will allow for a better GCSE implementation.
+    
+            * dfg/DFGCPSRethreadingPhase.cpp:
+            (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::setReplacement):
+            * dfg/DFGEdgeDominates.h:
+            (JSC::DFG::EdgeDominates::operator()):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::clearReplacements):
+            (JSC::DFG::Graph::initializeNodeOwners):
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::performSubstitutionForEdge):
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::attemptHoist):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::Node):
+            * dfg/DFGSSAConversionPhase.cpp:
+            (JSC::DFG::SSAConversionPhase::run):
+    
+    2014-07-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Infer immutable object properties
+            https://bugs.webkit.org/show_bug.cgi?id=134567
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This introduces a new way of inferring immutable object properties. A property is said to
+            be immutable if after its creation (i.e. the transition that creates it), we never
+            overwrite it (i.e. replace it) or delete it. Immutability is a property of an &quot;own
+            property&quot; - so if we say that &quot;f&quot; is immutable at &quot;o&quot; then we are implying that &quot;o&quot; has &quot;f&quot;
+            directly and not on a prototype. More specifically, the immutability inference will prove
+            that a property on some structure is immutable. This means that, for example, we may have a
+            structure S1 with property &quot;f&quot; where we claim that &quot;f&quot; at S1 is immutable, but S1 has a
+            transition to S2 that adds a new property &quot;g&quot; and we may claim that &quot;f&quot; at S2 is actually
+            mutable. This is mainly for convenience; it allows us to decouple immutability logic from
+            transition logic. Immutability can be used to constant-fold accesses to objects at
+            DFG-time. The DFG needs to prove the following to constant-fold the access:
+            
+            - The base of the access must be a constant object pointer. We prove that a property at a
+              structure is immutable, but that says nothing of its value; each actual instance of that
+              property may have a different value. So, a constant object pointer is needed to get an
+              actual constant instance of the immutable value.
+            
+            - A check (or watchpoint) must have been emitted proving that the object has a structure
+              that allows loading the property in question.
+            
+            - The replacement watchpoint set of the property in the structure that we've proven the
+              object to have is still valid and we add a watchpoint to it lazily. The replacement
+              watchpoint set is the key new mechanism that this change adds. It's possible that we have
+              proven that the object has one of many structures, in which case each of those structures
+              needs a valid replacement watchpoint set.
+            
+            The replacement watchpoint set is created the first time that any access to the property is
+            cached. A put replace cache will create, and immediately invalidate, the watchpoint set. A
+            get cache will create the watchpoint set and make it start watching. Any non-cached put
+            access will invalidate the watchpoint set if one had been created; the underlying algorithm
+            ensures that checking for the existence of a replacement watchpoint set is very fast in the
+            common case. This algorithm ensures that no cached access needs to ever do any work to
+            invalidate, or check the validity of, any replacement watchpoint sets. It also has some
+            other nice properties:
+            
+            - It's very robust in its definition of immutability. The strictest that it will ever be is
+              that for any instance of the object, the property must be written to only once,
+              specifically at the time that the property is created. But it's looser than this in
+              practice. For example, the property may be written to any number of times before we add
+              the final property that the object will have before anyone reads the property; this works
+              since for optimization purposes we only care if we detect immutability on the structure
+              that the object will have when it is most frequently read from, not any previous
+              structure that the object had. Also, we may write to the property any number of times
+              before anyone caches accesses to it.
+            
+            - It is mostly orthogonal to structure transitions. No new structures need to be created to
+              track the immutability of a property. Hence, there is no risk from this feature causing
+              more polymorphism. This is different from the previous &quot;specificValue&quot; constant
+              inference, which did cause additional structures to be created and sometimes those
+              structures led to fake polymorphism. This feature does leverage existing transitions to
+              do some of the watchpointing: property deletions don't fire the replacement watchpoint
+              set because that would cause a new structure and so the mandatory structure check would
+              fail. Also, this feature is guaranteed to never kick in for uncacheable dictionaries
+              because those wouldn't allow for cacheable accesses - and it takes a cacheable access for
+              this feature to be enabled.
+            
+            - No memory overhead is incurred except when accesses to the property are cached.
+              Dictionary properties will typically have no meta-data for immutability. The number of
+              replacement watchpoint sets we allocate is proportional to the number of inline caches in
+              the program, which is typically must smaller than the number of structures or even the
+              number of objects.
+            
+            This inference is far more powerful than the previous &quot;specificValue&quot; inference, so this
+            change also removes all of that code. It's interesting that the amount of code that is
+            changed to remove that feature is almost as big as the amount of code added to support the
+            new inference - and that's if you include the new tests in the tally. Without new tests,
+            it appears that the new feature actually touches less code!
+            
+            There is one corner case where the previous &quot;specificValue&quot; inference was more powerful.
+            You can imagine someone creating objects with functions as self properties on those
+            objects, such that each object instance had the same function pointers - essentially,
+            someone might be trying to create a vtable but failing at the whole &quot;one vtable for many
+            instances&quot; concept. The &quot;specificValue&quot; inference would do very well for such programs,
+            because a structure check would be sufficient to prove a constant value for all of the
+            function properties. This new inference will fail because it doesn't track the constant
+            values of constant properties; instead it detects the immutability of otherwise variable
+            properties (in the sense that each instance of the property may have a different value).
+            So, the new inference requires having a particular object instance to actually get the
+            constant value. I think it's OK to lose this antifeature. It took a lot of code to support
+            and was a constant source of grief in our transition logic, and there doesn't appear to be
+            any real evidence that programs benefited from that particular kind of inference since
+            usually it's the singleton prototype instance that has all of the functions.
+            
+            This change is a speed-up on everything. date-format-xparb and both SunSpider/raytrace and
+            V8/raytrace seem to be the biggest winners among the macrobenchmarks; they see &gt;5%
+            speed-ups. Many of our microbenchmarks see very large performance improvements, even 80% in
+            one case.
+    
+            * bytecode/ComplexGetStatus.cpp:
+            (JSC::ComplexGetStatus::computeFor):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeFromLLInt):
+            (JSC::GetByIdStatus::computeForStubInfo):
+            (JSC::GetByIdStatus::computeFor):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            (JSC::GetByIdVariant::operator=):
+            (JSC::GetByIdVariant::attemptToMerge):
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::alternateBase):
+            (JSC::GetByIdVariant::specificValue): Deleted.
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeForStubInfo):
+            (JSC::PutByIdStatus::computeFor):
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::operator=):
+            (JSC::PutByIdVariant::setter):
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::specificValue): Deleted.
+            * bytecode/Watchpoint.cpp:
+            (JSC::WatchpointSet::fireAllSlow):
+            (JSC::WatchpointSet::fireAll): Deleted.
+            * bytecode/Watchpoint.h:
+            (JSC::WatchpointSet::fireAll):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleGetByOffset):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+            (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::tryGetConstantProperty):
+            (JSC::DFG::Graph::visitChildren):
+            * dfg/DFGGraph.h:
+            * dfg/DFGWatchableStructureWatchingPhase.cpp:
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            * jit/JITOperations.cpp:
+            * jit/Repatch.cpp:
+            (JSC::repatchByIdSelfAccess):
+            (JSC::generateByIdStub):
+            (JSC::tryCacheGetByID):
+            (JSC::tryCachePutByID):
+            (JSC::tryBuildPutByIdList):
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+            (JSC::LLInt::putToScopeCommon):
+            * runtime/CommonSlowPaths.h:
+            (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::mayInterceptStoreTo):
+            * runtime/JSCJSValue.cpp:
+            (JSC::JSValue::putToPrimitive):
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::reset):
+            * runtime/JSObject.cpp:
+            (JSC::JSObject::put):
+            (JSC::JSObject::putDirectNonIndexAccessor):
+            (JSC::JSObject::deleteProperty):
+            (JSC::JSObject::defaultValue):
+            (JSC::getCallableObjectSlow): Deleted.
+            (JSC::JSObject::getPropertySpecificValue): Deleted.
+            * runtime/JSObject.h:
+            (JSC::JSObject::getDirect):
+            (JSC::JSObject::getDirectOffset):
+            (JSC::JSObject::inlineGetOwnPropertySlot):
+            (JSC::JSObject::putDirectInternal):
+            (JSC::JSObject::putOwnDataProperty):
+            (JSC::JSObject::putDirect):
+            (JSC::JSObject::putDirectWithoutTransition):
+            (JSC::getCallableObject): Deleted.
+            * runtime/JSScope.cpp:
+            (JSC::abstractAccess):
+            * runtime/PropertyMapHashTable.h:
+            (JSC::PropertyMapEntry::PropertyMapEntry):
+            (JSC::PropertyTable::copy):
+            * runtime/PropertyTable.cpp:
+            (JSC::PropertyTable::clone):
+            (JSC::PropertyTable::PropertyTable):
+            (JSC::PropertyTable::visitChildren): Deleted.
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            (JSC::Structure::materializePropertyMap):
+            (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
+            (JSC::Structure::addPropertyTransitionToExistingStructure):
+            (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
+            (JSC::Structure::addPropertyTransition):
+            (JSC::Structure::changePrototypeTransition):
+            (JSC::Structure::attributeChangeTransition):
+            (JSC::Structure::toDictionaryTransition):
+            (JSC::Structure::preventExtensionsTransition):
+            (JSC::Structure::takePropertyTableOrCloneIfPinned):
+            (JSC::Structure::nonPropertyTransition):
+            (JSC::Structure::addPropertyWithoutTransition):
+            (JSC::Structure::allocateRareData):
+            (JSC::Structure::ensurePropertyReplacementWatchpointSet):
+            (JSC::Structure::startWatchingPropertyForReplacements):
+            (JSC::Structure::didCachePropertyReplacement):
+            (JSC::Structure::startWatchingInternalProperties):
+            (JSC::Structure::copyPropertyTable):
+            (JSC::Structure::copyPropertyTableForPinning):
+            (JSC::Structure::getConcurrently):
+            (JSC::Structure::get):
+            (JSC::Structure::add):
+            (JSC::Structure::visitChildren):
+            (JSC::Structure::prototypeChainMayInterceptStoreTo):
+            (JSC::Structure::dump):
+            (JSC::Structure::despecifyDictionaryFunction): Deleted.
+            (JSC::Structure::despecifyFunctionTransition): Deleted.
+            (JSC::Structure::despecifyFunction): Deleted.
+            (JSC::Structure::despecifyAllFunctions): Deleted.
+            (JSC::Structure::putSpecificValue): Deleted.
+            * runtime/Structure.h:
+            (JSC::Structure::startWatchingPropertyForReplacements):
+            (JSC::Structure::startWatchingInternalPropertiesIfNecessary):
+            (JSC::Structure::startWatchingInternalPropertiesIfNecessaryForEntireChain):
+            (JSC::Structure::transitionDidInvolveSpecificValue): Deleted.
+            (JSC::Structure::disableSpecificFunctionTracking): Deleted.
+            * runtime/StructureInlines.h:
+            (JSC::Structure::getConcurrently):
+            (JSC::Structure::didReplaceProperty):
+            (JSC::Structure::propertyReplacementWatchpointSet):
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::destroy):
+            * runtime/StructureRareData.h:
+            * tests/stress/infer-constant-global-property.js: Added.
+            (foo.Math.sin):
+            (foo):
+            * tests/stress/infer-constant-property.js: Added.
+            (foo):
+            * tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js: Added.
+            (foo):
+            (bar):
+    
+    2014-07-03  Saam Barati  &lt;sbarati@apple.com&gt;
+    
+            Add more coverage for the profile_types_with_high_fidelity op code.
+            https://bugs.webkit.org/show_bug.cgi?id=134616
+    
+            Reviewed by Filip Pizlo.
+    
+            More operations are now being recorded by the profile_types_with_high_fidelity 
+            opcode. Specifically: function parameters, function return values,
+            function 'this' value, get_by_id, get_by_value, resolve nodes, function return 
+            values at the call site. Added more flags to the profile_types_with_high_fidelity
+            opcode so more focused tasks can take place when the instruction is
+            being linked in CodeBlock. Re-worked the type profiler to search 
+            through character offset ranges when asked for the type of an expression
+            at a given offset. Removed redundant calls to Structure::toStructureShape
+            in HighFidelityLog and TypeSet by caching calls based on StructureID.
+    
+            * bytecode/BytecodeList.json:
+            * bytecode/BytecodeUseDef.h:
+            (JSC::computeUsesForBytecodeOffset):
+            (JSC::computeDefsForBytecodeOffset):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::finalizeUnconditionally):
+            (JSC::CodeBlock::scopeDependentProfile):
+            * bytecode/CodeBlock.h:
+            (JSC::CodeBlock::returnStatementTypeSet):
+            * bytecode/TypeLocation.h:
+            * bytecode/UnlinkedCodeBlock.cpp:
+            (JSC::UnlinkedCodeBlock::highFidelityTypeProfileExpressionInfoForBytecodeOffset):
+            (JSC::UnlinkedCodeBlock::addHighFidelityTypeProfileExpressionInfo):
+            * bytecode/UnlinkedCodeBlock.h:
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::emitMove):
+            (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+            (JSC::BytecodeGenerator::emitGetFromScopeWithProfile):
+            (JSC::BytecodeGenerator::emitPutToScope):
+            (JSC::BytecodeGenerator::emitPutToScopeWithProfile):
+            (JSC::BytecodeGenerator::emitPutById):
+            (JSC::BytecodeGenerator::emitPutByVal):
+            * bytecompiler/BytecodeGenerator.h:
+            (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::ResolveNode::emitBytecode):
+            (JSC::BracketAccessorNode::emitBytecode):
+            (JSC::DotAccessorNode::emitBytecode):
+            (JSC::FunctionCallValueNode::emitBytecode):
+            (JSC::FunctionCallResolveNode::emitBytecode):
+            (JSC::FunctionCallBracketNode::emitBytecode):
+            (JSC::FunctionCallDotNode::emitBytecode):
+            (JSC::CallFunctionCallDotNode::emitBytecode):
+            (JSC::ApplyFunctionCallDotNode::emitBytecode):
+            (JSC::PostfixNode::emitResolve):
+            (JSC::PostfixNode::emitBracket):
+            (JSC::PostfixNode::emitDot):
+            (JSC::PrefixNode::emitResolve):
+            (JSC::PrefixNode::emitBracket):
+            (JSC::PrefixNode::emitDot):
+            (JSC::ReadModifyResolveNode::emitBytecode):
+            (JSC::AssignResolveNode::emitBytecode):
+            (JSC::AssignDotNode::emitBytecode):
+            (JSC::ReadModifyDotNode::emitBytecode):
+            (JSC::AssignBracketNode::emitBytecode):
+            (JSC::ReadModifyBracketNode::emitBytecode):
+            (JSC::ReturnNode::emitBytecode):
+            (JSC::FunctionBodyNode::emitBytecode):
+            * inspector/agents/InspectorRuntimeAgent.cpp:
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset):
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange): Deleted.
+            * inspector/agents/InspectorRuntimeAgent.h:
+            * inspector/protocol/Runtime.json:
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::getFromScopeCommon):
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+            * llint/LLIntSlowPaths.h:
+            * llint/LowLevelInterpreter.asm:
+            * runtime/HighFidelityLog.cpp:
+            (JSC::HighFidelityLog::processHighFidelityLog):
+            (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
+            (JSC::HighFidelityLog::recordTypeInformationForLocation): Deleted.
+            * runtime/HighFidelityLog.h:
+            (JSC::HighFidelityLog::recordTypeInformationForLocation):
+            * runtime/HighFidelityTypeProfiler.cpp:
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset):
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset):
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset):
+            (JSC::HighFidelityTypeProfiler::insertNewLocation):
+            (JSC::HighFidelityTypeProfiler::findLocation):
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange): Deleted.
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange): Deleted.
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange): Deleted.
+            (JSC::HighFidelityTypeProfiler::getLocationBasedHash): Deleted.
+            * runtime/HighFidelityTypeProfiler.h:
+            (JSC::LocationKey::LocationKey): Deleted.
+            (JSC::LocationKey::hash): Deleted.
+            (JSC::LocationKey::operator==): Deleted.
+            * runtime/Structure.cpp:
+            (JSC::Structure::toStructureShape):
+            * runtime/Structure.h:
+            * runtime/TypeSet.cpp:
+            (JSC::TypeSet::TypeSet):
+            (JSC::TypeSet::addTypeForValue):
+            (JSC::TypeSet::seenTypes):
+            (JSC::TypeSet::removeDuplicatesInStructureHistory): Deleted.
+            * runtime/TypeSet.h:
+            (JSC::StructureShape::setConstructorName):
+            * runtime/VM.cpp:
+            (JSC::VM::getTypesForVariableAtOffset):
+            (JSC::VM::dumpHighFidelityProfilingTypes):
+            (JSC::VM::getTypesForVariableInRange): Deleted.
+            * runtime/VM.h:
+    
+    2014-07-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt][REGRESSION] debug tests fail because PutByIdDirect is now implemented in terms of In
+            https://bugs.webkit.org/show_bug.cgi?id=134642
+    
+            Rubber stamped by Andreas Kling.
+    
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+    
+    2014-07-01  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Allocate a new GetterSetter if we change the value of any of its entries other than when they were previously null, so that if we constant-infer an accessor slot then we immediately get the function constant for free
+            https://bugs.webkit.org/show_bug.cgi?id=134518
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This has no real effect right now, particularly since almost all uses of
+            setSetter/setGetter were already allocating a branch new GetterSetter. But once we start
+            doing more aggressive constant property inference, this change will allow us to remove
+            all runtime checks from getter/setter calls.
+    
+            * runtime/GetterSetter.cpp:
+            (JSC::GetterSetter::withGetter):
+            (JSC::GetterSetter::withSetter):
+            * runtime/GetterSetter.h:
+            (JSC::GetterSetter::setGetter):
+            (JSC::GetterSetter::setSetter):
+            * runtime/JSObject.cpp:
+            (JSC::JSObject::defineOwnNonIndexProperty):
+    
+    2014-07-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Rename notifyTransitionFromThisStructure to didTransitionFromThisStructure
+    
+            Rubber stamped by Mark Hahnenberg.
+    
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            (JSC::Structure::nonPropertyTransition):
+            (JSC::Structure::didTransitionFromThisStructure):
+            (JSC::Structure::notifyTransitionFromThisStructure): Deleted.
+            * runtime/Structure.h:
+    
+    2014-07-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Remove the functionality for cloning StructureRareData since we never do that anymore.
+    
+            Rubber stamped by Mark Hahnenberg.
+    
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            (JSC::Structure::cloneRareDataFrom): Deleted.
+            * runtime/Structure.h:
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::clone): Deleted.
+            (JSC::StructureRareData::StructureRareData): Deleted.
+            * runtime/StructureRareData.h:
+            (JSC::StructureRareData::needsCloning): Deleted.
+    
+    2014-07-01  Mark Lam  &lt;mark.lam@apple.com&gt;
+    
+            [ftlopt] DebuggerCallFrame::scope() should return a DebuggerScope.
+            &lt;https://webkit.org/b/134420&gt;
+    
+            Reviewed by Geoffrey Garen.
+    
+            Previously, DebuggerCallFrame::scope() returns a JSActivation (and relevant
+            peers) which the WebInspector will use to introspect CallFrame variables.
+            Instead, we should be returning a DebuggerScope as an abstraction layer that
+            provides the introspection functionality that the WebInspector needs.  This
+            is the first step towards not forcing every frame to have a JSActivation
+            object just because the debugger is enabled.
+    
+            1. Instantiate the debuggerScopeStructure as a member of the JSGlobalObject
+               instead of the VM.  This allows JSObject::globalObject() to be able to
+               return the global object for the DebuggerScope.
+    
+            2. On the DebuggerScope's life-cycle management:
+    
+               The DebuggerCallFrame is designed to be &quot;valid&quot; only during a debugging session
+               (while the debugger is broken) through the use of a DebuggerCallFrameScope in
+               Debugger::pauseIfNeeded().  Once the debugger resumes from the break, the
+               DebuggerCallFrameScope destructs, and the DebuggerCallFrame will be invalidated.
+               We can't guarantee (from this code alone) that the Inspector code isn't still
+               holding a ref to the DebuggerCallFrame (though they shouldn't), but by contract,
+               the frame will be invalidated, and any attempt to query it will return null values.
+               This is pre-existing behavior.
+    
+               Now, we're adding the DebuggerScope into the picture.  While a single debugger
+               pause session is in progress, the Inspector may request the scope from the
+               DebuggerCallFrame.  While the DebuggerCallFrame is still valid, we want
+               DebuggerCallFrame::scope() to always return the same DebuggerScope object.
+               This is why we hold on to the DebuggerScope with a strong ref.
+    
+               If we use a weak ref instead, the following cooky behavior can manifest:
+               1. The Inspector calls Debugger::scope() to get the top scope.
+               2. The Inspector iterates down the scope chain and is now only holding a
+                  reference to a parent scope.  It is no longer referencing the top scope.
+               3. A GC occurs, and the DebuggerCallFrame's weak m_scope ref to the top scope
+                  gets cleared.
+               4. The Inspector calls DebuggerCallFrame::scope() to get the top scope again but gets
+                  a different DebuggerScope instance.
+               5. The Inspector iterates down the scope chain but never sees the parent scope
+                  instance that retained a ref to in step 2 above.  This is because when iterating
+                  this new DebuggerScope instance (which has no knowledge of the previous parent
+                  DebuggerScope instance), a new DebuggerScope instance will get created for the
+                  same parent scope. 
+    
+               Since the DebuggerScope is a JSObject, it's liveness is determined by its reachability.
+               However, it's &quot;validity&quot; is determined by the life-cycle of its owner DebuggerCallFrame.
+               When the owner DebuggerCallFrame gets invalidated, its debugger scope chain (if
+               instantiated) will also get invalidated.  This is why we need the
+               DebuggerScope::invalidateChain() method.  The Inspector should not be using the
+               DebuggerScope instance after its owner DebuggerCallFrame is invalidated.  If it does,
+               those methods will do nothing or returned a failed status.
+    
+            * debugger/Debugger.h:
+            * debugger/DebuggerCallFrame.cpp:
+            (JSC::DebuggerCallFrame::scope):
+            (JSC::DebuggerCallFrame::evaluate):
+            (JSC::DebuggerCallFrame::invalidate):
+            (JSC::DebuggerCallFrame::vm):
+            (JSC::DebuggerCallFrame::lexicalGlobalObject):
+            * debugger/DebuggerCallFrame.h:
+            * debugger/DebuggerScope.cpp:
+            (JSC::DebuggerScope::DebuggerScope):
+            (JSC::DebuggerScope::finishCreation):
+            (JSC::DebuggerScope::visitChildren):
+            (JSC::DebuggerScope::className):
+            (JSC::DebuggerScope::getOwnPropertySlot):
+            (JSC::DebuggerScope::put):
+            (JSC::DebuggerScope::deleteProperty):
+            (JSC::DebuggerScope::getOwnPropertyNames):
+            (JSC::DebuggerScope::defineOwnProperty):
+            (JSC::DebuggerScope::next):
+            (JSC::DebuggerScope::invalidateChain):
+            (JSC::DebuggerScope::isWithScope):
+            (JSC::DebuggerScope::isGlobalScope):
+            (JSC::DebuggerScope::isFunctionScope):
+            * debugger/DebuggerScope.h:
+            (JSC::DebuggerScope::create):
+            (JSC::DebuggerScope::Iterator::Iterator):
+            (JSC::DebuggerScope::Iterator::get):
+            (JSC::DebuggerScope::Iterator::operator++):
+            (JSC::DebuggerScope::Iterator::operator==):
+            (JSC::DebuggerScope::Iterator::operator!=):
+            (JSC::DebuggerScope::isValid):
+            (JSC::DebuggerScope::jsScope):
+            (JSC::DebuggerScope::begin):
+            (JSC::DebuggerScope::end):
+            * inspector/JSJavaScriptCallFrame.cpp:
+            (Inspector::JSJavaScriptCallFrame::scopeType):
+            (Inspector::JSJavaScriptCallFrame::scopeChain):
+            * inspector/JavaScriptCallFrame.h:
+            (Inspector::JavaScriptCallFrame::scopeChain):
+            * inspector/ScriptDebugServer.cpp:
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::reset):
+            (JSC::JSGlobalObject::visitChildren):
+            * runtime/JSGlobalObject.h:
+            (JSC::JSGlobalObject::debuggerScopeStructure):
+            * runtime/JSObject.h:
+            (JSC::JSObject::isWithScope):
+            * runtime/JSScope.h:
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-07-01  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] DFG bytecode parser should turn PutById with nothing but a Setter stub as stuff+handleCall, and handleCall should be allowed to inline if it wants to
+            https://bugs.webkit.org/show_bug.cgi?id=130756
+    
+            Reviewed by Oliver Hunt.
+            
+            The enables exposing the call to setters in the DFG, and then inlining it. Previously we
+            already supproted inlined-cached calls to setters from within put_by_id inline caches,
+            and the DFG could certainly emit such IC's. Now, if an IC had a setter call, then the DFG
+            will either emit the GetGetterSetterByOffset/GetSetter/Call combo, or it will do one
+            better and inline the call.
+            
+            A lot of the core functionality was already available from the previous work to inline
+            getters. So, there are some refactorings in this patch that move preexisting
+            functionality around. For example, the work to figure out how the DFG should go about
+            getting to what we call the &quot;loaded value&quot; - i.e. the GetterSetter object reference in
+            the case of accessors - is now shared in ComplexGetStatus, and both GetByIdStatus and
+            PutByIdStatus use it. This means that we can keep the safety checks common.  This patch
+            also does additional refactorings in DFG::ByteCodeParser so that we can continue to reuse
+            handleCall() for all of the various kinds of calls we can now emit.
+            
+            83% speed-up on getter-richards, 2% speed-up on box2d.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/ComplexGetStatus.cpp: Added.
+            (JSC::ComplexGetStatus::computeFor):
+            * bytecode/ComplexGetStatus.h: Added.
+            (JSC::ComplexGetStatus::ComplexGetStatus):
+            (JSC::ComplexGetStatus::skip):
+            (JSC::ComplexGetStatus::takesSlowPath):
+            (JSC::ComplexGetStatus::kind):
+            (JSC::ComplexGetStatus::attributes):
+            (JSC::ComplexGetStatus::specificValue):
+            (JSC::ComplexGetStatus::offset):
+            (JSC::ComplexGetStatus::chain):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            * bytecode/PolymorphicPutByIdList.h:
+            (JSC::PutByIdAccess::PutByIdAccess):
+            (JSC::PutByIdAccess::setter):
+            (JSC::PutByIdAccess::structure):
+            (JSC::PutByIdAccess::chainCount):
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeFromLLInt):
+            (JSC::PutByIdStatus::computeFor):
+            (JSC::PutByIdStatus::computeForStubInfo):
+            (JSC::PutByIdStatus::makesCalls):
+            * bytecode/PutByIdStatus.h:
+            (JSC::PutByIdStatus::makesCalls): Deleted.
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::PutByIdVariant):
+            (JSC::PutByIdVariant::operator=):
+            (JSC::PutByIdVariant::replace):
+            (JSC::PutByIdVariant::transition):
+            (JSC::PutByIdVariant::setter):
+            (JSC::PutByIdVariant::writesStructures):
+            (JSC::PutByIdVariant::reallocatesStorage):
+            (JSC::PutByIdVariant::makesCalls):
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::PutByIdVariant):
+            (JSC::PutByIdVariant::structure):
+            (JSC::PutByIdVariant::oldStructure):
+            (JSC::PutByIdVariant::alternateBase):
+            (JSC::PutByIdVariant::specificValue):
+            (JSC::PutByIdVariant::callLinkStatus):
+            (JSC::PutByIdVariant::replace): Deleted.
+            (JSC::PutByIdVariant::transition): Deleted.
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+            (JSC::DFG::ByteCodeParser::addCall):
+            (JSC::DFG::ByteCodeParser::handleCall):
+            (JSC::DFG::ByteCodeParser::handleInlining):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * jit/Repatch.cpp:
+            (JSC::tryCachePutByID):
+            (JSC::tryBuildPutByIdList):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::takesSlowPathInDFGForImpureProperty):
+            * runtime/IntendedStructureChain.h:
+            * tests/stress/exit-from-setter.js: Added.
+            * tests/stress/poly-chain-setter.js: Added.
+            (Cons):
+            (foo):
+            (test):
+            * tests/stress/poly-chain-then-setter.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            * tests/stress/poly-setter-combo.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            (.test):
+            * tests/stress/poly-setter-then-self.js: Added.
+            (foo):
+            (test):
+            (.test):
+            * tests/stress/weird-setter-counter.js: Added.
+            (foo):
+            (test):
+            * tests/stress/weird-setter-counter-syntactic.js: Added.
+            (foo):
+            (test):
+    
+    2014-07-01  Matthew Mirman  &lt;mmirman@apple.com&gt;
+    
+            Added an implementation of the &quot;in&quot; check to FTL.
+            https://bugs.webkit.org/show_bug.cgi?id=134508
+    
+            Reviewed by Filip Pizlo.
+    
+            * ftl/FTLCapabilities.cpp: enabled compilation for &quot;in&quot;
+            (JSC::FTL::canCompile): ditto
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::generateCheckInICFastPath): added.
+            (JSC::FTL::fixFunctionBasedOnStackMaps): added case for CheckIn descriptors.
+            * ftl/FTLInlineCacheDescriptor.h:
+            (JSC::FTL::CheckInGenerator::CheckInGenerator): added.
+            (JSC::FTL::CheckInDescriptor::CheckInDescriptor): added.
+            * ftl/FTLInlineCacheSize.cpp: 
+            (JSC::FTL::sizeOfCheckIn): added. Currently larger than necessary.
+            * ftl/FTLInlineCacheSize.h: ditto
+            * ftl/FTLIntrinsicRepository.h: Added function type for operationInGeneric
+            * ftl/FTLLowerDFGToLLVM.cpp: 
+            (JSC::FTL::LowerDFGToLLVM::compileNode): added case for In.
+            (JSC::FTL::LowerDFGToLLVM::compileIn): added.
+            * ftl/FTLSlowPathCall.cpp: Added a callOperation for operationIn
+            (JSC::FTL::callOperation): ditto
+            * ftl/FTLSlowPathCall.h: ditto
+            * ftl/FTLState.h: Added a vector to hold CheckIn descriptors.
+            * jit/JITOperations.h: made operationIns internal.
+            * tests/stress/ftl-checkin.js: Added.
+            * tests/stress/ftl-checkin-variable.js: Added.
+    
+    2014-06-30  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+    
+            CodeBlock::stronglyVisitWeakReferences should mark DFG::CommonData::weakStructureReferences
+            https://bugs.webkit.org/show_bug.cgi?id=134455
+    
+            Reviewed by Geoffrey Garen.
+    
+            Otherwise we get hanging pointers which can cause us to die later.
+    
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::stronglyVisitWeakReferences):
+    
+    2014-06-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] Reduce the GC's influence on optimization decisions
+            https://bugs.webkit.org/show_bug.cgi?id=134427
+    
+            Reviewed by Oliver Hunt.
+            
+            This is a slight speed-up on some platforms, that arises from a bunch of fixes that I made
+            while trying to make the GC keep more structures alive
+            (https://bugs.webkit.org/show_bug.cgi?id=128072).
+            
+            The fixes are, roughly:
+            
+            - If the GC clears an inline cache, then this no longer causes the IC to be forever
+              polymorphic.
+            
+            - If we exit in inlined code into a function that tries to OSR enter, then we jettison
+              sooner.
+            
+            - Some variables being uninitialized led to rage-recompilations.
+            
+            This is a pretty strong step in the direction of keeping more Structures alive and not
+            blowing away code just because a Structure died. But, it seems like there is still a slight
+            speed-up to be had from blowing away code that references dead Structures.
+    
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpAssumingJITType):
+            (JSC::shouldMarkTransition):
+            (JSC::CodeBlock::propagateTransitions):
+            (JSC::CodeBlock::determineLiveness):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeForStubInfo):
+            * dfg/DFGCapabilities.cpp:
+            (JSC::DFG::isSupportedForInlining):
+            (JSC::DFG::mightInlineFunctionForCall):
+            (JSC::DFG::mightInlineFunctionForClosureCall):
+            (JSC::DFG::mightInlineFunctionForConstruct):
+            * dfg/DFGCapabilities.h:
+            * dfg/DFGCommonData.h:
+            * dfg/DFGDesiredWeakReferences.cpp:
+            (JSC::DFG::DesiredWeakReferences::reallyAdd):
+            * dfg/DFGOSREntry.cpp:
+            (JSC::DFG::prepareOSREntry):
+            * dfg/DFGOSRExitCompilerCommon.cpp:
+            (JSC::DFG::handleExitCounts):
+            * dfg/DFGOperations.cpp:
+            * dfg/DFGOperations.h:
+            * ftl/FTLForOSREntryJITCode.cpp:
+            (JSC::FTL::ForOSREntryJITCode::ForOSREntryJITCode): These variables being uninitialized is benign in terms of correctness but can sometimes cause rage-recompilations. For some reason it took this patch to reveal this.
+            * ftl/FTLOSREntry.cpp:
+            (JSC::FTL::prepareOSREntry):
+            * runtime/Executable.cpp:
+            (JSC::ExecutableBase::destroy):
+            (JSC::NativeExecutable::destroy):
+            (JSC::ScriptExecutable::ScriptExecutable):
+            (JSC::ScriptExecutable::destroy):
+            (JSC::ScriptExecutable::installCode):
+            (JSC::EvalExecutable::EvalExecutable):
+            (JSC::ProgramExecutable::ProgramExecutable):
+            * runtime/Executable.h:
+            (JSC::ScriptExecutable::setDidTryToEnterInLoop):
+            (JSC::ScriptExecutable::didTryToEnterInLoop):
+            (JSC::ScriptExecutable::addressOfDidTryToEnterInLoop):
+            (JSC::ScriptExecutable::ScriptExecutable): Deleted.
+            * runtime/StructureInlines.h:
+            (JSC::Structure::storedPrototypeObject):
+            (JSC::Structure::storedPrototypeStructure):
+    
+    2014-06-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
+            https://bugs.webkit.org/show_bug.cgi?id=134333
+    
+            Reviewed by Geoffrey Garen.
+            
+            This is engineered to provide loads of information to the profiler without incurring any
+            costs when the profiler is disabled. It's the oldest trick in the book: the thing that
+            fires the watchpoint doesn't actually create anything to describe the reason why it was
+            fired; instead it creates a stack-allocated FireDetail subclass instance. Only if the
+            FireDetail::dump() virtual method is called does anything happen.
+            
+            Currently we use this to produce very fine-grained data for Structure watchpoints and
+            some cases of variable watchpoints. For all other situations, the given reason is just a
+            string constant, by using StringFireDetail. If we find a situation where that string
+            constant is insufficient to diagnose an issue then we can change it to provide more
+            fine-grained information.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::jettison):
+            * bytecode/CodeBlock.h:
+            * bytecode/CodeBlockJettisoningWatchpoint.cpp:
+            (JSC::CodeBlockJettisoningWatchpoint::fireInternal):
+            * bytecode/CodeBlockJettisoningWatchpoint.h:
+            * bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp: Removed.
+            * bytecode/ProfiledCodeBlockJettisoningWatchpoint.h: Removed.
+            * bytecode/StructureStubClearingWatchpoint.cpp:
+            (JSC::StructureStubClearingWatchpoint::fireInternal):
+            * bytecode/StructureStubClearingWatchpoint.h:
+            * bytecode/VariableWatchpointSet.h:
+            (JSC::VariableWatchpointSet::invalidate):
+            (JSC::VariableWatchpointSet::finalizeUnconditionally):
+            * bytecode/VariableWatchpointSetInlines.h:
+            (JSC::VariableWatchpointSet::notifyWrite):
+            * bytecode/Watchpoint.cpp:
+            (JSC::StringFireDetail::dump):
+            (JSC::WatchpointSet::fireAll):
+            (JSC::WatchpointSet::fireAllSlow):
+            (JSC::WatchpointSet::fireAllWatchpoints):
+            (JSC::InlineWatchpointSet::fireAll):
+            * bytecode/Watchpoint.h:
+            (JSC::FireDetail::FireDetail):
+            (JSC::FireDetail::~FireDetail):
+            (JSC::StringFireDetail::StringFireDetail):
+            (JSC::Watchpoint::fire):
+            (JSC::WatchpointSet::fireAll):
+            (JSC::WatchpointSet::touch):
+            (JSC::WatchpointSet::invalidate):
+            (JSC::InlineWatchpointSet::fireAll):
+            (JSC::InlineWatchpointSet::touch):
+            * dfg/DFGCommonData.h:
+            * dfg/DFGOperations.cpp:
+            * interpreter/Interpreter.cpp:
+            (JSC::Interpreter::execute):
+            * jsc.cpp:
+            (WTF::Masquerader::create):
+            * profiler/ProfilerCompilation.cpp:
+            (JSC::Profiler::Compilation::setJettisonReason):
+            (JSC::Profiler::Compilation::toJS):
+            * profiler/ProfilerCompilation.h:
+            (JSC::Profiler::Compilation::setJettisonReason): Deleted.
+            * runtime/ArrayBuffer.cpp:
+            (JSC::ArrayBuffer::transfer):
+            * runtime/ArrayBufferNeuteringWatchpoint.cpp:
+            (JSC::ArrayBufferNeuteringWatchpoint::fireAll):
+            * runtime/ArrayBufferNeuteringWatchpoint.h:
+            * runtime/CommonIdentifiers.h:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::SLOW_PATH_DECL):
+            * runtime/Identifier.cpp:
+            (JSC::Identifier::dump):
+            * runtime/Identifier.h:
+            * runtime/JSFunction.cpp:
+            (JSC::JSFunction::put):
+            (JSC::JSFunction::defineOwnProperty):
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::addFunction):
+            (JSC::JSGlobalObject::haveABadTime):
+            * runtime/JSSymbolTableObject.cpp:
+            (JSC::VariableWriteFireDetail::dump):
+            * runtime/JSSymbolTableObject.h:
+            (JSC::VariableWriteFireDetail::VariableWriteFireDetail):
+            (JSC::symbolTablePut):
+            (JSC::symbolTablePutWithAttributes):
+            * runtime/PropertyName.h:
+            (JSC::PropertyName::dump):
+            * runtime/Structure.cpp:
+            (JSC::Structure::notifyTransitionFromThisStructure):
+            * runtime/Structure.h:
+            (JSC::Structure::notifyTransitionFromThisStructure): Deleted.
+            * runtime/SymbolTable.cpp:
+            (JSC::SymbolTableEntry::notifyWriteSlow):
+            (JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally):
+            * runtime/SymbolTable.h:
+            (JSC::SymbolTableEntry::notifyWrite):
+            * runtime/VM.cpp:
+            (JSC::VM::addImpureProperty):
+    
</ins><span class="cx"> 2014-08-05  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r172099.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -321,6 +321,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CodeBlockJettisoningWatchpoint.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CodeOrigin.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CodeType.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\bytecode\ComplexGetStatus.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\ConstantStructureCheck.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\DeferredCompilationCallback.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\DFGExitProfile.cpp&quot; /&gt;
</span><span class="lines">@@ -402,6 +403,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGFunctionWhitelist.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGGraph.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGGraphSafepoint.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGHeapLocation.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGInPlaceAbstractState.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGIntegerCheckCombiningPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGInvalidationPointInjectionPhase.cpp&quot; /&gt;
</span><span class="lines">@@ -431,10 +433,12 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGOSRExitCompilerCommon.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGOSRExitJumpPlaceholder.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGOSRExitPreparation.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGPhantomRemovalPhase.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPlan.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPredictionInjectionPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGPredictionPropagationPhase.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGPureValue.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGResurrectionForValidationPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGSafepoint.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGSpeculativeJIT.cpp&quot; /&gt;
</span><span class="lines">@@ -908,6 +912,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\CodeOrigin.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\CodeType.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\Comment.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\bytecode\ComplexGetStatus.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\ConstantStructureCheck.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\DataFormat.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\DeferredCompilationCallback.h&quot; /&gt;
</span><span class="lines">@@ -1023,6 +1028,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGGPRInfo.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGGraph.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGGraphSafepoint.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGHeapLocation.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGInPlaceAbstractState.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGInsertionSet.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGIntegerCheckCombiningPhase.h&quot; /&gt;
</span><span class="lines">@@ -1058,10 +1064,12 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGOSRExitCompilerCommon.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGOSRExitJumpPlaceholder.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGOSRExitPreparation.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGPhantomRemovalPhase.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPlan.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPredictionInjectionPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGPredictionPropagationPhase.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGPureValue.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGRegisterBank.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGRegisterSet.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGResurrectionForValidationPhase.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -351,6 +351,8 @@
</span><span class="cx">                 0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */; };
</span><span class="cx">                 0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */; };
</span><ins>+                0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */; };
+                0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F7025A91714B0FA00382C0E /* DFGOSRExitCompilerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */; };
</span><span class="cx">                 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
</span><span class="lines">@@ -442,6 +444,10 @@
</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>+                0FB17660196B8F9E0091052A /* DFGHeapLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB1765C196B8F9E0091052A /* DFGHeapLocation.cpp */; };
+                0FB17661196B8F9E0091052A /* DFGHeapLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB1765D196B8F9E0091052A /* DFGHeapLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */; };
+                0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB1765F196B8F9E0091052A /* DFGPureValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */; };
</span><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="lines">@@ -466,6 +472,8 @@
</span><span class="cx">                 0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */; };
</span><span class="cx">                 0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FBFDD04196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */; };
+                0FBFDD05196C92BF007A5BFA /* DFGPhantomRemovalPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */; };
</span><span class="lines">@@ -489,14 +497,13 @@
</span><span class="cx">                 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
</span><span class="cx">                 0FC97F33182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F2F182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp */; };
</span><span class="cx">                 0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F30182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0FC97F35182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */; };
-                0FC97F36182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0FC97F3D18202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */; };
</span><span class="cx">                 0FC97F3E18202119002C9B26 /* DFGInvalidationPointInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3918202119002C9B26 /* DFGJumpReplacement.cpp */; };
</span><span class="cx">                 0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3A18202119002C9B26 /* DFGJumpReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FC97F4118202119002C9B26 /* DFGWatchpointCollectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */; };
</span><span class="cx">                 0FC97F4218202119002C9B26 /* DFGWatchpointCollectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */; };
</ins><span class="cx">                 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */; };
</span><span class="cx">                 0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2534,6 +2541,8 @@
</span><span class="cx">                 0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArityCheckFailReturnThunks.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckFailReturnThunks.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessData.cpp; path = dfg/DFGVariableAccessData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexGetStatus.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComplexGetStatus.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompilerCommon.cpp; path = dfg/DFGOSRExitCompilerCommon.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilerCommon.h; path = dfg/DFGOSRExitCompilerCommon.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2623,6 +2632,10 @@
</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>+                0FB1765C196B8F9E0091052A /* DFGHeapLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGHeapLocation.cpp; path = dfg/DFGHeapLocation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FB1765D196B8F9E0091052A /* DFGHeapLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGHeapLocation.h; path = dfg/DFGHeapLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPureValue.cpp; path = dfg/DFGPureValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FB1765F196B8F9E0091052A /* DFGPureValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPureValue.h; path = dfg/DFGPureValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><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="lines">@@ -2657,6 +2670,8 @@
</span><span class="cx">                 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPredictionInjectionPhase.h; path = dfg/DFGPredictionInjectionPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUnificationPhase.cpp; path = dfg/DFGUnificationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhantomRemovalPhase.cpp; path = dfg/DFGPhantomRemovalPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhantomRemovalPhase.h; path = dfg/DFGPhantomRemovalPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExit.h; path = dfg/DFGOSRExit.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompiler.h; path = dfg/DFGOSRExitCompiler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler64.cpp; path = dfg/DFGOSRExitCompiler64.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2681,14 +2696,13 @@
</span><span class="cx">                 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F2F182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlockJettisoningWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F30182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockJettisoningWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProfiledCodeBlockJettisoningWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfiledCodeBlockJettisoningWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInvalidationPointInjectionPhase.cpp; path = dfg/DFGInvalidationPointInjectionPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInvalidationPointInjectionPhase.h; path = dfg/DFGInvalidationPointInjectionPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3918202119002C9B26 /* DFGJumpReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJumpReplacement.cpp; path = dfg/DFGJumpReplacement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3A18202119002C9B26 /* DFGJumpReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJumpReplacement.h; path = dfg/DFGJumpReplacement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGWatchpointCollectionPhase.cpp; path = dfg/DFGWatchpointCollectionPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGWatchpointCollectionPhase.h; path = dfg/DFGWatchpointCollectionPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWatchpointSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitorInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserError.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLSaveRestore.cpp; path = ftl/FTLSaveRestore.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5129,6 +5143,8 @@
</span><span class="cx">                                 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */,
</span><span class="cx">                                 0F2FCCF218A60070001A27F8 /* DFGGraphSafepoint.cpp */,
</span><span class="cx">                                 0F2FCCF318A60070001A27F8 /* DFGGraphSafepoint.h */,
</span><ins>+                                0FB1765C196B8F9E0091052A /* DFGHeapLocation.cpp */,
+                                0FB1765D196B8F9E0091052A /* DFGHeapLocation.h */,
</ins><span class="cx">                                 0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */,
</span><span class="cx">                                 0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */,
</span><span class="cx">                                 A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */,
</span><span class="lines">@@ -5195,6 +5211,8 @@
</span><span class="cx">                                 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */,
</span><span class="cx">                                 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */,
</span><span class="cx">                                 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */,
</span><ins>+                                0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */,
+                                0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */,
</ins><span class="cx">                                 0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
</span><span class="cx">                                 0FFFC95014EF909500C72532 /* DFGPhase.h */,
</span><span class="cx">                                 A78A9772179738B8009DF744 /* DFGPlan.cpp */,
</span><span class="lines">@@ -5203,6 +5221,8 @@
</span><span class="cx">                                 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
</span><span class="cx">                                 0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
</span><span class="cx">                                 0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
</span><ins>+                                0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */,
+                                0FB1765F196B8F9E0091052A /* DFGPureValue.h */,
</ins><span class="cx">                                 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
</span><span class="cx">                                 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */,
</span><span class="cx">                                 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */,
</span><span class="lines">@@ -5403,6 +5423,8 @@
</span><span class="cx">                                 0FBD7E671447998F00481315 /* CodeOrigin.h */,
</span><span class="cx">                                 0F8F943F1667632D00D61971 /* CodeType.cpp */,
</span><span class="cx">                                 0F0B83A514BCF50400885B4F /* CodeType.h */,
</span><ins>+                                0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */,
+                                0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */,
</ins><span class="cx">                                 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */,
</span><span class="cx">                                 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */,
</span><span class="cx">                                 0F426A4A1460CD6B00131F8F /* DataFormat.h */,
</span><span class="lines">@@ -5446,8 +5468,6 @@
</span><span class="cx">                                 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
</span><span class="cx">                                 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */,
</span><span class="cx">                                 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */,
</span><del>-                                0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */,
-                                0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */,
</del><span class="cx">                                 0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
</span><span class="cx">                                 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
</span><span class="cx">                                 0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */,
</span><span class="lines">@@ -5477,11 +5497,13 @@
</span><span class="cx">                                 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */,
</span><span class="cx">                                 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */,
</span><span class="cx">                                 0F426A451460CBAB00131F8F /* ValueRecovery.h */,
</span><ins>+                                0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */,
</ins><span class="cx">                                 0F9181C618415CA50057B669 /* VariableWatchpointSet.h */,
</span><span class="cx">                                 FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */,
</span><span class="cx">                                 0F426A461460CBAB00131F8F /* VirtualRegister.h */,
</span><span class="cx">                                 0F919D2215853CDE004A4E7D /* Watchpoint.cpp */,
</span><span class="cx">                                 0F919D2315853CDE004A4E7D /* Watchpoint.h */,
</span><ins>+                                52DAD38E195A164E00F30464 /* TypeLocation.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = bytecode;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -6126,6 +6148,7 @@
</span><span class="cx">                                 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
</span><span class="cx">                                 A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
</span><span class="cx">                                 A704D90717A0BAA8006BA554 /* DFGMergeMode.h in Headers */,
</span><ins>+                                0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
</ins><span class="cx">                                 0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
</span><span class="cx">                                 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
</span><span class="cx">                                 0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
</span><span class="lines">@@ -6331,6 +6354,7 @@
</span><span class="cx">                                 8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
</span><span class="cx">                                 A532438C18568335002ED692 /* InspectorJSTypeBuilders.h in Headers */,
</span><span class="cx">                                 A50E4B6218809DD50068A46D /* InspectorRuntimeAgent.h in Headers */,
</span><ins>+                                0FBFDD05196C92BF007A5BFA /* DFGPhantomRemovalPhase.h in Headers */,
</ins><span class="cx">                                 A55D93AC18514F7900400DED /* InspectorTypeBuilder.h in Headers */,
</span><span class="cx">                                 A593CF831840377100BFCE27 /* InspectorValues.h in Headers */,
</span><span class="cx">                                 969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
</span><span class="lines">@@ -6587,7 +6611,6 @@
</span><span class="cx">                                 0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
</span><span class="cx">                                 868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
</span><span class="cx">                                 BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
</span><del>-                                0FC97F36182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h in Headers */,
</del><span class="cx">                                 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
</span><span class="cx">                                 BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
</span><span class="cx">                                 0FF729A5166AD351000F5BA3 /* ProfilerBytecode.h in Headers */,
</span><span class="lines">@@ -6612,6 +6635,7 @@
</span><span class="cx">                                 A785F6BC18C553FE00F10626 /* SpillRegistersMode.h in Headers */,
</span><span class="cx">                                 BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
</span><span class="cx">                                 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
</span><ins>+                                 0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */,
</ins><span class="cx">                                 0F12DE101979D5FD0006FF4E /* ExceptionFuzz.h in Headers */,
</span><span class="cx">                                 BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
</span><span class="cx">                                 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
</span><span class="lines">@@ -6669,6 +6693,7 @@
</span><span class="cx">                                 86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */,
</span><span class="cx">                                 0F2B670517B6B5AB00A7AE3F /* SimpleTypedArrayController.h in Headers */,
</span><span class="cx">                                 14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
</span><ins>+                                0FB17661196B8F9E0091052A /* DFGHeapLocation.h in Headers */,
</ins><span class="cx">                                 C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
</span><span class="cx">                                 A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */,
</span><span class="cx">                                 933040040E6A749400786E6A /* SmallStrings.h in Headers */,
</span><span class="lines">@@ -7692,6 +7717,7 @@
</span><span class="cx">                                 C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */,
</span><span class="cx">                                 C2981FDC17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.cpp in Sources */,
</span><span class="cx">                                 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
</span><ins>+                                0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */,
</ins><span class="cx">                                 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
</span><span class="cx">                                 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
</span><span class="cx">                                 0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
</span><span class="lines">@@ -7756,11 +7782,13 @@
</span><span class="cx">                                 0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */,
</span><span class="cx">                                 0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
</span><span class="cx">                                 0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
</span><ins>+                                0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
</ins><span class="cx">                                 0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */,
</span><span class="cx">                                 0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */,
</span><span class="cx">                                 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */,
</span><span class="cx">                                 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */,
</span><span class="cx">                                 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */,
</span><ins>+                                0FB17660196B8F9E0091052A /* DFGHeapLocation.cpp in Sources */,
</ins><span class="cx">                                 0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */,
</span><span class="cx">                                 0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
</span><span class="cx">                                 0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */,
</span><span class="lines">@@ -8031,7 +8059,6 @@
</span><span class="cx">                                 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
</span><span class="cx">                                 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
</span><span class="cx">                                 95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
</span><del>-                                0FC97F35182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp in Sources */,
</del><span class="cx">                                 95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
</span><span class="cx">                                 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
</span><span class="cx">                                 0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */,
</span><span class="lines">@@ -8091,6 +8118,7 @@
</span><span class="cx">                                 C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */,
</span><span class="cx">                                 9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
</span><span class="cx">                                 0F8F2B9E17306C8D007DBDA5 /* SourceCode.cpp in Sources */,
</span><ins>+                                0FBFDD04196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp in Sources */,
</ins><span class="cx">                                 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
</span><span class="cx">                                 E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */,
</span><span class="cx">                                 0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */,
</span><span class="lines">@@ -8134,6 +8162,7 @@
</span><span class="cx">                                 FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */,
</span><span class="cx">                                 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
</span><span class="cx">                                 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
</span><ins>+                                0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */,
</ins><span class="cx">                                 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
</span><span class="cx">                                 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
</span><span class="cx">                                 A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -112,6 +112,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_next_pname&quot;, &quot;length&quot; : 7 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_resolve_scope&quot;, &quot;length&quot; : 6 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_from_scope&quot;, &quot;length&quot; : 8 },
</span><ins>+            { &quot;name&quot; : &quot;op_get_from_scope_with_profile&quot;, &quot;length&quot; : 9 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_put_to_scope&quot;, &quot;length&quot; : 7 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_put_to_scope_with_profile&quot;, &quot;length&quot; : 8 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_push_with_scope&quot;, &quot;length&quot; : 2 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -121,6 +121,7 @@
</span><span class="cx">     case op_init_global_const_nop:
</span><span class="cx">     case op_init_global_const:
</span><span class="cx">     case op_push_name_scope:
</span><ins>+    case op_get_from_scope_with_profile:
</ins><span class="cx">     case op_get_from_scope:
</span><span class="cx">     case op_to_primitive:
</span><span class="cx">     case op_get_by_id:
</span><span class="lines">@@ -313,6 +314,7 @@
</span><span class="cx">     case op_new_func_exp:
</span><span class="cx">     case op_call_varargs:
</span><span class="cx">     case op_construct_varargs:
</span><ins>+    case op_get_from_scope_with_profile:
</ins><span class="cx">     case op_get_from_scope:
</span><span class="cx">     case op_call:
</span><span class="cx">     case op_call_eval:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;DFGJITCode.h&quot;
</span><span class="cx"> #include &quot;DFGWorklist.h&quot;
</span><span class="cx"> #include &quot;Debugger.h&quot;
</span><ins>+#include &quot;FunctionExecutableDump.h&quot;
</ins><span class="cx"> #include &quot;HighFidelityTypeProfiler.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="lines">@@ -150,9 +151,11 @@
</span><span class="cx">         out.print(specializationKind());
</span><span class="cx">     out.print(&quot;, &quot;, instructionCount());
</span><span class="cx">     if (this-&gt;jitType() == JITCode::BaselineJIT &amp;&amp; m_shouldAlwaysBeInlined)
</span><del>-        out.print(&quot; (SABI)&quot;);
</del><ins>+        out.print(&quot; (ShouldAlwaysBeInlined)&quot;);
</ins><span class="cx">     if (ownerExecutable()-&gt;neverInline())
</span><span class="cx">         out.print(&quot; (NeverInline)&quot;);
</span><ins>+    if (ownerExecutable()-&gt;didTryToEnterInLoop())
+        out.print(&quot; (DidTryToEnterInLoop)&quot;);
</ins><span class="cx">     if (ownerExecutable()-&gt;isStrictMode())
</span><span class="cx">         out.print(&quot; (StrictMode)&quot;);
</span><span class="cx">     if (this-&gt;jitType() == JITCode::BaselineJIT &amp;&amp; m_didFailFTLCompilation)
</span><span class="lines">@@ -1541,6 +1544,28 @@
</span><span class="cx">     return vector.capacity() * sizeof(T);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+namespace {
+
+class PutToScopeFireDetail : public FireDetail {
+public:
+    PutToScopeFireDetail(CodeBlock* codeBlock, const Identifier&amp; ident)
+        : m_codeBlock(codeBlock)
+        , m_ident(ident)
+    {
+    }
+    
+    virtual void dump(PrintStream&amp; out) const override
+    {
+        out.print(&quot;Linking put_to_scope in &quot;, FunctionExecutableDump(jsCast&lt;FunctionExecutable*&gt;(m_codeBlock-&gt;ownerExecutable())), &quot; for &quot;, m_ident);
+    }
+    
+private:
+    CodeBlock* m_codeBlock;
+    const Identifier&amp; m_ident;
+};
+
+} // anonymous namespace
+
</ins><span class="cx"> CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock&amp; other)
</span><span class="cx">     : m_globalObject(other.m_globalObject)
</span><span class="cx">     , m_heap(other.m_heap)
</span><span class="lines">@@ -1630,6 +1655,7 @@
</span><span class="cx">     , m_osrExitCounter(0)
</span><span class="cx">     , m_optimizationDelayCounter(0)
</span><span class="cx">     , m_reoptimizationRetryCounter(0)
</span><ins>+    , m_returnStatementTypeSet(nullptr)
</ins><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
</span><span class="cx"> #endif
</span><span class="lines">@@ -1857,11 +1883,13 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case op_get_from_scope_with_profile:
</ins><span class="cx">         case op_get_from_scope: {
</span><del>-            ValueProfile* profile = &amp;m_valueProfiles[pc[opLength - 1].u.operand];
</del><ins>+            int offset = (pc[0].u.opcode == op_get_from_scope_with_profile ? 2 : 1);
+            ValueProfile* profile = &amp;m_valueProfiles[pc[opLength - offset].u.operand];
</ins><span class="cx">             ASSERT(profile-&gt;m_bytecodeOffset == -1);
</span><span class="cx">             profile-&gt;m_bytecodeOffset = i;
</span><del>-            instructions[i + opLength - 1] = profile;
</del><ins>+            instructions[i + opLength - offset] = profile;
</ins><span class="cx"> 
</span><span class="cx">             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</span><span class="cx">             const Identifier&amp; ident = identifier(pc[3].u.operand);
</span><span class="lines">@@ -1874,6 +1902,14 @@
</span><span class="cx">             else if (op.structure)
</span><span class="cx">                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
</span><span class="cx">             instructions[i + 6].u.pointer = reinterpret_cast&lt;void*&gt;(op.operand);
</span><ins>+
+            if (pc[0].u.opcode == op_get_from_scope_with_profile) {
+                // The format of this instruction is: get_from_scope_with_profile dst, scope, id, ResolveModeAndType, Structure, Operand, ..., TypeLocation
+                size_t instructionOffset = i + opLength - 1;
+                TypeLocation* location = vm()-&gt;nextLocation();
+                scopeDependentProfile(op, ident, instructionOffset, location);
+                instructions[i + 8].u.location = location;
+            }
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1889,72 +1925,66 @@
</span><span class="cx">                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
</span><span class="cx">             else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) {
</span><span class="cx">                 if (op.watchpointSet)
</span><del>-                    op.watchpointSet-&gt;invalidate();
</del><ins>+                    op.watchpointSet-&gt;invalidate(PutToScopeFireDetail(this, ident));
</ins><span class="cx">             } else if (op.structure)
</span><span class="cx">                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
</span><span class="cx">             instructions[i + 6].u.pointer = reinterpret_cast&lt;void*&gt;(op.operand);
</span><span class="cx"> 
</span><span class="cx">             if (pc[0].u.opcode == op_put_to_scope_with_profile) {
</span><span class="cx">                 // The format of this instruction is: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
</span><ins>+                size_t instructionOffset = i + opLength - 1;
</ins><span class="cx">                 TypeLocation* location = vm()-&gt;nextLocation();
</span><del>-                size_t instructionOffset = i + opLength - 1;
-                int divot, startOffset, endOffset; 
-                unsigned line = 0, column = 0;
-                expressionRangeForBytecodeOffset(instructionOffset, divot, startOffset, endOffset, line, column);
-
-                location-&gt;m_line = line;
-                location-&gt;m_column = column;
-                location-&gt;m_sourceID = m_ownerExecutable-&gt;sourceID();
-
-                // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
-                SymbolTable* symbolTable = 0;
-                if (op.type == ClosureVar) 
-                    symbolTable = op.activation-&gt;symbolTable();
-                else if (op.type == GlobalVar)
-                    symbolTable = m_globalObject.get()-&gt;symbolTable();
-                
-                if (symbolTable) {
-                    ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
-                    location-&gt;m_globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
-                    location-&gt;m_globalTypeSet =symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
-                } else
-                    location-&gt;m_globalVariableID = HighFidelityNoGlobalIDExists;
-
-                vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
</del><ins>+                scopeDependentProfile(op, ident, instructionOffset, location);
</ins><span class="cx">                 instructions[i + 7].u.location = location;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case op_profile_types_with_high_fidelity: {
</span><del>-
</del><ins>+            size_t instructionOffset = i + opLength - 1;
+            unsigned divotStart, divotEnd;
+            bool shouldAnalyze = m_unlinkedCode-&gt;highFidelityTypeProfileExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
</ins><span class="cx">             VirtualRegister virtualRegister(pc[1].u.operand);
</span><span class="cx">             SymbolTable* symbolTable = m_symbolTable.get();
</span><span class="cx">             TypeLocation* location = vm()-&gt;nextLocation();
</span><del>-            size_t instructionOffset = i + opLength - 1;
-            int divot, startOffset, endOffset; 
-            unsigned line = 0, column = 0;
-            expressionRangeForBytecodeOffset(instructionOffset, divot, startOffset, endOffset, line, column);
</del><ins>+            location-&gt;m_divotStart = divotStart;
+            location-&gt;m_divotEnd = divotEnd;
+            location-&gt;m_sourceID = m_ownerExecutable-&gt;sourceID();
</ins><span class="cx"> 
</span><del>-            int hasGlobalIDFlag = pc[3].u.operand;
-            if (hasGlobalIDFlag) {
</del><ins>+            ProfileTypesWithHighFidelityBytecodeFlag flag = static_cast&lt;ProfileTypesWithHighFidelityBytecodeFlag&gt;(pc[3].u.operand);
+            switch (flag) {
+            case ProfileTypesBytecodeHasGlobalID: {
</ins><span class="cx">                 ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</span><span class="cx">                 location-&gt;m_globalVariableID = symbolTable-&gt;uniqueIDForRegister(locker, virtualRegister.offset(), *vm());
</span><span class="cx">                 location-&gt;m_globalTypeSet = symbolTable-&gt;globalTypeSetForRegister(locker, virtualRegister.offset(), *vm());
</span><del>-            } else
</del><ins>+                break;
+            }
+            case ProfileTypesBytecodeDoesNotHaveGlobalID: 
+            case ProfileTypesBytecodeFunctionArgument:
+            case ProfileTypesBytecodeFunctionThisObject: {
</ins><span class="cx">                 location-&gt;m_globalVariableID = HighFidelityNoGlobalIDExists;
</span><del>-            
</del><ins>+                break;
+            }
+            case ProfileTypesBytecodeFunctionReturnStatement: {
+                location-&gt;m_globalTypeSet = returnStatementTypeSet();
+                location-&gt;m_globalVariableID = HighFidelityReturnStatement;
+                location-&gt;m_divotForFunctionOffsetIfReturnStatement = m_sourceOffset; 
+                if (!shouldAnalyze) {
+                    // Because some return statements are added implicitly (to return undefined at the end of a function), and these nodes don't emit expression ranges, give them some range.
+                    // Currently, this divot is on the open brace of the function. 
+                    location-&gt;m_divotStart = location-&gt;m_divotEnd = location-&gt;m_divotForFunctionOffsetIfReturnStatement;
+                    shouldAnalyze = true;
+                }
+                break;
+            }
+            }
</ins><span class="cx"> 
</span><del>-            location-&gt;m_line = line;
-            location-&gt;m_column = column;
-            location-&gt;m_sourceID = m_ownerExecutable-&gt;sourceID();
-
-            vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
</del><ins>+            if (shouldAnalyze)
+                vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
</ins><span class="cx">             instructions[i + 2].u.location = location;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-
</del><span class="cx">         case op_captured_mov:
</span><span class="cx">         case op_new_captured_func: {
</span><span class="cx">             if (pc[3].u.index == UINT_MAX) {
</span><span class="lines">@@ -2185,6 +2215,17 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool shouldMarkTransition(DFG::WeakReferenceTransition&amp; transition)
+{
+    if (transition.m_codeOrigin &amp;&amp; !Heap::isMarked(transition.m_codeOrigin.get()))
+        return false;
+    
+    if (!Heap::isMarked(transition.m_from.get()))
+        return false;
+    
+    return true;
+}
+
</ins><span class="cx"> void CodeBlock::propagateTransitions(SlotVisitor&amp; visitor)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(visitor);
</span><span class="lines">@@ -2261,21 +2302,28 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     if (JITCode::isOptimizingJIT(jitType())) {
</span><span class="cx">         DFG::CommonData* dfgCommon = m_jitCode-&gt;dfgCommon();
</span><ins>+        
</ins><span class="cx">         for (unsigned i = 0; i &lt; dfgCommon-&gt;transitions.size(); ++i) {
</span><del>-            if ((!dfgCommon-&gt;transitions[i].m_codeOrigin
-                 || Heap::isMarked(dfgCommon-&gt;transitions[i].m_codeOrigin.get()))
-                &amp;&amp; Heap::isMarked(dfgCommon-&gt;transitions[i].m_from.get())) {
</del><ins>+            if (shouldMarkTransition(dfgCommon-&gt;transitions[i])) {
</ins><span class="cx">                 // If the following three things are live, then the target of the
</span><span class="cx">                 // transition is also live:
</span><ins>+                //
</ins><span class="cx">                 // - This code block. We know it's live already because otherwise
</span><span class="cx">                 //   we wouldn't be scanning ourselves.
</span><ins>+                //
</ins><span class="cx">                 // - The code origin of the transition. Transitions may arise from
</span><span class="cx">                 //   code that was inlined. They are not relevant if the user's
</span><span class="cx">                 //   object that is required for the inlinee to run is no longer
</span><span class="cx">                 //   live.
</span><ins>+                //
</ins><span class="cx">                 // - The source of the transition. The transition checks if some
</span><span class="cx">                 //   heap location holds the source, and if so, stores the target.
</span><span class="cx">                 //   Hence the source must be live for the transition to be live.
</span><ins>+                //
+                // We also short-circuit the liveness if the structure is harmless
+                // to mark (i.e. its global object and prototype are both already
+                // live).
+                
</ins><span class="cx">                 visitor.append(&amp;dfgCommon-&gt;transitions[i].m_to);
</span><span class="cx">             } else
</span><span class="cx">                 allAreMarkedSoFar = false;
</span><span class="lines">@@ -2310,6 +2358,14 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+    if (allAreLiveSoFar) {
+        for (unsigned i = 0; i &lt; dfgCommon-&gt;weakStructureReferences.size(); ++i) {
+            if (!Heap::isMarked(dfgCommon-&gt;weakStructureReferences[i].get())) {
+                allAreLiveSoFar = false;
+                break;
+            }
+        }
+    }
</ins><span class="cx">     
</span><span class="cx">     // If some weak references are dead, then this fixpoint iteration was
</span><span class="cx">     // unsuccessful.
</span><span class="lines">@@ -2394,6 +2450,7 @@
</span><span class="cx">                 activation.clear();
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            case op_get_from_scope_with_profile:
</ins><span class="cx">             case op_get_from_scope:
</span><span class="cx">             case op_put_to_scope_with_profile:
</span><span class="cx">             case op_put_to_scope: {
</span><span class="lines">@@ -2625,6 +2682,9 @@
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = 0; i &lt; dfgCommon-&gt;weakReferences.size(); ++i)
</span><span class="cx">         visitor.append(&amp;dfgCommon-&gt;weakReferences[i]);
</span><ins>+
+    for (unsigned i = 0; i &lt; dfgCommon-&gt;weakStructureReferences.size(); ++i)
+        visitor.append(&amp;dfgCommon-&gt;weakStructureReferences[i]);
</ins><span class="cx"> #endif    
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2945,7 +3005,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode)
</del><ins>+void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(reason != Profiler::NotJettisoned);
</span><span class="cx">     
</span><span class="lines">@@ -2954,14 +3014,17 @@
</span><span class="cx">         dataLog(&quot;Jettisoning &quot;, *this);
</span><span class="cx">         if (mode == CountReoptimization)
</span><span class="cx">             dataLog(&quot; and counting reoptimization&quot;);
</span><del>-        dataLog(&quot; due to &quot;, reason, &quot;.\n&quot;);
</del><ins>+        dataLog(&quot; due to &quot;, reason);
+        if (detail)
+            dataLog(&quot;, &quot;, *detail);
+        dataLog(&quot;.\n&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     DeferGCForAWhile deferGC(*m_heap);
</span><span class="cx">     RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType()));
</span><span class="cx">     
</span><span class="cx">     if (Profiler::Compilation* compilation = jitCode()-&gt;dfgCommon()-&gt;compilation.get())
</span><del>-        compilation-&gt;setJettisonReason(reason);
</del><ins>+        compilation-&gt;setJettisonReason(reason, detail);
</ins><span class="cx">     
</span><span class="cx">     // We want to accomplish two things here:
</span><span class="cx">     // 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it
</span><span class="lines">@@ -3797,4 +3860,30 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void CodeBlock::scopeDependentProfile(ResolveOp op, const Identifier&amp; ident, size_t instructionOffset, TypeLocation* location)
+{
+    unsigned divotStart, divotEnd;
+    bool shouldAnalyze = m_unlinkedCode-&gt;highFidelityTypeProfileExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
+    location-&gt;m_divotStart = divotStart;
+    location-&gt;m_divotEnd = divotEnd;
+    location-&gt;m_sourceID = m_ownerExecutable-&gt;sourceID();
+
+    // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
+    SymbolTable* symbolTable = nullptr;
+    if (op.type == ClosureVar) 
+        symbolTable = op.activation-&gt;symbolTable();
+    else if (op.type == GlobalVar)
+        symbolTable = m_globalObject.get()-&gt;symbolTable();
+    
+    if (symbolTable) {
+        ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
+        location-&gt;m_globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
+        location-&gt;m_globalTypeSet = symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
+    } else
+        location-&gt;m_globalVariableID = HighFidelityNoGlobalIDExists;
+
+    if (shouldAnalyze)
+        vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx"> #include &quot;ProfilerJettisonReason.h&quot;
</span><span class="cx"> #include &quot;RegExpObject.h&quot;
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><ins>+#include &quot;TypeSet.h&quot;
</ins><span class="cx"> #include &quot;UnconditionalFinalizer.h&quot;
</span><span class="cx"> #include &quot;ValueProfile.h&quot;
</span><span class="cx"> #include &quot;VirtualRegister.h&quot;
</span><span class="lines">@@ -310,7 +311,7 @@
</span><span class="cx">     bool hasOptimizedReplacement(); // the typeToReplace is my JITType
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization);
</del><ins>+    void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization, const FireDetail* = nullptr);
</ins><span class="cx">     
</span><span class="cx">     ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
</span><span class="cx"> 
</span><span class="lines">@@ -940,8 +941,15 @@
</span><span class="cx">     NO_RETURN_DUE_TO_CRASH void endValidationDidFail();
</span><span class="cx"> 
</span><span class="cx">     bool isKnownToBeLiveDuringGC(); // Will only return valid results when called during GC. Assumes that you've already established that the owner executable is live.
</span><ins>+    RefPtr&lt;TypeSet&gt; returnStatementTypeSet() 
+    {
+        if (!m_returnStatementTypeSet)
+            m_returnStatementTypeSet = TypeSet::create();
</ins><span class="cx"> 
</span><ins>+        return m_returnStatementTypeSet;
+    }
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> protected:
</span><span class="cx">     virtual void visitWeakReferences(SlotVisitor&amp;) override;
</span><span class="cx">     virtual void finalizeUnconditionally() override;
</span><span class="lines">@@ -1010,6 +1018,8 @@
</span><span class="cx">         if (!m_rareData)
</span><span class="cx">             m_rareData = adoptPtr(new RareData);
</span><span class="cx">     }
</span><ins>+
+    void scopeDependentProfile(ResolveOp, const Identifier&amp;, size_t, TypeLocation*);
</ins><span class="cx">     
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     void resetStubInternal(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span><span class="lines">@@ -1090,6 +1100,8 @@
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;BytecodeLivenessAnalysis&gt; m_livenessAnalysis;
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;TypeSet&gt; m_returnStatementTypeSet;
+
</ins><span class="cx">     struct RareData {
</span><span class="cx">         WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     public:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockJettisoningWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -32,12 +32,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-void CodeBlockJettisoningWatchpoint::fireInternal()
</del><ins>+void CodeBlockJettisoningWatchpoint::fireInternal(const FireDetail&amp; detail)
</ins><span class="cx"> {
</span><span class="cx">     if (DFG::shouldShowDisassembly())
</span><span class="cx">         dataLog(&quot;Firing watchpoint &quot;, RawPointer(this), &quot; on &quot;, *m_codeBlock, &quot;\n&quot;);
</span><span class="cx"> 
</span><del>-    m_codeBlock-&gt;jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization);
</del><ins>+    m_codeBlock-&gt;jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &amp;detail);
</ins><span class="cx"> 
</span><span class="cx">     if (isOnList())
</span><span class="cx">         remove();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockJettisoningWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> protected:
</span><del>-    virtual void fireInternal() override;
</del><ins>+    virtual void fireInternal(const FireDetail&amp;) override;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     CodeBlock* m_codeBlock;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeComplexGetStatuscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.cpp (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,80 @@
</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;ComplexGetStatus.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC {
+
+ComplexGetStatus ComplexGetStatus::computeFor(
+    CodeBlock* profiledBlock, Structure* headStructure, StructureChain* chain,
+    unsigned chainCount, StringImpl* uid)
+{
+    // FIXME: We should assert that we never see a structure that
+    // hasImpureGetOwnPropertySlot() but for which we don't
+    // newImpurePropertyFiresWatchpoints(). We're not at a point where we can do
+    // that, yet.
+    // https://bugs.webkit.org/show_bug.cgi?id=131810
+    
+    if (headStructure-&gt;takesSlowPathInDFGForImpureProperty())
+        return takesSlowPath();
+    
+    ComplexGetStatus result;
+    result.m_kind = Inlineable;
+    
+    if (chain) {
+        result.m_chain = adoptRef(new IntendedStructureChain(
+            profiledBlock, headStructure, chain, chainCount));
+        
+        if (!result.m_chain-&gt;isStillValid())
+            return skip();
+        
+        if (headStructure-&gt;takesSlowPathInDFGForImpureProperty()
+            || result.m_chain-&gt;takesSlowPathInDFGForImpureProperty())
+            return takesSlowPath();
+        
+        JSObject* currentObject = result.m_chain-&gt;terminalPrototype();
+        Structure* currentStructure = result.m_chain-&gt;last();
+        
+        ASSERT_UNUSED(currentObject, currentObject);
+        
+        result.m_offset = currentStructure-&gt;getConcurrently(
+            *profiledBlock-&gt;vm(), uid, result.m_attributes);
+    } else {
+        result.m_offset = headStructure-&gt;getConcurrently(
+            *profiledBlock-&gt;vm(), uid, result.m_attributes);
+    }
+    
+    if (!isValidOffset(result.m_offset))
+        return takesSlowPath();
+    
+    return result;
+}
+
+} // namespace JSC
+
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeComplexGetStatush"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.h (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/ComplexGetStatus.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,120 @@
</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 ComplexGetStatus_h
+#define ComplexGetStatus_h
+
+#include &quot;IntendedStructureChain.h&quot;
+#include &quot;JSCJSValue.h&quot;
+#include &quot;PropertyOffset.h&quot;
+
+namespace JSC {
+
+class CodeBlock;
+class StructureChain;
+
+// This class is useful for figuring out how to inline a cached get-like access. We
+// say &quot;get-like&quot; because this is appropriate for loading the GetterSetter object in
+// a put_by_id that hits a setter. Notably, this doesn't figure out how to call
+// accessors, or even whether they should be called. What it gives us, is a way of
+// determining how to load the value from the requested property (identified by a
+// StringImpl* uid) from an object of the given structure in the given CodeBlock,
+// assuming that such an access had already been cached by Repatch (and so Repatch had
+// already done a bunch of safety checks). This doesn't reexecute any checks that
+// Repatch would have executed, and for prototype chain accesses, it doesn't ask the
+// objects in the prototype chain whether their getOwnPropertySlot would attempt to
+// intercept the access - so this really is only appropriate if you already know that
+// one of the JITOperations had OK'd this for caching and that Repatch concurred.
+//
+// The typical use pattern is something like:
+//
+//     ComplexGetStatus status = ComplexGetStatus::computeFor(...);
+//     switch (status.kind()) {
+//     case ComplexGetStatus::ShouldSkip:
+//         // Handle the case where this kind of access is possibly safe but wouldn't
+//         // pass the required safety checks. For example, if an IC gives us a list of
+//         // accesses and one of them is ShouldSkip, then we should pretend as if it
+//         // wasn't even there.
+//         break;
+//     case ComplexGetStatus::TakesSlowPath:
+//         // This kind of access is not safe to inline. Bail out of any attempst to
+//         // inline.
+//         break;
+//     case ComplexGetStatus::Inlineable:
+//         // The good stuff goes here. If it's Inlineable then the other properties of
+//         // the 'status' object will tell you everything you need to know about how
+//         // to execute the get-like operation.
+//         break;
+//     }
+
+class ComplexGetStatus {
+public:
+    enum Kind {
+        ShouldSkip,
+        TakesSlowPath,
+        Inlineable
+    };
+    
+    ComplexGetStatus()
+        : m_kind(ShouldSkip)
+        , m_offset(invalidOffset)
+        , m_attributes(UINT_MAX)
+    {
+    }
+    
+    static ComplexGetStatus skip()
+    {
+        return ComplexGetStatus();
+    }
+    
+    static ComplexGetStatus takesSlowPath()
+    {
+        ComplexGetStatus result;
+        result.m_kind = TakesSlowPath;
+        return result;
+    }
+    
+    static ComplexGetStatus computeFor(
+        CodeBlock* profiledBlock, Structure* headStructure, StructureChain* chain,
+        unsigned chainCount, StringImpl* uid);
+    
+    Kind kind() const { return m_kind; }
+    unsigned attributes() const { return m_attributes; }
+    JSValue specificValue() const { return m_specificValue; }
+    PropertyOffset offset() const { return m_offset; }
+    IntendedStructureChain* chain() const { return m_chain.get(); }
+    
+private:
+    Kind m_kind;
+    PropertyOffset m_offset;
+    unsigned m_attributes;
+    JSValue m_specificValue;
+    RefPtr&lt;IntendedStructureChain&gt; m_chain;
+};
+
+} // namespace JSC
+
+#endif // ComplexGetStatus_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AccessorCallJITStubRoutine.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><ins>+#include &quot;ComplexGetStatus.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSScope.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="lines">@@ -83,15 +84,12 @@
</span><span class="cx">         return GetByIdStatus(NoInformation, false);
</span><span class="cx"> 
</span><span class="cx">     unsigned attributesIgnored;
</span><del>-    JSCell* specificValue;
</del><span class="cx">     PropertyOffset offset = structure-&gt;getConcurrently(
</span><del>-        *profiledBlock-&gt;vm(), uid, attributesIgnored, specificValue);
-    if (structure-&gt;isDictionary())
-        specificValue = 0;
</del><ins>+        *profiledBlock-&gt;vm(), uid, attributesIgnored);
</ins><span class="cx">     if (!isValidOffset(offset))
</span><span class="cx">         return GetByIdStatus(NoInformation, false);
</span><span class="cx">     
</span><del>-    return GetByIdStatus(Simple, false, GetByIdVariant(StructureSet(structure), offset, specificValue));
</del><ins>+    return GetByIdStatus(Simple, false, GetByIdVariant(StructureSet(structure), offset));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap&amp; map, unsigned bytecodeIndex, StringImpl* uid)
</span><span class="lines">@@ -138,9 +136,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (stubInfo-&gt;resetByGC)
-        return GetByIdStatus(TakesSlowPath, true);
-
</del><span class="cx">     // Finally figure out if we can derive an access strategy.
</span><span class="cx">     GetByIdStatus result;
</span><span class="cx">     result.m_state = Simple;
</span><span class="lines">@@ -154,18 +149,13 @@
</span><span class="cx">         if (structure-&gt;takesSlowPathInDFGForImpureProperty())
</span><span class="cx">             return GetByIdStatus(slowPathState, true);
</span><span class="cx">         unsigned attributesIgnored;
</span><del>-        JSCell* specificValue;
</del><span class="cx">         GetByIdVariant variant;
</span><span class="cx">         variant.m_offset = structure-&gt;getConcurrently(
</span><del>-            *profiledBlock-&gt;vm(), uid, attributesIgnored, specificValue);
</del><ins>+            *profiledBlock-&gt;vm(), uid, attributesIgnored);
</ins><span class="cx">         if (!isValidOffset(variant.m_offset))
</span><span class="cx">             return GetByIdStatus(slowPathState, true);
</span><span class="cx">         
</span><del>-        if (structure-&gt;isDictionary())
-            specificValue = 0;
-        
</del><span class="cx">         variant.m_structureSet.add(structure);
</span><del>-        variant.m_specificValue = JSValue(specificValue);
</del><span class="cx">         bool didAppend = result.appendVariant(variant);
</span><span class="cx">         ASSERT_UNUSED(didAppend, didAppend);
</span><span class="cx">         return result;
</span><span class="lines">@@ -175,88 +165,49 @@
</span><span class="cx">         for (unsigned listIndex = 0; listIndex &lt; list-&gt;size(); ++listIndex) {
</span><span class="cx">             Structure* structure = list-&gt;at(listIndex).structure();
</span><span class="cx">             
</span><del>-            // FIXME: We should assert that we never see a structure that
-            // hasImpureGetOwnPropertySlot() but for which we don't
-            // newImpurePropertyFiresWatchpoints(). We're not at a point where we can do
-            // that, yet.
-            // https://bugs.webkit.org/show_bug.cgi?id=131810
-            
-            if (structure-&gt;takesSlowPathInDFGForImpureProperty())
</del><ins>+            ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(
+                profiledBlock, structure, list-&gt;at(listIndex).chain(),
+                list-&gt;at(listIndex).chainCount(), uid);
+             
+            switch (complexGetStatus.kind()) {
+            case ComplexGetStatus::ShouldSkip:
+                continue;
+                 
+            case ComplexGetStatus::TakesSlowPath:
</ins><span class="cx">                 return GetByIdStatus(slowPathState, true);
</span><del>-            
-            unsigned attributesIgnored;
-            JSCell* specificValue;
-            PropertyOffset myOffset;
-            RefPtr&lt;IntendedStructureChain&gt; chain;
-
-            if (list-&gt;at(listIndex).chain()) {
-                chain = adoptRef(new IntendedStructureChain(
-                    profiledBlock, structure, list-&gt;at(listIndex).chain(),
-                    list-&gt;at(listIndex).chainCount()));
-                
-                if (!chain-&gt;isStillValid()) {
-                    // This won't ever run again so skip it.
-                    continue;
</del><ins>+                 
+            case ComplexGetStatus::Inlineable: {
+                std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus;
+                switch (list-&gt;at(listIndex).type()) {
+                case GetByIdAccess::SimpleInline:
+                case GetByIdAccess::SimpleStub: {
+                    break;
</ins><span class="cx">                 }
</span><del>-                
-                if (structure-&gt;takesSlowPathInDFGForImpureProperty())
</del><ins>+                case GetByIdAccess::Getter: {
+                    AccessorCallJITStubRoutine* stub = static_cast&lt;AccessorCallJITStubRoutine*&gt;(
+                        list-&gt;at(listIndex).stubRoutine());
+                    callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;(
+                        CallLinkStatus::computeFor(locker, *stub-&gt;m_callLinkInfo, callExitSiteData));
+                    break;
+                }
+                case GetByIdAccess::CustomGetter:
+                case GetByIdAccess::WatchedStub:{
+                    // FIXME: It would be totally sweet to support this at some point in the future.
+                    // https://bugs.webkit.org/show_bug.cgi?id=133052
</ins><span class="cx">                     return GetByIdStatus(slowPathState, true);
</span><del>-                
-                size_t chainSize = chain-&gt;size();
-                for (size_t i = 0; i &lt; chainSize; i++) {
-                    if (chain-&gt;at(i)-&gt;takesSlowPathInDFGForImpureProperty())
-                        return GetByIdStatus(slowPathState, true);
</del><span class="cx">                 }
</span><del>-                
-                JSObject* currentObject = chain-&gt;terminalPrototype();
-                Structure* currentStructure = chain-&gt;last();
-                
-                ASSERT_UNUSED(currentObject, currentObject);
-                
-                myOffset = currentStructure-&gt;getConcurrently(
-                    *profiledBlock-&gt;vm(), uid, attributesIgnored, specificValue);
-                if (currentStructure-&gt;isDictionary())
-                    specificValue = 0;
-            } else {
-                myOffset = structure-&gt;getConcurrently(
-                    *profiledBlock-&gt;vm(), uid, attributesIgnored, specificValue);
-                if (structure-&gt;isDictionary())
-                    specificValue = 0;
-            }
-            
-            if (!isValidOffset(myOffset))
-                return GetByIdStatus(slowPathState, true);
-            
-            std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus;
-            switch (list-&gt;at(listIndex).type()) {
-            case GetByIdAccess::SimpleInline:
-            case GetByIdAccess::SimpleStub: {
</del><ins>+                default:
+                    RELEASE_ASSERT_NOT_REACHED();
+                }
+                 
+                GetByIdVariant variant(
+                    StructureSet(structure), complexGetStatus.offset(), complexGetStatus.chain(),
+                    std::move(callLinkStatus));
+                 
+                if (!result.appendVariant(variant))
+                    return GetByIdStatus(slowPathState, true);
</ins><span class="cx">                 break;
</span><del>-            }
-            case GetByIdAccess::Getter: {
-                AccessorCallJITStubRoutine* stub = static_cast&lt;AccessorCallJITStubRoutine*&gt;(
-                    list-&gt;at(listIndex).stubRoutine());
-                callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;(
-                    CallLinkStatus::computeFor(locker, *stub-&gt;m_callLinkInfo, callExitSiteData));
-                break;
-            }
-            case GetByIdAccess::CustomGetter:
-            case GetByIdAccess::WatchedStub: {
-                // FIXME: It would be totally sweet to support these at some point in the future.
-                // https://bugs.webkit.org/show_bug.cgi?id=133052
-                // https://bugs.webkit.org/show_bug.cgi?id=135172
-                return GetByIdStatus(slowPathState, true);
-            }
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-            }
-            
-            GetByIdVariant variant(
-                StructureSet(structure), myOffset, specificValue, chain.get(),
-                WTF::move(callLinkStatus));
-            
-            if (!result.appendVariant(variant))
-                return GetByIdStatus(slowPathState, true);
</del><ins>+            } }
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         return result;
</span><span class="lines">@@ -334,16 +285,13 @@
</span><span class="cx">             return GetByIdStatus(TakesSlowPath);
</span><span class="cx">         
</span><span class="cx">         unsigned attributes;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = structure-&gt;getConcurrently(vm, uid, attributes, specificValue);
</del><ins>+        PropertyOffset offset = structure-&gt;getConcurrently(vm, uid, attributes);
</ins><span class="cx">         if (!isValidOffset(offset))
</span><span class="cx">             return GetByIdStatus(TakesSlowPath); // It's probably a prototype lookup. Give up on life for now, even though we could totally be way smarter about it.
</span><span class="cx">         if (attributes &amp; Accessor)
</span><span class="cx">             return GetByIdStatus(MakesCalls); // We could be smarter here, like strenght-reducing this to a Call.
</span><del>-        if (structure-&gt;isDictionary())
-            specificValue = 0;
</del><span class="cx">         
</span><del>-        if (!result.appendVariant(GetByIdVariant(structure, offset, specificValue)))
</del><ins>+        if (!result.appendVariant(GetByIdVariant(structure, offset)))
</ins><span class="cx">             return GetByIdStatus(TakesSlowPath);
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdVariantcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -33,17 +33,15 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> GetByIdVariant::GetByIdVariant(
</span><del>-    const StructureSet&amp; structureSet, PropertyOffset offset, JSValue specificValue,
</del><ins>+    const StructureSet&amp; structureSet, PropertyOffset offset,
</ins><span class="cx">     const IntendedStructureChain* chain, std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus)
</span><span class="cx">     : m_structureSet(structureSet)
</span><span class="cx">     , m_alternateBase(nullptr)
</span><del>-    , m_specificValue(specificValue)
</del><span class="cx">     , m_offset(offset)
</span><span class="cx">     , m_callLinkStatus(WTF::move(callLinkStatus))
</span><span class="cx"> {
</span><span class="cx">     if (!structureSet.size()) {
</span><span class="cx">         ASSERT(offset == invalidOffset);
</span><del>-        ASSERT(!specificValue);
</del><span class="cx">         ASSERT(!chain);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -56,6 +54,7 @@
</span><span class="cx"> GetByIdVariant::~GetByIdVariant() { }
</span><span class="cx"> 
</span><span class="cx"> GetByIdVariant::GetByIdVariant(const GetByIdVariant&amp; other)
</span><ins>+    : GetByIdVariant()
</ins><span class="cx"> {
</span><span class="cx">     *this = other;
</span><span class="cx"> }
</span><span class="lines">@@ -65,7 +64,6 @@
</span><span class="cx">     m_structureSet = other.m_structureSet;
</span><span class="cx">     m_constantChecks = other.m_constantChecks;
</span><span class="cx">     m_alternateBase = other.m_alternateBase;
</span><del>-    m_specificValue = other.m_specificValue;
</del><span class="cx">     m_offset = other.m_offset;
</span><span class="cx">     if (other.m_callLinkStatus)
</span><span class="cx">         m_callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;(*other.m_callLinkStatus);
</span><span class="lines">@@ -74,6 +72,16 @@
</span><span class="cx">     return *this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+StructureSet GetByIdVariant::baseStructure() const
+{
+    if (!m_alternateBase)
+        return structureSet();
+    
+    Structure* structure = structureFor(m_constantChecks, m_alternateBase);
+    RELEASE_ASSERT(structure);
+    return structure;
+}
+
</ins><span class="cx"> bool GetByIdVariant::attemptToMerge(const GetByIdVariant&amp; other)
</span><span class="cx"> {
</span><span class="cx">     if (m_alternateBase != other.m_alternateBase)
</span><span class="lines">@@ -85,9 +93,6 @@
</span><span class="cx">     if (!areCompatible(m_constantChecks, other.m_constantChecks))
</span><span class="cx">         return false;
</span><span class="cx">     
</span><del>-    if (m_specificValue != other.m_specificValue)
-        m_specificValue = JSValue();
-
</del><span class="cx">     mergeInto(other.m_constantChecks, m_constantChecks);
</span><span class="cx">     m_structureSet.merge(other.m_structureSet);
</span><span class="cx">     
</span><span class="lines">@@ -111,8 +116,6 @@
</span><span class="cx">         &quot;[&quot;, listDumpInContext(m_constantChecks, context), &quot;]&quot;);
</span><span class="cx">     if (m_alternateBase)
</span><span class="cx">         out.print(&quot;, alternateBase = &quot;, inContext(JSValue(m_alternateBase), context));
</span><del>-    if (specificValue())
-        out.print(&quot;, specificValue = &quot;, inContext(specificValue(), context));
</del><span class="cx">     out.print(&quot;, offset = &quot;, offset());
</span><span class="cx">     if (m_callLinkStatus)
</span><span class="cx">         out.print(&quot;, call = &quot;, *m_callLinkStatus);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdVarianth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -42,8 +42,7 @@
</span><span class="cx"> class GetByIdVariant {
</span><span class="cx"> public:
</span><span class="cx">     GetByIdVariant(
</span><del>-        const StructureSet&amp; structureSet = StructureSet(),
-        PropertyOffset offset = invalidOffset, JSValue specificValue = JSValue(),
</del><ins>+        const StructureSet&amp; structureSet = StructureSet(), PropertyOffset offset = invalidOffset,
</ins><span class="cx">         const IntendedStructureChain* chain = nullptr,
</span><span class="cx">         std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus = nullptr);
</span><span class="cx">     
</span><span class="lines">@@ -58,7 +57,7 @@
</span><span class="cx">     StructureSet&amp; structureSet() { return m_structureSet; }
</span><span class="cx">     const ConstantStructureCheckVector&amp; constantChecks() const { return m_constantChecks; }
</span><span class="cx">     JSObject* alternateBase() const { return m_alternateBase; }
</span><del>-    JSValue specificValue() const { return m_specificValue; }
</del><ins>+    StructureSet baseStructure() const;
</ins><span class="cx">     PropertyOffset offset() const { return m_offset; }
</span><span class="cx">     CallLinkStatus* callLinkStatus() const { return m_callLinkStatus.get(); }
</span><span class="cx">     
</span><span class="lines">@@ -73,7 +72,6 @@
</span><span class="cx">     StructureSet m_structureSet;
</span><span class="cx">     ConstantStructureCheckVector m_constantChecks;
</span><span class="cx">     JSObject* m_alternateBase;
</span><del>-    JSValue m_specificValue;
</del><span class="cx">     PropertyOffset m_offset;
</span><span class="cx">     std::unique_ptr&lt;CallLinkStatus&gt; m_callLinkStatus;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicPutByIdListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx">     
</span><span class="cx">     PutByIdAccess()
</span><span class="cx">         : m_type(Invalid)
</span><ins>+        , m_chainCount(UINT_MAX)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -95,6 +96,7 @@
</span><span class="cx">         AccessType accessType,
</span><span class="cx">         Structure* structure,
</span><span class="cx">         StructureChain* chain,
</span><ins>+        unsigned chainCount,
</ins><span class="cx">         PutPropertySlot::PutValueFunc customSetter,
</span><span class="cx">         PassRefPtr&lt;JITStubRoutine&gt; stubRoutine)
</span><span class="cx">     {
</span><span class="lines">@@ -102,8 +104,10 @@
</span><span class="cx">         PutByIdAccess result;
</span><span class="cx">         result.m_oldStructure.set(vm, owner, structure);
</span><span class="cx">         result.m_type = accessType;
</span><del>-        if (chain)
</del><ins>+        if (chain) {
</ins><span class="cx">             result.m_chain.set(vm, owner, chain);
</span><ins>+            result.m_chainCount = chainCount;
+        }
</ins><span class="cx">         result.m_customSetter = customSetter;
</span><span class="cx">         result.m_stubRoutine = stubRoutine;
</span><span class="cx">         return result;
</span><span class="lines">@@ -132,7 +136,7 @@
</span><span class="cx">     
</span><span class="cx">     Structure* structure() const
</span><span class="cx">     {
</span><del>-        ASSERT(isReplace());
</del><ins>+        ASSERT(isReplace() || isSetter() || isCustom());
</ins><span class="cx">         return m_oldStructure.get();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -148,6 +152,12 @@
</span><span class="cx">         return m_chain.get();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    unsigned chainCount() const
+    {
+        ASSERT(isSetter() || isCustom());
+        return m_chainCount;
+    }
+    
</ins><span class="cx">     JITStubRoutine* stubRoutine() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(isTransition() || isReplace() || isSetter() || isCustom());
</span><span class="lines">@@ -169,6 +179,7 @@
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_oldStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_newStructure;
</span><span class="cx">     WriteBarrier&lt;StructureChain&gt; m_chain;
</span><ins>+    unsigned m_chainCount;
</ins><span class="cx">     PutPropertySlot::PutValueFunc m_customSetter;
</span><span class="cx">     RefPtr&lt;JITStubRoutine&gt; m_stubRoutine;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeProfiledCodeBlockJettisoningWatchpointcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,68 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013, 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;ProfiledCodeBlockJettisoningWatchpoint.h&quot;
-
-#if ENABLE(DFG_JIT)
-
-#include &quot;CodeBlock.h&quot;
-#include &quot;DFGCommon.h&quot;
-#include &quot;DFGExitProfile.h&quot;
-#include &quot;JSCInlines.h&quot;
-
-namespace JSC {
-
-void ProfiledCodeBlockJettisoningWatchpoint::fireInternal()
-{
-    if (DFG::shouldShowDisassembly()) {
-        dataLog(
-            &quot;Firing profiled watchpoint &quot;, RawPointer(this), &quot; on &quot;, *m_codeBlock, &quot; due to &quot;,
-            m_exitKind, &quot; at &quot;, m_codeOrigin, &quot;\n&quot;);
-    }
-    
-    // FIXME: Maybe this should call alternative().
-    // https://bugs.webkit.org/show_bug.cgi?id=123677
-    CodeBlock* machineBaselineCodeBlock = m_codeBlock-&gt;baselineAlternative();
-    CodeBlock* sourceBaselineCodeBlock =
-        baselineCodeBlockForOriginAndBaselineCodeBlock(
-            m_codeOrigin, machineBaselineCodeBlock);
-    
-    if (sourceBaselineCodeBlock) {
-        sourceBaselineCodeBlock-&gt;addFrequentExitSite(
-            DFG::FrequentExitSite(
-                m_codeOrigin.bytecodeIndex, m_exitKind,
-                exitingJITTypeFor(m_codeBlock-&gt;jitType())));
-    }
-    
-    m_codeBlock-&gt;jettison(Profiler::JettisonDueToProfiledWatchpoint, CountReoptimization);
-    
-    if (isOnList())
-        remove();
-}
-
-} // namespace JSC
-
-#endif // ENABLE(DFG_JIT)
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeProfiledCodeBlockJettisoningWatchpointh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,69 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 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 ProfiledCodeBlockJettisoningWatchpoint_h
-#define ProfiledCodeBlockJettisoningWatchpoint_h
-
-#if ENABLE(DFG_JIT)
-
-#include &quot;CodeOrigin.h&quot;
-#include &quot;ExitKind.h&quot;
-#include &quot;Watchpoint.h&quot;
-
-namespace JSC {
-
-class CodeBlock;
-
-class ProfiledCodeBlockJettisoningWatchpoint : public Watchpoint {
-public:
-    ProfiledCodeBlockJettisoningWatchpoint()
-        : m_exitKind(ExitKindUnset)
-        , m_codeBlock(0)
-    {
-    }
-    
-    ProfiledCodeBlockJettisoningWatchpoint(
-        CodeOrigin codeOrigin, ExitKind exitKind, CodeBlock* codeBlock)
-        : m_codeOrigin(codeOrigin)
-        , m_exitKind(exitKind)
-        , m_codeBlock(codeBlock)
-    {
-    }
-    
-protected:
-    virtual void fireInternal() override;
-
-private:
-    CodeOrigin m_codeOrigin;
-    ExitKind m_exitKind;
-    CodeBlock* m_codeBlock;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // ProfiledCodeBlockJettisoningWatchpoint_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -26,7 +26,9 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;PutByIdStatus.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;AccessorCallJITStubRoutine.h&quot;
</ins><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><ins>+#include &quot;ComplexGetStatus.h&quot;
</ins><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -96,10 +98,11 @@
</span><span class="cx">     if (!isValidOffset(offset))
</span><span class="cx">         return PutByIdStatus(NoInformation);
</span><span class="cx">     
</span><del>-    return PutByIdVariant::transition(
-        structure, newStructure,
-        chain ? adoptRef(new IntendedStructureChain(profiledBlock, structure, chain)) : 0,
-        offset);
</del><ins>+    RefPtr&lt;IntendedStructureChain&gt; intendedChain;
+    if (chain)
+        intendedChain = adoptRef(new IntendedStructureChain(profiledBlock, structure, chain));
+    
+    return PutByIdVariant::transition(structure, newStructure, intendedChain.get(), offset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap&amp; map, unsigned bytecodeIndex, StringImpl* uid)
</span><span class="lines">@@ -115,7 +118,9 @@
</span><span class="cx">         return PutByIdStatus(TakesSlowPath);
</span><span class="cx">     
</span><span class="cx">     StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex));
</span><del>-    PutByIdStatus result = computeForStubInfo(locker, profiledBlock, stubInfo, uid);
</del><ins>+    PutByIdStatus result = computeForStubInfo(
+        locker, profiledBlock, stubInfo, uid,
+        CallLinkStatus::computeExitSiteData(locker, profiledBlock, bytecodeIndex));
</ins><span class="cx">     if (!result)
</span><span class="cx">         return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
</span><span class="cx">     
</span><span class="lines">@@ -127,14 +132,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&amp;, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, StringImpl* uid)
</del><ins>+PutByIdStatus PutByIdStatus::computeForStubInfo(
+    const ConcurrentJITLocker&amp; locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo,
+    StringImpl* uid, CallLinkStatus::ExitSiteData callExitSiteData)
</ins><span class="cx"> {
</span><span class="cx">     if (!stubInfo || !stubInfo-&gt;seen)
</span><span class="cx">         return PutByIdStatus();
</span><span class="cx">     
</span><del>-    if (stubInfo-&gt;resetByGC)
-        return PutByIdStatus(TakesSlowPath);
-
</del><span class="cx">     switch (stubInfo-&gt;accessType) {
</span><span class="cx">     case access_unset:
</span><span class="cx">         // If the JIT saw it but didn't optimize it, then assume that this takes slow path.
</span><span class="lines">@@ -158,13 +162,16 @@
</span><span class="cx">             stubInfo-&gt;u.putByIdTransition.structure-&gt;getConcurrently(
</span><span class="cx">                 *profiledBlock-&gt;vm(), uid);
</span><span class="cx">         if (isValidOffset(offset)) {
</span><ins>+            RefPtr&lt;IntendedStructureChain&gt; chain;
+            if (stubInfo-&gt;u.putByIdTransition.chain) {
+                chain = adoptRef(new IntendedStructureChain(
+                    profiledBlock, stubInfo-&gt;u.putByIdTransition.previousStructure.get(),
+                    stubInfo-&gt;u.putByIdTransition.chain.get()));
+            }
</ins><span class="cx">             return PutByIdVariant::transition(
</span><span class="cx">                 stubInfo-&gt;u.putByIdTransition.previousStructure.get(),
</span><span class="cx">                 stubInfo-&gt;u.putByIdTransition.structure.get(),
</span><del>-                stubInfo-&gt;u.putByIdTransition.chain ? adoptRef(new IntendedStructureChain(
-                    profiledBlock, stubInfo-&gt;u.putByIdTransition.previousStructure.get(),
-                    stubInfo-&gt;u.putByIdTransition.chain.get())) : 0,
-                offset);
</del><ins>+                chain.get(), offset);
</ins><span class="cx">         }
</span><span class="cx">         return PutByIdStatus(TakesSlowPath);
</span><span class="cx">     }
</span><span class="lines">@@ -175,17 +182,32 @@
</span><span class="cx">         PutByIdStatus result;
</span><span class="cx">         result.m_state = Simple;
</span><span class="cx">         
</span><ins>+        State slowPathState = TakesSlowPath;
</ins><span class="cx">         for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
</span><span class="cx">             const PutByIdAccess&amp; access = list-&gt;at(i);
</span><span class="cx">             
</span><span class="cx">             switch (access.type()) {
</span><ins>+            case PutByIdAccess::Setter:
+            case PutByIdAccess::CustomSetter:
+                slowPathState = MakesCalls;
+                break;
+            default:
+                break;
+            }
+        }
+        
+        for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
+            const PutByIdAccess&amp; access = list-&gt;at(i);
+            
+            PutByIdVariant variant;
+            
+            switch (access.type()) {
</ins><span class="cx">             case PutByIdAccess::Replace: {
</span><span class="cx">                 Structure* structure = access.structure();
</span><span class="cx">                 PropertyOffset offset = structure-&gt;getConcurrently(*profiledBlock-&gt;vm(), uid);
</span><span class="cx">                 if (!isValidOffset(offset))
</span><del>-                    return PutByIdStatus(TakesSlowPath);
-                if (!result.appendVariant(PutByIdVariant::replace(structure, offset)))
-                    return PutByIdStatus(TakesSlowPath);
</del><ins>+                    return PutByIdStatus(slowPathState);
+                variant = PutByIdVariant::replace(structure, offset);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="lines">@@ -193,7 +215,7 @@
</span><span class="cx">                 PropertyOffset offset =
</span><span class="cx">                     access.newStructure()-&gt;getConcurrently(*profiledBlock-&gt;vm(), uid);
</span><span class="cx">                 if (!isValidOffset(offset))
</span><del>-                    return PutByIdStatus(TakesSlowPath);
</del><ins>+                    return PutByIdStatus(slowPathState);
</ins><span class="cx">                 RefPtr&lt;IntendedStructureChain&gt; chain;
</span><span class="cx">                 if (access.chain()) {
</span><span class="cx">                     chain = adoptRef(new IntendedStructureChain(
</span><span class="lines">@@ -201,19 +223,48 @@
</span><span class="cx">                     if (!chain-&gt;isStillValid())
</span><span class="cx">                         continue;
</span><span class="cx">                 }
</span><del>-                bool ok = result.appendVariant(PutByIdVariant::transition(
-                    access.oldStructure(), access.newStructure(), chain.get(), offset));
-                if (!ok)
-                    return PutByIdStatus(TakesSlowPath);
</del><ins>+                variant = PutByIdVariant::transition(
+                    access.oldStructure(), access.newStructure(), chain.get(), offset);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            case PutByIdAccess::Setter:
</del><ins>+                
+            case PutByIdAccess::Setter: {
+                Structure* structure = access.structure();
+                
+                ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(
+                    profiledBlock, structure, access.chain(), access.chainCount(), uid);
+                
+                switch (complexGetStatus.kind()) {
+                case ComplexGetStatus::ShouldSkip:
+                    continue;
+                    
+                case ComplexGetStatus::TakesSlowPath:
+                    return PutByIdStatus(slowPathState);
+                    
+                case ComplexGetStatus::Inlineable: {
+                    AccessorCallJITStubRoutine* stub = static_cast&lt;AccessorCallJITStubRoutine*&gt;(
+                        access.stubRoutine());
+                    std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus =
+                        std::make_unique&lt;CallLinkStatus&gt;(
+                            CallLinkStatus::computeFor(
+                                locker, *stub-&gt;m_callLinkInfo, callExitSiteData));
+                    
+                    variant = PutByIdVariant::setter(
+                        structure, complexGetStatus.offset(), complexGetStatus.chain(),
+                        std::move(callLinkStatus));
+                } }
+                break;
+            }
+                
</ins><span class="cx">             case PutByIdAccess::CustomSetter:
</span><span class="cx">                 return PutByIdStatus(MakesCalls);
</span><span class="cx"> 
</span><span class="cx">             default:
</span><del>-                return PutByIdStatus(TakesSlowPath);
</del><ins>+                return PutByIdStatus(slowPathState);
</ins><span class="cx">             }
</span><ins>+            
+            if (!result.appendVariant(variant))
+                return PutByIdStatus(slowPathState);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         return result;
</span><span class="lines">@@ -229,16 +280,20 @@
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     if (dfgBlock) {
</span><ins>+        CallLinkStatus::ExitSiteData exitSiteData;
</ins><span class="cx">         {
</span><span class="cx">             ConcurrentJITLocker locker(baselineBlock-&gt;m_lock);
</span><span class="cx">             if (hasExitSite(locker, baselineBlock, codeOrigin.bytecodeIndex, ExitFromFTL))
</span><span class="cx">                 return PutByIdStatus(TakesSlowPath);
</span><ins>+            exitSiteData = CallLinkStatus::computeExitSiteData(
+                locker, baselineBlock, codeOrigin.bytecodeIndex, ExitFromFTL);
</ins><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         PutByIdStatus result;
</span><span class="cx">         {
</span><span class="cx">             ConcurrentJITLocker locker(dfgBlock-&gt;m_lock);
</span><del>-            result = computeForStubInfo(locker, dfgBlock, dfgMap.get(codeOrigin), uid);
</del><ins>+            result = computeForStubInfo(
+                locker, dfgBlock, dfgMap.get(codeOrigin), uid, exitSiteData);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         // We use TakesSlowPath in some cases where the stub was unset. That's weird and
</span><span class="lines">@@ -275,19 +330,24 @@
</span><span class="cx">             return PutByIdStatus(TakesSlowPath);
</span><span class="cx">     
</span><span class="cx">         unsigned attributes;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = structure-&gt;getConcurrently(vm, uid, attributes, specificValue);
</del><ins>+        PropertyOffset offset = structure-&gt;getConcurrently(vm, uid, attributes);
</ins><span class="cx">         if (isValidOffset(offset)) {
</span><span class="cx">             if (attributes &amp; CustomAccessor)
</span><span class="cx">                 return PutByIdStatus(MakesCalls);
</span><span class="cx"> 
</span><span class="cx">             if (attributes &amp; (Accessor | ReadOnly))
</span><span class="cx">                 return PutByIdStatus(TakesSlowPath);
</span><del>-            if (specificValue) {
-                // We need the PutById slow path to verify that we're storing the right value into
-                // the specialized slot.
</del><ins>+            
+            WatchpointSet* replaceSet = structure-&gt;propertyReplacementWatchpointSet(offset);
+            if (!replaceSet || replaceSet-&gt;isStillValid()) {
+                // When this executes, it'll create, and fire, this replacement watchpoint set.
+                // That means that  this has probably never executed or that something fishy is
+                // going on. Also, we cannot create or fire the watchpoint set from the concurrent
+                // JIT thread, so even if we wanted to do this, we'd need to have a lazy thingy.
+                // So, better leave this alone and take slow path.
</ins><span class="cx">                 return PutByIdStatus(TakesSlowPath);
</span><span class="cx">             }
</span><ins>+            
</ins><span class="cx">             if (!result.appendVariant(PutByIdVariant::replace(structure, offset)))
</span><span class="cx">                 return PutByIdStatus(TakesSlowPath);
</span><span class="cx">             continue;
</span><span class="lines">@@ -325,26 +385,13 @@
</span><span class="cx">         }
</span><span class="cx">     
</span><span class="cx">         // We only optimize if there is already a structure that the transition is cached to.
</span><del>-        // Among other things, this allows us to guard against a transition with a specific
-        // value.
-        //
-        // - If we're storing a value that could be specific: this would only be a problem if
-        //   the existing transition did have a specific value already, since if it didn't,
-        //   then we would behave &quot;as if&quot; we were not storing a specific value. If it did
-        //   have a specific value, then we'll know - the fact that we pass 0 for
-        //   specificValue will tell us.
-        //
-        // - If we're not storing a value that could be specific: again, this would only be a
-        //   problem if the existing transition did have a specific value, which we check for
-        //   by passing 0 for the specificValue.
-        Structure* transition = Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, 0, offset);
</del><ins>+        Structure* transition = Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, offset);
</ins><span class="cx">         if (!transition)
</span><del>-            return PutByIdStatus(TakesSlowPath); // This occurs in bizarre cases only. See above.
-        ASSERT(!transition-&gt;transitionDidInvolveSpecificValue());
</del><ins>+            return PutByIdStatus(TakesSlowPath);
</ins><span class="cx">         ASSERT(isValidOffset(offset));
</span><span class="cx">     
</span><span class="cx">         bool didAppend = result.appendVariant(
</span><del>-            PutByIdVariant::transition(structure, transition, chain.release(), offset));
</del><ins>+            PutByIdVariant::transition(structure, transition, chain.get(), offset));
</ins><span class="cx">         if (!didAppend)
</span><span class="cx">             return PutByIdStatus(TakesSlowPath);
</span><span class="cx">     }
</span><span class="lines">@@ -352,6 +399,22 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool PutByIdStatus::makesCalls() const
+{
+    if (m_state == MakesCalls)
+        return true;
+    
+    if (m_state != Simple)
+        return false;
+    
+    for (unsigned i = m_variants.size(); i--;) {
+        if (m_variants[i].makesCalls())
+            return true;
+    }
+    
+    return false;
+}
+
</ins><span class="cx"> void PutByIdStatus::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     switch (m_state) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdStatush"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef PutByIdStatus_h
</span><span class="cx"> #define PutByIdStatus_h
</span><span class="cx"> 
</span><ins>+#include &quot;CallLinkStatus.h&quot;
</ins><span class="cx"> #include &quot;ExitingJITType.h&quot;
</span><span class="cx"> #include &quot;PutByIdVariant.h&quot;
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><span class="lines">@@ -80,7 +81,7 @@
</span><span class="cx">     bool operator!() const { return m_state == NoInformation; }
</span><span class="cx">     bool isSimple() const { return m_state == Simple; }
</span><span class="cx">     bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; }
</span><del>-    bool makesCalls() const { return m_state == MakesCalls; }
</del><ins>+    bool makesCalls() const;
</ins><span class="cx">     
</span><span class="cx">     size_t numVariants() const { return m_variants.size(); }
</span><span class="cx">     const Vector&lt;PutByIdVariant, 1&gt;&amp; variants() const { return m_variants; }
</span><span class="lines">@@ -94,7 +95,9 @@
</span><span class="cx">     static bool hasExitSite(const ConcurrentJITLocker&amp;, CodeBlock*, unsigned bytecodeIndex, ExitingJITType = ExitFromAnything);
</span><span class="cx"> #endif
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    static PutByIdStatus computeForStubInfo(const ConcurrentJITLocker&amp;, CodeBlock*, StructureStubInfo*, StringImpl* uid);
</del><ins>+    static PutByIdStatus computeForStubInfo(
+        const ConcurrentJITLocker&amp;, CodeBlock*, StructureStubInfo*, StringImpl* uid,
+        CallLinkStatus::ExitSiteData);
</ins><span class="cx"> #endif
</span><span class="cx">     static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, StringImpl* uid);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdVariantcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -26,10 +26,72 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;PutByIdVariant.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;CallLinkStatus.h&quot;
+#include &quot;JSCInlines.h&quot;
</ins><span class="cx"> #include &lt;wtf/ListDump.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+PutByIdVariant::PutByIdVariant(const PutByIdVariant&amp; other)
+    : PutByIdVariant()
+{
+    *this = other;
+}
+
+PutByIdVariant&amp; PutByIdVariant::operator=(const PutByIdVariant&amp; other)
+{
+    m_kind = other.m_kind;
+    m_oldStructure = other.m_oldStructure;
+    m_newStructure = other.m_newStructure;
+    m_constantChecks = other.m_constantChecks;
+    m_alternateBase = other.m_alternateBase;
+    m_offset = other.m_offset;
+    if (other.m_callLinkStatus)
+        m_callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;(*other.m_callLinkStatus);
+    else
+        m_callLinkStatus = nullptr;
+    return *this;
+}
+
+PutByIdVariant PutByIdVariant::replace(const StructureSet&amp; structure, PropertyOffset offset)
+{
+    PutByIdVariant result;
+    result.m_kind = Replace;
+    result.m_oldStructure = structure;
+    result.m_offset = offset;
+    return result;
+}
+
+PutByIdVariant PutByIdVariant::transition(
+    const StructureSet&amp; oldStructure, Structure* newStructure,
+    const IntendedStructureChain* structureChain, PropertyOffset offset)
+{
+    PutByIdVariant result;
+    result.m_kind = Transition;
+    result.m_oldStructure = oldStructure;
+    result.m_newStructure = newStructure;
+    if (structureChain)
+        structureChain-&gt;gatherChecks(result.m_constantChecks);
+    result.m_offset = offset;
+    return result;
+}
+
+PutByIdVariant PutByIdVariant::setter(
+    const StructureSet&amp; structure, PropertyOffset offset,
+    IntendedStructureChain* chain, std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus)
+{
+    PutByIdVariant result;
+    result.m_kind = Setter;
+    result.m_oldStructure = structure;
+    if (chain) {
+        chain-&gt;gatherChecks(result.m_constantChecks);
+        result.m_alternateBase = chain-&gt;terminalPrototype();
+    }
+    result.m_offset = offset;
+    result.m_callLinkStatus = std::move(callLinkStatus);
+    return result;
+}
+
</ins><span class="cx"> Structure* PutByIdVariant::oldStructureForTransition() const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(kind() == Transition);
</span><span class="lines">@@ -46,18 +108,42 @@
</span><span class="cx"> 
</span><span class="cx"> bool PutByIdVariant::writesStructures() const
</span><span class="cx"> {
</span><del>-    return kind() == Transition;
</del><ins>+    switch (kind()) {
+    case Transition:
+    case Setter:
+        return true;
+    default:
+        return false;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool PutByIdVariant::reallocatesStorage() const
</span><span class="cx"> {
</span><del>-    if (kind() != Transition)
</del><ins>+    switch (kind()) {
+    case Transition:
+        return oldStructureForTransition()-&gt;outOfLineCapacity() != newStructure()-&gt;outOfLineCapacity();
+    case Setter:
+        return true;
+    default:
</ins><span class="cx">         return false;
</span><ins>+    }
+}
+
+bool PutByIdVariant::makesCalls() const
+{
+    return kind() == Setter;
+}
+
+StructureSet PutByIdVariant::baseStructure() const
+{
+    ASSERT(kind() == Setter);
</ins><span class="cx">     
</span><del>-    if (oldStructureForTransition()-&gt;outOfLineCapacity() == newStructure()-&gt;outOfLineCapacity())
-        return false;
</del><ins>+    if (!m_alternateBase)
+        return structure();
</ins><span class="cx">     
</span><del>-    return true;
</del><ins>+    Structure* structure = structureFor(m_constantChecks, m_alternateBase);
+    RELEASE_ASSERT(structure);
+    return structure;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool PutByIdVariant::attemptToMerge(const PutByIdVariant&amp; other)
</span><span class="lines">@@ -139,15 +225,26 @@
</span><span class="cx">         
</span><span class="cx">     case Replace:
</span><span class="cx">         out.print(
</span><del>-            &quot;&lt;Replace: &quot;, inContext(structure(), context), &quot;, &quot;, offset(), &quot;&gt;&quot;);
</del><ins>+            &quot;&lt;Replace: &quot;, inContext(structure(), context), &quot;, offset = &quot;, offset(), &quot;&gt;&quot;);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case Transition:
</span><span class="cx">         out.print(
</span><span class="cx">             &quot;&lt;Transition: &quot;, inContext(oldStructure(), context), &quot; -&gt; &quot;,
</span><span class="cx">             pointerDumpInContext(newStructure(), context), &quot;, [&quot;,
</span><del>-            listDumpInContext(constantChecks(), context), &quot;], &quot;, offset(), &quot;&gt;&quot;);
</del><ins>+            listDumpInContext(constantChecks(), context), &quot;], offset = &quot;, offset(), &quot;&gt;&quot;);
</ins><span class="cx">         return;
</span><ins>+        
+    case Setter:
+        out.print(
+            &quot;&lt;Setter: &quot;, inContext(structure(), context), &quot;, [&quot;,
+            listDumpInContext(constantChecks(), context), &quot;]&quot;);
+        if (m_alternateBase)
+            out.print(&quot;, alternateBase = &quot;, inContext(JSValue(m_alternateBase), context));
+        out.print(&quot;, offset = &quot;, m_offset);
+        out.print(&quot;, call = &quot;, *m_callLinkStatus);
+        out.print(&quot;&gt;&quot;);
+        return;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdVarianth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -32,44 +32,39 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class CallLinkStatus;
+
</ins><span class="cx"> class PutByIdVariant {
</span><span class="cx"> public:
</span><span class="cx">     enum Kind {
</span><span class="cx">         NotSet,
</span><span class="cx">         Replace,
</span><del>-        Transition
</del><ins>+        Transition,
+        Setter
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     PutByIdVariant()
</span><span class="cx">         : m_kind(NotSet)
</span><span class="cx">         , m_newStructure(nullptr)
</span><ins>+        , m_alternateBase(nullptr)
</ins><span class="cx">         , m_offset(invalidOffset)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    static PutByIdVariant replace(const StructureSet&amp; structure, PropertyOffset offset)
-    {
-        PutByIdVariant result;
-        result.m_kind = Replace;
-        result.m_oldStructure = structure;
-        result.m_offset = offset;
-        return result;
-    }
</del><ins>+    PutByIdVariant(const PutByIdVariant&amp;);
+    PutByIdVariant&amp; operator=(const PutByIdVariant&amp;);
+
+    static PutByIdVariant replace(
+        const StructureSet&amp; structure, PropertyOffset offset);
</ins><span class="cx">     
</span><span class="cx">     static PutByIdVariant transition(
</span><span class="cx">         const StructureSet&amp; oldStructure, Structure* newStructure,
</span><del>-        PassRefPtr&lt;IntendedStructureChain&gt; structureChain, PropertyOffset offset)
-    {
-        PutByIdVariant result;
-        result.m_kind = Transition;
-        result.m_oldStructure = oldStructure;
-        result.m_newStructure = newStructure;
-        if (structureChain)
-            structureChain-&gt;gatherChecks(result.m_constantChecks);
-        result.m_offset = offset;
-        return result;
-    }
</del><ins>+        const IntendedStructureChain* structureChain, PropertyOffset offset);
</ins><span class="cx">     
</span><ins>+    static PutByIdVariant setter(
+        const StructureSet&amp; structure, PropertyOffset offset,
+        IntendedStructureChain* chain, std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus);
+    
</ins><span class="cx">     Kind kind() const { return m_kind; }
</span><span class="cx">     
</span><span class="cx">     bool isSet() const { return kind() != NotSet; }
</span><span class="lines">@@ -77,19 +72,19 @@
</span><span class="cx">     
</span><span class="cx">     const StructureSet&amp; structure() const
</span><span class="cx">     {
</span><del>-        ASSERT(kind() == Replace);
</del><ins>+        ASSERT(kind() == Replace || kind() == Setter);
</ins><span class="cx">         return m_oldStructure;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     const StructureSet&amp; oldStructure() const
</span><span class="cx">     {
</span><del>-        ASSERT(kind() == Transition || kind() == Replace);
</del><ins>+        ASSERT(kind() == Transition || kind() == Replace || kind() == Setter);
</ins><span class="cx">         return m_oldStructure;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     StructureSet&amp; oldStructure()
</span><span class="cx">     {
</span><del>-        ASSERT(kind() == Transition || kind() == Replace);
</del><ins>+        ASSERT(kind() == Transition || kind() == Replace || kind() == Setter);
</ins><span class="cx">         return m_oldStructure;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -103,6 +98,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool writesStructures() const;
</span><span class="cx">     bool reallocatesStorage() const;
</span><ins>+    bool makesCalls() const;
</ins><span class="cx">     
</span><span class="cx">     const ConstantStructureCheckVector&amp; constantChecks() const
</span><span class="cx">     {
</span><span class="lines">@@ -115,6 +111,20 @@
</span><span class="cx">         return m_offset;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    JSObject* alternateBase() const
+    {
+        ASSERT(kind() == Setter);
+        return m_alternateBase;
+    }
+    
+    StructureSet baseStructure() const;
+    
+    CallLinkStatus* callLinkStatus() const
+    {
+        ASSERT(kind() == Setter);
+        return m_callLinkStatus.get();
+    }
+
</ins><span class="cx">     bool attemptToMerge(const PutByIdVariant&amp; other);
</span><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="lines">@@ -127,7 +137,9 @@
</span><span class="cx">     StructureSet m_oldStructure;
</span><span class="cx">     Structure* m_newStructure;
</span><span class="cx">     ConstantStructureCheckVector m_constantChecks;
</span><ins>+    JSObject* m_alternateBase;
</ins><span class="cx">     PropertyOffset m_offset;
</span><ins>+    std::unique_ptr&lt;CallLinkStatus&gt; m_callLinkStatus;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">     return head.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StructureStubClearingWatchpoint::fireInternal()
</del><ins>+void StructureStubClearingWatchpoint::fireInternal(const FireDetail&amp;)
</ins><span class="cx"> {
</span><span class="cx">     // This will implicitly cause my own demise: stub reset removes all watchpoints.
</span><span class="cx">     // That works, because deleting a watchpoint removes it from the set's list, and
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">         OwnPtr&lt;StructureStubClearingWatchpoint&gt;&amp; head);
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    virtual void fireInternal() override;
</del><ins>+    virtual void fireInternal(const FireDetail&amp;) override;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WatchpointsOnStructureStubInfo&amp; m_holder;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeTypeLocationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/TypeLocation.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -32,11 +32,11 @@
</span><span class="cx"> 
</span><span class="cx"> enum HighFidelityGlobalIDFlags {
</span><span class="cx">     HighFidelityNeedsUniqueIDGeneration = -1,
</span><del>-    HighFidelityNoGlobalIDExists = -2
</del><ins>+    HighFidelityNoGlobalIDExists = -2,
+    HighFidelityReturnStatement = -3
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class TypeLocation {
</span><del>-                       
</del><span class="cx"> public:
</span><span class="cx">     TypeLocation() 
</span><span class="cx">         : m_instructionTypeSet(TypeSet::create())
</span><span class="lines">@@ -46,8 +46,9 @@
</span><span class="cx"> 
</span><span class="cx">     int64_t m_globalVariableID;
</span><span class="cx">     intptr_t m_sourceID;
</span><del>-    unsigned m_line;
-    unsigned m_column;
</del><ins>+    unsigned m_divotStart;
+    unsigned m_divotEnd;
+    unsigned m_divotForFunctionOffsetIfReturnStatement;
</ins><span class="cx">     RefPtr&lt;TypeSet&gt; m_instructionTypeSet;
</span><span class="cx">     RefPtr&lt;TypeSet&gt; m_globalTypeSet;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -400,6 +400,32 @@
</span><span class="cx">     m_expressionInfo.append(info);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool UnlinkedCodeBlock::highFidelityTypeProfileExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned&amp; startDivot, unsigned&amp; endDivot)
+{
+    static const bool verbose = false;
+    auto iter = m_highFidelityTypeProfileInfoMap.find(bytecodeOffset);
+    if (iter == m_highFidelityTypeProfileInfoMap.end()) {
+        if (verbose)
+            dataLogF(&quot;Don't have assignment info for offset:%u\n&quot;, bytecodeOffset);
+        startDivot = UINT_MAX;
+        endDivot = UINT_MAX;
+        return false;
+    }
+    
+    HighFidelityTypeProfileExpressionRange&amp; range = iter-&gt;value;
+    startDivot = range.m_startDivot;
+    endDivot = range.m_endDivot;
+    return true;
+}
+
+void UnlinkedCodeBlock::addHighFidelityTypeProfileExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot)
+{
+    HighFidelityTypeProfileExpressionRange range;
+    range.m_startDivot = startDivot;
+    range.m_endDivot = endDivot;
+    m_highFidelityTypeProfileInfoMap.set(instructionOffset, range);  
+}
+
</ins><span class="cx"> void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
</span><span class="cx"> {
</span><span class="cx">     UnlinkedProgramCodeBlock* thisObject = jsCast&lt;UnlinkedProgramCodeBlock*&gt;(cell);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -272,6 +272,8 @@
</span><span class="cx">     void addExpressionInfo(unsigned instructionOffset, int divot,
</span><span class="cx">         int startOffset, int endOffset, unsigned line, unsigned column);
</span><span class="cx"> 
</span><ins>+    void addHighFidelityTypeProfileExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot);
+
</ins><span class="cx">     bool hasExpressionInfo() { return m_expressionInfo.size(); }
</span><span class="cx"> 
</span><span class="cx">     // Special registers
</span><span class="lines">@@ -464,6 +466,8 @@
</span><span class="cx">     void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int&amp; divot,
</span><span class="cx">         int&amp; startOffset, int&amp; endOffset, unsigned&amp; line, unsigned&amp; column);
</span><span class="cx"> 
</span><ins>+    bool highFidelityTypeProfileExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned&amp; startDivot, unsigned&amp; endDivot);
+
</ins><span class="cx">     void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn)
</span><span class="cx">     {
</span><span class="cx">         m_features = features;
</span><span class="lines">@@ -575,6 +579,11 @@
</span><span class="cx"> private:
</span><span class="cx">     OwnPtr&lt;RareData&gt; m_rareData;
</span><span class="cx">     Vector&lt;ExpressionRangeInfo&gt; m_expressionInfo;
</span><ins>+    struct HighFidelityTypeProfileExpressionRange {
+        unsigned m_startDivot;
+        unsigned m_endDivot;
+    };
+    HashMap&lt;unsigned, HighFidelityTypeProfileExpressionRange&gt; m_highFidelityTypeProfileInfoMap;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWatchpointSetcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,49 @@
</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;VariableWatchpointSet.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC {
+
+void VariableWriteFireDetail::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;Write to &quot;, m_name, &quot; in &quot;, JSValue(m_object));
+}
+
+void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value, JSObject* baseObject, const PropertyName&amp; propertyName)
+{
+    notifyWrite(vm, value, VariableWriteFireDetail(baseObject, propertyName));
+}
+
+void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value, const char* reason)
+{
+    notifyWrite(vm, value, StringFireDetail(reason));
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWatchpointSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -31,8 +31,24 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class JSObject;
</ins><span class="cx"> class SymbolTable;
</span><span class="cx"> 
</span><ins>+class VariableWriteFireDetail : public FireDetail {
+public:
+    VariableWriteFireDetail(JSObject* object, const PropertyName&amp; name)
+        : m_object(object)
+        , m_name(name)
+    {
+    }
+    
+    virtual void dump(PrintStream&amp;) const override;
+
+private:
+    JSObject* m_object;
+    const PropertyName&amp; m_name;
+};
+
</ins><span class="cx"> class VariableWatchpointSet : public WatchpointSet {
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> public:
</span><span class="lines">@@ -57,15 +73,17 @@
</span><span class="cx">     //        you will have been notified that the watchpoint was fired.
</span><span class="cx">     JSValue inferredValue() const { return m_inferredValue.get(); }
</span><span class="cx">     
</span><del>-    inline void notifyWrite(VM&amp;, JSValue);
</del><ins>+    void notifyWrite(VM&amp;, JSValue, const FireDetail&amp;);
+    JS_EXPORT_PRIVATE void notifyWrite(VM&amp;, JSValue, JSObject* baseObject, const PropertyName&amp;);
+    void notifyWrite(VM&amp;, JSValue, const char* reason);
</ins><span class="cx">     
</span><del>-    void invalidate()
</del><ins>+    void invalidate(const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><span class="cx">         m_inferredValue.clear();
</span><del>-        WatchpointSet::invalidate();
</del><ins>+        WatchpointSet::invalidate(detail);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void finalizeUnconditionally()
</del><ins>+    void finalizeUnconditionally(const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(!!m_inferredValue == (state() == IsWatched));
</span><span class="cx">         if (!m_inferredValue)
</span><span class="lines">@@ -76,7 +94,7 @@
</span><span class="cx">         JSCell* cell = inferredValue.asCell();
</span><span class="cx">         if (Heap::isMarked(cell))
</span><span class="cx">             return;
</span><del>-        invalidate();
</del><ins>+        invalidate(detail);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;Unknown&gt;* addressOfInferredValue() { return &amp;m_inferredValue; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWatchpointSetInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-inline void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value)
</del><ins>+inline void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!!value);
</span><span class="cx">     switch (state()) {
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">         ASSERT(!!m_inferredValue);
</span><span class="cx">         if (value == m_inferredValue.get())
</span><span class="cx">             return;
</span><del>-        invalidate();
</del><ins>+        invalidate(detail);
</ins><span class="cx">         return;
</span><span class="cx">             
</span><span class="cx">     case IsInvalidated:
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">         
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><del>-    
</del><ins>+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // VariableWatchpointSetInlines_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 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">@@ -31,6 +31,11 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+void StringFireDetail::dump(PrintStream&amp; out) const
+{
+    out.print(m_string);
+}
+
</ins><span class="cx"> Watchpoint::~Watchpoint()
</span><span class="cx"> {
</span><span class="cx">     if (isOnList())
</span><span class="lines">@@ -64,20 +69,25 @@
</span><span class="cx">     m_state = IsWatched;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WatchpointSet::fireAllSlow()
</del><ins>+void WatchpointSet::fireAllSlow(const FireDetail&amp; detail)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(state() == IsWatched);
</span><span class="cx">     
</span><span class="cx">     WTF::storeStoreFence();
</span><del>-    fireAllWatchpoints();
</del><ins>+    fireAllWatchpoints(detail);
</ins><span class="cx">     m_state = IsInvalidated;
</span><span class="cx">     WTF::storeStoreFence();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WatchpointSet::fireAllWatchpoints()
</del><ins>+void WatchpointSet::fireAllSlow(const char* reason)
</ins><span class="cx"> {
</span><ins>+    fireAllSlow(StringFireDetail(reason));
+}
+
+void WatchpointSet::fireAllWatchpoints(const FireDetail&amp; detail)
+{
</ins><span class="cx">     while (!m_set.isEmpty())
</span><del>-        m_set.begin()-&gt;fire();
</del><ins>+        m_set.begin()-&gt;fire(detail);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InlineWatchpointSet::add(Watchpoint* watchpoint)
</span><span class="lines">@@ -85,6 +95,11 @@
</span><span class="cx">     inflate()-&gt;add(watchpoint);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InlineWatchpointSet::fireAll(const char* reason)
+{
+    fireAll(StringFireDetail(reason));
+}
+
</ins><span class="cx"> WatchpointSet* InlineWatchpointSet::inflateSlow()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isThin());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 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">@@ -27,11 +27,38 @@
</span><span class="cx"> #define Watchpoint_h
</span><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Atomics.h&gt;
</span><ins>+#include &lt;wtf/PrintStream.h&gt;
</ins><span class="cx"> #include &lt;wtf/SentinelLinkedList.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSafeRefCounted.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class FireDetail {
+public:
+    FireDetail()
+    {
+    }
+    
+    virtual ~FireDetail()
+    {
+    }
+    
+    virtual void dump(PrintStream&amp;) const = 0;
+};
+
+class StringFireDetail : public FireDetail {
+public:
+    StringFireDetail(const char* string)
+        : m_string(string)
+    {
+    }
+    
+    virtual void dump(PrintStream&amp; out) const override;
+
+private:
+    const char* m_string;
+};
+
</ins><span class="cx"> class Watchpoint : public BasicRawSentinelNode&lt;Watchpoint&gt; {
</span><span class="cx"> public:
</span><span class="cx">     Watchpoint()
</span><span class="lines">@@ -40,10 +67,10 @@
</span><span class="cx">     
</span><span class="cx">     virtual ~Watchpoint();
</span><span class="cx"> 
</span><del>-    void fire() { fireInternal(); }
</del><ins>+    void fire(const FireDetail&amp; detail) { fireInternal(detail); }
</ins><span class="cx">     
</span><span class="cx"> protected:
</span><del>-    virtual void fireInternal() = 0;
</del><ins>+    virtual void fireInternal(const FireDetail&amp;) = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum WatchpointState {
</span><span class="lines">@@ -102,35 +129,43 @@
</span><span class="cx">         m_state = IsWatched;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void fireAll()
</del><ins>+    void fireAll(const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><del>-        if (state() != IsWatched)
</del><ins>+        if (LIKELY(state() != IsWatched))
</ins><span class="cx">             return;
</span><del>-        fireAllSlow();
</del><ins>+        fireAllSlow(detail);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void touch()
</del><ins>+    void fireAll(const char* reason)
</ins><span class="cx">     {
</span><ins>+        if (LIKELY(state() != IsWatched))
+            return;
+        fireAllSlow(reason);
+    }
+    
+    void touch(const FireDetail&amp; detail)
+    {
</ins><span class="cx">         if (state() == ClearWatchpoint)
</span><span class="cx">             startWatching();
</span><span class="cx">         else
</span><del>-            fireAll();
</del><ins>+            fireAll(detail);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void invalidate()
</del><ins>+    void invalidate(const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><span class="cx">         if (state() == IsWatched)
</span><del>-            fireAll();
</del><ins>+            fireAll(detail);
</ins><span class="cx">         m_state = IsInvalidated;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     int8_t* addressOfState() { return &amp;m_state; }
</span><span class="cx">     int8_t* addressOfSetIsNotEmpty() { return &amp;m_setIsNotEmpty; }
</span><span class="cx">     
</span><del>-    JS_EXPORT_PRIVATE void fireAllSlow(); // Call only if you've checked isWatched.
</del><ins>+    JS_EXPORT_PRIVATE void fireAllSlow(const FireDetail&amp;); // Call only if you've checked isWatched.
+    JS_EXPORT_PRIVATE void fireAllSlow(const char* reason); // Ditto.
</ins><span class="cx">     
</span><span class="cx"> private:
</span><del>-    void fireAllWatchpoints();
</del><ins>+    void fireAllWatchpoints(const FireDetail&amp;);
</ins><span class="cx">     
</span><span class="cx">     friend class InlineWatchpointSet;
</span><span class="cx"> 
</span><span class="lines">@@ -206,10 +241,10 @@
</span><span class="cx">         m_data = encodeState(IsWatched);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void fireAll()
</del><ins>+    void fireAll(const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><span class="cx">         if (isFat()) {
</span><del>-            fat()-&gt;fireAll();
</del><ins>+            fat()-&gt;fireAll(detail);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         if (decodeState(m_data) == ClearWatchpoint)
</span><span class="lines">@@ -218,10 +253,12 @@
</span><span class="cx">         WTF::storeStoreFence();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void touch()
</del><ins>+    JS_EXPORT_PRIVATE void fireAll(const char* reason);
+    
+    void touch(const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><span class="cx">         if (isFat()) {
</span><del>-            fat()-&gt;touch();
</del><ins>+            fat()-&gt;touch(detail);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         if (decodeState(m_data) == ClearWatchpoint)
</span><span class="lines">@@ -231,6 +268,11 @@
</span><span class="cx">         WTF::storeStoreFence();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void touch(const char* reason)
+    {
+        touch(StringFireDetail(reason));
+    }
+    
</ins><span class="cx"> private:
</span><span class="cx">     static const uintptr_t IsThinFlag        = 1;
</span><span class="cx">     static const uintptr_t StateMask         = 6;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1005,7 +1005,7 @@
</span><span class="cx">         instructions().append(watchableVariable(dst-&gt;index()));
</span><span class="cx"> 
</span><span class="cx">     if (!dst-&gt;isTemporary() &amp;&amp; isProfilingTypesWithHighFidelity())
</span><del>-        emitProfileTypesWithHighFidelity(dst, true);
</del><ins>+        emitProfileTypesWithHighFidelity(dst, ProfileTypesBytecodeHasGlobalID);
</ins><span class="cx"> 
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="lines">@@ -1116,16 +1116,12 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BytecodeGenerator::emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, bool hasGlobalID)
</del><ins>+void BytecodeGenerator::emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, ProfileTypesWithHighFidelityBytecodeFlag flag)
</ins><span class="cx"> {
</span><span class="cx">     emitOpcode(op_profile_types_with_high_fidelity);
</span><span class="cx">     instructions().append(registerToProfile-&gt;index());
</span><del>-    instructions().append(0); // placeholder for TypeLocation
-    // This is a flag indicating whether we should track this value to its globalID or not.
-    if (hasGlobalID)
-        instructions().append(1);
-    else
-        instructions().append(0);
</del><ins>+    instructions().append(0); // This is a placeholder for the TypeLocation object pointer.
+    instructions().append(flag);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
</span><span class="lines">@@ -1267,26 +1263,52 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitGetFromScopeWithProfile(RegisterID* dst, RegisterID* scope, const Identifier&amp; identifier, ResolveMode resolveMode)
+{
+    m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
+
+    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope_with_profile);
+    instructions().append(kill(dst));
+    instructions().append(scope-&gt;index());
+    instructions().append(addConstant(identifier));
+    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(profile);
+    instructions().append(0); // This is a placeholder for a TypeLocation pointer.
+    return dst;
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier&amp; identifier, RegisterID* value, ResolveMode resolveMode)
</span><span class="cx"> {
</span><span class="cx">     m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
</span><span class="cx"> 
</span><span class="cx">     // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
</span><del>-    if (isProfilingTypesWithHighFidelity())
-        emitOpcode(op_put_to_scope_with_profile);
-    else
-        emitOpcode(op_put_to_scope);
</del><ins>+    emitOpcode(op_put_to_scope);
</ins><span class="cx">     instructions().append(scope-&gt;index());
</span><span class="cx">     instructions().append(addConstant(identifier));
</span><span class="cx">     instructions().append(value-&gt;index());
</span><span class="cx">     instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
</span><span class="cx">     instructions().append(0);
</span><span class="cx">     instructions().append(0);
</span><del>-    if (isProfilingTypesWithHighFidelity())
-        instructions().append(0);
</del><span class="cx">     return value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitPutToScopeWithProfile(RegisterID* scope, const Identifier&amp; identifier, RegisterID* value, ResolveMode resolveMode)
+{
+    m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
+
+    emitOpcode(op_put_to_scope_with_profile);
+    instructions().append(scope-&gt;index());
+    instructions().append(addConstant(identifier));
+    instructions().append(value-&gt;index());
+    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(0); // This is a placeholder for a TypeLocation pointer.
+    return value;
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
</span><span class="cx"> { 
</span><span class="cx">     emitOpcode(op_instanceof);
</span><span class="lines">@@ -1351,9 +1373,6 @@
</span><span class="cx">     instructions().append(0);
</span><span class="cx">     instructions().append(0);
</span><span class="cx"> 
</span><del>-    if (isProfilingTypesWithHighFidelity())
-        emitProfileTypesWithHighFidelity(value, false);
-
</del><span class="cx">     return value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1451,9 +1470,6 @@
</span><span class="cx">     instructions().append(value-&gt;index());
</span><span class="cx">     instructions().append(arrayProfile);
</span><span class="cx"> 
</span><del>-    if (isProfilingTypesWithHighFidelity())
-        emitProfileTypesWithHighFidelity(value, false);
-
</del><span class="cx">     return value;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -155,6 +155,14 @@
</span><span class="cx">         TryData* tryData;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    enum ProfileTypesWithHighFidelityBytecodeFlag { 
+        ProfileTypesBytecodeHasGlobalID,
+        ProfileTypesBytecodeDoesNotHaveGlobalID,
+        ProfileTypesBytecodeFunctionArgument,
+        ProfileTypesBytecodeFunctionThisObject,
+        ProfileTypesBytecodeFunctionReturnStatement  
+    };
+
</ins><span class="cx">     class BytecodeGenerator {
</span><span class="cx">         WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     public:
</span><span class="lines">@@ -316,6 +324,14 @@
</span><span class="cx">                 m_codeBlock-&gt;addExpressionInfo(instructionOffset, divotOffset, startOffset, endOffset, line, column);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        void emitHighFidelityTypeProfilingExpressionInfo(const JSTextPosition&amp; startDivot, const JSTextPosition&amp; endDivot)
+        {
+            unsigned start = startDivot.offset + 1; // Ranges are inclusive of their endpoints, AND 1 indexed.
+            unsigned end = endDivot.offset; // End Ranges already go one past the inclusive range, so no need to do + 1 - 1.
+            unsigned instructionOffset = instructions().size() - 1;
+            m_codeBlock-&gt;addHighFidelityTypeProfileExpressionInfo(instructionOffset, start, end);
+        }
+
</ins><span class="cx">         ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
</span><span class="cx">         {
</span><span class="cx">             return (m_codeType != FunctionCode || m_codeBlock-&gt;needsFullScopeChain() || rightHasAssignments) &amp;&amp; !rightIsPure;
</span><span class="lines">@@ -332,7 +348,7 @@
</span><span class="cx">             return emitNode(n);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        void emitProfileTypesWithHighFidelity(RegisterID* dst, bool);
</del><ins>+        void emitProfileTypesWithHighFidelity(RegisterID* dst, ProfileTypesWithHighFidelityBytecodeFlag);
</ins><span class="cx"> 
</span><span class="cx">         RegisterID* emitLoad(RegisterID* dst, bool);
</span><span class="cx">         RegisterID* emitLoad(RegisterID* dst, double);
</span><span class="lines">@@ -399,7 +415,9 @@
</span><span class="cx">         ResolveType resolveType();
</span><span class="cx">         RegisterID* emitResolveScope(RegisterID* dst, const Identifier&amp;);
</span><span class="cx">         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&amp;, ResolveMode);
</span><ins>+        RegisterID* emitGetFromScopeWithProfile(RegisterID* dst, RegisterID* scope, const Identifier&amp;, ResolveMode);
</ins><span class="cx">         RegisterID* emitPutToScope(RegisterID* scope, const Identifier&amp;, RegisterID* value, ResolveMode);
</span><ins>+        RegisterID* emitPutToScopeWithProfile(RegisterID* scope, const Identifier&amp;, RegisterID* value, ResolveMode);
</ins><span class="cx"> 
</span><span class="cx">         PassRefPtr&lt;Label&gt; emitLabel(Label*);
</span><span class="cx">         void emitLoopHint();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -152,13 +152,23 @@
</span><span class="cx">     if (Local local = generator.local(m_ident)) {
</span><span class="cx">         if (dst == generator.ignoredResult())
</span><span class="cx">             return 0;
</span><ins>+        if (generator.isProfilingTypesWithHighFidelity()) {
+            generator.emitProfileTypesWithHighFidelity(local.get(), ProfileTypesBytecodeHasGlobalID);
+            generator.emitHighFidelityTypeProfilingExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
+        }
</ins><span class="cx">         return generator.moveToDestinationIfNeeded(dst, local.get());
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     JSTextPosition divot = m_start + m_ident.length();
</span><span class="cx">     generator.emitExpressionInfo(divot, m_start, divot);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
</span><del>-    return generator.emitGetFromScope(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound);
</del><ins>+    RegisterID* ret;
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        ret = generator.emitGetFromScopeWithProfile(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
+    } else
+        ret = generator.emitGetFromScope(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound);
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ArrayNode ------------------------------------
</span><span class="lines">@@ -374,7 +384,13 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript-&gt;isPure(generator));
</span><span class="cx">     RegisterID* property = generator.emitNode(m_subscript);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
</del><ins>+    RegisterID* finalDest = generator.finalDestination(dst);
+    RegisterID* ret = generator.emitGetByVal(finalDest, base.get(), property);
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ DotAccessorNode --------------------------------
</span><span class="lines">@@ -394,7 +410,13 @@
</span><span class="cx"> nonArgumentsPath:
</span><span class="cx">     RegisterID* base = generator.emitNode(m_base);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
</del><ins>+    RegisterID* finalDest = generator.finalDestination(dst);
+    RegisterID* ret = generator.emitGetById(finalDest, base, m_ident);
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ArgumentListNode -----------------------------
</span><span class="lines">@@ -473,7 +495,12 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; returnValue = generator.finalDestination(dst, func.get());
</span><span class="cx">     CallArguments callArguments(generator, m_args);
</span><span class="cx">     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><del>-    return generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallResolveNode ----------------------------------
</span><span class="lines">@@ -489,7 +516,12 @@
</span><span class="cx">         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><span class="cx">         // This passes NoExpectedFunction because we expect that if the function is in a
</span><span class="cx">         // local variable, then it's not one of our built-in constructors.
</span><del>-        return generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+        RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        if (generator.isProfilingTypesWithHighFidelity()) {
+            generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+            generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+        }
+        return ret;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;RegisterID&gt; func = generator.newTemporary();
</span><span class="lines">@@ -500,7 +532,12 @@
</span><span class="cx">     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
</span><span class="cx">     generator.emitResolveScope(callArguments.thisRegister(), m_ident);
</span><span class="cx">     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound);
</span><del>-    return generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallBracketNode ----------------------------------
</span><span class="lines">@@ -514,7 +551,12 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; returnValue = generator.finalDestination(dst, function.get());
</span><span class="cx">     CallArguments callArguments(generator, m_args);
</span><span class="cx">     generator.emitMove(callArguments.thisRegister(), base.get());
</span><del>-    return generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ FunctionCallDotNode ----------------------------------
</span><span class="lines">@@ -527,7 +569,12 @@
</span><span class="cx">     generator.emitNode(callArguments.thisRegister(), m_base);
</span><span class="cx">     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
</span><span class="cx">     generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
</span><del>-    return generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</del><ins>+    RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static RegisterID* getArgumentByVal(BytecodeGenerator&amp; generator, ExpressionNode* base, RegisterID* property, RegisterID* dst, JSTextPosition divot, JSTextPosition divotStart, JSTextPosition divotEnd)
</span><span class="lines">@@ -597,6 +644,10 @@
</span><span class="cx">         }
</span><span class="cx">         generator.emitLabel(end.get());
</span><span class="cx">     }
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return returnValue.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -707,6 +758,10 @@
</span><span class="cx">         generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">         generator.emitLabel(end.get());
</span><span class="cx">     }
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return returnValue.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -747,9 +802,9 @@
</span><span class="cx">             generator.emitToNumber(tempDst.get(), localReg);
</span><span class="cx">             generator.emitMove(tempDstSrc.get(), localReg);
</span><span class="cx">             emitIncOrDec(generator, tempDstSrc.get(), m_operator);
</span><ins>+            generator.emitMove(localReg, tempDstSrc.get());
</ins><span class="cx">             if (generator.isProfilingTypesWithHighFidelity())
</span><del>-                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            generator.emitMove(localReg, tempDstSrc.get());
</del><ins>+                generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</ins><span class="cx">             return tempDst.get();
</span><span class="cx">         }
</span><span class="cx">         return emitPostIncOrDec(generator, generator.finalDestination(dst), localReg, m_operator);
</span><span class="lines">@@ -759,7 +814,12 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), ident);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
</span><del>-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitPutToScopeWithProfile(scope.get(), ident, value.get(), ThrowIfNotFound);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    } else
+        generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
+
</ins><span class="cx">     return oldValue.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -781,6 +841,10 @@
</span><span class="cx">     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), value.get());
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, oldValue);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -801,6 +865,10 @@
</span><span class="cx">     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutById(base.get(), ident, value.get());
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, oldValue);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -921,9 +989,9 @@
</span><span class="cx">             RefPtr&lt;RegisterID&gt; tempDst = generator.tempDestination(dst);
</span><span class="cx">             generator.emitMove(tempDst.get(), localReg);
</span><span class="cx">             emitIncOrDec(generator, tempDst.get(), m_operator);
</span><ins>+            generator.emitMove(localReg, tempDst.get());
</ins><span class="cx">             if (generator.isProfilingTypesWithHighFidelity())
</span><del>-                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            generator.emitMove(localReg, tempDst.get());
</del><ins>+                generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</ins><span class="cx">             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
</span><span class="cx">         }
</span><span class="cx">         emitIncOrDec(generator, localReg, m_operator);
</span><span class="lines">@@ -934,7 +1002,11 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), ident);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
</span><span class="cx">     emitIncOrDec(generator, value.get(), m_operator);
</span><del>-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitPutToScopeWithProfile(scope.get(), ident, value.get(), ThrowIfNotFound);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    } else 
+        generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, value.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -954,6 +1026,10 @@
</span><span class="cx">     emitIncOrDec(generator, value, m_operator);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), value);
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(value, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, propDst.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -972,6 +1048,10 @@
</span><span class="cx">     emitIncOrDec(generator, value, m_operator);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutById(base.get(), ident, value);
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(value, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, propDst.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1424,9 +1504,9 @@
</span><span class="cx">             RefPtr&lt;RegisterID&gt; result = generator.newTemporary();
</span><span class="cx">             generator.emitMove(result.get(), local.get());
</span><span class="cx">             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right-&gt;resultDescriptor()));
</span><ins>+            generator.emitMove(local.get(), result.get());
</ins><span class="cx">             if (generator.isProfilingTypesWithHighFidelity())
</span><del>-                generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-            generator.emitMove(local.get(), result.get());
</del><ins>+                generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</ins><span class="cx">             return generator.moveToDestinationIfNeeded(dst, result.get());
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -1438,7 +1518,13 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right-&gt;resultDescriptor()), this);
</span><del>-    return generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
</del><ins>+    RegisterID* ret; 
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        ret = generator.emitPutToScopeWithProfile(scope.get(), m_ident, result.get(), ThrowIfNotFound);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    } else
+        ret = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignResolveNode -----------------------------------
</span><span class="lines">@@ -1453,9 +1539,9 @@
</span><span class="cx">         if (local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) {
</span><span class="cx">             RefPtr&lt;RegisterID&gt; tempDst = generator.tempDestination(dst);
</span><span class="cx">             generator.emitNode(tempDst.get(), m_right);
</span><ins>+            generator.emitMove(local.get(), tempDst.get());
</ins><span class="cx">             if (generator.isProfilingTypesWithHighFidelity())
</span><del>-                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            generator.emitMove(local.get(), tempDst.get());
</del><ins>+                generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</ins><span class="cx">             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
</span><span class="cx">         }
</span><span class="cx">         RegisterID* result = generator.emitNode(local.get(), m_right);
</span><span class="lines">@@ -1469,7 +1555,13 @@
</span><span class="cx">         dst = 0;
</span><span class="cx">     RefPtr&lt;RegisterID&gt; result = generator.emitNode(dst, m_right);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    return generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+    RegisterID* ret;
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        ret = generator.emitPutToScopeWithProfile(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    } else
+        ret = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignDotNode -----------------------------------
</span><span class="lines">@@ -1482,6 +1574,10 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
</span><span class="cx">     generator.emitPutById(base.get(), m_ident, forwardResult);
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(forwardResult, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, forwardResult);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1496,7 +1592,12 @@
</span><span class="cx">     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, static_cast&lt;JSC::Operator&gt;(m_operator), OperandTypes(ResultType::unknownType(), m_right-&gt;resultDescriptor()));
</span><span class="cx"> 
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    return generator.emitPutById(base.get(), m_ident, updatedValue);
</del><ins>+    RegisterID* ret = generator.emitPutById(base.get(), m_ident, updatedValue);
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(updatedValue, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignErrorNode -----------------------------------
</span><span class="lines">@@ -1518,6 +1619,10 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), forwardResult);
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(forwardResult, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, forwardResult);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1534,6 +1639,10 @@
</span><span class="cx"> 
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), updatedValue);
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(updatedValue, ProfileTypesBytecodeDoesNotHaveGlobalID);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx"> 
</span><span class="cx">     return updatedValue;
</span><span class="cx"> }
</span><span class="lines">@@ -2022,6 +2131,10 @@
</span><span class="cx">         dst = 0;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;RegisterID&gt; returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(returnRegister.get(), ProfileTypesBytecodeFunctionReturnStatement);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
+    }
</ins><span class="cx">     if (generator.scopeDepth()) {
</span><span class="cx">         returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
</span><span class="cx">         generator.emitPopScopes(0);
</span><span class="lines">@@ -2349,6 +2462,22 @@
</span><span class="cx"> 
</span><span class="cx"> void FunctionBodyNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</span><span class="cx"> {
</span><ins>+    if (generator.isProfilingTypesWithHighFidelity()) {
+        JSTextPosition start(-1, m_startStartOffset, -1); // This divot is at the open brace of the function.
+        JSTextPosition end(-1, m_startStartOffset + 1, -1);
+        generator.emitProfileTypesWithHighFidelity(generator.thisRegister(), ProfileTypesBytecodeFunctionThisObject);
+        generator.emitHighFidelityTypeProfilingExpressionInfo(start, end);
+        for (size_t i = 0; i &lt; m_parameters-&gt;size(); i++) {
+            // FIXME: Handle Destructuring assignments into arguments.
+            if (!m_parameters-&gt;at(i)-&gt;isBindingNode())
+                continue;
+            BindingNode* parameter = static_cast&lt;BindingNode*&gt;(m_parameters-&gt;at(i));
+            RegisterID reg(CallFrame::argumentOffset(i));
+            generator.emitProfileTypesWithHighFidelity(&amp;reg, ProfileTypesBytecodeFunctionArgument);
+            generator.emitHighFidelityTypeProfilingExpressionInfo(parameter-&gt;divotStart(), parameter-&gt;divotEnd());
+        }
+    }
+
</ins><span class="cx">     generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
</span><span class="cx">     emitStatementsBytecode(generator, generator.ignoredResult());
</span><span class="cx"> 
</span><span class="lines">@@ -2365,6 +2494,8 @@
</span><span class="cx">     // If there is no return we must automatically insert one.
</span><span class="cx">     if (!returnNode) {
</span><span class="cx">         RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
</span><ins>+        if (generator.isProfilingTypesWithHighFidelity())
+            generator.emitProfileTypesWithHighFidelity(r0, ProfileTypesBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code.
</ins><span class="cx">         ASSERT(startOffset() &gt;= lineStartOffset());
</span><span class="cx">         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
</span><span class="cx">         generator.emitReturn(r0);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/Debugger.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/Debugger.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/debugger/Debugger.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class CodeBlock;
</ins><span class="cx"> class ExecState;
</span><span class="cx"> class JSGlobalObject;
</span><span class="cx"> class SourceProvider;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerCallFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -30,12 +30,14 @@
</span><span class="cx"> #include &quot;DebuggerCallFrame.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><ins>+#include &quot;DebuggerScope.h&quot;
</ins><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JSActivation.h&quot;
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;Parser.h&quot;
</span><span class="cx"> #include &quot;StackVisitor.h&quot;
</span><ins>+#include &quot;StrongInlines.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -106,20 +108,25 @@
</span><span class="cx">     return getCalculatedDisplayName(m_callFrame, function);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSScope* DebuggerCallFrame::scope() const
</del><ins>+DebuggerScope* DebuggerCallFrame::scope()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isValid());
</span><span class="cx">     if (!isValid())
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    CodeBlock* codeBlock = m_callFrame-&gt;codeBlock();
-    if (codeBlock &amp;&amp; codeBlock-&gt;needsActivation() &amp;&amp; !m_callFrame-&gt;hasActivation()) {
-        JSActivation* activation = JSActivation::create(*codeBlock-&gt;vm(), m_callFrame, codeBlock);
-        m_callFrame-&gt;setActivation(activation);
-        m_callFrame-&gt;setScope(activation);
</del><ins>+    if (!m_scope) {
+        VM&amp; vm = m_callFrame-&gt;vm();
+        CodeBlock* codeBlock = m_callFrame-&gt;codeBlock();
+        if (codeBlock &amp;&amp; codeBlock-&gt;needsActivation() &amp;&amp; !m_callFrame-&gt;hasActivation()) {
+            ASSERT(!m_callFrame-&gt;scope()-&gt;isWithScope());
+            JSActivation* activation = JSActivation::create(vm, m_callFrame, codeBlock);
+            m_callFrame-&gt;setActivation(activation);
+            m_callFrame-&gt;setScope(activation);
+        }
+
+        m_scope.set(vm, DebuggerScope::create(vm, m_callFrame-&gt;scope()));
</ins><span class="cx">     }
</span><del>-
-    return m_callFrame-&gt;scope();
</del><ins>+    return m_scope.get();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> DebuggerCallFrame::Type DebuggerCallFrame::type() const
</span><span class="lines">@@ -162,7 +169,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSValue thisValue = thisValueForCallFrame(callFrame);
</span><del>-    JSValue result = vm.interpreter-&gt;execute(eval, callFrame, thisValue, scope());
</del><ins>+    JSValue result = vm.interpreter-&gt;execute(eval, callFrame, thisValue, scope()-&gt;jsScope());
</ins><span class="cx">     if (vm.exception()) {
</span><span class="cx">         exception = vm.exception();
</span><span class="cx">         vm.clearException();
</span><span class="lines">@@ -174,6 +181,10 @@
</span><span class="cx"> void DebuggerCallFrame::invalidate()
</span><span class="cx"> {
</span><span class="cx">     m_callFrame = nullptr;
</span><ins>+    if (m_scope) {
+        m_scope-&gt;invalidateChain();
+        m_scope.clear();
+    }
</ins><span class="cx">     RefPtr&lt;DebuggerCallFrame&gt; frame = m_caller.release();
</span><span class="cx">     while (frame) {
</span><span class="cx">         frame-&gt;m_callFrame = nullptr;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerCallFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -29,14 +29,18 @@
</span><span class="cx"> #ifndef DebuggerCallFrame_h
</span><span class="cx"> #define DebuggerCallFrame_h
</span><span class="cx"> 
</span><del>-#include &quot;CallFrame.h&quot;
</del><span class="cx"> #include &quot;DebuggerPrimitives.h&quot;
</span><ins>+#include &quot;Strong.h&quot;
</ins><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/text/TextPosition.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class DebuggerScope;
+class ExecState;
+typedef ExecState CallFrame;
+
</ins><span class="cx"> class DebuggerCallFrame : public RefCounted&lt;DebuggerCallFrame&gt; {
</span><span class="cx"> public:
</span><span class="cx">     enum Type { ProgramType, FunctionType };
</span><span class="lines">@@ -58,7 +62,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE const TextPosition&amp; position() const { return m_position; }
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject() const;
</span><del>-    JS_EXPORT_PRIVATE JSScope* scope() const;
</del><ins>+    JS_EXPORT_PRIVATE DebuggerScope* scope();
</ins><span class="cx">     JS_EXPORT_PRIVATE String functionName() const;
</span><span class="cx">     JS_EXPORT_PRIVATE Type type() const;
</span><span class="cx">     JS_EXPORT_PRIVATE JSValue thisValue() const;
</span><span class="lines">@@ -78,6 +82,9 @@
</span><span class="cx">     CallFrame* m_callFrame;
</span><span class="cx">     RefPtr&lt;DebuggerCallFrame&gt; m_caller;
</span><span class="cx">     TextPosition m_position;
</span><ins>+    // The DebuggerCallFrameScope is responsible for calling invalidate() which,
+    // in turn, will clear this strong ref.
+    Strong&lt;DebuggerScope&gt; m_scope;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSActivation.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;JSWithScope.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -35,17 +36,16 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo DebuggerScope::s_info = { &quot;DebuggerScope&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(DebuggerScope) };
</span><span class="cx"> 
</span><del>-DebuggerScope::DebuggerScope(VM&amp; vm)
-    : JSNonFinalObject(vm, vm.debuggerScopeStructure.get())
</del><ins>+DebuggerScope::DebuggerScope(VM&amp; vm, JSScope* scope)
+    : JSNonFinalObject(vm, scope-&gt;globalObject()-&gt;debuggerScopeStructure())
</ins><span class="cx"> {
</span><ins>+    ASSERT(scope);
+    m_scope.set(vm, this, scope);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DebuggerScope::finishCreation(VM&amp; vm, JSObject* activation)
</del><ins>+void DebuggerScope::finishCreation(VM&amp; vm)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm);
</span><del>-    ASSERT(activation);
-    ASSERT(activation-&gt;isActivationObject());
-    m_activation.set(vm, this, jsCast&lt;JSActivation*&gt;(activation));
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DebuggerScope::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
</span><span class="lines">@@ -53,43 +53,108 @@
</span><span class="cx">     DebuggerScope* thisObject = jsCast&lt;DebuggerScope*&gt;(cell);
</span><span class="cx">     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</span><span class="cx">     JSObject::visitChildren(thisObject, visitor);
</span><del>-    visitor.append(&amp;thisObject-&gt;m_activation);
</del><ins>+    visitor.append(&amp;thisObject-&gt;m_scope);
+    visitor.append(&amp;thisObject-&gt;m_next);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String DebuggerScope::className(const JSObject* object)
</span><span class="cx"> {
</span><del>-    const DebuggerScope* thisObject = jsCast&lt;const DebuggerScope*&gt;(object);
-    return thisObject-&gt;m_activation-&gt;methodTable()-&gt;className(thisObject-&gt;m_activation.get());
</del><ins>+    const DebuggerScope* scope = jsCast&lt;const DebuggerScope*&gt;(object);
+    ASSERT(scope-&gt;isValid());
+    if (!scope-&gt;isValid())
+        return String();
+    JSObject* thisObject = JSScope::objectAtScope(scope-&gt;jsScope());
+    return thisObject-&gt;methodTable()-&gt;className(thisObject);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool DebuggerScope::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot&amp; slot)
</span><span class="cx"> {
</span><del>-    DebuggerScope* thisObject = jsCast&lt;DebuggerScope*&gt;(object);
-    return thisObject-&gt;m_activation-&gt;methodTable()-&gt;getOwnPropertySlot(thisObject-&gt;m_activation.get(), exec, propertyName, slot);
</del><ins>+    DebuggerScope* scope = jsCast&lt;DebuggerScope*&gt;(object);
+    ASSERT(scope-&gt;isValid());
+    if (!scope-&gt;isValid())
+        return false;
+    JSObject* thisObject = JSScope::objectAtScope(scope-&gt;jsScope());
+    return thisObject-&gt;methodTable()-&gt;getOwnPropertySlot(thisObject, exec, propertyName, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DebuggerScope::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot&amp; slot)
</span><span class="cx"> {
</span><del>-    DebuggerScope* thisObject = jsCast&lt;DebuggerScope*&gt;(cell);
-    thisObject-&gt;m_activation-&gt;methodTable()-&gt;put(thisObject-&gt;m_activation.get(), exec, propertyName, value, slot);
</del><ins>+    DebuggerScope* scope = jsCast&lt;DebuggerScope*&gt;(cell);
+    ASSERT(scope-&gt;isValid());
+    if (!scope-&gt;isValid())
+        return;
+    JSObject* thisObject = JSScope::objectAtScope(scope-&gt;jsScope());
+    thisObject-&gt;methodTable()-&gt;put(thisObject, exec, propertyName, value, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool DebuggerScope::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
</span><span class="cx"> {
</span><del>-    DebuggerScope* thisObject = jsCast&lt;DebuggerScope*&gt;(cell);
-    return thisObject-&gt;m_activation-&gt;methodTable()-&gt;deleteProperty(thisObject-&gt;m_activation.get(), exec, propertyName);
</del><ins>+    DebuggerScope* scope = jsCast&lt;DebuggerScope*&gt;(cell);
+    ASSERT(scope-&gt;isValid());
+    if (!scope-&gt;isValid())
+        return false;
+    JSObject* thisObject = JSScope::objectAtScope(scope-&gt;jsScope());
+    return thisObject-&gt;methodTable()-&gt;deleteProperty(thisObject, exec, propertyName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DebuggerScope::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray&amp; propertyNames, EnumerationMode mode)
</span><span class="cx"> {
</span><del>-    DebuggerScope* thisObject = jsCast&lt;DebuggerScope*&gt;(object);
-    thisObject-&gt;m_activation-&gt;methodTable()-&gt;getPropertyNames(thisObject-&gt;m_activation.get(), exec, propertyNames, mode);
</del><ins>+    DebuggerScope* scope = jsCast&lt;DebuggerScope*&gt;(object);
+    ASSERT(scope-&gt;isValid());
+    if (!scope-&gt;isValid())
+        return;
+    JSObject* thisObject = JSScope::objectAtScope(scope-&gt;jsScope());
+    thisObject-&gt;methodTable()-&gt;getPropertyNames(thisObject, exec, propertyNames, mode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool DebuggerScope::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor&amp; descriptor, bool shouldThrow)
</span><span class="cx"> {
</span><del>-    DebuggerScope* thisObject = jsCast&lt;DebuggerScope*&gt;(object);
-    return thisObject-&gt;m_activation-&gt;methodTable()-&gt;defineOwnProperty(thisObject-&gt;m_activation.get(), exec, propertyName, descriptor, shouldThrow);
</del><ins>+    DebuggerScope* scope = jsCast&lt;DebuggerScope*&gt;(object);
+    ASSERT(scope-&gt;isValid());
+    if (!scope-&gt;isValid())
+        return false;
+    JSObject* thisObject = JSScope::objectAtScope(scope-&gt;jsScope());
+    return thisObject-&gt;methodTable()-&gt;defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+DebuggerScope* DebuggerScope::next()
+{
+    ASSERT(isValid());
+    if (!m_next &amp;&amp; m_scope-&gt;next()) {
+        VM&amp; vm = *m_scope-&gt;vm();
+        DebuggerScope* nextScope = create(vm, m_scope-&gt;next());
+        m_next.set(vm, this, nextScope);
+    }
+    return m_next.get();
+}
+
+void DebuggerScope::invalidateChain()
+{
+    DebuggerScope* scope = this;
+    while (scope) {
+        ASSERT(scope-&gt;isValid());
+        DebuggerScope* nextScope = scope-&gt;m_next.get();
+        scope-&gt;m_next.clear();
+        scope-&gt;m_scope.clear();
+        scope = nextScope;
+    }
+}
+
+bool DebuggerScope::isWithScope() const
+{
+    return m_scope-&gt;isWithScope();
+}
+
+bool DebuggerScope::isGlobalScope() const
+{
+    return m_scope-&gt;isGlobalObject();
+}
+
+bool DebuggerScope::isFunctionScope() const
+{
+    // In the current debugger implementation, every function will create an
+    // activation object. Hence, an activation object implies a function scope.
+    return m_scope-&gt;isActivationObject();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerScope.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerScope.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -30,15 +30,18 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class DebuggerCallFrame;
+class JSScope;
+
</ins><span class="cx"> class DebuggerScope : public JSNonFinalObject {
</span><span class="cx"> public:
</span><span class="cx">     typedef JSNonFinalObject Base;
</span><span class="cx"> 
</span><del>-    static DebuggerScope* create(VM&amp; vm, JSObject* object)
</del><ins>+    static DebuggerScope* create(VM&amp; vm, JSScope* scope)
</ins><span class="cx">     {
</span><del>-        DebuggerScope* activation = new (NotNull, allocateCell&lt;DebuggerScope&gt;(vm.heap)) DebuggerScope(vm);
-        activation-&gt;finishCreation(vm, object);
-        return activation;
</del><ins>+        DebuggerScope* debuggerScope = new (NotNull, allocateCell&lt;DebuggerScope&gt;(vm.heap)) DebuggerScope(vm, scope);
+        debuggerScope-&gt;finishCreation(vm);
+        return debuggerScope;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="lines">@@ -56,16 +59,59 @@
</span><span class="cx">         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-protected:
</del><ins>+    class Iterator {
+    public:
+        Iterator(DebuggerScope* node)
+            : m_node(node)
+        {
+        }
+
+        DebuggerScope* get() { return m_node; }
+        Iterator&amp; operator++() { m_node = m_node-&gt;next(); return *this; }
+        // postfix ++ intentionally omitted
+
+        bool operator==(const Iterator&amp; other) const { return m_node == other.m_node; }
+        bool operator!=(const Iterator&amp; other) const { return m_node != other.m_node; }
+
+    private:
+        DebuggerScope* m_node;
+    };
+
+    Iterator begin();
+    Iterator end();
+    DebuggerScope* next();
+
+    void invalidateChain();
+    bool isValid() const { return !!m_scope; }
+
+    bool isWithScope() const;
+    bool isGlobalScope() const;
+    bool isFunctionScope() const;
+
+private:
+    JS_EXPORT_PRIVATE DebuggerScope(VM&amp;, JSScope*);
+    JS_EXPORT_PRIVATE void finishCreation(VM&amp;);
+
+    JSScope* jsScope() const { return m_scope.get(); }
+
</ins><span class="cx">     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE void finishCreation(VM&amp;, JSObject* activation);
</del><ins>+    WriteBarrier&lt;JSScope&gt; m_scope;
+    WriteBarrier&lt;DebuggerScope&gt; m_next;
</ins><span class="cx"> 
</span><del>-private:
-    JS_EXPORT_PRIVATE DebuggerScope(VM&amp;);
-    WriteBarrier&lt;JSActivation&gt; m_activation;
</del><ins>+    friend class DebuggerCallFrame;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+inline DebuggerScope::Iterator DebuggerScope::begin()
+{
+    return Iterator(this); 
+}
+
+inline DebuggerScope::Iterator DebuggerScope::end()
+{ 
+    return Iterator(0); 
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // DebuggerScope_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -42,31 +42,22 @@
</span><span class="cx"> #define FOR_EACH_ABSTRACT_HEAP_KIND(macro) \
</span><span class="cx">     macro(InvalidAbstractHeap) \
</span><span class="cx">     macro(World) \
</span><del>-    macro(Arguments_numArguments) \
-    macro(Arguments_overrideLength) \
</del><span class="cx">     macro(Arguments_registers) \
</span><del>-    macro(Arguments_slowArguments) \
-    macro(ArrayBuffer_data) \
-    macro(Butterfly_arrayBuffer) \
</del><span class="cx">     macro(Butterfly_publicLength) \
</span><span class="cx">     macro(Butterfly_vectorLength) \
</span><span class="cx">     macro(GetterSetter_getter) \
</span><span class="cx">     macro(GetterSetter_setter) \
</span><del>-    macro(JSArrayBufferView_length) \
-    macro(JSArrayBufferView_mode) \
-    macro(JSArrayBufferView_vector) \
</del><span class="cx">     macro(JSCell_structureID) \
</span><span class="cx">     macro(JSCell_indexingType) \
</span><span class="cx">     macro(JSCell_typeInfoFlags) \
</span><span class="cx">     macro(JSCell_typeInfoType) \
</span><del>-    macro(JSFunction_executable) \
-    macro(JSFunction_scopeChain) \
</del><span class="cx">     macro(JSObject_butterfly) \
</span><span class="cx">     macro(JSVariableObject_registers) \
</span><span class="cx">     macro(NamedProperties) \
</span><span class="cx">     macro(IndexedInt32Properties) \
</span><span class="cx">     macro(IndexedDoubleProperties) \
</span><span class="cx">     macro(IndexedContiguousProperties) \
</span><ins>+    macro(IndexedArrayStorageProperties) \
</ins><span class="cx">     macro(ArrayStorageProperties) \
</span><span class="cx">     macro(Variables) \
</span><span class="cx">     macro(TypedArrayProperties) \
</span><span class="lines">@@ -76,7 +67,7 @@
</span><span class="cx">     macro(Absolute) \
</span><span class="cx">     /* Use this for writes only, to indicate that this may fire watchpoints. Usually this is never directly written but instead we test to see if a node clobbers this; it just so happens that you have to write world to clobber it. */\
</span><span class="cx">     macro(Watchpoint_fire) \
</span><del>-    /* Use this for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\
</del><ins>+    /* Use these for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\
</ins><span class="cx">     macro(MiscFields) \
</span><span class="cx">     /* Use this for writes only, just to indicate that hoisting the node is invalid. This works because we don't hoist anything that has any side effects at all. */\
</span><span class="cx">     macro(SideState)
</span><span class="lines">@@ -207,7 +198,7 @@
</span><span class="cx">         return payloadImpl();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isDisjoint(const AbstractHeap&amp; other)
</del><ins>+    bool isDisjoint(const AbstractHeap&amp; other) const
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(kind() != InvalidAbstractHeap);
</span><span class="cx">         ASSERT(other.kind() != InvalidAbstractHeap);
</span><span class="lines">@@ -220,7 +211,7 @@
</span><span class="cx">         return payload().isDisjoint(other.payload());
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool overlaps(const AbstractHeap&amp; other)
</del><ins>+    bool overlaps(const AbstractHeap&amp; other) const
</ins><span class="cx">     {
</span><span class="cx">         return !isDisjoint(other);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGAbstractInterpreter.h&quot;
</span><span class="cx"> #include &quot;GetByIdStatus.h&quot;
</span><ins>+#include &quot;GetterSetter.h&quot;
</ins><span class="cx"> #include &quot;Operations.h&quot;
</span><span class="cx"> #include &quot;PutByIdStatus.h&quot;
</span><span class="cx"> #include &quot;StringObject.h&quot;
</span><span class="lines">@@ -1354,11 +1355,35 @@
</span><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case GetCallee:
</span><del>-    case GetGetter:
-    case GetSetter:
</del><span class="cx">         forNode(node).setType(SpecFunction);
</span><span class="cx">         break;
</span><span class="cx">         
</span><ins>+    case GetGetter: {
+        JSValue base = forNode(node-&gt;child1()).m_value;
+        if (base) {
+            if (JSObject* getter = jsCast&lt;GetterSetter*&gt;(base)-&gt;getterConcurrently()) {
+                setConstant(node, *m_graph.freeze(getter));
+                break;
+            }
+        }
+        
+        forNode(node).setType(SpecObject);
+        break;
+    }
+        
+    case GetSetter: {
+        JSValue base = forNode(node-&gt;child1()).m_value;
+        if (base) {
+            if (JSObject* setter = jsCast&lt;GetterSetter*&gt;(base)-&gt;setterConcurrently()) {
+                setConstant(node, *m_graph.freeze(setter));
+                break;
+            }
+        }
+        
+        forNode(node).setType(SpecObject);
+        break;
+    }
+        
</ins><span class="cx">     case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
</span><span class="cx">     case GetMyScope:
</span><span class="cx">     case SkipTopScope:
</span><span class="lines">@@ -1405,14 +1430,17 @@
</span><span class="cx">                 // something more subtle?
</span><span class="cx">                 AbstractValue result;
</span><span class="cx">                 for (unsigned i = status.numVariants(); i--;) {
</span><del>-                    if (!status[i].specificValue()) {
</del><ins>+                    DFG_ASSERT(m_graph, node, !status[i].alternateBase());
+                    JSValue constantResult =
+                        m_graph.tryGetConstantProperty(value, status[i].offset());
+                    if (!constantResult) {
</ins><span class="cx">                         result.makeHeapTop();
</span><span class="cx">                         break;
</span><span class="cx">                     }
</span><span class="cx">                     
</span><span class="cx">                     AbstractValue thisResult;
</span><span class="cx">                     thisResult.set(
</span><del>-                        m_graph, *m_graph.freeze(status[i].specificValue()),
</del><ins>+                        m_graph, *m_graph.freeze(constantResult),
</ins><span class="cx">                         m_state.structureClobberState());
</span><span class="cx">                     result.merge(thisResult);
</span><span class="cx">                 }
</span><span class="lines">@@ -1587,11 +1615,25 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case GetByOffset: {
</span><ins>+        StorageAccessData data = m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()];
+        JSValue result = m_graph.tryGetConstantProperty(forNode(node-&gt;child2()), data.offset);
+        if (result) {
+            setConstant(node, *m_graph.freeze(result));
+            break;
+        }
+        
</ins><span class="cx">         forNode(node).makeHeapTop();
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case GetGetterSetterByOffset: {
</span><ins>+        StorageAccessData data = m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()];
+        JSValue result = m_graph.tryGetConstantProperty(forNode(node-&gt;child2()), data.offset);
+        if (result &amp;&amp; jsDynamicCast&lt;GetterSetter*&gt;(result)) {
+            setConstant(node, *m_graph.freeze(result));
+            break;
+        }
+        
</ins><span class="cx">         forNode(node).set(m_graph, m_graph.m_vm.getterSetterStructure.get());
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -1620,14 +1662,23 @@
</span><span class="cx">             if (set.isEmpty())
</span><span class="cx">                 continue;
</span><span class="cx">             baseSet.merge(set);
</span><del>-            if (!variant.specificValue()) {
</del><ins>+            
+            JSValue baseForLoad;
+            if (variant.alternateBase())
+                baseForLoad = variant.alternateBase();
+            else
+                baseForLoad = base.m_value;
+            JSValue constantResult =
+                m_graph.tryGetConstantProperty(
+                    baseForLoad, variant.baseStructure(), variant.offset());
+            if (!constantResult) {
</ins><span class="cx">                 result.makeHeapTop();
</span><span class="cx">                 continue;
</span><span class="cx">             }
</span><span class="cx">             AbstractValue thisResult;
</span><span class="cx">             thisResult.set(
</span><span class="cx">                 m_graph,
</span><del>-                *m_graph.freeze(variant.specificValue()),
</del><ins>+                *m_graph.freeze(constantResult),
</ins><span class="cx">                 m_state.structureClobberState());
</span><span class="cx">             result.merge(thisResult);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAdjacencyListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAdjacencyList.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAdjacencyList.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGAdjacencyList.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    AdjacencyList(Kind kind, Edge child1, Edge child2, Edge child3)
</del><ins>+    AdjacencyList(Kind kind, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
</ins><span class="cx">     {
</span><span class="cx">         ASSERT_UNUSED(kind, kind == Fixed);
</span><span class="cx">         initialize(child1, child2, child3);
</span><span class="lines">@@ -132,7 +132,7 @@
</span><span class="cx">             setChild(i, child(i + 1));
</span><span class="cx">         setChild(Size - 1, Edge());
</span><span class="cx">     }
</span><del>-
</del><ins>+    
</ins><span class="cx">     unsigned firstChild() const
</span><span class="cx">     {
</span><span class="cx">         return m_words[0].m_encodedWord;
</span><span class="lines">@@ -151,6 +151,41 @@
</span><span class="cx">         m_words[1].m_encodedWord = numChildren;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    AdjacencyList sanitized() const
+    {
+        return AdjacencyList(Fixed, child1().sanitized(), child2().sanitized(), child3().sanitized());
+    }
+    
+    unsigned hash() const
+    {
+        unsigned result = 0;
+        if (!child1())
+            return result;
+        
+        result += child1().hash();
+        
+        if (!child2())
+            return result;
+        
+        result *= 3;
+        result += child2().hash();
+        
+        if (!child3())
+            return result;
+        
+        result *= 3;
+        result += child3().hash();
+        
+        return result;
+    }
+    
+    bool operator==(const AdjacencyList&amp; other) const
+    {
+        return child1() == other.child1()
+            &amp;&amp; child2() == other.child2()
+            &amp;&amp; child3() == other.child3();
+    }
+    
</ins><span class="cx"> private:
</span><span class="cx">     Edge m_words[Size];
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -171,8 +171,8 @@
</span><span class="cx">         SSAData(BasicBlock*);
</span><span class="cx">         ~SSAData();
</span><span class="cx">     };
</span><del>-    OwnPtr&lt;SSAData&gt; ssa;
-
</del><ins>+    std::unique_ptr&lt;SSAData&gt; ssa;
+    
</ins><span class="cx"> private:
</span><span class="cx">     friend class InsertionSet;
</span><span class="cx">     Vector&lt;Node*, 8&gt; m_nodes;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -171,6 +171,10 @@
</span><span class="cx">     // Handle calls. This resolves issues surrounding inlining and intrinsics.
</span><span class="cx">     void handleCall(
</span><span class="cx">         int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
</span><ins>+        Node* callTarget, int argCount, int registerOffset, CallLinkStatus,
+        SpeculatedType prediction);
+    void handleCall(
+        int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
</ins><span class="cx">         Node* callTarget, int argCount, int registerOffset, CallLinkStatus);
</span><span class="cx">     void handleCall(int result, NodeType op, CodeSpecializationKind, unsigned instructionSize, int callee, int argCount, int registerOffset);
</span><span class="cx">     void handleCall(Instruction* pc, NodeType op, CodeSpecializationKind);
</span><span class="lines">@@ -183,7 +187,7 @@
</span><span class="cx">     bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType);
</span><span class="cx">     bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
</span><span class="cx">     Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, Node* value);
</span><del>-    Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset, NodeType op = GetByOffset);
</del><ins>+    Node* handleGetByOffset(SpeculatedType, Node* base, const StructureSet&amp;, unsigned identifierNumber, PropertyOffset, NodeType op = GetByOffset);
</ins><span class="cx">     void handleGetById(
</span><span class="cx">         int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber,
</span><span class="cx">         const GetByIdStatus&amp;);
</span><span class="lines">@@ -640,10 +644,10 @@
</span><span class="cx">         m_numPassedVarArgs++;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* addCall(int result, NodeType op, Node* callee, int argCount, int registerOffset)
</del><ins>+    Node* addCallWithoutSettingResult(
+        NodeType op, Node* callee, int argCount, int registerOffset,
+        SpeculatedType prediction)
</ins><span class="cx">     {
</span><del>-        SpeculatedType prediction = getPrediction();
-        
</del><span class="cx">         addVarArgChild(callee);
</span><span class="cx">         size_t parameterSlots = JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize + argCount;
</span><span class="cx">         if (parameterSlots &gt; m_parameterSlots)
</span><span class="lines">@@ -653,8 +657,18 @@
</span><span class="cx">         for (int i = 0 + dummyThisArgument; i &lt; argCount; ++i)
</span><span class="cx">             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
</span><span class="cx"> 
</span><del>-        Node* call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
-        set(VirtualRegister(result), call);
</del><ins>+        return addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
+    }
+    
+    Node* addCall(
+        int result, NodeType op, Node* callee, int argCount, int registerOffset,
+        SpeculatedType prediction)
+    {
+        Node* call = addCallWithoutSettingResult(
+            op, callee, argCount, registerOffset, prediction);
+        VirtualRegister resultReg(result);
+        if (resultReg.isValid())
+            set(VirtualRegister(result), call);
</ins><span class="cx">         return call;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -994,6 +1008,16 @@
</span><span class="cx">     Node* callTarget, int argumentCountIncludingThis, int registerOffset,
</span><span class="cx">     CallLinkStatus callLinkStatus)
</span><span class="cx"> {
</span><ins>+    handleCall(
+        result, op, kind, instructionSize, callTarget, argumentCountIncludingThis,
+        registerOffset, callLinkStatus, getPrediction());
+}
+
+void ByteCodeParser::handleCall(
+    int result, NodeType op, InlineCallFrame::Kind kind, unsigned instructionSize,
+    Node* callTarget, int argumentCountIncludingThis, int registerOffset,
+    CallLinkStatus callLinkStatus, SpeculatedType prediction)
+{
</ins><span class="cx">     ASSERT(registerOffset &lt;= 0);
</span><span class="cx">     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</span><span class="cx">     
</span><span class="lines">@@ -1004,12 +1028,11 @@
</span><span class="cx">         // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
</span><span class="cx">         // that we cannot optimize them.
</span><span class="cx">         
</span><del>-        addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset);
</del><ins>+        addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset, prediction);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     unsigned nextOffset = m_currentIndex + instructionSize;
</span><del>-    SpeculatedType prediction = getPrediction();
</del><span class="cx"> 
</span><span class="cx">     if (InternalFunction* function = callLinkStatus.internalFunction()) {
</span><span class="cx">         if (handleConstantInternalFunction(result, function, registerOffset, argumentCountIncludingThis, prediction, specializationKind)) {
</span><span class="lines">@@ -1021,7 +1044,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         // Can only handle this using the generic call handler.
</span><del>-        addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset);
</del><ins>+        addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset, prediction);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -1058,7 +1081,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    Node* call = addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset);
</del><ins>+    Node* call = addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset, prediction);
</ins><span class="cx"> 
</span><span class="cx">     if (knownFunction) 
</span><span class="cx">         call-&gt;giveKnownFunction(knownFunction);
</span><span class="lines">@@ -1205,9 +1228,12 @@
</span><span class="cx">     
</span><span class="cx">     size_t argumentPositionStart = m_graph.m_argumentPositions.size();
</span><span class="cx"> 
</span><ins>+    VirtualRegister resultReg(resultOperand);
+    if (resultReg.isValid())
+        resultReg = m_inlineStackTop-&gt;remapOperand(resultReg);
+    
</ins><span class="cx">     InlineStackEntry inlineStackEntry(
</span><del>-        this, codeBlock, codeBlock, m_graph.lastBlock(), callLinkStatus.function(),
-        m_inlineStackTop-&gt;remapOperand(VirtualRegister(resultOperand)),
</del><ins>+        this, codeBlock, codeBlock, m_graph.lastBlock(), callLinkStatus.function(), resultReg,
</ins><span class="cx">         (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind);
</span><span class="cx">     
</span><span class="cx">     // This is where the actual inlining really happens.
</span><span class="lines">@@ -1673,8 +1699,15 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Node* ByteCodeParser::handleGetByOffset(SpeculatedType prediction, Node* base, unsigned identifierNumber, PropertyOffset offset, NodeType op)
</del><ins>+Node* ByteCodeParser::handleGetByOffset(SpeculatedType prediction, Node* base, const StructureSet&amp; structureSet, unsigned identifierNumber, PropertyOffset offset, NodeType op)
</ins><span class="cx"> {
</span><ins>+    if (base-&gt;hasConstant()) {
+        if (JSValue constant = m_graph.tryGetConstantProperty(base-&gt;asJSValue(), structureSet, offset)) {
+            addToGraph(Phantom, base);
+            return weakJSConstant(constant);
+        }
+    }
+    
</ins><span class="cx">     Node* propertyStorage;
</span><span class="cx">     if (isInlineOffset(offset))
</span><span class="cx">         propertyStorage = base;
</span><span class="lines">@@ -1769,20 +1802,14 @@
</span><span class="cx">     // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
</span><span class="cx">     // ensure that the base of the original get_by_id is kept alive until we're done with
</span><span class="cx">     // all of the speculations. We only insert the Phantom if there had been a CheckStructure
</span><del>-    // on something other than the base following the CheckStructure on base, or if the
-    // access was compiled to a WeakJSConstant specific value, in which case we might not
-    // have any explicit use of the base at all.
-    if (variant.specificValue() || originalBase != base)
</del><ins>+    // on something other than the base following the CheckStructure on base.
+    if (originalBase != base)
</ins><span class="cx">         addToGraph(Phantom, originalBase);
</span><span class="cx">     
</span><del>-    Node* loadedValue;
-    if (variant.specificValue())
-        loadedValue = weakJSConstant(variant.specificValue());
-    else {
-        loadedValue = handleGetByOffset(
-            prediction, base, identifierNumber, variant.offset(),
-            variant.callLinkStatus() ? GetGetterSetterByOffset : GetByOffset);
-    }
</del><ins>+    Node* loadedValue = handleGetByOffset(
+        variant.callLinkStatus() ? SpecCellOther : prediction,
+        base, variant.baseStructure(), identifierNumber, variant.offset(),
+        variant.callLinkStatus() ? GetGetterSetterByOffset : GetByOffset);
</ins><span class="cx">     
</span><span class="cx">     if (!variant.callLinkStatus()) {
</span><span class="cx">         set(VirtualRegister(destinationOperand), loadedValue);
</span><span class="lines">@@ -1824,7 +1851,7 @@
</span><span class="cx">     
</span><span class="cx">     handleCall(
</span><span class="cx">         destinationOperand, Call, InlineCallFrame::GetterCall, OPCODE_LENGTH(op_get_by_id),
</span><del>-        getter, numberOfParameters - 1, registerOffset, *variant.callLinkStatus());
</del><ins>+        getter, numberOfParameters - 1, registerOffset, *variant.callLinkStatus(), prediction);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ByteCodeParser::emitPutById(
</span><span class="lines">@@ -1875,7 +1902,8 @@
</span><span class="cx">     ASSERT(putByIdStatus.numVariants() == 1);
</span><span class="cx">     const PutByIdVariant&amp; variant = putByIdStatus[0];
</span><span class="cx">     
</span><del>-    if (variant.kind() == PutByIdVariant::Replace) {
</del><ins>+    switch (variant.kind()) {
+    case PutByIdVariant::Replace: {
</ins><span class="cx">         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structure())), base);
</span><span class="cx">         handlePutByOffset(base, identifierNumber, variant.offset(), value);
</span><span class="cx">         if (m_graph.compilation())
</span><span class="lines">@@ -1883,57 +1911,111 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (variant.kind() != PutByIdVariant::Transition) {
-        emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
-        return;
-    }
</del><ins>+    case PutByIdVariant::Transition: {
+        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
+        emitChecks(variant.constantChecks());
</ins><span class="cx"> 
</span><del>-    addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
-    emitChecks(variant.constantChecks());
-
-    ASSERT(variant.oldStructureForTransition()-&gt;transitionWatchpointSetHasBeenInvalidated());
</del><ins>+        ASSERT(variant.oldStructureForTransition()-&gt;transitionWatchpointSetHasBeenInvalidated());
</ins><span class="cx">     
</span><del>-    Node* propertyStorage;
-    Transition* transition = m_graph.m_transitions.add(
-        variant.oldStructureForTransition(), variant.newStructure());
</del><ins>+        Node* propertyStorage;
+        Transition* transition = m_graph.m_transitions.add(
+            variant.oldStructureForTransition(), variant.newStructure());
</ins><span class="cx"> 
</span><del>-    if (variant.reallocatesStorage()) {
</del><ins>+        if (variant.reallocatesStorage()) {
</ins><span class="cx"> 
</span><del>-        // If we're growing the property storage then it must be because we're
-        // storing into the out-of-line storage.
-        ASSERT(!isInlineOffset(variant.offset()));
</del><ins>+            // If we're growing the property storage then it must be because we're
+            // storing into the out-of-line storage.
+            ASSERT(!isInlineOffset(variant.offset()));
</ins><span class="cx"> 
</span><del>-        if (!variant.oldStructureForTransition()-&gt;outOfLineCapacity()) {
-            propertyStorage = addToGraph(
-                AllocatePropertyStorage, OpInfo(transition), base);
</del><ins>+            if (!variant.oldStructureForTransition()-&gt;outOfLineCapacity()) {
+                propertyStorage = addToGraph(
+                    AllocatePropertyStorage, OpInfo(transition), base);
+            } else {
+                propertyStorage = addToGraph(
+                    ReallocatePropertyStorage, OpInfo(transition),
+                    base, addToGraph(GetButterfly, base));
+            }
</ins><span class="cx">         } else {
</span><del>-            propertyStorage = addToGraph(
-                ReallocatePropertyStorage, OpInfo(transition),
-                base, addToGraph(GetButterfly, base));
</del><ins>+            if (isInlineOffset(variant.offset()))
+                propertyStorage = base;
+            else
+                propertyStorage = addToGraph(GetButterfly, base);
</ins><span class="cx">         }
</span><del>-    } else {
-        if (isInlineOffset(variant.offset()))
-            propertyStorage = base;
-        else
-            propertyStorage = addToGraph(GetButterfly, base);
-    }
</del><span class="cx"> 
</span><del>-    addToGraph(PutStructure, OpInfo(transition), base);
</del><ins>+        addToGraph(PutStructure, OpInfo(transition), base);
</ins><span class="cx"> 
</span><del>-    addToGraph(
-        PutByOffset,
-        OpInfo(m_graph.m_storageAccessData.size()),
-        propertyStorage,
-        base,
-        value);
</del><ins>+        addToGraph(
+            PutByOffset,
+            OpInfo(m_graph.m_storageAccessData.size()),
+            propertyStorage,
+            base,
+            value);
</ins><span class="cx"> 
</span><del>-    StorageAccessData storageAccessData;
-    storageAccessData.offset = variant.offset();
-    storageAccessData.identifierNumber = identifierNumber;
-    m_graph.m_storageAccessData.append(storageAccessData);
</del><ins>+        StorageAccessData storageAccessData;
+        storageAccessData.offset = variant.offset();
+        storageAccessData.identifierNumber = identifierNumber;
+        m_graph.m_storageAccessData.append(storageAccessData);
</ins><span class="cx"> 
</span><del>-    if (m_graph.compilation())
-        m_graph.compilation()-&gt;noticeInlinedPutById();
</del><ins>+        if (m_graph.compilation())
+            m_graph.compilation()-&gt;noticeInlinedPutById();
+        return;
+    }
+        
+    case PutByIdVariant::Setter: {
+        Node* originalBase = base;
+        
+        addToGraph(
+            CheckStructure, OpInfo(m_graph.addStructureSet(variant.structure())), base);
+        
+        emitChecks(variant.constantChecks());
+        
+        if (variant.alternateBase())
+            base = weakJSConstant(variant.alternateBase());
+        
+        Node* loadedValue = handleGetByOffset(
+            SpecCellOther, base, variant.baseStructure(), identifierNumber, variant.offset(),
+            GetGetterSetterByOffset);
+        
+        Node* setter = addToGraph(GetSetter, loadedValue);
+        
+        // Make a call. We don't try to get fancy with using the smallest operand number because
+        // the stack layout phase should compress the stack anyway.
+    
+        unsigned numberOfParameters = 0;
+        numberOfParameters++; // The 'this' argument.
+        numberOfParameters++; // The new value.
+        numberOfParameters++; // True return PC.
+    
+        // Start with a register offset that corresponds to the last in-use register.
+        int registerOffset = virtualRegisterForLocal(
+            m_inlineStackTop-&gt;m_profiledBlock-&gt;m_numCalleeRegisters - 1).offset();
+        registerOffset -= numberOfParameters;
+        registerOffset -= JSStack::CallFrameHeaderSize;
+    
+        // Get the alignment right.
+        registerOffset = -WTF::roundUpToMultipleOf(
+            stackAlignmentRegisters(),
+            -registerOffset);
+    
+        ensureLocals(
+            m_inlineStackTop-&gt;remapOperand(
+                VirtualRegister(registerOffset)).toLocal());
+    
+        int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
+        set(VirtualRegister(nextRegister++), originalBase, ImmediateNakedSet);
+        set(VirtualRegister(nextRegister++), value, ImmediateNakedSet);
+    
+        handleCall(
+            VirtualRegister().offset(), Call, InlineCallFrame::SetterCall,
+            OPCODE_LENGTH(op_put_by_id), setter, numberOfParameters - 1, registerOffset,
+            *variant.callLinkStatus(), SpecOther);
+        return;
+    }
+    
+    default: {
+        emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
+        return;
+    } }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ByteCodeParser::prepareToParseBlock()
</span><span class="lines">@@ -2715,8 +2797,8 @@
</span><span class="cx">         case op_ret:
</span><span class="cx">             flushForReturn();
</span><span class="cx">             if (inlineCallFrame()) {
</span><del>-                ASSERT(m_inlineStackTop-&gt;m_returnValue.isValid());
-                setDirect(m_inlineStackTop-&gt;m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSetWithFlush);
</del><ins>+                if (m_inlineStackTop-&gt;m_returnValue.isValid())
+                    setDirect(m_inlineStackTop-&gt;m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSetWithFlush);
</ins><span class="cx">                 m_inlineStackTop-&gt;m_didReturn = true;
</span><span class="cx">                 if (m_inlineStackTop-&gt;m_unlinkedBlocks.isEmpty()) {
</span><span class="cx">                     // If we're returning from the first block, then we're done parsing.
</span><span class="lines">@@ -2894,10 +2976,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().onlyStructure());
</span><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><del>-                if (JSValue specificValue = status[0].specificValue())
-                    set(VirtualRegister(dst), weakJSConstant(specificValue.asCell()));
-                else
-                    set(VirtualRegister(dst), handleGetByOffset(prediction, base, identifierNumber, operand));
</del><ins>+                set(VirtualRegister(dst), handleGetByOffset(prediction, base, status[0].structureSet(), identifierNumber, operand));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case GlobalVar:
</span><span class="lines">@@ -2905,16 +2984,16 @@
</span><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx">                 SymbolTableEntry entry = globalObject-&gt;symbolTable()-&gt;get(uid);
</span><span class="cx">                 VariableWatchpointSet* watchpointSet = entry.watchpointSet();
</span><del>-                JSValue specificValue =
</del><ins>+                JSValue inferredValue =
</ins><span class="cx">                     watchpointSet ? watchpointSet-&gt;inferredValue() : JSValue();
</span><del>-                if (!specificValue) {
</del><ins>+                if (!inferredValue) {
</ins><span class="cx">                     SpeculatedType prediction = getPrediction();
</span><span class="cx">                     set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
</span><del>-                set(VirtualRegister(dst), weakJSConstant(specificValue));
</del><ins>+                set(VirtualRegister(dst), weakJSConstant(inferredValue));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case ClosureVar:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCPSRethreadingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -201,12 +201,12 @@
</span><span class="cx">             
</span><span class="cx">             if (otherNode-&gt;op() == GetLocal) {
</span><span class="cx">                 // Replace all references to this GetLocal with otherNode.
</span><del>-                node-&gt;misc.replacement = otherNode;
</del><ins>+                node-&gt;replacement = otherNode;
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             ASSERT(otherNode-&gt;op() == SetLocal);
</span><del>-            node-&gt;misc.replacement = otherNode-&gt;child1().node();
</del><ins>+            node-&gt;replacement = otherNode-&gt;child1().node();
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCSEPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGAbstractHeap.h&quot;
</span><ins>+#include &quot;DFGClobberSet.h&quot;
</ins><span class="cx"> #include &quot;DFGClobberize.h&quot;
</span><span class="cx"> #include &quot;DFGEdgeUsesStructure.h&quot;
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="lines">@@ -39,18 +40,52 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><del>-class CSEPhase : public Phase {
</del><ins>+// This file contains two CSE implementations: local and global. LocalCSE typically runs when we're
+// in DFG mode, i.e. we want to compile quickly. LocalCSE contains a lot of optimizations for
+// compile time. GlobalCSE, on the other hand, is fairly straight-forward. It will find more
+// optimization opportunities by virtue of being global.
+
+namespace {
+
+const bool verbose = false;
+
+class ClobberFilter {
</ins><span class="cx"> public:
</span><del>-    CSEPhase(Graph&amp; graph)
-        : Phase(graph, &quot;common subexpression elimination&quot;)
</del><ins>+    ClobberFilter(AbstractHeap heap)
+        : m_heap(heap)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool operator()(const ImpureMap::KeyValuePairType&amp; pair) const
+    {
+        return m_heap.overlaps(pair.key.heap());
+    }
+    
+private:
+    AbstractHeap m_heap;
+};
+
+inline void clobber(ImpureMap&amp; map, AbstractHeap heap)
+{
+    ClobberFilter filter(heap);
+    map.removeIf(filter);
+}
+
+class LocalCSEPhase : public Phase {
+public:
+    LocalCSEPhase(Graph&amp; graph)
+        : Phase(graph, &quot;local common subexpression elimination&quot;)
+        , m_smallBlock(graph)
+        , m_largeBlock(graph)
+    {
+    }
+    
</ins><span class="cx">     bool run()
</span><span class="cx">     {
</span><del>-        ASSERT(m_graph.m_fixpointState != BeforeFixpoint);
</del><ins>+        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
+        ASSERT(m_graph.m_form == ThreadedCPS || m_graph.m_form == LoadStore);
</ins><span class="cx">         
</span><del>-        m_changed = false;
</del><ins>+        bool changed = false;
</ins><span class="cx">         
</span><span class="cx">         m_graph.clearReplacements();
</span><span class="cx">         
</span><span class="lines">@@ -59,1177 +94,590 @@
</span><span class="cx">             if (!block)
</span><span class="cx">                 continue;
</span><span class="cx">             
</span><del>-            // All Phis need to already be marked as relevant to OSR.
-            if (!ASSERT_DISABLED) {
-                for (unsigned i = 0; i &lt; block-&gt;phis.size(); ++i)
-                    ASSERT(block-&gt;phis[i]-&gt;flags() &amp; NodeRelevantToOSR);
-            }
-            
-            for (unsigned i = block-&gt;size(); i--;) {
-                Node* node = block-&gt;at(i);
-                
-                switch (node-&gt;op()) {
-                case SetLocal:
-                case GetLocal: // FIXME: The GetLocal case is only necessary until we do https://bugs.webkit.org/show_bug.cgi?id=106707.
-                    node-&gt;mergeFlags(NodeRelevantToOSR);
-                    break;
-                default:
-                    node-&gt;clearFlags(NodeRelevantToOSR);
-                    break;
-                }
-            }
</del><ins>+            if (block-&gt;size() &lt;= SmallMaps::capacity)
+                changed |= m_smallBlock.run(block);
+            else
+                changed |= m_largeBlock.run(block);
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            
-            for (unsigned i = block-&gt;size(); i--;) {
-                Node* node = block-&gt;at(i);
-                if (!node-&gt;containsMovHint())
-                    continue;
-                
-                ASSERT(node-&gt;op() != ZombieHint);
-                node-&gt;child1()-&gt;mergeFlags(NodeRelevantToOSR);
-            }
-        }
-        
-        if (m_graph.m_form == SSA) {
-            Vector&lt;BasicBlock*&gt; depthFirst;
-            m_graph.getBlocksInDepthFirstOrder(depthFirst);
-            for (unsigned i = 0; i &lt; depthFirst.size(); ++i)
-                performBlockCSE(depthFirst[i]);
-        } else {
-            for (unsigned blockIndex = 0; blockIndex &lt; m_graph.numBlocks(); ++blockIndex)
-                performBlockCSE(m_graph.block(blockIndex));
-        }
-        
-        return m_changed;
</del><ins>+        return changed;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><ins>+    class SmallMaps {
+    public:
+        // This permits SmallMaps to be used for blocks that have up to 100 nodes. In practice,
+        // fewer than half of the nodes in a block have pure defs, and even fewer have impure defs.
+        // Thus, a capacity limit of 100 probably means that somewhere around ~40 things may end up
+        // in one of these &quot;small&quot; list-based maps. That number still seems largeish, except that
+        // the overhead of HashMaps can be quite high currently: clearing them, or even removing
+        // enough things from them, deletes (or resizes) their backing store eagerly. Hence
+        // HashMaps induce a lot of malloc traffic.
+        static const unsigned capacity = 100;
</ins><span class="cx">     
</span><del>-    unsigned endIndexForPureCSE()
-    {
-        unsigned result = m_lastSeen[m_currentNode-&gt;op()];
-        if (result == UINT_MAX)
-            result = 0;
-        else
-            result++;
-        ASSERT(result &lt;= m_indexInBlock);
-        return result;
-    }
-
-    Node* pureCSE(Node* node)
-    {
-        Edge child1 = node-&gt;child1().sanitized();
-        Edge child2 = node-&gt;child2().sanitized();
-        Edge child3 = node-&gt;child3().sanitized();
-        
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock-&gt;at(i);
-            if (otherNode == child1 || otherNode == child2 || otherNode == child3)
-                break;
-
-            if (node-&gt;op() != otherNode-&gt;op())
-                continue;
-            
-            Edge otherChild = otherNode-&gt;child1().sanitized();
-            if (!otherChild)
-                return otherNode;
-            if (otherChild != child1)
-                continue;
-            
-            otherChild = otherNode-&gt;child2().sanitized();
-            if (!otherChild)
-                return otherNode;
-            if (otherChild != child2)
-                continue;
-            
-            otherChild = otherNode-&gt;child3().sanitized();
-            if (!otherChild)
-                return otherNode;
-            if (otherChild != child3)
-                continue;
-            
-            return otherNode;
</del><ins>+        SmallMaps()
+            : m_pureLength(0)
+            , m_impureLength(0)
+        {
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* constantCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock-&gt;at(i);
-            if (otherNode-&gt;op() != node-&gt;op())
-                continue;
-            
-            if (otherNode-&gt;constant() != node-&gt;constant())
-                continue;
-            
-            return otherNode;
</del><ins>+        void clear()
+        {
+            m_pureLength = 0;
+            m_impureLength = 0;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* constantStoragePointerCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock-&gt;at(i);
-            if (otherNode-&gt;op() != ConstantStoragePointer)
-                continue;
-            
-            if (otherNode-&gt;storagePointer() != node-&gt;storagePointer())
-                continue;
-            
-            return otherNode;
</del><ins>+        void write(AbstractHeap heap)
+        {
+            for (unsigned i = 0; i &lt; m_impureLength; ++i) {
+                if (heap.overlaps(m_impureMap[i].key.heap()))
+                    m_impureMap[i--] = m_impureMap[--m_impureLength];
+            }
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* getCalleeLoadElimination()
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetCallee:
-                return node;
-            default:
-                break;
</del><ins>+        Node* addPure(PureValue value, Node* node)
+        {
+            for (unsigned i = m_pureLength; i--;) {
+                if (m_pureMap[i].key == value)
+                    return m_pureMap[i].value;
</ins><span class="cx">             }
</span><ins>+        
+            ASSERT(m_pureLength &lt; capacity);
+            m_pureMap[m_pureLength++] = WTF::KeyValuePair&lt;PureValue, Node*&gt;(value, node);
+            return nullptr;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
-    
-    Node* getArrayLengthElimination(Node* array)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetArrayLength:
-                if (node-&gt;child1() == array)
-                    return node;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-                if (!m_graph.byValIsPure(node))
-                    return 0;
-                if (node-&gt;arrayMode().mayStoreToHole())
-                    return 0;
-                break;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
</del><ins>+        
+        Node* findReplacement(HeapLocation location)
+        {
+            for (unsigned i = m_impureLength; i--;) {
+                if (m_impureMap[i].key == location)
+                    return m_impureMap[i].value;
</ins><span class="cx">             }
</span><ins>+            return nullptr;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* globalVarLoadElimination(WriteBarrier&lt;Unknown&gt;* registerPointer)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetGlobalVar:
-                if (node-&gt;registerPointer() == registerPointer)
-                    return node;
-                break;
-            case PutGlobalVar:
-                if (node-&gt;registerPointer() == registerPointer)
-                    return node-&gt;child1().node();
-                break;
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node))
-                break;
</del><ins>+        Node* addImpure(HeapLocation location, Node* node)
+        {
+            if (Node* result = findReplacement(location))
+                return result;
+            ASSERT(m_impureLength &lt; capacity);
+            m_impureMap[m_impureLength++] = WTF::KeyValuePair&lt;HeapLocation, Node*&gt;(location, node);
+            return nullptr;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* scopedVarLoadElimination(Node* registers, int varNumber)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetClosureVar: {
-                if (node-&gt;child1() == registers &amp;&amp; node-&gt;varNumber() == varNumber)
-                    return node;
-                break;
-            } 
-            case PutClosureVar: {
-                if (node-&gt;varNumber() != varNumber)
-                    break;
-                if (node-&gt;child2() == registers)
-                    return node-&gt;child3().node();
-                return 0;
-            }
-            case SetLocal: {
-                VariableAccessData* variableAccessData = node-&gt;variableAccessData();
-                if (variableAccessData-&gt;isCaptured()
-                    &amp;&amp; variableAccessData-&gt;local() == static_cast&lt;VirtualRegister&gt;(varNumber))
-                    return 0;
-                break;
-            }
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node))
-                break;
</del><ins>+    private:
+        WTF::KeyValuePair&lt;PureValue, Node*&gt; m_pureMap[capacity];
+        WTF::KeyValuePair&lt;HeapLocation, Node*&gt; m_impureMap[capacity];
+        unsigned m_pureLength;
+        unsigned m_impureLength;
+    };
+
+    class LargeMaps {
+    public:
+        LargeMaps()
+        {
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    bool varInjectionWatchpointElimination()
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node-&gt;op() == VarInjectionWatchpoint)
-                return true;
-            if (m_graph.clobbersWorld(node))
-                break;
</del><ins>+        void clear()
+        {
+            m_pureMap.clear();
+            m_impureMap.clear();
</ins><span class="cx">         }
</span><del>-        return false;
-    }
</del><span class="cx">     
</span><del>-    Node* getByValLoadElimination(Node* child1, Node* child2, ArrayMode arrayMode)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1 || node == child2) 
-                break;
-
-            switch (node-&gt;op()) {
-            case GetByVal:
-                if (!m_graph.byValIsPure(node))
-                    return 0;
-                if (node-&gt;child1() == child1
-                    &amp;&amp; node-&gt;child2() == child2
-                    &amp;&amp; node-&gt;arrayMode().type() == arrayMode.type())
-                    return node;
-                break;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias: {
-                if (!m_graph.byValIsPure(node))
-                    return 0;
-                // Typed arrays 
-                if (arrayMode.typedArrayType() != NotTypedArray)
-                    return 0;
-                if (m_graph.varArgChild(node, 0) == child1
-                    &amp;&amp; m_graph.varArgChild(node, 1) == child2
-                    &amp;&amp; node-&gt;arrayMode().type() == arrayMode.type())
-                    return m_graph.varArgChild(node, 2).node();
-                // We must assume that the PutByVal will clobber the location we're getting from.
-                // FIXME: We can do better; if we know that the PutByVal is accessing an array of a
-                // different type than the GetByVal, then we know that they won't clobber each other.
-                // ... except of course for typed arrays, where all typed arrays clobber all other
-                // typed arrays!  An Int32Array can alias a Float64Array for example, and so on.
-                return 0;
-            }
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
</del><ins>+        void write(AbstractHeap heap)
+        {
+            clobber(m_impureMap, heap);
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
-
-    bool checkFunctionElimination(FrozenValue* function, Node* child1)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
-
-            if (node-&gt;op() == CheckFunction &amp;&amp; node-&gt;child1() == child1 &amp;&amp; node-&gt;function() == function)
-                return true;
</del><ins>+    
+        Node* addPure(PureValue value, Node* node)
+        {
+            auto result = m_pureMap.add(value, node);
+            if (result.isNewEntry)
+                return nullptr;
+            return result.iterator-&gt;value;
</ins><span class="cx">         }
</span><del>-        return false;
-    }
</del><ins>+        
+        Node* findReplacement(HeapLocation location)
+        {
+            return m_impureMap.get(location);
+        }
</ins><span class="cx">     
</span><del>-    bool checkExecutableElimination(ExecutableBase* executable, Node* child1)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1)
-                break;
-
-            if (node-&gt;op() == CheckExecutable &amp;&amp; node-&gt;child1() == child1 &amp;&amp; node-&gt;executable() == executable)
-                return true;
</del><ins>+        Node* addImpure(HeapLocation location, Node* node)
+        {
+            auto result = m_impureMap.add(location, node);
+            if (result.isNewEntry)
+                return nullptr;
+            return result.iterator-&gt;value;
</ins><span class="cx">         }
</span><del>-        return false;
-    }
</del><span class="cx"> 
</span><del>-    bool checkStructureElimination(const StructureSet&amp; structureSet, Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
</del><ins>+    private:
+        HashMap&lt;PureValue, Node*&gt; m_pureMap;
+        HashMap&lt;HeapLocation, Node*&gt; m_impureMap;
+    };
</ins><span class="cx"> 
</span><del>-            switch (node-&gt;op()) {
-            case CheckStructure:
-                if (node-&gt;child1() == child1
-                    &amp;&amp; structureSet.isSupersetOf(node-&gt;structureSet()))
-                    return true;
-                break;
-                
-            case PutStructure:
-                if (node-&gt;child1() == child1
-                    &amp;&amp; structureSet.contains(node-&gt;transition()-&gt;next))
-                    return true;
-                if (structureSet.contains(node-&gt;transition()-&gt;previous))
-                    return false;
-                break;
-                
-            case PutByOffset:
-                // Setting a property cannot change the structure.
-                break;
-                
-            case MultiPutByOffset:
-                if (node-&gt;multiPutByOffsetData().writesStructures())
-                    return false;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return false;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our structures.
-                // But that seems like it would take Effort.
-                return false;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return false;
-                break;
-            }
</del><ins>+    template&lt;typename Maps&gt;
+    class BlockCSE {
+    public:
+        BlockCSE(Graph&amp; graph)
+            : m_graph(graph)
+        {
</ins><span class="cx">         }
</span><del>-        return false;
-    }
</del><span class="cx">     
</span><del>-    bool structureTransitionWatchpointElimination(Structure* structure, Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
</del><ins>+        bool run(BasicBlock* block)
+        {
+            m_maps.clear();
+            m_changed = false;
+        
+            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                m_node = block-&gt;at(nodeIndex);
+                m_graph.performSubstitution(m_node);
+            
+                if (m_node-&gt;op() == Identity) {
+                    m_node-&gt;convertToCheck();
+                    m_node-&gt;replacement = m_node-&gt;child1().node();
+                    m_changed = true;
+                } else {
+                    // This rule only makes sense for local CSE, since in SSA form we have already
+                    // factored the bounds check out of the PutByVal. It's kind of gross, but we
+                    // still have reason to believe that PutByValAlias is a good optimization and
+                    // that it's better to do it with a single node rather than separating out the
+                    // CheckInBounds.
+                    if (m_node-&gt;op() == PutByVal || m_node-&gt;op() == PutByValDirect) {
+                        HeapLocation heap;
+                        
+                        Node* base = m_graph.varArgChild(m_node, 0).node();
+                        Node* index = m_graph.varArgChild(m_node, 1).node();
+                        
+                        ArrayMode mode = m_node-&gt;arrayMode();
+                        switch (mode.type()) {
+                        case Array::Int32:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, IndexedInt32Properties, base, index);
+                            break;
+                            
+                        case Array::Double:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, IndexedDoubleProperties, base, index);
+                            break;
+                            
+                        case Array::Contiguous:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, IndexedContiguousProperties, base, index);
+                            break;
+                            
+                        case Array::Int8Array:
+                        case Array::Int16Array:
+                        case Array::Int32Array:
+                        case Array::Uint8Array:
+                        case Array::Uint8ClampedArray:
+                        case Array::Uint16Array:
+                        case Array::Uint32Array:
+                        case Array::Float32Array:
+                        case Array::Float64Array:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, TypedArrayProperties, base, index);
+                            break;
+                            
+                        default:
+                            break;
+                        }
</ins><span class="cx"> 
</span><del>-            switch (node-&gt;op()) {
-            case CheckStructure:
-                if (node-&gt;child1() == child1
-                    &amp;&amp; node-&gt;structureSet().isSubsetOf(StructureSet(structure)))
-                    return true;
-                break;
-                
-            case PutStructure:
-                ASSERT(node-&gt;transition()-&gt;previous != structure);
-                break;
-                
-            case PutByOffset:
-                // Setting a property cannot change the structure.
-                break;
-                    
-            case MultiPutByOffset:
-                if (node-&gt;multiPutByOffsetData().writesStructures())
-                    return false;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return false;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our structures.
-                // But that seems like it would take Effort.
-                return false;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return false;
-                break;
-            }
-        }
-        return false;
-    }
-    
-    Node* getByOffsetLoadElimination(unsigned identifierNumber, Node* base)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == base)
-                break;
</del><ins>+                        if (!!heap &amp;&amp; m_maps.findReplacement(heap))
+                            m_node-&gt;setOp(PutByValAlias);
+                    }
</ins><span class="cx"> 
</span><del>-            switch (node-&gt;op()) {
-            case GetByOffset:
-                if (node-&gt;child2() == base
-                    &amp;&amp; m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber == identifierNumber)
-                    return node;
-                break;
-                
-            case MultiGetByOffset:
-                if (node-&gt;child1() == base
-                    &amp;&amp; node-&gt;multiGetByOffsetData().identifierNumber == identifierNumber)
-                    return node;
-                break;
-                
-            case PutByOffset:
-                if (m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber == identifierNumber) {
-                    if (node-&gt;child2() == base) // Must be same property storage.
-                        return node-&gt;child3().node();
-                    return 0;
</del><ins>+                    clobberize(m_graph, m_node, *this);
</ins><span class="cx">                 }
</span><del>-                break;
-                
-            case MultiPutByOffset:
-                if (node-&gt;multiPutByOffsetData().identifierNumber == identifierNumber) {
-                    if (node-&gt;child1() == base)
-                        return node-&gt;child2().node();
-                    return 0;
-                }
-                break;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
</del><span class="cx">             }
</span><ins>+        
+            return m_changed;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* getGetterSetterByOffsetLoadElimination(unsigned identifierNumber, Node* base)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == base)
-                break;
</del><ins>+        void read(AbstractHeap) { }
+    
+        void write(AbstractHeap heap)
+        {
+            m_maps.write(heap);
+        }
+        
+        void def(PureValue value)
+        {
+            Node* match = m_maps.addPure(value, m_node);
+            if (!match)
+                return;
</ins><span class="cx"> 
</span><del>-            switch (node-&gt;op()) {
-            case GetGetterSetterByOffset:
-                if (node-&gt;child2() == base
-                    &amp;&amp; m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber == identifierNumber)
-                    return node;
-                break;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
</del><ins>+            m_node-&gt;replaceWith(match);
+            m_changed = true;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    Node* getPropertyStorageLoadElimination(Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
-
-            switch (node-&gt;op()) {
-            case GetButterfly:
-                if (node-&gt;child1() == child1)
-                    return node;
-                break;
-
-            case AllocatePropertyStorage:
-            case ReallocatePropertyStorage:
-                // If we can cheaply prove this is a change to our object's storage, we
-                // can optimize and use its result.
-                if (node-&gt;child1() == child1)
-                    return node;
-                // Otherwise, we currently can't prove that this doesn't change our object's
-                // storage, so we conservatively assume that it may change the storage
-                // pointer of any object, including ours.
-                return 0;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our butterfly.
-                // But that seems like it would take Effort.
-                return 0;
-                
-            case MultiPutByOffset:
-                if (node-&gt;multiPutByOffsetData().reallocatesStorage())
-                    return 0;
-                break;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
</del><ins>+        void def(HeapLocation location, Node* value)
+        {
+            Node* match = m_maps.addImpure(location, value);
+            if (!match)
+                return;
+        
+            if (m_node-&gt;op() == GetLocal) {
+                // For uncaptured locals, usually the CPS rethreading phase does this. But it's OK
+                // for us to mess with locals - regardless of their capturedness - so long as:
+                // 
+                // - We dethread the graph. Any changes we make may invalidate the assumptions of
+                //   our CPS form, particularly if this GetLocal is linked to the variablesAtTail.
+                //
+                // - We don't introduce a Phantom for the child of the GetLocal. This wouldn't be
+                //   totally wrong but it would pessimize the code. Just because there is a
+                //   GetLocal doesn't mean that the child was live. Simply rerouting the all uses
+                //   of this GetLocal will preserve the live-at-exit information just fine.
+                //
+                // We accomplish the latter by just clearing the child; then the Phantom that we
+                // introduce won't have children and so it will eventually just be deleted.
+            
+                m_node-&gt;child1() = Edge();
+                m_graph.dethread();
</ins><span class="cx">             }
</span><ins>+        
+            m_node-&gt;replaceWith(match);
+            m_changed = true;
</ins><span class="cx">         }
</span><del>-        return 0;
-    }
</del><span class="cx">     
</span><del>-    bool checkArrayElimination(Node* child1, ArrayMode arrayMode)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
</del><ins>+    private:
+        Graph&amp; m_graph;
+        
+        bool m_changed;
+        Node* m_node;
+    
+        Maps m_maps;
+    };
</ins><span class="cx"> 
</span><del>-            switch (node-&gt;op()) {
-            case CheckArray:
-                if (node-&gt;child1() == child1 &amp;&amp; node-&gt;arrayMode() == arrayMode)
-                    return true;
-                break;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our array.
-                // But that seems like it would take Effort.
-                return false;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return false;
-                break;
-            }
-        }
-        return false;
-    }
</del><ins>+    BlockCSE&lt;SmallMaps&gt; m_smallBlock;
+    BlockCSE&lt;LargeMaps&gt; m_largeBlock;
+};
</ins><span class="cx"> 
</span><del>-    Node* getIndexedPropertyStorageLoadElimination(Node* child1, ArrayMode arrayMode)
</del><ins>+class GlobalCSEPhase : public Phase {
+public:
+    GlobalCSEPhase(Graph&amp; graph)
+        : Phase(graph, &quot;global common subexpression elimination&quot;)
</ins><span class="cx">     {
</span><del>-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
-
-            switch (node-&gt;op()) {
-            case GetIndexedPropertyStorage: {
-                if (node-&gt;child1() == child1 &amp;&amp; node-&gt;arrayMode() == arrayMode)
-                    return node;
-                break;
-            }
-
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
-        }
-        return 0;
</del><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* getInternalFieldLoadElimination(NodeType op, Node* child1)
</del><ins>+    bool run()
</ins><span class="cx">     {
</span><del>-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node == child1) 
-                break;
</del><ins>+        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
+        ASSERT(m_graph.m_form == SSA);
+        
+        m_graph.initializeNodeOwners();
+        m_graph.m_dominators.computeIfNecessary(m_graph);
+        
+        m_graph.getBlocksInPreOrder(m_preOrder);
+        
+        m_impureDataMap.resize(m_graph.numBlocks());
+        
+        // First figure out what gets clobbered by blocks. Node that this uses the preOrder list
+        // for convenience only.
+        for (unsigned i = m_preOrder.size(); i--;) {
+            m_block = m_preOrder[i];
+            m_impureData = &amp;m_impureDataMap[m_block-&gt;index];
+            for (unsigned nodeIndex = m_block-&gt;size(); nodeIndex--;)
+                addWrites(m_graph, m_block-&gt;at(nodeIndex), m_impureData-&gt;writes);
+        }
+        
+        // Based on my experience doing this before, what follows might have to be made iterative.
+        // Right now it doesn't have to be iterative because everything is dominator-bsed. But when
+        // validation is enabled, we check if iterating would find new CSE opportunities.
</ins><span class="cx"> 
</span><del>-            if (node-&gt;op() == op &amp;&amp; node-&gt;child1() == child1)
-                return node;
-
-            if (m_graph.clobbersWorld(node))
-                return 0;
</del><ins>+        bool changed = iterate();
+        
+        // Iterating a second time should not find new CSE opportunities, unless we have a bug.
+        if (validationEnabled()) {
+            reset();
+            DFG_ASSERT(m_graph, nullptr, !iterate());
</ins><span class="cx">         }
</span><del>-        return 0;
</del><ins>+        
+        return changed;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* getMyScopeLoadElimination()
</del><ins>+    void reset()
</ins><span class="cx">     {
</span><del>-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case CreateActivation:
-                // This may cause us to return a different scope.
-                return 0;
-            case GetMyScope:
-                return node;
-            default:
-                break;
-            }
-        }
-        return 0;
-    }
-    
-    Node* getLocalLoadElimination(VirtualRegister local, Node*&amp; relevantLocalOp, bool careAboutClobbering)
-    {
-        relevantLocalOp = 0;
</del><ins>+        m_pureValues.clear();
</ins><span class="cx">         
</span><del>-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetLocal:
-                if (node-&gt;local() == local) {
-                    relevantLocalOp = node;
-                    return node;
-                }
-                break;
-                
-            case GetLocalUnlinked:
-                if (node-&gt;unlinkedLocal() == local) {
-                    relevantLocalOp = node;
-                    return node;
-                }
-                break;
-                
-            case SetLocal:
-                if (node-&gt;local() == local) {
-                    relevantLocalOp = node;
-                    return node-&gt;child1().node();
-                }
-                break;
-                
-            case GetClosureVar:
-            case PutClosureVar:
-                if (static_cast&lt;VirtualRegister&gt;(node-&gt;varNumber()) == local)
-                    return 0;
-                break;
-                
-            default:
-                if (careAboutClobbering &amp;&amp; m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
</del><ins>+        for (unsigned i = m_impureDataMap.size(); i--;) {
+            m_impureDataMap[i].availableAtTail.clear();
+            m_impureDataMap[i].didVisit = false;
</ins><span class="cx">         }
</span><del>-        return 0;
</del><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* uncapturedSetLocalStoreElimination(VirtualRegister local)
</del><ins>+    bool iterate()
</ins><span class="cx">     {
</span><del>-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetLocal:
-            case Flush:
-                if (node-&gt;local() == local)
-                    return nullptr;
-                break;
-                
-            case GetLocalUnlinked:
-                if (node-&gt;unlinkedLocal() == local)
-                    return nullptr;
-                break;
-                
-            case SetLocal: {
-                if (node-&gt;local() != local)
-                    break;
-                return node;
-            }
-                
-            case GetClosureVar:
-            case PutClosureVar:
-                if (static_cast&lt;VirtualRegister&gt;(node-&gt;varNumber()) == local)
-                    return nullptr;
-                break;
-                
-            case GetMyScope:
-            case SkipTopScope:
-                if (node-&gt;origin.semantic.inlineCallFrame)
-                    break;
-                if (m_graph.uncheckedActivationRegister() == local)
-                    return nullptr;
-                break;
-                
-            case CheckArgumentsNotCreated:
-            case GetMyArgumentsLength:
-            case GetMyArgumentsLengthSafe:
-                if (m_graph.uncheckedArgumentsRegisterFor(node-&gt;origin.semantic) == local)
-                    return nullptr;
-                break;
-                
-            case GetMyArgumentByVal:
-            case GetMyArgumentByValSafe:
-                return nullptr;
-                
-            case GetByVal:
-                // If this is accessing arguments then it's potentially accessing locals.
-                if (node-&gt;arrayMode().type() == Array::Arguments)
-                    return nullptr;
-                break;
-                
-            case CreateArguments:
-            case TearOffActivation:
-            case TearOffArguments:
-                // If an activation is being torn off then it means that captured variables
-                // are live. We could be clever here and check if the local qualifies as an
-                // argument register. But that seems like it would buy us very little since
-                // any kind of tear offs are rare to begin with.
-                return nullptr;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node))
-                return nullptr;
-        }
-        return nullptr;
-    }
</del><ins>+        if (verbose)
+            dataLog(&quot;Performing iteration.\n&quot;);
+        
+        m_changed = false;
+        m_graph.clearReplacements();
+        
+        for (unsigned i = 0; i &lt; m_preOrder.size(); ++i) {
+            m_block = m_preOrder[i];
+            m_impureData = &amp;m_impureDataMap[m_block-&gt;index];
+            m_writesSoFar.clear();
+            
+            if (verbose)
+                dataLog(&quot;Processing block &quot;, *m_block, &quot;:\n&quot;);
</ins><span class="cx"> 
</span><del>-    Node* capturedSetLocalStoreElimination(VirtualRegister local)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            switch (node-&gt;op()) {
-            case GetLocal:
-            case Flush:
-                if (node-&gt;local() == local)
-                    return nullptr;
-                break;
</del><ins>+            for (unsigned nodeIndex = 0; nodeIndex &lt; m_block-&gt;size(); ++nodeIndex) {
+                m_node = m_block-&gt;at(nodeIndex);
+                if (verbose)
+                    dataLog(&quot;  Looking at node &quot;, m_node, &quot;:\n&quot;);
</ins><span class="cx">                 
</span><del>-            case GetLocalUnlinked:
-                if (node-&gt;unlinkedLocal() == local)
-                    return nullptr;
-                break;
</del><ins>+                m_graph.performSubstitution(m_node);
</ins><span class="cx">                 
</span><del>-            case SetLocal: {
-                if (node-&gt;local() != local)
-                    break;
-                return node;
</del><ins>+                if (m_node-&gt;op() == Identity) {
+                    m_node-&gt;convertToCheck();
+                    m_node-&gt;replacement = m_node-&gt;child1().node();
+                    m_changed = true;
+                } else
+                    clobberize(m_graph, m_node, *this);
</ins><span class="cx">             }
</span><del>-                
-            case Phantom:
-            case Check:
-            case HardPhantom:
-            case MovHint:
-            case JSConstant:
-            case DoubleConstant:
-            case Int52Constant:
-                break;
-                
-            default:
-                return nullptr;
-            }
</del><ins>+            
+            m_impureData-&gt;didVisit = true;
</ins><span class="cx">         }
</span><del>-        return nullptr;
</del><ins>+        
+        return m_changed;
</ins><span class="cx">     }
</span><ins>+
+    void read(AbstractHeap) { }
</ins><span class="cx">     
</span><del>-    Node* setLocalStoreElimination(VariableAccessData* variableAccessData)
</del><ins>+    void write(AbstractHeap heap)
</ins><span class="cx">     {
</span><del>-        if (variableAccessData-&gt;isCaptured())
-            return capturedSetLocalStoreElimination(variableAccessData-&gt;local());
-        return uncapturedSetLocalStoreElimination(variableAccessData-&gt;local());
</del><ins>+        clobber(m_impureData-&gt;availableAtTail, heap);
+        m_writesSoFar.add(heap);
+        if (verbose)
+            dataLog(&quot;    Clobbered, new tail map: &quot;, mapDump(m_impureData-&gt;availableAtTail), &quot;\n&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool invalidationPointElimination()
</del><ins>+    void def(PureValue value)
</ins><span class="cx">     {
</span><del>-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock-&gt;at(i);
-            if (node-&gt;op() == InvalidationPoint)
-                return true;
-            if (writesOverlap(m_graph, node, Watchpoint_fire))
-                break;
</del><ins>+        // With pure values we do not have to worry about the possibility of some control flow path
+        // clobbering the value. So, we just search for all of the like values that have been
+        // computed. We pick one that is in a block that dominates ours. Note that this means that
+        // a PureValue will map to a list of nodes, since there may be many places in the control
+        // flow graph that compute a value but only one of them that dominates us. we may build up
+        // a large list of nodes that compute some value in the case of gnarly control flow. This
+        // is probably OK.
+        
+        auto result = m_pureValues.add(value, Vector&lt;Node*&gt;());
+        if (result.isNewEntry) {
+            result.iterator-&gt;value.append(m_node);
+            return;
</ins><span class="cx">         }
</span><del>-        return false;
-    }
-    
-    void eliminateIrrelevantPhantomChildren(Node* node)
-    {
-        ASSERT(node-&gt;op() == Phantom);
-        for (unsigned i = 0; i &lt; AdjacencyList::Size; ++i) {
-            Edge edge = node-&gt;children.child(i);
-            if (!edge)
-                continue;
-            if (edge.useKind() != UntypedUse)
-                continue; // Keep the type check.
-            if (edge-&gt;flags() &amp; NodeRelevantToOSR)
-                continue;
-            
-            node-&gt;children.removeEdge(i--);
-            m_changed = true;
-        }
-    }
-    
-    bool setReplacement(Node* replacement)
-    {
-        if (!replacement)
-            return false;
</del><span class="cx">         
</span><del>-        if (!ASSERT_DISABLED
-            &amp;&amp; canonicalResultRepresentation(m_currentNode-&gt;result()) != canonicalResultRepresentation(replacement-&gt;result())) {
-            startCrashing();
-            dataLog(&quot;CSE attempting to replace a node with a mismatched result: &quot;, m_currentNode, &quot; with &quot;, replacement, &quot;\n&quot;);
-            dataLog(&quot;\n&quot;);
-            m_graph.dump();
-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+        for (unsigned i = result.iterator-&gt;value.size(); i--;) {
+            Node* candidate = result.iterator-&gt;value[i];
+            if (m_graph.m_dominators.dominates(candidate-&gt;owner, m_block)) {
+                m_node-&gt;replaceWith(candidate);
+                m_changed = true;
+                return;
+            }
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        m_currentNode-&gt;convertToPhantom();
-        eliminateIrrelevantPhantomChildren(m_currentNode);
-        
-        // At this point we will eliminate all references to this node.
-        m_currentNode-&gt;misc.replacement = replacement;
-        
-        m_changed = true;
-        
-        return true;
</del><ins>+        result.iterator-&gt;value.append(m_node);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void eliminate()
</del><ins>+    Node* findReplacement(HeapLocation location)
</ins><span class="cx">     {
</span><del>-        ASSERT(m_currentNode-&gt;mustGenerate());
-        m_currentNode-&gt;convertToPhantom();
-        eliminateIrrelevantPhantomChildren(m_currentNode);
</del><ins>+        // At this instant, our &quot;availableAtTail&quot; reflects the set of things that are available in
+        // this block so far. We check this map to find block-local CSE opportunities before doing
+        // a global search.
+        Node* match = m_impureData-&gt;availableAtTail.get(location);
+        if (match) {
+            if (verbose)
+                dataLog(&quot;      Found local match: &quot;, match, &quot;\n&quot;);
+            return match;
+        }
</ins><span class="cx">         
</span><del>-        m_changed = true;
-    }
-    
-    void eliminate(Node* node, NodeType phantomType = Phantom)
-    {
-        if (!node)
-            return;
-        ASSERT(node-&gt;mustGenerate());
-        node-&gt;setOpAndDefaultFlags(phantomType);
-        if (phantomType == Phantom)
-            eliminateIrrelevantPhantomChildren(node);
</del><ins>+        // If it's not available at this point in the block, and at some prior point in the block
+        // we have clobbered this heap location, then there is no point in doing a global search.
+        if (m_writesSoFar.overlaps(location.heap())) {
+            if (verbose)
+                dataLog(&quot;      Not looking globally because of local clobber: &quot;, m_writesSoFar, &quot;\n&quot;);
+            return nullptr;
+        }
</ins><span class="cx">         
</span><del>-        m_changed = true;
-    }
-    
-    void performNodeCSE(Node* node)
-    {
-        m_graph.performSubstitution(node);
</del><ins>+        // This perfoms a backward search over the control flow graph to find some possible
+        // non-local def() that matches our heap location. Such a match is only valid if there does
+        // not exist any path from that def() to our block that contains a write() that overlaps
+        // our heap. This algorithm looks for both of these things (the matching def and the
+        // overlapping writes) in one backwards DFS pass.
+        //
+        // This starts by looking at the starting block's predecessors, and then it continues along
+        // their predecessors. As soon as this finds a possible def() - one that defines the heap
+        // location we want while dominating our starting block - it assumes that this one must be
+        // the match. It then lets the DFS over predecessors complete, but it doesn't add the
+        // def()'s predecessors; this ensures that any blocks we visit thereafter are on some path
+        // from the def() to us. As soon as the DFG finds a write() that overlaps the location's
+        // heap, it stops, assuming that there is no possible match. Note that the write() case may
+        // trigger before we find a def(), or after. Either way, the write() case causes this
+        // function to immediately return nullptr.
+        //
+        // If the write() is found before we find the def(), then we know that any def() we would
+        // find would have a path to us that trips over the write() and hence becomes invalid. This
+        // is just a direct outcome of us looking for a def() that dominates us. Given a block A
+        // that dominates block B - so that A is the one that would have the def() and B is our
+        // starting block - we know that any other block must either be on the path from A to B, or
+        // it must be on a path from the root to A, but not both. So, if we haven't found A yet but
+        // we already have found a block C that has a write(), then C must be on some path from A
+        // to B, which means that A's def() is invalid for our purposes. Hence, before we find the
+        // def(), stopping on write() is the right thing to do.
+        //
+        // Stopping on write() is also the right thing to do after we find the def(). After we find
+        // the def(), we don't add that block's predecessors to the search worklist. That means
+        // that henceforth the only blocks we will see in the search are blocks on the path from
+        // the def() to us. If any such block has a write() that clobbers our heap then we should
+        // give up.
+        //
+        // Hence this graph search algorithm ends up being deceptively simple: any overlapping
+        // write() causes us to immediately return nullptr, and a matching def() means that we just
+        // record it and neglect to visit its precessors.
</ins><span class="cx">         
</span><del>-        switch (node-&gt;op()) {
</del><ins>+        Vector&lt;BasicBlock*, 8&gt; worklist;
+        Vector&lt;BasicBlock*, 8&gt; seenList;
+        BitVector seen;
</ins><span class="cx">         
</span><del>-        case Identity:
-            setReplacement(node-&gt;child1().node());
-            break;
-            
-        // Handle the pure nodes. These nodes never have any side-effects.
-        case BitAnd:
-        case BitOr:
-        case BitXor:
-        case BitRShift:
-        case BitLShift:
-        case BitURShift:
-        case ArithAbs:
-        case ArithMin:
-        case ArithMax:
-        case ArithSqrt:
-        case ArithFRound:
-        case ArithSin:
-        case ArithCos:
-        case StringCharAt:
-        case StringCharCodeAt:
-        case IsUndefined:
-        case IsBoolean:
-        case IsNumber:
-        case IsString:
-        case IsObject:
-        case IsFunction:
-        case LogicalNot:
-        case SkipTopScope:
-        case SkipScope:
-        case GetClosureRegisters:
-        case GetScope:
-        case TypeOf:
-        case CompareEqConstant:
-        case ValueToInt32:
-        case MakeRope:
-        case DoubleRep:
-        case ValueRep:
-        case Int52Rep:
-        case BooleanToNumber:
-            setReplacement(pureCSE(node));
-            break;
-            
-        case ArithAdd:
-        case ArithSub:
-        case ArithNegate:
-        case ArithMul:
-        case ArithDiv:
-        case ArithMod:
-        case UInt32ToNumber:
-        case DoubleAsInt32: {
-            Node* candidate = pureCSE(node);
-            if (!candidate)
-                break;
-            if (!subsumes(candidate-&gt;arithMode(), node-&gt;arithMode())) {
-                if (!subsumes(node-&gt;arithMode(), candidate-&gt;arithMode()))
-                    break;
-                candidate-&gt;setArithMode(node-&gt;arithMode());
</del><ins>+        for (unsigned i = m_block-&gt;predecessors.size(); i--;) {
+            BasicBlock* predecessor = m_block-&gt;predecessors[i];
+            if (!seen.get(predecessor-&gt;index)) {
+                worklist.append(predecessor);
+                seen.set(predecessor-&gt;index);
</ins><span class="cx">             }
</span><del>-            setReplacement(candidate);
-            break;
</del><span class="cx">         }
</span><ins>+        
+        while (!worklist.isEmpty()) {
+            BasicBlock* block = worklist.takeLast();
+            seenList.append(block);
</ins><span class="cx">             
</span><del>-        case GetCallee:
-            setReplacement(getCalleeLoadElimination());
-            break;
-
-        case GetLocal: {
-            VariableAccessData* variableAccessData = node-&gt;variableAccessData();
-            if (!variableAccessData-&gt;isCaptured())
-                break;
-            Node* relevantLocalOp;
-            Node* possibleReplacement = getLocalLoadElimination(variableAccessData-&gt;local(), relevantLocalOp, variableAccessData-&gt;isCaptured());
-            if (!relevantLocalOp)
-                break;
-            if (relevantLocalOp-&gt;op() != GetLocalUnlinked
-                &amp;&amp; relevantLocalOp-&gt;variableAccessData() != variableAccessData)
-                break;
-            Node* phi = node-&gt;child1().node();
-            if (!setReplacement(possibleReplacement))
-                break;
</del><ins>+            if (verbose)
+                dataLog(&quot;      Searching in block &quot;, *block, &quot;\n&quot;);
+            ImpureBlockData&amp; data = m_impureDataMap[block-&gt;index];
</ins><span class="cx">             
</span><del>-            m_graph.dethread();
-            
-            // If we replace a GetLocal with a GetLocalUnlinked, then turn the GetLocalUnlinked
-            // into a GetLocal.
-            if (relevantLocalOp-&gt;op() == GetLocalUnlinked)
-                relevantLocalOp-&gt;convertToGetLocal(variableAccessData, phi);
-
-            m_changed = true;
-            break;
-        }
-            
-        case GetLocalUnlinked: {
-            Node* relevantLocalOpIgnored;
-            setReplacement(getLocalLoadElimination(node-&gt;unlinkedLocal(), relevantLocalOpIgnored, true));
-            break;
-        }
-            
-        case JSConstant:
-        case DoubleConstant:
-        case Int52Constant:
-            // This is strange, but necessary. Some phases will convert nodes to constants,
-            // which may result in duplicated constants. We use CSE to clean this up.
-            setReplacement(constantCSE(node));
-            break;
-            
-        case ConstantStoragePointer:
-            setReplacement(constantStoragePointerCSE(node));
-            break;
-            
-        case GetArrayLength:
-            setReplacement(getArrayLengthElimination(node-&gt;child1().node()));
-            break;
-
-        case GetMyScope:
-            setReplacement(getMyScopeLoadElimination());
-            break;
-            
-        // Handle nodes that are conditionally pure: these are pure, and can
-        // be CSE'd, so long as the prediction is the one we want.
-        case CompareLess:
-        case CompareLessEq:
-        case CompareGreater:
-        case CompareGreaterEq:
-        case CompareEq: {
-            if (m_graph.isPredictedNumerical(node)) {
-                Node* replacement = pureCSE(node);
-                if (replacement &amp;&amp; m_graph.isPredictedNumerical(replacement))
-                    setReplacement(replacement);
</del><ins>+            // We require strict domination because this would only see things in our own block if
+            // they came *after* our position in the block. Clearly, while our block dominates
+            // itself, the things in the block after us don't dominate us.
+            if (m_graph.m_dominators.dominates(block, m_block) &amp;&amp; block != m_block) {
+                if (verbose)
+                    dataLog(&quot;        It strictly dominates.\n&quot;);
+                DFG_ASSERT(m_graph, m_node, data.didVisit);
+                DFG_ASSERT(m_graph, m_node, !match);
+                if (verbose)
+                    dataLog(&quot;        Availability map: &quot;, mapDump(data.availableAtTail), &quot;\n&quot;);
+                match = data.availableAtTail.get(location);
+                if (verbose)
+                    dataLog(&quot;        Availability: &quot;, match, &quot;\n&quot;);
+                if (match) {
+                    // Don't examine the predecessors of a match. At this point we just want to
+                    // establish that other blocks on the path from here to there don't clobber
+                    // the location we're interested in.
+                    continue;
+                }
</ins><span class="cx">             }
</span><del>-            break;
-        }
</del><span class="cx">             
</span><del>-        // Finally handle heap accesses. These are not quite pure, but we can still
-        // optimize them provided that some subtle conditions are met.
-        case GetGlobalVar:
-            setReplacement(globalVarLoadElimination(node-&gt;registerPointer()));
-            break;
-
-        case GetClosureVar: {
-            setReplacement(scopedVarLoadElimination(node-&gt;child1().node(), node-&gt;varNumber()));
-            break;
-        }
-
-        case VarInjectionWatchpoint:
-            if (varInjectionWatchpointElimination())
-                eliminate();
-            break;
-            
-        case GetByVal:
-            if (m_graph.byValIsPure(node))
-                setReplacement(getByValLoadElimination(node-&gt;child1().node(), node-&gt;child2().node(), node-&gt;arrayMode()));
-            break;
-                
-        case PutByValDirect:
-        case PutByVal: {
-            Edge child1 = m_graph.varArgChild(node, 0);
-            Edge child2 = m_graph.varArgChild(node, 1);
-            if (node-&gt;arrayMode().canCSEStorage()) {
-                Node* replacement = getByValLoadElimination(child1.node(), child2.node(), node-&gt;arrayMode());
-                if (!replacement)
-                    break;
-                node-&gt;setOp(PutByValAlias);
</del><ins>+            if (verbose)
+                dataLog(&quot;        Dealing with write set &quot;, data.writes, &quot;\n&quot;);
+            if (data.writes.overlaps(location.heap())) {
+                if (verbose)
+                    dataLog(&quot;        Clobbered.\n&quot;);
+                return nullptr;
</ins><span class="cx">             }
</span><del>-            break;
-        }
</del><span class="cx">             
</span><del>-        case CheckStructure:
-            if (checkStructureElimination(node-&gt;structureSet(), node-&gt;child1().node()))
-                eliminate();
-            break;
-            
-        case CheckFunction:
-            if (checkFunctionElimination(node-&gt;function(), node-&gt;child1().node()))
-                eliminate();
-            break;
-                
-        case CheckExecutable:
-            if (checkExecutableElimination(node-&gt;executable(), node-&gt;child1().node()))
-                eliminate();
-            break;
-                
-        case CheckArray:
-            if (checkArrayElimination(node-&gt;child1().node(), node-&gt;arrayMode()))
-                eliminate();
-            break;
-            
-        case GetIndexedPropertyStorage: {
-            setReplacement(getIndexedPropertyStorageLoadElimination(node-&gt;child1().node(), node-&gt;arrayMode()));
-            break;
-        }
-            
-        case GetTypedArrayByteOffset:
-        case GetGetter:
-        case GetSetter: {
-            setReplacement(getInternalFieldLoadElimination(node-&gt;op(), node-&gt;child1().node()));
-            break;
-        }
-
-        case GetButterfly:
-            setReplacement(getPropertyStorageLoadElimination(node-&gt;child1().node()));
-            break;
-
-        case GetByOffset:
-            setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber, node-&gt;child2().node()));
-            break;
-            
-        case GetGetterSetterByOffset:
-            setReplacement(getGetterSetterByOffsetLoadElimination(m_graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber, node-&gt;child2().node()));
-            break;
-            
-        case MultiGetByOffset:
-            setReplacement(getByOffsetLoadElimination(node-&gt;multiGetByOffsetData().identifierNumber, node-&gt;child1().node()));
-            break;
-            
-        case InvalidationPoint:
-            if (invalidationPointElimination())
-                eliminate();
-            break;
-            
-        case Phantom:
-            // FIXME: we ought to remove Phantom's that have no children.
-            // NB. It would be incorrect to do this for HardPhantom. In fact, the whole point
-            // of HardPhantom is that we *don't* do this for HardPhantoms, since they signify
-            // a more strict kind of liveness than the Phantom bytecode liveness.
-            eliminateIrrelevantPhantomChildren(node);
-            break;
-            
-        case Flush:
-            // This is needed for arguments simplification to work. We need to eliminate the
-            // redundancy between op_enter's undefined-all-the-things and the subsequent
-            // op_init_lazy_reg.
-            
-            ASSERT(m_graph.m_form != SSA);
-            
-            if (Node* setLocal = setLocalStoreElimination(node-&gt;variableAccessData())) {
-                node-&gt;convertToPhantom();
-                Node* dataNode = setLocal-&gt;child1().node();
-                ASSERT(dataNode-&gt;hasResult());
-                node-&gt;child1() = dataNode-&gt;defaultEdge();
-                m_graph.dethread();
-                m_changed = true;
</del><ins>+            for (unsigned i = block-&gt;predecessors.size(); i--;) {
+                BasicBlock* predecessor = block-&gt;predecessors[i];
+                if (!seen.get(predecessor-&gt;index)) {
+                    worklist.append(predecessor);
+                    seen.set(predecessor-&gt;index);
+                }
</ins><span class="cx">             }
</span><del>-            break;
-            
-        default:
-            // do nothing.
-            break;
</del><span class="cx">         }
</span><span class="cx">         
</span><del>-        m_lastSeen[node-&gt;op()] = m_indexInBlock;
</del><ins>+        if (!match)
+            return nullptr;
+        
+        // Cache the results for next time. We cache them both for this block and for all of our
+        // predecessors, since even though we've already visited our predecessors, our predecessors
+        // probably have successors other than us.
+        // FIXME: Consider caching failed searches as well, when match is null. It's not clear that
+        // the reduction in compile time would warrant the increase in complexity, though.
+        // https://bugs.webkit.org/show_bug.cgi?id=134876
+        for (BasicBlock* block : seenList)
+            m_impureDataMap[block-&gt;index].availableAtTail.add(location, match);
+        m_impureData-&gt;availableAtTail.add(location, match);
+        
+        return match;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void performBlockCSE(BasicBlock* block)
</del><ins>+    void def(HeapLocation location, Node* value)
</ins><span class="cx">     {
</span><del>-        if (!block)
-            return;
-        if (!block-&gt;isReachable)
-            return;
</del><ins>+        if (verbose)
+            dataLog(&quot;    Got heap location def: &quot;, location, &quot; -&gt; &quot;, value, &quot;\n&quot;);
</ins><span class="cx">         
</span><del>-        m_currentBlock = block;
-        for (unsigned i = 0; i &lt; LastNodeType; ++i)
-            m_lastSeen[i] = UINT_MAX;
</del><ins>+        Node* match = findReplacement(location);
</ins><span class="cx">         
</span><del>-        for (m_indexInBlock = 0; m_indexInBlock &lt; block-&gt;size(); ++m_indexInBlock) {
-            m_currentNode = block-&gt;at(m_indexInBlock);
-            performNodeCSE(m_currentNode);
</del><ins>+        if (verbose)
+            dataLog(&quot;      Got match: &quot;, match, &quot;\n&quot;);
+        
+        if (!match) {
+            if (verbose)
+                dataLog(&quot;      Adding at-tail mapping: &quot;, location, &quot; -&gt; &quot;, value, &quot;\n&quot;);
+            auto result = m_impureData-&gt;availableAtTail.add(location, value);
+            ASSERT_UNUSED(result, result.isNewEntry);
+            return;
</ins><span class="cx">         }
</span><ins>+        
+        m_node-&gt;replaceWith(match);
+        m_changed = true;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    BasicBlock* m_currentBlock;
-    Node* m_currentNode;
-    unsigned m_indexInBlock;
-    std::array&lt;unsigned, LastNodeType&gt; m_lastSeen;
-    bool m_changed; // Only tracks changes that have a substantive effect on other optimizations.
</del><ins>+    struct ImpureBlockData {
+        ImpureBlockData()
+            : didVisit(false)
+        {
+        }
+        
+        ClobberSet writes;
+        ImpureMap availableAtTail;
+        bool didVisit;
+    };
+    
+    Vector&lt;BasicBlock*&gt; m_preOrder;
+
+    PureMultiMap m_pureValues;
+    Vector&lt;ImpureBlockData&gt; m_impureDataMap;
+    
+    BasicBlock* m_block;
+    Node* m_node;
+    ImpureBlockData* m_impureData;
+    ClobberSet m_writesSoFar;
+    
+    bool m_changed;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-bool performCSE(Graph&amp; graph)
</del><ins>+} // anonymous namespace
+
+bool performLocalCSE(Graph&amp; graph)
</ins><span class="cx"> {
</span><del>-    SamplingRegion samplingRegion(&quot;DFG CSE Phase&quot;);
-    return runPhase&lt;CSEPhase&gt;(graph);
</del><ins>+    SamplingRegion samplingRegion(&quot;DFG LocalCSE Phase&quot;);
+    return runPhase&lt;LocalCSEPhase&gt;(graph);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool performGlobalCSE(Graph&amp; graph)
+{
+    SamplingRegion samplingRegion(&quot;DFG GlobalCSE Phase&quot;);
+    return runPhase&lt;GlobalCSEPhase&gt;(graph);
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span><del>-
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCSEPhaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 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">@@ -34,12 +34,21 @@
</span><span class="cx"> 
</span><span class="cx"> class Graph;
</span><span class="cx"> 
</span><del>-// Block-local common subexpression elimination. This is an optional phase, but
-// it is rather profitable. It has fairly accurate heap modeling and will match
-// a wide range of subexpression similarities. It's known to produce big wins
-// on a few benchmarks, and is relatively cheap to run.
-bool performCSE(Graph&amp;);
</del><ins>+// Block-local common subexpression elimination. It uses clobberize() for heap
+// modeling, which is quite precise. This phase is known to produce big wins on
+// a few benchmarks, and is relatively cheap to run.
+//
+// Note that this phase also gets rid of Identity nodes, which means that it's
+// currently not an optional phase. Basically, DFG IR doesn't have use-lists,
+// so there is no instantaneous replaceAllUsesWith operation. Instead, you turn
+// a node into an Identity and wait for CSE to clean it up.
+bool performLocalCSE(Graph&amp;);
</ins><span class="cx"> 
</span><ins>+// Same, but global. Only works for SSA. This will find common subexpressions
+// both in the same block and in any block that dominates the current block. It
+// has no limits on how far it will look for load-elimination opportunities.
+bool performGlobalCSE(Graph&amp;);
+
</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="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -45,6 +45,12 @@
</span><span class="cx">         &amp;&amp; FunctionWhitelist::ensureGlobalWhitelist().contains(codeBlock);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool isSupportedForInlining(CodeBlock* codeBlock)
+{
+    return !codeBlock-&gt;ownerExecutable()-&gt;needsActivation()
+        &amp;&amp; codeBlock-&gt;ownerExecutable()-&gt;isInliningCandidate();
+}
+
</ins><span class="cx"> bool mightCompileEval(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><span class="cx">     return isSupported(codeBlock)
</span><span class="lines">@@ -69,20 +75,17 @@
</span><span class="cx"> bool mightInlineFunctionForCall(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><span class="cx">     return codeBlock-&gt;instructionCount() &lt;= Options::maximumFunctionForCallInlineCandidateInstructionCount()
</span><del>-        &amp;&amp; !codeBlock-&gt;ownerExecutable()-&gt;needsActivation()
-        &amp;&amp; codeBlock-&gt;ownerExecutable()-&gt;isInliningCandidate();
</del><ins>+        &amp;&amp; isSupportedForInlining(codeBlock);
</ins><span class="cx"> }
</span><span class="cx"> bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><span class="cx">     return codeBlock-&gt;instructionCount() &lt;= Options::maximumFunctionForClosureCallInlineCandidateInstructionCount()
</span><del>-        &amp;&amp; !codeBlock-&gt;ownerExecutable()-&gt;needsActivation()
-        &amp;&amp; codeBlock-&gt;ownerExecutable()-&gt;isInliningCandidate();
</del><ins>+        &amp;&amp; isSupportedForInlining(codeBlock);
</ins><span class="cx"> }
</span><span class="cx"> bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><span class="cx">     return codeBlock-&gt;instructionCount() &lt;= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
</span><del>-        &amp;&amp; !codeBlock-&gt;ownerExecutable()-&gt;needsActivation()
-        &amp;&amp; codeBlock-&gt;ownerExecutable()-&gt;isInliningCandidate();
</del><ins>+        &amp;&amp; isSupportedForInlining(codeBlock);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> // Fast check functions; if they return true it is still necessary to
</span><span class="cx"> // check opcodes.
</span><span class="cx"> bool isSupported(CodeBlock*);
</span><ins>+bool isSupportedForInlining(CodeBlock*);
</ins><span class="cx"> bool mightCompileEval(CodeBlock*);
</span><span class="cx"> bool mightCompileProgram(CodeBlock*);
</span><span class="cx"> bool mightCompileFunctionForCall(CodeBlock*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberSet.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberSet.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberSet.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -122,37 +122,38 @@
</span><span class="cx"> void addReads(Graph&amp; graph, Node* node, ClobberSet&amp; readSet)
</span><span class="cx"> {
</span><span class="cx">     ClobberSetAdd addRead(readSet);
</span><del>-    NoOpClobberize addWrite;
-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    NoOpClobberize noOp;
+    clobberize(graph, node, addRead, noOp, noOp);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void addWrites(Graph&amp; graph, Node* node, ClobberSet&amp; writeSet)
</span><span class="cx"> {
</span><del>-    NoOpClobberize addRead;
</del><ins>+    NoOpClobberize noOp;
</ins><span class="cx">     ClobberSetAdd addWrite(writeSet);
</span><del>-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    clobberize(graph, node, noOp, addWrite, noOp);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void addReadsAndWrites(Graph&amp; graph, Node* node, ClobberSet&amp; readSet, ClobberSet&amp; writeSet)
</span><span class="cx"> {
</span><span class="cx">     ClobberSetAdd addRead(readSet);
</span><span class="cx">     ClobberSetAdd addWrite(writeSet);
</span><del>-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    NoOpClobberize noOp;
+    clobberize(graph, node, addRead, addWrite, noOp);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool readsOverlap(Graph&amp; graph, Node* node, ClobberSet&amp; readSet)
</span><span class="cx"> {
</span><span class="cx">     ClobberSetOverlaps addRead(readSet);
</span><del>-    NoOpClobberize addWrite;
-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    NoOpClobberize noOp;
+    clobberize(graph, node, addRead, noOp, noOp);
</ins><span class="cx">     return addRead.result();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool writesOverlap(Graph&amp; graph, Node* node, ClobberSet&amp; writeSet)
</span><span class="cx"> {
</span><del>-    NoOpClobberize addRead;
</del><ins>+    NoOpClobberize noOp;
</ins><span class="cx">     ClobberSetOverlaps addWrite(writeSet);
</span><del>-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    clobberize(graph, node, noOp, addWrite, noOp);
</ins><span class="cx">     return addWrite.result();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -34,17 +34,25 @@
</span><span class="cx"> 
</span><span class="cx"> bool doesWrites(Graph&amp; graph, Node* node)
</span><span class="cx"> {
</span><del>-    NoOpClobberize addRead;
</del><ins>+    NoOpClobberize noOp;
</ins><span class="cx">     CheckClobberize addWrite;
</span><del>-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    clobberize(graph, node, noOp, addWrite, noOp);
</ins><span class="cx">     return addWrite.result();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool accessesOverlap(Graph&amp; graph, Node* node, AbstractHeap heap)
+{
+    NoOpClobberize noOp;
+    AbstractHeapOverlaps addAccess(heap);
+    clobberize(graph, node, addAccess, addAccess, noOp);
+    return addAccess.result();
+}
+
</ins><span class="cx"> bool writesOverlap(Graph&amp; graph, Node* node, AbstractHeap heap)
</span><span class="cx"> {
</span><del>-    NoOpClobberize addRead;
</del><ins>+    NoOpClobberize noOp;
</ins><span class="cx">     AbstractHeapOverlaps addWrite(heap);
</span><del>-    clobberize(graph, node, addRead, addWrite);
</del><ins>+    clobberize(graph, node, noOp, addWrite, noOp);
</ins><span class="cx">     return addWrite.result();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -31,11 +31,13 @@
</span><span class="cx"> #include &quot;DFGAbstractHeap.h&quot;
</span><span class="cx"> #include &quot;DFGEdgeUsesStructure.h&quot;
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><ins>+#include &quot;DFGHeapLocation.h&quot;
+#include &quot;DFGPureValue.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><del>-template&lt;typename ReadFunctor, typename WriteFunctor&gt;
-void clobberize(Graph&amp; graph, Node* node, ReadFunctor&amp; read, WriteFunctor&amp; write)
</del><ins>+template&lt;typename ReadFunctor, typename WriteFunctor, typename DefFunctor&gt;
+void clobberize(Graph&amp; graph, Node* node, ReadFunctor&amp; read, WriteFunctor&amp; write, DefFunctor&amp; def)
</ins><span class="cx"> {
</span><span class="cx">     // Some notes:
</span><span class="cx">     //
</span><span class="lines">@@ -69,6 +71,29 @@
</span><span class="cx">     //   prior to type inference - though they probably could be if we did some
</span><span class="cx">     //   small hacking.
</span><span class="cx">     
</span><ins>+    // While read() and write() are fairly self-explanatory - they track what sorts of things the
+    // node may read or write - the def() functor is more tricky. It tells you the heap locations
+    // (not just abstract heaps) that are defined by a node. A heap location comprises an abstract
+    // heap, some nodes, and a LocationKind. Briefly, a location defined by a node is a location
+    // whose value can be deduced from looking at the node itself. The locations returned must obey
+    // the following properties:
+    //
+    // - If someone wants to CSE a load from the heap, then a HeapLocation object should be
+    //   sufficient to find a single matching node.
+    //
+    // - The abstract heap is the only abstract heap that could be clobbered to invalidate any such
+    //   CSE attempt. I.e. if clobberize() reports that on every path between some node and a node
+    //   that defines a HeapLocation that it wanted, there were no writes to any abstract heap that
+    //   overlap the location's heap, then we have a sound match. Effectively, the semantics of
+    //   write() and def() are intertwined such that for them to be sound they must agree on what
+    //   is CSEable.
+    //
+    // read(), write(), and def() for heap locations is enough to do GCSE on effectful things. To
+    // keep things simple, this code will also def() pure things. def() must be overloaded to also
+    // accept PureValue. This way, a client of clobberize() can implement GCSE entirely using the
+    // information that clobberize() passes to write() and def(). Other clients of clobberize() can
+    // just ignore def() by using a NoOpClobberize functor.
+
</ins><span class="cx">     if (edgesUseStructure(graph, node))
</span><span class="cx">         read(JSCell_structureID);
</span><span class="cx">     
</span><span class="lines">@@ -76,23 +101,23 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><ins>+        def(PureValue(node, node-&gt;constant()));
+        return;
+        
</ins><span class="cx">     case Identity:
</span><span class="cx">     case Phantom:
</span><span class="cx">     case HardPhantom:
</span><ins>+    case Check:
+    case ExtractOSREntryLocal:
+        return;
+        
</ins><span class="cx">     case BitAnd:
</span><span class="cx">     case BitOr:
</span><span class="cx">     case BitXor:
</span><span class="cx">     case BitLShift:
</span><span class="cx">     case BitRShift:
</span><span class="cx">     case BitURShift:
</span><del>-    case ValueToInt32:
-    case ArithAdd:
-    case ArithSub:
-    case ArithNegate:
-    case ArithMul:
</del><span class="cx">     case ArithIMul:
</span><del>-    case ArithDiv:
-    case ArithMod:
</del><span class="cx">     case ArithAbs:
</span><span class="cx">     case ArithMin:
</span><span class="cx">     case ArithMax:
</span><span class="lines">@@ -102,7 +127,6 @@
</span><span class="cx">     case ArithCos:
</span><span class="cx">     case GetScope:
</span><span class="cx">     case SkipScope:
</span><del>-    case CheckFunction:
</del><span class="cx">     case StringCharCodeAt:
</span><span class="cx">     case StringFromCharCode:
</span><span class="cx">     case CompareEqConstant:
</span><span class="lines">@@ -112,25 +136,44 @@
</span><span class="cx">     case IsNumber:
</span><span class="cx">     case IsString:
</span><span class="cx">     case LogicalNot:
</span><del>-    case ExtractOSREntryLocal:
</del><span class="cx">     case CheckInBounds:
</span><del>-    case ConstantStoragePointer:
-    case UInt32ToNumber:
-    case DoubleAsInt32:
-    case Check:
</del><span class="cx">     case DoubleRep:
</span><span class="cx">     case ValueRep:
</span><span class="cx">     case Int52Rep:
</span><span class="cx">     case BooleanToNumber:
</span><span class="cx">     case FiatInt52:
</span><span class="cx">     case MakeRope:
</span><ins>+    case ValueToInt32:
+        def(PureValue(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><ins>+    case ArithAdd:
+    case ArithSub:
+    case ArithNegate:
+    case ArithMul:
+    case ArithDiv:
+    case ArithMod:
+    case DoubleAsInt32:
+    case UInt32ToNumber:
+        def(PureValue(node, node-&gt;arithMode()));
+        return;
+        
+    case CheckFunction:
+        def(PureValue(CheckFunction, AdjacencyList(AdjacencyList::Fixed, node-&gt;child1()), node-&gt;function()));
+        return;
+        
+    case CheckExecutable:
+        def(PureValue(node, node-&gt;executable()));
+        return;
+        
+    case ConstantStoragePointer:
+        def(PureValue(node, node-&gt;storagePointer()));
+        return;
+         
</ins><span class="cx">     case MovHint:
</span><span class="cx">     case ZombieHint:
</span><span class="cx">     case Upsilon:
</span><span class="cx">     case Phi:
</span><del>-    case Flush:
</del><span class="cx">     case PhantomLocal:
</span><span class="cx">     case SetArgument:
</span><span class="cx">     case PhantomArguments:
</span><span class="lines">@@ -145,7 +188,6 @@
</span><span class="cx">     case CheckTierUpAtReturn:
</span><span class="cx">     case CheckTierUpAndOSREnter:
</span><span class="cx">     case LoopHint:
</span><del>-    case InvalidationPoint:
</del><span class="cx">     case Breakpoint:
</span><span class="cx">     case ProfileWillCall:
</span><span class="cx">     case ProfileDidCall:
</span><span class="lines">@@ -154,6 +196,16 @@
</span><span class="cx">         write(SideState);
</span><span class="cx">         return;
</span><span class="cx">         
</span><ins>+    case InvalidationPoint:
+        write(SideState);
+        def(HeapLocation(InvalidationPointLoc, Watchpoint_fire), node);
+        return;
+
+    case Flush:
+        read(AbstractHeap(Variables, node-&gt;local()));
+        write(SideState);
+        return;
+
</ins><span class="cx">     case VariableWatchpoint:
</span><span class="cx">     case TypedArrayWatchpoint:
</span><span class="cx">         read(Watchpoint_fire);
</span><span class="lines">@@ -166,13 +218,20 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case CreateActivation:
</span><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        write(SideState);
+        write(Watchpoint_fire);
+        return;
+        
</ins><span class="cx">     case CreateArguments:
</span><ins>+        read(Variables);
</ins><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         write(SideState);
</span><span class="cx">         write(Watchpoint_fire);
</span><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case FunctionReentryWatchpoint:
</span><span class="cx">         read(Watchpoint_fire);
</span><span class="cx">         return;
</span><span class="lines">@@ -185,13 +244,30 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case VarInjectionWatchpoint:
</span><ins>+        read(MiscFields);
+        def(HeapLocation(VarInjectionWatchpointLoc, MiscFields), node);
+        return;
+
</ins><span class="cx">     case AllocationProfileWatchpoint:
</span><ins>+        read(MiscFields);
+        def(HeapLocation(AllocationProfileWatchpointLoc, MiscFields), node);
+        return;
+        
</ins><span class="cx">     case IsObject:
</span><ins>+        read(MiscFields);
+        def(HeapLocation(IsObjectLoc, MiscFields, node-&gt;child1()), node);
+        return;
+        
</ins><span class="cx">     case IsFunction:
</span><ins>+        read(MiscFields);
+        def(HeapLocation(IsFunctionLoc, MiscFields, node-&gt;child1()), node);
+        return;
+        
</ins><span class="cx">     case TypeOf:
</span><span class="cx">         read(MiscFields);
</span><ins>+        def(HeapLocation(TypeOfLoc, MiscFields, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case GetById:
</span><span class="cx">     case GetByIdFlush:
</span><span class="cx">     case PutById:
</span><span class="lines">@@ -214,27 +290,33 @@
</span><span class="cx">         
</span><span class="cx">     case GetGetter:
</span><span class="cx">         read(GetterSetter_getter);
</span><ins>+        def(HeapLocation(GetterLoc, GetterSetter_getter, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetSetter:
</span><span class="cx">         read(GetterSetter_setter);
</span><ins>+        def(HeapLocation(SetterLoc, GetterSetter_setter, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetCallee:
</span><span class="cx">         read(AbstractHeap(Variables, JSStack::Callee));
</span><ins>+        def(HeapLocation(VariableLoc, AbstractHeap(Variables, JSStack::Callee)), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetLocal:
</span><span class="cx">     case GetArgument:
</span><span class="cx">         read(AbstractHeap(Variables, node-&gt;local()));
</span><ins>+        def(HeapLocation(VariableLoc, AbstractHeap(Variables, node-&gt;local())), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case SetLocal:
</span><span class="cx">         write(AbstractHeap(Variables, node-&gt;local()));
</span><ins>+        def(HeapLocation(VariableLoc, AbstractHeap(Variables, node-&gt;local())), node-&gt;child1().node());
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetLocalUnlinked:
</span><span class="cx">         read(AbstractHeap(Variables, node-&gt;unlinkedLocal()));
</span><ins>+        def(HeapLocation(VariableLoc, AbstractHeap(Variables, node-&gt;unlinkedLocal())), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetByVal: {
</span><span class="lines">@@ -264,18 +346,20 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             // This appears to read nothing because it's only reading immutable data.
</span><ins>+            def(PureValue(node, mode.asWord()));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Arguments:
</span><span class="cx">             read(Arguments_registers);
</span><span class="cx">             read(Variables);
</span><ins>+            def(HeapLocation(IndexedPropertyLoc, Variables, node-&gt;child1(), node-&gt;child2()), node);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Int32:
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><del>-                read(Butterfly_vectorLength);
</del><span class="cx">                 read(IndexedInt32Properties);
</span><ins>+                def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, node-&gt;child1(), node-&gt;child2()), node);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><span class="lines">@@ -285,8 +369,8 @@
</span><span class="cx">         case Array::Double:
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><del>-                read(Butterfly_vectorLength);
</del><span class="cx">                 read(IndexedDoubleProperties);
</span><ins>+                def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, node-&gt;child1(), node-&gt;child2()), node);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><span class="lines">@@ -296,8 +380,8 @@
</span><span class="cx">         case Array::Contiguous:
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><del>-                read(Butterfly_vectorLength);
</del><span class="cx">                 read(IndexedContiguousProperties);
</span><ins>+                def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, node-&gt;child1(), node-&gt;child2()), node);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><span class="lines">@@ -306,7 +390,11 @@
</span><span class="cx">             
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">         case Array::SlowPutArrayStorage:
</span><del>-            // Give up on life for now.
</del><ins>+            if (mode.isInBounds()) {
+                read(Butterfly_vectorLength);
+                read(IndexedArrayStorageProperties);
+                return;
+            }
</ins><span class="cx">             read(World);
</span><span class="cx">             write(World);
</span><span class="cx">             return;
</span><span class="lines">@@ -321,8 +409,8 @@
</span><span class="cx">         case Array::Float32Array:
</span><span class="cx">         case Array::Float64Array:
</span><span class="cx">             read(TypedArrayProperties);
</span><del>-            read(JSArrayBufferView_vector);
-            read(JSArrayBufferView_length);
</del><ins>+            read(MiscFields);
+            def(HeapLocation(IndexedPropertyLoc, TypedArrayProperties, node-&gt;child1(), node-&gt;child2()), node);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -333,6 +421,9 @@
</span><span class="cx">     case PutByVal:
</span><span class="cx">     case PutByValAlias: {
</span><span class="cx">         ArrayMode mode = node-&gt;arrayMode();
</span><ins>+        Node* base = graph.varArgChild(node, 0).node();
+        Node* index = graph.varArgChild(node, 1).node();
+        Node* value = graph.varArgChild(node, 2).node();
</ins><span class="cx">         switch (mode.modeForPut().type()) {
</span><span class="cx">         case Array::SelectUsingPredictions:
</span><span class="cx">         case Array::Unprofiled:
</span><span class="lines">@@ -354,9 +445,9 @@
</span><span class="cx">             
</span><span class="cx">         case Array::Arguments:
</span><span class="cx">             read(Arguments_registers);
</span><del>-            read(Arguments_numArguments);
-            read(Arguments_slowArguments);
</del><ins>+            read(MiscFields);
</ins><span class="cx">             write(Variables);
</span><ins>+            def(HeapLocation(IndexedPropertyLoc, Variables, base, index), value);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Int32:
</span><span class="lines">@@ -369,6 +460,9 @@
</span><span class="cx">             read(Butterfly_vectorLength);
</span><span class="cx">             read(IndexedInt32Properties);
</span><span class="cx">             write(IndexedInt32Properties);
</span><ins>+            if (node-&gt;arrayMode().mayStoreToHole())
+                write(Butterfly_publicLength);
+            def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, base, index), value);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Double:
</span><span class="lines">@@ -381,6 +475,9 @@
</span><span class="cx">             read(Butterfly_vectorLength);
</span><span class="cx">             read(IndexedDoubleProperties);
</span><span class="cx">             write(IndexedDoubleProperties);
</span><ins>+            if (node-&gt;arrayMode().mayStoreToHole())
+                write(Butterfly_publicLength);
+            def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, base, index), value);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Contiguous:
</span><span class="lines">@@ -393,6 +490,9 @@
</span><span class="cx">             read(Butterfly_vectorLength);
</span><span class="cx">             read(IndexedContiguousProperties);
</span><span class="cx">             write(IndexedContiguousProperties);
</span><ins>+            if (node-&gt;arrayMode().mayStoreToHole())
+                write(Butterfly_publicLength);
+            def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, base, index), value);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="lines">@@ -411,9 +511,10 @@
</span><span class="cx">         case Array::Uint32Array:
</span><span class="cx">         case Array::Float32Array:
</span><span class="cx">         case Array::Float64Array:
</span><del>-            read(JSArrayBufferView_vector);
-            read(JSArrayBufferView_length);
</del><ins>+            read(MiscFields);
</ins><span class="cx">             write(TypedArrayProperties);
</span><ins>+            // FIXME: We can't def() anything here because these operations truncate their inputs.
+            // https://bugs.webkit.org/show_bug.cgi?id=134737
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -421,7 +522,6 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case CheckStructure:
</span><del>-    case InstanceOf:
</del><span class="cx">         read(JSCell_structureID);
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -433,12 +533,14 @@
</span><span class="cx"> 
</span><span class="cx">     case CheckHasInstance:
</span><span class="cx">         read(JSCell_typeInfoFlags);
</span><ins>+        def(HeapLocation(CheckHasInstanceLoc, JSCell_typeInfoFlags, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    case CheckExecutable:
-        read(JSFunction_executable);
</del><ins>+    case InstanceOf:
+        read(JSCell_structureID);
+        def(HeapLocation(InstanceOfLoc, JSCell_structureID, node-&gt;child1(), node-&gt;child2()), node);
</ins><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case PutStructure:
</span><span class="cx">         write(JSCell_structureID);
</span><span class="cx">         write(JSCell_typeInfoType);
</span><span class="lines">@@ -448,15 +550,18 @@
</span><span class="cx">         
</span><span class="cx">     case AllocatePropertyStorage:
</span><span class="cx">         write(JSObject_butterfly);
</span><ins>+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), node);
</ins><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><ins>+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetButterfly:
</span><span class="cx">         read(JSObject_butterfly);
</span><ins>+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case Arrayify:
</span><span class="lines">@@ -471,42 +576,59 @@
</span><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetIndexedPropertyStorage:
</span><del>-        if (node-&gt;arrayMode().type() == Array::String)
</del><ins>+        if (node-&gt;arrayMode().type() == Array::String) {
+            def(PureValue(node, node-&gt;arrayMode().asWord()));
</ins><span class="cx">             return;
</span><del>-        read(JSArrayBufferView_vector);
</del><ins>+        }
+        read(MiscFields);
+        def(HeapLocation(IndexedPropertyStorageLoc, MiscFields, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetTypedArrayByteOffset:
</span><del>-        read(JSArrayBufferView_vector);
-        read(JSArrayBufferView_mode);
-        read(Butterfly_arrayBuffer);
-        read(ArrayBuffer_data);
</del><ins>+        read(MiscFields);
+        def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetByOffset:
</span><del>-    case GetGetterSetterByOffset:
-        read(AbstractHeap(NamedProperties, graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber));
</del><ins>+    case GetGetterSetterByOffset: {
+        unsigned identifierNumber =
+            graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber;
+        AbstractHeap heap(NamedProperties, identifierNumber);
+        read(heap);
+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child2()), node);
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">         
</span><del>-    case MultiGetByOffset:
</del><ins>+    case MultiGetByOffset: {
</ins><span class="cx">         read(JSCell_structureID);
</span><span class="cx">         read(JSObject_butterfly);
</span><del>-        read(AbstractHeap(NamedProperties, node-&gt;multiGetByOffsetData().identifierNumber));
</del><ins>+        AbstractHeap heap(NamedProperties, node-&gt;multiGetByOffsetData().identifierNumber);
+        read(heap);
+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">         
</span><del>-    case MultiPutByOffset:
</del><ins>+    case MultiPutByOffset: {
</ins><span class="cx">         read(JSCell_structureID);
</span><span class="cx">         read(JSObject_butterfly);
</span><del>-        write(AbstractHeap(NamedProperties, node-&gt;multiPutByOffsetData().identifierNumber));
</del><ins>+        AbstractHeap heap(NamedProperties, node-&gt;multiPutByOffsetData().identifierNumber);
+        write(heap);
</ins><span class="cx">         if (node-&gt;multiPutByOffsetData().writesStructures())
</span><span class="cx">             write(JSCell_structureID);
</span><span class="cx">         if (node-&gt;multiPutByOffsetData().reallocatesStorage())
</span><span class="cx">             write(JSObject_butterfly);
</span><ins>+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child1()), node-&gt;child2().node());
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">         
</span><del>-    case PutByOffset:
-        write(AbstractHeap(NamedProperties, graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber));
</del><ins>+    case PutByOffset: {
+        unsigned identifierNumber =
+            graph.m_storageAccessData[node-&gt;storageAccessDataIndex()].identifierNumber;
+        AbstractHeap heap(NamedProperties, identifierNumber);
+        write(heap);
+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child2()), node-&gt;child3().node());
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">         
</span><span class="cx">     case GetArrayLength: {
</span><span class="cx">         ArrayMode mode = node-&gt;arrayMode();
</span><span class="lines">@@ -517,78 +639,90 @@
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">         case Array::SlowPutArrayStorage:
</span><span class="cx">             read(Butterfly_publicLength);
</span><ins>+            def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node-&gt;child1()), node);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::String:
</span><ins>+            def(PureValue(node, mode.asWord()));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Arguments:
</span><del>-            read(Arguments_overrideLength);
-            read(Arguments_numArguments);
</del><ins>+            read(MiscFields);
+            def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), node);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            read(JSArrayBufferView_length);
</del><ins>+            ASSERT(mode.typedArrayType() != NotTypedArray);
+            read(MiscFields);
+            def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), node);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case GetMyScope:
</span><del>-        read(AbstractHeap(Variables, JSStack::ScopeChain));
</del><ins>+        if (graph.m_codeBlock-&gt;needsActivation()) {
+            read(AbstractHeap(Variables, JSStack::ScopeChain));
+            def(HeapLocation(VariableLoc, AbstractHeap(Variables, JSStack::ScopeChain)), node);
+        } else
+            def(PureValue(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case SkipTopScope:
</span><span class="cx">         read(AbstractHeap(Variables, graph.activationRegister()));
</span><ins>+        def(HeapLocation(SkipTopScopeLoc, AbstractHeap(Variables, graph.activationRegister()), node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetClosureRegisters:
</span><span class="cx">         read(JSVariableObject_registers);
</span><ins>+        def(HeapLocation(ClosureRegistersLoc, JSVariableObject_registers, node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case GetClosureVar:
</span><span class="cx">         read(AbstractHeap(Variables, node-&gt;varNumber()));
</span><ins>+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(Variables, node-&gt;varNumber()), node-&gt;child1()), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case PutClosureVar:
</span><span class="cx">         write(AbstractHeap(Variables, node-&gt;varNumber()));
</span><ins>+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(Variables, node-&gt;varNumber()), node-&gt;child2()), node-&gt;child3().node());
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetGlobalVar:
</span><span class="cx">         read(AbstractHeap(Absolute, node-&gt;registerPointer()));
</span><ins>+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node-&gt;registerPointer())), node);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case PutGlobalVar:
</span><span class="cx">         write(AbstractHeap(Absolute, node-&gt;registerPointer()));
</span><ins>+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node-&gt;registerPointer())), node-&gt;child1().node());
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    case NewObject:
</del><span class="cx">     case NewArray:
</span><span class="cx">     case NewArrayWithSize:
</span><span class="cx">     case NewArrayBuffer:
</span><ins>+    case NewTypedArray:
+        // FIXME: Enable CSE for these nodes. We can't do this right now because there is no way
+        // for us to claim an index node and a value node. We could make this work if we lowered
+        // these nodes or if we had a more flexible way of def()'ing.
+        // https://bugs.webkit.org/show_bug.cgi?id=134737
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+
+    case NewObject:
</ins><span class="cx">     case NewRegexp:
</span><span class="cx">     case NewStringObject:
</span><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+        
</ins><span class="cx">     case NewFunctionNoCheck:
</span><span class="cx">     case NewFunction:
</span><span class="cx">     case NewFunctionExpression:
</span><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><del>-        
-    case NewTypedArray:
-        read(HeapObjectCount);
-        write(HeapObjectCount);
-        switch (node-&gt;child1().useKind()) {
-        case Int32Use:
-            return;
-        case UntypedUse:
-            read(World);
-            write(World);
-            return;
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return;
-        }
-        
</del><ins>+
</ins><span class="cx">     case RegExpExec:
</span><span class="cx">     case RegExpTest:
</span><span class="cx">         read(RegExpState);
</span><span class="lines">@@ -601,6 +735,7 @@
</span><span class="cx">             write(World);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><ins>+        def(PureValue(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case CompareEq:
</span><span class="lines">@@ -608,8 +743,10 @@
</span><span class="cx">     case CompareLessEq:
</span><span class="cx">     case CompareGreater:
</span><span class="cx">     case CompareGreaterEq:
</span><del>-        if (!node-&gt;isBinaryUseKind(UntypedUse))
</del><ins>+        if (!node-&gt;isBinaryUseKind(UntypedUse)) {
+            def(PureValue(node));
</ins><span class="cx">             return;
</span><ins>+        }
</ins><span class="cx">         read(World);
</span><span class="cx">         write(World);
</span><span class="cx">         return;
</span><span class="lines">@@ -618,6 +755,8 @@
</span><span class="cx">         switch (node-&gt;child1().useKind()) {
</span><span class="cx">         case StringObjectUse:
</span><span class="cx">         case StringOrStringObjectUse:
</span><ins>+            // These don't def a pure value, unfortunately. I'll avoid load-eliminating these for
+            // now.
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case CellUse:
</span><span class="lines">@@ -632,20 +771,28 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">     case TearOffActivation:
</span><ins>+        read(Variables);
</ins><span class="cx">         write(JSVariableObject_registers);
</span><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case TearOffArguments:
</span><ins>+        read(Variables);
</ins><span class="cx">         write(Arguments_registers);
</span><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetMyArgumentsLength:
</span><span class="cx">         read(AbstractHeap(Variables, graph.argumentsRegisterFor(node-&gt;origin.semantic)));
</span><span class="cx">         read(AbstractHeap(Variables, JSStack::ArgumentCount));
</span><ins>+        // FIXME: We could def() this by specifying the code origin as a kind of m_info, like we
+        // have for PureValue.
+        // https://bugs.webkit.org/show_bug.cgi?id=134797
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetMyArgumentByVal:
</span><span class="cx">         read(Variables);
</span><ins>+        // FIXME: We could def() this by specifying the code origin as a kind of m_info, like we
+        // have for PureValue.
+        // https://bugs.webkit.org/show_bug.cgi?id=134797
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case CheckArgumentsNotCreated:
</span><span class="lines">@@ -675,7 +822,8 @@
</span><span class="cx"> class NoOpClobberize {
</span><span class="cx"> public:
</span><span class="cx">     NoOpClobberize() { }
</span><del>-    void operator()(AbstractHeap) { }
</del><ins>+    template&lt;typename... T&gt;
+    void operator()(T...) { }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class CheckClobberize {
</span><span class="lines">@@ -685,7 +833,8 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void operator()(AbstractHeap) { m_result = true; }
</del><ins>+    template&lt;typename... T&gt;
+    void operator()(T...) { m_result = true; }
</ins><span class="cx">     
</span><span class="cx">     bool result() const { return m_result; }
</span><span class="cx">     
</span><span class="lines">@@ -717,8 +866,75 @@
</span><span class="cx">     bool m_result;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+bool accessesOverlap(Graph&amp;, Node*, AbstractHeap);
</ins><span class="cx"> bool writesOverlap(Graph&amp;, Node*, AbstractHeap);
</span><span class="cx"> 
</span><ins>+// We would have used bind() for these, but because of the overlaoding that we are doing,
+// it's quite a bit of clearer to just write this out the traditional way.
+
+template&lt;typename T&gt;
+class ReadMethodClobberize {
+public:
+    ReadMethodClobberize(T&amp; value)
+        : m_value(value)
+    {
+    }
+    
+    void operator()(AbstractHeap heap)
+    {
+        m_value.read(heap);
+    }
+private:
+    T&amp; m_value;
+};
+
+template&lt;typename T&gt;
+class WriteMethodClobberize {
+public:
+    WriteMethodClobberize(T&amp; value)
+        : m_value(value)
+    {
+    }
+    
+    void operator()(AbstractHeap heap)
+    {
+        m_value.write(heap);
+    }
+private:
+    T&amp; m_value;
+};
+
+template&lt;typename T&gt;
+class DefMethodClobberize {
+public:
+    DefMethodClobberize(T&amp; value)
+        : m_value(value)
+    {
+    }
+    
+    void operator()(PureValue value)
+    {
+        m_value.def(value);
+    }
+    
+    void operator()(HeapLocation location, Node* node)
+    {
+        m_value.def(location, node);
+    }
+
+private:
+    T&amp; m_value;
+};
+
+template&lt;typename Adaptor&gt;
+void clobberize(Graph&amp; graph, Node* node, Adaptor&amp; adaptor)
+{
+    ReadMethodClobberize&lt;Adaptor&gt; read(adaptor);
+    WriteMethodClobberize&lt;Adaptor&gt; write(adaptor);
+    DefMethodClobberize&lt;Adaptor&gt; def(adaptor);
+    clobberize(graph, node, read, write, def);
+}
+
</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="trunkSourceJavaScriptCoredfgDFGCommonDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommonData.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommonData.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommonData.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -32,7 +32,6 @@
</span><span class="cx"> #include &quot;DFGJumpReplacement.h&quot;
</span><span class="cx"> #include &quot;InlineCallFrameSet.h&quot;
</span><span class="cx"> #include &quot;JSCell.h&quot;
</span><del>-#include &quot;ProfiledCodeBlockJettisoningWatchpoint.h&quot;
</del><span class="cx"> #include &quot;ProfilerCompilation.h&quot;
</span><span class="cx"> #include &quot;SymbolTable.h&quot;
</span><span class="cx"> #include &lt;wtf/Bag.h&gt;
</span><span class="lines">@@ -95,8 +94,8 @@
</span><span class="cx">     Vector&lt;Identifier&gt; dfgIdentifiers;
</span><span class="cx">     Vector&lt;WeakReferenceTransition&gt; transitions;
</span><span class="cx">     Vector&lt;WriteBarrier&lt;JSCell&gt;&gt; weakReferences;
</span><ins>+    Vector&lt;WriteBarrier&lt;Structure&gt;&gt; weakStructureReferences;
</ins><span class="cx">     SegmentedVector&lt;CodeBlockJettisoningWatchpoint, 1, 0&gt; watchpoints;
</span><del>-    SegmentedVector&lt;ProfiledCodeBlockJettisoningWatchpoint, 1, 0&gt; profiledWatchpoints;
</del><span class="cx">     Vector&lt;JumpReplacement&gt; jumpReplacements;
</span><span class="cx">     
</span><span class="cx">     RefPtr&lt;Profiler::Compilation&gt; compilation;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -414,8 +414,13 @@
</span><span class="cx"> 
</span><span class="cx">         addBaseCheck(indexInBlock, node, baseValue, variant.structureSet());
</span><span class="cx">         
</span><del>-        if (variant.specificValue()) {
-            m_graph.convertToConstant(node, m_graph.freeze(variant.specificValue()));
</del><ins>+        JSValue baseForLoad;
+        if (variant.alternateBase())
+            baseForLoad = variant.alternateBase();
+        else
+            baseForLoad = baseValue.m_value;
+        if (JSValue value = m_graph.tryGetConstantProperty(baseForLoad, variant.baseStructure(), variant.offset())) {
+            m_graph.convertToConstant(node, m_graph.freeze(value));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDCEPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -107,7 +107,7 @@
</span><span class="cx">         
</span><span class="cx">         if (m_graph.m_form == SSA) {
</span><span class="cx">             Vector&lt;BasicBlock*&gt; depthFirst;
</span><del>-            m_graph.getBlocksInDepthFirstOrder(depthFirst);
</del><ins>+            m_graph.getBlocksInPreOrder(depthFirst);
</ins><span class="cx">             for (unsigned i = 0; i &lt; depthFirst.size(); ++i)
</span><span class="cx">                 fixupBlock(depthFirst[i]);
</span><span class="cx">         } else {
</span><span class="lines">@@ -193,9 +193,9 @@
</span><span class="cx">                 
</span><span class="cx">             switch (node-&gt;op()) {
</span><span class="cx">             case MovHint: {
</span><del>-                // Check if the child is dead. MovHint's child would only be a Phantom
-                // if we had just killed it.
-                if (node-&gt;child1()-&gt;op() == Phantom) {
</del><ins>+                // Check if the child is dead. MovHint's child would only be a Phantom or
+                // Check if we had just killed it.
+                if (node-&gt;child1()-&gt;op() == Phantom || node-&gt;child1()-&gt;op() == Check) {
</ins><span class="cx">                     node-&gt;setOpAndDefaultFlags(ZombieHint);
</span><span class="cx">                     node-&gt;child1() = Edge();
</span><span class="cx">                     break;
</span><span class="lines">@@ -220,7 +220,7 @@
</span><span class="cx">                         m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node-&gt;origin, edge);
</span><span class="cx">                     }
</span><span class="cx"> 
</span><del>-                    node-&gt;convertToPhantomUnchecked();
</del><ins>+                    node-&gt;convertToPhantom();
</ins><span class="cx">                     node-&gt;children.reset();
</span><span class="cx">                     node-&gt;setRefCount(1);
</span><span class="cx">                     break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWeakReferencescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -57,7 +57,13 @@
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = 0; i &lt; m_references.size(); i++) {
</span><span class="cx">         JSCell* target = m_references[i];
</span><del>-        common-&gt;weakReferences.append(WriteBarrier&lt;JSCell&gt;(vm, m_codeBlock-&gt;ownerExecutable(), target));
</del><ins>+        if (Structure* structure = jsDynamicCast&lt;Structure*&gt;(target)) {
+            common-&gt;weakStructureReferences.append(
+                WriteBarrier&lt;Structure&gt;(vm, m_codeBlock-&gt;ownerExecutable(), structure));
+        } else {
+            common-&gt;weakReferences.append(
+                WriteBarrier&lt;JSCell&gt;(vm, m_codeBlock-&gt;ownerExecutable(), target));
+        }
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGEdgeDominatesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGEdgeDominates.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGEdgeDominates.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGEdgeDominates.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -45,10 +45,10 @@
</span><span class="cx">     
</span><span class="cx">     void operator()(Node*, Edge edge)
</span><span class="cx">     {
</span><del>-        bool result = m_graph.m_dominators.dominates(edge.node()-&gt;misc.owner, m_block);
</del><ins>+        bool result = m_graph.m_dominators.dominates(edge.node()-&gt;owner, m_block);
</ins><span class="cx">         if (verbose) {
</span><span class="cx">             dataLog(
</span><del>-                &quot;Checking if &quot;, edge, &quot; in &quot;, *edge.node()-&gt;misc.owner,
</del><ins>+                &quot;Checking if &quot;, edge, &quot; in &quot;, *edge.node()-&gt;owner,
</ins><span class="cx">                 &quot; dominates &quot;, *m_block, &quot;: &quot;, result, &quot;\n&quot;);
</span><span class="cx">         }
</span><span class="cx">         m_result &amp;= result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1296,22 +1296,24 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isStringPrototypeMethodSane(Structure* stringPrototypeStructure, StringImpl* uid)
</del><ins>+    bool isStringPrototypeMethodSane(
+        JSObject* stringPrototype, Structure* stringPrototypeStructure, StringImpl* uid)
</ins><span class="cx">     {
</span><span class="cx">         unsigned attributesUnused;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = stringPrototypeStructure-&gt;getConcurrently(
-            vm(), uid, attributesUnused, specificValue);
</del><ins>+        PropertyOffset offset =
+            stringPrototypeStructure-&gt;getConcurrently(vm(), uid, attributesUnused);
</ins><span class="cx">         if (!isValidOffset(offset))
</span><span class="cx">             return false;
</span><span class="cx">         
</span><del>-        if (!specificValue)
</del><ins>+        JSValue value = m_graph.tryGetConstantProperty(
+            stringPrototype, stringPrototypeStructure, offset);
+        if (!value)
</ins><span class="cx">             return false;
</span><span class="cx">         
</span><del>-        if (!specificValue-&gt;inherits(JSFunction::info()))
</del><ins>+        JSFunction* function = jsDynamicCast&lt;JSFunction*&gt;(value);
+        if (!function)
</ins><span class="cx">             return false;
</span><span class="cx">         
</span><del>-        JSFunction* function = jsCast&lt;JSFunction*&gt;(specificValue);
</del><span class="cx">         if (function-&gt;executable()-&gt;intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
</span><span class="cx">             return false;
</span><span class="cx">         
</span><span class="lines">@@ -1340,9 +1342,9 @@
</span><span class="cx">         // (that would call toString()). We don't want the DFG to have to distinguish
</span><span class="cx">         // between the two, just because that seems like it would get confusing. So we
</span><span class="cx">         // just require both methods to be sane.
</span><del>-        if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames-&gt;valueOf.impl()))
</del><ins>+        if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames-&gt;valueOf.impl()))
</ins><span class="cx">             return false;
</span><del>-        if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames-&gt;toString.impl()))
</del><ins>+        if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames-&gt;toString.impl()))
</ins><span class="cx">             return false;
</span><span class="cx">         
</span><span class="cx">         return true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -639,28 +639,78 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Graph::addForDepthFirstSort(Vector&lt;BasicBlock*&gt;&amp; result, Vector&lt;BasicBlock*, 16&gt;&amp; worklist, HashSet&lt;BasicBlock*&gt;&amp; seen, BasicBlock* block)
</del><ins>+// Utilities for pre- and post-order traversals.
+namespace {
+
+inline void addForPreOrder(Vector&lt;BasicBlock*&gt;&amp; result, Vector&lt;BasicBlock*, 16&gt;&amp; worklist, BitVector&amp; seen, BasicBlock* block)
</ins><span class="cx"> {
</span><del>-    if (seen.contains(block))
</del><ins>+    if (seen.get(block-&gt;index))
</ins><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     result.append(block);
</span><span class="cx">     worklist.append(block);
</span><del>-    seen.add(block);
</del><ins>+    seen.set(block-&gt;index);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Graph::getBlocksInDepthFirstOrder(Vector&lt;BasicBlock*&gt;&amp; result)
</del><ins>+enum PostOrderTaskKind {
+    PostOrderFirstVisit,
+    PostOrderAddToResult
+};
+
+struct PostOrderTask {
+    PostOrderTask(BasicBlock* block = nullptr, PostOrderTaskKind kind = PostOrderFirstVisit)
+        : m_block(block)
+        , m_kind(kind)
+    {
+    }
+    
+    BasicBlock* m_block;
+    PostOrderTaskKind m_kind;
+};
+
+inline void addForPostOrder(Vector&lt;PostOrderTask, 16&gt;&amp; worklist, BitVector&amp; seen, BasicBlock* block)
</ins><span class="cx"> {
</span><ins>+    if (seen.get(block-&gt;index))
+        return;
+    
+    worklist.append(PostOrderTask(block, PostOrderFirstVisit));
+    seen.set(block-&gt;index);
+}
+
+} // anonymous namespace
+
+void Graph::getBlocksInPreOrder(Vector&lt;BasicBlock*&gt;&amp; result)
+{
</ins><span class="cx">     Vector&lt;BasicBlock*, 16&gt; worklist;
</span><del>-    HashSet&lt;BasicBlock*&gt; seen;
-    addForDepthFirstSort(result, worklist, seen, block(0));
</del><ins>+    BitVector seen;
+    addForPreOrder(result, worklist, seen, block(0));
</ins><span class="cx">     while (!worklist.isEmpty()) {
</span><span class="cx">         BasicBlock* block = worklist.takeLast();
</span><span class="cx">         for (unsigned i = block-&gt;numSuccessors(); i--;)
</span><del>-            addForDepthFirstSort(result, worklist, seen, block-&gt;successor(i));
</del><ins>+            addForPreOrder(result, worklist, seen, block-&gt;successor(i));
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Graph::getBlocksInPostOrder(Vector&lt;BasicBlock*&gt;&amp; result)
+{
+    Vector&lt;PostOrderTask, 16&gt; worklist;
+    BitVector seen;
+    addForPostOrder(worklist, seen, block(0));
+    while (!worklist.isEmpty()) {
+        PostOrderTask task = worklist.takeLast();
+        switch (task.m_kind) {
+        case PostOrderFirstVisit:
+            worklist.append(PostOrderTask(task.m_block, PostOrderAddToResult));
+            for (unsigned i = task.m_block-&gt;numSuccessors(); i--;)
+                addForPostOrder(worklist, seen, task.m_block-&gt;successor(i));
+            break;
+        case PostOrderAddToResult:
+            result.append(task.m_block);
+            break;
+        }
+    }
+}
+
</ins><span class="cx"> void Graph::clearReplacements()
</span><span class="cx"> {
</span><span class="cx">     for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
</span><span class="lines">@@ -668,9 +718,9 @@
</span><span class="cx">         if (!block)
</span><span class="cx">             continue;
</span><span class="cx">         for (unsigned phiIndex = block-&gt;phis.size(); phiIndex--;)
</span><del>-            block-&gt;phis[phiIndex]-&gt;misc.replacement = 0;
</del><ins>+            block-&gt;phis[phiIndex]-&gt;replacement = 0;
</ins><span class="cx">         for (unsigned nodeIndex = block-&gt;size(); nodeIndex--;)
</span><del>-            block-&gt;at(nodeIndex)-&gt;misc.replacement = 0;
</del><ins>+            block-&gt;at(nodeIndex)-&gt;replacement = 0;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -681,9 +731,9 @@
</span><span class="cx">         if (!block)
</span><span class="cx">             continue;
</span><span class="cx">         for (unsigned phiIndex = block-&gt;phis.size(); phiIndex--;)
</span><del>-            block-&gt;phis[phiIndex]-&gt;misc.owner = block;
</del><ins>+            block-&gt;phis[phiIndex]-&gt;owner = block;
</ins><span class="cx">         for (unsigned nodeIndex = block-&gt;size(); nodeIndex--;)
</span><del>-            block-&gt;at(nodeIndex)-&gt;misc.owner = block;
</del><ins>+            block-&gt;at(nodeIndex)-&gt;owner = block;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -789,6 +839,71 @@
</span><span class="cx">     return std::max(frameRegisterCount(), requiredRegisterCountForExit());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSValue Graph::tryGetConstantProperty(
+    JSValue base, const StructureSet&amp; structureSet, PropertyOffset offset)
+{
+    if (!base || !base.isObject())
+        return JSValue();
+    
+    JSObject* object = asObject(base);
+    
+    for (unsigned i = structureSet.size(); i--;) {
+        Structure* structure = structureSet[i];
+        WatchpointSet* set = structure-&gt;propertyReplacementWatchpointSet(offset);
+        if (!set || !set-&gt;isStillValid())
+            return JSValue();
+        
+        ASSERT(structure-&gt;isValidOffset(offset));
+        ASSERT(!structure-&gt;isUncacheableDictionary());
+        
+        watchpoints().addLazily(set);
+    }
+    
+    // What follows may require some extra thought. We need this load to load a valid JSValue. If
+    // our profiling makes sense and we're still on track to generate code that won't be
+    // invalidated, then we have nothing to worry about. We do, however, have to worry about
+    // loading - and then using - an invalid JSValue in the case that unbeknownst to us our code
+    // is doomed.
+    //
+    // One argument in favor of this code is that it should definitely work because the butterfly
+    // is always set before the structure. However, we don't currently have a fence between those
+    // stores. It's not clear if this matters, however. We don't ever shrink the property storage.
+    // So, for this to fail, you'd need an access on a constant object pointer such that the inline
+    // caches told us that the object had a structure that it did not *yet* have, and then later,
+    // the object transitioned to that structure that the inline caches had alraedy seen. And then
+    // the processor reordered the stores. Seems unlikely and difficult to test. I believe that
+    // this is worth revisiting but it isn't worth losing sleep over. Filed:
+    // https://bugs.webkit.org/show_bug.cgi?id=134641
+    //
+    // For now, we just do the minimal thing: defend against the structure right now being
+    // incompatible with the getDirect we're trying to do. The easiest way to do that is to
+    // determine if the structure belongs to the proven set.
+    
+    if (!structureSet.contains(object-&gt;structure()))
+        return JSValue();
+    
+    return object-&gt;getDirect(offset);
+}
+
+JSValue Graph::tryGetConstantProperty(JSValue base, Structure* structure, PropertyOffset offset)
+{
+    return tryGetConstantProperty(base, StructureSet(structure), offset);
+}
+
+JSValue Graph::tryGetConstantProperty(
+    JSValue base, const StructureAbstractValue&amp; structure, PropertyOffset offset)
+{
+    if (structure.isTop() || structure.isClobbered())
+        return JSValue();
+    
+    return tryGetConstantProperty(base, structure.set(), offset);
+}
+
+JSValue Graph::tryGetConstantProperty(const AbstractValue&amp; base, PropertyOffset offset)
+{
+    return tryGetConstantProperty(base.m_value, base.m_structure, offset);
+}
+
</ins><span class="cx"> JSActivation* Graph::tryGetActivation(Node* node)
</span><span class="cx"> {
</span><span class="cx">     return node-&gt;dynamicCastConstant&lt;JSActivation*&gt;();
</span><span class="lines">@@ -900,7 +1015,6 @@
</span><span class="cx">             case MultiGetByOffset:
</span><span class="cx">                 for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;) {
</span><span class="cx">                     GetByIdVariant&amp; variant = node-&gt;multiGetByOffsetData().variants[i];
</span><del>-                    visitor.appendUnbarrieredReadOnlyValue(variant.specificValue());
</del><span class="cx">                     const StructureSet&amp; set = variant.structureSet();
</span><span class="cx">                     for (unsigned j = set.size(); j--;)
</span><span class="cx">                         visitor.appendUnbarrieredReadOnlyPointer(set[j]);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -125,7 +125,7 @@
</span><span class="cx">             return;
</span><span class="cx">         
</span><span class="cx">         // Check if there is any replacement.
</span><del>-        Node* replacement = child-&gt;misc.replacement;
</del><ins>+        Node* replacement = child-&gt;replacement;
</ins><span class="cx">         if (!replacement)
</span><span class="cx">             return;
</span><span class="cx">         
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">         
</span><span class="cx">         // There is definitely a replacement. Assert that the replacement does not
</span><span class="cx">         // have a replacement.
</span><del>-        ASSERT(!child-&gt;misc.replacement);
</del><ins>+        ASSERT(!child-&gt;replacement);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename... Params&gt;
</span><span class="lines">@@ -675,7 +675,8 @@
</span><span class="cx">     void clearReplacements();
</span><span class="cx">     void initializeNodeOwners();
</span><span class="cx">     
</span><del>-    void getBlocksInDepthFirstOrder(Vector&lt;BasicBlock*&gt;&amp; result);
</del><ins>+    void getBlocksInPreOrder(Vector&lt;BasicBlock*&gt;&amp; result);
+    void getBlocksInPostOrder(Vector&lt;BasicBlock*&gt;&amp; result);
</ins><span class="cx">     
</span><span class="cx">     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
</span><span class="cx">     
</span><span class="lines">@@ -691,6 +692,11 @@
</span><span class="cx">     unsigned requiredRegisterCountForExit();
</span><span class="cx">     unsigned requiredRegisterCountForExecutionAndExit();
</span><span class="cx">     
</span><ins>+    JSValue tryGetConstantProperty(JSValue base, const StructureSet&amp;, PropertyOffset);
+    JSValue tryGetConstantProperty(JSValue base, Structure*, PropertyOffset);
+    JSValue tryGetConstantProperty(JSValue base, const StructureAbstractValue&amp;, PropertyOffset);
+    JSValue tryGetConstantProperty(const AbstractValue&amp;, PropertyOffset);
+    
</ins><span class="cx">     JSActivation* tryGetActivation(Node*);
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;* tryGetRegisters(Node*);
</span><span class="cx">     
</span><span class="lines">@@ -758,7 +764,6 @@
</span><span class="cx"> private:
</span><span class="cx">     
</span><span class="cx">     void handleSuccessor(Vector&lt;BasicBlock*, 16&gt;&amp; worklist, BasicBlock*, BasicBlock* successor);
</span><del>-    void addForDepthFirstSort(Vector&lt;BasicBlock*&gt;&amp; result, Vector&lt;BasicBlock*, 16&gt;&amp; worklist, HashSet&lt;BasicBlock*&gt;&amp; seen, BasicBlock*);
</del><span class="cx">     
</span><span class="cx">     AddSpeculationMode addImmediateShouldSpeculateInt32(Node* add, bool variableShouldSpeculateInt32, Node* immediate, RareCaseProfilingSource source)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGHeapLocationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,158 @@
</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;DFGHeapLocation.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+void HeapLocation::dump(PrintStream&amp; out) const
+{
+    out.print(m_kind, &quot;:&quot;, m_heap);
+    
+    if (!m_base)
+        return;
+    
+    out.print(&quot;[&quot;, m_base);
+    if (m_index)
+        out.print(&quot;, &quot;, m_index);
+    out.print(&quot;]&quot;);
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream&amp; out, LocationKind kind)
+{
+    switch (kind) {
+    case InvalidLocationKind:
+        out.print(&quot;InvalidLocationKind&quot;);
+        return;
+        
+    case InvalidationPointLoc:
+        out.print(&quot;InvalidationPointLoc&quot;);
+        return;
+        
+    case IsObjectLoc:
+        out.print(&quot;IsObjectLoc&quot;);
+        return;
+        
+    case IsFunctionLoc:
+        out.print(&quot;IsFunctionLoc&quot;);
+        return;
+        
+    case TypeOfLoc:
+        out.print(&quot;TypeOfLoc&quot;);
+        return;
+        
+    case GetterLoc:
+        out.print(&quot;GetterLoc&quot;);
+        return;
+        
+    case SetterLoc:
+        out.print(&quot;SetterLoc&quot;);
+        return;
+        
+    case VariableLoc:
+        out.print(&quot;VariableLoc&quot;);
+        return;
+        
+    case ArrayLengthLoc:
+        out.print(&quot;ArrayLengthLoc&quot;);
+        return;
+        
+    case ButterflyLoc:
+        out.print(&quot;ButterflyLoc&quot;);
+        return;
+        
+    case CheckHasInstanceLoc:
+        out.print(&quot;CheckHasInstanceLoc&quot;);
+        return;
+        
+    case ClosureRegistersLoc:
+        out.print(&quot;ClosureRegistersLoc&quot;);
+        return;
+        
+    case ClosureVariableLoc:
+        out.print(&quot;ClosureVariableLoc&quot;);
+        return;
+        
+    case GlobalVariableLoc:
+        out.print(&quot;GlobalVariableLoc&quot;);
+        return;
+        
+    case IndexedPropertyLoc:
+        out.print(&quot;IndexedPorpertyLoc&quot;);
+        return;
+        
+    case IndexedPropertyStorageLoc:
+        out.print(&quot;IndexedPropertyStorageLoc&quot;);
+        return;
+        
+    case InstanceOfLoc:
+        out.print(&quot;InstanceOfLoc&quot;);
+        return;
+        
+    case MyArgumentByValLoc:
+        out.print(&quot;MyArgumentByValLoc&quot;);
+        return;
+        
+    case MyArgumentsLengthLoc:
+        out.print(&quot;MyArgumentsLengthLoc&quot;);
+        return;
+        
+    case NamedPropertyLoc:
+        out.print(&quot;NamedPropertyLoc&quot;);
+        return;
+        
+    case SkipTopScopeLoc:
+        out.print(&quot;SkipTopScopeLoc&quot;);
+        return;
+        
+    case TypedArrayByteOffsetLoc:
+        out.print(&quot;TypedArrayByteOffsetLoc&quot;);
+        return;
+        
+    case VarInjectionWatchpointLoc:
+        out.print(&quot;VarInjectionWatchpointLoc&quot;);
+        return;
+        
+    case AllocationProfileWatchpointLoc:
+        out.print(&quot;AllocationProfileWatchpointLoc&quot;);
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGHeapLocationh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,160 @@
</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 DFGHeapLocation_h
+#define DFGHeapLocation_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGAbstractHeap.h&quot;
+#include &quot;DFGNode.h&quot;
+
+namespace JSC { namespace DFG {
+
+enum LocationKind {
+    InvalidLocationKind,
+    
+    AllocationProfileWatchpointLoc,
+    ArrayLengthLoc,
+    ButterflyLoc,
+    CheckHasInstanceLoc,
+    ClosureRegistersLoc,
+    ClosureVariableLoc,
+    GetterLoc,
+    GlobalVariableLoc,
+    IndexedPropertyLoc,
+    IndexedPropertyStorageLoc,
+    InstanceOfLoc,
+    InvalidationPointLoc,
+    IsFunctionLoc,
+    IsObjectLoc,
+    MyArgumentByValLoc,
+    MyArgumentsLengthLoc,
+    NamedPropertyLoc,
+    SetterLoc,
+    SkipTopScopeLoc,
+    TypeOfLoc,
+    TypedArrayByteOffsetLoc,
+    VarInjectionWatchpointLoc,
+    VariableLoc
+};
+
+class HeapLocation {
+public:
+    HeapLocation(
+        LocationKind kind = InvalidLocationKind,
+        AbstractHeap heap = AbstractHeap(),
+        Node* base = nullptr, Node* index = nullptr)
+        : m_kind(kind)
+        , m_heap(heap)
+        , m_base(base)
+        , m_index(index)
+    {
+        ASSERT((kind == InvalidLocationKind) == !heap);
+        ASSERT(!!m_heap || !m_base);
+        ASSERT(m_base || !m_index);
+    }
+    
+    HeapLocation(LocationKind kind, AbstractHeap heap, Edge base, Edge index = Edge())
+        : HeapLocation(kind, heap, base.node(), index.node())
+    {
+    }
+    
+    HeapLocation(WTF::HashTableDeletedValueType)
+        : m_kind(InvalidLocationKind)
+        , m_heap(WTF::HashTableDeletedValue)
+        , m_base(nullptr)
+        , m_index(nullptr)
+    {
+    }
+    
+    bool operator!() const { return !m_heap; }
+    
+    LocationKind kind() const { return m_kind; }
+    AbstractHeap heap() const { return m_heap; }
+    Node* base() const { return m_base; }
+    Node* index() const { return m_index; }
+    
+    unsigned hash() const
+    {
+        return m_kind + m_heap.hash() + WTF::PtrHash&lt;Node*&gt;::hash(m_index) + m_kind;
+    }
+    
+    bool operator==(const HeapLocation&amp; other) const
+    {
+        return m_kind == other.m_kind
+            &amp;&amp; m_heap == other.m_heap
+            &amp;&amp; m_base == other.m_base
+            &amp;&amp; m_index == other.m_index;
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_heap.isHashTableDeletedValue();
+    }
+    
+    void dump(PrintStream&amp; out) const;
+    
+private:
+    LocationKind m_kind;
+    AbstractHeap m_heap;
+    Node* m_base;
+    Node* m_index;
+};
+
+struct HeapLocationHash {
+    static unsigned hash(const HeapLocation&amp; key) { return key.hash(); }
+    static bool equal(const HeapLocation&amp; a, const HeapLocation&amp; b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&amp;, JSC::DFG::LocationKind);
+
+template&lt;typename T&gt; struct DefaultHash;
+template&lt;&gt; struct DefaultHash&lt;JSC::DFG::HeapLocation&gt; {
+    typedef JSC::DFG::HeapLocationHash Hash;
+};
+
+template&lt;typename T&gt; struct HashTraits;
+template&lt;&gt; struct HashTraits&lt;JSC::DFG::HeapLocation&gt; : SimpleClassHashTraits&lt;JSC::DFG::HeapLocation&gt; {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+namespace JSC { namespace DFG {
+
+typedef HashMap&lt;HeapLocation, Node*&gt; ImpureMap;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGHeapLocation_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLICMPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -151,7 +151,7 @@
</span><span class="cx">         // For maximum profit, we walk blocks in DFS order to ensure that we generally
</span><span class="cx">         // tend to hoist dominators before dominatees.
</span><span class="cx">         Vector&lt;BasicBlock*&gt; depthFirst;
</span><del>-        m_graph.getBlocksInDepthFirstOrder(depthFirst);
</del><ins>+        m_graph.getBlocksInPreOrder(depthFirst);
</ins><span class="cx">         Vector&lt;const NaturalLoop*&gt; loopStack;
</span><span class="cx">         bool changed = false;
</span><span class="cx">         for (
</span><span class="lines">@@ -245,7 +245,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         data.preHeader-&gt;insertBeforeLast(node);
</span><del>-        node-&gt;misc.owner = data.preHeader;
</del><ins>+        node-&gt;owner = data.preHeader;
</ins><span class="cx">         NodeOrigin originalOrigin = node-&gt;origin;
</span><span class="cx">         node-&gt;origin.forExit = data.preHeader-&gt;last()-&gt;origin.forExit;
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -208,8 +208,9 @@
</span><span class="cx">         , m_virtualRegister(VirtualRegister())
</span><span class="cx">         , m_refCount(1)
</span><span class="cx">         , m_prediction(SpecNone)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -222,8 +223,9 @@
</span><span class="cx">         , m_prediction(SpecNone)
</span><span class="cx">         , m_opInfo(0)
</span><span class="cx">         , m_opInfo2(0)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">         ASSERT(!(m_flags &amp; NodeHasVarArgs));
</span><span class="cx">     }
</span><span class="lines">@@ -237,8 +239,9 @@
</span><span class="cx">         , m_prediction(SpecNone)
</span><span class="cx">         , m_opInfo(0)
</span><span class="cx">         , m_opInfo2(0)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">         setResult(result);
</span><span class="cx">         ASSERT(!(m_flags &amp; NodeHasVarArgs));
</span><span class="lines">@@ -253,8 +256,9 @@
</span><span class="cx">         , m_prediction(SpecNone)
</span><span class="cx">         , m_opInfo(imm.m_value)
</span><span class="cx">         , m_opInfo2(0)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">         ASSERT(!(m_flags &amp; NodeHasVarArgs));
</span><span class="cx">     }
</span><span class="lines">@@ -268,8 +272,9 @@
</span><span class="cx">         , m_prediction(SpecNone)
</span><span class="cx">         , m_opInfo(imm.m_value)
</span><span class="cx">         , m_opInfo2(0)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">         setResult(result);
</span><span class="cx">         ASSERT(!(m_flags &amp; NodeHasVarArgs));
</span><span class="lines">@@ -284,8 +289,9 @@
</span><span class="cx">         , m_prediction(SpecNone)
</span><span class="cx">         , m_opInfo(imm1.m_value)
</span><span class="cx">         , m_opInfo2(imm2.m_value)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">         ASSERT(!(m_flags &amp; NodeHasVarArgs));
</span><span class="cx">     }
</span><span class="lines">@@ -299,8 +305,9 @@
</span><span class="cx">         , m_prediction(SpecNone)
</span><span class="cx">         , m_opInfo(imm1.m_value)
</span><span class="cx">         , m_opInfo2(imm2.m_value)
</span><ins>+        , replacement(nullptr)
+        , owner(nullptr)
</ins><span class="cx">     {
</span><del>-        misc.replacement = 0;
</del><span class="cx">         setOpAndDefaultFlags(op);
</span><span class="cx">         ASSERT(m_flags &amp; NodeHasVarArgs);
</span><span class="cx">     }
</span><span class="lines">@@ -366,11 +373,17 @@
</span><span class="cx">     {
</span><span class="cx">         setOpAndDefaultFlags(Phantom);
</span><span class="cx">     }
</span><del>-
-    void convertToPhantomUnchecked()
</del><ins>+    
+    void convertToCheck()
</ins><span class="cx">     {
</span><del>-        setOpAndDefaultFlags(Phantom);
</del><ins>+        setOpAndDefaultFlags(Check);
</ins><span class="cx">     }
</span><ins>+    
+    void replaceWith(Node* other)
+    {
+        convertToPhantom();
+        replacement = other;
+    }
</ins><span class="cx"> 
</span><span class="cx">     void convertToIdentity();
</span><span class="cx"> 
</span><span class="lines">@@ -436,6 +449,7 @@
</span><span class="cx">         ASSERT(op() == GetIndexedPropertyStorage);
</span><span class="cx">         m_op = ConstantStoragePointer;
</span><span class="cx">         m_opInfo = bitwise_cast&lt;uintptr_t&gt;(pointer);
</span><ins>+        children.reset();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void convertToGetLocalUnlinked(VirtualRegister local)
</span><span class="lines">@@ -1760,19 +1774,17 @@
</span><span class="cx">     AbstractValue value;
</span><span class="cx">     
</span><span class="cx">     // Miscellaneous data that is usually meaningless, but can hold some analysis results
</span><del>-    // if you ask right. For example, if you do Graph::initializeNodeOwners(), misc.owner
</del><ins>+    // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
</ins><span class="cx">     // will tell you which basic block a node belongs to. You cannot rely on this persisting
</span><span class="cx">     // across transformations unless you do the maintenance work yourself. Other phases use
</span><del>-    // misc.replacement, but they do so manually: first you do Graph::clearReplacements()
</del><ins>+    // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
</ins><span class="cx">     // and then you set, and use, replacement's yourself.
</span><span class="cx">     //
</span><span class="cx">     // Bottom line: don't use these fields unless you initialize them yourself, or by
</span><span class="cx">     // calling some appropriate methods that initialize them the way you want. Otherwise,
</span><span class="cx">     // these fields are meaningless.
</span><del>-    union {
-        Node* replacement;
-        BasicBlock* owner;
-    } misc;
</del><ins>+    Node* replacement;
+    BasicBlock* owner;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline bool nodeComparator(Node* a, Node* b)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSREntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -58,6 +58,9 @@
</span><span class="cx"> 
</span><span class="cx">     sanitizeStackForVM(vm);
</span><span class="cx">     
</span><ins>+    if (bytecodeIndex)
+        codeBlock-&gt;ownerExecutable()-&gt;setDidTryToEnterInLoop(true);
+    
</ins><span class="cx">     if (codeBlock-&gt;jitType() != JITCode::DFGJIT) {
</span><span class="cx">         RELEASE_ASSERT(codeBlock-&gt;jitType() == JITCode::FTLJIT);
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitCompilerCommoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -54,20 +54,55 @@
</span><span class="cx">         AssemblyHelpers::GreaterThanOrEqual,
</span><span class="cx">         AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()),
</span><span class="cx">         AssemblyHelpers::TrustedImm32(0));
</span><ins>+    
+    // We want to figure out if there's a possibility that we're in a loop. For the outermost
+    // code block in the inline stack, we handle this appropriately by having the loop OSR trigger
+    // check the exit count of the replacement of the CodeBlock from which we are OSRing. The
+    // problem is the inlined functions, which might also have loops, but whose baseline versions
+    // don't know where to look for the exit count. Figure out if those loops are severe enough
+    // that we had tried to OSR enter. If so, then we should use the loop reoptimization trigger.
+    // Otherwise, we should use the normal reoptimization trigger.
+    
+    AssemblyHelpers::JumpList loopThreshold;
+    
+    for (InlineCallFrame* inlineCallFrame = exit.m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame-&gt;caller.inlineCallFrame) {
+        loopThreshold.append(
+            jit.branchTest8(
+                AssemblyHelpers::NonZero,
+                AssemblyHelpers::AbsoluteAddress(
+                    inlineCallFrame-&gt;executable-&gt;addressOfDidTryToEnterInLoop())));
+    }
+    
+    jit.move(
+        AssemblyHelpers::TrustedImm32(jit.codeBlock()-&gt;exitCountThresholdForReoptimization()),
+        GPRInfo::regT1);
+    
+    if (!loopThreshold.empty()) {
+        AssemblyHelpers::Jump done = jit.jump();
+
+        loopThreshold.link(&amp;jit);
+        jit.move(
+            AssemblyHelpers::TrustedImm32(
+                jit.codeBlock()-&gt;exitCountThresholdForReoptimizationFromLoop()),
+            GPRInfo::regT1);
</ins><span class="cx">         
</span><del>-    tooFewFails = jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(jit.codeBlock()-&gt;exitCountThresholdForReoptimization()));
</del><ins>+        done.link(&amp;jit);
+    }
</ins><span class="cx">     
</span><ins>+    tooFewFails = jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1);
+    
</ins><span class="cx">     reoptimizeNow.link(&amp;jit);
</span><span class="cx">     
</span><span class="cx">     // Reoptimize as soon as possible.
</span><span class="cx"> #if !NUMBER_OF_ARGUMENT_REGISTERS
</span><span class="cx">     jit.poke(GPRInfo::regT0);
</span><ins>+    jit.poke(AssemblyHelpers::TrustedImmPtr(&amp;exit), 1);
</ins><span class="cx"> #else
</span><span class="cx">     jit.move(GPRInfo::regT0, GPRInfo::argumentGPR0);
</span><del>-    ASSERT(GPRInfo::argumentGPR0 != GPRInfo::regT1);
</del><ins>+    jit.move(AssemblyHelpers::TrustedImmPtr(&amp;exit), GPRInfo::argumentGPR1);
</ins><span class="cx"> #endif
</span><del>-    jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast&lt;void*&gt;(triggerReoptimizationNow)), GPRInfo::regT1);
-    jit.call(GPRInfo::regT1);
</del><ins>+    jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast&lt;void*&gt;(triggerReoptimizationNow)), GPRInfo::nonArgGPR0);
+    jit.call(GPRInfo::nonArgGPR0);
</ins><span class="cx">     AssemblyHelpers::Jump doneAdjusting = jit.jump();
</span><span class="cx">     
</span><span class="cx">     tooFewFails.link(&amp;jit);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1030,7 +1030,7 @@
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><span class="cx">     JSValue value = JSValue::decode(encodedValue);
</span><span class="cx"> 
</span><del>-    set-&gt;notifyWrite(vm, value);
</del><ins>+    set-&gt;notifyWrite(vm, value, &quot;Executed NotifyWrite&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
</span><span class="lines">@@ -1105,7 +1105,7 @@
</span><span class="cx">     dataLog(&quot;\n&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-extern &quot;C&quot; void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
</del><ins>+extern &quot;C&quot; void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
</ins><span class="cx"> {
</span><span class="cx">     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
</span><span class="cx">     // really be profitable.
</span><span class="lines">@@ -1129,13 +1129,21 @@
</span><span class="cx">     ASSERT(codeBlock-&gt;hasOptimizedReplacement());
</span><span class="cx">     CodeBlock* optimizedCodeBlock = codeBlock-&gt;replacement();
</span><span class="cx">     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock-&gt;jitType()));
</span><ins>+    
+    bool didTryToEnterIntoInlinedLoops = false;
+    for (InlineCallFrame* inlineCallFrame = exit-&gt;m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame-&gt;caller.inlineCallFrame) {
+        if (inlineCallFrame-&gt;executable-&gt;didTryToEnterInLoop()) {
+            didTryToEnterIntoInlinedLoops = true;
+            break;
+        }
+    }
</ins><span class="cx"> 
</span><span class="cx">     // In order to trigger reoptimization, one of two things must have happened:
</span><span class="cx">     // 1) We exited more than some number of times.
</span><span class="cx">     // 2) We exited and got stuck in a loop, and now we're exiting again.
</span><span class="cx">     bool didExitABunch = optimizedCodeBlock-&gt;shouldReoptimizeNow();
</span><span class="cx">     bool didGetStuckInLoop =
</span><del>-        codeBlock-&gt;checkIfOptimizationThresholdReached()
</del><ins>+        (codeBlock-&gt;checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
</ins><span class="cx">         &amp;&amp; optimizedCodeBlock-&gt;shouldReoptimizeFromLoopNow();
</span><span class="cx">     
</span><span class="cx">     if (!didExitABunch &amp;&amp; !didGetStuckInLoop) {
</span><span class="lines">@@ -1228,7 +1236,7 @@
</span><span class="cx">     
</span><span class="cx">     if (Options::verboseOSR()) {
</span><span class="cx">         dataLog(
</span><del>-            *codeBlock, &quot;: Entered triggerTierUpNow with executeCounter = &quot;,
</del><ins>+            *codeBlock, &quot;: Entered triggerOSREntryNow with executeCounter = &quot;,
</ins><span class="cx">             jitCode-&gt;tierUpCounter, &quot;\n&quot;);
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -31,9 +31,9 @@
</span><span class="cx"> #include &quot;JITOperations.h&quot;
</span><span class="cx"> #include &quot;PutKind.h&quot;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace DFG {
</ins><span class="cx"> 
</span><del>-namespace DFG {
</del><ins>+struct OSRExitBase;
</ins><span class="cx"> 
</span><span class="cx"> extern &quot;C&quot; {
</span><span class="cx"> 
</span><span class="lines">@@ -136,7 +136,7 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void*, void*) WTF_INTERNAL;
</span><span class="cx"> 
</span><del>-void JIT_OPERATION triggerReoptimizationNow(CodeBlock*) WTF_INTERNAL;
</del><ins>+void JIT_OPERATION triggerReoptimizationNow(CodeBlock*, OSRExitBase*) WTF_INTERNAL;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> void JIT_OPERATION triggerTierUpNow(ExecState*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,148 @@
</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;DFGPhantomRemovalPhase.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGGraph.h&quot;
+#include &quot;DFGInsertionSet.h&quot;
+#include &quot;DFGPhase.h&quot;
+#include &quot;DFGPredictionPropagationPhase.h&quot;
+#include &quot;DFGVariableAccessDataDump.h&quot;
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+class PhantomRemovalPhase : public Phase {
+public:
+    PhantomRemovalPhase(Graph&amp; graph)
+        : Phase(graph, &quot;phantom removal&quot;)
+    {
+    }
+    
+    bool run()
+    {
+        bool changed = false;
+        
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            
+            // All Phis need to already be marked as relevant to OSR.
+            if (!ASSERT_DISABLED) {
+                for (unsigned i = 0; i &lt; block-&gt;phis.size(); ++i)
+                    ASSERT(block-&gt;phis[i]-&gt;flags() &amp; NodeRelevantToOSR);
+            }
+            
+            for (unsigned i = block-&gt;size(); i--;) {
+                Node* node = block-&gt;at(i);
+                
+                switch (node-&gt;op()) {
+                case SetLocal:
+                case GetLocal: // FIXME: The GetLocal case is only necessary until we do https://bugs.webkit.org/show_bug.cgi?id=106707.
+                    node-&gt;mergeFlags(NodeRelevantToOSR);
+                    break;
+                default:
+                    node-&gt;clearFlags(NodeRelevantToOSR);
+                    break;
+                }
+            }
+        }
+        
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            
+            for (unsigned i = block-&gt;size(); i--;) {
+                Node* node = block-&gt;at(i);
+                if (node-&gt;op() == MovHint)
+                    node-&gt;child1()-&gt;mergeFlags(NodeRelevantToOSR);
+            }
+        }
+        
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            
+            unsigned sourceIndex = 0;
+            unsigned targetIndex = 0;
+            Node* lastNode = nullptr;
+            while (sourceIndex &lt; block-&gt;size()) {
+                Node* node = block-&gt;at(sourceIndex++);
+                if (node-&gt;op() == Phantom) {
+                    if (lastNode &amp;&amp; (lastNode-&gt;origin.forExit != node-&gt;origin.forExit || (lastNode-&gt;flags() &amp; NodeHasVarArgs)))
+                        lastNode = nullptr;
+                    for (unsigned i = 0; i &lt; AdjacencyList::Size; ++i) {
+                        Edge edge = node-&gt;children.child(i);
+                        if (!edge)
+                            break;
+                        if (edge.useKind() != UntypedUse)
+                            continue; // Keep the type check.
+                        if (edge-&gt;flags() &amp; NodeRelevantToOSR) {
+                            bool found = false;
+                            if (lastNode) {
+                                for (unsigned j = 0; j &lt; AdjacencyList::Size; ++j) {
+                                    if (lastNode-&gt;children.child(j).node() == edge.node()) {
+                                        found = true;
+                                        break;
+                                    }
+                                }
+                            }
+                            if (!found)
+                                continue;
+                        }
+                        
+                        node-&gt;children.removeEdge(i--);
+                        changed = true;
+                    }
+                    
+                    if (node-&gt;children.isEmpty())
+                        continue;
+                }
+                lastNode = node;
+                block-&gt;at(targetIndex++) = node;
+            }
+            block-&gt;resize(targetIndex);
+        }
+        
+        return changed;
+    }
+};
+    
+bool performPhantomRemoval(Graph&amp; graph)
+{
+    SamplingRegion samplingRegion(&quot;DFG Phantom Removal Phase&quot;);
+    return runPhase&lt;PhantomRemovalPhase&gt;(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,44 @@
</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 DFGPhantomRemovalPhase_h
+#define DFGPhantomRemovalPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Cleans up unnecessary Phantoms and Phanton children. This reduces live ranges, but also, it
+// eliminates many Phantoms entirely. This invalidates liveness analysis.
+
+bool performPhantomRemoval(Graph&amp;);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPhantomRemovalPhase_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #include &quot;DFGLoopPreHeaderCreationPhase.h&quot;
</span><span class="cx"> #include &quot;DFGOSRAvailabilityAnalysisPhase.h&quot;
</span><span class="cx"> #include &quot;DFGOSREntrypointCreationPhase.h&quot;
</span><ins>+#include &quot;DFGPhantomRemovalPhase.h&quot;
</ins><span class="cx"> #include &quot;DFGPredictionInjectionPhase.h&quot;
</span><span class="cx"> #include &quot;DFGPredictionPropagationPhase.h&quot;
</span><span class="cx"> #include &quot;DFGResurrectionForValidationPhase.h&quot;
</span><span class="lines">@@ -250,18 +251,18 @@
</span><span class="cx">         validate(dfg);
</span><span class="cx">         
</span><span class="cx">     performStrengthReduction(dfg);
</span><del>-    performCSE(dfg);
</del><ins>+    performLocalCSE(dfg);
</ins><span class="cx">     performArgumentsSimplification(dfg);
</span><span class="cx">     performCPSRethreading(dfg);
</span><span class="cx">     performCFA(dfg);
</span><span class="cx">     performConstantFolding(dfg);
</span><span class="cx">     bool changed = false;
</span><span class="cx">     changed |= performCFGSimplification(dfg);
</span><del>-    changed |= performCSE(dfg);
</del><ins>+    changed |= performLocalCSE(dfg);
</ins><span class="cx">     
</span><span class="cx">     if (validationEnabled())
</span><span class="cx">         validate(dfg);
</span><del>-
</del><ins>+    
</ins><span class="cx">     performCPSRethreading(dfg);
</span><span class="cx">     if (changed) {
</span><span class="cx">         performCFA(dfg);
</span><span class="lines">@@ -282,6 +283,7 @@
</span><span class="cx">         performTierUpCheckInjection(dfg);
</span><span class="cx"> 
</span><span class="cx">         performStoreBarrierElision(dfg);
</span><ins>+        performPhantomRemoval(dfg);
</ins><span class="cx">         performCPSRethreading(dfg);
</span><span class="cx">         performDCE(dfg);
</span><span class="cx">         performStackLayout(dfg);
</span><span class="lines">@@ -309,17 +311,13 @@
</span><span class="cx">             return FailPath;
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        performPhantomRemoval(dfg);
</ins><span class="cx">         performCriticalEdgeBreaking(dfg);
</span><span class="cx">         performLoopPreHeaderCreation(dfg);
</span><span class="cx">         performCPSRethreading(dfg);
</span><span class="cx">         performSSAConversion(dfg);
</span><span class="cx">         performSSALowering(dfg);
</span><del>-        performCSE(dfg);
-        
-        // 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);
</del><ins>+        performGlobalCSE(dfg);
</ins><span class="cx">         performLivenessAnalysis(dfg);
</span><span class="cx">         performCFA(dfg);
</span><span class="cx">         performConstantFolding(dfg);
</span><span class="lines">@@ -330,14 +328,16 @@
</span><span class="cx">             performCFA(dfg);
</span><span class="cx">         }
</span><span class="cx">         performLICM(dfg);
</span><ins>+        performPhantomRemoval(dfg);
</ins><span class="cx">         performIntegerCheckCombining(dfg);
</span><del>-        performCSE(dfg);
</del><ins>+        performGlobalCSE(dfg);
</ins><span class="cx">         
</span><span class="cx">         // At this point we're not allowed to do any further code motion because our reasoning
</span><span class="cx">         // about code motion assumes that it's OK to insert GC points in random places.
</span><span class="cx">         dfg.m_fixpointState = FixpointConverged;
</span><span class="cx">         
</span><span class="cx">         performStoreBarrierElision(dfg);
</span><ins>+        performPhantomRemoval(dfg);
</ins><span class="cx">         performLivenessAnalysis(dfg);
</span><span class="cx">         performCFA(dfg);
</span><span class="cx">         if (Options::validateFTLOSRExitLiveness())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPureValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPureValue.cpp (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPureValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPureValue.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,52 @@
</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;DFGPureValue.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGGraph.h&quot;
+
+namespace JSC { namespace DFG {
+
+void PureValue::dump(PrintStream&amp; out) const
+{
+    out.print(Graph::opName(op()));
+    out.print(&quot;(&quot;);
+    CommaPrinter comma;
+    for (unsigned i = 0; i &lt; AdjacencyList::Size; ++i) {
+        if (children().child(i))
+            out.print(comma, children().child(i));
+    }
+    if (m_info)
+        out.print(comma, m_info);
+    out.print(&quot;)&quot;);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPureValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGPureValue.h (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPureValue.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGPureValue.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,145 @@
</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 DFGPureValue_h
+#define DFGPureValue_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGNode.h&quot;
+
+namespace JSC { namespace DFG {
+
+class PureValue {
+public:
+    PureValue()
+        : m_op(LastNodeType)
+        , m_info(0)
+    {
+    }
+    
+    PureValue(NodeType op, const AdjacencyList&amp; children, uintptr_t info)
+        : m_op(op)
+        , m_children(children.sanitized())
+        , m_info(info)
+    {
+        ASSERT(!(defaultFlags(op) &amp; NodeHasVarArgs));
+    }
+    
+    PureValue(NodeType op, const AdjacencyList&amp; children, const void* ptr)
+        : PureValue(op, children, bitwise_cast&lt;uintptr_t&gt;(ptr))
+    {
+    }
+    
+    PureValue(NodeType op, const AdjacencyList&amp; children)
+        : PureValue(op, children, static_cast&lt;uintptr_t&gt;(0))
+    {
+    }
+    
+    PureValue(Node* node, uintptr_t info)
+        : PureValue(node-&gt;op(), node-&gt;children, info)
+    {
+    }
+    
+    PureValue(Node* node, const void* ptr)
+        : PureValue(node-&gt;op(), node-&gt;children, ptr)
+    {
+    }
+    
+    PureValue(Node* node)
+        : PureValue(node-&gt;op(), node-&gt;children)
+    {
+    }
+    
+    PureValue(WTF::HashTableDeletedValueType)
+        : m_op(LastNodeType)
+        , m_info(1)
+    {
+    }
+    
+    bool operator!() const { return m_op == LastNodeType &amp;&amp; !m_info; }
+    
+    NodeType op() const { return m_op; }
+    const AdjacencyList&amp; children() const { return m_children; }
+    uintptr_t info() const { return m_info; }
+
+    unsigned hash() const
+    {
+        return WTF::IntHash&lt;int&gt;::hash(static_cast&lt;int&gt;(m_op)) + m_children.hash() + m_info;
+    }
+    
+    bool operator==(const PureValue&amp; other) const
+    {
+        return m_op == other.m_op
+            &amp;&amp; m_children == other.m_children
+            &amp;&amp; m_info == other.m_info;
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_op == LastNodeType &amp;&amp; m_info;
+    }
+    
+    void dump(PrintStream&amp; out) const;
+    
+private:
+    NodeType m_op;
+    AdjacencyList m_children;
+    uintptr_t m_info;
+};
+
+struct PureValueHash {
+    static unsigned hash(const PureValue&amp; key) { return key.hash(); }
+    static bool equal(const PureValue&amp; a, const PureValue&amp; b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+template&lt;typename T&gt; struct DefaultHash;
+template&lt;&gt; struct DefaultHash&lt;JSC::DFG::PureValue&gt; {
+    typedef JSC::DFG::PureValueHash Hash;
+};
+
+template&lt;typename T&gt; struct HashTraits;
+template&lt;&gt; struct HashTraits&lt;JSC::DFG::PureValue&gt; : SimpleClassHashTraits&lt;JSC::DFG::PureValue&gt; {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+namespace JSC { namespace DFG {
+
+typedef HashMap&lt;PureValue, Node*&gt; PureMap;
+typedef HashMap&lt;PureValue, Vector&lt;Node*&gt;&gt; PureMultiMap;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPureValue_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSSAConversionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -246,7 +246,7 @@
</span><span class="cx">                         block-&gt;variablesAtHead.operand(phi-&gt;local()), &quot;\n&quot;);
</span><span class="cx">                 }
</span><span class="cx">                 ASSERT(phi != block-&gt;variablesAtHead.operand(phi-&gt;local()));
</span><del>-                phi-&gt;misc.replacement = block-&gt;variablesAtHead.operand(phi-&gt;local());
</del><ins>+                phi-&gt;replacement = block-&gt;variablesAtHead.operand(phi-&gt;local());
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -261,9 +261,9 @@
</span><span class="cx">                 Node* node = block-&gt;variablesAtHead[i];
</span><span class="cx">                 if (!node)
</span><span class="cx">                     continue;
</span><del>-                while (node-&gt;misc.replacement) {
-                    ASSERT(node != node-&gt;misc.replacement);
-                    node = node-&gt;misc.replacement;
</del><ins>+                while (node-&gt;replacement) {
+                    ASSERT(node != node-&gt;replacement);
+                    node = node-&gt;replacement;
</ins><span class="cx">                 }
</span><span class="cx">                 block-&gt;variablesAtHead[i] = node;
</span><span class="cx">             }
</span><span class="lines">@@ -301,11 +301,11 @@
</span><span class="cx">                 continue;
</span><span class="cx">             
</span><span class="cx">             for (unsigned phiIndex = block-&gt;phis.size(); phiIndex--;) {
</span><del>-                block-&gt;phis[phiIndex]-&gt;misc.replacement =
</del><ins>+                block-&gt;phis[phiIndex]-&gt;replacement =
</ins><span class="cx">                     block-&gt;variablesAtHead.operand(block-&gt;phis[phiIndex]-&gt;local());
</span><span class="cx">             }
</span><span class="cx">             for (unsigned nodeIndex = block-&gt;size(); nodeIndex--;)
</span><del>-                ASSERT(!block-&gt;at(nodeIndex)-&gt;misc.replacement);
</del><ins>+                ASSERT(!block-&gt;at(nodeIndex)-&gt;replacement);
</ins><span class="cx">             
</span><span class="cx">             for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
</span><span class="cx">                 Node* node = block-&gt;at(nodeIndex);
</span><span class="lines">@@ -319,7 +319,7 @@
</span><span class="cx">                         node-&gt;mergeFlags(NodeMustGenerate);
</span><span class="cx">                     else
</span><span class="cx">                         node-&gt;setOpAndDefaultFlags(Check);
</span><del>-                    node-&gt;misc.replacement = node-&gt;child1().node(); // Only for Upsilons.
</del><ins>+                    node-&gt;replacement = node-&gt;child1().node(); // Only for Upsilons.
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                     
</span><span class="lines">@@ -333,7 +333,7 @@
</span><span class="cx">                     if (variable-&gt;isCaptured())
</span><span class="cx">                         break;
</span><span class="cx">                     node-&gt;convertToPhantom();
</span><del>-                    node-&gt;misc.replacement = block-&gt;variablesAtHead.operand(variable-&gt;local());
</del><ins>+                    node-&gt;replacement = block-&gt;variablesAtHead.operand(variable-&gt;local());
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                     
</span><span class="lines">@@ -342,7 +342,7 @@
</span><span class="cx">                     node-&gt;convertToPhantom();
</span><span class="cx">                     // This is only for Upsilons. An Upsilon will only refer to a Flush if
</span><span class="cx">                     // there were no SetLocals or GetLocals in the block.
</span><del>-                    node-&gt;misc.replacement = block-&gt;variablesAtHead.operand(node-&gt;local());
</del><ins>+                    node-&gt;replacement = block-&gt;variablesAtHead.operand(node-&gt;local());
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                     
</span><span class="lines">@@ -367,7 +367,7 @@
</span><span class="cx">                     node-&gt;convertToPhantom();
</span><span class="cx">                     // This is only for Upsilons. An Upsilon will only refer to a
</span><span class="cx">                     // PhantomLocal if there were no SetLocals or GetLocals in the block.
</span><del>-                    node-&gt;misc.replacement = block-&gt;variablesAtHead.operand(variable-&gt;local());
</del><ins>+                    node-&gt;replacement = block-&gt;variablesAtHead.operand(variable-&gt;local());
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                     
</span><span class="lines">@@ -398,7 +398,7 @@
</span><span class="cx">             block-&gt;variablesAtTail.clear();
</span><span class="cx">             block-&gt;valuesAtHead.clear();
</span><span class="cx">             block-&gt;valuesAtHead.clear();
</span><del>-            block-&gt;ssa = adoptPtr(new BasicBlock::SSAData(block));
</del><ins>+            block-&gt;ssa = std::make_unique&lt;BasicBlock::SSAData&gt;(block);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         m_graph.m_arguments.clear();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -28,6 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;DFGAbstractHeap.h&quot;
+#include &quot;DFGClobberize.h&quot;
</ins><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;DFGInsertionSet.h&quot;
</span><span class="cx"> #include &quot;DFGPhase.h&quot;
</span><span class="lines">@@ -216,6 +218,76 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case Flush: {
+            ASSERT(m_graph.m_form != SSA);
+            
+            Node* setLocal = nullptr;
+            VirtualRegister local = m_node-&gt;local();
+            
+            if (m_node-&gt;variableAccessData()-&gt;isCaptured()) {
+                for (unsigned i = m_nodeIndex; i--;) {
+                    Node* node = m_block-&gt;at(i);
+                    bool done = false;
+                    switch (node-&gt;op()) {
+                    case GetLocal:
+                    case Flush:
+                        if (node-&gt;local() == local)
+                            done = true;
+                        break;
+                
+                    case GetLocalUnlinked:
+                        if (node-&gt;unlinkedLocal() == local)
+                            done = true;
+                        break;
+                
+                    case SetLocal: {
+                        if (node-&gt;local() != local)
+                            break;
+                        setLocal = node;
+                        done = true;
+                        break;
+                    }
+                
+                    case Phantom:
+                    case Check:
+                    case HardPhantom:
+                    case MovHint:
+                    case JSConstant:
+                    case DoubleConstant:
+                    case Int52Constant:
+                        break;
+                
+                    default:
+                        done = true;
+                        break;
+                    }
+                    if (done)
+                        break;
+                }
+            } else {
+                for (unsigned i = m_nodeIndex; i--;) {
+                    Node* node = m_block-&gt;at(i);
+                    if (node-&gt;op() == SetLocal &amp;&amp; node-&gt;local() == local) {
+                        setLocal = node;
+                        break;
+                    }
+                    if (accessesOverlap(m_graph, node, AbstractHeap(Variables, local)))
+                        break;
+                }
+            }
+            
+            if (!setLocal)
+                break;
+            
+            m_node-&gt;convertToPhantom();
+            Node* dataNode = setLocal-&gt;child1().node();
+            DFG_ASSERT(m_graph, m_node, dataNode-&gt;hasResult());
+            m_node-&gt;child1() = dataNode-&gt;defaultEdge();
+            m_graph.dethread();
+            m_changed = true;
+            break;
+        }
+            
</ins><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -86,7 +86,6 @@
</span><span class="cx">                 case MultiGetByOffset:
</span><span class="cx">                     for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;) {
</span><span class="cx">                         GetByIdVariant&amp; variant = node-&gt;multiGetByOffsetData().variants[i];
</span><del>-                        tryWatch(m_graph.freeze(variant.specificValue())-&gt;structure());
</del><span class="cx">                         tryWatch(variant.structureSet());
</span><span class="cx">                         // Don't need to watch anything in the structure chain because that would
</span><span class="cx">                         // have been decomposed into CheckStructure's. Don't need to watch the
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -166,6 +166,10 @@
</span><span class="cx">         // case because it would prevent us from catching bugs where the FTL backend
</span><span class="cx">         // pipeline failed to optimize out an Identity.
</span><span class="cx">         break;
</span><ins>+    case In:
+        if (node-&gt;child2().useKind() == CellUse)
+            break;
+        return CannotCompile;
</ins><span class="cx">     case PutByIdDirect:
</span><span class="cx">     case PutById:
</span><span class="cx">         if (node-&gt;child1().useKind() == CellUse)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -166,6 +166,68 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void generateCheckInICFastPath(
+    State&amp; state, CodeBlock* codeBlock, GeneratedFunction generatedFunction,
+    StackMaps::RecordMap&amp; recordMap, CheckInDescriptor&amp; ic, size_t sizeOfIC)
+{
+    VM&amp; vm = state.graph.m_vm;
+
+    StackMaps::RecordMap::iterator iter = recordMap.find(ic.stackmapID());
+    if (iter == recordMap.end()) {
+        // It was optimized out.
+        return;
+    }
+    
+    Vector&lt;StackMaps::Record&gt;&amp; records = iter-&gt;value;
+    
+    RELEASE_ASSERT(records.size() == ic.m_generators.size());
+
+    for (unsigned i = records.size(); i--;) {
+        StackMaps::Record&amp; record = records[i];
+        auto generator = ic.m_generators[i];
+
+        StructureStubInfo&amp; stubInfo = *generator.m_stub;
+        auto call = generator.m_slowCall;
+        auto slowPathBegin = generator.m_beginLabel;
+
+        CCallHelpers fastPathJIT(&amp;vm, codeBlock);
+        
+        auto jump = fastPathJIT.patchableJump();
+        auto done = fastPathJIT.label();
+
+        char* startOfIC =
+            bitwise_cast&lt;char*&gt;(generatedFunction) + record.instructionOffset;
+        
+        LinkBuffer fastPath(vm, fastPathJIT, startOfIC, sizeOfIC);
+        LinkBuffer&amp; slowPath = *state.finalizer-&gt;sideCodeLinkBuffer;
+        // Note: we could handle the !isValid() case. We just don't appear to have a
+        // reason to do so, yet.
+        RELEASE_ASSERT(fastPath.isValid());
+
+        MacroAssembler::AssemblerType_T::fillNops(
+            startOfIC + fastPath.size(), sizeOfIC - fastPath.size());
+        
+        state.finalizer-&gt;sideCodeLinkBuffer-&gt;link(
+            ic.m_slowPathDone[i], CodeLocationLabel(startOfIC + sizeOfIC));
+        
+        CodeLocationLabel slowPathBeginLoc = slowPath.locationOf(slowPathBegin);
+        fastPath.link(jump, slowPathBeginLoc);
+
+        CodeLocationCall callReturnLocation = fastPath.locationOf(call);
+
+        stubInfo.patch.deltaCallToDone = MacroAssembler::differenceBetweenCodePtr(
+            callReturnLocation, fastPath.locationOf(done));
+
+        stubInfo.patch.deltaCallToJump = MacroAssembler::differenceBetweenCodePtr(
+            callReturnLocation, fastPath.locationOf(jump));
+        stubInfo.callReturnLocation = callReturnLocation;
+        stubInfo.patch.deltaCallToSlowCase = MacroAssembler::differenceBetweenCodePtr(
+            callReturnLocation, slowPathBeginLoc);
+        
+    }
+}
+
+
</ins><span class="cx"> static RegisterSet usedRegistersFor(const StackMaps::Record&amp; record)
</span><span class="cx"> {
</span><span class="cx">     if (Options::assumeAllRegsInFTLICAreLive())
</span><span class="lines">@@ -290,7 +352,7 @@
</span><span class="cx">         state.finalizer-&gt;exitThunksLinkBuffer = linkBuffer.release();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!state.getByIds.isEmpty() || !state.putByIds.isEmpty()) {
</del><ins>+    if (!state.getByIds.isEmpty() || !state.putByIds.isEmpty() || !state.checkIns.isEmpty()) {
</ins><span class="cx">         CCallHelpers slowPathJIT(&amp;vm, codeBlock);
</span><span class="cx">         
</span><span class="cx">         CCallHelpers::JumpList exceptionTarget;
</span><span class="lines">@@ -320,13 +382,13 @@
</span><span class="cx">                     JSValueRegs(result), NeedToSpill);
</span><span class="cx">                 
</span><span class="cx">                 MacroAssembler::Label begin = slowPathJIT.label();
</span><del>-                
</del><ins>+
</ins><span class="cx">                 MacroAssembler::Call call = callOperation(
</span><span class="cx">                     state, usedRegisters, slowPathJIT, getById.codeOrigin(), &amp;exceptionTarget,
</span><span class="cx">                     operationGetByIdOptimize, result, gen.stubInfo(), base, getById.uid());
</span><del>-                
</del><ins>+
</ins><span class="cx">                 gen.reportSlowPathCall(begin, call);
</span><del>-                
</del><ins>+
</ins><span class="cx">                 getById.m_slowPathDone.append(slowPathJIT.jump());
</span><span class="cx">                 getById.m_generators.append(gen);
</span><span class="cx">             }
</span><span class="lines">@@ -369,6 +431,44 @@
</span><span class="cx">                 putById.m_generators.append(gen);
</span><span class="cx">             }
</span><span class="cx">         }
</span><ins>+
+
+        for (unsigned i = state.checkIns.size(); i--;) {
+            CheckInDescriptor&amp; checkIn = state.checkIns[i];
+            
+            if (verboseCompilationEnabled())
+                dataLog(&quot;Handling checkIn stackmap #&quot;, checkIn.stackmapID(), &quot;\n&quot;);
+            
+            iter = recordMap.find(checkIn.stackmapID());
+            if (iter == recordMap.end()) {
+                // It was optimized out.
+                continue;
+            }
+            
+            for (unsigned i = 0; i &lt; iter-&gt;value.size(); ++i) {
+                StackMaps::Record&amp; record = iter-&gt;value[i];
+                RegisterSet usedRegisters = usedRegistersFor(record);
+                GPRReg result = record.locations[0].directGPR();
+                GPRReg obj = record.locations[1].directGPR();
+                StructureStubInfo* stubInfo = codeBlock-&gt;addStubInfo(); 
+                stubInfo-&gt;codeOrigin = checkIn.codeOrigin();
+                stubInfo-&gt;patch.baseGPR = static_cast&lt;int8_t&gt;(obj);
+                stubInfo-&gt;patch.valueGPR = static_cast&lt;int8_t&gt;(result);
+                stubInfo-&gt;patch.usedRegisters = usedRegisters;
+                stubInfo-&gt;patch.spillMode = NeedToSpill;
+
+                MacroAssembler::Label begin = slowPathJIT.label();
+
+                MacroAssembler::Call slowCall = callOperation(
+                    state, usedRegisters, slowPathJIT, checkIn.codeOrigin(), &amp;exceptionTarget,
+                    operationInOptimize, result, stubInfo, obj, checkIn.m_id);
+
+                checkIn.m_slowPathDone.append(slowPathJIT.jump());
+                
+                checkIn.m_generators.append(CheckInGenerator(stubInfo, slowCall, begin));
+            }
+        }
+
</ins><span class="cx">         
</span><span class="cx">         exceptionTarget.link(&amp;slowPathJIT);
</span><span class="cx">         MacroAssembler::Jump exceptionJump = slowPathJIT.jump();
</span><span class="lines">@@ -388,6 +488,12 @@
</span><span class="cx">                 state, codeBlock, generatedFunction, recordMap, state.putByIds[i],
</span><span class="cx">                 sizeOfPutById());
</span><span class="cx">         }
</span><ins>+
+        for (unsigned i = state.checkIns.size(); i--;) {
+            generateCheckInICFastPath(
+                state, codeBlock, generatedFunction, recordMap, state.checkIns[i],
+                sizeOfCheckIn()); 
+        } 
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Handling JS calls is weird: we need to ensure that we sort them by the PC in LLVM
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLForOSREntryJITCodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLForOSREntryJITCode.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLForOSREntryJITCode.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLForOSREntryJITCode.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -31,6 +31,8 @@
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><span class="cx"> ForOSREntryJITCode::ForOSREntryJITCode()
</span><ins>+    : m_bytecodeIndex(UINT_MAX)
+    , m_entryFailureCount(0)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLInlineCacheDescriptorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -94,6 +94,35 @@
</span><span class="cx">     PutKind m_putKind;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct CheckInGenerator {
+    StructureStubInfo* m_stub;
+    MacroAssembler::Call m_slowCall;
+    MacroAssembler::Label m_beginLabel;
+
+    CheckInGenerator(StructureStubInfo* stub, MacroAssembler::Call slowCall, MacroAssembler::Label beginLabel)
+        : m_stub(stub) 
+        , m_slowCall(slowCall)
+        , m_beginLabel(beginLabel)
+    {
+    }
+};
+
+class CheckInDescriptor : public InlineCacheDescriptor {
+public:
+    CheckInDescriptor() { }
+    
+    CheckInDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const StringImpl* id)
+        : InlineCacheDescriptor(stackmapID, codeOrigin, nullptr)
+        , m_id(id)
+    {
+    }
+
+    
+    const StringImpl* m_id;
+    Vector&lt;CheckInGenerator&gt; m_generators;
+};
+
+
</ins><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLInlineCacheSizecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -61,6 +61,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+size_t sizeOfCheckIn()
+{
+#if CPU(ARM64)
+    return 4;
+#else
+    return 5; 
+#endif
+}
+
+
</ins><span class="cx"> size_t sizeOfCall()
</span><span class="cx"> {
</span><span class="cx"> #if CPU(ARM64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLInlineCacheSizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> size_t sizeOfGetById();
</span><span class="cx"> size_t sizeOfPutById();
</span><span class="cx"> size_t sizeOfCall();
</span><ins>+size_t sizeOfCheckIn();
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx">     macro(J_JITOperation_E, functionType(int64, intPtr)) \
</span><span class="cx">     macro(J_JITOperation_EA, functionType(int64, intPtr, intPtr)) \
</span><span class="cx">     macro(J_JITOperation_EAZ, functionType(int64, intPtr, intPtr, int32)) \
</span><ins>+    macro(J_JITOperation_ECJ, functionType(int64, intPtr, intPtr, int64)) \
</ins><span class="cx">     macro(J_JITOperation_EDA, functionType(int64, intPtr, doubleType, intPtr)) \
</span><span class="cx">     macro(J_JITOperation_EJ, functionType(int64, intPtr, int64)) \
</span><span class="cx">     macro(J_JITOperation_EJA, functionType(int64, intPtr, int64, intPtr)) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -144,7 +144,7 @@
</span><span class="cx">         createPhiVariables();
</span><span class="cx"> 
</span><span class="cx">         Vector&lt;BasicBlock*&gt; depthFirst;
</span><del>-        m_graph.getBlocksInDepthFirstOrder(depthFirst);
</del><ins>+        m_graph.getBlocksInPreOrder(depthFirst);
</ins><span class="cx"> 
</span><span class="cx">         int maxNumberOfArguments = -1;
</span><span class="cx">         for (unsigned blockIndex = depthFirst.size(); blockIndex--; ) {
</span><span class="lines">@@ -479,8 +479,11 @@
</span><span class="cx">         case GetById:
</span><span class="cx">             compileGetById();
</span><span class="cx">             break;
</span><ins>+        case In:
+            compileIn();
+            break;
+        case PutById:
</ins><span class="cx">         case PutByIdDirect:
</span><del>-        case PutById:
</del><span class="cx">             compilePutById();
</span><span class="cx">             break;
</span><span class="cx">         case GetButterfly:
</span><span class="lines">@@ -3280,8 +3283,13 @@
</span><span class="cx">             
</span><span class="cx">             GetByIdVariant variant = data.variants[i];
</span><span class="cx">             LValue result;
</span><del>-            if (variant.specificValue())
-                result = m_out.constInt64(JSValue::encode(variant.specificValue()));
</del><ins>+            JSValue constantResult;
+            if (variant.alternateBase()) {
+                constantResult = m_graph.tryGetConstantProperty(
+                    variant.alternateBase(), variant.baseStructure(), variant.offset());
+            }
+            if (constantResult)
+                result = m_out.constInt64(JSValue::encode(constantResult));
</ins><span class="cx">             else {
</span><span class="cx">                 LValue propertyBase;
</span><span class="cx">                 if (variant.alternateBase())
</span><span class="lines">@@ -3974,6 +3982,33 @@
</span><span class="cx">         setBoolean(m_out.notNull(pointerResult));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void compileIn()
+    {
+        Edge base = m_node-&gt;child2();
+        LValue cell = lowCell(base);
+        speculateObject(base, cell);
+        if (JSString* string = m_node-&gt;child1()-&gt;dynamicCastConstant&lt;JSString*&gt;()) {
+            if (string-&gt;tryGetValueImpl() &amp;&amp; string-&gt;tryGetValueImpl()-&gt;isAtomic()) {
+
+                const StringImpl* str = string-&gt;tryGetValueImpl();
+                unsigned stackmapID = m_stackmapIDs++;
+            
+                LValue call = m_out.call(
+                    m_out.patchpointInt64Intrinsic(),
+                    m_out.constInt64(stackmapID), m_out.constInt32(sizeOfCheckIn()),
+                    constNull(m_out.ref8), m_out.constInt32(1), cell);
+
+                setInstructionCallingConvention(call, LLVMAnyRegCallConv);
+
+                m_ftlState.checkIns.append(CheckInDescriptor(stackmapID, m_node-&gt;origin.semantic, str));
+                setJSValue(call);
+                return;
+            }
+        } 
+
+        setJSValue(vmCall(m_out.operation(operationGenericIn), m_callFrame, cell, lowJSValue(m_node-&gt;child1())));
+    }
+
</ins><span class="cx">     void compileCheckHasInstance()
</span><span class="cx">     {
</span><span class="cx">         speculate(
</span><span class="lines">@@ -5115,7 +5150,7 @@
</span><span class="cx">     
</span><span class="cx">     LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
</span><span class="cx">     {
</span><del>-        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
</del><ins>+        DFG_ASSERT(m_graph, m_node, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
</ins><span class="cx">         
</span><span class="cx">         if (edge-&gt;op() == JSConstant) {
</span><span class="cx">             JSValue value = edge-&gt;asJSValue();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSREntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -54,9 +54,12 @@
</span><span class="cx">             bytecodeIndex, &quot;.\n&quot;);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    if (bytecodeIndex)
+        jsCast&lt;ScriptExecutable*&gt;(executable)-&gt;setDidTryToEnterInLoop(true);
+
</ins><span class="cx">     if (bytecodeIndex != entryCode-&gt;bytecodeIndex()) {
</span><span class="cx">         if (Options::verboseOSR())
</span><del>-            dataLog(&quot;    OSR failed because we don't have an entrypoint for bc#&quot;, bytecodeIndex, &quot;; ours is for bc#&quot;, entryCode-&gt;bytecodeIndex());
</del><ins>+            dataLog(&quot;    OSR failed because we don't have an entrypoint for bc#&quot;, bytecodeIndex, &quot;; ours is for bc#&quot;, entryCode-&gt;bytecodeIndex(), &quot;\n&quot;);
</ins><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLSlowPathCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -176,6 +176,19 @@
</span><span class="cx"> MacroAssembler::Call callOperation(
</span><span class="cx">     State&amp; state, const RegisterSet&amp; usedRegisters, CCallHelpers&amp; jit,
</span><span class="cx">     CodeOrigin codeOrigin, MacroAssembler::JumpList* exceptionTarget,
</span><ins>+    J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo,
+    GPRReg object, const StringImpl* uid)
+{
+    storeCodeOrigin(state, jit, codeOrigin);
+    CallContext context(state, usedRegisters, jit, 4, result);
+    jit.setupArgumentsWithExecState(
+        CCallHelpers::TrustedImmPtr(stubInfo), object, CCallHelpers::TrustedImmPtr(uid));
+    return context.makeCall(bitwise_cast&lt;void*&gt;(operation), exceptionTarget);
+}
+
+MacroAssembler::Call callOperation(
+    State&amp; state, const RegisterSet&amp; usedRegisters, CCallHelpers&amp; jit,
+    CodeOrigin codeOrigin, MacroAssembler::JumpList* exceptionTarget,
</ins><span class="cx">     J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo,
</span><span class="cx">     GPRReg object, StringImpl* uid)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLSlowPathCallh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -59,6 +59,10 @@
</span><span class="cx"> 
</span><span class="cx"> MacroAssembler::Call callOperation(
</span><span class="cx">     State&amp;, const RegisterSet&amp;, CCallHelpers&amp;, CodeOrigin, CCallHelpers::JumpList*,
</span><ins>+    J_JITOperation_ESsiCI, GPRReg, StructureStubInfo*, GPRReg,
+    const StringImpl*);
+MacroAssembler::Call callOperation(
+    State&amp;, const RegisterSet&amp;, CCallHelpers&amp;, CodeOrigin, CCallHelpers::JumpList*,
</ins><span class="cx">     J_JITOperation_ESsiJI, GPRReg result, StructureStubInfo*, GPRReg object,
</span><span class="cx">     StringImpl* uid);
</span><span class="cx"> MacroAssembler::Call callOperation(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLState.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLState.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/ftl/FTLState.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     unsigned capturedStackmapID;
</span><span class="cx">     SegmentedVector&lt;GetByIdDescriptor&gt; getByIds;
</span><span class="cx">     SegmentedVector&lt;PutByIdDescriptor&gt; putByIds;
</span><ins>+    SegmentedVector&lt;CheckInDescriptor&gt; checkIns;
</ins><span class="cx">     Vector&lt;JSCall&gt; jsCalls;
</span><span class="cx">     Vector&lt;CString&gt; codeSectionNames;
</span><span class="cx">     Vector&lt;CString&gt; dataSectionNames;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSJavaScriptCallFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> 
</span><ins>+#include &quot;DebuggerScope.h&quot;
</ins><span class="cx"> #include &quot;Error.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;JSCellInlines.h&quot;
</span><span class="lines">@@ -95,29 +96,30 @@
</span><span class="cx">         return jsUndefined();
</span><span class="cx">     int index = exec-&gt;argument(0).asInt32();
</span><span class="cx"> 
</span><del>-    JSScope* scopeChain = impl().scopeChain();
-    ScopeChainIterator end = scopeChain-&gt;end();
</del><ins>+    DebuggerScope* scopeChain = impl().scopeChain();
+    DebuggerScope::Iterator end = scopeChain-&gt;end();
</ins><span class="cx"> 
</span><del>-    // FIXME: We should be identifying and returning CATCH_SCOPE appropriately.
</del><ins>+    bool foundLocalScope = false;
+    for (DebuggerScope::Iterator iter = scopeChain-&gt;begin(); iter != end; ++iter) {
+        DebuggerScope* scope = iter.get();
</ins><span class="cx"> 
</span><del>-    bool foundLocalScope = false;
-    for (ScopeChainIterator iter = scopeChain-&gt;begin(); iter != end; ++iter) {
-        JSObject* scope = iter.get();
-        if (scope-&gt;isActivationObject()) {
-            if (!foundLocalScope) {
-                // First activation object is local scope, each successive activation object is closure.
-                if (!index)
-                    return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
-                foundLocalScope = true;
-            } else if (!index)
-                return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
</del><ins>+        if (!foundLocalScope &amp;&amp; scope-&gt;isFunctionScope()) {
+            // First function scope is the local scope, each successive one is a closure.
+            if (!index)
+                return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
+            foundLocalScope = true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!index) {
</span><del>-            // Last in the chain is global scope.
-            if (++iter == end)
</del><ins>+            if (scope-&gt;isWithScope())
+                return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
+            if (scope-&gt;isGlobalScope()) {
+                ASSERT(++iter == end);
</ins><span class="cx">                 return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
</span><del>-            return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
</del><ins>+            }
+            // FIXME: We should be identifying and returning CATCH_SCOPE appropriately.
+            ASSERT(scope-&gt;isFunctionScope());
+            return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         --index;
</span><span class="lines">@@ -157,9 +159,9 @@
</span><span class="cx">     if (!impl().scopeChain())
</span><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><del>-    JSScope* scopeChain = impl().scopeChain();
-    ScopeChainIterator iter = scopeChain-&gt;begin();
-    ScopeChainIterator end = scopeChain-&gt;end();
</del><ins>+    DebuggerScope* scopeChain = impl().scopeChain();
+    DebuggerScope::Iterator iter = scopeChain-&gt;begin();
+    DebuggerScope::Iterator end = scopeChain-&gt;end();
</ins><span class="cx"> 
</span><span class="cx">     // We must always have something in the scope chain.
</span><span class="cx">     ASSERT(iter != end);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJavaScriptCallFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JavaScriptCallFrame.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JavaScriptCallFrame.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/inspector/JavaScriptCallFrame.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2013 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2008, 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">@@ -53,7 +53,7 @@
</span><span class="cx"> 
</span><span class="cx">     String functionName() const { return m_debuggerCallFrame-&gt;functionName(); }
</span><span class="cx">     JSC::DebuggerCallFrame::Type type() const { return m_debuggerCallFrame-&gt;type(); }
</span><del>-    JSC::JSScope* scopeChain() const { return m_debuggerCallFrame-&gt;scope(); }
</del><ins>+    JSC::DebuggerScope* scopeChain() const { return m_debuggerCallFrame-&gt;scope(); }
</ins><span class="cx">     JSC::JSGlobalObject* vmEntryGlobalObject() const { return m_debuggerCallFrame-&gt;vmEntryGlobalObject(); }
</span><span class="cx"> 
</span><span class="cx">     JSC::JSValue thisValue() const { return m_debuggerCallFrame-&gt;thisValue(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptDebugServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DebuggerCallFrame.h&quot;
</span><ins>+#include &quot;DebuggerScope.h&quot;
</ins><span class="cx"> #include &quot;JSJavaScriptCallFrame.h&quot;
</span><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="cx"> #include &quot;JavaScriptCallFrame.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -191,10 +191,10 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange(ErrorString*, const String&amp; in_variableName, const String&amp; in_id, int in_startLine, int in_startColumn, int in_endLine, int in_endColumn, String* out_types) 
</del><ins>+void InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset(ErrorString*, const String&amp; in_variableName, const String&amp; in_id, int in_divot, String* out_types) 
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = globalVM();
</span><del>-    String types(vm.getTypesForVariableInRange(in_startLine, in_startColumn, in_endLine, in_endColumn, in_variableName, in_id));
</del><ins>+    String types(vm.getTypesForVariableAtOffset(in_divot, in_variableName, in_id));
</ins><span class="cx">     *out_types = types;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">     virtual void getProperties(ErrorString*, const String&amp; objectId, const bool* ownProperties, RefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::TypeBuilder::Runtime::PropertyDescriptor&gt;&gt;&amp; result, RefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor&gt;&gt;&amp; internalProperties) override final;
</span><span class="cx">     virtual void releaseObjectGroup(ErrorString*, const String&amp; objectGroup) override final;
</span><span class="cx">     virtual void run(ErrorString*) override;
</span><del>-    virtual void getRuntimeTypeForVariableInTextRange(ErrorString*, const String&amp; in_variableName, const String&amp; in_id, int in_startLine, int in_startColumn, int in_endLine, int in_endColumn, String* out_types) override;
</del><ins>+    virtual void getRuntimeTypeForVariableAtOffset(ErrorString*, const String&amp; in_variableName, const String&amp; in_id, int in_divot, String* out_types) override;
</ins><span class="cx"> 
</span><span class="cx">     void setScriptDebugServer(ScriptDebugServer* scriptDebugServer) { m_scriptDebugServer = scriptDebugServer; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolRuntimejson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -198,14 +198,11 @@
</span><span class="cx">             &quot;description&quot;: &quot;Disables reporting of execution contexts creation.&quot;
</span><span class="cx">         },
</span><span class="cx">         {
</span><del>-            &quot;name&quot;: &quot;getRuntimeTypeForVariableInTextRange&quot;,
</del><ins>+            &quot;name&quot;: &quot;getRuntimeTypeForVariableAtOffset&quot;,
</ins><span class="cx">             &quot;parameters&quot;: [
</span><span class="cx">                 { &quot;name&quot;: &quot;variableName&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;Variable we want type infromation for.&quot; },
</span><span class="cx">                 { &quot;name&quot;: &quot;sourceID&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;sourceID uniquely identifying a script&quot; },
</span><del>-                { &quot;name&quot;: &quot;startLine&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;start line for variable name&quot; },
-                { &quot;name&quot;: &quot;startColumn&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;start column for variable name&quot; },
-                { &quot;name&quot;: &quot;endLine&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;end line for variable name&quot; },
-                { &quot;name&quot;: &quot;endColumn&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;end column for variable name&quot; }
</del><ins>+                { &quot;name&quot;: &quot;divot&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;character offset for assignment range&quot; }
</ins><span class="cx">             ],
</span><span class="cx">             &quot;returns&quot;: [
</span><span class="cx">                 { &quot;name&quot;: &quot;types&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;Types for requested variable.&quot; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1181,7 +1181,7 @@
</span><span class="cx">     if (numVariables || numFunctions) {
</span><span class="cx">         BatchedTransitionOptimizer optimizer(vm, variableObject);
</span><span class="cx">         if (variableObject-&gt;next())
</span><del>-            variableObject-&gt;globalObject()-&gt;varInjectionWatchpoint()-&gt;fireAll();
</del><ins>+            variableObject-&gt;globalObject()-&gt;varInjectionWatchpoint()-&gt;fireAll(&quot;Executed eval, fired VarInjection watchpoint&quot;);
</ins><span class="cx"> 
</span><span class="cx">         for (unsigned i = 0; i &lt; numVariables; ++i) {
</span><span class="cx">             const Identifier&amp; ident = codeBlock-&gt;variable(i);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1694,9 +1694,13 @@
</span><span class="cx">     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
</span><span class="cx">     if (slot.isCacheableValue() &amp;&amp; slot.slotBase() == scope &amp;&amp; scope-&gt;structure(vm)-&gt;propertyAccessesAreCacheable()) {
</span><span class="cx">         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
</span><del>-            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
-            pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), scope-&gt;structure(vm));
-            pc[6].u.operand = slot.cachedOffset();
</del><ins>+            Structure* structure = scope-&gt;structure(vm);
+            {
+                ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
+                pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), structure);
+                pc[6].u.operand = slot.cachedOffset();
+            }
+            structure-&gt;startWatchingPropertyForReplacements(vm, slot.cachedOffset());
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1726,14 +1730,7 @@
</span><span class="cx">     if (exec-&gt;vm().exception())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
-    if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
-        if (slot.isCacheablePut() &amp;&amp; slot.base() == scope &amp;&amp; scope-&gt;structure()-&gt;propertyAccessesAreCacheable()) {
-            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
-            pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), scope-&gt;structure());
-            pc[6].u.operand = slot.cachedOffset();
-        }
-    }
</del><ins>+    CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -204,9 +204,9 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetById(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*) WTF_INTERNAL;
</span><del>-EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, StringImpl*);
-EncodedJSValue JIT_OPERATION operationIn(ExecState*, StructureStubInfo*, JSCell*, StringImpl*);
-EncodedJSValue JIT_OPERATION operationGenericIn(ExecState*, JSCell*, EncodedJSValue);
</del><ins>+EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, StringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationIn(ExecState*, StructureStubInfo*, JSCell*, StringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGenericIn(ExecState*, JSCell*, EncodedJSValue) WTF_INTERNAL;
</ins><span class="cx"> void JIT_OPERATION operationPutByIdStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationPutByIdNonStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationPutByIdDirectStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -97,12 +97,14 @@
</span><span class="cx">     repatchCall(repatchBuffer, call, newCalleeFunction);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void repatchByIdSelfAccess(VM&amp; vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, Structure* structure, const Identifier&amp; propertyName, PropertyOffset offset,
-    const FunctionPtr &amp;slowPathFunction, bool compact)
</del><ins>+static void repatchByIdSelfAccess(
+    VM&amp; vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, Structure* structure,
+    const Identifier&amp; propertyName, PropertyOffset offset, const FunctionPtr &amp;slowPathFunction,
+    bool compact)
</ins><span class="cx"> {
</span><span class="cx">     if (structure-&gt;typeInfo().newImpurePropertyFiresWatchpoints())
</span><span class="cx">         vm.registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
</span><del>-
</del><ins>+    
</ins><span class="cx">     RepatchBuffer repatchBuffer(codeBlock);
</span><span class="cx"> 
</span><span class="cx">     // Only optimize once!
</span><span class="lines">@@ -355,8 +357,10 @@
</span><span class="cx">                 failureCases, scratchGPR);
</span><span class="cx">             currStructure = it-&gt;get();
</span><span class="cx">         }
</span><ins>+        ASSERT(protoObject-&gt;structure() == currStructure);
</ins><span class="cx">     }
</span><span class="cx">     
</span><ins>+    currStructure-&gt;startWatchingPropertyForReplacements(*vm, offset);
</ins><span class="cx">     GPRReg baseForAccessGPR;
</span><span class="cx">     if (chain) {
</span><span class="cx">         // We could have clobbered scratchGPR earlier, so we have to reload from baseGPR to get the target.
</span><span class="lines">@@ -743,9 +747,10 @@
</span><span class="cx">         &amp;&amp; slot.isCacheableValue()
</span><span class="cx">         &amp;&amp; !slot.watchpointSet()
</span><span class="cx">         &amp;&amp; MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset()))) {
</span><del>-            repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, propertyName, slot.cachedOffset(), operationGetByIdBuildList, true);
-            stubInfo.initGetByIdSelf(*vm, codeBlock-&gt;ownerExecutable(), structure);
-            return RetryCacheLater;
</del><ins>+        structure-&gt;startWatchingPropertyForReplacements(*vm, slot.cachedOffset());
+        repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, propertyName, slot.cachedOffset(), operationGetByIdBuildList, true);
+        stubInfo.initGetByIdSelf(*vm, codeBlock-&gt;ownerExecutable(), structure);
+        return RetryCacheLater;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdBuildList);
</span><span class="lines">@@ -1231,6 +1236,7 @@
</span><span class="cx">         if (!MacroAssembler::isPtrAlignedAddressOffset(offsetRelativeToPatchedStorage(slot.cachedOffset())))
</span><span class="cx">             return GiveUpOnCache;
</span><span class="cx"> 
</span><ins>+        structure-&gt;didCachePropertyReplacement(*vm, slot.cachedOffset());
</ins><span class="cx">         repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, ident, slot.cachedOffset(), appropriateListBuildingPutByIdFunction(slot, putKind), false);
</span><span class="cx">         stubInfo.initPutByIdReplace(*vm, codeBlock-&gt;ownerExecutable(), structure);
</span><span class="cx">         return RetryCacheLater;
</span><span class="lines">@@ -1262,7 +1268,7 @@
</span><span class="cx">         list-&gt;addAccess(PutByIdAccess::setter(
</span><span class="cx">             *vm, codeBlock-&gt;ownerExecutable(),
</span><span class="cx">             slot.isCacheableSetter() ? PutByIdAccess::Setter : PutByIdAccess::CustomSetter,
</span><del>-            structure, prototypeChain, slot.customSetter(), stubRoutine));
</del><ins>+            structure, prototypeChain, count, slot.customSetter(), stubRoutine));
</ins><span class="cx"> 
</span><span class="cx">         RepatchBuffer repatchBuffer(codeBlock);
</span><span class="cx">         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine-&gt;code().code()));
</span><span class="lines">@@ -1347,6 +1353,8 @@
</span><span class="cx">             if (list-&gt;isFull())
</span><span class="cx">                 return GiveUpOnCache; // Will get here due to recursion.
</span><span class="cx">             
</span><ins>+            structure-&gt;didCachePropertyReplacement(*vm, slot.cachedOffset());
+            
</ins><span class="cx">             // We're now committed to creating the stub. Mogrify the meta-data accordingly.
</span><span class="cx">             emitPutReplaceStub(
</span><span class="cx">                 exec, baseValue, propertyName, slot, stubInfo, putKind,
</span><span class="lines">@@ -1393,7 +1401,7 @@
</span><span class="cx">         list-&gt;addAccess(PutByIdAccess::setter(
</span><span class="cx">             *vm, codeBlock-&gt;ownerExecutable(),
</span><span class="cx">             slot.isCacheableSetter() ? PutByIdAccess::Setter : PutByIdAccess::CustomSetter,
</span><del>-            structure, prototypeChain, slot.customSetter(), stubRoutine));
</del><ins>+            structure, prototypeChain, count, slot.customSetter(), stubRoutine));
</ins><span class="cx"> 
</span><span class="cx">         RepatchBuffer repatchBuffer(codeBlock);
</span><span class="cx">         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine-&gt;code().code()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -179,7 +179,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Masquerader* create(VM&amp; vm, JSGlobalObject* globalObject)
</span><span class="cx">     {
</span><del>-        globalObject-&gt;masqueradesAsUndefinedWatchpoint()-&gt;fireAll();
</del><ins>+        globalObject-&gt;masqueradesAsUndefinedWatchpoint()-&gt;fireAll(&quot;Masquerading object allocated&quot;);
</ins><span class="cx">         Structure* structure = createStructure(vm, globalObject, jsNull());
</span><span class="cx">         Masquerader* result = new (NotNull, allocateCell&lt;Masquerader&gt;(vm.heap, sizeof(Masquerader))) Masquerader(vm, structure);
</span><span class="cx">         result-&gt;finishCreation(vm);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -701,6 +701,7 @@
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">             } else {
</span><ins>+                structure-&gt;didCachePropertyReplacement(vm, slot.cachedOffset());
</ins><span class="cx">                 pc[4].u.structure.set(
</span><span class="cx">                     vm, codeBlock-&gt;ownerExecutable(), structure);
</span><span class="cx">                 if (isInlineOffset(slot.cachedOffset())) {
</span><span class="lines">@@ -1417,9 +1418,8 @@
</span><span class="cx">     LLINT_RETURN(JSScope::resolve(exec, exec-&gt;scope(), ident));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
</del><ins>+static JSValue getFromScopeCommon(ExecState* exec, Instruction* pc, VM&amp; vm)
</ins><span class="cx"> {
</span><del>-    LLINT_BEGIN();
</del><span class="cx">     const Identifier&amp; ident = exec-&gt;codeBlock()-&gt;identifier(pc[3].u.operand);
</span><span class="cx">     JSObject* scope = jsCast&lt;JSObject*&gt;(LLINT_OP(2).jsValue());
</span><span class="cx">     ResolveModeAndType modeAndType(pc[4].u.operand);
</span><span class="lines">@@ -1427,25 +1427,45 @@
</span><span class="cx">     PropertySlot slot(scope);
</span><span class="cx">     if (!scope-&gt;getPropertySlot(exec, ident, slot)) {
</span><span class="cx">         if (modeAndType.mode() == ThrowIfNotFound)
</span><del>-            LLINT_RETURN(exec-&gt;vm().throwException(exec, createUndefinedVariableError(exec, ident)));
-        LLINT_RETURN(jsUndefined());
</del><ins>+            return exec-&gt;vm().throwException(exec, createUndefinedVariableError(exec, ident));
+        return jsUndefined();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
</span><span class="cx">     if (slot.isCacheableValue() &amp;&amp; slot.slotBase() == scope &amp;&amp; scope-&gt;structure()-&gt;propertyAccessesAreCacheable()) {
</span><span class="cx">         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
</span><span class="cx">             CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><del>-            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
-            pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), scope-&gt;structure());
-            pc[6].u.operand = slot.cachedOffset();
</del><ins>+            Structure* structure = scope-&gt;structure(vm);
+            {
+                ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
+                pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), structure);
+                pc[6].u.operand = slot.cachedOffset();
+            }
+            structure-&gt;startWatchingPropertyForReplacements(vm, slot.cachedOffset());
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LLINT_RETURN(slot.getValue(exec, ident));
</del><ins>+    return slot.getValue(exec, ident);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static JSObject* putToScopeCommon(ExecState* exec, Instruction* pc, VM&amp;)
</del><ins>+LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
</ins><span class="cx"> {
</span><ins>+    LLINT_BEGIN();
+    JSValue value = getFromScopeCommon(exec, pc, vm);
+    LLINT_RETURN(value);
+}
+
+LLINT_SLOW_PATH_DECL(slow_path_get_from_scope_with_profile)
+{
+    LLINT_BEGIN();
+    JSValue value = getFromScopeCommon(exec, pc, vm);
+    TypeLocation* location = pc[8].u.location;
+    vm.highFidelityLog()-&gt;recordTypeInformationForLocation(value, location);
+    LLINT_RETURN(value);
+}
+
+static JSObject* putToScopeCommon(ExecState* exec, Instruction* pc)
+{
</ins><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><span class="cx">     const Identifier&amp; ident = codeBlock-&gt;identifier(pc[2].u.operand);
</span><span class="cx">     JSObject* scope = jsCast&lt;JSObject*&gt;(LLINT_OP(1).jsValue());
</span><span class="lines">@@ -1457,23 +1477,16 @@
</span><span class="cx"> 
</span><span class="cx">     PutPropertySlot slot(scope, codeBlock-&gt;isStrictMode());
</span><span class="cx">     scope-&gt;methodTable()-&gt;put(scope, exec, ident, value, slot);
</span><ins>+    
+    CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
</ins><span class="cx"> 
</span><del>-    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
-    if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
-        if (slot.isCacheablePut() &amp;&amp; slot.base() == scope &amp;&amp; scope-&gt;structure()-&gt;propertyAccessesAreCacheable()) {
-            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
-            pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), scope-&gt;structure());
-            pc[6].u.operand = slot.cachedOffset();
-        }
-    }
-
</del><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN();
</span><del>-    JSObject* error = putToScopeCommon(exec, pc, vm);
</del><ins>+    JSObject* error = putToScopeCommon(exec, pc);
</ins><span class="cx">     if (error)
</span><span class="cx">         LLINT_THROW(error);
</span><span class="cx">     LLINT_END();
</span><span class="lines">@@ -1483,7 +1496,7 @@
</span><span class="cx"> {
</span><span class="cx">     // The format of this instruction is the same as put_to_scope with a TypeLocation appended: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
</span><span class="cx">     LLINT_BEGIN();
</span><del>-    JSObject* error = putToScopeCommon(exec, pc, vm);
</del><ins>+    JSObject* error = putToScopeCommon(exec, pc);
</ins><span class="cx">     if (error)
</span><span class="cx">         LLINT_THROW(error);
</span><span class="cx">     TypeLocation* location = pc[7].u.location;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -121,6 +121,7 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_exception);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><ins>+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope_with_profile);
</ins><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope_with_profile);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_types_with_high_fidelity);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1250,3 +1250,8 @@
</span><span class="cx">     traceExecution()
</span><span class="cx">     callSlowPath(_llint_slow_path_put_to_scope_with_profile)
</span><span class="cx">     dispatch(8)
</span><ins>+
+_llint_op_get_from_scope_with_profile:
+    traceExecution()
+    callSlowPath(_llint_slow_path_get_from_scope_with_profile)
+    dispatch(9)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerProfilerCompilationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;ProfilerDatabase.h&quot;
</span><ins>+#include &quot;Watchpoint.h&quot;
</ins><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace Profiler {
</span><span class="lines">@@ -93,6 +94,18 @@
</span><span class="cx">     return &amp;m_osrExits.last();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Compilation::setJettisonReason(JettisonReason jettisonReason, const FireDetail* detail)
+{
+    if (m_jettisonReason != NotJettisoned)
+        return; // We only care about the original jettison reason.
+    
+    m_jettisonReason = jettisonReason;
+    if (detail)
+        m_additionalJettisonReason = toCString(*detail);
+    else
+        m_additionalJettisonReason = CString();
+}
+
</ins><span class="cx"> JSValue Compilation::toJS(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     JSObject* result = constructEmptyObject(exec);
</span><span class="lines">@@ -133,6 +146,8 @@
</span><span class="cx">     result-&gt;putDirect(exec-&gt;vm(), exec-&gt;propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
</span><span class="cx">     result-&gt;putDirect(exec-&gt;vm(), exec-&gt;propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
</span><span class="cx">     result-&gt;putDirect(exec-&gt;vm(), exec-&gt;propertyNames().jettisonReason, jsString(exec, String::fromUTF8(toCString(m_jettisonReason))));
</span><ins>+    if (!m_additionalJettisonReason.isNull())
+        result-&gt;putDirect(exec-&gt;vm(), exec-&gt;propertyNames().additionalJettisonReason, jsString(exec, String::fromUTF8(m_additionalJettisonReason)));
</ins><span class="cx">     
</span><span class="cx">     return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerProfilerCompilationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/profiler/ProfilerCompilation.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -39,8 +39,12 @@
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/SegmentedVector.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC { namespace Profiler {
</del><ins>+namespace JSC {
</ins><span class="cx"> 
</span><ins>+class FireDetail;
+
+namespace Profiler {
+
</ins><span class="cx"> class Bytecodes;
</span><span class="cx"> class Database;
</span><span class="cx"> 
</span><span class="lines">@@ -69,10 +73,7 @@
</span><span class="cx">     void addOSRExitSite(const Vector&lt;const void*&gt;&amp; codeAddresses);
</span><span class="cx">     OSRExit* addOSRExit(unsigned id, const OriginStack&amp;, ExitKind, bool isWatchpoint);
</span><span class="cx">     
</span><del>-    void setJettisonReason(JettisonReason jettisonReason)
-    {
-        m_jettisonReason = jettisonReason;
-    }
</del><ins>+    void setJettisonReason(JettisonReason, const FireDetail*);
</ins><span class="cx">     
</span><span class="cx">     JSValue toJS(ExecState*) const;
</span><span class="cx">     
</span><span class="lines">@@ -80,6 +81,7 @@
</span><span class="cx">     Bytecodes* m_bytecodes;
</span><span class="cx">     CompilationKind m_kind;
</span><span class="cx">     JettisonReason m_jettisonReason;
</span><ins>+    CString m_additionalJettisonReason;
</ins><span class="cx">     Vector&lt;ProfiledBytecodes&gt; m_profiledBytecodes;
</span><span class="cx">     Vector&lt;CompiledBytecode&gt; m_descriptions;
</span><span class="cx">     HashMap&lt;OriginStack, std::unique_ptr&lt;ExecutionCounter&gt;&gt; m_counters;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx">         if (JSArrayBufferView* view = jsDynamicCast&lt;JSArrayBufferView*&gt;(cell))
</span><span class="cx">             view-&gt;neuter();
</span><span class="cx">         else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast&lt;ArrayBufferNeuteringWatchpoint*&gt;(cell))
</span><del>-            watchpoint-&gt;set()-&gt;fireAll();
</del><ins>+            watchpoint-&gt;fireAll();
</ins><span class="cx">     }
</span><span class="cx">     return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -60,5 +60,10 @@
</span><span class="cx">     return Structure::create(vm, 0, jsNull(), TypeInfo(CellType, StructureFlags), info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ArrayBufferNeuteringWatchpoint::fireAll()
+{
+    set()-&gt;fireAll(&quot;Array buffer was neutered&quot;);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -50,6 +50,8 @@
</span><span class="cx">     static Structure* createStructure(VM&amp;);
</span><span class="cx">     
</span><span class="cx">     WatchpointSet* set() { return m_set.get(); }
</span><ins>+    
+    void fireAll();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     RefPtr&lt;WatchpointSet&gt; m_set;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonIdentifiersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -62,6 +62,7 @@
</span><span class="cx">     macro(__lookupGetter__) \
</span><span class="cx">     macro(__lookupSetter__) \
</span><span class="cx">     macro(add) \
</span><ins>+    macro(additionalJettisonReason) \
</ins><span class="cx">     macro(anonymous) \
</span><span class="cx">     macro(arguments) \
</span><span class="cx">     macro(assign) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -205,7 +205,7 @@
</span><span class="cx"> SLOW_PATH_DECL(slow_path_touch_entry)
</span><span class="cx"> {
</span><span class="cx">     BEGIN();
</span><del>-    exec-&gt;codeBlock()-&gt;symbolTable()-&gt;m_functionEnteredOnce.touch();
</del><ins>+    exec-&gt;codeBlock()-&gt;symbolTable()-&gt;m_functionEnteredOnce.touch(&quot;Function (re)entered&quot;);
</ins><span class="cx">     END();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -266,7 +266,7 @@
</span><span class="cx">     BEGIN();
</span><span class="cx">     JSValue value = OP_C(2).jsValue();
</span><span class="cx">     if (VariableWatchpointSet* set = pc[3].u.watchpointSet)
</span><del>-        set-&gt;notifyWrite(vm, value);
</del><ins>+        set-&gt;notifyWrite(vm, value, &quot;Executed op_captured_mov&quot;);
</ins><span class="cx">     RETURN(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -277,7 +277,7 @@
</span><span class="cx">     ASSERT(codeBlock-&gt;codeType() != FunctionCode || !codeBlock-&gt;needsActivation() || exec-&gt;hasActivation());
</span><span class="cx">     JSValue value = JSFunction::create(vm, codeBlock-&gt;functionDecl(pc[2].u.operand), exec-&gt;scope());
</span><span class="cx">     if (VariableWatchpointSet* set = pc[3].u.watchpointSet)
</span><del>-        set-&gt;notifyWrite(vm, value);
</del><ins>+        set-&gt;notifyWrite(vm, value, &quot;Executed op_new_captured_func&quot;);
</ins><span class="cx">     RETURN(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -91,6 +91,33 @@
</span><span class="cx">     return baseObj-&gt;hasProperty(exec, property);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void tryCachePutToScopeGlobal(
+    ExecState* exec, CodeBlock* codeBlock, Instruction* pc, JSObject* scope,
+    ResolveModeAndType modeAndType, PutPropertySlot&amp; slot)
+{
+    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
+    
+    if (modeAndType.type() != GlobalProperty &amp;&amp; modeAndType.type() != GlobalPropertyWithVarInjectionChecks)
+        return;
+    
+    if (!slot.isCacheablePut()
+        || slot.base() != scope
+        || !scope-&gt;structure()-&gt;propertyAccessesAreCacheable())
+        return;
+    
+    if (slot.type() == PutPropertySlot::NewProperty) {
+        // Don't cache if we've done a transition. We want to detect the first replace so that we
+        // can invalidate the watchpoint.
+        return;
+    }
+    
+    scope-&gt;structure()-&gt;didCachePropertyReplacement(exec-&gt;vm(), slot.cachedOffset());
+
+    ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
+    pc[5].u.structure.set(exec-&gt;vm(), codeBlock-&gt;ownerExecutable(), scope-&gt;structure());
+    pc[6].u.operand = slot.cachedOffset();
+}
+
</ins><span class="cx"> } // namespace CommonSlowPaths
</span><span class="cx"> 
</span><span class="cx"> class ExecState;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/Executable.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -43,12 +43,10 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo ExecutableBase::s_info = { &quot;Executable&quot;, 0, 0, CREATE_METHOD_TABLE(ExecutableBase) };
</span><span class="cx"> 
</span><del>-#if ENABLE(JIT)
</del><span class="cx"> void ExecutableBase::destroy(JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     static_cast&lt;ExecutableBase*&gt;(cell)-&gt;ExecutableBase::~ExecutableBase();
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> void ExecutableBase::clearCode()
</span><span class="cx"> {
</span><span class="lines">@@ -80,12 +78,10 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo NativeExecutable::s_info = { &quot;NativeExecutable&quot;, &amp;ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(NativeExecutable) };
</span><span class="cx"> 
</span><del>-#if ENABLE(JIT)
</del><span class="cx"> void NativeExecutable::destroy(JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     static_cast&lt;NativeExecutable*&gt;(cell)-&gt;NativeExecutable::~NativeExecutable();
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> Intrinsic NativeExecutable::intrinsic() const
</span><span class="lines">@@ -96,18 +92,33 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo ScriptExecutable::s_info = { &quot;ScriptExecutable&quot;, &amp;ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(ScriptExecutable) };
</span><span class="cx"> 
</span><del>-#if ENABLE(JIT)
</del><ins>+ScriptExecutable::ScriptExecutable(Structure* structure, VM&amp; vm, const SourceCode&amp; source, bool isInStrictContext)
+    : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
+    , m_source(source)
+    , m_features(isInStrictContext ? StrictModeFeature : 0)
+    , m_hasCapturedVariables(false)
+    , m_neverInline(false)
+    , m_didTryToEnterInLoop(false)
+    , m_firstLine(-1)
+    , m_lastLine(-1)
+    , m_startColumn(UINT_MAX)
+    , m_endColumn(UINT_MAX)
+{
+}
+
</ins><span class="cx"> void ScriptExecutable::destroy(JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     static_cast&lt;ScriptExecutable*&gt;(cell)-&gt;ScriptExecutable::~ScriptExecutable();
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(genericCodeBlock-&gt;ownerExecutable() == this);
</span><span class="cx">     RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock-&gt;jitType()));
</span><span class="cx">     
</span><ins>+    if (Options::verboseOSR())
+        dataLog(&quot;Installing &quot;, *genericCodeBlock, &quot;\n&quot;);
+    
</ins><span class="cx">     VM&amp; vm = *genericCodeBlock-&gt;vm();
</span><span class="cx">     
</span><span class="cx">     if (vm.m_perBytecodeProfiler)
</span><span class="lines">@@ -348,7 +359,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode&amp; source, bool inStrictContext)
</span><del>-    : ScriptExecutable(exec-&gt;vm().evalExecutableStructure.get(), exec, source, inStrictContext)
</del><ins>+    : ScriptExecutable(exec-&gt;vm().evalExecutableStructure.get(), exec-&gt;vm(), source, inStrictContext)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -360,7 +371,7 @@
</span><span class="cx"> const ClassInfo ProgramExecutable::s_info = { &quot;ProgramExecutable&quot;, &amp;ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(ProgramExecutable) };
</span><span class="cx"> 
</span><span class="cx"> ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode&amp; source)
</span><del>-    : ScriptExecutable(exec-&gt;vm().programExecutableStructure.get(), exec, source, false)
</del><ins>+    : ScriptExecutable(exec-&gt;vm().programExecutableStructure.get(), exec-&gt;vm(), source, false)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/Executable.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2010, 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">@@ -86,11 +86,9 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef JSCell Base;
</span><span class="cx"> 
</span><del>-#if ENABLE(JIT)
</del><span class="cx">     static const bool needsDestruction = true;
</span><span class="cx">     static const bool hasImmortalStructure = true;
</span><span class="cx">     static void destroy(JSCell*);
</span><del>-#endif
</del><span class="cx">         
</span><span class="cx">     CodeBlockHash hashFor(CodeSpecializationKind) const;
</span><span class="cx"> 
</span><span class="lines">@@ -298,9 +296,7 @@
</span><span class="cx">         return executable;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-#if ENABLE(JIT)
</del><span class="cx">     static void destroy(JSCell*);
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     CodeBlockHash hashFor(CodeSpecializationKind) const;
</span><span class="cx"> 
</span><span class="lines">@@ -356,29 +352,9 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef ExecutableBase Base;
</span><span class="cx"> 
</span><del>-    ScriptExecutable(Structure* structure, VM&amp; vm, const SourceCode&amp; source, bool isInStrictContext)
-        : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
-        , m_source(source)
-        , m_features(isInStrictContext ? StrictModeFeature : 0)
-        , m_neverInline(false)
-        , m_startColumn(UINT_MAX)
-        , m_endColumn(UINT_MAX)
-    {
-    }
</del><ins>+    ScriptExecutable(Structure* structure, VM&amp; vm, const SourceCode&amp; source, bool isInStrictContext);
</ins><span class="cx"> 
</span><del>-    ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode&amp; source, bool isInStrictContext)
-        : ExecutableBase(exec-&gt;vm(), structure, NUM_PARAMETERS_NOT_COMPILED)
-        , m_source(source)
-        , m_features(isInStrictContext ? StrictModeFeature : 0)
-        , m_neverInline(false)
-        , m_startColumn(UINT_MAX)
-        , m_endColumn(UINT_MAX)
-    {
-    }
-
-#if ENABLE(JIT)
</del><span class="cx">     static void destroy(JSCell*);
</span><del>-#endif
</del><span class="cx">         
</span><span class="cx">     CodeBlockHash hashFor(CodeSpecializationKind) const;
</span><span class="cx"> 
</span><span class="lines">@@ -397,8 +373,12 @@
</span><span class="cx">     ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
</span><span class="cx">         
</span><span class="cx">     void setNeverInline(bool value) { m_neverInline = value; }
</span><ins>+    void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; }
</ins><span class="cx">     bool neverInline() const { return m_neverInline; }
</span><ins>+    bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; }
</ins><span class="cx">     bool isInliningCandidate() const { return !neverInline(); }
</span><ins>+    
+    bool* addressOfDidTryToEnterInLoop() { return &amp;m_didTryToEnterInLoop; }
</ins><span class="cx"> 
</span><span class="cx">     void unlinkCalls();
</span><span class="cx">         
</span><span class="lines">@@ -450,6 +430,7 @@
</span><span class="cx">     CodeFeatures m_features;
</span><span class="cx">     bool m_hasCapturedVariables;
</span><span class="cx">     bool m_neverInline;
</span><ins>+    bool m_didTryToEnterInLoop;
</ins><span class="cx">     int m_firstLine;
</span><span class="cx">     int m_lastLine;
</span><span class="cx">     unsigned m_startColumn;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeGetterSettercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/GetterSetter.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/GetterSetter.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/GetterSetter.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2004, 2007, 2008, 2009 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2004, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -44,6 +44,32 @@
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_setter);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+GetterSetter* GetterSetter::withGetter(VM&amp; vm, JSObject* newGetter)
+{
+    if (!getter()) {
+        setGetter(vm, newGetter);
+        return this;
+    }
+    
+    GetterSetter* result = GetterSetter::create(vm);
+    result-&gt;setGetter(vm, newGetter);
+    result-&gt;setSetter(vm, setter());
+    return result;
+}
+
+GetterSetter* GetterSetter::withSetter(VM&amp; vm, JSObject* newSetter)
+{
+    if (!setter()) {
+        setSetter(vm, newSetter);
+        return this;
+    }
+    
+    GetterSetter* result = GetterSetter::create(vm);
+    result-&gt;setGetter(vm, getter());
+    result-&gt;setSetter(vm, newSetter);
+    return result;
+}
+
</ins><span class="cx"> JSValue callGetter(ExecState* exec, JSValue base, JSValue getterSetter)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Some callers may invoke get() without checking for an exception first.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeGetterSetterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/GetterSetter.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/GetterSetter.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/GetterSetter.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -33,7 +33,11 @@
</span><span class="cx">     class JSObject;
</span><span class="cx"> 
</span><span class="cx">     // This is an internal value object which stores getter and setter functions
</span><del>-    // for a property.
</del><ins>+    // for a property. Instances of this class have the property that once a getter
+    // or setter is set to a non-null value, then they cannot be changed. This means
+    // that if a property holding a GetterSetter reference is constant-inferred and
+    // that constant is observed to have a non-null setter (or getter) then we can
+    // constant fold that setter (or getter).
</ins><span class="cx">     class GetterSetter : public JSCell {
</span><span class="cx">         friend class JIT;
</span><span class="cx"> 
</span><span class="lines">@@ -56,9 +60,44 @@
</span><span class="cx">         static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx">         JSObject* getter() const { return m_getter.get(); }
</span><del>-        void setGetter(VM&amp; vm, JSObject* getter) { m_getter.setMayBeNull(vm, this, getter); }
</del><ins>+        
+        JSObject* getterConcurrently() const
+        {
+            JSObject* result = getter();
+            WTF::loadLoadFence();
+            return result;
+        }
+        
+        // Set the getter. It's only valid to call this if you've never set the getter on this
+        // object.
+        void setGetter(VM&amp; vm, JSObject* getter)
+        {
+            RELEASE_ASSERT(!m_getter);
+            WTF::storeStoreFence();
+            m_getter.setMayBeNull(vm, this, getter);
+        }
+        
</ins><span class="cx">         JSObject* setter() const { return m_setter.get(); }
</span><del>-        void setSetter(VM&amp; vm, JSObject* setter) { m_setter.setMayBeNull(vm, this, setter); }
</del><ins>+        
+        JSObject* setterConcurrently() const
+        {
+            JSObject* result = setter();
+            WTF::loadLoadFence();
+            return result;
+        }
+        
+        // Set the setter. It's only valid to call this if you've never set the setter on this
+        // object.
+        void setSetter(VM&amp; vm, JSObject* setter)
+        {
+            RELEASE_ASSERT(!m_setter);
+            WTF::storeStoreFence();
+            m_setter.setMayBeNull(vm, this, setter);
+        }
+        
+        GetterSetter* withGetter(VM&amp;, JSObject* getter);
+        GetterSetter* withSetter(VM&amp;, JSObject* setter);
+        
</ins><span class="cx">         static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">         {
</span><span class="cx">             return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType), info());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityLogcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -53,22 +53,6 @@
</span><span class="cx">     delete[] m_nextBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HighFidelityLog::recordTypeInformationForLocation(JSValue v, TypeLocation* location)
-{
-    ASSERT(m_logStartPtr);
-    ASSERT(m_currentOffset &lt; m_highFidelityLogSize);
-
-    LogEntry* entry = m_logStartPtr + m_currentOffset;
-
-    entry-&gt;location = location;
-    entry-&gt;value = v;
-    entry-&gt;structure = (v.isCell() ? v.asCell()-&gt;structure() : nullptr);
-
-    m_currentOffset += 1;
-    if (m_currentOffset == m_highFidelityLogSize)
-        processHighFidelityLog(true, &quot;Log Full&quot;);
-}
-
</del><span class="cx"> void HighFidelityLog::processHighFidelityLog(bool asynchronously, String reason)
</span><span class="cx"> {
</span><span class="cx">     // This should only be called from the main execution thread.
</span><span class="lines">@@ -85,9 +69,7 @@
</span><span class="cx">     data-&gt;m_locker = locker;
</span><span class="cx"> 
</span><span class="cx">     m_currentOffset = 0;
</span><del>-    LogEntry* temp = m_logStartPtr;
-    m_logStartPtr = m_nextBuffer;
-    m_nextBuffer = temp;
</del><ins>+    std::swap(m_logStartPtr, m_nextBuffer);
</ins><span class="cx">     
</span><span class="cx">     if (asynchronously)
</span><span class="cx">         createThread(actuallyProcessLogThreadFunction, data, &quot;ProcessHighFidelityLog&quot;);
</span><span class="lines">@@ -97,19 +79,28 @@
</span><span class="cx"> 
</span><span class="cx"> void HighFidelityLog::actuallyProcessLogThreadFunction(void* arg)
</span><span class="cx"> {
</span><del>-    double before  = currentTimeMS();
</del><ins>+    double before = currentTimeMS();
</ins><span class="cx">     ThreadData* data = static_cast&lt;ThreadData*&gt;(arg);
</span><span class="cx">     LogEntry* entry = data-&gt;m_processLogPtr;
</span><ins>+    HashMap&lt;StructureID, RefPtr&lt;StructureShape&gt;&gt; seenShapes;
</ins><span class="cx">     size_t processLogToOffset = data-&gt;m_proccessLogToOffset; 
</span><span class="cx">     size_t i = 0;
</span><span class="cx">     while (i &lt; processLogToOffset) {
</span><del>-        Structure* structure = entry-&gt;structure ? entry-&gt;structure : nullptr;
</del><ins>+        StructureID id = entry-&gt;structureID;
</ins><span class="cx">         RefPtr&lt;StructureShape&gt; shape; 
</span><del>-        if (structure)
-            shape = structure-&gt;toStructureShape();
</del><ins>+        if (id) {
+            auto iter = seenShapes.find(id);
+            if (iter == seenShapes.end()) {
+                shape = entry-&gt;value.asCell()-&gt;structure()-&gt;toStructureShape();
+                seenShapes.set(id, shape);
+            } else 
+                shape = iter-&gt;value;
+        }
+
</ins><span class="cx">         if (entry-&gt;location-&gt;m_globalTypeSet)
</span><del>-            entry-&gt;location-&gt;m_globalTypeSet-&gt;addTypeForValue(entry-&gt;value, shape);
-        entry-&gt;location-&gt;m_instructionTypeSet-&gt;addTypeForValue(entry-&gt;value, shape);
</del><ins>+            entry-&gt;location-&gt;m_globalTypeSet-&gt;addTypeForValue(entry-&gt;value, shape, id);
+        entry-&gt;location-&gt;m_instructionTypeSet-&gt;addTypeForValue(entry-&gt;value, shape, id);
+
</ins><span class="cx">         entry++;
</span><span class="cx">         i++;
</span><span class="cx">     }
</span><span class="lines">@@ -118,7 +109,7 @@
</span><span class="cx">     delete data;
</span><span class="cx">     double after = currentTimeMS();
</span><span class="cx">     if (verbose)
</span><del>-        dataLogF(&quot;Processing the log took: '%f' ms\n&quot;, after - before);
</del><ins>+        dataLogF(&quot; Processing the log took: '%f' ms\n&quot;, after - before);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityLogh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">         public:
</span><span class="cx">         JSValue value;
</span><span class="cx">         TypeLocation* location; 
</span><del>-        Structure* structure;
</del><ins>+        StructureID structureID;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     HighFidelityLog()
</span><span class="lines">@@ -56,7 +56,22 @@
</span><span class="cx"> 
</span><span class="cx">     ~HighFidelityLog();
</span><span class="cx"> 
</span><del>-    void recordTypeInformationForLocation(JSValue v, TypeLocation*);
</del><ins>+    ALWAYS_INLINE void recordTypeInformationForLocation(JSValue value, TypeLocation* location)
+    {
+        ASSERT(m_logStartPtr);
+        ASSERT(m_currentOffset &lt; m_highFidelityLogSize);
+    
+        LogEntry* entry = m_logStartPtr + m_currentOffset;
+    
+        entry-&gt;location = location;
+        entry-&gt;value = value;
+        entry-&gt;structureID = (value.isCell() ? value.asCell()-&gt;structureID() : 0);
+    
+        m_currentOffset += 1;
+        if (m_currentOffset == m_highFidelityLogSize)
+            processHighFidelityLog(true, &quot;Log Full&quot;);
+    }
+
</ins><span class="cx">     void processHighFidelityLog(bool asynchronously = false, String = &quot;&quot;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -32,57 +32,67 @@
</span><span class="cx"> 
</span><span class="cx"> static const bool verbose = false;
</span><span class="cx"> 
</span><del>-String HighFidelityTypeProfiler::getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine , unsigned endColumn, const String&amp; variableName, intptr_t sourceID)
</del><ins>+String HighFidelityTypeProfiler::getTypesForVariableInAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID)
</ins><span class="cx"> {
</span><del>-    String global = getGlobalTypesForVariableInRange(startLine, startColumn, endLine, endColumn, variableName, sourceID);
</del><ins>+    String global = getGlobalTypesForVariableAtOffset(divot, variableName, sourceID);
</ins><span class="cx">     if (!global.isEmpty())
</span><span class="cx">         return global;
</span><span class="cx">     
</span><del>-    return getLocalTypesForVariableInRange(startLine, startColumn, endLine, endColumn, variableName, sourceID);
</del><ins>+    return getLocalTypesForVariableAtOffset(divot, variableName, sourceID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-WTF::String HighFidelityTypeProfiler::getGlobalTypesForVariableInRange(unsigned startLine, unsigned, unsigned, unsigned, const WTF::String&amp;, intptr_t sourceID)
</del><ins>+String HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset(unsigned divot, const String&amp; , intptr_t sourceID)
</ins><span class="cx"> {
</span><del>-    auto iterLocationMap = m_globalLocationToGlobalIDMap.find(getLocationBasedHash(sourceID, startLine));
-    if (iterLocationMap == m_globalLocationToGlobalIDMap.end())
-        return &quot;&quot;;
</del><ins>+    TypeLocation* location = findLocation(divot, sourceID);
+    if (!location)
+        return  &quot;&quot;;
</ins><span class="cx"> 
</span><del>-    auto iterIDMap = m_globalIDMap.find(iterLocationMap-&gt;second);
-    if (iterIDMap == m_globalIDMap.end())
</del><ins>+    if (location-&gt;m_globalVariableID == HighFidelityNoGlobalIDExists)
</ins><span class="cx">         return &quot;&quot;;
</span><span class="cx"> 
</span><del>-    return iterIDMap-&gt;second-&gt;seenTypes();
</del><ins>+    return location-&gt;m_globalTypeSet-&gt;seenTypes();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-WTF::String HighFidelityTypeProfiler::getLocalTypesForVariableInRange(unsigned startLine, unsigned , unsigned , unsigned , const WTF::String&amp; , intptr_t sourceID)
</del><ins>+String HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset(unsigned divot, const String&amp; , intptr_t sourceID)
</ins><span class="cx"> {
</span><del>-    auto iter = m_globalLocationMap.find(getLocationBasedHash(sourceID, startLine));
-    auto end = m_globalLocationMap.end();
-    if (iter == end)
</del><ins>+    TypeLocation* location = findLocation(divot, sourceID);
+    if (!location)
</ins><span class="cx">         return  &quot;&quot;;
</span><span class="cx"> 
</span><del>-    return iter-&gt;second-&gt;seenTypes();
</del><ins>+    return location-&gt;m_instructionTypeSet-&gt;seenTypes();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HighFidelityTypeProfiler::insertNewLocation(TypeLocation* location)
</span><span class="cx"> {
</span><span class="cx">     if (verbose)
</span><del>-        dataLogF(&quot;Registering location:: line:%u, column:%u\n&quot;, location-&gt;m_line, location-&gt;m_column);
</del><ins>+        dataLogF(&quot;Registering location:: divotStart:%u, divotEnd:%u\n&quot;, location-&gt;m_divotStart, location-&gt;m_divotEnd);
</ins><span class="cx"> 
</span><del>-    LocationKey key(getLocationBasedHash(location-&gt;m_sourceID, location-&gt;m_line));
-
-    if (location-&gt;m_globalVariableID != HighFidelityNoGlobalIDExists) { 
-        // Build the mapping relationships Map1:key=&gt;globalId, Map2:globalID=&gt;TypeSet 
-        m_globalLocationToGlobalIDMap[key] = location-&gt;m_globalVariableID;
-        m_globalIDMap[location-&gt;m_globalVariableID] = location-&gt;m_globalTypeSet;
</del><ins>+    if (!m_bucketMap.contains(location-&gt;m_sourceID)) {
+        Vector&lt;TypeLocation*&gt; bucket;
+        m_bucketMap.set(location-&gt;m_sourceID, bucket);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_globalLocationMap[key] = location-&gt;m_instructionTypeSet;
</del><ins>+    Vector&lt;TypeLocation*&gt;&amp; bucket = m_bucketMap.find(location-&gt;m_sourceID)-&gt;value;
+    bucket.append(location);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-LocationKey HighFidelityTypeProfiler::getLocationBasedHash(intptr_t id, unsigned line)
</del><ins>+TypeLocation* HighFidelityTypeProfiler::findLocation(unsigned divot, intptr_t sourceID)
</ins><span class="cx"> {
</span><del>-    return LocationKey(id, line, 1);
</del><ins>+    ASSERT(m_bucketMap.contains(sourceID)); 
+
+    Vector&lt;TypeLocation*&gt;&amp; bucket = m_bucketMap.find(sourceID)-&gt;value;
+    unsigned distance = UINT_MAX; // Because assignments may be nested, make sure we find the closest enclosing assignment to this character offset.
+    TypeLocation* bestMatch = nullptr;
+    for (size_t i = 0, size = bucket.size(); i &lt; size; i++) {
+        TypeLocation* location = bucket.at(i);
+        if (location-&gt;m_divotStart &lt;= divot &amp;&amp; divot &lt;= location-&gt;m_divotEnd &amp;&amp; location-&gt;m_divotEnd - location-&gt;m_divotStart &lt;= distance) {
+            distance = location-&gt;m_divotEnd - location-&gt;m_divotStart;
+            bestMatch = location;
+        }
+    }
+
+    // FIXME: BestMatch should never be null. This doesn't hold currently because we ignore some Eval/With/VarInjection variable assignments.
+    return bestMatch;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -31,57 +31,25 @@
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMethod.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><ins>+#include &lt;wtf/Vector.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class TypeLocation;
</span><span class="cx"> 
</span><del>-struct LocationKey {
-
-public:
-    LocationKey(intptr_t sourceID, unsigned line, unsigned column) 
-        : m_sourceID(sourceID)
-        , m_line(line)
-        , m_column(column)
-
-    {
-    }
-
-    unsigned hash() const
-    {
-        return m_line + m_sourceID;
-    }
-
-    // FIXME: For now, this is a hack. We do the following: Map:&quot;ID:Line&quot; =&gt; TypeSet. Obviously, this assumes all assignments are on discrete lines, which is an incorrect assumption.
-    bool operator==(const LocationKey&amp; other) const
-    {
-        return m_sourceID == other.m_sourceID
-               &amp;&amp; m_line == other.m_line;
-    }
-
-    intptr_t m_sourceID;
-    unsigned m_line;
-    unsigned m_column;
-};
-
</del><span class="cx"> class HighFidelityTypeProfiler {
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    String getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String&amp; variableName, intptr_t sourceID);
-    String getGlobalTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String&amp; variableName, intptr_t sourceID);
-    String getLocalTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String&amp; variableName, intptr_t sourceID);
</del><ins>+    String getTypesForVariableInAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID);
+    String getGlobalTypesForVariableAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID);
+    String getLocalTypesForVariableAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID);
</ins><span class="cx">     void insertNewLocation(TypeLocation*);
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    static LocationKey getLocationBasedHash(intptr_t, unsigned);
</del><ins>+    TypeLocation* findLocation(unsigned divot, intptr_t sourceID);
</ins><span class="cx"> 
</span><del>-    typedef std::unordered_map&lt;LocationKey, RefPtr&lt;TypeSet&gt;, HashMethod&lt;LocationKey&gt;&gt; GlobalLocationMap; 
-    typedef std::unordered_map&lt;int64_t, RefPtr&lt;TypeSet&gt;&gt; GlobalIDMap; 
-    typedef std::unordered_map&lt;LocationKey, int64_t, HashMethod&lt;LocationKey&gt;&gt; GlobalLocationToGlobalIDMap;
-
-    GlobalIDMap m_globalIDMap;
-    GlobalLocationMap m_globalLocationMap;
-    GlobalLocationToGlobalIDMap m_globalLocationToGlobalIDMap;
</del><ins>+    typedef HashMap&lt;intptr_t, Vector&lt;TypeLocation*&gt;&gt; SourceIDToLocationBucketMap;
+    SourceIDToLocationBucketMap m_bucketMap;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIdentifiercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Identifier.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Identifier.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/Identifier.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -97,6 +97,14 @@
</span><span class="cx">     return Identifier(vm, vm-&gt;numericStrings.add(value));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Identifier::dump(PrintStream&amp; out) const
+{
+    if (impl())
+        out.print(impl());
+    else
+        out.print(&quot;&lt;null identifier&gt;&quot;);
+}
+
</ins><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> 
</span><span class="cx"> void Identifier::checkCurrentAtomicStringTable(VM* vm)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIdentifierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Identifier.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Identifier.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/Identifier.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -96,6 +96,8 @@
</span><span class="cx">         // Only to be used with string literals.
</span><span class="cx">         JS_EXPORT_PRIVATE static PassRef&lt;StringImpl&gt; add(VM*, const char*);
</span><span class="cx">         JS_EXPORT_PRIVATE static PassRef&lt;StringImpl&gt; add(ExecState*, const char*);
</span><ins>+        
+        void dump(PrintStream&amp;) const;
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         String m_string;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIndexingHeaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/IndexingHeader.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/IndexingHeader.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/IndexingHeader.h        2014-08-06 05:27:46 UTC (rev 172129)
</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></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntendedStructureChaincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -107,8 +107,7 @@
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = 0; i &lt; m_vector.size(); ++i) {
</span><span class="cx">         unsigned attributes;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = m_vector[i]-&gt;getConcurrently(vm, uid, attributes, specificValue);
</del><ins>+        PropertyOffset offset = m_vector[i]-&gt;getConcurrently(vm, uid, attributes);
</ins><span class="cx">         if (!isValidOffset(offset))
</span><span class="cx">             continue;
</span><span class="cx">         if (attributes &amp; (ReadOnly | Accessor))
</span><span class="lines">@@ -130,6 +129,15 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool IntendedStructureChain::takesSlowPathInDFGForImpureProperty()
+{
+    for (size_t i = 0; i &lt; size(); ++i) {
+        if (at(i)-&gt;takesSlowPathInDFGForImpureProperty())
+            return true;
+    }
+    return false;
+}
+
</ins><span class="cx"> JSObject* IntendedStructureChain::terminalPrototype() const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_vector.isEmpty());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntendedStructureChainh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -52,6 +52,8 @@
</span><span class="cx">     bool mayInterceptStoreTo(VM&amp;, StringImpl* uid);
</span><span class="cx">     bool isNormalized();
</span><span class="cx">     
</span><ins>+    bool takesSlowPathInDFGForImpureProperty();
+    
</ins><span class="cx">     JSValue prototype() const { return m_prototype; }
</span><span class="cx">     
</span><span class="cx">     size_t size() const { return m_vector.size(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSActivationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSActivation.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSActivation.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSActivation.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -103,7 +103,7 @@
</span><span class="cx">         if (isTornOff() &amp;&amp; !isValid(iter-&gt;value))
</span><span class="cx">             return false;
</span><span class="cx">         if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet())
</span><del>-            set-&gt;invalidate(); // Don't mess around - if we had found this statically, we would have invcalidated it.
</del><ins>+            set-&gt;invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invcalidated it.
</ins><span class="cx">         reg = &amp;registerAt(iter-&gt;value.getIndex());
</span><span class="cx">     }
</span><span class="cx">     reg-&gt;set(vm, this, value);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -141,8 +141,7 @@
</span><span class="cx"> 
</span><span class="cx">     for (; ; obj = asObject(prototype)) {
</span><span class="cx">         unsigned attributes;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = obj-&gt;structure()-&gt;get(vm, propertyName, attributes, specificValue);
</del><ins>+        PropertyOffset offset = obj-&gt;structure()-&gt;get(vm, propertyName, attributes);
</ins><span class="cx">         if (offset != invalidOffset) {
</span><span class="cx">             if (attributes &amp; ReadOnly) {
</span><span class="cx">                 if (slot.isStrictMode())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunction.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -405,7 +405,7 @@
</span><span class="cx">         PropertySlot slot(thisObject);
</span><span class="cx">         thisObject-&gt;methodTable(exec-&gt;vm())-&gt;getOwnPropertySlot(thisObject, exec, propertyName, slot);
</span><span class="cx">         thisObject-&gt;m_allocationProfile.clear();
</span><del>-        thisObject-&gt;m_allocationProfileWatchpoint.fireAll();
</del><ins>+        thisObject-&gt;m_allocationProfileWatchpoint.fireAll(&quot;Store to prototype property of a function&quot;);
</ins><span class="cx">         // Don't allow this to be cached, since a [[Put]] must clear m_allocationProfile.
</span><span class="cx">         PutPropertySlot dontCache(thisObject);
</span><span class="cx">         Base::put(thisObject, exec, propertyName, value, dontCache);
</span><span class="lines">@@ -452,7 +452,7 @@
</span><span class="cx">         PropertySlot slot(thisObject);
</span><span class="cx">         thisObject-&gt;methodTable(exec-&gt;vm())-&gt;getOwnPropertySlot(thisObject, exec, propertyName, slot);
</span><span class="cx">         thisObject-&gt;m_allocationProfile.clear();
</span><del>-        thisObject-&gt;m_allocationProfileWatchpoint.fireAll();
</del><ins>+        thisObject-&gt;m_allocationProfileWatchpoint.fireAll(&quot;Store to prototype property of a function&quot;);
</ins><span class="cx">         return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> #include &quot;DateConstructor.h&quot;
</span><span class="cx"> #include &quot;DatePrototype.h&quot;
</span><span class="cx"> #include &quot;Debugger.h&quot;
</span><ins>+#include &quot;DebuggerScope.h&quot;
</ins><span class="cx"> #include &quot;Error.h&quot;
</span><span class="cx"> #include &quot;ErrorConstructor.h&quot;
</span><span class="cx"> #include &quot;ErrorPrototype.h&quot;
</span><span class="lines">@@ -262,7 +263,7 @@
</span><span class="cx">     NewGlobalVar var = addGlobalVar(propertyName, IsVariable);
</span><span class="cx">     registerAt(var.registerNumber).set(exec-&gt;vm(), this, value);
</span><span class="cx">     if (var.set)
</span><del>-        var.set-&gt;notifyWrite(vm, value);
</del><ins>+        var.set-&gt;notifyWrite(vm, value, VariableWriteFireDetail(this, propertyName));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline JSObject* lastInPrototypeChain(JSObject* object)
</span><span class="lines">@@ -281,7 +282,7 @@
</span><span class="cx">     m_functionPrototype.set(vm, this, FunctionPrototype::create(vm, FunctionPrototype::createStructure(vm, this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
</span><span class="cx">     m_functionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
</span><span class="cx">     m_boundFunctionStructure.set(vm, this, JSBoundFunction::createStructure(vm, this, m_functionPrototype.get()));
</span><del>-    m_namedFunctionStructure.set(vm, this, Structure::addPropertyTransition(vm, m_functionStructure.get(), vm.propertyNames-&gt;name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset));
</del><ins>+    m_namedFunctionStructure.set(vm, this, Structure::addPropertyTransition(vm, m_functionStructure.get(), vm.propertyNames-&gt;name, DontDelete | ReadOnly | DontEnum, m_functionNameOffset));
</ins><span class="cx">     m_internalFunctionStructure.set(vm, this, InternalFunction::createStructure(vm, this, m_functionPrototype.get()));
</span><span class="cx">     JSFunction* callFunction = 0;
</span><span class="cx">     JSFunction* applyFunction = 0;
</span><span class="lines">@@ -320,6 +321,7 @@
</span><span class="cx">     m_nameScopeStructure.set(vm, this, JSNameScope::createStructure(vm, this, jsNull()));
</span><span class="cx">     m_activationStructure.set(vm, this, JSActivation::createStructure(vm, this, jsNull()));
</span><span class="cx">     m_strictEvalActivationStructure.set(vm, this, StrictEvalActivation::createStructure(vm, this, jsNull()));
</span><ins>+    m_debuggerScopeStructure.set(m_vm, this, DebuggerScope::createStructure(m_vm, this, jsNull()));
</ins><span class="cx">     m_withScopeStructure.set(vm, this, JSWithScope::createStructure(vm, this, jsNull()));
</span><span class="cx"> 
</span><span class="cx">     m_nullPrototypeObjectStructure.set(vm, this, JSFinalObject::createStructure(vm, this, jsNull(), JSFinalObject::defaultInlineCapacity()));
</span><span class="lines">@@ -427,8 +429,8 @@
</span><span class="cx">     PrototypeMap&amp; prototypeMap = vm.prototypeMap;
</span><span class="cx">     Structure* iteratorResultStructure = prototypeMap.emptyObjectStructureForPrototype(m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity());
</span><span class="cx">     PropertyOffset offset;
</span><del>-    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames-&gt;done, 0, 0, offset);
-    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames-&gt;value, 0, 0, offset);
</del><ins>+    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames-&gt;done, 0, offset);
+    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames-&gt;value, 0, offset);
</ins><span class="cx">     m_iteratorResultStructure.set(vm, this, iteratorResultStructure);
</span><span class="cx"> 
</span><span class="cx">     m_evalFunction.set(vm, this, JSFunction::create(vm, this, 1, vm.propertyNames-&gt;eval.string(), globalFuncEval));
</span><span class="lines">@@ -561,7 +563,7 @@
</span><span class="cx">     // Make sure that all allocations or indexed storage transitions that are inlining
</span><span class="cx">     // the assumption that it's safe to transition to a non-SlowPut array storage don't
</span><span class="cx">     // do so anymore.
</span><del>-    m_havingABadTimeWatchpoint-&gt;fireAll();
</del><ins>+    m_havingABadTimeWatchpoint-&gt;fireAll(&quot;Having a bad time&quot;);
</ins><span class="cx">     ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time.
</span><span class="cx">     
</span><span class="cx">     // Make sure that all JSArray allocations that load the appropriate structure from
</span><span class="lines">@@ -662,6 +664,7 @@
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_promisePrototype);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    visitor.append(&amp;thisObject-&gt;m_debuggerScopeStructure);
</ins><span class="cx">     visitor.append(&amp;thisObject-&gt;m_withScopeStructure);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_strictEvalActivationStructure);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_activationStructure);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -186,6 +186,7 @@
</span><span class="cx">     WriteBarrier&lt;JSPromisePrototype&gt; m_promisePrototype;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    WriteBarrier&lt;Structure&gt; m_debuggerScopeStructure;
</ins><span class="cx">     WriteBarrier&lt;Structure&gt; m_withScopeStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_strictEvalActivationStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_activationStructure;
</span><span class="lines">@@ -391,6 +392,7 @@
</span><span class="cx">     JSPromisePrototype* promisePrototype() const { return m_promisePrototype.get(); }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(); }
</ins><span class="cx">     Structure* withScopeStructure() const { return m_withScopeStructure.get(); }
</span><span class="cx">     Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
</span><span class="cx">     Structure* activationStructure() const { return m_activationStructure.get(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -56,15 +56,6 @@
</span><span class="cx"> // ArrayConventions.h.
</span><span class="cx"> static unsigned lastArraySize = 0;
</span><span class="cx"> 
</span><del>-JSCell* getCallableObjectSlow(JSCell* cell)
-{
-    if (cell-&gt;type() == JSFunctionType)
-        return cell;
-    if (cell-&gt;structure()-&gt;classInfo()-&gt;isSubClassOf(InternalFunction::info()))
-        return cell;
-    return 0;
-}
-
</del><span class="cx"> STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSObject);
</span><span class="cx"> STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSFinalObject);
</span><span class="cx"> 
</span><span class="lines">@@ -361,7 +352,7 @@
</span><span class="cx">             prototype = obj-&gt;prototype();
</span><span class="cx">             if (prototype.isNull()) {
</span><span class="cx">                 ASSERT(!thisObject-&gt;structure(vm)-&gt;prototypeChainMayInterceptStoreTo(exec-&gt;vm(), propertyName));
</span><del>-                if (!thisObject-&gt;putDirectInternal&lt;PutModePut&gt;(vm, propertyName, value, 0, slot, getCallableObject(value))
</del><ins>+                if (!thisObject-&gt;putDirectInternal&lt;PutModePut&gt;(vm, propertyName, value, 0, slot)
</ins><span class="cx">                     &amp;&amp; slot.isStrictMode())
</span><span class="cx">                     throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
</span><span class="cx">                 return;
</span><span class="lines">@@ -372,8 +363,7 @@
</span><span class="cx">     JSObject* obj;
</span><span class="cx">     for (obj = thisObject; ; obj = asObject(prototype)) {
</span><span class="cx">         unsigned attributes;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = obj-&gt;structure(vm)-&gt;get(vm, propertyName, attributes, specificValue);
</del><ins>+        PropertyOffset offset = obj-&gt;structure(vm)-&gt;get(vm, propertyName, attributes);
</ins><span class="cx">         if (isValidOffset(offset)) {
</span><span class="cx">             if (attributes &amp; ReadOnly) {
</span><span class="cx">                 ASSERT(thisObject-&gt;structure(vm)-&gt;prototypeChainMayInterceptStoreTo(exec-&gt;vm(), propertyName) || obj == thisObject);
</span><span class="lines">@@ -413,7 +403,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     ASSERT(!thisObject-&gt;structure(vm)-&gt;prototypeChainMayInterceptStoreTo(exec-&gt;vm(), propertyName) || obj == thisObject);
</span><del>-    if (!thisObject-&gt;putDirectInternal&lt;PutModePut&gt;(vm, propertyName, value, 0, slot, getCallableObject(value)) &amp;&amp; slot.isStrictMode())
</del><ins>+    if (!thisObject-&gt;putDirectInternal&lt;PutModePut&gt;(vm, propertyName, value, 0, slot) &amp;&amp; slot.isStrictMode())
</ins><span class="cx">         throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
</span><span class="cx">     return;
</span><span class="cx"> }
</span><span class="lines">@@ -1235,7 +1225,7 @@
</span><span class="cx">     ASSERT(propertyName.asIndex() == PropertyName::NotAnIndex);
</span><span class="cx"> 
</span><span class="cx">     PutPropertySlot slot(this);
</span><del>-    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, attributes, slot, getCallableObject(value));
</del><ins>+    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, attributes, slot);
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(slot.type() == PutPropertySlot::NewProperty);
</span><span class="cx"> 
</span><span class="lines">@@ -1248,7 +1238,7 @@
</span><span class="cx"> void JSObject::putDirectNonIndexAccessor(VM&amp; vm, PropertyName propertyName, JSValue value, unsigned attributes)
</span><span class="cx"> {
</span><span class="cx">     PutPropertySlot slot(this);
</span><del>-    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, attributes, slot, getCallableObject(value));
</del><ins>+    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, attributes, slot);
</ins><span class="cx"> 
</span><span class="cx">     // putDirect will change our Structure if we add a new property. For
</span><span class="cx">     // getters and setters, though, we also need to change our Structure
</span><span class="lines">@@ -1288,9 +1278,8 @@
</span><span class="cx">         thisObject-&gt;reifyStaticFunctionsForDelete(exec);
</span><span class="cx"> 
</span><span class="cx">     unsigned attributes;
</span><del>-    JSCell* specificValue;
</del><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><del>-    if (isValidOffset(thisObject-&gt;structure(vm)-&gt;get(vm, propertyName, attributes, specificValue))) {
</del><ins>+    if (isValidOffset(thisObject-&gt;structure(vm)-&gt;get(vm, propertyName, attributes))) {
</ins><span class="cx">         if (attributes &amp; DontDelete &amp;&amp; !vm.isInDefineOwnProperty())
</span><span class="cx">             return false;
</span><span class="cx">         thisObject-&gt;removeDirect(vm, propertyName);
</span><span class="lines">@@ -1404,6 +1393,10 @@
</span><span class="cx"> // ECMA 8.6.2.6
</span><span class="cx"> JSValue JSObject::defaultValue(const JSObject* object, ExecState* exec, PreferredPrimitiveType hint)
</span><span class="cx"> {
</span><ins>+    // Make sure that whatever default value methods there are on object's prototype chain are
+    // being watched.
+    object-&gt;structure()-&gt;startWatchingInternalPropertiesIfNecessaryForEntireChain(exec-&gt;vm());
+    
</ins><span class="cx">     // Must call toString first for Date objects.
</span><span class="cx">     if ((hint == PreferString) || (hint != PreferNumber &amp;&amp; object-&gt;prototype() == exec-&gt;lexicalGlobalObject()-&gt;datePrototype())) {
</span><span class="cx">         JSValue value = callDefaultValueFunction(exec, object, exec-&gt;propertyNames().toString);
</span><span class="lines">@@ -1467,20 +1460,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSObject::getPropertySpecificValue(ExecState* exec, PropertyName propertyName, JSCell*&amp; specificValue) const
-{
-    VM&amp; vm = exec-&gt;vm();
-    unsigned attributes;
-    if (isValidOffset(structure(vm)-&gt;get(vm, propertyName, attributes, specificValue)))
-        return true;
-
-    // This could be a function within the static table? - should probably
-    // also look in the hash?  This currently should not be a problem, since
-    // we've currently always call 'get' first, which should have populated
-    // the normal storage.
-    return false;
-}
-
</del><span class="cx"> void JSObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray&amp; propertyNames, EnumerationMode mode)
</span><span class="cx"> {
</span><span class="cx">     propertyNames.setBaseObject(object);
</span><span class="lines">@@ -2656,17 +2635,22 @@
</span><span class="cx">     if (!accessor)
</span><span class="cx">         return false;
</span><span class="cx">     GetterSetter* getterSetter;
</span><ins>+    bool getterSetterChanged = false;
</ins><span class="cx">     if (accessor.isCustomGetterSetter())
</span><span class="cx">         getterSetter = GetterSetter::create(exec-&gt;vm());
</span><span class="cx">     else {
</span><span class="cx">         ASSERT(accessor.isGetterSetter());
</span><span class="cx">         getterSetter = asGetterSetter(accessor);
</span><span class="cx">     }
</span><del>-    if (descriptor.setterPresent())
-        getterSetter-&gt;setSetter(exec-&gt;vm(), descriptor.setterObject());
-    if (descriptor.getterPresent())
-        getterSetter-&gt;setGetter(exec-&gt;vm(), descriptor.getterObject());
-    if (current.attributesEqual(descriptor))
</del><ins>+    if (descriptor.setterPresent()) {
+        getterSetter = getterSetter-&gt;withSetter(exec-&gt;vm(), descriptor.setterObject());
+        getterSetterChanged = true;
+    }
+    if (descriptor.getterPresent()) {
+        getterSetter = getterSetter-&gt;withGetter(exec-&gt;vm(), descriptor.getterObject());
+        getterSetterChanged = true;
+    }
+    if (current.attributesEqual(descriptor) &amp;&amp; !getterSetterChanged)
</ins><span class="cx">         return true;
</span><span class="cx">     methodTable(exec-&gt;vm())-&gt;deleteProperty(this, exec, propertyName);
</span><span class="cx">     unsigned attrs = descriptor.attributesOverridingCurrent(current);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -57,15 +57,6 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JS_EXPORT_PRIVATE JSCell* getCallableObjectSlow(JSCell*);
-
-inline JSCell* getCallableObject(JSValue value)
-{
-    if (!value.isCell())
-        return 0;
-    return getCallableObjectSlow(value.asCell());
-}
-
</del><span class="cx"> class GetterSetter;
</span><span class="cx"> class InternalFunction;
</span><span class="cx"> class JSFunction;
</span><span class="lines">@@ -493,8 +484,6 @@
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE static JSValue toThis(JSCell*, ExecState*, ECMAMode);
</span><span class="cx"> 
</span><del>-    bool getPropertySpecificValue(ExecState*, PropertyName, JSCell*&amp; specificFunction) const;
-
</del><span class="cx">     // This get function only looks at the property map.
</span><span class="cx">     JSValue getDirect(VM&amp; vm, PropertyName propertyName) const
</span><span class="cx">     {
</span><span class="lines">@@ -503,12 +492,11 @@
</span><span class="cx">         checkOffset(offset, structure-&gt;inlineCapacity());
</span><span class="cx">         return offset != invalidOffset ? getDirect(offset) : JSValue();
</span><span class="cx">     }
</span><del>-
</del><ins>+    
</ins><span class="cx">     JSValue getDirect(VM&amp; vm, PropertyName propertyName, unsigned&amp; attributes) const
</span><span class="cx">     {
</span><del>-        JSCell* specific;
</del><span class="cx">         Structure* structure = this-&gt;structure(vm);
</span><del>-        PropertyOffset offset = structure-&gt;get(vm, propertyName, attributes, specific);
</del><ins>+        PropertyOffset offset = structure-&gt;get(vm, propertyName, attributes);
</ins><span class="cx">         checkOffset(offset, structure-&gt;inlineCapacity());
</span><span class="cx">         return offset != invalidOffset ? getDirect(offset) : JSValue();
</span><span class="cx">     }
</span><span class="lines">@@ -523,9 +511,8 @@
</span><span class="cx"> 
</span><span class="cx">     PropertyOffset getDirectOffset(VM&amp; vm, PropertyName propertyName, unsigned&amp; attributes)
</span><span class="cx">     {
</span><del>-        JSCell* specific;
</del><span class="cx">         Structure* structure = this-&gt;structure(vm);
</span><del>-        PropertyOffset offset = structure-&gt;get(vm, propertyName, attributes, specific);
</del><ins>+        PropertyOffset offset = structure-&gt;get(vm, propertyName, attributes);
</ins><span class="cx">         checkOffset(offset, structure-&gt;inlineCapacity());
</span><span class="cx">         return offset;
</span><span class="cx">     }
</span><span class="lines">@@ -602,6 +589,7 @@
</span><span class="cx">     bool isNameScopeObject() const;
</span><span class="cx">     bool isActivationObject() const;
</span><span class="cx">     bool isErrorInstance() const;
</span><ins>+    bool isWithScope() const;
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void seal(VM&amp;);
</span><span class="cx">     JS_EXPORT_PRIVATE void freeze(VM&amp;);
</span><span class="lines">@@ -960,7 +948,7 @@
</span><span class="cx">     ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(VM&amp;, ArrayStorage*);
</span><span class="cx">         
</span><span class="cx">     template&lt;PutMode&gt;
</span><del>-    bool putDirectInternal(VM&amp;, PropertyName, JSValue, unsigned attr, PutPropertySlot&amp;, JSCell*);
</del><ins>+    bool putDirectInternal(VM&amp;, PropertyName, JSValue, unsigned attr, PutPropertySlot&amp;);
</ins><span class="cx"> 
</span><span class="cx">     bool inlineGetOwnPropertySlot(VM&amp;, Structure&amp;, PropertyName, PropertySlot&amp;);
</span><span class="cx">     JS_EXPORT_PRIVATE void fillGetterPropertySlot(PropertySlot&amp;, JSValue, unsigned, PropertyOffset);
</span><span class="lines">@@ -1158,6 +1146,11 @@
</span><span class="cx">     return type() == ErrorInstanceType;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool JSObject::isWithScope() const
+{
+    return type() == WithScopeType;
+}
+
</ins><span class="cx"> inline void JSObject::setStructureAndButterfly(VM&amp; vm, Structure* structure, Butterfly* butterfly)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(structure);
</span><span class="lines">@@ -1218,8 +1211,7 @@
</span><span class="cx"> ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(VM&amp; vm, Structure&amp; structure, PropertyName propertyName, PropertySlot&amp; slot)
</span><span class="cx"> {
</span><span class="cx">     unsigned attributes;
</span><del>-    JSCell* specific;
-    PropertyOffset offset = structure.get(vm, propertyName, attributes, specific);
</del><ins>+    PropertyOffset offset = structure.get(vm, propertyName, attributes);
</ins><span class="cx">     if (!isValidOffset(offset))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -1323,7 +1315,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;JSObject::PutMode mode&gt;
</span><del>-inline bool JSObject::putDirectInternal(VM&amp; vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot&amp; slot, JSCell* specificFunction)
</del><ins>+inline bool JSObject::putDirectInternal(VM&amp; vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot&amp; slot)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(value);
</span><span class="cx">     ASSERT(value.isGetterSetter() == !!(attributes &amp; Accessor));
</span><span class="lines">@@ -1333,25 +1325,15 @@
</span><span class="cx">     Structure* structure = this-&gt;structure(vm);
</span><span class="cx">     if (structure-&gt;isDictionary()) {
</span><span class="cx">         unsigned currentAttributes;
</span><del>-        JSCell* currentSpecificFunction;
-        PropertyOffset offset = structure-&gt;get(vm, propertyName, currentAttributes, currentSpecificFunction);
</del><ins>+        PropertyOffset offset = structure-&gt;get(vm, propertyName, currentAttributes);
</ins><span class="cx">         if (offset != invalidOffset) {
</span><del>-            // If there is currently a specific function, and there now either isn't,
-            // or the new value is different, then despecify.
-            if (currentSpecificFunction &amp;&amp; (specificFunction != currentSpecificFunction))
-                structure-&gt;despecifyDictionaryFunction(vm, propertyName);
</del><span class="cx">             if ((mode == PutModePut) &amp;&amp; currentAttributes &amp; ReadOnly)
</span><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">             putDirect(vm, offset, value);
</span><del>-            // At this point, the objects structure only has a specific value set if previously there
-            // had been one set, and if the new value being specified is the same (otherwise we would
-            // have despecified, above).  So, if currentSpecificFunction is not set, or if the new
-            // value is different (or there is no new value), then the slot now has no value - and
-            // as such it is cachable.
-            // If there was previously a value, and the new value is the same, then we cannot cache.
-            if (!currentSpecificFunction || (specificFunction != currentSpecificFunction))
-                slot.setExistingProperty(this, offset);
</del><ins>+            structure-&gt;didReplaceProperty(offset);
+            
+            slot.setExistingProperty(this, offset);
</ins><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1362,15 +1344,13 @@
</span><span class="cx">         Butterfly* newButterfly = butterfly();
</span><span class="cx">         if (this-&gt;structure()-&gt;putWillGrowOutOfLineStorage())
</span><span class="cx">             newButterfly = growOutOfLineStorage(vm, this-&gt;structure()-&gt;outOfLineCapacity(), this-&gt;structure()-&gt;suggestedNewOutOfLineStorageCapacity());
</span><del>-        offset = this-&gt;structure()-&gt;addPropertyWithoutTransition(vm, propertyName, attributes, specificFunction);
</del><ins>+        offset = this-&gt;structure()-&gt;addPropertyWithoutTransition(vm, propertyName, attributes);
</ins><span class="cx">         setStructureAndButterfly(vm, this-&gt;structure(), newButterfly);
</span><span class="cx"> 
</span><span class="cx">         validateOffset(offset);
</span><span class="cx">         ASSERT(this-&gt;structure()-&gt;isValidOffset(offset));
</span><span class="cx">         putDirect(vm, offset, value);
</span><del>-        // See comment on setNewProperty call below.
-        if (!specificFunction)
-            slot.setNewProperty(this, offset);
</del><ins>+        slot.setNewProperty(this, offset);
</ins><span class="cx">         if (attributes &amp; ReadOnly)
</span><span class="cx">             this-&gt;structure()-&gt;setContainsReadOnlyProperties();
</span><span class="cx">         return true;
</span><span class="lines">@@ -1378,7 +1358,7 @@
</span><span class="cx"> 
</span><span class="cx">     PropertyOffset offset;
</span><span class="cx">     size_t currentCapacity = this-&gt;structure()-&gt;outOfLineCapacity();
</span><del>-    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this-&gt;structure(), propertyName, attributes, specificFunction, offset)) {
</del><ins>+    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this-&gt;structure(), propertyName, attributes, offset)) {
</ins><span class="cx">         DeferGC deferGC(vm.heap);
</span><span class="cx">         Butterfly* newButterfly = butterfly();
</span><span class="cx">         if (currentCapacity != structure-&gt;outOfLineCapacity()) {
</span><span class="lines">@@ -1390,40 +1370,17 @@
</span><span class="cx">         ASSERT(structure-&gt;isValidOffset(offset));
</span><span class="cx">         setStructureAndButterfly(vm, structure, newButterfly);
</span><span class="cx">         putDirect(vm, offset, value);
</span><del>-        // This is a new property; transitions with specific values are not currently cachable,
-        // so leave the slot in an uncachable state.
-        if (!specificFunction)
-            slot.setNewProperty(this, offset);
</del><ins>+        slot.setNewProperty(this, offset);
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     unsigned currentAttributes;
</span><del>-    JSCell* currentSpecificFunction;
-    offset = structure-&gt;get(vm, propertyName, currentAttributes, currentSpecificFunction);
</del><ins>+    offset = structure-&gt;get(vm, propertyName, currentAttributes);
</ins><span class="cx">     if (offset != invalidOffset) {
</span><span class="cx">         if ((mode == PutModePut) &amp;&amp; currentAttributes &amp; ReadOnly)
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><del>-        // There are three possibilities here:
-        //  (1) There is an existing specific value set, and we're overwriting with *the same value*.
-        //       * Do nothing - no need to despecify, but that means we can't cache (a cached
-        //         put could write a different value). Leave the slot in an uncachable state.
-        //  (2) There is a specific value currently set, but we're writing a different value.
-        //       * First, we have to despecify.  Having done so, this is now a regular slot
-        //         with no specific value, so go ahead &amp; cache like normal.
-        //  (3) Normal case, there is no specific value set.
-        //       * Go ahead &amp; cache like normal.
-        if (currentSpecificFunction) {
-            // case (1) Do the put, then return leaving the slot uncachable.
-            if (specificFunction == currentSpecificFunction) {
-                putDirect(vm, offset, value);
-                return true;
-            }
-            // case (2) Despecify, fall through to (3).
-            setStructure(vm, Structure::despecifyFunctionTransition(vm, structure, propertyName));
-        }
-
-        // case (3) set the slot, do the put, return.
</del><ins>+        structure-&gt;didReplaceProperty(offset);
</ins><span class="cx">         slot.setExistingProperty(this, offset);
</span><span class="cx">         putDirect(vm, offset, value);
</span><span class="cx">         return true;
</span><span class="lines">@@ -1432,17 +1389,14 @@
</span><span class="cx">     if ((mode == PutModePut) &amp;&amp; !isExtensible())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    structure = Structure::addPropertyTransition(vm, structure, propertyName, attributes, specificFunction, offset, slot.context());
</del><ins>+    structure = Structure::addPropertyTransition(vm, structure, propertyName, attributes, offset, slot.context());
</ins><span class="cx">     
</span><span class="cx">     validateOffset(offset);
</span><span class="cx">     ASSERT(structure-&gt;isValidOffset(offset));
</span><span class="cx">     setStructureAndReallocateStorageIfNecessary(vm, structure);
</span><span class="cx"> 
</span><span class="cx">     putDirect(vm, offset, value);
</span><del>-    // This is a new property; transitions with specific values are not currently cachable,
-    // so leave the slot in an uncachable state.
-    if (!specificFunction)
-        slot.setNewProperty(this, offset);
</del><ins>+    slot.setNewProperty(this, offset);
</ins><span class="cx">     if (attributes &amp; ReadOnly)
</span><span class="cx">         structure-&gt;setContainsReadOnlyProperties();
</span><span class="cx">     return true;
</span><span class="lines">@@ -1476,7 +1430,7 @@
</span><span class="cx">     ASSERT(!structure()-&gt;hasGetterSetterProperties());
</span><span class="cx">     ASSERT(!structure()-&gt;hasCustomGetterSetterProperties());
</span><span class="cx"> 
</span><del>-    return putDirectInternal&lt;PutModePut&gt;(vm, propertyName, value, 0, slot, getCallableObject(value));
</del><ins>+    return putDirectInternal&lt;PutModePut&gt;(vm, propertyName, value, 0, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void JSObject::putDirect(VM&amp; vm, PropertyName propertyName, JSValue value, unsigned attributes)
</span><span class="lines">@@ -1484,14 +1438,14 @@
</span><span class="cx">     ASSERT(!value.isGetterSetter() &amp;&amp; !(attributes &amp; Accessor));
</span><span class="cx">     ASSERT(!value.isCustomGetterSetter());
</span><span class="cx">     PutPropertySlot slot(this);
</span><del>-    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, attributes, slot, getCallableObject(value));
</del><ins>+    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, attributes, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void JSObject::putDirect(VM&amp; vm, PropertyName propertyName, JSValue value, PutPropertySlot&amp; slot)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!value.isGetterSetter());
</span><span class="cx">     ASSERT(!value.isCustomGetterSetter());
</span><del>-    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, 0, slot, getCallableObject(value));
</del><ins>+    putDirectInternal&lt;PutModeDefineOwnProperty&gt;(vm, propertyName, value, 0, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void JSObject::putDirectWithoutTransition(VM&amp; vm, PropertyName propertyName, JSValue value, unsigned attributes)
</span><span class="lines">@@ -1502,7 +1456,7 @@
</span><span class="cx">     Butterfly* newButterfly = m_butterfly.get();
</span><span class="cx">     if (structure()-&gt;putWillGrowOutOfLineStorage())
</span><span class="cx">         newButterfly = growOutOfLineStorage(vm, structure()-&gt;outOfLineCapacity(), structure()-&gt;suggestedNewOutOfLineStorageCapacity());
</span><del>-    PropertyOffset offset = structure()-&gt;addPropertyWithoutTransition(vm, propertyName, attributes, getCallableObject(value));
</del><ins>+    PropertyOffset offset = structure()-&gt;addPropertyWithoutTransition(vm, propertyName, attributes);
</ins><span class="cx">     setStructureAndButterfly(vm, structure(), newButterfly);
</span><span class="cx">     putDirect(vm, offset, value);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -96,8 +96,19 @@
</span><span class="cx">             op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0, 0);
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><del>-
-        op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject-&gt;structure(), 0, 0, slot.cachedOffset());
</del><ins>+        
+        WatchpointState state = globalObject-&gt;structure()-&gt;ensurePropertyReplacementWatchpointSet(exec-&gt;vm(), slot.cachedOffset())-&gt;state();
+        if (state == IsWatched &amp;&amp; getOrPut == Put) {
+            // The field exists, but because the replacement watchpoint is still intact. This is
+            // kind of dangerous. We have two options:
+            // 1) Invalidate the watchpoint set. That would work, but it's possible that this code
+            //    path never executes - in which case this would be unwise.
+            // 2) Have the invalidation happen at run-time. All we have to do is leave the code
+            //    uncached. The only downside is slightly more work when this does execute.
+            // We go with option (2) here because it seems less evil.
+            op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0, 0);
+        } else
+            op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject-&gt;structure(), 0, 0, slot.cachedOffset());
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx">     static size_t offsetOfNext();
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE static JSObject* objectAtScope(JSScope*);
</del><ins>+    static JSObject* objectAtScope(JSScope*);
</ins><span class="cx"> 
</span><span class="cx">     static JSValue resolve(ExecState*, JSScope*, const Identifier&amp;);
</span><span class="cx">     static ResolveOp abstractResolve(ExecState*, JSScope*, const Identifier&amp;, GetOrPut, ResolveType);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSSymbolTableObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -36,6 +36,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class JSSymbolTableObject;
+
</ins><span class="cx"> class JSSymbolTableObject : public JSScope {
</span><span class="cx"> public:
</span><span class="cx">     typedef JSScope Base;
</span><span class="lines">@@ -143,7 +145,7 @@
</span><span class="cx">         if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet()) {
</span><span class="cx">             // FIXME: It's strange that we're doing this while holding the symbol table's lock.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=134601
</span><del>-            set-&gt;notifyWrite(vm, value);
</del><ins>+            set-&gt;notifyWrite(vm, value, object, propertyName);
</ins><span class="cx">         }
</span><span class="cx">         reg = &amp;object-&gt;registerAt(fastEntry.getIndex());
</span><span class="cx">     }
</span><span class="lines">@@ -171,7 +173,7 @@
</span><span class="cx">         SymbolTableEntry&amp; entry = iter-&gt;value;
</span><span class="cx">         ASSERT(!entry.isNull());
</span><span class="cx">         if (VariableWatchpointSet* set = entry.watchpointSet())
</span><del>-            set-&gt;notifyWrite(vm, value);
</del><ins>+            set-&gt;notifyWrite(vm, value, object, propertyName);
</ins><span class="cx">         entry.setAttributes(attributes);
</span><span class="cx">         reg = &amp;object-&gt;registerAt(entry.getIndex());
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePropertyMapHashTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PropertyMapHashTable.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PropertyMapHashTable.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/PropertyMapHashTable.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -82,13 +82,11 @@
</span><span class="cx">     StringImpl* key;
</span><span class="cx">     PropertyOffset offset;
</span><span class="cx">     unsigned attributes;
</span><del>-    WriteBarrier&lt;JSCell&gt; specificValue;
</del><span class="cx"> 
</span><del>-    PropertyMapEntry(VM&amp; vm, JSCell* owner, StringImpl* key, PropertyOffset offset, unsigned attributes, JSCell* specificValue)
</del><ins>+    PropertyMapEntry(StringImpl* key, PropertyOffset offset, unsigned attributes)
</ins><span class="cx">         : key(key)
</span><span class="cx">         , offset(offset)
</span><span class="cx">         , attributes(attributes)
</span><del>-        , specificValue(vm, owner, specificValue, WriteBarrier&lt;JSCell&gt;::MayBeNull)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="lines">@@ -147,8 +145,6 @@
</span><span class="cx">         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static void visitChildren(JSCell*, SlotVisitor&amp;);
-
</del><span class="cx">     typedef StringImpl* KeyType;
</span><span class="cx">     typedef PropertyMapEntry ValueType;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePropertyNameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PropertyName.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PropertyName.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/PropertyName.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -108,6 +108,14 @@
</span><span class="cx">     {
</span><span class="cx">         return m_impl ? toUInt32FromStringImpl(m_impl) : NotAnIndex;
</span><span class="cx">     }
</span><ins>+    
+    void dump(PrintStream&amp; out) const
+    {
+        if (m_impl)
+            out.print(m_impl);
+        else
+            out.print(&quot;&lt;null property name&gt;&quot;);
+    }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     AtomicStringImpl* m_impl;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePropertyTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PropertyTable.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PropertyTable.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/PropertyTable.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -82,10 +82,8 @@
</span><span class="cx">     memcpy(m_index, other.m_index, dataSize());
</span><span class="cx"> 
</span><span class="cx">     iterator end = this-&gt;end();
</span><del>-    for (iterator iter = begin(); iter != end; ++iter) {
</del><ins>+    for (iterator iter = begin(); iter != end; ++iter)
</ins><span class="cx">         iter-&gt;key-&gt;ref();
</span><del>-        vm.heap.writeBarrier(this, iter-&gt;specificValue.get());
-    }
</del><span class="cx"> 
</span><span class="cx">     // Copy the m_deletedOffsets vector.
</span><span class="cx">     Vector&lt;PropertyOffset&gt;* otherDeletedOffsets = other.m_deletedOffsets.get();
</span><span class="lines">@@ -109,7 +107,6 @@
</span><span class="cx">         ASSERT(canInsert());
</span><span class="cx">         reinsert(*iter);
</span><span class="cx">         iter-&gt;key-&gt;ref();
</span><del>-        vm.heap.writeBarrier(this, iter-&gt;specificValue.get());
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Copy the m_deletedOffsets vector.
</span><span class="lines">@@ -132,16 +129,5 @@
</span><span class="cx">     fastFree(m_index);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PropertyTable::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
-{
-    PropertyTable* thisObject = jsCast&lt;PropertyTable*&gt;(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</del><ins>+} // namespace JSC
</ins><span class="cx"> 
</span><del>-    JSCell::visitChildren(thisObject, visitor);
-
-    PropertyTable::iterator end = thisObject-&gt;end();
-    for (PropertyTable::iterator ptr = thisObject-&gt;begin(); ptr != end; ++ptr)
-        visitor.append(&amp;ptr-&gt;specificValue);
-}
-
-}
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/Structure.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2009, 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">@@ -166,7 +166,6 @@
</span><span class="cx">     setHasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo-&gt;hasStaticSetterOrReadonlyProperties());
</span><span class="cx">     setHasNonEnumerableProperties(false);
</span><span class="cx">     setAttributesInPrevious(0);
</span><del>-    setSpecificFunctionThrashCount(0);
</del><span class="cx">     setPreventExtensions(false);
</span><span class="cx">     setDidTransition(false);
</span><span class="cx">     setStaticFunctionsReified(false);
</span><span class="lines">@@ -197,7 +196,6 @@
</span><span class="cx">     setHasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo-&gt;hasStaticSetterOrReadonlyProperties());
</span><span class="cx">     setHasNonEnumerableProperties(false);
</span><span class="cx">     setAttributesInPrevious(0);
</span><del>-    setSpecificFunctionThrashCount(0);
</del><span class="cx">     setPreventExtensions(false);
</span><span class="cx">     setDidTransition(false);
</span><span class="cx">     setStaticFunctionsReified(false);
</span><span class="lines">@@ -227,7 +225,6 @@
</span><span class="cx">     setHasReadOnlyOrGetterSetterPropertiesExcludingProto(previous-&gt;hasReadOnlyOrGetterSetterPropertiesExcludingProto());
</span><span class="cx">     setHasNonEnumerableProperties(previous-&gt;hasNonEnumerableProperties());
</span><span class="cx">     setAttributesInPrevious(0);
</span><del>-    setSpecificFunctionThrashCount(previous-&gt;specificFunctionThrashCount());
</del><span class="cx">     setPreventExtensions(previous-&gt;preventExtensions());
</span><span class="cx">     setDidTransition(true);
</span><span class="cx">     setStaticFunctionsReified(previous-&gt;staticFunctionsReified());
</span><span class="lines">@@ -238,11 +235,9 @@
</span><span class="cx">     m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!previous-&gt;typeInfo().structureIsImmortal());
</span><del>-    if (previous-&gt;hasRareData() &amp;&amp; previous-&gt;rareData()-&gt;needsCloning())
-        cloneRareDataFrom(vm, previous);
</del><span class="cx">     setPreviousID(vm, previous);
</span><span class="cx"> 
</span><del>-    previous-&gt;notifyTransitionFromThisStructure();
</del><ins>+    previous-&gt;didTransitionFromThisStructure();
</ins><span class="cx">     if (previous-&gt;m_globalObject)
</span><span class="cx">         m_globalObject.set(vm, this, previous-&gt;m_globalObject.get());
</span><span class="cx">     ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo-&gt;hasStaticSetterOrReadonlyProperties());
</span><span class="lines">@@ -313,37 +308,19 @@
</span><span class="cx">         structure = structures[i];
</span><span class="cx">         if (!structure-&gt;m_nameInPrevious)
</span><span class="cx">             continue;
</span><del>-        PropertyMapEntry entry(vm, this, structure-&gt;m_nameInPrevious.get(), structure-&gt;m_offset, structure-&gt;attributesInPrevious(), structure-&gt;m_specificValueInPrevious.get());
</del><ins>+        PropertyMapEntry entry(structure-&gt;m_nameInPrevious.get(), structure-&gt;m_offset, structure-&gt;attributesInPrevious());
</ins><span class="cx">         propertyTable()-&gt;add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     checkOffsetConsistency();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Structure::despecifyDictionaryFunction(VM&amp; vm, PropertyName propertyName)
</del><ins>+Structure* Structure::addPropertyTransitionToExistingStructureImpl(Structure* structure, StringImpl* uid, unsigned attributes, PropertyOffset&amp; offset)
</ins><span class="cx"> {
</span><del>-    StringImpl* rep = propertyName.uid();
-
-    DeferGC deferGC(vm.heap);
-    materializePropertyMapIfNecessary(vm, deferGC);
-
-    ASSERT(isDictionary());
-    ASSERT(propertyTable());
-
-    PropertyMapEntry* entry = propertyTable()-&gt;get(rep);
-    ASSERT(entry);
-    entry-&gt;specificValue.clear();
-}
-
-Structure* Structure::addPropertyTransitionToExistingStructureImpl(Structure* structure, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&amp; offset)
-{
</del><span class="cx">     ASSERT(!structure-&gt;isDictionary());
</span><span class="cx">     ASSERT(structure-&gt;isObject());
</span><span class="cx"> 
</span><span class="cx">     if (Structure* existingTransition = structure-&gt;m_transitionTable.get(uid, attributes)) {
</span><del>-        JSCell* specificValueInPrevious = existingTransition-&gt;m_specificValueInPrevious.get();
-        if (specificValueInPrevious &amp;&amp; specificValueInPrevious != specificValue)
-            return 0;
</del><span class="cx">         validateOffset(existingTransition-&gt;m_offset, existingTransition-&gt;inlineCapacity());
</span><span class="cx">         offset = existingTransition-&gt;m_offset;
</span><span class="cx">         return existingTransition;
</span><span class="lines">@@ -352,16 +329,16 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&amp; offset)
</del><ins>+Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset&amp; offset)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!isCompilationThread());
</span><del>-    return addPropertyTransitionToExistingStructureImpl(structure, propertyName.uid(), attributes, specificValue, offset);
</del><ins>+    return addPropertyTransitionToExistingStructureImpl(structure, propertyName.uid(), attributes, offset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-Structure* Structure::addPropertyTransitionToExistingStructureConcurrently(Structure* structure, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&amp; offset)
</del><ins>+Structure* Structure::addPropertyTransitionToExistingStructureConcurrently(Structure* structure, StringImpl* uid, unsigned attributes, PropertyOffset&amp; offset)
</ins><span class="cx"> {
</span><span class="cx">     ConcurrentJITLocker locker(structure-&gt;m_lock);
</span><del>-    return addPropertyTransitionToExistingStructureImpl(structure, uid, attributes, specificValue, offset);
</del><ins>+    return addPropertyTransitionToExistingStructureImpl(structure, uid, attributes, offset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Structure::anyObjectInChainMayInterceptIndexedAccesses() const
</span><span class="lines">@@ -416,25 +393,12 @@
</span><span class="cx">     return AllocateArrayStorage;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Structure* Structure::addPropertyTransition(VM&amp; vm, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&amp; offset, PutPropertySlot::Context context)
</del><ins>+Structure* Structure::addPropertyTransition(VM&amp; vm, Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset&amp; offset, PutPropertySlot::Context context)
</ins><span class="cx"> {
</span><del>-    // If we have a specific function, we may have got to this point if there is
-    // already a transition with the correct property name and attributes, but
-    // specialized to a different function.  In this case we just want to give up
-    // and despecialize the transition.
-    // In this case we clear the value of specificFunction which will result
-    // in us adding a non-specific transition, and any subsequent lookup in
-    // Structure::addPropertyTransitionToExistingStructure will just use that.
-    if (specificValue &amp;&amp; structure-&gt;m_transitionTable.contains(propertyName.uid(), attributes))
-        specificValue = 0;
-
</del><span class="cx">     ASSERT(!structure-&gt;isDictionary());
</span><span class="cx">     ASSERT(structure-&gt;isObject());
</span><del>-    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
</del><ins>+    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));
</ins><span class="cx">     
</span><del>-    if (structure-&gt;specificFunctionThrashCount() == maxSpecificFunctionThrashCount)
-        specificValue = 0;
-
</del><span class="cx">     int maxTransitionLength;
</span><span class="cx">     if (context == PutPropertySlot::PutById)
</span><span class="cx">         maxTransitionLength = s_maxTransitionLengthForNonEvalPutById;
</span><span class="lines">@@ -443,7 +407,7 @@
</span><span class="cx">     if (structure-&gt;transitionCount() &gt; maxTransitionLength) {
</span><span class="cx">         Structure* transition = toCacheableDictionaryTransition(vm, structure);
</span><span class="cx">         ASSERT(structure != transition);
</span><del>-        offset = transition-&gt;putSpecificValue(vm, propertyName, attributes, specificValue);
</del><ins>+        offset = transition-&gt;add(vm, propertyName, attributes);
</ins><span class="cx">         return transition;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -452,11 +416,10 @@
</span><span class="cx">     transition-&gt;m_cachedPrototypeChain.setMayBeNull(vm, transition, structure-&gt;m_cachedPrototypeChain.get());
</span><span class="cx">     transition-&gt;m_nameInPrevious = propertyName.uid();
</span><span class="cx">     transition-&gt;setAttributesInPrevious(attributes);
</span><del>-    transition-&gt;m_specificValueInPrevious.setMayBeNull(vm, transition, specificValue);
</del><span class="cx">     transition-&gt;propertyTable().set(vm, transition, structure-&gt;takePropertyTableOrCloneIfPinned(vm));
</span><span class="cx">     transition-&gt;m_offset = structure-&gt;m_offset;
</span><span class="cx"> 
</span><del>-    offset = transition-&gt;putSpecificValue(vm, propertyName, attributes, specificValue);
</del><ins>+    offset = transition-&gt;add(vm, propertyName, attributes);
</ins><span class="cx"> 
</span><span class="cx">     checkOffset(transition-&gt;m_offset, transition-&gt;inlineCapacity());
</span><span class="cx">     {
</span><span class="lines">@@ -496,30 +459,6 @@
</span><span class="cx">     return transition;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Structure* Structure::despecifyFunctionTransition(VM&amp; vm, Structure* structure, PropertyName replaceFunction)
-{
-    ASSERT(structure-&gt;specificFunctionThrashCount() &lt; maxSpecificFunctionThrashCount);
-    Structure* transition = create(vm, structure);
-
-    transition-&gt;setSpecificFunctionThrashCount(transition-&gt;specificFunctionThrashCount() + 1);
-
-    DeferGC deferGC(vm.heap);
-    structure-&gt;materializePropertyMapIfNecessary(vm, deferGC);
-    transition-&gt;propertyTable().set(vm, transition, structure-&gt;copyPropertyTableForPinning(vm));
-    transition-&gt;m_offset = structure-&gt;m_offset;
-    transition-&gt;pin();
-
-    if (transition-&gt;specificFunctionThrashCount() == maxSpecificFunctionThrashCount)
-        transition-&gt;despecifyAllFunctions(vm);
-    else {
-        bool removed = transition-&gt;despecifyFunction(vm, replaceFunction);
-        ASSERT_UNUSED(removed, removed);
-    }
-
-    transition-&gt;checkOffsetConsistency();
-    return transition;
-}
-
</del><span class="cx"> Structure* Structure::attributeChangeTransition(VM&amp; vm, Structure* structure, PropertyName propertyName, unsigned attributes)
</span><span class="cx"> {
</span><span class="cx">     DeferGC deferGC(vm.heap);
</span><span class="lines">@@ -649,7 +588,7 @@
</span><span class="cx">         if (globalObject-&gt;isOriginalArrayStructure(structure)) {
</span><span class="cx">             Structure* result = globalObject-&gt;originalArrayStructureForIndexingType(indexingType);
</span><span class="cx">             if (result-&gt;indexingTypeIncludingHistory() == indexingType) {
</span><del>-                structure-&gt;notifyTransitionFromThisStructure();
</del><ins>+                structure-&gt;didTransitionFromThisStructure();
</ins><span class="cx">                 return result;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -771,19 +710,16 @@
</span><span class="cx">     return this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PropertyOffset Structure::addPropertyWithoutTransition(VM&amp; vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
</del><ins>+PropertyOffset Structure::addPropertyWithoutTransition(VM&amp; vm, PropertyName propertyName, unsigned attributes)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!enumerationCache());
</span><span class="cx"> 
</span><del>-    if (specificFunctionThrashCount() == maxSpecificFunctionThrashCount)
-        specificValue = 0;
-
</del><span class="cx">     DeferGC deferGC(vm.heap);
</span><span class="cx">     materializePropertyMapIfNecessaryForPinning(vm, deferGC);
</span><span class="cx">     
</span><span class="cx">     pin();
</span><span class="cx"> 
</span><del>-    return putSpecificValue(vm, propertyName, attributes, specificValue);
</del><ins>+    return add(vm, propertyName, attributes);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PropertyOffset Structure::removePropertyWithoutTransition(VM&amp; vm, PropertyName propertyName)
</span><span class="lines">@@ -810,21 +746,57 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!hasRareData());
</span><span class="cx">     StructureRareData* rareData = StructureRareData::create(vm, previous());
</span><ins>+    WTF::storeStoreFence();
</ins><span class="cx">     m_previousOrRareData.set(vm, this, rareData);
</span><ins>+    WTF::storeStoreFence();
</ins><span class="cx">     setHasRareData(true);
</span><span class="cx">     ASSERT(hasRareData());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Structure::cloneRareDataFrom(VM&amp; vm, const Structure* other)
</del><ins>+WatchpointSet* Structure::ensurePropertyReplacementWatchpointSet(VM&amp; vm, PropertyOffset offset)
</ins><span class="cx"> {
</span><del>-    ASSERT(!hasRareData());
-    ASSERT(other-&gt;hasRareData());
-    StructureRareData* newRareData = StructureRareData::clone(vm, other-&gt;rareData());
-    m_previousOrRareData.set(vm, this, newRareData);
-    setHasRareData(true);
-    ASSERT(hasRareData());
</del><ins>+    ASSERT(!isUncacheableDictionary());
+    
+    if (!hasRareData())
+        allocateRareData(vm);
+    ConcurrentJITLocker locker(m_lock);
+    StructureRareData* rareData = this-&gt;rareData();
+    if (!rareData-&gt;m_replacementWatchpointSets) {
+        rareData-&gt;m_replacementWatchpointSets =
+            std::make_unique&lt;StructureRareData::PropertyWatchpointMap&gt;();
+        WTF::storeStoreFence();
+    }
+    auto result = rareData-&gt;m_replacementWatchpointSets-&gt;add(offset, nullptr);
+    if (result.isNewEntry)
+        result.iterator-&gt;value = adoptRef(new WatchpointSet(IsWatched));
+    return result.iterator-&gt;value.get();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Structure::startWatchingPropertyForReplacements(VM&amp; vm, PropertyName propertyName)
+{
+    ASSERT(!isUncacheableDictionary());
+    
+    PropertyOffset offset = get(vm, propertyName);
+    if (!JSC::isValidOffset(offset))
+        return;
+    
+    startWatchingPropertyForReplacements(vm, offset);
+}
+
+void Structure::didCachePropertyReplacement(VM&amp; vm, PropertyOffset offset)
+{
+    ensurePropertyReplacementWatchpointSet(vm, offset)-&gt;fireAll(&quot;Did cache property replacement&quot;);
+}
+
+void Structure::startWatchingInternalProperties(VM&amp; vm)
+{
+    if (!isUncacheableDictionary()) {
+        startWatchingPropertyForReplacements(vm, vm.propertyNames-&gt;toString);
+        startWatchingPropertyForReplacements(vm, vm.propertyNames-&gt;valueOf);
+    }
+    setDidWatchInternalProperties(true);
+}
+
</ins><span class="cx"> #if DUMP_PROPERTYMAP_STATS
</span><span class="cx"> 
</span><span class="cx"> PropertyMapHashTableStats* propertyMapHashTableStats = 0;
</span><span class="lines">@@ -881,7 +853,7 @@
</span><span class="cx">     return PropertyTable::create(vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PropertyOffset Structure::getConcurrently(VM&amp;, StringImpl* uid, unsigned&amp; attributes, JSCell*&amp; specificValue)
</del><ins>+PropertyOffset Structure::getConcurrently(VM&amp;, StringImpl* uid, unsigned&amp; attributes)
</ins><span class="cx"> {
</span><span class="cx">     Vector&lt;Structure*, 8&gt; structures;
</span><span class="cx">     Structure* structure;
</span><span class="lines">@@ -893,7 +865,6 @@
</span><span class="cx">         PropertyMapEntry* entry = table-&gt;get(uid);
</span><span class="cx">         if (entry) {
</span><span class="cx">             attributes = entry-&gt;attributes;
</span><del>-            specificValue = entry-&gt;specificValue.get();
</del><span class="cx">             PropertyOffset result = entry-&gt;offset;
</span><span class="cx">             structure-&gt;m_lock.unlock();
</span><span class="cx">             return result;
</span><span class="lines">@@ -907,43 +878,14 @@
</span><span class="cx">             continue;
</span><span class="cx">         
</span><span class="cx">         attributes = structure-&gt;attributesInPrevious();
</span><del>-        specificValue = structure-&gt;m_specificValueInPrevious.get();
</del><span class="cx">         return structure-&gt;m_offset;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     return invalidOffset;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Structure::despecifyFunction(VM&amp; vm, PropertyName propertyName)
</del><ins>+PropertyOffset Structure::add(VM&amp; vm, PropertyName propertyName, unsigned attributes)
</ins><span class="cx"> {
</span><del>-    DeferGC deferGC(vm.heap);
-    materializePropertyMapIfNecessary(vm, deferGC);
-    if (!propertyTable())
-        return false;
-
-    PropertyMapEntry* entry = propertyTable()-&gt;get(propertyName.uid());
-    if (!entry)
-        return false;
-
-    ASSERT(entry-&gt;specificValue);
-    entry-&gt;specificValue.clear();
-    return true;
-}
-
-void Structure::despecifyAllFunctions(VM&amp; vm)
-{
-    DeferGC deferGC(vm.heap);
-    materializePropertyMapIfNecessary(vm, deferGC);
-    if (!propertyTable())
-        return;
-
-    PropertyTable::iterator end = propertyTable()-&gt;end();
-    for (PropertyTable::iterator iter = propertyTable()-&gt;begin(); iter != end; ++iter)
-        iter-&gt;specificValue.clear();
-}
-
-PropertyOffset Structure::putSpecificValue(VM&amp; vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
-{
</del><span class="cx">     GCSafeConcurrentJITLocker locker(m_lock, vm.heap);
</span><span class="cx">     
</span><span class="cx">     ASSERT(!JSC::isValidOffset(get(vm, propertyName)));
</span><span class="lines">@@ -959,7 +901,7 @@
</span><span class="cx"> 
</span><span class="cx">     PropertyOffset newOffset = propertyTable()-&gt;nextOffset(m_inlineCapacity);
</span><span class="cx"> 
</span><del>-    propertyTable()-&gt;add(PropertyMapEntry(vm, propertyTable().get(), rep, newOffset, attributes, specificValue), m_offset, PropertyTable::PropertyOffsetMayChange);
</del><ins>+    propertyTable()-&gt;add(PropertyMapEntry(rep, newOffset, attributes), m_offset, PropertyTable::PropertyOffsetMayChange);
</ins><span class="cx">     
</span><span class="cx">     checkConsistency();
</span><span class="cx">     return newOffset;
</span><span class="lines">@@ -1018,6 +960,31 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+namespace {
+
+class StructureFireDetail : public FireDetail {
+public:
+    StructureFireDetail(const Structure* structure)
+        : m_structure(structure)
+    {
+    }
+    
+    virtual void dump(PrintStream&amp; out) const override
+    {
+        out.print(&quot;Structure transition from &quot;, *m_structure);
+    }
+
+private:
+    const Structure* m_structure;
+};
+
+} // anonymous namespace
+
+void Structure::didTransitionFromThisStructure() const
+{
+    m_transitionWatchpointSet.fireAll(StructureFireDetail(this));
+}
+
</ins><span class="cx"> JSValue Structure::prototypeForLookup(CodeBlock* codeBlock) const
</span><span class="cx"> {
</span><span class="cx">     return prototypeForLookup(codeBlock-&gt;globalObject());
</span><span class="lines">@@ -1037,7 +1004,6 @@
</span><span class="cx">         visitor.append(&amp;thisObject-&gt;m_cachedPrototypeChain);
</span><span class="cx">     }
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_previousOrRareData);
</span><del>-    visitor.append(&amp;thisObject-&gt;m_specificValueInPrevious);
</del><span class="cx"> 
</span><span class="cx">     if (thisObject-&gt;isPinnedPropertyTable()) {
</span><span class="cx">         ASSERT(thisObject-&gt;m_propertyTableUnsafe);
</span><span class="lines">@@ -1060,8 +1026,7 @@
</span><span class="cx">         current = prototype.asCell()-&gt;structure(vm);
</span><span class="cx">         
</span><span class="cx">         unsigned attributes;
</span><del>-        JSCell* specificValue;
-        PropertyOffset offset = current-&gt;get(vm, propertyName, attributes, specificValue);
</del><ins>+        PropertyOffset offset = current-&gt;get(vm, propertyName, attributes);
</ins><span class="cx">         if (!JSC::isValidOffset(offset))
</span><span class="cx">             continue;
</span><span class="cx">         
</span><span class="lines">@@ -1101,7 +1066,6 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     shape-&gt;markAsFinal();
</span><del>-
</del><span class="cx">     return shape.release();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1121,13 +1085,8 @@
</span><span class="cx">     if (table) {
</span><span class="cx">         PropertyTable::iterator iter = table-&gt;begin();
</span><span class="cx">         PropertyTable::iterator end = table-&gt;end();
</span><del>-        for (; iter != end; ++iter) {
</del><ins>+        for (; iter != end; ++iter)
</ins><span class="cx">             out.print(comma, iter-&gt;key, &quot;:&quot;, static_cast&lt;int&gt;(iter-&gt;offset));
</span><del>-            if (iter-&gt;specificValue) {
-                DumpContext dummyContext;
-                out.print(&quot;=&gt;&quot;, RawPointer(iter-&gt;specificValue.get()));
-            }
-        }
</del><span class="cx">         
</span><span class="cx">         structure-&gt;m_lock.unlock();
</span><span class="cx">     }
</span><span class="lines">@@ -1137,10 +1096,6 @@
</span><span class="cx">         if (!structure-&gt;m_nameInPrevious)
</span><span class="cx">             continue;
</span><span class="cx">         out.print(comma, structure-&gt;m_nameInPrevious.get(), &quot;:&quot;, static_cast&lt;int&gt;(structure-&gt;m_offset));
</span><del>-        if (structure-&gt;m_specificValueInPrevious) {
-            DumpContext dummyContext;
-            out.print(&quot;=&gt;&quot;, RawPointer(structure-&gt;m_specificValueInPrevious.get()));
-        }
</del><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     out.print(&quot;}, &quot;, IndexingTypeDump(indexingType()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/Structure.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -59,6 +59,7 @@
</span><span class="cx"> class PropertyNameArrayData;
</span><span class="cx"> class PropertyTable;
</span><span class="cx"> class StructureChain;
</span><ins>+class StructureShape;
</ins><span class="cx"> class SlotVisitor;
</span><span class="cx"> class JSString;
</span><span class="cx"> struct DumpContext;
</span><span class="lines">@@ -111,12 +112,11 @@
</span><span class="cx"> 
</span><span class="cx">     static void dumpStatistics();
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&amp;, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&amp;, PutPropertySlot::Context = PutPropertySlot::UnknownContext);
-    static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&amp;);
-    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&amp;);
</del><ins>+    JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&amp;, Structure*, PropertyName, unsigned attributes, PropertyOffset&amp;, PutPropertySlot::Context = PutPropertySlot::UnknownContext);
+    static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, StringImpl* uid, unsigned attributes, PropertyOffset&amp;);
+    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, PropertyOffset&amp;);
</ins><span class="cx">     static Structure* removePropertyTransition(VM&amp;, Structure*, PropertyName, PropertyOffset&amp;);
</span><span class="cx">     JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(VM&amp;, Structure*, JSValue prototype);
</span><del>-    JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(VM&amp;, Structure*, PropertyName);
</del><span class="cx">     static Structure* attributeChangeTransition(VM&amp;, Structure*, PropertyName, unsigned attributes);
</span><span class="cx">     JS_EXPORT_PRIVATE static Structure* toCacheableDictionaryTransition(VM&amp;, Structure*);
</span><span class="cx">     static Structure* toUncacheableDictionaryTransition(VM&amp;, Structure*);
</span><span class="lines">@@ -138,7 +138,7 @@
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx"> 
</span><span class="cx">     // These should be used with caution.  
</span><del>-    JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(VM&amp;, PropertyName, unsigned attributes, JSCell* specificValue);
</del><ins>+    JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(VM&amp;, PropertyName, unsigned attributes);
</ins><span class="cx">     PropertyOffset removePropertyWithoutTransition(VM&amp;, PropertyName);
</span><span class="cx">     void setPrototypeWithoutTransition(VM&amp; vm, JSValue prototype) { m_prototype.set(vm, this, prototype); }
</span><span class="cx">         
</span><span class="lines">@@ -188,8 +188,6 @@
</span><span class="cx">     // Will just the prototype chain intercept this property access?
</span><span class="cx">     bool prototypeChainMayInterceptStoreTo(VM&amp;, PropertyName);
</span><span class="cx">         
</span><del>-    bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
-        
</del><span class="cx">     Structure* previousID() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(structure()-&gt;classInfo() == info());
</span><span class="lines">@@ -263,10 +261,10 @@
</span><span class="cx"> 
</span><span class="cx">     PropertyOffset get(VM&amp;, PropertyName);
</span><span class="cx">     PropertyOffset get(VM&amp;, const WTF::String&amp; name);
</span><del>-    PropertyOffset get(VM&amp;, PropertyName, unsigned&amp; attributes, JSCell*&amp; specificValue);
</del><ins>+    PropertyOffset get(VM&amp;, PropertyName, unsigned&amp; attributes);
</ins><span class="cx"> 
</span><span class="cx">     PropertyOffset getConcurrently(VM&amp;, StringImpl* uid);
</span><del>-    PropertyOffset getConcurrently(VM&amp;, StringImpl* uid, unsigned&amp; attributes, JSCell*&amp; specificValue);
</del><ins>+    PropertyOffset getConcurrently(VM&amp;, StringImpl* uid, unsigned&amp; attributes);
</ins><span class="cx">     
</span><span class="cx">     void setHasGetterSetterPropertiesWithProtoCheck(bool is__proto__)
</span><span class="cx">     {
</span><span class="lines">@@ -290,9 +288,6 @@
</span><span class="cx">         return !JSC::isValidOffset(m_offset);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE void despecifyDictionaryFunction(VM&amp;, PropertyName);
-    void disableSpecificFunctionTracking() { setSpecificFunctionThrashCount(maxSpecificFunctionThrashCount); }
-
</del><span class="cx">     void setEnumerationCache(VM&amp;, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
</span><span class="cx">     JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
</span><span class="cx">     void getPropertyNamesFromStructure(VM&amp;, PropertyNameArray&amp;, EnumerationMode);
</span><span class="lines">@@ -371,16 +366,36 @@
</span><span class="cx">         ASSERT(transitionWatchpointSetIsStillValid());
</span><span class="cx">         m_transitionWatchpointSet.add(watchpoint);
</span><span class="cx">     }
</span><del>-        
-    void notifyTransitionFromThisStructure() const
-    {
-        m_transitionWatchpointSet.fireAll();
-    }
</del><span class="cx">     
</span><ins>+    void didTransitionFromThisStructure() const;
+    
</ins><span class="cx">     InlineWatchpointSet&amp; transitionWatchpointSet() const
</span><span class="cx">     {
</span><span class="cx">         return m_transitionWatchpointSet;
</span><span class="cx">     }
</span><ins>+    
+    WatchpointSet* ensurePropertyReplacementWatchpointSet(VM&amp;, PropertyOffset);
+    void startWatchingPropertyForReplacements(VM&amp; vm, PropertyOffset offset)
+    {
+        ensurePropertyReplacementWatchpointSet(vm, offset);
+    }
+    void startWatchingPropertyForReplacements(VM&amp;, PropertyName);
+    WatchpointSet* propertyReplacementWatchpointSet(PropertyOffset);
+    void didReplaceProperty(PropertyOffset);
+    void didCachePropertyReplacement(VM&amp;, PropertyOffset);
+    
+    void startWatchingInternalPropertiesIfNecessary(VM&amp; vm)
+    {
+        if (LIKELY(didWatchInternalProperties()))
+            return;
+        startWatchingInternalProperties(vm);
+    }
+    
+    void startWatchingInternalPropertiesIfNecessaryForEntireChain(VM&amp; vm)
+    {
+        for (Structure* structure = this; structure; structure = structure-&gt;storedPrototypeStructure())
+            structure-&gt;startWatchingInternalPropertiesIfNecessary(vm);
+    }
</ins><span class="cx"> 
</span><span class="cx">     PassRefPtr&lt;StructureShape&gt; toStructureShape();
</span><span class="cx">     
</span><span class="lines">@@ -416,13 +431,13 @@
</span><span class="cx">     DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4);
</span><span class="cx">     DEFINE_BITFIELD(bool, hasNonEnumerableProperties, HasNonEnumerableProperties, 1, 5);
</span><span class="cx">     DEFINE_BITFIELD(unsigned, attributesInPrevious, AttributesInPrevious, 14, 6);
</span><del>-    DEFINE_BITFIELD(unsigned, specificFunctionThrashCount, SpecificFunctionThrashCount, 2, 20);
-    DEFINE_BITFIELD(bool, preventExtensions, PreventExtensions, 1, 22);
-    DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 23);
-    DEFINE_BITFIELD(bool, staticFunctionsReified, StaticFunctionsReified, 1, 24);
-    DEFINE_BITFIELD(bool, hasRareData, HasRareData, 1, 25);
-    DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 26);
-    DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 27);
</del><ins>+    DEFINE_BITFIELD(bool, preventExtensions, PreventExtensions, 1, 20);
+    DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 21);
+    DEFINE_BITFIELD(bool, staticFunctionsReified, StaticFunctionsReified, 1, 22);
+    DEFINE_BITFIELD(bool, hasRareData, HasRareData, 1, 23);
+    DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 24);
+    DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 25);
+    DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 26);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="lines">@@ -433,7 +448,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Structure* create(VM&amp;, Structure*);
</span><span class="cx">     
</span><del>-    static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&amp;);
</del><ins>+    static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, StringImpl* uid, unsigned attributes, PropertyOffset&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // This will return the structure that has a usable property table, that property table,
</span><span class="cx">     // and the list of structures that we visited before we got to it. If it returns a
</span><span class="lines">@@ -443,15 +458,12 @@
</span><span class="cx">     
</span><span class="cx">     static Structure* toDictionaryTransition(VM&amp;, Structure*, DictionaryKind);
</span><span class="cx"> 
</span><del>-    PropertyOffset putSpecificValue(VM&amp;, PropertyName, unsigned attributes, JSCell* specificValue);
</del><ins>+    PropertyOffset add(VM&amp;, PropertyName, unsigned attributes);
</ins><span class="cx">     PropertyOffset remove(PropertyName);
</span><span class="cx"> 
</span><span class="cx">     void createPropertyMap(const GCSafeConcurrentJITLocker&amp;, VM&amp;, unsigned keyCount = 0);
</span><span class="cx">     void checkConsistency();
</span><span class="cx"> 
</span><del>-    bool despecifyFunction(VM&amp;, PropertyName);
-    void despecifyAllFunctions(VM&amp;);
-
</del><span class="cx">     WriteBarrier&lt;PropertyTable&gt;&amp; propertyTable();
</span><span class="cx">     PropertyTable* takePropertyTableOrCloneIfPinned(VM&amp;);
</span><span class="cx">     PropertyTable* copyPropertyTable(VM&amp;);
</span><span class="lines">@@ -527,13 +539,12 @@
</span><span class="cx">     bool checkOffsetConsistency() const;
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void allocateRareData(VM&amp;);
</span><del>-    void cloneRareDataFrom(VM&amp;, const Structure*);
</del><ins>+    
+    void startWatchingInternalProperties(VM&amp;);
</ins><span class="cx"> 
</span><span class="cx">     static const int s_maxTransitionLength = 64;
</span><span class="cx">     static const int s_maxTransitionLengthForNonEvalPutById = 512;
</span><span class="cx"> 
</span><del>-    static const unsigned maxSpecificFunctionThrashCount = 3;
-    
</del><span class="cx">     // These need to be properly aligned at the beginning of the 'Structure'
</span><span class="cx">     // part of the object.
</span><span class="cx">     StructureIDBlob m_blob;
</span><span class="lines">@@ -546,7 +557,6 @@
</span><span class="cx">     WriteBarrier&lt;JSCell&gt; m_previousOrRareData;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;StringImpl&gt; m_nameInPrevious;
</span><del>-    WriteBarrier&lt;JSCell&gt; m_specificValueInPrevious;
</del><span class="cx"> 
</span><span class="cx">     const ClassInfo* m_classInfo;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureInlines.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureInlines.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/StructureInlines.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSValue value = m_prototype.get();
</span><span class="cx">     if (value.isNull())
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     return asObject(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSObject* object = storedPrototypeObject();
</span><span class="cx">     if (!object)
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     return object-&gt;structure();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -99,7 +99,7 @@
</span><span class="cx">     return entry ? entry-&gt;offset : invalidOffset;
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-ALWAYS_INLINE PropertyOffset Structure::get(VM&amp; vm, PropertyName propertyName, unsigned&amp; attributes, JSCell*&amp; specificValue)
</del><ins>+ALWAYS_INLINE PropertyOffset Structure::get(VM&amp; vm, PropertyName propertyName, unsigned&amp; attributes)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!isCompilationThread());
</span><span class="cx">     ASSERT(structure()-&gt;classInfo() == info());
</span><span class="lines">@@ -114,16 +114,13 @@
</span><span class="cx">         return invalidOffset;
</span><span class="cx"> 
</span><span class="cx">     attributes = entry-&gt;attributes;
</span><del>-    specificValue = entry-&gt;specificValue.get();
</del><span class="cx">     return entry-&gt;offset;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline PropertyOffset Structure::getConcurrently(VM&amp; vm, StringImpl* uid)
</span><span class="cx"> {
</span><span class="cx">     unsigned attributesIgnored;
</span><del>-    JSCell* specificValueIgnored;
-    return getConcurrently(
-        vm, uid, attributesIgnored, specificValueIgnored);
</del><ins>+    return getConcurrently(vm, uid, attributesIgnored);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool Structure::hasIndexingHeader(const JSCell* cell) const
</span><span class="lines">@@ -242,6 +239,31 @@
</span><span class="cx">     return m_propertyTableUnsafe;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void Structure::didReplaceProperty(PropertyOffset offset)
+{
+    if (LIKELY(!hasRareData()))
+        return;
+    StructureRareData::PropertyWatchpointMap* map = rareData()-&gt;m_replacementWatchpointSets.get();
+    if (LIKELY(!map))
+        return;
+    WatchpointSet* set = map-&gt;get(offset);
+    if (LIKELY(!set))
+        return;
+    set-&gt;fireAll(&quot;Property did get replaced&quot;);
+}
+
+inline WatchpointSet* Structure::propertyReplacementWatchpointSet(PropertyOffset offset)
+{
+    ConcurrentJITLocker locker(m_lock);
+    if (!hasRareData())
+        return nullptr;
+    WTF::loadLoadFence();
+    StructureRareData::PropertyWatchpointMap* map = rareData()-&gt;m_replacementWatchpointSets.get();
+    if (!map)
+        return nullptr;
+    return map-&gt;get(offset);
+}
+
</ins><span class="cx"> ALWAYS_INLINE bool Structure::checkOffsetConsistency() const
</span><span class="cx"> {
</span><span class="cx">     PropertyTable* propertyTable = m_propertyTableUnsafe.get();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -46,11 +46,9 @@
</span><span class="cx">     return rareData;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-StructureRareData* StructureRareData::clone(VM&amp; vm, const StructureRareData* other)
</del><ins>+void StructureRareData::destroy(JSCell* cell)
</ins><span class="cx"> {
</span><del>-    StructureRareData* newRareData = new (NotNull, allocateCell&lt;StructureRareData&gt;(vm.heap)) StructureRareData(vm, other);
-    newRareData-&gt;finishCreation(vm);
-    return newRareData;
</del><ins>+    static_cast&lt;StructureRareData*&gt;(cell)-&gt;StructureRareData::~StructureRareData();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> StructureRareData::StructureRareData(VM&amp; vm, Structure* previous)
</span><span class="lines">@@ -60,15 +58,6 @@
</span><span class="cx">         m_previous.set(vm, this, previous);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-StructureRareData::StructureRareData(VM&amp; vm, const StructureRareData* other)
-    : JSCell(vm, other-&gt;structure())
-{
-    if (other-&gt;previousID())
-        m_previous.set(vm, this, other-&gt;previousID());
-    if (other-&gt;objectToStringValue())
-        m_objectToStringValue.set(vm, this, other-&gt;objectToStringValue());
-}
-
</del><span class="cx"> void StructureRareData::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
</span><span class="cx"> {
</span><span class="cx">     StructureRareData* thisObject = jsCast&lt;StructureRareData*&gt;(cell);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareData.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareData.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareData.h        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -29,6 +29,7 @@
</span><span class="cx"> #include &quot;ClassInfo.h&quot;
</span><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="cx"> #include &quot;JSTypeInfo.h&quot;
</span><ins>+#include &quot;PropertyOffset.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -39,15 +40,15 @@
</span><span class="cx">     friend class Structure;
</span><span class="cx"> public:
</span><span class="cx">     static StructureRareData* create(VM&amp;, Structure*);
</span><del>-    static StructureRareData* clone(VM&amp;, const StructureRareData* other);
</del><span class="cx"> 
</span><ins>+    static const bool needsDestruction = true;
+    static const bool hasImmortalStructure = true;
+    static void destroy(JSCell*);
+
</ins><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue prototype);
</span><span class="cx"> 
</span><del>-    // Returns true if this StructureRareData should also be cloned when cloning the owner Structure.
-    bool needsCloning() const { return false; }
-
</del><span class="cx">     Structure* previousID() const;
</span><span class="cx">     void setPreviousID(VM&amp;, Structure*);
</span><span class="cx">     void clearPreviousID();
</span><span class="lines">@@ -61,14 +62,18 @@
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    friend class Structure;
+    
</ins><span class="cx">     StructureRareData(VM&amp;, Structure*);
</span><del>-    StructureRareData(VM&amp;, const StructureRareData*);
</del><span class="cx"> 
</span><span class="cx">     static const unsigned StructureFlags = JSCell::StructureFlags;
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_previous;
</span><span class="cx">     WriteBarrier&lt;JSString&gt; m_objectToStringValue;
</span><span class="cx">     WriteBarrier&lt;JSPropertyNameIterator&gt; m_enumerationCache;
</span><ins>+    
+    typedef HashMap&lt;PropertyOffset, RefPtr&lt;WatchpointSet&gt;, WTF::IntHash&lt;PropertyOffset&gt;, WTF::UnsignedWithZeroKeyHashTraits&lt;PropertyOffset&gt;&gt; PropertyWatchpointMap;
+    std::unique_ptr&lt;PropertyWatchpointMap&gt; m_replacementWatchpointSets;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -79,13 +79,13 @@
</span><span class="cx">     fatEntry()-&gt;m_watchpoints-&gt;add(watchpoint);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SymbolTableEntry::notifyWriteSlow(VM&amp; vm, JSValue value)
</del><ins>+void SymbolTableEntry::notifyWriteSlow(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
</ins><span class="cx"> {
</span><span class="cx">     VariableWatchpointSet* watchpoints = fatEntry()-&gt;m_watchpoints.get();
</span><span class="cx">     if (!watchpoints)
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    watchpoints-&gt;notifyWrite(vm, value);
</del><ins>+    watchpoints-&gt;notifyWrite(vm, value, detail);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow()
</span><span class="lines">@@ -132,11 +132,12 @@
</span><span class="cx"> 
</span><span class="cx"> void SymbolTable::WatchpointCleanup::finalizeUnconditionally()
</span><span class="cx"> {
</span><ins>+    StringFireDetail detail(&quot;Symbol table clean-up during GC&quot;);
</ins><span class="cx">     Map::iterator iter = m_symbolTable-&gt;m_map.begin();
</span><span class="cx">     Map::iterator end = m_symbolTable-&gt;m_map.end();
</span><span class="cx">     for (; iter != end; ++iter) {
</span><span class="cx">         if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet())
</span><del>-            set-&gt;finalizeUnconditionally();
</del><ins>+            set-&gt;finalizeUnconditionally(detail);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -230,11 +230,11 @@
</span><span class="cx">         return fatEntry()-&gt;m_watchpoints.get();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ALWAYS_INLINE void notifyWrite(VM&amp; vm, JSValue value)
</del><ins>+    ALWAYS_INLINE void notifyWrite(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
</ins><span class="cx">     {
</span><span class="cx">         if (LIKELY(!isFat()))
</span><span class="cx">             return;
</span><del>-        notifyWriteSlow(vm, value);
</del><ins>+        notifyWriteSlow(vm, value, detail);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="lines">@@ -258,7 +258,7 @@
</span><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     SymbolTableEntry&amp; copySlow(const SymbolTableEntry&amp;);
</span><del>-    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&amp;, JSValue);
</del><ins>+    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&amp;, JSValue, const FireDetail&amp;);
</ins><span class="cx">     
</span><span class="cx">     bool isFat() const
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeSet.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> TypeSet::TypeSet()
</span><span class="cx">     : m_seenTypes(TypeNothing)
</span><span class="cx">     , m_structureHistory(new Vector&lt;RefPtr&lt;StructureShape&gt;&gt;)
</span><del>-    , m_mightHaveDuplicatesInStructureHistory(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -69,34 +68,31 @@
</span><span class="cx">     return ret;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TypeSet::addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt; shape) 
</del><ins>+void TypeSet::addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt; shape, StructureID id) 
</ins><span class="cx"> {
</span><span class="cx">     RuntimeType t = getRuntimeTypeForValue(v);
</span><span class="cx">     m_seenTypes = m_seenTypes | t;
</span><span class="cx"> 
</span><del>-    if (shape) {
-        m_structureHistory-&gt;append(shape);
-        m_mightHaveDuplicatesInStructureHistory = true;
-    }
-}
</del><ins>+    if (id &amp;&amp; shape) {
+        ASSERT(m_structureIDHistory.isValidKey(id));
+        auto iter = m_structureIDHistory.find(id);
+        if (iter == m_structureIDHistory.end()) {
+            m_structureIDHistory.set(id, 1);
+            // Make one more pass making sure that we don't have the same shape. (Same shapes may have different StructureIDs).
+            bool found = false;
+            String hash = shape-&gt;propertyHash();
+            for (size_t i = 0; i &lt; m_structureHistory-&gt;size(); i++) {
+                RefPtr&lt;StructureShape&gt; obj = m_structureHistory-&gt;at(i);
+                if (obj-&gt;propertyHash() == hash) {
+                    found = true;
+                    break;
+                }
+            }
</ins><span class="cx"> 
</span><del>-void TypeSet::removeDuplicatesInStructureHistory() 
-{
-    Vector&lt;RefPtr&lt;StructureShape&gt;&gt;* newHistory = new Vector&lt;RefPtr&lt;StructureShape&gt;&gt;;
-    HashMap&lt;String, bool&gt; container;
-    for (size_t i = 0; i &lt; m_structureHistory-&gt;size(); i++) {
-        RefPtr&lt;StructureShape&gt; a = m_structureHistory-&gt;at(i);
-        String hash = a-&gt;propertyHash();
-        auto iter = container.find(hash);
-        if (iter == container.end()) {
-            container.add(hash, true);
-            newHistory-&gt;append(a);
</del><ins>+            if (!found)
+                m_structureHistory-&gt;append(shape);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><del>-
-    delete m_structureHistory;
-    m_structureHistory = newHistory;
-    m_mightHaveDuplicatesInStructureHistory = false;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String TypeSet::seenTypes() 
</span><span class="lines">@@ -104,9 +100,6 @@
</span><span class="cx">     if (m_seenTypes == TypeNothing)
</span><span class="cx">         return &quot;(Unreached Statement)&quot;;
</span><span class="cx"> 
</span><del>-    if (m_mightHaveDuplicatesInStructureHistory)
-        removeDuplicatesInStructureHistory();
-
</del><span class="cx">     StringBuilder seen;
</span><span class="cx"> 
</span><span class="cx">     if (m_seenTypes &amp; TypeFunction)
</span><span class="lines">@@ -128,6 +121,14 @@
</span><span class="cx">     if (m_seenTypes &amp; TypeObject)
</span><span class="cx">          seen.append(&quot;Object &quot;);
</span><span class="cx"> 
</span><ins>+    for (size_t i = 0; i &lt; m_structureHistory-&gt;size(); i++) {
+        RefPtr&lt;StructureShape&gt; shape = m_structureHistory-&gt;at(i);
+        if (!shape-&gt;m_constructorName.isEmpty()) {
+            seen.append(shape-&gt;m_constructorName);
+            seen.append(&quot; &quot;);
+        }
+    }
+
</ins><span class="cx">     if (m_structureHistory-&gt;size()) 
</span><span class="cx">         seen.append(&quot;\nStructures:[ &quot;);
</span><span class="cx">     for (size_t i = 0; i &lt; m_structureHistory-&gt;size(); i++) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeSet.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeSet.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/TypeSet.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef TypeSet_h
</span><span class="cx"> #define TypeSet_h
</span><span class="cx"> 
</span><ins>+#include &quot;StructureIDTable.h&quot;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="lines">@@ -60,10 +61,12 @@
</span><span class="cx">     void addProperty(RefPtr&lt;StringImpl&gt;);
</span><span class="cx">     static String leastUpperBound(Vector&lt;RefPtr&lt;StructureShape&gt;&gt;*);
</span><span class="cx">     String stringRepresentation();
</span><ins>+    void setConstructorName(String name) { m_constructorName = name; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     HashMap&lt;RefPtr&lt;StringImpl&gt;, bool&gt; m_fields;         
</span><span class="cx">     std::unique_ptr&lt;String&gt; m_propertyHash;
</span><ins>+    String m_constructorName;
</ins><span class="cx">     bool m_final;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -72,7 +75,7 @@
</span><span class="cx"> public:
</span><span class="cx">     static PassRefPtr&lt;TypeSet&gt; create() { return adoptRef(new TypeSet); }
</span><span class="cx">     TypeSet();
</span><del>-    void addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt;);
</del><ins>+    void addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt;, StructureID);
</ins><span class="cx">     static RuntimeType getRuntimeTypeForValue(JSValue);
</span><span class="cx">     JS_EXPORT_PRIVATE String seenTypes();
</span><span class="cx"> 
</span><span class="lines">@@ -80,9 +83,7 @@
</span><span class="cx">     uint32_t m_seenTypes;
</span><span class="cx">     void dumpSeenTypes();
</span><span class="cx">     Vector&lt;RefPtr&lt;StructureShape&gt;&gt;* m_structureHistory;
</span><del>-    bool m_mightHaveDuplicatesInStructureHistory;
-    void removeDuplicatesInStructureHistory();
-
</del><ins>+    HashMap&lt;StructureID, uint8_t&gt; m_structureIDHistory;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -40,7 +40,6 @@
</span><span class="cx"> #include &quot;CustomGetterSetter.h&quot;
</span><span class="cx"> #include &quot;DFGLongLivedState.h&quot;
</span><span class="cx"> #include &quot;DFGWorklist.h&quot;
</span><del>-#include &quot;DebuggerScope.h&quot;
</del><span class="cx"> #include &quot;ErrorInstance.h&quot;
</span><span class="cx"> #include &quot;FTLThunks.h&quot;
</span><span class="cx"> #include &quot;FunctionConstructor.h&quot;
</span><span class="lines">@@ -206,7 +205,6 @@
</span><span class="cx">     propertyNames = new CommonIdentifiers(this);
</span><span class="cx">     structureStructure.set(*this, Structure::createStructure(*this));
</span><span class="cx">     structureRareDataStructure.set(*this, StructureRareData::createStructure(*this, 0, jsNull()));
</span><del>-    debuggerScopeStructure.set(*this, DebuggerScope::createStructure(*this, 0, jsNull()));
</del><span class="cx">     terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
</span><span class="cx">     stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
</span><span class="cx">     notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, 0, jsNull()));
</span><span class="lines">@@ -835,7 +833,7 @@
</span><span class="cx"> void VM::addImpureProperty(const String&amp; propertyName)
</span><span class="cx"> {
</span><span class="cx">     if (RefPtr&lt;WatchpointSet&gt; watchpointSet = m_impurePropertyWatchpointSets.take(propertyName))
</span><del>-        watchpointSet-&gt;fireAll();
</del><ins>+        watchpointSet-&gt;fireAll(&quot;Impure property added&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> class SetEnabledProfilerFunctor {
</span><span class="lines">@@ -858,7 +856,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String VM::getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String&amp; variableName, const String&amp; sourceIDAsString)
</del><ins>+String VM::getTypesForVariableAtOffset(unsigned offset, const String&amp; variableName, const String&amp; sourceIDAsString)
</ins><span class="cx"> {
</span><span class="cx">     if (!isProfilingTypesWithHighFidelity())
</span><span class="cx">         return &quot;(Not Profiling)&quot;;
</span><span class="lines">@@ -869,7 +867,7 @@
</span><span class="cx">         CRASH();
</span><span class="cx"> 
</span><span class="cx">     updateHighFidelityTypeProfileState();
</span><del>-    return m_highFidelityTypeProfiler-&gt;getTypesForVariableInRange(startLine, startColumn, endLine, endColumn, variableName, sourceID);
</del><ins>+    return m_highFidelityTypeProfiler-&gt;getTypesForVariableInAtOffset(offset, variableName, sourceID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void VM::updateHighFidelityTypeProfileState()
</span><span class="lines">@@ -889,11 +887,11 @@
</span><span class="cx">     HighFidelityTypeProfiler* profiler = m_highFidelityTypeProfiler.get();
</span><span class="cx">     for (Bag&lt;TypeLocation&gt;::iterator iter = m_locationInfo.begin(); !!iter; ++iter) {
</span><span class="cx">         TypeLocation* location = *iter;
</span><del>-        dataLogF(&quot;[Line, Column]::[%u, %u] &quot;, location-&gt;m_line, location-&gt;m_column);
</del><ins>+        dataLogF(&quot;[Start, End]::[%u, %u] &quot;, location-&gt;m_divotStart, location-&gt;m_divotEnd);
</ins><span class="cx">         dataLog(&quot;\n\t\t#Local#\n\t\t&quot;,
</span><del>-                profiler-&gt;getLocalTypesForVariableInRange(location-&gt;m_line, location-&gt;m_column, location-&gt;m_line, location-&gt;m_column, &quot;&quot;, location-&gt;m_sourceID).replace(&quot;\n&quot;, &quot;\n\t\t&quot;),
</del><ins>+                profiler-&gt;getLocalTypesForVariableAtOffset(location-&gt;m_divotStart, &quot;&quot;, location-&gt;m_sourceID).replace(&quot;\n&quot;, &quot;\n\t\t&quot;),
</ins><span class="cx">                 &quot;\n\t\t#Global#\n\t\t&quot;,
</span><del>-                profiler-&gt;getGlobalTypesForVariableInRange(location-&gt;m_line, location-&gt;m_column, location-&gt;m_line, location-&gt;m_column, &quot;&quot;, location-&gt;m_sourceID).replace(&quot;\n&quot;, &quot;\n\t\t&quot;),
</del><ins>+                profiler-&gt;getGlobalTypesForVariableAtOffset(location-&gt;m_divotStart, &quot;&quot;, location-&gt;m_sourceID).replace(&quot;\n&quot;, &quot;\n\t\t&quot;),
</ins><span class="cx">                 &quot;\n&quot;);
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -240,7 +240,6 @@
</span><span class="cx"> 
</span><span class="cx">         Strong&lt;Structure&gt; structureStructure;
</span><span class="cx">         Strong&lt;Structure&gt; structureRareDataStructure;
</span><del>-        Strong&lt;Structure&gt; debuggerScopeStructure;
</del><span class="cx">         Strong&lt;Structure&gt; terminatedExecutionErrorStructure;
</span><span class="cx">         Strong&lt;Structure&gt; stringStructure;
</span><span class="cx">         Strong&lt;Structure&gt; notAnObjectStructure;
</span><span class="lines">@@ -494,7 +493,7 @@
</span><span class="cx">         BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
</span><span class="cx"> 
</span><span class="cx">         bool isProfilingTypesWithHighFidelity() { return !!m_highFidelityTypeProfiler; }
</span><del>-        String getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String&amp; variableName, const String&amp; sourceID);
</del><ins>+        String getTypesForVariableAtOffset(unsigned divot, const String&amp; variableName, const String&amp; sourceID);
</ins><span class="cx">         HighFidelityLog* highFidelityLog() { return m_highFidelityLog.get(); }
</span><span class="cx">         HighFidelityTypeProfiler* highFidelityTypeProfiler() { return m_highFidelityTypeProfiler.get(); }
</span><span class="cx">         void updateHighFidelityTypeProfileState();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresscachedprototypesetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/cached-prototype-setter.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/cached-prototype-setter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/cached-prototype-setter.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+(function() {
+    var xSetterCalled = false;
+
+    function MyConstructor()
+    {
+        this.x = 1;
+    }
+    
+    new MyConstructor;
+    new MyConstructor;
+    function setter() {
+        xSetterCalled = true;
+    }
+    Object.prototype.__defineSetter__(&quot;x&quot;, setter);
+    new MyConstructor;
+
+    if (!xSetterCalled)
+        throw new Error(&quot;FAIL: 'x' setter was not called.&quot;);
+})();
+
+(function() {
+    var xSetterCalled = false;
+
+    function makeO()
+    {
+        var o = { };
+        o.x = 1;
+        return o;
+    }
+
+    makeO();
+    makeO();
+    function setter(x) {
+        xSetterCalled = true;
+    }
+    Object.prototype.__defineSetter__(&quot;x&quot;, setter);
+    makeO();
+
+    if (!xSetterCalled)
+        throw new Error(&quot;FAIL: 'x' setter was not called.&quot;);
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressexitfromsetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/exit-from-setter.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/exit-from-setter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/exit-from-setter.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+(function() {
+    var o = {_f:42};
+    o.__defineSetter__(&quot;f&quot;, function(value) { this._f = value * 100; });
+    var n = 50000;
+    function foo(o_, v_) {
+        var o = o_.f;
+        var v = v_.f;
+        o.f = v;
+        o.f = v + 1;
+    }
+    noInline(foo);
+    for (var i = 0; i &lt; n; ++i) {
+        foo({f:o}, {f:11});
+    }
+    if (o._f != (11 + 1) * 100)
+        throw &quot;Error: bad o._f: &quot; + o._f;
+    for (var i = 0; i &lt; n; ++i) {
+        foo({f:o}, {f:1000000000});
+    }
+    if (o._f != 100 * (1000000000 + 1))
+        throw &quot;Error: bad o._f (2): &quot; + o._f;
+})();
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftlcheckinvariablejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-checkin-variable.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-checkin-variable.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-checkin-variable.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+function foo(l,x){
+    var t = l in x; 
+    return t;
+}
+
+noInline(foo);
+
+var r;
+for (var i = 0; i &lt; 1000000; ++i) {
+    var z = { 'y' : i, 's' : i + 1 };
+    z.s = 10;
+    r = foo(&quot;s&quot;,z);
+}
+
+if (!r) {
+    print (&quot;Error: &quot; + r);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressftlcheckinjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/ftl-checkin.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/ftl-checkin.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/ftl-checkin.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+function foo(x){
+    var t = &quot;s&quot; in x; 
+    return t;
+}
+
+noInline(foo);
+
+var r;
+for (var i = 0; i &lt; 1000000; ++i) {
+    var z = { 'y' : i, 's' : i + 1 };
+    z.s = 10;
+    r = foo(z);
+}
+
+if (!r) {
+    print (&quot;Error: &quot; + r);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressinferconstantglobalpropertyjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/infer-constant-global-property.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/infer-constant-global-property.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/infer-constant-global-property.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+function foo(p) {
+    if (p)
+        Math = {sin: function() { return 42; }, PI: 43, abs: Math.abs};
+}
+
+noInline(foo);
+
+(function() {
+    var n = 100000;
+    var m = 100;
+    var result = 0;
+    for (var i = 0; i &lt; n; ++i) {
+        foo(i == n - m);
+        result += Math.sin(Math.PI);
+    }
+    if (Math.abs(result - m * 42) &gt; 1e-8)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressinferconstantpropertyjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/infer-constant-property.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/infer-constant-property.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/infer-constant-property.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+var o = {f:{f:{f:{f:{f:{f:{f:42}}}}}}};
+
+function foo(p) {
+    if (p)
+        o.f.f.f.f.f.f = {f:53};
+}
+
+noInline(foo);
+
+(function() {
+    var n = 100000;
+    var m = 100;
+    var result = 0;
+    
+    for (var i = 0; i &lt; n; ++i) {
+        foo(i == n - m);
+        result += o.f.f.f.f.f.f.f;
+    }
+    
+    if (result != (n - m) * 42 + m * 53)
+        throw &quot;Error: bad result: &quot; + result;
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressjitcachepolyreplacethencachegetandfoldtheninvalidatejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+var o = {f:42};
+
+function foo(p, o, v) {
+    if (p)
+        o.f = v;
+}
+
+function bar() {
+    return o.f;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 10; ++i)
+    foo(false);
+
+for (var i = 0; i &lt; 10; ++i)
+    foo(true, {}, 42);
+
+for (var i = 0; i &lt; 10; ++i)
+    foo(true, o, 42);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = bar();
+    if (result != 42)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+foo(true, o, 53);
+var result = bar();
+if (result != 53)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressjitcachereplacethencachegetandfoldtheninvalidatejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+var o = {f:42};
+
+function foo(p, v) {
+    if (p)
+        o.f = v;
+}
+
+function bar() {
+    return o.f;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 10; ++i)
+    foo(false);
+
+for (var i = 0; i &lt; 10; ++i)
+    foo(true, 42);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = bar();
+    if (result != 42)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+foo(true, 53);
+var result = bar();
+if (result != 53)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressjitputtoscopeglobalcachewatchpointinvalidatejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function foo(p, v) {
+    if (p)
+        global = v;
+}
+
+function bar() {
+    return global;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 10; ++i)
+    foo(false);
+
+var value = 42;
+foo(true, value);
+var n = 100000;
+var m = 100;
+for (var i = 0; i &lt; n; ++i) {
+    if (i == n - m)
+        foo(true, value = 53);
+    var result = bar();
+    if (result != value)
+        throw &quot;Error: on iteration &quot; + i + &quot; got: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressllintcachereplacethencachegetandfoldtheninvalidatejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+var o = {f:42};
+
+function foo(v) {
+    o.f = v;
+}
+
+function bar() {
+    return o.f;
+}
+
+noInline(foo);
+noInline(bar);
+
+foo(42);
+foo(42);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = bar();
+    if (result != 42)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+foo(53);
+var result = bar();
+if (result != 53)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressllintputtoscopeglobalcachewatchpointinvalidatejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+function foo(v) {
+    global = v;
+}
+
+function bar() {
+    return global;
+}
+
+noInline(foo);
+noInline(bar);
+
+var value = 42;
+foo(value);
+var n = 100000;
+var m = 100;
+for (var i = 0; i &lt; n; ++i) {
+    if (i == n - m)
+        foo(value = 53);
+    var result = bar();
+    if (result != value)
+        throw &quot;Error: on iteration &quot; + i + &quot; got: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolychainsetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/poly-chain-setter.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/poly-chain-setter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/poly-chain-setter.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+function Cons() {
+}
+Cons.prototype.__defineSetter__(&quot;f&quot;, function(value) {
+    counter++;
+    this._f = value;
+});
+Cons.prototype.__defineGetter__(&quot;f&quot;, function() { return this._f; });
+
+function foo(o, v) {
+    o.f = v;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error(&quot;Bad result: &quot; + result);
+    if (counter != expectedCount)
+        throw new Error(&quot;Bad counter value: &quot; + counter);
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    test(new Cons(), i, counter + 1);
+    
+    var o = new Cons();
+    o.g = 54;
+    test(o, i, counter + 1);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolychainthensetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/poly-chain-then-setter.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/poly-chain-then-setter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/poly-chain-then-setter.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+}
+Cons2.prototype.__defineSetter__(&quot;f&quot;, function(value) {
+    counter++;
+    this._f = value;
+});
+Cons2.prototype.__defineGetter__(&quot;f&quot;, function() { return this._f; });
+
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error(&quot;Bad result: &quot; + result);
+    if (counter != expectedCount)
+        throw new Error(&quot;Bad counter value: &quot; + counter);
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    test(new Cons1(), i, counter);
+    test(new Cons2(), i, counter + 1);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolysettercombojs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/poly-setter-combo.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/poly-setter-combo.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/poly-setter-combo.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+}
+Cons2.prototype.__defineSetter__(&quot;f&quot;, function(value) {
+    counter++;
+    this._f = value;
+});
+Cons2.prototype.__defineGetter__(&quot;f&quot;, function() { return this._f; });
+
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error(&quot;Bad result: &quot; + result);
+    if (counter != expectedCount)
+        throw new Error(&quot;Bad counter value: &quot; + counter);
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    test(new Cons1(), i, counter);
+    test(new Cons2(), i, counter + 1);
+    
+    var o = {};
+    o.__defineSetter__(&quot;f&quot;, function(value) {
+        this._f = value;
+        counter++;
+    });
+    o.__defineGetter__(&quot;f&quot;, function() { return this._f; });
+    test(o, i, counter + 1);
+
+    test({f: 42}, i, counter);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolysetterthenselfjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/poly-setter-then-self.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/poly-setter-then-self.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/poly-setter-then-self.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error(&quot;Bad result: &quot; + result);
+    if (counter != expectedCount)
+        throw new Error(&quot;Bad counter value: &quot; + counter);
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var o = {};
+    o.__defineSetter__(&quot;f&quot;, function(value) {
+        counter++;
+        this._f = value;
+    });
+    o.__defineGetter__(&quot;f&quot;, function() { return this._f; });
+    test(o, i, counter + 1);
+
+    test({f: 42}, i, counter);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressrepeatputtoscopeglobalwithsamevaluewatchpointinvalidatejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+function foo(v) {
+    global = v;
+}
+
+function bar() {
+    return global;
+}
+
+noInline(foo);
+noInline(bar);
+
+var value = 42;
+for (var i = 0; i &lt; 10; ++i)
+    foo(value);
+var n = 100000;
+var m = 100;
+for (var i = 0; i &lt; n; ++i) {
+    if (i == n - m)
+        foo(value = 53);
+    var result = bar();
+    if (result != value)
+        throw &quot;Error: on iteration &quot; + i + &quot; got: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressweirdsettercountersyntacticjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter-syntactic.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter-syntactic.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter-syntactic.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error(&quot;Bad result: &quot; + result);
+    if (counter != expectedCount)
+        throw new Error(&quot;Bad counter value: &quot; + counter);
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var o = {
+        get f() {
+            return this._f;
+        },
+        set f(value) {
+            counter++;
+            this._f = value;
+        }
+    };
+    test(o, i, counter + 1);
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressweirdsettercounterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter.js (0 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/weird-setter-counter.js        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error(&quot;Bad result: &quot; + result);
+    if (counter != expectedCount)
+        throw new Error(&quot;Bad counter value: &quot; + counter);
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var o = {};
+    o.__defineSetter__(&quot;f&quot;, function(value) {
+        counter++;
+        this._f = value;
+    });
+    o.__defineGetter__(&quot;f&quot;, function() { return this._f; });
+    test(o, i, counter + 1);
+}
</ins></span></pre></div>
<a id="trunkSourceWTFwtfPrintStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/PrintStream.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PrintStream.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/WTF/wtf/PrintStream.h        2014-08-06 05:27:46 UTC (rev 172129)
</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">@@ -34,6 +34,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><ins>+class AtomicStringImpl;
</ins><span class="cx"> class CString;
</span><span class="cx"> class String;
</span><span class="cx"> class StringImpl;
</span><span class="lines">@@ -69,10 +70,12 @@
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&amp;, const CString&amp;);
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&amp;, const String&amp;);
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&amp;, const StringImpl*);
</span><ins>+inline void printInternal(PrintStream&amp; out, const AtomicStringImpl* value) { printInternal(out, bitwise_cast&lt;const StringImpl*&gt;(value)); }
</ins><span class="cx"> inline void printInternal(PrintStream&amp; out, char* value) { printInternal(out, static_cast&lt;const char*&gt;(value)); }
</span><span class="cx"> inline void printInternal(PrintStream&amp; out, CString&amp; value) { printInternal(out, static_cast&lt;const CString&amp;&gt;(value)); }
</span><span class="cx"> inline void printInternal(PrintStream&amp; out, String&amp; value) { printInternal(out, static_cast&lt;const String&amp;&gt;(value)); }
</span><span class="cx"> inline void printInternal(PrintStream&amp; out, StringImpl* value) { printInternal(out, static_cast&lt;const StringImpl*&gt;(value)); }
</span><ins>+inline void printInternal(PrintStream&amp; out, AtomicStringImpl* value) { printInternal(out, static_cast&lt;const AtomicStringImpl*&gt;(value)); }
</ins><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&amp;, bool);
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&amp;, signed char); // NOTE: this prints as a number, not as a character; use CharacterDump if you want the character
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&amp;, unsigned char); // NOTE: see above.
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/WebCore/ChangeLog        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2014-07-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Merge r170564, r170571, r170604, r170628, r170672, r170680, r170724, r170728, r170729, r170819, r170821, r170836, r170855, r170860, r170890, r170907, r170929, r171052, r171106, r171152, r171153, r171214 from ftlopt.
+
+    2014-07-01  Mark Lam  &lt;mark.lam@apple.com&gt;
+    
+            [ftlopt] DebuggerCallFrame::scope() should return a DebuggerScope.
+            &lt;https://webkit.org/b/134420&gt;
+    
+            Reviewed by Geoffrey Garen.
+    
+            No new tests.
+    
+            * ForwardingHeaders/debugger/DebuggerCallFrame.h: Removed.
+            - This is not in use.  Hence, we can remove it.
+            * bindings/js/ScriptController.cpp:
+            (WebCore::ScriptController::attachDebugger):
+            - We should acquire the JSLock before modifying a JS global object.
+    
+    2014-06-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
+            https://bugs.webkit.org/show_bug.cgi?id=134333
+    
+            Reviewed by Geoffrey Garen.
+    
+            No new tests because no change in behavior.
+    
+            * bindings/scripts/CodeGeneratorJS.pm:
+            (GenerateHeader):
+    
</ins><span class="cx"> 2014-08-05  Ryuan Choi  &lt;ryuan.choi@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Build break since r172093
</span></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersdebuggerDebuggerCallFrameh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/ForwardingHeaders/debugger/DebuggerCallFrame.h (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/debugger/DebuggerCallFrame.h        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/WebCore/ForwardingHeaders/debugger/DebuggerCallFrame.h        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,4 +0,0 @@
</span><del>-#ifndef WebCore_FWD_DebuggerCallFrame_h
-#define WebCore_FWD_DebuggerCallFrame_h
-#include &lt;JavaScriptCore/DebuggerCallFrame.h&gt;
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMWindowBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -282,7 +282,7 @@
</span><span class="cx">         if (!wrapper)
</span><span class="cx">             continue;
</span><span class="cx">         JSDOMWindowBase* jsWindow = JSC::jsCast&lt;JSDOMWindowBase*&gt;(wrapper);
</span><del>-        jsWindow-&gt;m_windowCloseWatchpoints.fireAll();
</del><ins>+        jsWindow-&gt;m_windowCloseWatchpoints.fireAll(&quot;Frame cleared&quot;);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsScriptControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/ScriptController.cpp        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -307,6 +307,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     JSDOMWindow* globalObject = shell-&gt;window();
</span><ins>+    JSLockHolder lock(globalObject-&gt;vm());
</ins><span class="cx">     if (debugger)
</span><span class="cx">         debugger-&gt;attach(globalObject);
</span><span class="cx">     else if (JSC::Debugger* currentDebugger = globalObject-&gt;debugger())
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -849,7 +849,7 @@
</span><span class="cx">         AddIncludesForTypeInHeader($implType) unless $svgPropertyOrListPropertyType;
</span><span class="cx">         push(@headerContent, &quot;    static $className* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, PassRefPtr&lt;$implType&gt; impl)\n&quot;);
</span><span class="cx">         push(@headerContent, &quot;    {\n&quot;);
</span><del>-        push(@headerContent, &quot;        globalObject-&gt;masqueradesAsUndefinedWatchpoint()-&gt;fireAll();\n&quot;);
</del><ins>+        push(@headerContent, &quot;        globalObject-&gt;masqueradesAsUndefinedWatchpoint()-&gt;fireAll(\&quot;Allocated masquerading object\&quot;);\n&quot;);
</ins><span class="cx">         push(@headerContent, &quot;        $className* ptr = new (NotNull, JSC::allocateCell&lt;$className&gt;(globalObject-&gt;vm().heap)) $className(structure, globalObject, impl);\n&quot;);
</span><span class="cx">         push(@headerContent, &quot;        ptr-&gt;finishCreation(globalObject-&gt;vm());\n&quot;);
</span><span class="cx">         push(@headerContent, &quot;        return ptr;\n&quot;);
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Tools/ChangeLog        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-07-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Merge r170564, r170571, r170604, r170628, r170672, r170680, r170724, r170728, r170729, r170819, r170821, r170836, r170855, r170860, r170890, r170907, r170929, r171052, r171106, r171152, r171153, r171214 from ftlopt.
+
+    2014-06-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+    
+            [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
+            https://bugs.webkit.org/show_bug.cgi?id=134333
+    
+            Reviewed by Geoffrey Garen.
+    
+            * Scripts/display-profiler-output:
+    
</ins><span class="cx"> 2014-08-05  David Farler  &lt;dfarler@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Run ImageDiff in the sim bootstrap
</span></span></pre></div>
<a id="trunkToolsScriptsdisplayprofileroutput"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/display-profiler-output (172128 => 172129)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/display-profiler-output        2014-08-06 05:20:33 UTC (rev 172128)
+++ trunk/Tools/Scripts/display-profiler-output        2014-08-06 05:27:46 UTC (rev 172129)
</span><span class="lines">@@ -331,7 +331,7 @@
</span><span class="cx"> class Compilation
</span><span class="cx">     attr_accessor :bytecode, :engine, :descriptions, :counters, :compilationIndex
</span><span class="cx">     attr_accessor :osrExits, :profiledBytecodes, :numInlinedGetByIds, :numInlinedPutByIds
</span><del>-    attr_accessor :numInlinedCalls, :jettisonReason
</del><ins>+    attr_accessor :numInlinedCalls, :jettisonReason, :additionalJettisonReason
</ins><span class="cx">     
</span><span class="cx">     def initialize(json)
</span><span class="cx">         @bytecode = $bytecodes[json[&quot;bytecodesID&quot;].to_i]
</span><span class="lines">@@ -385,6 +385,7 @@
</span><span class="cx">         @numInlinedPutByIds = json[&quot;numInlinedPutByIds&quot;]
</span><span class="cx">         @numInlinedCalls = json[&quot;numInlinedCalls&quot;]
</span><span class="cx">         @jettisonReason = json[&quot;jettisonReason&quot;]
</span><ins>+        @additionalJettisonReason = json[&quot;additionalJettisonReason&quot;]
</ins><span class="cx">     end
</span><span class="cx">     
</span><span class="cx">     def codeHashSortKey
</span><span class="lines">@@ -858,6 +859,9 @@
</span><span class="cx">             }
</span><span class="cx">             if compilation.jettisonReason != &quot;NotJettisoned&quot;
</span><span class="cx">                 puts &quot;    Jettisoned due to #{compilation.jettisonReason}&quot;
</span><ins>+                if compilation.additionalJettisonReason
+                    puts &quot;        #{compilation.additionalJettisonReason}&quot;
+                end
</ins><span class="cx">             end
</span><span class="cx">         }
</span><span class="cx">     when &quot;inlines&quot;
</span></span></pre>
</div>
</div>

</body>
</html>