<!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>[211279] branches/safari-603-branch/Source</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/211279">211279</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-01-27 01:19:06 -0800 (Fri, 27 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/211237">r211237</a>. rdar://problem/30179506</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchSourceJavaScriptCoreCMakeListstxt">branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreChangeLog">branches/safari-603-branch/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorebytecodeCodeBlockcpp">branches/safari-603-branch/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorebytecodeStructureSetcpp">branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorebytecodeStructureSeth">branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGAbstractInterpreterh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGAbstractValuecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGAbstractValueh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGArrayModecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGArrayifySlowPathGeneratorh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGByteCodeParsercpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGCallArrayAllocatorSlowPathGeneratorh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGCallCreateDirectArgumentsSlowPathGeneratorh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGCommonDatacpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCommonData.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGDesiredWeakReferencescpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGFixupPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGGraphcpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGGraphh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGJITCompilerh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGJITCompiler.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGMultiGetByOffsetDatacpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGMultiGetByOffsetDatah">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGNodecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGNodeh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGOpInfoh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOpInfo.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGPlancpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSafeToExecuteh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJITcpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJITh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGStructureAbstractValuecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGStructureAbstractValueh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGTransitioncpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGTransitionh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGValidatecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreftlFTLOutputh">branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
<li><a href="#branchessafari603branchSourceWTFChangeLog">branches/safari-603-branch/Source/WTF/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWTFwtfTinyPtrSeth">branches/safari-603-branch/Source/WTF/wtf/TinyPtrSet.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGRegisteredStructureh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGRegisteredStructureSetcpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGRegisteredStructureSeth">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGStructureRegistrationPhaseh">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -373,6 +373,7 @@
</span><span class="cx">     dfg/DFGPromotedHeapLocation.cpp
</span><span class="cx">     dfg/DFGPureValue.cpp
</span><span class="cx">     dfg/DFGPutStackSinkingPhase.cpp
</span><ins>+    dfg/DFGRegisteredStructureSet.cpp
</ins><span class="cx">     dfg/DFGSSACalculator.cpp
</span><span class="cx">     dfg/DFGSSAConversionPhase.cpp
</span><span class="cx">     dfg/DFGSSALoweringPhase.cpp
</span><span class="lines">@@ -386,7 +387,6 @@
</span><span class="cx">     dfg/DFGStoreBarrierInsertionPhase.cpp
</span><span class="cx">     dfg/DFGStrengthReductionPhase.cpp
</span><span class="cx">     dfg/DFGStructureAbstractValue.cpp
</span><del>-    dfg/DFGStructureRegistrationPhase.cpp
</del><span class="cx">     dfg/DFGThreadData.cpp
</span><span class="cx">     dfg/DFGThunks.cpp
</span><span class="cx">     dfg/DFGTierUpCheckInjectionPhase.cpp
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ChangeLog (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -1,5 +1,290 @@
</span><span class="cx"> 2017-01-27  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r211237. rdar://problem/30179506
+
+    2017-01-26  Saam Barati  &lt;sbarati@apple.com&gt;
+
+            Harden how the compiler references GC objects
+            https://bugs.webkit.org/show_bug.cgi?id=167277
+            &lt;rdar://problem/30179506&gt;
+
+            Reviewed by Filip Pizlo.
+
+            Since r210971, the DFG/FTL will flash safepoints before
+            each phase. This means that there are more opportunities for
+            a GC to happen while the compiler is running. Because of this,
+            the compiler must keep track of all the heap pointers that are part
+            of the Graph data structure. To accomplish this, I've designed
+            a new type called RegisteredStructure that can only be constructed
+            after the Graph becomes aware of its underlying Structure*. I
+            designed this new type to have the type system in C++ help us catch
+            errors where we're not informing the graph/plan of a heap pointer.
+            I've made it a compile error to create an OpInfo with a pointer
+            T* where T inherits from HeapCell. This encourages an OpInfo
+            to be created with either a FrozenValue* or a RegisteredStructure.
+            I've added similar compile time assertions for TrustedImmPtr in DFG::SpeculativeJIT
+            and FTL::Output::constIntPtr. These static asserts don't save us from all bad
+            programs because there are ways to write code that's incorrect that compiles,
+            but the new types do help us ensure that the most obvious way of writing the
+            code is correct.
+
+            The reason this patch is so big is that I've strung RegisteredStructure and
+            RegisteredStructureSet through the entire DFG/FTL.
+
+            * CMakeLists.txt:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::determineLiveness):
+            * bytecode/StructureSet.cpp:
+            (JSC::StructureSet::filter): Deleted.
+            (JSC::StructureSet::filterArrayModes): Deleted.
+            (JSC::StructureSet::speculationFromStructures): Deleted.
+            (JSC::StructureSet::arrayModesFromStructures): Deleted.
+            (JSC::StructureSet::validateReferences): Deleted.
+            * bytecode/StructureSet.h:
+            * dfg/DFGAbstractInterpreter.h:
+            (JSC::DFG::AbstractInterpreter::filter):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::booleanResult):
+            (JSC::DFG::isToThisAnIdentity):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::observeTransition):
+            (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::filter):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::set):
+            (JSC::DFG::AbstractValue::setType):
+            (JSC::DFG::AbstractValue::mergeOSREntryValue):
+            (JSC::DFG::AbstractValue::filter):
+            (JSC::DFG::AbstractValue::changeStructure):
+            (JSC::DFG::AbstractValue::contains):
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::observeTransition):
+            (JSC::DFG::AbstractValue::TransitionObserver::TransitionObserver):
+            * dfg/DFGArgumentsEliminationPhase.cpp:
+            * dfg/DFGArrayMode.cpp:
+            (JSC::DFG::ArrayMode::alreadyChecked):
+            * dfg/DFGArrayifySlowPathGenerator.h:
+            (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+            (JSC::DFG::ByteCodeParser::load):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+            * dfg/DFGCallArrayAllocatorSlowPathGenerator.h:
+            (JSC::DFG::CallArrayAllocatorSlowPathGenerator::CallArrayAllocatorSlowPathGenerator):
+            (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableSizeSlowPathGenerator):
+            * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h:
+            (JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator):
+            * dfg/DFGCommonData.cpp:
+            (JSC::DFG::CommonData::notifyCompilingStructureTransition):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addBaseCheck):
+            (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+            * dfg/DFGDesiredWeakReferences.cpp:
+            (JSC::DFG::DesiredWeakReferences::reallyAdd):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::checkArray):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::Graph):
+            (JSC::DFG::Graph::dump):
+            (JSC::DFG::Graph::tryGetConstantProperty):
+            (JSC::DFG::Graph::inferredValueForProperty):
+            (JSC::DFG::Graph::visitChildren):
+            (JSC::DFG::Graph::freeze):
+            (JSC::DFG::Graph::registerStructure):
+            (JSC::DFG::Graph::assertIsRegistered):
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::registerStructure):
+            (JSC::DFG::Graph::addStructureSet):
+            * dfg/DFGJITCompiler.h:
+            (JSC::DFG::JITCompiler::branchWeakStructure):
+            * dfg/DFGMultiGetByOffsetData.cpp:
+            (JSC::DFG::MultiGetByOffsetCase::dumpInContext):
+            * dfg/DFGMultiGetByOffsetData.h:
+            (JSC::DFG::MultiGetByOffsetCase::MultiGetByOffsetCase):
+            (JSC::DFG::MultiGetByOffsetCase::set):
+            * dfg/DFGNode.cpp:
+            (JSC::DFG::Node::convertToPutStructureHint):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToCheckStructure):
+            (JSC::DFG::Node::structureSet):
+            (JSC::DFG::Node::structure):
+            (JSC::DFG::Node::OpInfoWrapper::OpInfoWrapper):
+            (JSC::DFG::Node::OpInfoWrapper::operator=):
+            (JSC::DFG::Node::OpInfoWrapper::asRegisteredStructure):
+            * dfg/DFGObjectAllocationSinkingPhase.cpp:
+            * dfg/DFGOpInfo.h:
+            (JSC::DFG::OpInfo::OpInfo):
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
+            * dfg/DFGRegisteredStructure.h: Added.
+            (JSC::DFG::RegisteredStructure::get):
+            (JSC::DFG::RegisteredStructure::operator-&gt;):
+            (JSC::DFG::RegisteredStructure::operator==):
+            (JSC::DFG::RegisteredStructure::operator!=):
+            (JSC::DFG::RegisteredStructure::operator bool):
+            (JSC::DFG::RegisteredStructure::RegisteredStructure):
+            (JSC::DFG::RegisteredStructure::createPrivate):
+            * dfg/DFGRegisteredStructureSet.cpp: Added.
+            (JSC::DFG::RegisteredStructureSet::filter):
+            (JSC::DFG::RegisteredStructureSet::filterArrayModes):
+            (JSC::DFG::RegisteredStructureSet::speculationFromStructures):
+            (JSC::DFG::RegisteredStructureSet::arrayModesFromStructures):
+            (JSC::DFG::RegisteredStructureSet::validateReferences):
+            * dfg/DFGRegisteredStructureSet.h: Added.
+            (JSC::DFG::RegisteredStructureSet::RegisteredStructureSet):
+            (JSC::DFG::RegisteredStructureSet::onlyStructure):
+            (JSC::DFG::RegisteredStructureSet::toStructureSet):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
+            (JSC::DFG::SpeculativeJIT::emitGetCallee):
+            (JSC::DFG::SpeculativeJIT::silentFill):
+            (JSC::DFG::SpeculativeJIT::checkArray):
+            (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+            (JSC::DFG::SpeculativeJIT::compileFromCharCode):
+            (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+            (JSC::DFG::compileClampDoubleToByte):
+            (JSC::DFG::SpeculativeJIT::compileMakeRope):
+            (JSC::DFG::SpeculativeJIT::compileArithRounding):
+            (JSC::DFG::SpeculativeJIT::compileNewFunctionCommon):
+            (JSC::DFG::SpeculativeJIT::compileNewFunction):
+            (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+            (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
+            (JSC::DFG::SpeculativeJIT::compileCreateScopedArguments):
+            (JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
+            (JSC::DFG::SpeculativeJIT::compileSpread):
+            (JSC::DFG::SpeculativeJIT::compileArraySlice):
+            (JSC::DFG::SpeculativeJIT::compileTypeOf):
+            (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+            (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+            (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell):
+            (JSC::DFG::SpeculativeJIT::compileNewTypedArray):
+            (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
+            (JSC::DFG::SpeculativeJIT::compileMaterializeNewObject):
+            * dfg/DFGSpeculativeJIT.h:
+            (JSC::DFG::SpeculativeJIT::TrustedImmPtr::TrustedImmPtr):
+            (JSC::DFG::SpeculativeJIT::TrustedImmPtr::weakPointer):
+            (JSC::DFG::SpeculativeJIT::TrustedImmPtr::operator MacroAssembler::TrustedImmPtr):
+            (JSC::DFG::SpeculativeJIT::TrustedImmPtr::asIntptr):
+            (JSC::DFG::SpeculativeJIT::callOperation):
+            (JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject):
+            (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined):
+            (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined):
+            (JSC::DFG::SpeculativeJIT::emitCall):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+            (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+            (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+            (JSC::DFG::SpeculativeJIT::compile):
+            (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined):
+            (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined):
+            (JSC::DFG::SpeculativeJIT::emitCall):
+            (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+            (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+            (JSC::DFG::SpeculativeJIT::compile):
+            (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize):
+            * dfg/DFGStrengthReductionPhase.cpp:
+            (JSC::DFG::StrengthReductionPhase::handleNode):
+            * dfg/DFGStructureAbstractValue.cpp:
+            (JSC::DFG::StructureAbstractValue::assertIsRegistered):
+            (JSC::DFG::StructureAbstractValue::clobber):
+            (JSC::DFG::StructureAbstractValue::observeTransition):
+            (JSC::DFG::StructureAbstractValue::observeTransitions):
+            (JSC::DFG::StructureAbstractValue::add):
+            (JSC::DFG::StructureAbstractValue::merge):
+            (JSC::DFG::StructureAbstractValue::mergeNotTop):
+            (JSC::DFG::StructureAbstractValue::filter):
+            (JSC::DFG::StructureAbstractValue::filterSlow):
+            (JSC::DFG::StructureAbstractValue::filterClassInfoSlow):
+            (JSC::DFG::StructureAbstractValue::contains):
+            (JSC::DFG::StructureAbstractValue::isSubsetOf):
+            (JSC::DFG::StructureAbstractValue::isSupersetOf):
+            (JSC::DFG::StructureAbstractValue::overlaps):
+            (JSC::DFG::StructureAbstractValue::isSubClassOf):
+            (JSC::DFG::StructureAbstractValue::dumpInContext):
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::StructureAbstractValue):
+            (JSC::DFG::StructureAbstractValue::operator=):
+            (JSC::DFG::StructureAbstractValue::set):
+            (JSC::DFG::StructureAbstractValue::toStructureSet):
+            (JSC::DFG::StructureAbstractValue::at):
+            (JSC::DFG::StructureAbstractValue::operator[]):
+            (JSC::DFG::StructureAbstractValue::onlyStructure):
+            * dfg/DFGStructureRegistrationPhase.cpp:
+            (JSC::DFG::StructureRegistrationPhase::StructureRegistrationPhase): Deleted.
+            (JSC::DFG::StructureRegistrationPhase::run): Deleted.
+            (JSC::DFG::StructureRegistrationPhase::registerStructures): Deleted.
+            (JSC::DFG::StructureRegistrationPhase::registerStructure): Deleted.
+            (JSC::DFG::StructureRegistrationPhase::assertAreRegistered): Deleted.
+            (JSC::DFG::StructureRegistrationPhase::assertIsRegistered): Deleted.
+            (JSC::DFG::performStructureRegistration): Deleted.
+            * dfg/DFGStructureRegistrationPhase.h:
+            * dfg/DFGTransition.cpp:
+            (JSC::DFG::Transition::dumpInContext):
+            * dfg/DFGTransition.h:
+            (JSC::DFG::Transition::Transition):
+            * dfg/DFGTypeCheckHoistingPhase.cpp:
+            (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck):
+            (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheckAccountingForArrayMode):
+            * dfg/DFGValidate.cpp:
+            * ftl/FTLLowerDFGToB3.cpp:
+            (JSC::FTL::DFG::LowerDFGToB3::lower):
+            (JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor):
+            (JSC::FTL::DFG::LowerDFGToB3::compileCheckStructure):
+            (JSC::FTL::DFG::LowerDFGToB3::compilePutStructure):
+            (JSC::FTL::DFG::LowerDFGToB3::compileArraySlice):
+            (JSC::FTL::DFG::LowerDFGToB3::compileCreateActivation):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction):
+            (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments):
+            (JSC::FTL::DFG::LowerDFGToB3::compileCreateRest):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewArray):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayBuffer):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
+            (JSC::FTL::DFG::LowerDFGToB3::compileAllocatePropertyStorage):
+            (JSC::FTL::DFG::LowerDFGToB3::compileReallocatePropertyStorage):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMultiGetByOffset):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset):
+            (JSC::FTL::DFG::LowerDFGToB3::compileGetMapBucket):
+            (JSC::FTL::DFG::LowerDFGToB3::compileOverridesHasInstance):
+            (JSC::FTL::DFG::LowerDFGToB3::compileCheckStructureImmediate):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeCreateActivation):
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
+            (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenTail):
+            (JSC::FTL::DFG::LowerDFGToB3::checkStructure):
+            (JSC::FTL::DFG::LowerDFGToB3::checkInferredType):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateObject):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateUninitializedContiguousJSArray):
+            (JSC::FTL::DFG::LowerDFGToB3::boolify):
+            (JSC::FTL::DFG::LowerDFGToB3::equalNullOrUndefined):
+            (JSC::FTL::DFG::LowerDFGToB3::lowCell):
+            (JSC::FTL::DFG::LowerDFGToB3::speculateStringObjectForStructureID):
+            (JSC::FTL::DFG::LowerDFGToB3::weakPointer):
+            (JSC::FTL::DFG::LowerDFGToB3::frozenPointer):
+            (JSC::FTL::DFG::LowerDFGToB3::weakStructureID):
+            (JSC::FTL::DFG::LowerDFGToB3::weakStructure):
+            (JSC::FTL::DFG::LowerDFGToB3::crash):
+            * ftl/FTLOutput.h:
+            (JSC::FTL::Output::weakPointer):
+            (JSC::FTL::Output::constIntPtr):
+
+2017-01-27  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r211246. rdar://problem/29916672
</span><span class="cx"> 
</span><span class="cx">     2017-01-26  Mark Lam  &lt;mark.lam@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -518,8 +518,6 @@
</span><span class="cx">                 0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */; };
</span><span class="cx">                 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
</span><del>-                0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */; };
-                0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */; };
</del><span class="cx">                 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; };
</span><span class="cx">                 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F7C39FB1C8F629300480151 /* RegExpInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C39FA1C8F629300480151 /* RegExpInlines.h */; };
</span><span class="lines">@@ -1437,6 +1435,8 @@
</span><span class="cx">                 796FB43A1DFF8C3F0039C95D /* JSWebAssemblyHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 796FB4391DFF8C3F0039C95D /* JSWebAssemblyHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
</span><span class="cx">                 797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                7980C16C1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7980C16A1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp */; };
+                7980C16D1E3A940E00B71615 /* DFGRegisteredStructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 798937781DCAB57300F8D4FB /* JSFixedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */; };
</span><span class="cx">                 798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 798937771DCAB57300F8D4FB /* JSFixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1467,6 +1467,7 @@
</span><span class="cx">                 79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 79F8FC1E1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */; };
</span><span class="cx">                 79F8FC1F1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 79F8FC1D1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h */; };
</span><ins>+                79FC8A081E32E9F000D88F0E /* DFGRegisteredStructure.h in Headers */ = {isa = PBXBuildFile; fileRef = 79FC8A071E32E9F000D88F0E /* DFGRegisteredStructure.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 7BC547D31B6959A100959B58 /* WasmFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC547D21B69599B00959B58 /* WasmFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
</span><span class="cx">                 7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2960,8 +2961,6 @@
</span><span class="cx">                 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubClearingWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureRegistrationPhase.cpp; path = dfg/DFGStructureRegistrationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureRegistrationPhase.h; path = dfg/DFGStructureRegistrationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F7C39FA1C8F629300480151 /* RegExpInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7C39FC1C8F659500480151 /* RegExpObjectInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObjectInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7C39FE1C90C55B00480151 /* DFGOpInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOpInfo.h; path = dfg/DFGOpInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3890,6 +3889,8 @@
</span><span class="cx">                 796FB4391DFF8C3F0039C95D /* JSWebAssemblyHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyHelpers.h; path = js/JSWebAssemblyHelpers.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7980C16A1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGRegisteredStructureSet.cpp; path = dfg/DFGRegisteredStructureSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisteredStructureSet.h; path = dfg/DFGRegisteredStructureSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 798937771DCAB57300F8D4FB /* JSFixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFixedArray.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3PCToOriginMap.h; path = b3/B3PCToOriginMap.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3920,6 +3921,7 @@
</span><span class="cx">                 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableEnvironment.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMaximalFlushInsertionPhase.cpp; path = dfg/DFGMaximalFlushInsertionPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79F8FC1D1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMaximalFlushInsertionPhase.h; path = dfg/DFGMaximalFlushInsertionPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                79FC8A071E32E9F000D88F0E /* DFGRegisteredStructure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisteredStructure.h; path = dfg/DFGRegisteredStructure.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7BC547D21B69599B00959B58 /* WasmFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmFormat.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseDeferred.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7051,6 +7053,9 @@
</span><span class="cx">                                 0FB1765F196B8F9E0091052A /* DFGPureValue.h */,
</span><span class="cx">                                 0F3A1BF71A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp */,
</span><span class="cx">                                 0F3A1BF81A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h */,
</span><ins>+                                79FC8A071E32E9F000D88F0E /* DFGRegisteredStructure.h */,
+                                7980C16A1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp */,
+                                7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */,
</ins><span class="cx">                                 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
</span><span class="cx">                                 0F2FCCF418A60070001A27F8 /* DFGSafepoint.cpp */,
</span><span class="cx">                                 0F2FCCF518A60070001A27F8 /* DFGSafepoint.h */,
</span><span class="lines">@@ -7083,8 +7088,6 @@
</span><span class="cx">                                 0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */,
</span><span class="cx">                                 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */,
</span><span class="cx">                                 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */,
</span><del>-                                0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */,
-                                0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */,
</del><span class="cx">                                 0F2FCCF718A60070001A27F8 /* DFGThreadData.cpp */,
</span><span class="cx">                                 0F2FCCF818A60070001A27F8 /* DFGThreadData.h */,
</span><span class="cx">                                 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
</span><span class="lines">@@ -8031,6 +8034,7 @@
</span><span class="cx">                                 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
</span><span class="cx">                                 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
</span><span class="cx">                                 0FA762051DB9242900B7A2FD /* CollectionScope.h in Headers */,
</span><ins>+                                79FC8A081E32E9F000D88F0E /* DFGRegisteredStructure.h in Headers */,
</ins><span class="cx">                                 A53243981856A489002ED692 /* CombinedDomains.json in Headers */,
</span><span class="cx">                                 BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
</span><span class="cx">                                 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
</span><span class="lines">@@ -8244,7 +8248,6 @@
</span><span class="cx">                                 0FC20CB61852E2C600C9E954 /* DFGStrengthReductionPhase.h in Headers */,
</span><span class="cx">                                 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */,
</span><span class="cx">                                 0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */,
</span><del>-                                0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */,
</del><span class="cx">                                 0F2FCCFF18A60070001A27F8 /* DFGThreadData.h in Headers */,
</span><span class="cx">                                 0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
</span><span class="cx">                                 0FD8A32817D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.h in Headers */,
</span><span class="lines">@@ -8631,6 +8634,7 @@
</span><span class="cx">                                 A50E4B6418809DD50068A46D /* JSGlobalObjectRuntimeAgent.h in Headers */,
</span><span class="cx">                                 A503FA2A188F105900110F14 /* JSGlobalObjectScriptDebugServer.h in Headers */,
</span><span class="cx">                                 A513E5C0185BFACC007E95AD /* JSInjectedScriptHost.h in Headers */,
</span><ins>+                                7980C16D1E3A940E00B71615 /* DFGRegisteredStructureSet.h in Headers */,
</ins><span class="cx">                                 A513E5C2185BFACC007E95AD /* JSInjectedScriptHostPrototype.h in Headers */,
</span><span class="cx">                                 C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
</span><span class="cx">                                 0F2B66F817B6B5AB00A7AE3F /* JSInt16Array.h in Headers */,
</span><span class="lines">@@ -9943,7 +9947,6 @@
</span><span class="cx">                                 0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */,
</span><span class="cx">                                 0F7DF13B1E2971110095951B /* JSDestructibleObjectSubspace.cpp in Sources */,
</span><span class="cx">                                 0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */,
</span><del>-                                0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */,
</del><span class="cx">                                 0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */,
</span><span class="cx">                                 0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
</span><span class="cx">                                 0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
</span><span class="lines">@@ -9985,6 +9988,7 @@
</span><span class="cx">                                 14AD91171DCA97FD0014F9FE /* EvalCodeBlock.cpp in Sources */,
</span><span class="cx">                                 147341E21DC2CE9600AA29BA /* EvalExecutable.cpp in Sources */,
</span><span class="cx">                                 A54982031891D0B00081E5B8 /* EventLoop.cpp in Sources */,
</span><ins>+                                7980C16C1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp in Sources */,
</ins><span class="cx">                                 FE1C0FFF1B194FD100B53FCA /* Exception.cpp in Sources */,
</span><span class="cx">                                 FE80C19B1D776A98008510C0 /* ExceptionEventLocation.cpp in Sources */,
</span><span class="cx">                                 0F12DE0F1979D5FD0006FF4E /* ExceptionFuzz.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/bytecode/CodeBlock.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -2725,6 +2725,7 @@
</span><span class="cx">     // GC we still have not proved liveness, then this code block is toast.
</span><span class="cx">     bool allAreLiveSoFar = true;
</span><span class="cx">     for (unsigned i = 0; i &lt; dfgCommon-&gt;weakReferences.size(); ++i) {
</span><ins>+        ASSERT(!jsDynamicCast&lt;CodeBlock*&gt;(dfgCommon-&gt;weakReferences[i].get()));
</ins><span class="cx">         if (!Heap::isMarkedConcurrently(dfgCommon-&gt;weakReferences[i].get())) {
</span><span class="cx">             allAreLiveSoFar = false;
</span><span class="cx">             break;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorebytecodeStructureSetcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -26,64 +26,11 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;StructureSet.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;DFGAbstractValue.h&quot;
</del><span class="cx"> #include &quot;TrackedReferences.h&quot;
</span><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-#if ENABLE(DFG_JIT)
-
-void StructureSet::filter(const DFG::StructureAbstractValue&amp; other)
-{
-    genericFilter([&amp;] (Structure* structure) -&gt; bool { return other.contains(structure); });
-}
-
-void StructureSet::filter(SpeculatedType type)
-{
-    genericFilter(
-        [&amp;] (Structure* structure) -&gt; bool {
-            return type &amp; speculationFromStructure(structure);
-        });
-}
-
-void StructureSet::filterArrayModes(ArrayModes arrayModes)
-{
-    genericFilter(
-        [&amp;] (Structure* structure) -&gt; bool {
-            return arrayModes &amp; arrayModeFromStructure(structure);
-        });
-}
-
-void StructureSet::filter(const DFG::AbstractValue&amp; other)
-{
-    filter(other.m_structure);
-    filter(other.m_type);
-    filterArrayModes(other.m_arrayModes);
-}
-
-#endif // ENABLE(DFG_JIT)
-
-SpeculatedType StructureSet::speculationFromStructures() const
-{
-    SpeculatedType result = SpecNone;
-    forEach(
-        [&amp;] (Structure* structure) {
-            mergeSpeculation(result, speculationFromStructure(structure));
-        });
-    return result;
-}
-
-ArrayModes StructureSet::arrayModesFromStructures() const
-{
-    ArrayModes result = 0;
-    forEach(
-        [&amp;] (Structure* structure) {
-            mergeArrayModes(result, asArrayModes(structure-&gt;indexingType()));
-        });
-    return result;
-}
-
</del><span class="cx"> void StructureSet::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><span class="cx">     CommaPrinter comma;
</span><span class="lines">@@ -97,13 +44,5 @@
</span><span class="cx">     dumpInContext(out, nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StructureSet::validateReferences(const TrackedReferences&amp; trackedReferences) const
-{
-    forEach(
-        [&amp;] (Structure* structure) {
-            trackedReferences.check(structure);
-        });
-}
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorebytecodeStructureSeth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -35,11 +35,6 @@
</span><span class="cx"> 
</span><span class="cx"> class TrackedReferences;
</span><span class="cx"> 
</span><del>-namespace DFG {
-class StructureAbstractValue;
-struct AbstractValue;
-}
-
</del><span class="cx"> class StructureSet : public TinyPtrSet&lt;Structure*&gt; {
</span><span class="cx"> public:
</span><span class="cx">     // I really want to do this:
</span><span class="lines">@@ -66,20 +61,8 @@
</span><span class="cx">         return onlyEntry();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-#if ENABLE(DFG_JIT)
-    void filter(const DFG::StructureAbstractValue&amp;);
-    void filter(SpeculatedType);
-    void filterArrayModes(ArrayModes);
-    void filter(const DFG::AbstractValue&amp;);
-#endif // ENABLE(DFG_JIT)
-    
-    SpeculatedType speculationFromStructures() const;
-    ArrayModes arrayModesFromStructures() const;
-    
</del><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><del>-    
-    void validateReferences(const TrackedReferences&amp;) const;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGAbstractInterpreterh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -112,7 +112,7 @@
</span><span class="cx">     void dump(PrintStream&amp; out);
</span><span class="cx">     
</span><span class="cx">     template&lt;typename T&gt;
</span><del>-    FiltrationResult filter(T node, const StructureSet&amp; set, SpeculatedType admittedTypes = SpecNone)
</del><ins>+    FiltrationResult filter(T node, const RegisteredStructureSet&amp; set, SpeculatedType admittedTypes = SpecNone)
</ins><span class="cx">     {
</span><span class="cx">         return filter(forNode(node), set, admittedTypes);
</span><span class="cx">     }
</span><span class="lines">@@ -141,7 +141,7 @@
</span><span class="cx">         return filterClassInfo(forNode(node), classInfo);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    FiltrationResult filter(AbstractValue&amp;, const StructureSet&amp;, SpeculatedType admittedTypes = SpecNone);
</del><ins>+    FiltrationResult filter(AbstractValue&amp;, const RegisteredStructureSet&amp;, SpeculatedType admittedTypes = SpecNone);
</ins><span class="cx">     FiltrationResult filterArrayModes(AbstractValue&amp;, ArrayModes);
</span><span class="cx">     FiltrationResult filter(AbstractValue&amp;, SpeculatedType);
</span><span class="cx">     FiltrationResult filterByValue(AbstractValue&amp;, FrozenValue);
</span><span class="lines">@@ -156,7 +156,7 @@
</span><span class="cx">     void forAllValues(unsigned indexInBlock, Functor&amp;);
</span><span class="cx">     
</span><span class="cx">     void clobberStructures(unsigned indexInBlock);
</span><del>-    void observeTransition(unsigned indexInBlock, Structure* from, Structure* to);
</del><ins>+    void observeTransition(unsigned indexInBlock, RegisteredStructure from, RegisteredStructure to);
</ins><span class="cx">     void observeTransitions(unsigned indexInBlock, const TransitionVector&amp;);
</span><span class="cx">     void setDidClobber();
</span><span class="cx">     
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx">     if (isCellSpeculation(value.m_type) &amp;&amp; !value.m_structure.isTop()) {
</span><span class="cx">         bool allTrue = true;
</span><span class="cx">         for (unsigned i = value.m_structure.size(); i--;) {
</span><del>-            Structure* structure = value.m_structure[i];
</del><ins>+            RegisteredStructure structure = value.m_structure[i];
</ins><span class="cx">             if (structure-&gt;masqueradesAsUndefined(m_codeBlock-&gt;globalObjectFor(node-&gt;origin.semantic))
</span><span class="cx">                 || structure-&gt;typeInfo().type() == StringType) {
</span><span class="cx">                 allTrue = false;
</span><span class="lines">@@ -152,7 +152,7 @@
</span><span class="cx"> 
</span><span class="cx">     if ((isStrictMode || (valueForNode.m_type &amp;&amp; !(valueForNode.m_type &amp; ~SpecObject))) &amp;&amp; valueForNode.m_structure.isFinite()) {
</span><span class="cx">         bool overridesToThis = false;
</span><del>-        valueForNode.m_structure.forEach([&amp;](Structure* structure) {
</del><ins>+        valueForNode.m_structure.forEach([&amp;](RegisteredStructure structure) {
</ins><span class="cx">             TypeInfo type = structure-&gt;typeInfo();
</span><span class="cx">             ASSERT(type.isObject() || type.type() == StringType || type.type() == SymbolType);
</span><span class="cx">             if (!isStrictMode)
</span><span class="lines">@@ -1656,10 +1656,10 @@
</span><span class="cx"> 
</span><span class="cx">         // FIXME: We could do better here if we prove that the
</span><span class="cx">         // incoming value has only a single structure.
</span><del>-        StructureSet structureSet;
-        structureSet.add(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithInt32));
-        structureSet.add(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous));
-        structureSet.add(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithDouble));
</del><ins>+        RegisteredStructureSet structureSet;
+        structureSet.add(m_graph.registerStructure(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithInt32)));
+        structureSet.add(m_graph.registerStructure(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous)));
+        structureSet.add(m_graph.registerStructure(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithDouble)));
</ins><span class="cx"> 
</span><span class="cx">         forNode(node).set(m_graph, structureSet);
</span><span class="cx">         break;
</span><span class="lines">@@ -1856,7 +1856,7 @@
</span><span class="cx">             // structure.
</span><span class="cx">             filter(
</span><span class="cx">                 node-&gt;child1(),
</span><del>-                m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;stringObjectStructure());
</del><ins>+                m_graph.registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;stringObjectStructure()));
</ins><span class="cx">             break;
</span><span class="cx">         case StringOrStringObjectUse:
</span><span class="cx">             break;
</span><span class="lines">@@ -1963,7 +1963,7 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case NewObject:
</span><del>-        ASSERT(node-&gt;structure());
</del><ins>+        ASSERT(!!node-&gt;structure().get());
</ins><span class="cx">         forNode(node).set(m_graph, node-&gt;structure());
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="lines">@@ -2121,7 +2121,7 @@
</span><span class="cx">             JSGlobalObject* globalObject = nullptr;
</span><span class="cx">             bool ok = true;
</span><span class="cx">             forNode(node-&gt;child1()).m_structure.forEach(
</span><del>-                [&amp;] (Structure* structure) {
</del><ins>+                [&amp;] (RegisteredStructure structure) {
</ins><span class="cx">                     if (!globalObject)
</span><span class="cx">                         globalObject = structure-&gt;globalObject();
</span><span class="cx">                     else if (globalObject != structure-&gt;globalObject())
</span><span class="lines">@@ -2184,7 +2184,7 @@
</span><span class="cx">         if (value.m_structure.isFinite()
</span><span class="cx">             &amp;&amp; (node-&gt;child1().useKind() == CellUse || !(value.m_type &amp; ~SpecCell))) {
</span><span class="cx">             UniquedStringImpl* uid = m_graph.identifiers()[node-&gt;identifierNumber()];
</span><del>-            GetByIdStatus status = GetByIdStatus::computeFor(value.m_structure.set(), uid);
</del><ins>+            GetByIdStatus status = GetByIdStatus::computeFor(value.m_structure.toStructureSet(), uid);
</ins><span class="cx">             if (status.isSimple()) {
</span><span class="cx">                 // Figure out what the result is going to be - is it TOP, a constant, or maybe
</span><span class="cx">                 // something more subtle?
</span><span class="lines">@@ -2238,7 +2238,7 @@
</span><span class="cx">     case CheckStructure: {
</span><span class="cx">         AbstractValue&amp; value = forNode(node-&gt;child1());
</span><span class="cx"> 
</span><del>-        StructureSet&amp; set = node-&gt;structureSet();
</del><ins>+        const RegisteredStructureSet&amp; set = node-&gt;structureSet();
</ins><span class="cx">         
</span><span class="cx">         // It's interesting that we could have proven that the object has a larger structure set
</span><span class="cx">         // that includes the set we're testing. In that case we could make the structure check
</span><span class="lines">@@ -2270,11 +2270,11 @@
</span><span class="cx">         // https://bugs.webkit.org/show_bug.cgi?id=136988
</span><span class="cx">         
</span><span class="cx">         AbstractValue&amp; value = forNode(node-&gt;child1());
</span><del>-        StructureSet&amp; set = node-&gt;structureSet();
</del><ins>+        const RegisteredStructureSet&amp; set = node-&gt;structureSet();
</ins><span class="cx">         
</span><span class="cx">         if (value.value()) {
</span><span class="cx">             if (Structure* structure = jsDynamicCast&lt;Structure*&gt;(value.value())) {
</span><del>-                if (set.contains(structure)) {
</del><ins>+                if (set.contains(m_graph.registerStructure(structure))) {
</ins><span class="cx">                     m_state.setFoundConstants(true);
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="lines">@@ -2289,7 +2289,7 @@
</span><span class="cx">                 node,
</span><span class="cx">                 [&amp;] (Node* incoming) {
</span><span class="cx">                     if (Structure* structure = incoming-&gt;dynamicCastConstant&lt;Structure*&gt;()) {
</span><del>-                        if (set.contains(structure))
</del><ins>+                        if (set.contains(m_graph.registerStructure(structure)))
</ins><span class="cx">                             return;
</span><span class="cx">                     }
</span><span class="cx">                     allGood = false;
</span><span class="lines">@@ -2300,8 +2300,8 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">             
</span><del>-        if (Structure* structure = set.onlyStructure()) {
-            filterByValue(node-&gt;child1(), *m_graph.freeze(structure));
</del><ins>+        if (RegisteredStructure structure = set.onlyStructure()) {
+            filterByValue(node-&gt;child1(), *m_graph.freeze(structure.get()));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -2432,7 +2432,7 @@
</span><span class="cx">     }
</span><span class="cx">     case ArrayifyToStructure: {
</span><span class="cx">         AbstractValue&amp; value = forNode(node-&gt;child1());
</span><del>-        if (value.m_structure.isSubsetOf(StructureSet(node-&gt;structure())))
</del><ins>+        if (value.m_structure.isSubsetOf(RegisteredStructureSet(node-&gt;structure())))
</ins><span class="cx">             m_state.setFoundConstants(true);
</span><span class="cx">         clobberStructures(clobberLimit);
</span><span class="cx">         
</span><span class="lines">@@ -2546,10 +2546,10 @@
</span><span class="cx">         UniquedStringImpl* uid = m_graph.identifiers()[node-&gt;multiGetByOffsetData().identifierNumber];
</span><span class="cx"> 
</span><span class="cx">         AbstractValue base = forNode(node-&gt;child1());
</span><del>-        StructureSet baseSet;
</del><ins>+        RegisteredStructureSet baseSet;
</ins><span class="cx">         AbstractValue result;
</span><span class="cx">         for (const MultiGetByOffsetCase&amp; getCase : node-&gt;multiGetByOffsetData().cases) {
</span><del>-            StructureSet set = getCase.set();
</del><ins>+            RegisteredStructureSet set = getCase.set();
</ins><span class="cx">             set.filter(base);
</span><span class="cx">             if (set.isEmpty())
</span><span class="cx">                 continue;
</span><span class="lines">@@ -2591,7 +2591,7 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case MultiPutByOffset: {
</span><del>-        StructureSet newSet;
</del><ins>+        RegisteredStructureSet newSet;
</ins><span class="cx">         TransitionVector transitions;
</span><span class="cx">         
</span><span class="cx">         // Ordinarily you have to be careful with calling setFoundConstants()
</span><span class="lines">@@ -2604,7 +2604,7 @@
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
</span><span class="cx">             const PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
</span><del>-            StructureSet thisSet = variant.oldStructure();
</del><ins>+            RegisteredStructureSet thisSet = *m_graph.addStructureSet(variant.oldStructure());
</ins><span class="cx">             thisSet.filter(base);
</span><span class="cx">             if (thisSet.isEmpty())
</span><span class="cx">                 continue;
</span><span class="lines">@@ -2614,11 +2614,12 @@
</span><span class="cx">             resultingValue.merge(thisValue);
</span><span class="cx">             
</span><span class="cx">             if (variant.kind() == PutByIdVariant::Transition) {
</span><del>-                if (thisSet.onlyStructure() != variant.newStructure()) {
</del><ins>+                RegisteredStructure newStructure = m_graph.registerStructure(variant.newStructure());
+                if (thisSet.onlyStructure() != newStructure) {
</ins><span class="cx">                     transitions.append(
</span><del>-                        Transition(variant.oldStructureForTransition(), variant.newStructure()));
</del><ins>+                        Transition(m_graph.registerStructure(variant.oldStructureForTransition()), newStructure));
</ins><span class="cx">                 } // else this is really a replace.
</span><del>-                newSet.add(variant.newStructure());
</del><ins>+                newSet.add(newStructure);
</ins><span class="cx">             } else {
</span><span class="cx">                 ASSERT(variant.kind() == PutByIdVariant::Replace);
</span><span class="cx">                 newSet.merge(thisSet);
</span><span class="lines">@@ -2705,25 +2706,25 @@
</span><span class="cx">         if (value.m_structure.isFinite()) {
</span><span class="cx">             PutByIdStatus status = PutByIdStatus::computeFor(
</span><span class="cx">                 m_graph.globalObjectFor(node-&gt;origin.semantic),
</span><del>-                value.m_structure.set(),
</del><ins>+                value.m_structure.toStructureSet(),
</ins><span class="cx">                 m_graph.identifiers()[node-&gt;identifierNumber()],
</span><span class="cx">                 node-&gt;op() == PutByIdDirect);
</span><span class="cx"> 
</span><span class="cx">             if (status.isSimple()) {
</span><del>-                StructureSet newSet;
</del><ins>+                RegisteredStructureSet newSet;
</ins><span class="cx">                 TransitionVector transitions;
</span><span class="cx">                 
</span><span class="cx">                 for (unsigned i = status.numVariants(); i--;) {
</span><span class="cx">                     const PutByIdVariant&amp; variant = status[i];
</span><span class="cx">                     if (variant.kind() == PutByIdVariant::Transition) {
</span><ins>+                        RegisteredStructure newStructure = m_graph.registerStructure(variant.newStructure());
</ins><span class="cx">                         transitions.append(
</span><span class="cx">                             Transition(
</span><del>-                                variant.oldStructureForTransition(), variant.newStructure()));
-                        m_graph.registerStructure(variant.newStructure());
-                        newSet.add(variant.newStructure());
</del><ins>+                                m_graph.registerStructure(variant.oldStructureForTransition()), newStructure));
+                        newSet.add(newStructure);
</ins><span class="cx">                     } else {
</span><span class="cx">                         ASSERT(variant.kind() == PutByIdVariant::Replace);
</span><del>-                        newSet.merge(variant.oldStructure());
</del><ins>+                        newSet.merge(*m_graph.addStructureSet(variant.oldStructure()));
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="lines">@@ -3059,7 +3060,7 @@
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="cx"> void AbstractInterpreter&lt;AbstractStateType&gt;::observeTransition(
</span><del>-    unsigned clobberLimit, Structure* from, Structure* to)
</del><ins>+    unsigned clobberLimit, RegisteredStructure from, RegisteredStructure to)
</ins><span class="cx"> {
</span><span class="cx">     AbstractValue::TransitionObserver transitionObserver(from, to);
</span><span class="cx">     forAllValues(clobberLimit, transitionObserver);
</span><span class="lines">@@ -3132,7 +3133,7 @@
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="cx"> FiltrationResult AbstractInterpreter&lt;AbstractStateType&gt;::filter(
</span><del>-    AbstractValue&amp; value, const StructureSet&amp; set, SpeculatedType admittedTypes)
</del><ins>+    AbstractValue&amp; value, const RegisteredStructureSet&amp; set, SpeculatedType admittedTypes)
</ins><span class="cx"> {
</span><span class="cx">     if (value.filter(m_graph, set, admittedTypes) == FiltrationOK)
</span><span class="cx">         return FiltrationOK;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -52,8 +52,10 @@
</span><span class="cx"> {
</span><span class="cx">     if (!!value &amp;&amp; value.value().isCell()) {
</span><span class="cx">         Structure* structure = value.structure();
</span><del>-        if (graph.registerStructure(structure) == StructureRegisteredAndWatched) {
-            m_structure = structure;
</del><ins>+        StructureRegistrationResult result;
+        RegisteredStructure RegisteredStructure = graph.registerStructure(structure, result);
+        if (result == StructureRegisteredAndWatched) {
+            m_structure = RegisteredStructure;
</ins><span class="cx">             if (clobberState == StructuresAreClobbered) {
</span><span class="cx">                 m_arrayModes = ALL_ARRAY_MODES;
</span><span class="cx">                 m_structure.clobber();
</span><span class="lines">@@ -77,11 +79,16 @@
</span><span class="cx"> 
</span><span class="cx"> void AbstractValue::set(Graph&amp; graph, Structure* structure)
</span><span class="cx"> {
</span><ins>+    set(graph, graph.registerStructure(structure));
+}
+
+void AbstractValue::set(Graph&amp; graph, RegisteredStructure structure)
+{
</ins><span class="cx">     RELEASE_ASSERT(structure);
</span><span class="cx">     
</span><span class="cx">     m_structure = structure;
</span><span class="cx">     m_arrayModes = asArrayModes(structure-&gt;indexingType());
</span><del>-    m_type = speculationFromStructure(structure);
</del><ins>+    m_type = speculationFromStructure(structure.get());
</ins><span class="cx">     m_value = JSValue();
</span><span class="cx">     
</span><span class="cx">     checkConsistency();
</span><span class="lines">@@ -88,7 +95,7 @@
</span><span class="cx">     assertIsRegistered(graph);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AbstractValue::set(Graph&amp; graph, const StructureSet&amp; set)
</del><ins>+void AbstractValue::set(Graph&amp; graph, const RegisteredStructureSet&amp; set)
</ins><span class="cx"> {
</span><span class="cx">     m_structure = set;
</span><span class="cx">     m_arrayModes = set.arrayModesFromStructures();
</span><span class="lines">@@ -104,9 +111,9 @@
</span><span class="cx">     SpeculatedType cellType = type &amp; SpecCell;
</span><span class="cx">     if (cellType) {
</span><span class="cx">         if (!(cellType &amp; ~SpecString))
</span><del>-            m_structure = graph.m_vm.stringStructure.get();
</del><ins>+            m_structure = graph.stringStructure;
</ins><span class="cx">         else if (isSymbolSpeculation(cellType))
</span><del>-            m_structure = graph.m_vm.symbolStructure.get();
</del><ins>+            m_structure = graph.symbolStructure;
</ins><span class="cx">         else
</span><span class="cx">             m_structure.makeTop();
</span><span class="cx">         m_arrayModes = ALL_ARRAY_MODES;
</span><span class="lines">@@ -217,7 +224,7 @@
</span><span class="cx">     if (isClear()) {
</span><span class="cx">         FrozenValue* frozenValue = graph.freeze(value);
</span><span class="cx">         if (frozenValue-&gt;pointsToHeap()) {
</span><del>-            m_structure = frozenValue-&gt;structure();
</del><ins>+            m_structure = graph.registerStructure(frozenValue-&gt;structure());
</ins><span class="cx">             m_arrayModes = asArrayModes(frozenValue-&gt;structure()-&gt;indexingType());
</span><span class="cx">         } else {
</span><span class="cx">             m_structure.clear();
</span><span class="lines">@@ -229,10 +236,9 @@
</span><span class="cx">     } else {
</span><span class="cx">         mergeSpeculation(m_type, speculationFromValue(value));
</span><span class="cx">         if (!!value &amp;&amp; value.isCell()) {
</span><del>-            Structure* structure = value.asCell()-&gt;structure();
-            graph.registerStructure(structure);
</del><ins>+            RegisteredStructure structure = graph.registerStructure(value.asCell()-&gt;structure());
</ins><span class="cx">             mergeArrayModes(m_arrayModes, asArrayModes(structure-&gt;indexingType()));
</span><del>-            m_structure.merge(StructureSet(structure));
</del><ins>+            m_structure.merge(RegisteredStructureSet(structure));
</ins><span class="cx">         }
</span><span class="cx">         if (m_value != value)
</span><span class="cx">             m_value = JSValue();
</span><span class="lines">@@ -256,7 +262,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FiltrationResult AbstractValue::filter(
</span><del>-    Graph&amp; graph, const StructureSet&amp; other, SpeculatedType admittedTypes)
</del><ins>+    Graph&amp; graph, const RegisteredStructureSet&amp; other, SpeculatedType admittedTypes)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!(admittedTypes &amp; SpecCell));
</span><span class="cx">     
</span><span class="lines">@@ -272,10 +278,10 @@
</span><span class="cx">     m_structure.filter(other);
</span><span class="cx">     
</span><span class="cx">     // It's possible that prior to the above two statements we had (Foo, TOP), where
</span><del>-    // Foo is a SpeculatedType that is disjoint with the passed StructureSet. In that
</del><ins>+    // Foo is a SpeculatedType that is disjoint with the passed RegisteredStructureSet. In that
</ins><span class="cx">     // case, we will now have (None, [someStructure]). In general, we need to make
</span><span class="cx">     // sure that new information gleaned from the SpeculatedType needs to be fed back
</span><del>-    // into the information gleaned from the StructureSet.
</del><ins>+    // into the information gleaned from the RegisteredStructureSet.
</ins><span class="cx">     m_structure.filter(m_type);
</span><span class="cx">     
</span><span class="cx">     filterArrayModesByType();
</span><span class="lines">@@ -283,7 +289,7 @@
</span><span class="cx">     return normalizeClarity(graph);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-FiltrationResult AbstractValue::changeStructure(Graph&amp; graph, const StructureSet&amp; other)
</del><ins>+FiltrationResult AbstractValue::changeStructure(Graph&amp; graph, const RegisteredStructureSet&amp; other)
</ins><span class="cx"> {
</span><span class="cx">     m_type &amp;= other.speculationFromStructures();
</span><span class="cx">     m_arrayModes = other.arrayModesFromStructures();
</span><span class="lines">@@ -361,10 +367,10 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AbstractValue::contains(Structure* structure) const
</del><ins>+bool AbstractValue::contains(RegisteredStructure structure) const
</ins><span class="cx"> {
</span><del>-    return couldBeType(speculationFromStructure(structure))
-        &amp;&amp; (m_arrayModes &amp; arrayModeFromStructure(structure))
</del><ins>+    return couldBeType(speculationFromStructure(structure.get()))
+        &amp;&amp; (m_arrayModes &amp; arrayModeFromStructure(structure.get()))
</ins><span class="cx">         &amp;&amp; m_structure.contains(structure);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGAbstractValueh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> #include &quot;ResultType.h&quot;
</span><span class="cx"> #include &quot;SpeculatedType.h&quot;
</span><span class="cx"> #include &quot;DumpContext.h&quot;
</span><del>-#include &quot;StructureSet.h&quot;
</del><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -120,7 +119,7 @@
</span><span class="cx">         value.observeInvalidationPoint();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void observeTransition(Structure* from, Structure* to)
</del><ins>+    void observeTransition(RegisteredStructure from, RegisteredStructure to)
</ins><span class="cx">     {
</span><span class="cx">         if (m_type &amp; SpecCell) {
</span><span class="cx">             m_structure.observeTransition(from, to);
</span><span class="lines">@@ -133,7 +132,7 @@
</span><span class="cx">     
</span><span class="cx">     class TransitionObserver {
</span><span class="cx">     public:
</span><del>-        TransitionObserver(Structure* from, Structure* to)
</del><ins>+        TransitionObserver(RegisteredStructure from, RegisteredStructure to)
</ins><span class="cx">             : m_from(from)
</span><span class="cx">             , m_to(to)
</span><span class="cx">         {
</span><span class="lines">@@ -144,8 +143,8 @@
</span><span class="cx">             value.observeTransition(m_from, m_to);
</span><span class="cx">         }
</span><span class="cx">     private:
</span><del>-        Structure* m_from;
-        Structure* m_to;
</del><ins>+        RegisteredStructure m_from;
+        RegisteredStructure m_to;
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     class TransitionsObserver {
</span><span class="lines">@@ -209,7 +208,8 @@
</span><span class="cx">     
</span><span class="cx">     void set(Graph&amp;, const FrozenValue&amp;, StructureClobberState);
</span><span class="cx">     void set(Graph&amp;, Structure*);
</span><del>-    void set(Graph&amp;, const StructureSet&amp;);
</del><ins>+    void set(Graph&amp;, RegisteredStructure);
+    void set(Graph&amp;, const RegisteredStructureSet&amp;);
</ins><span class="cx">     
</span><span class="cx">     // Set this value to represent the given set of types as precisely as possible.
</span><span class="cx">     void setType(Graph&amp;, SpeculatedType);
</span><span class="lines">@@ -301,7 +301,7 @@
</span><span class="cx">     // SpecCell. Hence, after this call, the value will no longer have any non-cell members. But, you can
</span><span class="cx">     // use admittedTypes to preserve some non-cell types. Note that it's wrong for admittedTypes to overlap
</span><span class="cx">     // with SpecCell.
</span><del>-    FiltrationResult filter(Graph&amp;, const StructureSet&amp;, SpeculatedType admittedTypes = SpecNone);
</del><ins>+    FiltrationResult filter(Graph&amp;, const RegisteredStructureSet&amp;, SpeculatedType admittedTypes = SpecNone);
</ins><span class="cx">     
</span><span class="cx">     FiltrationResult filterArrayModes(ArrayModes);
</span><span class="cx">     FiltrationResult filter(SpeculatedType);
</span><span class="lines">@@ -311,9 +311,9 @@
</span><span class="cx"> 
</span><span class="cx">     FiltrationResult filter(Graph&amp;, const InferredType::Descriptor&amp;);
</span><span class="cx">     
</span><del>-    FiltrationResult changeStructure(Graph&amp;, const StructureSet&amp;);
</del><ins>+    FiltrationResult changeStructure(Graph&amp;, const RegisteredStructureSet&amp;);
</ins><span class="cx">     
</span><del>-    bool contains(Structure*) const;
</del><ins>+    bool contains(RegisteredStructure) const;
</ins><span class="cx"> 
</span><span class="cx">     bool validate(JSValue value) const
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -393,7 +393,7 @@
</span><span class="cx">                     }
</span><span class="cx">                     ASSERT(structure);
</span><span class="cx"> 
</span><del>-                    if (!node-&gt;structureSet().contains(structure))
</del><ins>+                    if (!node-&gt;structureSet().contains(m_graph.registerStructure(structure)))
</ins><span class="cx">                         escape(node-&gt;child1(), node);
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -360,12 +360,12 @@
</span><span class="cx">         if (value.m_structure.isTop())
</span><span class="cx">             return false;
</span><span class="cx">         for (unsigned i = value.m_structure.size(); i--;) {
</span><del>-            Structure* structure = value.m_structure[i];
</del><ins>+            RegisteredStructure structure = value.m_structure[i];
</ins><span class="cx">             if ((structure-&gt;indexingType() &amp; IndexingShapeMask) != shape)
</span><span class="cx">                 return false;
</span><span class="cx">             if (!(structure-&gt;indexingType() &amp; IsArray))
</span><span class="cx">                 return false;
</span><del>-            if (!graph.globalObjectFor(node-&gt;origin.semantic)-&gt;isOriginalArrayStructure(structure))
</del><ins>+            if (!graph.globalObjectFor(node-&gt;origin.semantic)-&gt;isOriginalArrayStructure(structure.get()))
</ins><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx">         return true;
</span><span class="lines">@@ -377,7 +377,7 @@
</span><span class="cx">         if (value.m_structure.isTop())
</span><span class="cx">             return false;
</span><span class="cx">         for (unsigned i = value.m_structure.size(); i--;) {
</span><del>-            Structure* structure = value.m_structure[i];
</del><ins>+            RegisteredStructure structure = value.m_structure[i];
</ins><span class="cx">             if ((structure-&gt;indexingType() &amp; IndexingShapeMask) != shape)
</span><span class="cx">                 return false;
</span><span class="cx">             if (!(structure-&gt;indexingType() &amp; IsArray))
</span><span class="lines">@@ -392,7 +392,7 @@
</span><span class="cx">         if (value.m_structure.isTop())
</span><span class="cx">             return false;
</span><span class="cx">         for (unsigned i = value.m_structure.size(); i--;) {
</span><del>-            Structure* structure = value.m_structure[i];
</del><ins>+            RegisteredStructure structure = value.m_structure[i];
</ins><span class="cx">             if ((structure-&gt;indexingType() &amp; IndexingShapeMask) != shape)
</span><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="lines">@@ -440,7 +440,7 @@
</span><span class="cx">             if (value.m_structure.isTop())
</span><span class="cx">                 return false;
</span><span class="cx">             for (unsigned i = value.m_structure.size(); i--;) {
</span><del>-                Structure* structure = value.m_structure[i];
</del><ins>+                RegisteredStructure structure = value.m_structure[i];
</ins><span class="cx">                 if (!hasAnyArrayStorage(structure-&gt;indexingType()))
</span><span class="cx">                     return false;
</span><span class="cx">                 if (!(structure-&gt;indexingType() &amp; IsArray))
</span><span class="lines">@@ -455,7 +455,7 @@
</span><span class="cx">             if (value.m_structure.isTop())
</span><span class="cx">                 return false;
</span><span class="cx">             for (unsigned i = value.m_structure.size(); i--;) {
</span><del>-                Structure* structure = value.m_structure[i];
</del><ins>+                RegisteredStructure structure = value.m_structure[i];
</ins><span class="cx">                 if (!hasAnyArrayStorage(structure-&gt;indexingType()))
</span><span class="cx">                     return false;
</span><span class="cx">             }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGArrayifySlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">         : JumpingSlowPathGenerator&lt;MacroAssembler::JumpList&gt;(from, jit)
</span><span class="cx">         , m_op(node-&gt;op())
</span><span class="cx">         , m_arrayMode(node-&gt;arrayMode())
</span><del>-        , m_structure(node-&gt;op() == ArrayifyToStructure ? node-&gt;structure() : 0)
</del><ins>+        , m_structure(node-&gt;op() == ArrayifyToStructure ? node-&gt;structure() : RegisteredStructure())
</ins><span class="cx">         , m_baseGPR(baseGPR)
</span><span class="cx">         , m_propertyGPR(propertyGPR)
</span><span class="cx">         , m_tempGPR(tempGPR)
</span><span class="lines">@@ -115,7 +115,7 @@
</span><span class="cx">         jit-&gt;m_jit.exceptionCheck();
</span><span class="cx">         
</span><span class="cx">         if (m_op == ArrayifyToStructure) {
</span><del>-            ASSERT(m_structure);
</del><ins>+            ASSERT(m_structure.get());
</ins><span class="cx">             m_badIndexingTypeJump.fill(
</span><span class="cx">                 jit, jit-&gt;m_jit.branchWeakStructure(MacroAssembler::NotEqual, MacroAssembler::Address(m_baseGPR, JSCell::structureIDOffset()), m_structure));
</span><span class="cx">         } else {
</span><span class="lines">@@ -136,7 +136,7 @@
</span><span class="cx"> private:
</span><span class="cx">     NodeType m_op;
</span><span class="cx">     ArrayMode m_arrayMode;
</span><del>-    Structure* m_structure;
</del><ins>+    RegisteredStructure m_structure;
</ins><span class="cx">     GPRReg m_baseGPR;
</span><span class="cx">     GPRReg m_propertyGPR;
</span><span class="cx">     GPRReg m_tempGPR;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -2960,7 +2960,7 @@
</span><span class="cx">             result = addToGraph(CallStringConstructor, get(virtualRegisterForArgument(1, registerOffset)));
</span><span class="cx">         
</span><span class="cx">         if (kind == CodeForConstruct)
</span><del>-            result = addToGraph(NewStringObject, OpInfo(function-&gt;globalObject()-&gt;stringObjectStructure()), result);
</del><ins>+            result = addToGraph(NewStringObject, OpInfo(m_graph.registerStructure(function-&gt;globalObject()-&gt;stringObjectStructure())), result);
</ins><span class="cx">         
</span><span class="cx">         set(VirtualRegister(resultOperand), result);
</span><span class="cx">         return true;
</span><span class="lines">@@ -2972,7 +2972,7 @@
</span><span class="cx"> 
</span><span class="cx">         Node* result;
</span><span class="cx">         if (argumentCountIncludingThis &lt;= 1)
</span><del>-            result = addToGraph(NewObject, OpInfo(function-&gt;globalObject()-&gt;objectStructureForObjectConstructor()));
</del><ins>+            result = addToGraph(NewObject, OpInfo(m_graph.registerStructure(function-&gt;globalObject()-&gt;objectStructureForObjectConstructor())));
</ins><span class="cx">         else
</span><span class="cx">             result = addToGraph(CallObjectConstructor, get(virtualRegisterForArgument(1, registerOffset)));
</span><span class="cx">         set(VirtualRegister(resultOperand), result);
</span><span class="lines">@@ -3383,7 +3383,7 @@
</span><span class="cx">             // We did emit a structure check. That means that we have an opportunity to do constant folding
</span><span class="cx">             // here, since we didn't do it above.
</span><span class="cx">             JSValue constant = m_graph.tryGetConstantProperty(
</span><del>-                base-&gt;asJSValue(), variant.structureSet(), variant.offset());
</del><ins>+                base-&gt;asJSValue(), *m_graph.addStructureSet(variant.structureSet()), variant.offset());
</ins><span class="cx">             if (constant)
</span><span class="cx">                 return weakJSConstant(constant);
</span><span class="cx">         }
</span><span class="lines">@@ -3429,7 +3429,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         if (ok)
</span><del>-            getByIdStatus.filter(base-&gt;structure());
</del><ins>+            getByIdStatus.filter(base-&gt;structure().get());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     NodeType getById;
</span><span class="lines">@@ -3482,7 +3482,7 @@
</span><span class="cx">             if (variant.conditionSet().isEmpty()) {
</span><span class="cx">                 cases.append(
</span><span class="cx">                     MultiGetByOffsetCase(
</span><del>-                        variant.structureSet(),
</del><ins>+                        *m_graph.addStructureSet(variant.structureSet()),
</ins><span class="cx">                         GetByOffsetMethod::load(variant.offset())));
</span><span class="cx">                 continue;
</span><span class="cx">             }
</span><span class="lines">@@ -3494,7 +3494,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            cases.append(MultiGetByOffsetCase(variant.structureSet(), method));
</del><ins>+            cases.append(MultiGetByOffsetCase(*m_graph.addStructureSet(variant.structureSet()), method));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (m_graph.compilation())
</span><span class="lines">@@ -3621,8 +3621,13 @@
</span><span class="cx">         if (m_graph.compilation())
</span><span class="cx">             m_graph.compilation()-&gt;noticeInlinedPutById();
</span><span class="cx"> 
</span><del>-        for (const PutByIdVariant&amp; variant : putByIdStatus.variants())
</del><ins>+        for (const PutByIdVariant&amp; variant : putByIdStatus.variants()) {
</ins><span class="cx">             m_graph.registerInferredType(variant.requiredType());
</span><ins>+            for (Structure* structure : variant.oldStructure())
+                m_graph.registerStructure(structure);
+            if (variant.kind() == PutByIdVariant::Transition)
+                m_graph.registerStructure(variant.newStructure());
+        }
</ins><span class="cx">         
</span><span class="cx">         MultiPutByOffsetData* data = m_graph.m_multiPutByOffsetData.add();
</span><span class="cx">         data-&gt;variants = putByIdStatus.variants();
</span><span class="lines">@@ -3653,7 +3658,7 @@
</span><span class="cx">     
</span><span class="cx">         Node* propertyStorage;
</span><span class="cx">         Transition* transition = m_graph.m_transitions.add(
</span><del>-            variant.oldStructureForTransition(), variant.newStructure());
</del><ins>+            m_graph.registerStructure(variant.oldStructureForTransition()), m_graph.registerStructure(variant.newStructure()));
</ins><span class="cx"> 
</span><span class="cx">         if (variant.reallocatesStorage()) {
</span><span class="cx"> 
</span><span class="lines">@@ -3900,7 +3905,7 @@
</span><span class="cx">                         m_graph.watchpoints().addLazily(rareData-&gt;allocationProfileWatchpointSet());
</span><span class="cx">                         // The callee is still live up to this point.
</span><span class="cx">                         addToGraph(Phantom, callee);
</span><del>-                        set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(structure)));
</del><ins>+                        set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(m_graph.registerStructure(structure))));
</ins><span class="cx">                         alreadyEmitted = true;
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="lines">@@ -3915,7 +3920,7 @@
</span><span class="cx">         case op_new_object: {
</span><span class="cx">             set(VirtualRegister(currentInstruction[1].u.operand),
</span><span class="cx">                 addToGraph(NewObject,
</span><del>-                    OpInfo(currentInstruction[3].u.objectAllocationProfile-&gt;structure())));
</del><ins>+                    OpInfo(m_graph.registerStructure(currentInstruction[3].u.objectAllocationProfile-&gt;structure()))));
</ins><span class="cx">             NEXT_OPCODE(op_new_object);
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="lines">@@ -5678,7 +5683,7 @@
</span><span class="cx">         ASSERT(callsiteBlockHead);
</span><span class="cx">         
</span><span class="cx">         m_inlineCallFrame = byteCodeParser-&gt;m_graph.m_plan.inlineCallFrames-&gt;add();
</span><del>-        byteCodeParser-&gt;m_graph.freeze(codeBlock-&gt;baselineVersion());
</del><ins>+
</ins><span class="cx">         // The owner is the machine code block, and we already have a barrier on that when the
</span><span class="cx">         // plan finishes.
</span><span class="cx">         m_inlineCallFrame-&gt;baselineCodeBlock.setWithoutWriteBarrier(codeBlock-&gt;baselineVersion());
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGCallArrayAllocatorSlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> public:
</span><span class="cx">     CallArrayAllocatorSlowPathGenerator(
</span><span class="cx">         MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZB function,
</span><del>-        GPRReg resultGPR, GPRReg storageGPR, Structure* structure, size_t size)
</del><ins>+        GPRReg resultGPR, GPRReg storageGPR, RegisteredStructure structure, size_t size)
</ins><span class="cx">         : JumpingSlowPathGenerator&lt;MacroAssembler::JumpList&gt;(from, jit)
</span><span class="cx">         , m_function(function)
</span><span class="cx">         , m_resultGPR(resultGPR)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">     P_JITOperation_EStZB m_function;
</span><span class="cx">     GPRReg m_resultGPR;
</span><span class="cx">     GPRReg m_storageGPR;
</span><del>-    Structure* m_structure;
</del><ins>+    RegisteredStructure m_structure;
</ins><span class="cx">     size_t m_size;
</span><span class="cx">     Vector&lt;SilentRegisterSavePlan, 2&gt; m_plans;
</span><span class="cx"> };
</span><span class="lines">@@ -78,7 +78,7 @@
</span><span class="cx"> public:
</span><span class="cx">     CallArrayAllocatorWithVariableSizeSlowPathGenerator(
</span><span class="cx">         MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZB function,
</span><del>-        GPRReg resultGPR, Structure* contiguousStructure, Structure* arrayStorageStructure, GPRReg sizeGPR, GPRReg storageGPR)
</del><ins>+        GPRReg resultGPR, RegisteredStructure contiguousStructure, RegisteredStructure arrayStorageStructure, GPRReg sizeGPR, GPRReg storageGPR)
</ins><span class="cx">         : JumpingSlowPathGenerator&lt;MacroAssembler::JumpList&gt;(from, jit)
</span><span class="cx">         , m_function(function)
</span><span class="cx">         , m_resultGPR(resultGPR)
</span><span class="lines">@@ -97,15 +97,15 @@
</span><span class="cx">         for (unsigned i = 0; i &lt; m_plans.size(); ++i)
</span><span class="cx">             jit-&gt;silentSpill(m_plans[i]);
</span><span class="cx">         GPRReg scratchGPR = AssemblyHelpers::selectScratchGPR(m_sizeGPR, m_storageGPR);
</span><del>-        if (m_contiguousStructure != m_arrayStorageOrContiguousStructure) {
</del><ins>+        if (m_contiguousStructure.get() != m_arrayStorageOrContiguousStructure.get()) {
</ins><span class="cx">             MacroAssembler::Jump bigLength = jit-&gt;m_jit.branch32(MacroAssembler::AboveOrEqual, m_sizeGPR, MacroAssembler::TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
</span><del>-            jit-&gt;m_jit.move(MacroAssembler::TrustedImmPtr(m_contiguousStructure), scratchGPR);
</del><ins>+            jit-&gt;m_jit.move(SpeculativeJIT::TrustedImmPtr(m_contiguousStructure), scratchGPR);
</ins><span class="cx">             MacroAssembler::Jump done = jit-&gt;m_jit.jump();
</span><span class="cx">             bigLength.link(&amp;jit-&gt;m_jit);
</span><del>-            jit-&gt;m_jit.move(MacroAssembler::TrustedImmPtr(m_arrayStorageOrContiguousStructure), scratchGPR);
</del><ins>+            jit-&gt;m_jit.move(SpeculativeJIT::TrustedImmPtr(m_arrayStorageOrContiguousStructure), scratchGPR);
</ins><span class="cx">             done.link(&amp;jit-&gt;m_jit);
</span><span class="cx">         } else
</span><del>-            jit-&gt;m_jit.move(MacroAssembler::TrustedImmPtr(m_contiguousStructure), scratchGPR);
</del><ins>+            jit-&gt;m_jit.move(SpeculativeJIT::TrustedImmPtr(m_contiguousStructure), scratchGPR);
</ins><span class="cx">         jit-&gt;callOperation(m_function, m_resultGPR, scratchGPR, m_sizeGPR, m_storageGPR);
</span><span class="cx">         GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR);
</span><span class="cx">         for (unsigned i = m_plans.size(); i--;)
</span><span class="lines">@@ -117,8 +117,8 @@
</span><span class="cx"> private:
</span><span class="cx">     P_JITOperation_EStZB m_function;
</span><span class="cx">     GPRReg m_resultGPR;
</span><del>-    Structure* m_contiguousStructure;
-    Structure* m_arrayStorageOrContiguousStructure;
</del><ins>+    RegisteredStructure m_contiguousStructure;
+    RegisteredStructure m_arrayStorageOrContiguousStructure;
</ins><span class="cx">     GPRReg m_sizeGPR;
</span><span class="cx">     GPRReg m_storageGPR;
</span><span class="cx">     Vector&lt;SilentRegisterSavePlan, 2&gt; m_plans;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGCallCreateDirectArgumentsSlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx"> class CallCreateDirectArgumentsSlowPathGenerator : public JumpingSlowPathGenerator&lt;MacroAssembler::JumpList&gt; {
</span><span class="cx"> public:
</span><span class="cx">     CallCreateDirectArgumentsSlowPathGenerator(
</span><del>-        MacroAssembler::JumpList from, SpeculativeJIT* jit, GPRReg resultGPR, Structure* structure,
</del><ins>+        MacroAssembler::JumpList from, SpeculativeJIT* jit, GPRReg resultGPR, RegisteredStructure structure,
</ins><span class="cx">         GPRReg lengthGPR, unsigned minCapacity)
</span><span class="cx">         : JumpingSlowPathGenerator&lt;MacroAssembler::JumpList&gt;(from, jit)
</span><span class="cx">         , m_resultGPR(resultGPR)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     GPRReg m_resultGPR;
</span><del>-    Structure* m_structure;
</del><ins>+    RegisteredStructure m_structure;
</ins><span class="cx">     GPRReg m_lengthGPR;
</span><span class="cx">     unsigned m_minCapacity;
</span><span class="cx">     Vector&lt;SilentRegisterSavePlan, 2&gt; m_plans;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGCommonDatacpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCommonData.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCommonData.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGCommonData.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -43,8 +43,8 @@
</span><span class="cx">     plan.transitions.addLazily(
</span><span class="cx">         codeBlock,
</span><span class="cx">         node-&gt;origin.semantic.codeOriginOwner(),
</span><del>-        node-&gt;transition()-&gt;previous,
-        node-&gt;transition()-&gt;next);
</del><ins>+        node-&gt;transition()-&gt;previous.get(),
+        node-&gt;transition()-&gt;next.get());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CallSiteIndex CommonData::addCodeOrigin(CodeOrigin codeOrigin)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -145,7 +145,7 @@
</span><span class="cx">             case CheckStructure:
</span><span class="cx">             case ArrayifyToStructure: {
</span><span class="cx">                 AbstractValue&amp; value = m_state.forNode(node-&gt;child1());
</span><del>-                StructureSet set;
</del><ins>+                RegisteredStructureSet set;
</ins><span class="cx">                 if (node-&gt;op() == ArrayifyToStructure)
</span><span class="cx">                     set = node-&gt;structure();
</span><span class="cx">                 else
</span><span class="lines">@@ -206,11 +206,11 @@
</span><span class="cx">                 
</span><span class="cx">             case CheckStructureImmediate: {
</span><span class="cx">                 AbstractValue&amp; value = m_state.forNode(node-&gt;child1());
</span><del>-                StructureSet&amp; set = node-&gt;structureSet();
</del><ins>+                const RegisteredStructureSet&amp; set = node-&gt;structureSet();
</ins><span class="cx">                 
</span><span class="cx">                 if (value.value()) {
</span><span class="cx">                     if (Structure* structure = jsDynamicCast&lt;Structure*&gt;(value.value())) {
</span><del>-                        if (set.contains(structure)) {
</del><ins>+                        if (set.contains(m_graph.registerStructure(structure))) {
</ins><span class="cx">                             m_interpreter.execute(indexInBlock);
</span><span class="cx">                             node-&gt;remove();
</span><span class="cx">                             eliminated = true;
</span><span class="lines">@@ -225,7 +225,7 @@
</span><span class="cx">                         node,
</span><span class="cx">                         [&amp;] (Node* incoming) {
</span><span class="cx">                             if (Structure* structure = incoming-&gt;dynamicCastConstant&lt;Structure*&gt;()) {
</span><del>-                                if (set.contains(structure))
</del><ins>+                                if (set.contains(m_graph.registerStructure(structure)))
</ins><span class="cx">                                     return;
</span><span class="cx">                             }
</span><span class="cx">                             allGood = false;
</span><span class="lines">@@ -421,7 +421,9 @@
</span><span class="cx"> 
</span><span class="cx">                 for (unsigned i = 0; i &lt; data.variants.size(); ++i) {
</span><span class="cx">                     PutByIdVariant&amp; variant = data.variants[i];
</span><del>-                    variant.oldStructure().filter(baseValue);
</del><ins>+                    variant.oldStructure().genericFilter([&amp;] (Structure* structure) -&gt; bool {
+                        return baseValue.contains(m_graph.registerStructure(structure));
+                    });
</ins><span class="cx">                     
</span><span class="cx">                     if (variant.oldStructure().isEmpty()) {
</span><span class="cx">                         data.variants[i--] = data.variants.last();
</span><span class="lines">@@ -460,12 +462,12 @@
</span><span class="cx">                 m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
</span><span class="cx">                 alreadyHandled = true; // Don't allow the default constant folder to do things to this.
</span><span class="cx"> 
</span><del>-                if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered()
</del><ins>+                if (!baseValue.m_structure.isFinite()
</ins><span class="cx">                     || (node-&gt;child1().useKind() == UntypedUse || (baseValue.m_type &amp; ~SpecCell)))
</span><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="cx">                 GetByIdStatus status = GetByIdStatus::computeFor(
</span><del>-                    baseValue.m_structure.set(), m_graph.identifiers()[identifierNumber]);
</del><ins>+                    baseValue.m_structure.toStructureSet(), m_graph.identifiers()[identifierNumber]);
</ins><span class="cx">                 if (!status.isSimple())
</span><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="lines">@@ -490,7 +492,7 @@
</span><span class="cx">                 for (const GetByIdVariant&amp; variant : status.variants()) {
</span><span class="cx">                     data-&gt;cases.append(
</span><span class="cx">                         MultiGetByOffsetCase(
</span><del>-                            variant.structureSet(),
</del><ins>+                            *m_graph.addStructureSet(variant.structureSet()),
</ins><span class="cx">                             GetByOffsetMethod::load(variant.offset())));
</span><span class="cx">                 }
</span><span class="cx">                 data-&gt;identifierNumber = identifierNumber;
</span><span class="lines">@@ -515,12 +517,12 @@
</span><span class="cx">                 m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
</span><span class="cx">                 alreadyHandled = true; // Don't allow the default constant folder to do things to this.
</span><span class="cx"> 
</span><del>-                if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered())
</del><ins>+                if (!baseValue.m_structure.isFinite())
</ins><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="cx">                 PutByIdStatus status = PutByIdStatus::computeFor(
</span><span class="cx">                     m_graph.globalObjectFor(origin.semantic),
</span><del>-                    baseValue.m_structure.set(),
</del><ins>+                    baseValue.m_structure.toStructureSet(),
</ins><span class="cx">                     m_graph.identifiers()[identifierNumber],
</span><span class="cx">                     node-&gt;op() == PutByIdDirect);
</span><span class="cx">                 
</span><span class="lines">@@ -713,7 +715,7 @@
</span><span class="cx">         // We aren't set up to handle prototype stuff.
</span><span class="cx">         DFG_ASSERT(m_graph, node, variant.conditionSet().isEmpty());
</span><span class="cx"> 
</span><del>-        if (JSValue value = m_graph.tryGetConstantProperty(baseValue.m_value, variant.structureSet(), variant.offset())) {
</del><ins>+        if (JSValue value = m_graph.tryGetConstantProperty(baseValue.m_value, *m_graph.addStructureSet(variant.structureSet()), variant.offset())) {
</ins><span class="cx">             m_graph.convertToConstant(node, m_graph.freeze(value));
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -759,7 +761,7 @@
</span><span class="cx">         Transition* transition = 0;
</span><span class="cx">         if (variant.kind() == PutByIdVariant::Transition) {
</span><span class="cx">             transition = m_graph.m_transitions.add(
</span><del>-                variant.oldStructureForTransition(), variant.newStructure());
</del><ins>+                m_graph.registerStructure(variant.oldStructureForTransition()), m_graph.registerStructure(variant.newStructure()));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         Edge propertyStorage;
</span><span class="lines">@@ -821,6 +823,12 @@
</span><span class="cx">     void addBaseCheck(
</span><span class="cx">         unsigned indexInBlock, Node* node, const AbstractValue&amp; baseValue, const StructureSet&amp; set)
</span><span class="cx">     {
</span><ins>+        addBaseCheck(indexInBlock, node, baseValue, *m_graph.addStructureSet(set));
+    }
+
+    void addBaseCheck(
+        unsigned indexInBlock, Node* node, const AbstractValue&amp; baseValue, const RegisteredStructureSet&amp; set)
+    {
</ins><span class="cx">         if (!baseValue.m_structure.isSubsetOf(set)) {
</span><span class="cx">             // Arises when we prune MultiGetByOffset. We could have a
</span><span class="cx">             // MultiGetByOffset with a single variant that checks for structure S,
</span><span class="lines">@@ -828,7 +836,7 @@
</span><span class="cx">             ASSERT(node-&gt;child1());
</span><span class="cx">             m_insertionSet.insertNode(
</span><span class="cx">                 indexInBlock, SpecNone, CheckStructure, node-&gt;origin,
</span><del>-                OpInfo(m_graph.addStructureSet(set)), node-&gt;child1());
</del><ins>+                OpInfo(m_graph.addStructureSet(set.toStructureSet())), node-&gt;child1());
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -838,8 +846,12 @@
</span><span class="cx">     
</span><span class="cx">     void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell, Structure* structure)
</span><span class="cx">     {
</span><del>-        if (m_graph.registerStructure(cell-&gt;structure()) == StructureRegisteredAndWatched)
-            return;
</del><ins>+        {
+            StructureRegistrationResult result;
+            m_graph.registerStructure(cell-&gt;structure(), result);
+            if (result == StructureRegisteredAndWatched)
+                return;
+        }
</ins><span class="cx">         
</span><span class="cx">         m_graph.registerStructure(structure);
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGDesiredWeakReferencescpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -72,6 +72,12 @@
</span><span class="cx">             common-&gt;weakStructureReferences.append(
</span><span class="cx">                 WriteBarrier&lt;Structure&gt;(vm, m_codeBlock, structure));
</span><span class="cx">         } else {
</span><ins>+            // There are weird relationships in how optimized CodeBlocks
+            // point to other CodeBlocks. We don't want to have them be
+            // part of the weak pointer set. For example, an optimized CodeBlock
+            // having a weak pointer to itself will cause it to get collected.
+            RELEASE_ASSERT(!jsDynamicCast&lt;CodeBlock*&gt;(target));
+
</ins><span class="cx">             common-&gt;weakReferences.append(
</span><span class="cx">                 WriteBarrier&lt;JSCell&gt;(vm, m_codeBlock, target));
</span><span class="cx">         }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -2365,7 +2365,7 @@
</span><span class="cx">                 if (structure) {
</span><span class="cx">                     m_insertionSet.insertNode(
</span><span class="cx">                         m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
</span><del>-                        OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
</del><ins>+                        OpInfo(m_graph.registerStructure(structure)), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
</ins><span class="cx">                 } else {
</span><span class="cx">                     m_insertionSet.insertNode(
</span><span class="cx">                         m_indexInBlock, SpecNone, Arrayify, origin,
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -88,6 +88,10 @@
</span><span class="cx">     
</span><span class="cx">     m_indexingCache = std::make_unique&lt;FlowIndexing&gt;(*this);
</span><span class="cx">     m_abstractValuesCache = std::make_unique&lt;FlowMap&lt;AbstractValue&gt;&gt;(*this);
</span><ins>+
+    registerStructure(vm.structureStructure.get());
+    this-&gt;stringStructure = registerStructure(vm.stringStructure.get());
+    this-&gt;symbolStructure = registerStructure(vm.symbolStructure.get());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Graph::~Graph()
</span><span class="lines">@@ -245,15 +249,15 @@
</span><span class="cx">     if (node-&gt;hasPromotedLocationDescriptor())
</span><span class="cx">         out.print(comma, node-&gt;promotedLocationDescriptor());
</span><span class="cx">     if (node-&gt;hasStructureSet())
</span><del>-        out.print(comma, inContext(node-&gt;structureSet(), context));
</del><ins>+        out.print(comma, inContext(node-&gt;structureSet().toStructureSet(), context));
</ins><span class="cx">     if (node-&gt;hasStructure())
</span><del>-        out.print(comma, inContext(*node-&gt;structure(), context));
</del><ins>+        out.print(comma, inContext(*node-&gt;structure().get(), context));
</ins><span class="cx">     if (node-&gt;hasTransition()) {
</span><span class="cx">         out.print(comma, pointerDumpInContext(node-&gt;transition(), context));
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">         out.print(&quot;, ID:&quot;, node-&gt;transition()-&gt;next-&gt;id());
</span><span class="cx"> #else
</span><del>-        out.print(&quot;, ID:&quot;, RawPointer(node-&gt;transition()-&gt;next));
</del><ins>+        out.print(&quot;, ID:&quot;, RawPointer(node-&gt;transition()-&gt;next.get()));
</ins><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx">     if (node-&gt;hasCellOperand()) {
</span><span class="lines">@@ -1207,7 +1211,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue Graph::tryGetConstantProperty(
</span><del>-    JSValue base, const StructureSet&amp; structureSet, PropertyOffset offset)
</del><ins>+    JSValue base, const RegisteredStructureSet&amp; structureSet, PropertyOffset offset)
</ins><span class="cx"> {
</span><span class="cx">     if (!base || !base.isObject())
</span><span class="cx">         return JSValue();
</span><span class="lines">@@ -1215,8 +1219,7 @@
</span><span class="cx">     JSObject* object = asObject(base);
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = structureSet.size(); i--;) {
</span><del>-        Structure* structure = structureSet[i];
-        assertIsRegistered(structure);
</del><ins>+        RegisteredStructure structure = structureSet[i];
</ins><span class="cx">         
</span><span class="cx">         WatchpointSet* set = structure-&gt;propertyReplacementWatchpointSet(offset);
</span><span class="cx">         if (!set || !set-&gt;isStillValid())
</span><span class="lines">@@ -1248,7 +1251,7 @@
</span><span class="cx">     // incompatible with the getDirect we're trying to do. The easiest way to do that is to
</span><span class="cx">     // determine if the structure belongs to the proven set.
</span><span class="cx">     
</span><del>-    if (!structureSet.contains(object-&gt;structure()))
</del><ins>+    if (!structureSet.toStructureSet().contains(object-&gt;structure()))
</ins><span class="cx">         return JSValue();
</span><span class="cx">     
</span><span class="cx">     return object-&gt;getDirect(offset);
</span><span class="lines">@@ -1256,7 +1259,7 @@
</span><span class="cx"> 
</span><span class="cx"> JSValue Graph::tryGetConstantProperty(JSValue base, Structure* structure, PropertyOffset offset)
</span><span class="cx"> {
</span><del>-    return tryGetConstantProperty(base, StructureSet(structure), offset);
</del><ins>+    return tryGetConstantProperty(base, RegisteredStructureSet(registerStructure(structure)), offset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue Graph::tryGetConstantProperty(
</span><span class="lines">@@ -1278,13 +1281,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> AbstractValue Graph::inferredValueForProperty(
</span><del>-    const StructureSet&amp; base, UniquedStringImpl* uid, StructureClobberState clobberState)
</del><ins>+    const RegisteredStructureSet&amp; base, UniquedStringImpl* uid, StructureClobberState clobberState)
</ins><span class="cx"> {
</span><span class="cx">     AbstractValue result;
</span><span class="cx">     base.forEach(
</span><del>-        [&amp;] (Structure* structure) {
</del><ins>+        [&amp;] (RegisteredStructure structure) {
</ins><span class="cx">             AbstractValue value;
</span><del>-            value.set(*this, inferredTypeForProperty(structure, uid));
</del><ins>+            value.set(*this, inferredTypeForProperty(structure.get(), uid));
</ins><span class="cx">             result.merge(value);
</span><span class="cx">         });
</span><span class="cx">     if (clobberState == StructuresAreClobbered)
</span><span class="lines">@@ -1413,57 +1416,6 @@
</span><span class="cx">         visitor.appendUnbarriered(value-&gt;value());
</span><span class="cx">         visitor.appendUnbarriered(value-&gt;structure());
</span><span class="cx">     }
</span><del>-    
-    for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
-        BasicBlock* block = this-&gt;block(blockIndex);
-        if (!block)
-            continue;
-        
-        for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
-            Node* node = block-&gt;at(nodeIndex);
-            
-            switch (node-&gt;op()) {
-            case CheckStructure:
-                for (unsigned i = node-&gt;structureSet().size(); i--;)
-                    visitor.appendUnbarriered(node-&gt;structureSet()[i]);
-                break;
-                
-            case NewObject:
-            case ArrayifyToStructure:
-            case NewStringObject:
-                visitor.appendUnbarriered(node-&gt;structure());
-                break;
-                
-            case PutStructure:
-            case AllocatePropertyStorage:
-            case ReallocatePropertyStorage:
-                visitor.appendUnbarriered(node-&gt;transition()-&gt;previous);
-                visitor.appendUnbarriered(node-&gt;transition()-&gt;next);
-                break;
-                
-            case MultiGetByOffset:
-                for (const MultiGetByOffsetCase&amp; getCase : node-&gt;multiGetByOffsetData().cases) {
-                    for (Structure* structure : getCase.set())
-                        visitor.appendUnbarriered(structure);
-                }
-                break;
-                    
-            case MultiPutByOffset:
-                for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
-                    PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
-                    const StructureSet&amp; set = variant.oldStructure();
-                    for (unsigned j = set.size(); j--;)
-                        visitor.appendUnbarriered(set[j]);
-                    if (variant.kind() == PutByIdVariant::Transition)
-                        visitor.appendUnbarriered(variant.newStructure());
-                }
-                break;
-                
-            default:
-                break;
-            }
-        }
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FrozenValue* Graph::freeze(JSValue value)
</span><span class="lines">@@ -1470,6 +1422,12 @@
</span><span class="cx"> {
</span><span class="cx">     if (UNLIKELY(!value))
</span><span class="cx">         return FrozenValue::emptySingleton();
</span><ins>+
+    // There are weird relationships in how optimized CodeBlocks
+    // point to other CodeBlocks. We don't want to have them be
+    // part of the weak pointer set. For example, an optimized CodeBlock
+    // having a weak pointer to itself will cause it to get collected.
+    RELEASE_ASSERT(!jsDynamicCast&lt;CodeBlock*&gt;(value));
</ins><span class="cx">     
</span><span class="cx">     auto result = m_frozenValueMap.add(JSValue::encode(value), nullptr);
</span><span class="cx">     if (LIKELY(!result.isNewEntry))
</span><span class="lines">@@ -1509,12 +1467,14 @@
</span><span class="cx">     convertToConstant(node, freezeStrong(value));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-StructureRegistrationResult Graph::registerStructure(Structure* structure)
</del><ins>+RegisteredStructure Graph::registerStructure(Structure* structure, StructureRegistrationResult&amp; result)
</ins><span class="cx"> {
</span><span class="cx">     m_plan.weakReferences.addLazily(structure);
</span><span class="cx">     if (m_plan.watchpoints.consider(structure))
</span><del>-        return StructureRegisteredAndWatched;
-    return StructureRegisteredNormally;
</del><ins>+        result = StructureRegisteredAndWatched;
+    else
+        result = StructureRegisteredNormally;
+    return RegisteredStructure::createPrivate(structure);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Graph::assertIsRegistered(Structure* structure)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGGraph.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -213,7 +213,12 @@
</span><span class="cx">     void convertToConstant(Node* node, JSValue value);
</span><span class="cx">     void convertToStrongConstant(Node* node, JSValue value);
</span><span class="cx">     
</span><del>-    StructureRegistrationResult registerStructure(Structure* structure);
</del><ins>+    RegisteredStructure registerStructure(Structure* structure)
+    {
+        StructureRegistrationResult ignored;
+        return registerStructure(structure, ignored);
+    }
+    RegisteredStructure registerStructure(Structure*, StructureRegistrationResult&amp;);
</ins><span class="cx">     void assertIsRegistered(Structure* structure);
</span><span class="cx">     
</span><span class="cx">     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
</span><span class="lines">@@ -341,13 +346,27 @@
</span><span class="cx">     
</span><span class="cx">     static const char *opName(NodeType);
</span><span class="cx">     
</span><del>-    StructureSet* addStructureSet(const StructureSet&amp; structureSet)
</del><ins>+    RegisteredStructureSet* addStructureSet(const StructureSet&amp; structureSet)
</ins><span class="cx">     {
</span><ins>+        m_structureSets.append();
+        RegisteredStructureSet* result = &amp;m_structureSets.last();
+
</ins><span class="cx">         for (Structure* structure : structureSet)
</span><del>-            registerStructure(structure);
-        m_structureSet.append(structureSet);
-        return &amp;m_structureSet.last();
</del><ins>+            result-&gt;add(registerStructure(structure));
+
+        return result;
</ins><span class="cx">     }
</span><ins>+
+    RegisteredStructureSet* addStructureSet(const RegisteredStructureSet&amp; structureSet)
+    {
+        m_structureSets.append();
+        RegisteredStructureSet* result = &amp;m_structureSets.last();
+
+        for (RegisteredStructure structure : structureSet)
+            result-&gt;add(structure);
+
+        return result;
+    }
</ins><span class="cx">     
</span><span class="cx">     JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin)
</span><span class="cx">     {
</span><span class="lines">@@ -715,7 +734,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     AbstractValue inferredValueForProperty(
</span><del>-        const StructureSet&amp; base, UniquedStringImpl* uid, StructureClobberState = StructuresAreWatched);
</del><ins>+        const RegisteredStructureSet&amp; base, UniquedStringImpl* uid, StructureClobberState = StructuresAreWatched);
</ins><span class="cx"> 
</span><span class="cx">     // This uses either constant property inference or property type inference to derive a good abstract
</span><span class="cx">     // value for some property accessed with the given abstract value base.
</span><span class="lines">@@ -818,7 +837,7 @@
</span><span class="cx">     unsigned requiredRegisterCountForExit();
</span><span class="cx">     unsigned requiredRegisterCountForExecutionAndExit();
</span><span class="cx">     
</span><del>-    JSValue tryGetConstantProperty(JSValue base, const StructureSet&amp;, PropertyOffset);
</del><ins>+    JSValue tryGetConstantProperty(JSValue base, const RegisteredStructureSet&amp;, PropertyOffset);
</ins><span class="cx">     JSValue tryGetConstantProperty(JSValue base, Structure*, PropertyOffset);
</span><span class="cx">     JSValue tryGetConstantProperty(JSValue base, const StructureAbstractValue&amp;, PropertyOffset);
</span><span class="cx">     JSValue tryGetConstantProperty(const AbstractValue&amp;, PropertyOffset);
</span><span class="lines">@@ -910,7 +929,6 @@
</span><span class="cx">     
</span><span class="cx">     SegmentedVector&lt;VariableAccessData, 16&gt; m_variableAccessData;
</span><span class="cx">     SegmentedVector&lt;ArgumentPosition, 8&gt; m_argumentPositions;
</span><del>-    SegmentedVector&lt;StructureSet, 16&gt; m_structureSet;
</del><span class="cx">     Bag&lt;Transition&gt; m_transitions;
</span><span class="cx">     SegmentedVector&lt;NewArrayBufferData, 4&gt; m_newArrayBufferData;
</span><span class="cx">     Bag&lt;BranchData&gt; m_branchData;
</span><span class="lines">@@ -960,6 +978,9 @@
</span><span class="cx">     std::unique_ptr&lt;FlowIndexing&gt; m_indexingCache;
</span><span class="cx">     std::unique_ptr&lt;FlowMap&lt;AbstractValue&gt;&gt; m_abstractValuesCache;
</span><span class="cx"> 
</span><ins>+    RegisteredStructure stringStructure;
+    RegisteredStructure symbolStructure;
+
</ins><span class="cx"> private:
</span><span class="cx">     void addNodeToMapByIndex(Node*);
</span><span class="cx"> 
</span><span class="lines">@@ -997,6 +1018,7 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;Node*, 0, UnsafeVectorOverflow&gt; m_nodesByIndex;
</span><span class="cx">     Vector&lt;unsigned, 0, UnsafeVectorOverflow&gt; m_nodeIndexFreeList;
</span><ins>+    SegmentedVector&lt;RegisteredStructureSet, 16&gt; m_structureSets;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGJITCompilerh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGJITCompiler.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -242,14 +242,14 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename T&gt;
</span><del>-    Jump branchWeakStructure(RelationalCondition cond, T left, Structure* weakStructure)
</del><ins>+    Jump branchWeakStructure(RelationalCondition cond, T left, RegisteredStructure weakStructure)
</ins><span class="cx">     {
</span><ins>+        Structure* structure = weakStructure.get();
</ins><span class="cx"> #if USE(JSVALUE64)
</span><del>-        Jump result = branch32(cond, left, TrustedImm32(weakStructure-&gt;id()));
-        addWeakReference(weakStructure);
</del><ins>+        Jump result = branch32(cond, left, TrustedImm32(structure-&gt;id()));
</ins><span class="cx">         return result;
</span><span class="cx"> #else
</span><del>-        return branchWeakPtr(cond, left, weakStructure);
</del><ins>+        return branchPtr(cond, left, TrustedImmPtr(structure));
</ins><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGMultiGetByOffsetDatacpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MultiGetByOffsetCase::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><del>-    out.print(inContext(m_set, context), &quot;:&quot;, inContext(m_method, context));
</del><ins>+    out.print(inContext(m_set.toStructureSet(), context), &quot;:&quot;, inContext(m_method, context));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MultiGetByOffsetCase::dump(PrintStream&amp; out) const
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGMultiGetByOffsetDatah"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;DFGRegisteredStructureSet.h&quot;
</ins><span class="cx"> #include &quot;DumpContext.h&quot;
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> #include &quot;StructureSet.h&quot;
</span><span class="lines">@@ -119,14 +120,14 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    MultiGetByOffsetCase(const StructureSet&amp; set, const GetByOffsetMethod&amp; method)
</del><ins>+    MultiGetByOffsetCase(const RegisteredStructureSet&amp; set, const GetByOffsetMethod&amp; method)
</ins><span class="cx">         : m_set(set)
</span><span class="cx">         , m_method(method)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StructureSet&amp; set() { return m_set; }
-    const StructureSet&amp; set() const { return m_set; }
</del><ins>+    RegisteredStructureSet&amp; set() { return m_set; }
+    const RegisteredStructureSet&amp; set() const { return m_set; }
</ins><span class="cx">     const GetByOffsetMethod&amp; method() const { return m_method; }
</span><span class="cx">     
</span><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span><span class="lines">@@ -133,7 +134,7 @@
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    StructureSet m_set;
</del><ins>+    RegisteredStructureSet m_set;
</ins><span class="cx">     GetByOffsetMethod m_method;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGNodecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -175,7 +175,7 @@
</span><span class="cx"> void Node::convertToPutStructureHint(Node* structure)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_op == PutStructure);
</span><del>-    ASSERT(structure-&gt;castConstant&lt;Structure*&gt;() == transition()-&gt;next);
</del><ins>+    ASSERT(structure-&gt;castConstant&lt;Structure*&gt;() == transition()-&gt;next.get());
</ins><span class="cx">     convertToPutHint(StructurePLoc, child1().node(), structure);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGNode.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -42,6 +42,8 @@
</span><span class="cx"> #include &quot;DFGNodeType.h&quot;
</span><span class="cx"> #include &quot;DFGObjectMaterializationData.h&quot;
</span><span class="cx"> #include &quot;DFGOpInfo.h&quot;
</span><ins>+#include &quot;DFGRegisteredStructure.h&quot;
+#include &quot;DFGRegisteredStructureSet.h&quot;
</ins><span class="cx"> #include &quot;DFGTransition.h&quot;
</span><span class="cx"> #include &quot;DFGUseKind.h&quot;
</span><span class="cx"> #include &quot;DFGVariableAccessData.h&quot;
</span><span class="lines">@@ -410,10 +412,10 @@
</span><span class="cx"> 
</span><span class="cx">     void remove();
</span><span class="cx"> 
</span><del>-    void convertToCheckStructure(StructureSet* set)
</del><ins>+    void convertToCheckStructure(RegisteredStructureSet* set)
</ins><span class="cx">     {
</span><span class="cx">         setOpAndDefaultFlags(CheckStructure);
</span><del>-        m_opInfo = set; 
</del><ins>+        m_opInfo = set;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void convertToCheckStructureImmediate(Node* structure)
</span><span class="lines">@@ -1614,10 +1616,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StructureSet&amp; structureSet()
</del><ins>+    const RegisteredStructureSet&amp; structureSet()
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(hasStructureSet());
</span><del>-        return *m_opInfo.as&lt;StructureSet*&gt;();
</del><ins>+        return *m_opInfo.as&lt;RegisteredStructureSet*&gt;();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasStructure()
</span><span class="lines">@@ -1632,10 +1634,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Structure* structure()
</del><ins>+    RegisteredStructure structure()
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(hasStructure());
</span><del>-        return m_opInfo.as&lt;Structure*&gt;();
</del><ins>+        return m_opInfo.asRegisteredStructure();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasStorageAccessData()
</span><span class="lines">@@ -2513,6 +2515,11 @@
</span><span class="cx">             u.int64 = 0;
</span><span class="cx">             u.constPointer = constPointer;
</span><span class="cx">         }
</span><ins>+        OpInfoWrapper(RegisteredStructure structure)
+        {
+            u.int64 = 0;
+            u.pointer = bitwise_cast&lt;void*&gt;(structure);
+        }
</ins><span class="cx">         OpInfoWrapper&amp; operator=(uint32_t int32)
</span><span class="cx">         {
</span><span class="cx">             u.int64 = 0;
</span><span class="lines">@@ -2542,6 +2549,12 @@
</span><span class="cx">             u.constPointer = constPointer;
</span><span class="cx">             return *this;
</span><span class="cx">         }
</span><ins>+        OpInfoWrapper&amp; operator=(RegisteredStructure structure)
+        {
+            u.int64 = 0;
+            u.pointer = bitwise_cast&lt;void*&gt;(structure);
+            return *this;
+        }
</ins><span class="cx">         template &lt;typename T&gt;
</span><span class="cx">         ALWAYS_INLINE auto as() const -&gt; typename std::enable_if&lt;std::is_pointer&lt;T&gt;::value &amp;&amp; !std::is_const&lt;typename std::remove_pointer&lt;T&gt;::type&gt;::value, T&gt;::type
</span><span class="cx">         {
</span><span class="lines">@@ -2562,6 +2575,11 @@
</span><span class="cx">         {
</span><span class="cx">             return u.int64;
</span><span class="cx">         }
</span><ins>+        ALWAYS_INLINE RegisteredStructure asRegisteredStructure() const
+        {
+            return bitwise_cast&lt;RegisteredStructure&gt;(u.pointer);
+        }
+
</ins><span class="cx">         union {
</span><span class="cx">             uint32_t int32;
</span><span class="cx">             uint64_t int64;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -186,7 +186,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Allocation&amp; setStructures(const StructureSet&amp; structures)
</del><ins>+    Allocation&amp; setStructures(const RegisteredStructureSet&amp; structures)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(hasStructures() &amp;&amp; !structures.isEmpty());
</span><span class="cx">         m_structures = structures;
</span><span class="lines">@@ -193,7 +193,7 @@
</span><span class="cx">         return *this;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Allocation&amp; mergeStructures(const StructureSet&amp; structures)
</del><ins>+    Allocation&amp; mergeStructures(const RegisteredStructureSet&amp; structures)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(hasStructures() || structures.isEmpty());
</span><span class="cx">         m_structures.merge(structures);
</span><span class="lines">@@ -200,7 +200,7 @@
</span><span class="cx">         return *this;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Allocation&amp; filterStructures(const StructureSet&amp; structures)
</del><ins>+    Allocation&amp; filterStructures(const RegisteredStructureSet&amp; structures)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(hasStructures());
</span><span class="cx">         m_structures.filter(structures);
</span><span class="lines">@@ -207,7 +207,7 @@
</span><span class="cx">         return *this;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    const StructureSet&amp; structures() const
</del><ins>+    const RegisteredStructureSet&amp; structures() const
</ins><span class="cx">     {
</span><span class="cx">         return m_structures;
</span><span class="cx">     }
</span><span class="lines">@@ -283,7 +283,7 @@
</span><span class="cx">         }
</span><span class="cx">         out.print(&quot;Allocation(&quot;);
</span><span class="cx">         if (!m_structures.isEmpty())
</span><del>-            out.print(inContext(m_structures, context));
</del><ins>+            out.print(inContext(m_structures.toStructureSet(), context));
</ins><span class="cx">         if (!m_fields.isEmpty()) {
</span><span class="cx">             if (!m_structures.isEmpty())
</span><span class="cx">                 out.print(&quot;, &quot;);
</span><span class="lines">@@ -296,7 +296,7 @@
</span><span class="cx">     Node* m_identifier; // This is the actual node that created the allocation
</span><span class="cx">     Kind m_kind;
</span><span class="cx">     HashMap&lt;PromotedLocationDescriptor, Node*&gt; m_fields;
</span><del>-    StructureSet m_structures;
</del><ins>+    RegisteredStructureSet m_structures;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class LocalHeap {
</span><span class="lines">@@ -832,7 +832,7 @@
</span><span class="cx">             target = &amp;m_heap.newAllocation(node, Allocation::Kind::Object);
</span><span class="cx">             target-&gt;setStructures(node-&gt;structure());
</span><span class="cx">             writes.add(
</span><del>-                StructurePLoc, LazyNode(m_graph.freeze(node-&gt;structure())));
</del><ins>+                StructurePLoc, LazyNode(m_graph.freeze(node-&gt;structure().get())));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case NewFunction:
</span><span class="lines">@@ -879,7 +879,7 @@
</span><span class="cx">         case PutStructure:
</span><span class="cx">             target = m_heap.onlyLocalAllocation(node-&gt;child1().node());
</span><span class="cx">             if (target &amp;&amp; target-&gt;isObjectAllocation()) {
</span><del>-                writes.add(StructurePLoc, LazyNode(m_graph.freeze(JSValue(node-&gt;transition()-&gt;next))));
</del><ins>+                writes.add(StructurePLoc, LazyNode(m_graph.freeze(JSValue(node-&gt;transition()-&gt;next.get()))));
</ins><span class="cx">                 target-&gt;setStructures(node-&gt;transition()-&gt;next);
</span><span class="cx">             } else
</span><span class="cx">                 m_heap.escape(node-&gt;child1().node());
</span><span class="lines">@@ -912,7 +912,7 @@
</span><span class="cx">             Allocation* allocation = m_heap.onlyLocalAllocation(node-&gt;child1().node());
</span><span class="cx">             if (allocation &amp;&amp; allocation-&gt;isObjectAllocation()) {
</span><span class="cx">                 MultiGetByOffsetData&amp; data = node-&gt;multiGetByOffsetData();
</span><del>-                StructureSet validStructures;
</del><ins>+                RegisteredStructureSet validStructures;
</ins><span class="cx">                 bool hasInvalidStructures = false;
</span><span class="cx">                 for (const auto&amp; multiGetByOffsetCase : data.cases) {
</span><span class="cx">                     if (!allocation-&gt;structures().overlaps(multiGetByOffsetCase.set()))
</span><span class="lines">@@ -1444,12 +1444,11 @@
</span><span class="cx">         switch (allocation.kind()) {
</span><span class="cx">         case Allocation::Kind::Object: {
</span><span class="cx">             ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
</span><del>-            StructureSet* set = m_graph.addStructureSet(allocation.structures());
</del><span class="cx"> 
</span><span class="cx">             return m_graph.addNode(
</span><span class="cx">                 allocation.identifier()-&gt;prediction(), Node::VarArg, MaterializeNewObject,
</span><span class="cx">                 where-&gt;origin.withSemantic(allocation.identifier()-&gt;origin.semantic),
</span><del>-                OpInfo(set), OpInfo(data), 0, 0);
</del><ins>+                OpInfo(m_graph.addStructureSet(allocation.structures())), OpInfo(data), 0, 0);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case Allocation::Kind::AsyncFunction:
</span><span class="lines">@@ -2103,7 +2102,7 @@
</span><span class="cx">         case NamedPropertyPLoc: {
</span><span class="cx">             Allocation&amp; allocation = m_heap.getAllocation(location.base());
</span><span class="cx"> 
</span><del>-            Vector&lt;Structure*&gt; structures;
</del><ins>+            Vector&lt;RegisteredStructure&gt; structures;
</ins><span class="cx">             structures.appendRange(allocation.structures().begin(), allocation.structures().end());
</span><span class="cx">             unsigned identifierNumber = location.info();
</span><span class="cx">             UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
</span><span class="lines">@@ -2111,7 +2110,7 @@
</span><span class="cx">             std::sort(
</span><span class="cx">                 structures.begin(),
</span><span class="cx">                 structures.end(),
</span><del>-                [uid] (Structure *a, Structure* b) -&gt; bool {
</del><ins>+                [uid] (RegisteredStructure a, RegisteredStructure b) -&gt; bool {
</ins><span class="cx">                     return a-&gt;getConcurrently(uid) &lt; b-&gt;getConcurrently(uid);
</span><span class="cx">                 });
</span><span class="cx"> 
</span><span class="lines">@@ -2142,7 +2141,7 @@
</span><span class="cx">             {
</span><span class="cx">                 PropertyOffset currentOffset = firstOffset;
</span><span class="cx">                 StructureSet currentSet;
</span><del>-                for (Structure* structure : structures) {
</del><ins>+                for (RegisteredStructure structure : structures) {
</ins><span class="cx">                     PropertyOffset offset = structure-&gt;getConcurrently(uid);
</span><span class="cx">                     if (offset != currentOffset) {
</span><span class="cx">                         // Because our analysis treats MultiPutByOffset like an escape, we only have to
</span><span class="lines">@@ -2155,7 +2154,7 @@
</span><span class="cx">                         currentOffset = offset;
</span><span class="cx">                         currentSet.clear();
</span><span class="cx">                     }
</span><del>-                    currentSet.add(structure);
</del><ins>+                    currentSet.add(structure.get());
</ins><span class="cx">                 }
</span><span class="cx">                 data-&gt;variants.append(
</span><span class="cx">                     PutByIdVariant::replace(currentSet, currentOffset, InferredType::Top));
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGOpInfoh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOpInfo.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOpInfo.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOpInfo.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 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">@@ -25,6 +25,8 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;DFGRegisteredStructure.h&quot;
+#include &quot;HeapCell.h&quot;
</ins><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="lines">@@ -42,8 +44,17 @@
</span><span class="cx"> #if OS(DARWIN)
</span><span class="cx">     explicit OpInfo(uintptr_t value) : m_value(static_cast&lt;uint64_t&gt;(value)) { }
</span><span class="cx"> #endif
</span><del>-    explicit OpInfo(void* value) : m_value(static_cast&lt;uint64_t&gt;(reinterpret_cast&lt;uintptr_t&gt;(value))) { }
-    explicit OpInfo(const void* value) : m_value(static_cast&lt;uint64_t&gt;(reinterpret_cast&lt;uintptr_t&gt;(value))) { }
</del><ins>+    explicit OpInfo(RegisteredStructure structure) : m_value(static_cast&lt;uint64_t&gt;(bitwise_cast&lt;uintptr_t&gt;(structure))) { }
+
+
+    template &lt;typename T&gt;
+    explicit OpInfo(T* ptr)
+    {
+        static_assert(!std::is_base_of&lt;HeapCell, T&gt;::value, &quot;To make an OpInfo with a cell in it, the cell must be registered or frozen.&quot;);
+        static_assert(!std::is_base_of&lt;StructureSet, T&gt;::value, &quot;To make an OpInfo with a structure set in, make sure to use RegisteredStructureSet.&quot;);
+        m_value = static_cast&lt;uint64_t&gt;(reinterpret_cast&lt;uintptr_t&gt;(ptr));
+    }
+
</ins><span class="cx">     uint64_t m_value;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGPlan.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGPlan.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGPlan.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -67,7 +67,6 @@
</span><span class="cx"> #include &quot;DFGStoreBarrierClusteringPhase.h&quot;
</span><span class="cx"> #include &quot;DFGStoreBarrierInsertionPhase.h&quot;
</span><span class="cx"> #include &quot;DFGStrengthReductionPhase.h&quot;
</span><del>-#include &quot;DFGStructureRegistrationPhase.h&quot;
</del><span class="cx"> #include &quot;DFGTierUpCheckInjectionPhase.h&quot;
</span><span class="cx"> #include &quot;DFGTypeCheckHoistingPhase.h&quot;
</span><span class="cx"> #include &quot;DFGUnificationPhase.h&quot;
</span><span class="lines">@@ -311,7 +310,6 @@
</span><span class="cx">     RUN_PHASE(performBackwardsPropagation);
</span><span class="cx">     RUN_PHASE(performPredictionPropagation);
</span><span class="cx">     RUN_PHASE(performFixup);
</span><del>-    RUN_PHASE(performStructureRegistration);
</del><span class="cx">     RUN_PHASE(performInvalidationPointInjection);
</span><span class="cx">     RUN_PHASE(performTypeCheckHoisting);
</span><span class="cx">     
</span><span class="lines">@@ -608,6 +606,11 @@
</span><span class="cx">             trackedReferences.add(reference.get());
</span><span class="cx">         for (WriteBarrier&lt;Unknown&gt;&amp; constant : codeBlock-&gt;constants())
</span><span class="cx">             trackedReferences.add(constant.get());
</span><ins>+
+        for (auto* inlineCallFrame : *inlineCallFrames) {
+            ASSERT(inlineCallFrame-&gt;baselineCodeBlock.get());
+            trackedReferences.add(inlineCallFrame-&gt;baselineCodeBlock.get());
+        }
</ins><span class="cx">         
</span><span class="cx">         // Check that any other references that we have anywhere in the JITCode are also
</span><span class="cx">         // tracked either strongly or weakly.
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGRegisteredStructurehfromrev211278branchessafari603branchSourceJavaScriptCoredfgDFGStructureRegistrationPhaseh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h (from rev 211278, branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h) (0 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;Structure.h&quot;
+#include &quot;StructureSet.h&quot;
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class RegisteredStructure {
+public:
+    RegisteredStructure() = default;
+
+    ALWAYS_INLINE Structure* get() const { return m_structure; }
+    Structure* operator-&gt;() const { return get(); }
+
+    bool operator==(const RegisteredStructure&amp; other) const
+    {
+        return get() == other.get();
+    }
+
+    bool operator!=(const RegisteredStructure&amp; other) const
+    {
+        return !(*this == other);
+    }
+
+    explicit operator bool() const
+    {
+        return !!get();
+    }
+
+private:
+    friend class Graph;
+
+    RegisteredStructure(Structure* structure)
+        : m_structure(structure)
+    {
+        ASSERT(structure);
+    }
+
+    static RegisteredStructure createPrivate(Structure* structure)
+    {
+        return RegisteredStructure(structure);
+    }
+
+    Structure* m_structure { nullptr };
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGRegisteredStructureSetcppfromrev211278branchessafari603branchSourceJavaScriptCorebytecodeStructureSetcpp"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp (from rev 211278, branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.cpp) (0 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;DFGRegisteredStructureSet.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGAbstractValue.h&quot;
+#include &quot;TrackedReferences.h&quot;
+
+namespace JSC { namespace DFG {
+
+void RegisteredStructureSet::filter(const DFG::StructureAbstractValue&amp; other)
+{
+    genericFilter(
+        [&amp;] (RegisteredStructure structure) -&gt; bool {
+            return other.contains(structure); 
+        });
+}
+
+void RegisteredStructureSet::filter(SpeculatedType type)
+{
+    genericFilter(
+        [&amp;] (RegisteredStructure structure) -&gt; bool {
+            return type &amp; speculationFromStructure(structure.get());
+        });
+}
+
+void RegisteredStructureSet::filterArrayModes(ArrayModes arrayModes)
+{
+    genericFilter(
+        [&amp;] (RegisteredStructure structure) -&gt; bool {
+            return arrayModes &amp; arrayModeFromStructure(structure.get());
+        });
+}
+
+void RegisteredStructureSet::filter(const DFG::AbstractValue&amp; other)
+{
+    filter(other.m_structure);
+    filter(other.m_type);
+    filterArrayModes(other.m_arrayModes);
+}
+
+SpeculatedType RegisteredStructureSet::speculationFromStructures() const
+{
+    SpeculatedType result = SpecNone;
+    forEach(
+        [&amp;] (RegisteredStructure structure) {
+            mergeSpeculation(result, speculationFromStructure(structure.get()));
+        });
+    return result;
+}
+
+ArrayModes RegisteredStructureSet::arrayModesFromStructures() const
+{
+    ArrayModes result = 0;
+    forEach(
+        [&amp;] (RegisteredStructure structure) {
+            mergeArrayModes(result, asArrayModes(structure-&gt;indexingType()));
+        });
+    return result;
+}
+
+void RegisteredStructureSet::validateReferences(const TrackedReferences&amp; trackedReferences) const
+{
+    // The type system should help us here, but protect people from getting that wrong using bitwise_cast or something crazy.
+    forEach(
+        [&amp;] (RegisteredStructure structure) {
+            trackedReferences.check(structure.get());
+        });
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGRegisteredStructureSethfromrev211278branchessafari603branchSourceJavaScriptCorebytecodeStructureSeth"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h (from rev 211278, branches/safari-603-branch/Source/JavaScriptCore/bytecode/StructureSet.h) (0 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGRegisteredStructure.h&quot;
+#include &quot;StructureSet.h&quot;
+#include &lt;wtf/TinyPtrSet.h&gt;
+
+namespace JSC {
+
+class TrackedReferences;
+
+namespace DFG {
+
+struct AbstractValue;
+class StructureAbstractValue;
+
+class RegisteredStructureSet : public TinyPtrSet&lt;RegisteredStructure&gt; {
+public:
+
+    RegisteredStructureSet()
+    { }
+    
+    RegisteredStructureSet(RegisteredStructure structure)
+        : TinyPtrSet(structure)
+    {
+    }
+    
+    ALWAYS_INLINE RegisteredStructureSet(const RegisteredStructureSet&amp; other)
+        : TinyPtrSet(other)
+    {
+    }
+    
+    RegisteredStructure onlyStructure() const
+    {
+        return onlyEntry();
+    }
+
+    StructureSet toStructureSet() const
+    {
+        StructureSet result;
+        forEach([&amp;] (RegisteredStructure structure) { result.add(structure.get()); });
+        return result;
+    }
+
+    void filter(const DFG::StructureAbstractValue&amp;);
+    void filter(SpeculatedType);
+    void filterArrayModes(ArrayModes);
+    void filter(const DFG::AbstractValue&amp;);
+    
+    SpeculatedType speculationFromStructures() const;
+    ArrayModes arrayModesFromStructures() const;
+
+    void validateReferences(const TrackedReferences&amp;) const;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -425,7 +425,7 @@
</span><span class="cx">     case AllocatePropertyStorage:
</span><span class="cx">     case ReallocatePropertyStorage:
</span><span class="cx">         return state.forNode(node-&gt;child1()).m_structure.isSubsetOf(
</span><del>-            StructureSet(node-&gt;transition()-&gt;previous));
</del><ins>+            RegisteredStructureSet(node-&gt;transition()-&gt;previous));
</ins><span class="cx">         
</span><span class="cx">     case GetByOffset:
</span><span class="cx">     case GetGetterSetterByOffset:
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SpeculativeJIT::emitAllocateRawObject(GPRReg resultGPR, Structure* structure, GPRReg storageGPR, unsigned numElements, unsigned vectorLength)
</del><ins>+void SpeculativeJIT::emitAllocateRawObject(GPRReg resultGPR, RegisteredStructure structure, GPRReg storageGPR, unsigned numElements, unsigned vectorLength)
</ins><span class="cx"> {
</span><span class="cx">     IndexingType indexingType = structure-&gt;indexingType();
</span><span class="cx">     bool hasIndexingHeader = hasIndexedProperties(indexingType);
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">     GPRReg scratch2GPR = scratch2.gpr();
</span><span class="cx"> 
</span><span class="cx">     ASSERT(vectorLength &gt;= numElements);
</span><del>-    vectorLength = Butterfly::optimalContiguousVectorLength(structure, vectorLength);
</del><ins>+    vectorLength = Butterfly::optimalContiguousVectorLength(structure.get(), vectorLength);
</ins><span class="cx">     
</span><span class="cx">     JITCompiler::JumpList slowCases;
</span><span class="cx"> 
</span><span class="lines">@@ -195,7 +195,7 @@
</span><span class="cx">                 calleeGPR);
</span><span class="cx">         } else {
</span><span class="cx">             m_jit.move(
</span><del>-                TrustedImmPtr(origin.inlineCallFrame-&gt;calleeRecovery.constant().asCell()),
</del><ins>+                TrustedImmPtr::weakPointer(m_jit.graph(), origin.inlineCallFrame-&gt;calleeRecovery.constant().asCell()),
</ins><span class="cx">                 calleeGPR);
</span><span class="cx">         }
</span><span class="cx">     } else
</span><span class="lines">@@ -648,7 +648,8 @@
</span><span class="cx">         m_jit.move(TrustedImm32(plan.node()-&gt;asBoolean()), plan.gpr());
</span><span class="cx">         break;
</span><span class="cx">     case SetCellConstant:
</span><del>-        m_jit.move(TrustedImmPtr(plan.node()-&gt;asCell()), plan.gpr());
</del><ins>+        ASSERT(plan.node()-&gt;constant()-&gt;value().isCell());
+        m_jit.move(TrustedImmPtr(plan.node()-&gt;constant()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     case SetTrustedJSConstant:
</span><span class="lines">@@ -877,7 +878,7 @@
</span><span class="cx">         m_jit.branchPtr(
</span><span class="cx">             MacroAssembler::NotEqual,
</span><span class="cx">             MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()),
</span><del>-            MacroAssembler::TrustedImmPtr(expectedClassInfo)));
</del><ins>+            TrustedImmPtr(expectedClassInfo)));
</ins><span class="cx">     
</span><span class="cx">     noResult(m_currentNode);
</span><span class="cx"> }
</span><span class="lines">@@ -2057,7 +2058,7 @@
</span><span class="cx">     cont8Bit.link(&amp;m_jit);
</span><span class="cx"> 
</span><span class="cx">     m_jit.lshift32(MacroAssembler::TrustedImm32(sizeof(void*) == 4 ? 2 : 3), scratchReg);
</span><del>-    m_jit.addPtr(MacroAssembler::TrustedImmPtr(m_jit.vm()-&gt;smallStrings.singleCharacterStrings()), scratchReg);
</del><ins>+    m_jit.addPtr(TrustedImmPtr(m_jit.vm()-&gt;smallStrings.singleCharacterStrings()), scratchReg);
</ins><span class="cx">     m_jit.loadPtr(scratchReg, scratchReg);
</span><span class="cx"> 
</span><span class="cx">     addSlowPathGenerator(
</span><span class="lines">@@ -2148,7 +2149,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::JumpList slowCases;
</span><span class="cx">     slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, TrustedImm32(0xff)));
</span><del>-    m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.vm()-&gt;smallStrings.singleCharacterStrings()), smallStringsReg);
</del><ins>+    m_jit.move(TrustedImmPtr(m_jit.vm()-&gt;smallStrings.singleCharacterStrings()), smallStringsReg);
</ins><span class="cx">     m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, propertyReg, MacroAssembler::ScalePtr, 0), scratchReg);
</span><span class="cx"> 
</span><span class="cx">     slowCases.append(m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
</span><span class="lines">@@ -2470,7 +2471,7 @@
</span><span class="cx">             JITCompiler::Jump isUndefined = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueUndefined));
</span><span class="cx"> 
</span><span class="cx">             static const double zero = 0;
</span><del>-            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;zero), resultFPR);
</del><ins>+            m_jit.loadDouble(TrustedImmPtr(&amp;zero), resultFPR);
</ins><span class="cx"> 
</span><span class="cx">             JITCompiler::Jump isNull = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueNull));
</span><span class="cx">             done.append(isNull);
</span><span class="lines">@@ -2480,13 +2481,13 @@
</span><span class="cx"> 
</span><span class="cx">             JITCompiler::Jump isFalse = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueFalse));
</span><span class="cx">             static const double one = 1;
</span><del>-            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;one), resultFPR);
</del><ins>+            m_jit.loadDouble(TrustedImmPtr(&amp;one), resultFPR);
</ins><span class="cx">             done.append(m_jit.jump());
</span><span class="cx">             done.append(isFalse);
</span><span class="cx"> 
</span><span class="cx">             isUndefined.link(&amp;m_jit);
</span><span class="cx">             static const double NaN = PNaN;
</span><del>-            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;NaN), resultFPR);
</del><ins>+            m_jit.loadDouble(TrustedImmPtr(&amp;NaN), resultFPR);
</ins><span class="cx">             done.append(m_jit.jump());
</span><span class="cx"> 
</span><span class="cx">             isNumber.link(&amp;m_jit);
</span><span class="lines">@@ -2519,7 +2520,7 @@
</span><span class="cx">             JITCompiler::Jump isUndefined = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::UndefinedTag));
</span><span class="cx"> 
</span><span class="cx">             static const double zero = 0;
</span><del>-            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;zero), resultFPR);
</del><ins>+            m_jit.loadDouble(TrustedImmPtr(&amp;zero), resultFPR);
</ins><span class="cx"> 
</span><span class="cx">             JITCompiler::Jump isNull = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::NullTag));
</span><span class="cx">             done.append(isNull);
</span><span class="lines">@@ -2528,13 +2529,13 @@
</span><span class="cx"> 
</span><span class="cx">             JITCompiler::Jump isFalse = m_jit.branchTest32(JITCompiler::Zero, op1PayloadGPR, TrustedImm32(1));
</span><span class="cx">             static const double one = 1;
</span><del>-            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;one), resultFPR);
</del><ins>+            m_jit.loadDouble(TrustedImmPtr(&amp;one), resultFPR);
</ins><span class="cx">             done.append(m_jit.jump());
</span><span class="cx">             done.append(isFalse);
</span><span class="cx"> 
</span><span class="cx">             isUndefined.link(&amp;m_jit);
</span><span class="cx">             static const double NaN = PNaN;
</span><del>-            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;NaN), resultFPR);
</del><ins>+            m_jit.loadDouble(TrustedImmPtr(&amp;NaN), resultFPR);
</ins><span class="cx">             done.append(m_jit.jump());
</span><span class="cx"> 
</span><span class="cx">             isNumber.link(&amp;m_jit);
</span><span class="lines">@@ -2649,12 +2650,12 @@
</span><span class="cx">     static const double zero = 0;
</span><span class="cx">     static const double byteMax = 255;
</span><span class="cx">     static const double half = 0.5;
</span><del>-    jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;zero), scratch);
</del><ins>+    jit.loadDouble(JITCompiler::TrustedImmPtr(&amp;zero), scratch);
</ins><span class="cx">     MacroAssembler::Jump tooSmall = jit.branchDouble(MacroAssembler::DoubleLessThanOrEqualOrUnordered, source, scratch);
</span><del>-    jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;byteMax), scratch);
</del><ins>+    jit.loadDouble(JITCompiler::TrustedImmPtr(&amp;byteMax), scratch);
</ins><span class="cx">     MacroAssembler::Jump tooBig = jit.branchDouble(MacroAssembler::DoubleGreaterThan, source, scratch);
</span><span class="cx">     
</span><del>-    jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;half), scratch);
</del><ins>+    jit.loadDouble(JITCompiler::TrustedImmPtr(&amp;half), scratch);
</ins><span class="cx">     // FIXME: This should probably just use a floating point round!
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=72054
</span><span class="cx">     jit.addDouble(source, scratch);
</span><span class="lines">@@ -3902,7 +3903,7 @@
</span><span class="cx">     MarkedAllocator* markedAllocator = subspaceFor&lt;JSString&gt;(*m_jit.vm())-&gt;allocatorFor(sizeof(JSRopeString));
</span><span class="cx">     RELEASE_ASSERT(markedAllocator);
</span><span class="cx">     m_jit.move(TrustedImmPtr(markedAllocator), allocatorGPR);
</span><del>-    emitAllocateJSCell(resultGPR, markedAllocator, allocatorGPR, TrustedImmPtr(m_jit.vm()-&gt;stringStructure.get()), scratchGPR, slowPath);
</del><ins>+    emitAllocateJSCell(resultGPR, markedAllocator, allocatorGPR, TrustedImmPtr(m_jit.graph().registerStructure(m_jit.vm()-&gt;stringStructure.get())), scratchGPR, slowPath);
</ins><span class="cx">         
</span><span class="cx">     m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(resultGPR, JSString::offsetOfValue()));
</span><span class="cx">     for (unsigned i = 0; i &lt; numOpGPRs; ++i)
</span><span class="lines">@@ -5099,7 +5100,7 @@
</span><span class="cx">                 FPRReg resultFPR = result.fpr();
</span><span class="cx">                 if (producesInteger(node-&gt;arithRoundingMode()) &amp;&amp; !shouldCheckNegativeZero(node-&gt;arithRoundingMode())) {
</span><span class="cx">                     static const double halfConstant = 0.5;
</span><del>-                    m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;halfConstant), resultFPR);
</del><ins>+                    m_jit.loadDouble(TrustedImmPtr(&amp;halfConstant), resultFPR);
</ins><span class="cx">                     m_jit.addDouble(valueFPR, resultFPR);
</span><span class="cx">                     m_jit.floorDouble(resultFPR, resultFPR);
</span><span class="cx">                 } else {
</span><span class="lines">@@ -5111,11 +5112,11 @@
</span><span class="cx">                     FPRTemporary scratch(this);
</span><span class="cx">                     FPRReg scratchFPR = scratch.fpr();
</span><span class="cx">                     static const double halfConstant = 0.5;
</span><del>-                    m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;halfConstant), scratchFPR);
</del><ins>+                    m_jit.loadDouble(TrustedImmPtr(&amp;halfConstant), scratchFPR);
</ins><span class="cx"> 
</span><span class="cx">                     JITCompiler::Jump shouldUseCeiled = m_jit.branchDouble(JITCompiler::DoubleLessThanOrEqual, realPartFPR, scratchFPR);
</span><span class="cx">                     static const double oneConstant = -1.0;
</span><del>-                    m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;oneConstant), scratchFPR);
</del><ins>+                    m_jit.loadDouble(TrustedImmPtr(&amp;oneConstant), scratchFPR);
</ins><span class="cx">                     m_jit.addDouble(scratchFPR, resultFPR);
</span><span class="cx">                     shouldUseCeiled.link(&amp;m_jit);
</span><span class="cx">                 }
</span><span class="lines">@@ -6355,12 +6356,12 @@
</span><span class="cx">     noResult(node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template &lt;typename ClassType&gt; void SpeculativeJIT::compileNewFunctionCommon(GPRReg resultGPR, Structure* structure, GPRReg scratch1GPR, GPRReg scratch2GPR, GPRReg scopeGPR, MacroAssembler::JumpList&amp; slowPath, size_t size, FunctionExecutable* executable, ptrdiff_t offsetOfScopeChain, ptrdiff_t offsetOfExecutable, ptrdiff_t offsetOfRareData)
</del><ins>+template &lt;typename ClassType&gt; void SpeculativeJIT::compileNewFunctionCommon(GPRReg resultGPR, RegisteredStructure structure, GPRReg scratch1GPR, GPRReg scratch2GPR, GPRReg scopeGPR, MacroAssembler::JumpList&amp; slowPath, size_t size, FunctionExecutable* executable, ptrdiff_t offsetOfScopeChain, ptrdiff_t offsetOfExecutable, ptrdiff_t offsetOfRareData)
</ins><span class="cx"> {
</span><span class="cx">     emitAllocateJSObjectWithKnownSize&lt;ClassType&gt;(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR, slowPath, size);
</span><span class="cx">     
</span><span class="cx">     m_jit.storePtr(scopeGPR, JITCompiler::Address(resultGPR, offsetOfScopeChain));
</span><del>-    m_jit.storePtr(TrustedImmPtr(executable), JITCompiler::Address(resultGPR, offsetOfExecutable));
</del><ins>+    m_jit.storePtr(TrustedImmPtr::weakPointer(m_jit.graph(), executable), JITCompiler::Address(resultGPR, offsetOfExecutable));
</ins><span class="cx">     m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(resultGPR, offsetOfRareData));
</span><span class="cx">     
</span><span class="cx">     m_jit.mutatorFence();
</span><span class="lines">@@ -6393,10 +6394,10 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Structure* structure =
</del><ins>+    RegisteredStructure structure = m_jit.graph().registerStructure(
</ins><span class="cx">         nodeType == NewGeneratorFunction ? m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;generatorFunctionStructure() :
</span><span class="cx">         nodeType == NewAsyncFunction ? m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;asyncFunctionStructure() :
</span><del>-        m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;functionStructure();
</del><ins>+        m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;functionStructure());
</ins><span class="cx">     
</span><span class="cx">     GPRTemporary result(this);
</span><span class="cx">     GPRTemporary scratch1(this);
</span><span class="lines">@@ -6512,8 +6513,8 @@
</span><span class="cx"> void SpeculativeJIT::compileCreateActivation(Node* node)
</span><span class="cx"> {
</span><span class="cx">     SymbolTable* table = node-&gt;castOperand&lt;SymbolTable*&gt;();
</span><del>-    Structure* structure = m_jit.graph().globalObjectFor(
-        node-&gt;origin.semantic)-&gt;activationStructure();
</del><ins>+    RegisteredStructure structure = m_jit.graph().registerStructure(m_jit.graph().globalObjectFor(
+        node-&gt;origin.semantic)-&gt;activationStructure());
</ins><span class="cx">         
</span><span class="cx">     SpeculateCellOperand scope(this, node-&gt;child1());
</span><span class="cx">     GPRReg scopeGPR = scope.gpr();
</span><span class="lines">@@ -6554,7 +6555,7 @@
</span><span class="cx">     // activation must be young.
</span><span class="cx">     m_jit.storePtr(scopeGPR, JITCompiler::Address(resultGPR, JSScope::offsetOfNext()));
</span><span class="cx">     m_jit.storePtr(
</span><del>-        TrustedImmPtr(table),
</del><ins>+        TrustedImmPtr(node-&gt;cellOperand()),
</ins><span class="cx">         JITCompiler::Address(resultGPR, JSLexicalEnvironment::offsetOfSymbolTable()));
</span><span class="cx">         
</span><span class="cx">     // Must initialize all members to undefined or the TDZ empty value.
</span><span class="lines">@@ -6617,8 +6618,8 @@
</span><span class="cx">         m_jit.sub32(TrustedImm32(1), lengthGPR);
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    Structure* structure =
-        m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;directArgumentsStructure();
</del><ins>+    RegisteredStructure structure =
+        m_jit.graph().registerStructure(m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;directArgumentsStructure());
</ins><span class="cx">         
</span><span class="cx">     // Use a different strategy for allocating the object depending on whether we know its
</span><span class="cx">     // size statically.
</span><span class="lines">@@ -6680,8 +6681,8 @@
</span><span class="cx">                 scratch1GPR);
</span><span class="cx">         } else {
</span><span class="cx">             m_jit.move(
</span><del>-                TrustedImmPtr(
-                    node-&gt;origin.semantic.inlineCallFrame-&gt;calleeRecovery.constant().asCell()),
</del><ins>+                TrustedImmPtr::weakPointer(
+                    m_jit.graph(), node-&gt;origin.semantic.inlineCallFrame-&gt;calleeRecovery.constant().asCell()),
</ins><span class="cx">                 scratch1GPR);
</span><span class="cx">         }
</span><span class="cx">     } else
</span><span class="lines">@@ -6797,7 +6798,7 @@
</span><span class="cx">     m_jit.setupArgument(
</span><span class="cx">         1, [&amp;] (GPRReg destGPR) {
</span><span class="cx">             m_jit.move(
</span><del>-                TrustedImmPtr(m_jit.globalObjectFor(node-&gt;origin.semantic)-&gt;scopedArgumentsStructure()),
</del><ins>+                TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.globalObjectFor(node-&gt;origin.semantic)-&gt;scopedArgumentsStructure()),
</ins><span class="cx">                 destGPR);
</span><span class="cx">         });
</span><span class="cx">     m_jit.setupArgument(0, [&amp;] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
</span><span class="lines">@@ -6824,8 +6825,8 @@
</span><span class="cx">     m_jit.setupArgument(
</span><span class="cx">         1, [&amp;] (GPRReg destGPR) {
</span><span class="cx">             m_jit.move(
</span><del>-                TrustedImmPtr(
-                    m_jit.globalObjectFor(node-&gt;origin.semantic)-&gt;clonedArgumentsStructure()),
</del><ins>+                TrustedImmPtr::weakPointer(
+                    m_jit.graph(), m_jit.globalObjectFor(node-&gt;origin.semantic)-&gt;clonedArgumentsStructure()),
</ins><span class="cx">                 destGPR);
</span><span class="cx">         });
</span><span class="cx">     m_jit.setupArgument(0, [&amp;] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
</span><span class="lines">@@ -6948,7 +6949,7 @@
</span><span class="cx">         m_jit.lshift32(TrustedImm32(3), scratch1GPR);
</span><span class="cx">         m_jit.add32(TrustedImm32(JSFixedArray::offsetOfData()), scratch1GPR);
</span><span class="cx"> 
</span><del>-        m_jit.emitAllocateVariableSizedCell&lt;JSFixedArray&gt;(resultGPR, TrustedImmPtr(m_jit.graph().m_vm.fixedArrayStructure.get()), scratch1GPR, scratch1GPR, scratch2GPR, slowPath);
</del><ins>+        m_jit.emitAllocateVariableSizedCell&lt;JSFixedArray&gt;(resultGPR, TrustedImmPtr(m_jit.graph().registerStructure(m_jit.graph().m_vm.fixedArrayStructure.get())), scratch1GPR, scratch1GPR, scratch2GPR, slowPath);
</ins><span class="cx">         m_jit.store32(lengthGPR, MacroAssembler::Address(resultGPR, JSFixedArray::offsetOfSize()));
</span><span class="cx"> 
</span><span class="cx">         m_jit.loadPtr(MacroAssembler::Address(argument, JSObject::butterflyOffset()), scratch1GPR);
</span><span class="lines">@@ -7265,17 +7266,17 @@
</span><span class="cx">         // to ensure the incoming array is one to be one of the original array structures
</span><span class="cx">         // with one of the following indexing shapes: Int32, Contiguous, Double. Therefore,
</span><span class="cx">         // we're a double array here.
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithDouble)), tempValue);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithDouble))), tempValue);
</ins><span class="cx">         emitMoveEmptyValue(jsNaN());
</span><span class="cx">         done.append(m_jit.jump());
</span><span class="cx"> 
</span><span class="cx">         isContiguous.link(&amp;m_jit);
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous)), tempValue);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous))), tempValue);
</ins><span class="cx">         emitMoveEmptyValue(JSValue());
</span><span class="cx">         done.append(m_jit.jump());
</span><span class="cx"> 
</span><span class="cx">         isInt32.link(&amp;m_jit);
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithInt32)), tempValue);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithInt32))), tempValue);
</ins><span class="cx">         emitMoveEmptyValue(JSValue());
</span><span class="cx"> 
</span><span class="cx">         done.link(&amp;m_jit);
</span><span class="lines">@@ -7455,7 +7456,7 @@
</span><span class="cx">     m_jit.emitTypeOf(
</span><span class="cx">         valueRegs, resultGPR,
</span><span class="cx">         [&amp;] (TypeofType type, bool fallsThrough) {
</span><del>-            m_jit.move(TrustedImmPtr(m_jit.vm()-&gt;smallStrings.typeString(type)), resultGPR);
</del><ins>+            m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.vm()-&gt;smallStrings.typeString(type)), resultGPR);
</ins><span class="cx">             if (!fallsThrough)
</span><span class="cx">                 done.append(m_jit.jump());
</span><span class="cx">         },
</span><span class="lines">@@ -7579,7 +7580,7 @@
</span><span class="cx">     GPRReg scratchGPR2 = scratch2.gpr();
</span><span class="cx">     GPRReg scratchGPR3 = scratch3.gpr();
</span><span class="cx">         
</span><del>-    m_jit.move(JITCompiler::TrustedImmPtr(allocator), scratchGPR2);
</del><ins>+    m_jit.move(TrustedImmPtr(allocator), scratchGPR2);
</ins><span class="cx">     JITCompiler::JumpList slowPath;
</span><span class="cx">     m_jit.emitAllocate(scratchGPR1, allocator, scratchGPR2, scratchGPR3, slowPath);
</span><span class="cx">     m_jit.addPtr(JITCompiler::TrustedImm32(size + sizeof(IndexingHeader)), scratchGPR1);
</span><span class="lines">@@ -7627,7 +7628,7 @@
</span><span class="cx">     GPRReg scratchGPR3 = scratch3.gpr();
</span><span class="cx">     
</span><span class="cx">     JITCompiler::JumpList slowPath;
</span><del>-    m_jit.move(JITCompiler::TrustedImmPtr(allocator), scratchGPR2);
</del><ins>+    m_jit.move(TrustedImmPtr(allocator), scratchGPR2);
</ins><span class="cx">     m_jit.emitAllocate(scratchGPR1, allocator, scratchGPR2, scratchGPR3, slowPath);
</span><span class="cx">     
</span><span class="cx">     m_jit.addPtr(JITCompiler::TrustedImm32(newSize + sizeof(IndexingHeader)), scratchGPR1);
</span><span class="lines">@@ -7856,10 +7857,10 @@
</span><span class="cx">         GPRReg resultGPR = result.gpr();
</span><span class="cx"> 
</span><span class="cx">         m_jit.load32(JITCompiler::Address(op1GPR, JSCell::structureIDOffset()), resultGPR);
</span><del>-        JITCompiler::Jump isString = m_jit.branchStructure(
</del><ins>+        JITCompiler::Jump isString = m_jit.branchWeakStructure(
</ins><span class="cx">             JITCompiler::Equal,
</span><span class="cx">             resultGPR,
</span><del>-            m_jit.vm()-&gt;stringStructure.get());
</del><ins>+            m_jit.graph().registerStructure(m_jit.vm()-&gt;stringStructure.get()));
</ins><span class="cx"> 
</span><span class="cx">         speculateStringObjectForStructure(node-&gt;child1(), resultGPR);
</span><span class="cx">         
</span><span class="lines">@@ -7955,8 +7956,8 @@
</span><span class="cx"> {
</span><span class="cx">     JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">     TypedArrayType type = node-&gt;typedArrayType();
</span><del>-    Structure* structure = globalObject-&gt;typedArrayStructureConcurrently(type);
-    RELEASE_ASSERT(structure);
</del><ins>+    RegisteredStructure structure = m_jit.graph().registerStructure(globalObject-&gt;typedArrayStructureConcurrently(type));
+    RELEASE_ASSERT(structure.get());
</ins><span class="cx">     
</span><span class="cx">     SpeculateInt32Operand size(this, node-&gt;child1());
</span><span class="cx">     GPRReg sizeGPR = size.gpr();
</span><span class="lines">@@ -8400,10 +8401,10 @@
</span><span class="cx">     GPRReg structureIDGPR = structureID.gpr();
</span><span class="cx"> 
</span><span class="cx">     m_jit.load32(JITCompiler::Address(gpr, JSCell::structureIDOffset()), structureIDGPR); 
</span><del>-    JITCompiler::Jump isString = m_jit.branchStructure(
</del><ins>+    JITCompiler::Jump isString = m_jit.branchWeakStructure(
</ins><span class="cx">         JITCompiler::Equal,
</span><span class="cx">         structureIDGPR, 
</span><del>-        m_jit.vm()-&gt;stringStructure.get());
</del><ins>+        m_jit.graph().registerStructure(m_jit.vm()-&gt;stringStructure.get()));
</ins><span class="cx">     
</span><span class="cx">     speculateStringObjectForStructure(edge, structureIDGPR);
</span><span class="cx">     
</span><span class="lines">@@ -9268,8 +9269,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileMaterializeNewObject(Node* node)
</span><span class="cx"> {
</span><del>-    Structure* structure = node-&gt;structureSet()[0];
-    ASSERT(m_jit.graph().varArgChild(node, 0)-&gt;dynamicCastConstant&lt;Structure*&gt;() == structure);
</del><ins>+    RegisteredStructure structure = node-&gt;structureSet().at(0);
+    ASSERT(m_jit.graph().varArgChild(node, 0)-&gt;dynamicCastConstant&lt;Structure*&gt;() == structure.get());
</ins><span class="cx"> 
</span><span class="cx">     ObjectMaterializationData&amp; data = node-&gt;objectMaterializationData();
</span><span class="cx">         
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -75,7 +75,6 @@
</span><span class="cx"> private:
</span><span class="cx">     typedef JITCompiler::TrustedImm32 TrustedImm32;
</span><span class="cx">     typedef JITCompiler::Imm32 Imm32;
</span><del>-    typedef JITCompiler::TrustedImmPtr TrustedImmPtr;
</del><span class="cx">     typedef JITCompiler::ImmPtr ImmPtr;
</span><span class="cx">     typedef JITCompiler::TrustedImm64 TrustedImm64;
</span><span class="cx">     typedef JITCompiler::Imm64 Imm64;
</span><span class="lines">@@ -112,6 +111,64 @@
</span><span class="cx">     SpeculativeJIT(JITCompiler&amp;);
</span><span class="cx">     ~SpeculativeJIT();
</span><span class="cx"> 
</span><ins>+    struct TrustedImmPtr {
+        template &lt;typename T&gt;
+        explicit TrustedImmPtr(T* value)
+            : m_value(value)
+        {
+            static_assert(!std::is_base_of&lt;HeapCell, T&gt;::value, &quot;To use a GC pointer, the graph must be aware of it. Use SpeculativeJIT::TrustedImmPtr::weakPointer instead.&quot;);
+        }
+
+        explicit TrustedImmPtr(RegisteredStructure structure)
+            : m_value(structure.get())
+        { }
+        
+        // This is only here so that TrustedImmPtr(0) does not confuse the C++
+        // overload handling rules.
+        explicit TrustedImmPtr(int value)
+            : m_value(value)
+        {
+            ASSERT(!value);
+        }
+
+        explicit TrustedImmPtr(std::nullptr_t)
+            : m_value(0)
+        { }
+
+        explicit TrustedImmPtr(FrozenValue* value)
+        {
+            RELEASE_ASSERT(value-&gt;value().isCell());
+            m_value = MacroAssembler::TrustedImmPtr(value-&gt;cell());
+        }
+
+        explicit TrustedImmPtr(size_t value)
+            : m_value(bitwise_cast&lt;void*&gt;(value))
+        {
+        }
+
+        static TrustedImmPtr weakPointer(Graph&amp; graph, JSCell* cell)
+        {     
+            // There are weird relationships in how optimized CodeBlocks
+            // point to other CodeBlocks. We don't want to have them be
+            // part of the weak pointer set. For example, an optimized CodeBlock
+            // having a weak pointer to itself will cause it to get collected.
+            ASSERT(!jsDynamicCast&lt;CodeBlock*&gt;(cell));
+
+            graph.m_plan.weakReferences.addLazily(cell);
+            return TrustedImmPtr(bitwise_cast&lt;size_t&gt;(cell));
+        }
+
+        operator MacroAssembler::TrustedImmPtr() const { return m_value; }
+
+        intptr_t asIntptr()
+        {
+            return m_value.asIntptr();
+        }
+
+    private:
+        MacroAssembler::TrustedImmPtr m_value;
+    };
+
</ins><span class="cx">     bool compile();
</span><span class="cx">     
</span><span class="cx">     void createOSREntries();
</span><span class="lines">@@ -982,17 +1039,17 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(obj, impl);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, Structure* structure)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, RegisteredStructure structure)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, Structure* structure, GPRReg arg2, GPRReg arg3)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, RegisteredStructure structure, GPRReg arg2, GPRReg arg3)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2, arg3);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, Structure* structure, size_t arg2, GPRReg arg3)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, RegisteredStructure structure, size_t arg2, GPRReg arg3)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2), arg3);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -1002,12 +1059,12 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, Structure* structure, GPRReg arg2, GPRReg butterfly)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, RegisteredStructure structure, GPRReg arg2, GPRReg butterfly)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2, butterfly);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, Structure* structure, size_t arg2, GPRReg butterfly)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, RegisteredStructure structure, size_t arg2, GPRReg butterfly)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2), butterfly);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -1022,12 +1079,12 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(butterfly));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, RegisteredStructure structure, void* pointer, size_t size)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, RegisteredStructure structure, size_t index, size_t size)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -1044,7 +1101,7 @@
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, JSCell* cell)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), cell));
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
</span><span class="lines">@@ -1059,7 +1116,7 @@
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
</del><ins>+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell));
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
</span><span class="lines">@@ -1067,7 +1124,7 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, Structure* structure)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, RegisteredStructure structure)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -1074,39 +1131,39 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table, TrustedImm64 initialValue)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, RegisteredStructure structure, GPRReg scope, SymbolTable* table, TrustedImm64 initialValue)
</ins><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table), initialValue);
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr::weakPointer(m_jit.graph(), table), initialValue);
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> #else
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table, TrustedImm32 tag, TrustedImm32 payload)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, RegisteredStructure structure, GPRReg scope, SymbolTable* table, TrustedImm32 tag, TrustedImm32 payload)
</ins><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table), payload, tag);
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr::weakPointer(m_jit.graph(), table), payload, tag);
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, RegisteredStructure structure, unsigned knownLength)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, RegisteredStructure structure, unsigned knownLength, unsigned minCapacity)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, RegisteredStructure structure, GPRReg length)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, RegisteredStructure structure, GPRReg length, unsigned minCapacity)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><del>-    JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
</del><ins>+    JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, RegisteredStructure structure)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -1140,13 +1197,13 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(S_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg2);
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg2);
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1170,7 +1227,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(V_JITOperation_EC operation, JSCell* arg1)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1));
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), arg1));
</ins><span class="cx">         return appendCall(operation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1197,12 +1254,12 @@
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, JSCell* arg2)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
</del><ins>+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), arg2));
</ins><span class="cx">         return appendCall(operation);
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(V_JITOperation_ECC operation, JSCell* arg1, GPRReg arg2)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2);
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), arg1), arg2);
</ins><span class="cx">         return appendCall(operation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1273,13 +1330,13 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
</del><ins>+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell));
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, GPRReg arg2)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), arg2);
</del><ins>+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell), arg2);
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1474,7 +1531,7 @@
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg result, JSCell* cell)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), cell));
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
</span><span class="lines">@@ -1544,7 +1601,7 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, RegisteredStructure structure, GPRReg arg2)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -1552,7 +1609,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg1);
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1);
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1900,7 +1957,7 @@
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(D_JITOperation_G operation, FPRReg result, JSGlobalObject* globalObject)
</span><span class="cx">     {
</span><del>-        m_jit.setupArguments(TrustedImmPtr(globalObject));
</del><ins>+        m_jit.setupArguments(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject));
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
</span><span class="lines">@@ -2009,7 +2066,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EC operation, JSValueRegs result, JSCell* cell)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), cell));
</ins><span class="cx">         return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_ECZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2)
</span><span class="lines">@@ -2019,12 +2076,12 @@
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJscC operation, JSValueRegs result, GPRReg arg1, JSCell* cell)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
</del><ins>+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell));
</ins><span class="cx">         return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, JSValueRegs arg2)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), EABI_32BIT_DUMMY_ARG arg2.payloadGPR(), arg2.tagGPR());
</del><ins>+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr::weakPointer(m_jit.graph(), cell), EABI_32BIT_DUMMY_ARG arg2.payloadGPR(), arg2.tagGPR());
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
</span><span class="lines">@@ -2109,7 +2166,7 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, JSValueRegs arg2)
</del><ins>+    JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, RegisteredStructure structure, JSValueRegs arg2)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2.payloadGPR(), arg2.tagGPR());
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="lines">@@ -2117,7 +2174,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1)
</span><span class="cx">     {
</span><del>-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg1.payloadGPR(), arg1.tagGPR());
</del><ins>+        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1.payloadGPR(), arg1.tagGPR());
</ins><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -2667,7 +2724,7 @@
</span><span class="cx">     void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
</span><span class="cx">     void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
</span><span class="cx">     void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
</span><del>-    template &lt;typename ClassType&gt; void compileNewFunctionCommon(GPRReg, Structure*, GPRReg, GPRReg, GPRReg, MacroAssembler::JumpList&amp;, size_t, FunctionExecutable*, ptrdiff_t, ptrdiff_t, ptrdiff_t);
</del><ins>+    template &lt;typename ClassType&gt; void compileNewFunctionCommon(GPRReg, RegisteredStructure, GPRReg, GPRReg, GPRReg, MacroAssembler::JumpList&amp;, size_t, FunctionExecutable*, ptrdiff_t, ptrdiff_t, ptrdiff_t);
</ins><span class="cx">     void compileNewFunction(Node*);
</span><span class="cx">     void compileSetFunctionName(Node*);
</span><span class="cx">     void compileForwardVarargs(Node*);
</span><span class="lines">@@ -2753,13 +2810,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename ClassType&gt;
</span><del>-    void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure, 
</del><ins>+    void emitAllocateDestructibleObject(GPRReg resultGPR, RegisteredStructure structure, 
</ins><span class="cx">         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList&amp; slowPath)
</span><span class="cx">     {
</span><del>-        m_jit.emitAllocateDestructibleObject&lt;ClassType&gt;(resultGPR, structure, scratchGPR1, scratchGPR2, slowPath);
</del><ins>+        m_jit.emitAllocateDestructibleObject&lt;ClassType&gt;(resultGPR, structure.get(), scratchGPR1, scratchGPR2, slowPath);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void emitAllocateRawObject(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements, unsigned vectorLength);
</del><ins>+    void emitAllocateRawObject(GPRReg resultGPR, RegisteredStructure, GPRReg storageGPR, unsigned numElements, unsigned vectorLength);
</ins><span class="cx">     
</span><span class="cx">     void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false);
</span><span class="cx">     void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false);
</span><span class="lines">@@ -3774,13 +3831,13 @@
</span><span class="cx"> template&lt;typename StructureLocationType&gt;
</span><span class="cx"> void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
</span><span class="cx"> {
</span><del>-    Structure* stringObjectStructure =
-        m_jit.globalObjectFor(m_currentNode-&gt;origin.semantic)-&gt;stringObjectStructure();
</del><ins>+    RegisteredStructure stringObjectStructure =
+        m_jit.graph().registerStructure(m_jit.globalObjectFor(m_currentNode-&gt;origin.semantic)-&gt;stringObjectStructure());
</ins><span class="cx">     
</span><del>-    if (!m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure))) {
</del><ins>+    if (!m_state.forNode(edge).m_structure.isSubsetOf(RegisteredStructureSet(stringObjectStructure))) {
</ins><span class="cx">         speculationCheck(
</span><span class="cx">             NotStringObject, JSValueRegs(), 0,
</span><del>-            m_jit.branchStructure(
</del><ins>+            m_jit.branchWeakStructure(
</ins><span class="cx">                 JITCompiler::NotEqual, structureLocation, stringObjectStructure));
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -294,7 +294,7 @@
</span><span class="cx">         isMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">         GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
</span><span class="cx">         GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
</span><del>-        m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</del><ins>+        m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</ins><span class="cx">         m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureIDOffset()), resultPayloadGPR);
</span><span class="cx">         m_jit.loadPtr(JITCompiler::Address(resultPayloadGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
</span><span class="cx">         m_jit.compare32(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultPayloadGPR);
</span><span class="lines">@@ -358,7 +358,7 @@
</span><span class="cx">    
</span><span class="cx">         GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
</span><span class="cx">         GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
</span><del>-        m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</del><ins>+        m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</ins><span class="cx">         m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureIDOffset()), resultGPR);
</span><span class="cx">         m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
</span><span class="cx">         branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, invert ? notTaken : taken);
</span><span class="lines">@@ -1082,7 +1082,7 @@
</span><span class="cx">             m_jit.emitRestoreCalleeSaves();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_jit.move(MacroAssembler::TrustedImmPtr(info), GPRInfo::regT2);
</del><ins>+    m_jit.move(TrustedImmPtr(info), GPRInfo::regT2);
</ins><span class="cx">     JITCompiler::Call slowCall = m_jit.nearCall();
</span><span class="cx"> 
</span><span class="cx">     done.link(&amp;m_jit);
</span><span class="lines">@@ -1242,10 +1242,9 @@
</span><span class="cx">     switch (info.registerFormat()) {
</span><span class="cx">     case DataFormatNone: {
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue jsValue = edge-&gt;asJSValue();
</del><span class="cx">             GPRReg gpr = allocate();
</span><span class="cx">             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><del>-            m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
</del><ins>+            m_jit.move(TrustedImmPtr(edge-&gt;constant()), gpr);
</ins><span class="cx">             info.fillCell(*m_stream, gpr);
</span><span class="cx">             return gpr;
</span><span class="cx">         }
</span><span class="lines">@@ -1724,7 +1723,7 @@
</span><span class="cx">             m_jit.branchPtr(
</span><span class="cx">                 MacroAssembler::Equal, 
</span><span class="cx">                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
</span><del>-                MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</del><ins>+                TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</ins><span class="cx"> 
</span><span class="cx">         isNotMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">     }
</span><span class="lines">@@ -1843,7 +1842,7 @@
</span><span class="cx">             m_jit.branchPtr(
</span><span class="cx">                 MacroAssembler::Equal, 
</span><span class="cx">                 MacroAssembler::Address(scratchGPR, Structure::globalObjectOffset()), 
</span><del>-                MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</del><ins>+                TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</ins><span class="cx"> 
</span><span class="cx">         isNotMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">     }
</span><span class="lines">@@ -3778,7 +3777,7 @@
</span><span class="cx">     case NewArray: {
</span><span class="cx">         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(node-&gt;indexingType())) {
</span><del>-            Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType());
</del><ins>+            RegisteredStructure structure = m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</ins><span class="cx">             ASSERT(structure-&gt;indexingType() == node-&gt;indexingType());
</span><span class="cx">             ASSERT(
</span><span class="cx">                 hasUndecided(structure-&gt;indexingType())
</span><span class="lines">@@ -3853,7 +3852,7 @@
</span><span class="cx">             flushRegisters();
</span><span class="cx">             GPRFlushedCallResult result(this);
</span><span class="cx">             callOperation(
</span><del>-                operationNewEmptyArray, result.gpr(), globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</del><ins>+                operationNewEmptyArray, result.gpr(), m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())));
</ins><span class="cx">             m_jit.exceptionCheck();
</span><span class="cx">             cellResult(result.gpr(), node);
</span><span class="cx">             break;
</span><span class="lines">@@ -3930,7 +3929,7 @@
</span><span class="cx">         GPRFlushedCallResult result(this);
</span><span class="cx">         
</span><span class="cx">         callOperation(
</span><del>-            operationNewArray, result.gpr(), globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()),
</del><ins>+            operationNewArray, result.gpr(), m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())),
</ins><span class="cx">             static_cast&lt;void*&gt;(buffer), node-&gt;numChildren());
</span><span class="cx">         m_jit.exceptionCheck();
</span><span class="cx"> 
</span><span class="lines">@@ -3976,10 +3975,10 @@
</span><span class="cx">         GPRReg resultGPR = result.gpr();
</span><span class="cx">         GPRReg structureGPR = selectScratchGPR(sizeGPR);
</span><span class="cx">         MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())), structureGPR);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()))), structureGPR);
</ins><span class="cx">         MacroAssembler::Jump done = m_jit.jump();
</span><span class="cx">         bigLength.link(&amp;m_jit);
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage))), structureGPR);
</ins><span class="cx">         done.link(&amp;m_jit);
</span><span class="cx">         callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR, nullptr);
</span><span class="cx">         m_jit.exceptionCheck();
</span><span class="lines">@@ -3999,7 +3998,7 @@
</span><span class="cx">             GPRReg resultGPR = result.gpr();
</span><span class="cx">             GPRReg storageGPR = storage.gpr();
</span><span class="cx"> 
</span><del>-            emitAllocateRawObject(resultGPR, globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements, numElements);
</del><ins>+            emitAllocateRawObject(resultGPR, m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType)), storageGPR, numElements, numElements);
</ins><span class="cx">             
</span><span class="cx">             if (node-&gt;indexingType() == ArrayWithDouble) {
</span><span class="cx">                 JSValue* data = m_jit.codeBlock()-&gt;constantBuffer(node-&gt;startConstant());
</span><span class="lines">@@ -4027,7 +4026,7 @@
</span><span class="cx">         flushRegisters();
</span><span class="cx">         GPRFlushedCallResult result(this);
</span><span class="cx">         
</span><del>-        callOperation(operationNewArrayBuffer, result.gpr(), globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()), node-&gt;startConstant(), node-&gt;numConstants());
</del><ins>+        callOperation(operationNewArrayBuffer, result.gpr(), m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())), node-&gt;startConstant(), node-&gt;numConstants());
</ins><span class="cx">         m_jit.exceptionCheck();
</span><span class="cx">         
</span><span class="cx">         cellResult(result.gpr(), node);
</span><span class="lines">@@ -4051,7 +4050,7 @@
</span><span class="cx">             JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">             callOperation(
</span><span class="cx">                 operationNewTypedArrayWithOneArgumentForType(node-&gt;typedArrayType()),
</span><del>-                resultGPR, globalObject-&gt;typedArrayStructureConcurrently(node-&gt;typedArrayType()), argumentRegs);
</del><ins>+                resultGPR, m_jit.graph().registerStructure(globalObject-&gt;typedArrayStructureConcurrently(node-&gt;typedArrayType())), argumentRegs);
</ins><span class="cx">             m_jit.exceptionCheck();
</span><span class="cx">             
</span><span class="cx">             cellResult(resultGPR, node);
</span><span class="lines">@@ -4171,7 +4170,7 @@
</span><span class="cx">         
</span><span class="cx">         MacroAssembler::JumpList slowPath;
</span><span class="cx">         
</span><del>-        Structure* structure = node-&gt;structure();
</del><ins>+        RegisteredStructure structure = node-&gt;structure();
</ins><span class="cx">         size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><span class="cx">         MarkedAllocator* allocatorPtr = subspaceFor&lt;JSFinalObject&gt;(*m_jit.vm())-&gt;allocatorFor(allocationSize);
</span><span class="cx"> 
</span><span class="lines">@@ -4416,8 +4415,8 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case PutStructure: {
</span><del>-        Structure* oldStructure = node-&gt;transition()-&gt;previous;
-        Structure* newStructure = node-&gt;transition()-&gt;next;
</del><ins>+        RegisteredStructure oldStructure = node-&gt;transition()-&gt;previous;
+        RegisteredStructure newStructure = node-&gt;transition()-&gt;next;
</ins><span class="cx"> 
</span><span class="cx">         m_jit.jitCode()-&gt;common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
</span><span class="cx"> 
</span><span class="lines">@@ -4427,7 +4426,7 @@
</span><span class="cx">         ASSERT_UNUSED(oldStructure, oldStructure-&gt;indexingType() == newStructure-&gt;indexingType());
</span><span class="cx">         ASSERT(oldStructure-&gt;typeInfo().type() == newStructure-&gt;typeInfo().type());
</span><span class="cx">         ASSERT(oldStructure-&gt;typeInfo().inlineTypeFlags() == newStructure-&gt;typeInfo().inlineTypeFlags());
</span><del>-        m_jit.storePtr(MacroAssembler::TrustedImmPtr(newStructure), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()));
</del><ins>+        m_jit.storePtr(TrustedImmPtr(newStructure), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()));
</ins><span class="cx">         
</span><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="lines">@@ -4691,7 +4690,7 @@
</span><span class="cx">         if (!hasInstanceValueNode-&gt;isCellConstant() || defaultHasInstanceFunction != hasInstanceValueNode-&gt;asCell()) {
</span><span class="cx">             JSValueRegs hasInstanceValueRegs = hasInstanceValue.jsValueRegs();
</span><span class="cx">             notDefaultHasInstanceValue.append(m_jit.branchIfNotCell(hasInstanceValueRegs));
</span><del>-            notDefaultHasInstanceValue.append(m_jit.branchPtr(MacroAssembler::NotEqual, hasInstanceValueRegs.payloadGPR(), TrustedImmPtr(defaultHasInstanceFunction)));
</del><ins>+            notDefaultHasInstanceValue.append(m_jit.branchPtr(MacroAssembler::NotEqual, hasInstanceValueRegs.payloadGPR(), TrustedImmPtr(node-&gt;cellOperand())));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Check that constructor 'ImplementsDefaultHasInstance'.
</span><span class="lines">@@ -4753,7 +4752,7 @@
</span><span class="cx">             isMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">             GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
</span><span class="cx">             GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
</span><del>-            m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node-&gt;origin.semantic)), localGlobalObjectGPR);
</del><ins>+            m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.globalObjectFor(node-&gt;origin.semantic)), localGlobalObjectGPR);
</ins><span class="cx">             m_jit.loadPtr(JITCompiler::Address(value.payloadGPR(), JSCell::structureIDOffset()), result.gpr());
</span><span class="cx">             m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR); 
</span><span class="cx">             m_jit.compare32(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr());
</span><span class="lines">@@ -5713,13 +5712,13 @@
</span><span class="cx">     // We can use result as a scratch for this.
</span><span class="cx">     emitInitializeButterfly(storageGPR, sizeGPR, emptyValueRegs, resultGPR);
</span><span class="cx">             
</span><del>-    Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType);
</del><ins>+    RegisteredStructure structure = m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType));
</ins><span class="cx">     emitAllocateJSObject&lt;JSArray&gt;(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases);
</span><span class="cx">             
</span><span class="cx">     addSlowPathGenerator(std::make_unique&lt;CallArrayAllocatorWithVariableSizeSlowPathGenerator&gt;(
</span><span class="cx">         slowCases, this, operationNewArrayWithSize, resultGPR,
</span><span class="cx">         structure,
</span><del>-        shouldConvertLargeSizeToArrayStorage ? globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : structure,
</del><ins>+        shouldConvertLargeSizeToArrayStorage ? m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)) : structure,
</ins><span class="cx">         sizeGPR, storageGPR));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -250,7 +250,7 @@
</span><span class="cx"> 
</span><span class="cx">         GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
</span><span class="cx">         GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
</span><del>-        m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</del><ins>+        m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</ins><span class="cx">         m_jit.emitLoadStructure(argGPR, resultGPR, scratch.gpr());
</span><span class="cx">         m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
</span><span class="cx">         m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultGPR);
</span><span class="lines">@@ -305,7 +305,7 @@
</span><span class="cx"> 
</span><span class="cx">         GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
</span><span class="cx">         GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
</span><del>-        m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</del><ins>+        m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic)), localGlobalObjectGPR);
</ins><span class="cx">         m_jit.emitLoadStructure(argGPR, resultGPR, scratch.gpr());
</span><span class="cx">         m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
</span><span class="cx">         branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, taken);
</span><span class="lines">@@ -1006,7 +1006,7 @@
</span><span class="cx">     m_jit.emitStoreCallSiteIndex(callSite);
</span><span class="cx">     
</span><span class="cx">     JITCompiler::DataLabelPtr targetToCheck;
</span><del>-    JITCompiler::Jump slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(0));
</del><ins>+    JITCompiler::Jump slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, TrustedImmPtr(0));
</ins><span class="cx"> 
</span><span class="cx">     if (isTail) {
</span><span class="cx">         if (node-&gt;op() == TailCall) {
</span><span class="lines">@@ -1035,7 +1035,7 @@
</span><span class="cx">             m_jit.emitRestoreCalleeSaves(); // This needs to happen after we moved calleeGPR to regT0
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::regT2); // Link info needs to be in regT2
</del><ins>+    m_jit.move(TrustedImmPtr(callLinkInfo), GPRInfo::regT2); // Link info needs to be in regT2
</ins><span class="cx">     JITCompiler::Call slowCall = m_jit.nearCall();
</span><span class="cx"> 
</span><span class="cx">     done.link(&amp;m_jit);
</span><span class="lines">@@ -1856,7 +1856,7 @@
</span><span class="cx">             m_jit.branchPtr(
</span><span class="cx">                 MacroAssembler::Equal, 
</span><span class="cx">                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
</span><del>-                MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</del><ins>+                TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</ins><span class="cx"> 
</span><span class="cx">         isNotMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">     }
</span><span class="lines">@@ -2007,7 +2007,7 @@
</span><span class="cx">             m_jit.branchPtr(
</span><span class="cx">                 MacroAssembler::Equal, 
</span><span class="cx">                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
</span><del>-                MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</del><ins>+                TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode-&gt;origin.semantic))));
</ins><span class="cx"> 
</span><span class="cx">         isNotMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">     }
</span><span class="lines">@@ -3757,7 +3757,7 @@
</span><span class="cx">     case NewArray: {
</span><span class="cx">         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(node-&gt;indexingType())) {
</span><del>-            Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType());
</del><ins>+            RegisteredStructure structure = m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</ins><span class="cx">             DFG_ASSERT(m_jit.graph(), node, structure-&gt;indexingType() == node-&gt;indexingType());
</span><span class="cx">             ASSERT(
</span><span class="cx">                 hasUndecided(structure-&gt;indexingType())
</span><span class="lines">@@ -3830,7 +3830,7 @@
</span><span class="cx">         if (!node-&gt;numChildren()) {
</span><span class="cx">             flushRegisters();
</span><span class="cx">             GPRFlushedCallResult result(this);
</span><del>-            callOperation(operationNewEmptyArray, result.gpr(), globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</del><ins>+            callOperation(operationNewEmptyArray, result.gpr(), m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())));
</ins><span class="cx">             m_jit.exceptionCheck();
</span><span class="cx">             cellResult(result.gpr(), node);
</span><span class="cx">             break;
</span><span class="lines">@@ -3912,7 +3912,7 @@
</span><span class="cx">         GPRFlushedCallResult result(this);
</span><span class="cx">         
</span><span class="cx">         callOperation(
</span><del>-            operationNewArray, result.gpr(), globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()),
</del><ins>+            operationNewArray, result.gpr(), m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())),
</ins><span class="cx">             static_cast&lt;void*&gt;(buffer), node-&gt;numChildren());
</span><span class="cx">         m_jit.exceptionCheck();
</span><span class="cx"> 
</span><span class="lines">@@ -3956,10 +3956,10 @@
</span><span class="cx">         GPRReg resultGPR = result.gpr();
</span><span class="cx">         GPRReg structureGPR = selectScratchGPR(sizeGPR);
</span><span class="cx">         MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())), structureGPR);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()))), structureGPR);
</ins><span class="cx">         MacroAssembler::Jump done = m_jit.jump();
</span><span class="cx">         bigLength.link(&amp;m_jit);
</span><del>-        m_jit.move(TrustedImmPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR);
</del><ins>+        m_jit.move(TrustedImmPtr(m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage))), structureGPR);
</ins><span class="cx">         done.link(&amp;m_jit);
</span><span class="cx">         callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR, nullptr);
</span><span class="cx">         m_jit.exceptionCheck();
</span><span class="lines">@@ -3979,7 +3979,7 @@
</span><span class="cx">             GPRReg resultGPR = result.gpr();
</span><span class="cx">             GPRReg storageGPR = storage.gpr();
</span><span class="cx"> 
</span><del>-            emitAllocateRawObject(resultGPR, globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements, numElements);
</del><ins>+            emitAllocateRawObject(resultGPR, m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType)), storageGPR, numElements, numElements);
</ins><span class="cx">             
</span><span class="cx">             DFG_ASSERT(m_jit.graph(), node, indexingType &amp; IsArray);
</span><span class="cx">             JSValue* data = m_jit.codeBlock()-&gt;constantBuffer(node-&gt;startConstant());
</span><span class="lines">@@ -4005,7 +4005,7 @@
</span><span class="cx">         flushRegisters();
</span><span class="cx">         GPRFlushedCallResult result(this);
</span><span class="cx">         
</span><del>-        callOperation(operationNewArrayBuffer, result.gpr(), globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()), node-&gt;startConstant(), node-&gt;numConstants());
</del><ins>+        callOperation(operationNewArrayBuffer, result.gpr(), m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType())), node-&gt;startConstant(), node-&gt;numConstants());
</ins><span class="cx">         m_jit.exceptionCheck();
</span><span class="cx">         
</span><span class="cx">         cellResult(result.gpr(), node);
</span><span class="lines">@@ -4029,7 +4029,7 @@
</span><span class="cx">             JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">             callOperation(
</span><span class="cx">                 operationNewTypedArrayWithOneArgumentForType(node-&gt;typedArrayType()),
</span><del>-                resultGPR, globalObject-&gt;typedArrayStructureConcurrently(node-&gt;typedArrayType()),
</del><ins>+                resultGPR, m_jit.graph().registerStructure(globalObject-&gt;typedArrayStructureConcurrently(node-&gt;typedArrayType())),
</ins><span class="cx">                 argumentGPR);
</span><span class="cx">             m_jit.exceptionCheck();
</span><span class="cx">             
</span><span class="lines">@@ -4143,7 +4143,7 @@
</span><span class="cx">         
</span><span class="cx">         MacroAssembler::JumpList slowPath;
</span><span class="cx"> 
</span><del>-        Structure* structure = node-&gt;structure();
</del><ins>+        RegisteredStructure structure = node-&gt;structure();
</ins><span class="cx">         size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><span class="cx">         MarkedAllocator* allocatorPtr = subspaceFor&lt;JSFinalObject&gt;(*m_jit.vm())-&gt;allocatorFor(allocationSize);
</span><span class="cx"> 
</span><span class="lines">@@ -4376,8 +4376,8 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case PutStructure: {
</span><del>-        Structure* oldStructure = node-&gt;transition()-&gt;previous;
-        Structure* newStructure = node-&gt;transition()-&gt;next;
</del><ins>+        RegisteredStructure oldStructure = node-&gt;transition()-&gt;previous;
+        RegisteredStructure newStructure = node-&gt;transition()-&gt;next;
</ins><span class="cx"> 
</span><span class="cx">         m_jit.jitCode()-&gt;common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
</span><span class="cx"> 
</span><span class="lines">@@ -4652,7 +4652,7 @@
</span><span class="cx">         // since it relies on OSR information. https://bugs.webkit.org/show_bug.cgi?id=154832
</span><span class="cx">         if (!hasInstanceValueNode-&gt;isCellConstant() || defaultHasInstanceFunction != hasInstanceValueNode-&gt;asCell()) {
</span><span class="cx">             GPRReg hasInstanceValueGPR = hasInstanceValue.gpr();
</span><del>-            notDefault = m_jit.branchPtr(MacroAssembler::NotEqual, hasInstanceValueGPR, TrustedImmPtr(defaultHasInstanceFunction));
</del><ins>+            notDefault = m_jit.branchPtr(MacroAssembler::NotEqual, hasInstanceValueGPR, TrustedImmPtr(node-&gt;cellOperand()));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Check that base 'ImplementsDefaultHasInstance'.
</span><span class="lines">@@ -4719,7 +4719,7 @@
</span><span class="cx">             isMasqueradesAsUndefined.link(&amp;m_jit);
</span><span class="cx">             GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
</span><span class="cx">             GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
</span><del>-            m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node-&gt;origin.semantic)), localGlobalObjectGPR);
</del><ins>+            m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.globalObjectFor(node-&gt;origin.semantic)), localGlobalObjectGPR);
</ins><span class="cx">             m_jit.emitLoadStructure(value.gpr(), result.gpr(), scratch.gpr());
</span><span class="cx">             m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR); 
</span><span class="cx">             m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr());
</span><span class="lines">@@ -4912,9 +4912,9 @@
</span><span class="cx">         m_jit.loadPtr(MacroAssembler::BaseIndex(bufferGPR, indexGPR, MacroAssembler::TimesEight), bucketGPR);
</span><span class="cx">         m_jit.move(bucketGPR, resultGPR);
</span><span class="cx">         auto notPresentInTable = m_jit.branchPtr(MacroAssembler::Equal, 
</span><del>-            bucketGPR, TrustedImmPtr(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::emptyValue()));
</del><ins>+            bucketGPR, TrustedImmPtr(bitwise_cast&lt;size_t&gt;(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::emptyValue())));
</ins><span class="cx">         loopAround.append(m_jit.branchPtr(MacroAssembler::Equal, 
</span><del>-            bucketGPR, TrustedImmPtr(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::deletedValue())));
</del><ins>+            bucketGPR, TrustedImmPtr(bitwise_cast&lt;size_t&gt;(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::deletedValue()))));
</ins><span class="cx"> 
</span><span class="cx">         m_jit.load64(MacroAssembler::Address(bucketGPR, HashMapBucket&lt;HashMapBucketDataKey&gt;::offsetOfKey()), bucketGPR);
</span><span class="cx"> 
</span><span class="lines">@@ -5982,7 +5982,7 @@
</span><span class="cx">         m_jit.move(TrustedImm64(JSValue::encode(JSValue())), scratchGPR);
</span><span class="cx">     emitInitializeButterfly(storageGPR, sizeGPR, JSValueRegs(scratchGPR), scratch2GPR);
</span><span class="cx"> 
</span><del>-    Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType);
</del><ins>+    RegisteredStructure structure = m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType));
</ins><span class="cx">     
</span><span class="cx">     emitAllocateJSObject&lt;JSArray&gt;(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases);
</span><span class="cx">     
</span><span class="lines">@@ -5991,7 +5991,7 @@
</span><span class="cx">     addSlowPathGenerator(std::make_unique&lt;CallArrayAllocatorWithVariableSizeSlowPathGenerator&gt;(
</span><span class="cx">         slowCases, this, operationNewArrayWithSize, resultGPR,
</span><span class="cx">         structure,
</span><del>-        shouldConvertLargeSizeToArrayStorage ? globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : structure,
</del><ins>+        shouldConvertLargeSizeToArrayStorage ? m_jit.graph().registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)) : structure,
</ins><span class="cx">         sizeGPR, storageGPR));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -540,7 +540,7 @@
</span><span class="cx"> 
</span><span class="cx">             if (m_node-&gt;op() == RegExpExec) {
</span><span class="cx">                 if (result) {
</span><del>-                    StructureSet* structureSet = m_graph.addStructureSet(structure);
</del><ins>+                    RegisteredStructureSet* structureSet = m_graph.addStructureSet(structure);
</ins><span class="cx"> 
</span><span class="cx">                     // Create an array modeling the JS array that we will try to allocate. This is
</span><span class="cx">                     // basically createRegExpMatchesArray but over C++ strings instead of JSStrings.
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGStructureAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = size(); i--;)
</span><del>-        graph.assertIsRegistered(at(i));
</del><ins>+        graph.assertIsRegistered(at(i).get());
</ins><span class="cx"> }
</span><span class="cx"> #endif // !ASSERT_DISABLED
</span><span class="cx"> 
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StructureSet::OutOfLineList* list = m_set.list();
</del><ins>+    RegisteredStructureSet::OutOfLineList* list = m_set.list();
</ins><span class="cx">     for (unsigned i = list-&gt;m_length; i--;) {
</span><span class="cx">         if (!list-&gt;list()[i]-&gt;dfgShouldWatch()) {
</span><span class="cx">             makeTop();
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StructureAbstractValue::observeTransition(Structure* from, Structure* to)
</del><ins>+void StructureAbstractValue::observeTransition(RegisteredStructure from, RegisteredStructure to)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!from-&gt;dfgShouldWatch());
</span><span class="cx"> 
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     if (isTop())
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    StructureSet newStructures;
</del><ins>+    RegisteredStructureSet newStructures;
</ins><span class="cx">     for (unsigned i = vector.size(); i--;) {
</span><span class="cx">         ASSERT(!vector[i].previous-&gt;dfgShouldWatch());
</span><span class="cx"> 
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">         makeTop();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::add(Structure* structure)
</del><ins>+bool StructureAbstractValue::add(RegisteredStructure structure)
</ins><span class="cx"> {
</span><span class="cx">     if (isTop())
</span><span class="cx">         return false;
</span><span class="lines">@@ -124,7 +124,7 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::merge(const StructureSet&amp; other)
</del><ins>+bool StructureAbstractValue::merge(const RegisteredStructureSet&amp; other)
</ins><span class="cx"> {
</span><span class="cx">     if (isTop())
</span><span class="cx">         return false;
</span><span class="lines">@@ -175,7 +175,7 @@
</span><span class="cx">     return changed;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::mergeNotTop(const StructureSet&amp; other)
</del><ins>+bool StructureAbstractValue::mergeNotTop(const RegisteredStructureSet&amp; other)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_set.merge(other))
</span><span class="cx">         return false;
</span><span class="lines">@@ -186,7 +186,7 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StructureAbstractValue::filter(const StructureSet&amp; other)
</del><ins>+void StructureAbstractValue::filter(const RegisteredStructureSet&amp; other)
</ins><span class="cx"> {
</span><span class="cx">     if (isTop()) {
</span><span class="cx">         m_set = other;
</span><span class="lines">@@ -229,7 +229,7 @@
</span><span class="cx">             return;
</span><span class="cx">         
</span><span class="cx">         if (!isClobbered()) {
</span><del>-            // See justification in filter(const StructureSet&amp;), above. An unclobbered set is
</del><ins>+            // See justification in filter(const RegisteredStructureSet&amp;), above. An unclobbered set is
</ins><span class="cx">             // almost always better.
</span><span class="cx">             if (m_set.size() &gt; other.m_set.size() + clobberedSupremacyThreshold)
</span><span class="cx">                 *this = other; // Keep the clobbered set.
</span><span class="lines">@@ -253,8 +253,8 @@
</span><span class="cx">     ASSERT(!isTop());
</span><span class="cx">     
</span><span class="cx">     m_set.genericFilter(
</span><del>-        [&amp;] (Structure* structure) {
-            return !!(speculationFromStructure(structure) &amp; type);
</del><ins>+        [&amp;] (RegisteredStructure structure) {
+            return !!(speculationFromStructure(structure.get()) &amp; type);
</ins><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -262,12 +262,12 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isTop());
</span><span class="cx">     m_set.genericFilter(
</span><del>-        [&amp;] (Structure* structure) {
</del><ins>+        [&amp;] (RegisteredStructure structure) {
</ins><span class="cx">             return structure-&gt;classInfo()-&gt;isSubClassOf(classInfo);
</span><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::contains(Structure* structure) const
</del><ins>+bool StructureAbstractValue::contains(RegisteredStructure structure) const
</ins><span class="cx"> {
</span><span class="cx">     if (isInfinite())
</span><span class="cx">         return true;
</span><span class="lines">@@ -275,9 +275,17 @@
</span><span class="cx">     return m_set.contains(structure);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::isSubsetOf(const StructureSet&amp; other) const
</del><ins>+bool StructureAbstractValue::contains(Structure* structure) const
</ins><span class="cx"> {
</span><span class="cx">     if (isInfinite())
</span><ins>+        return true;
+    
+    return m_set.toStructureSet().contains(structure);
+}
+
+bool StructureAbstractValue::isSubsetOf(const RegisteredStructureSet&amp; other) const
+{
+    if (isInfinite())
</ins><span class="cx">         return false;
</span><span class="cx">     
</span><span class="cx">     return m_set.isSubsetOf(other);
</span><span class="lines">@@ -304,7 +312,7 @@
</span><span class="cx">     return m_set.isSubsetOf(other.m_set);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::isSupersetOf(const StructureSet&amp; other) const
</del><ins>+bool StructureAbstractValue::isSupersetOf(const RegisteredStructureSet&amp; other) const
</ins><span class="cx"> {
</span><span class="cx">     if (isInfinite())
</span><span class="cx">         return true;
</span><span class="lines">@@ -312,7 +320,7 @@
</span><span class="cx">     return m_set.isSupersetOf(other);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool StructureAbstractValue::overlaps(const StructureSet&amp; other) const
</del><ins>+bool StructureAbstractValue::overlaps(const RegisteredStructureSet&amp; other) const
</ins><span class="cx"> {
</span><span class="cx">     if (isInfinite())
</span><span class="cx">         return true;
</span><span class="lines">@@ -334,7 +342,7 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Note taht this function returns true if the structure set is empty.
</span><del>-    for (const Structure* structure : m_set) {
</del><ins>+    for (const RegisteredStructure structure : m_set) {
</ins><span class="cx">         if (!structure-&gt;classInfo()-&gt;isSubClassOf(classInfo))
</span><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="lines">@@ -359,7 +367,7 @@
</span><span class="cx">     if (isTop())
</span><span class="cx">         out.print(&quot;TOP&quot;);
</span><span class="cx">     else
</span><del>-        out.print(inContext(m_set, context));
</del><ins>+        out.print(inContext(m_set.toStructureSet(), context));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StructureAbstractValue::dump(PrintStream&amp; out) const
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGStructureAbstractValueh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -27,10 +27,11 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;DFGRegisteredStructureSet.h&quot;
</ins><span class="cx"> #include &quot;DFGTransition.h&quot;
</span><ins>+#include &quot;DumpContext.h&quot;
</ins><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="cx"> #include &quot;SpeculatedType.h&quot;
</span><del>-#include &quot;DumpContext.h&quot;
</del><span class="cx"> #include &quot;StructureSet.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -42,12 +43,12 @@
</span><span class="cx"> class StructureAbstractValue {
</span><span class="cx"> public:
</span><span class="cx">     StructureAbstractValue() { }
</span><del>-    StructureAbstractValue(Structure* structure)
-        : m_set(StructureSet(structure))
</del><ins>+    StructureAbstractValue(RegisteredStructure structure)
+        : m_set(structure)
</ins><span class="cx">     {
</span><span class="cx">         setClobbered(false);
</span><span class="cx">     }
</span><del>-    StructureAbstractValue(const StructureSet&amp; other)
</del><ins>+    StructureAbstractValue(const RegisteredStructureSet&amp; other)
</ins><span class="cx">         : m_set(other)
</span><span class="cx">     {
</span><span class="cx">         setClobbered(false);
</span><span class="lines">@@ -58,13 +59,13 @@
</span><span class="cx">         setClobbered(other.isClobbered());
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ALWAYS_INLINE StructureAbstractValue&amp; operator=(Structure* structure)
</del><ins>+    ALWAYS_INLINE StructureAbstractValue&amp; operator=(RegisteredStructure structure)
</ins><span class="cx">     {
</span><del>-        m_set = StructureSet(structure);
</del><ins>+        m_set = RegisteredStructureSet(structure);
</ins><span class="cx">         setClobbered(false);
</span><span class="cx">         return *this;
</span><span class="cx">     }
</span><del>-    ALWAYS_INLINE StructureAbstractValue&amp; operator=(const StructureSet&amp; other)
</del><ins>+    ALWAYS_INLINE StructureAbstractValue&amp; operator=(const RegisteredStructureSet&amp; other)
</ins><span class="cx">     {
</span><span class="cx">         m_set = other;
</span><span class="cx">         setClobbered(false);
</span><span class="lines">@@ -98,7 +99,7 @@
</span><span class="cx">     void clobber();
</span><span class="cx">     void observeInvalidationPoint() { setClobbered(false); }
</span><span class="cx">     
</span><del>-    void observeTransition(Structure* from, Structure* to);
</del><ins>+    void observeTransition(RegisteredStructure from, RegisteredStructure to);
</ins><span class="cx">     void observeTransitions(const TransitionVector&amp;);
</span><span class="cx">     
</span><span class="cx">     static StructureAbstractValue top()
</span><span class="lines">@@ -131,9 +132,9 @@
</span><span class="cx">     // An infinite structure abstract value may currently have any structure.
</span><span class="cx">     bool isInfinite() const { return !isFinite(); }
</span><span class="cx">     
</span><del>-    bool add(Structure* structure);
</del><ins>+    bool add(RegisteredStructure);
</ins><span class="cx">     
</span><del>-    bool merge(const StructureSet&amp; other);
</del><ins>+    bool merge(const RegisteredStructureSet&amp; other);
</ins><span class="cx">     
</span><span class="cx">     ALWAYS_INLINE bool merge(const StructureAbstractValue&amp; other)
</span><span class="cx">     {
</span><span class="lines">@@ -151,7 +152,7 @@
</span><span class="cx">         return mergeSlow(other);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void filter(const StructureSet&amp; other);
</del><ins>+    void filter(const RegisteredStructureSet&amp; other);
</ins><span class="cx">     void filter(const StructureAbstractValue&amp; other);
</span><span class="cx">     
</span><span class="cx">     ALWAYS_INLINE void filter(SpeculatedType type)
</span><span class="lines">@@ -178,11 +179,17 @@
</span><span class="cx">         return equalsSlow(other);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    const StructureSet&amp; set() const
</del><ins>+    const RegisteredStructureSet&amp; set() const
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(!isTop());
</span><span class="cx">         return m_set;
</span><span class="cx">     }
</span><ins>+
+    StructureSet toStructureSet() const
+    {
+        RELEASE_ASSERT(isFinite());
+        return m_set.toStructureSet();
+    }
</ins><span class="cx">     
</span><span class="cx">     size_t size() const
</span><span class="cx">     {
</span><span class="lines">@@ -190,21 +197,21 @@
</span><span class="cx">         return m_set.size();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Structure* at(size_t i) const
</del><ins>+    RegisteredStructure at(size_t i) const
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(!isTop());
</span><span class="cx">         return m_set.at(i);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Structure* operator[](size_t i) const { return at(i); }
</del><ins>+    RegisteredStructure operator[](size_t i) const { return at(i); }
</ins><span class="cx"> 
</span><span class="cx">     // In most cases, what you really want to do is verify whether the set is top or clobbered, and
</span><span class="cx">     // if not, enumerate the set of structures. Use this only in cases where the singleton case is
</span><span class="cx">     // meaningfully special, like for transitions.
</span><del>-    Structure* onlyStructure() const
</del><ins>+    RegisteredStructure onlyStructure() const
</ins><span class="cx">     {
</span><span class="cx">         if (isInfinite())
</span><del>-            return nullptr;
</del><ins>+            return RegisteredStructure();
</ins><span class="cx">         return m_set.onlyStructure();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -224,18 +231,19 @@
</span><span class="cx">     // optimizations as a consequence of the &quot;this is smaller&quot; return value - so false for
</span><span class="cx">     // contains(), true for isSubsetOf(), false for isSupersetOf(), and false for overlaps().
</span><span class="cx"> 
</span><ins>+    bool contains(RegisteredStructure) const;
</ins><span class="cx">     bool contains(Structure* structure) const;
</span><span class="cx">     
</span><del>-    bool isSubsetOf(const StructureSet&amp; other) const;
</del><ins>+    bool isSubsetOf(const RegisteredStructureSet&amp; other) const;
</ins><span class="cx">     bool isSubsetOf(const StructureAbstractValue&amp; other) const;
</span><span class="cx">     
</span><del>-    bool isSupersetOf(const StructureSet&amp; other) const;
</del><ins>+    bool isSupersetOf(const RegisteredStructureSet&amp; other) const;
</ins><span class="cx">     bool isSupersetOf(const StructureAbstractValue&amp; other) const
</span><span class="cx">     {
</span><span class="cx">         return other.isSubsetOf(*this);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool overlaps(const StructureSet&amp; other) const;
</del><ins>+    bool overlaps(const RegisteredStructureSet&amp; other) const;
</ins><span class="cx">     bool overlaps(const StructureAbstractValue&amp; other) const;
</span><span class="cx"> 
</span><span class="cx">     bool isSubClassOf(const ClassInfo*) const;
</span><span class="lines">@@ -243,8 +251,8 @@
</span><span class="cx">     void validateReferences(const TrackedReferences&amp;) const;
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    static const uintptr_t clobberedFlag = StructureSet::reservedFlag;
-    static const uintptr_t topValue = StructureSet::reservedValue;
</del><ins>+    static const uintptr_t clobberedFlag = RegisteredStructureSet::reservedFlag;
+    static const uintptr_t topValue = RegisteredStructureSet::reservedValue;
</ins><span class="cx">     static const unsigned polymorphismLimit = 10;
</span><span class="cx">     static const unsigned clobberedSupremacyThreshold = 2;
</span><span class="cx">     
</span><span class="lines">@@ -260,7 +268,7 @@
</span><span class="cx">         m_set.m_pointer = topValue;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool mergeNotTop(const StructureSet&amp; other);
</del><ins>+    bool mergeNotTop(const RegisteredStructureSet&amp; other);
</ins><span class="cx">     
</span><span class="cx">     void setClobbered(bool clobbered)
</span><span class="cx">     {
</span><span class="lines">@@ -268,7 +276,7 @@
</span><span class="cx">         m_set.setReservedFlag(clobbered);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StructureSet m_set;
</del><ins>+    RegisteredStructureSet m_set;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp"></a>
<div class="delfile"><h4>Deleted: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -1,227 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include &quot;config.h&quot;
-#include &quot;DFGStructureRegistrationPhase.h&quot;
-
-#if ENABLE(DFG_JIT)
-
-#include &quot;DFGBasicBlockInlines.h&quot;
-#include &quot;DFGGraph.h&quot;
-#include &quot;DFGPhase.h&quot;
-#include &quot;JSCInlines.h&quot;
-
-namespace JSC { namespace DFG {
-
-class StructureRegistrationPhase : public Phase {
-public:
-    StructureRegistrationPhase(Graph&amp; graph)
-        : Phase(graph, &quot;structure registration&quot;)
-    {
-    }
-    
-    bool run()
-    {
-        // FIXME: This phase shouldn't exist. We should have registered all structures by now, since
-        // we may already have done optimizations that rely on structures having been registered.
-        // Currently, we still have places where we don't register structures prior to this phase,
-        // but structures don't end up being used for optimization prior to this phase. That's a
-        // pretty fragile situation and we should fix it eventually.
-        // https://bugs.webkit.org/show_bug.cgi?id=147889
-        
-        // We need to set this before this phase finishes. This phase doesn't do anything
-        // conditioned on this field, except for assertIsRegistered() below. We intend for that
-        // method to behave as if the phase was already finished. So, we set this up here.
-        m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
-        
-        // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
-        // have to watch these because there is no way to transition away from it, but they are
-        // watchable and so we will assert if they aren't watched.
-        registerStructure(m_graph.m_vm.structureStructure.get());
-        registerStructure(m_graph.m_vm.stringStructure.get());
-        registerStructure(m_graph.m_vm.symbolStructure.get());
-        
-        for (FrozenValue* value : m_graph.m_frozenValues)
-            assertIsRegistered(value-&gt;structure());
-        
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-        
-            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
-                Node* node = block-&gt;at(nodeIndex);
-            
-                switch (node-&gt;op()) {
-                case CheckStructure:
-                    assertAreRegistered(node-&gt;structureSet());
-                    break;
-                
-                case NewObject:
-                case ArrayifyToStructure:
-                case NewStringObject:
-                    registerStructure(node-&gt;structure());
-                    break;
-                
-                case PutStructure:
-                case AllocatePropertyStorage:
-                case ReallocatePropertyStorage:
-                    registerStructure(node-&gt;transition()-&gt;previous);
-                    registerStructure(node-&gt;transition()-&gt;next);
-                    break;
-
-                case GetGetterSetterByOffset:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;getterSetterStructure());
-                    break;
-
-                case MultiGetByOffset:
-                    for (const MultiGetByOffsetCase&amp; getCase : node-&gt;multiGetByOffsetData().cases)
-                        registerStructures(getCase.set());
-                    break;
-                    
-                case MultiPutByOffset:
-                    for (unsigned i = node-&gt;multiPutByOffsetData().variants.size(); i--;) {
-                        PutByIdVariant&amp; variant = node-&gt;multiPutByOffsetData().variants[i];
-                        registerStructures(variant.oldStructure());
-                        if (variant.kind() == PutByIdVariant::Transition)
-                            registerStructure(variant.newStructure());
-                    }
-                    break;
-                    
-                case NewArray:
-                case NewArrayBuffer:
-                case NewArrayWithSize: {
-                    JSGlobalObject* globalObject = m_graph.globalObjectFor(node-&gt;origin.semantic);
-                    registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
-                    registerStructure(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
-                    break;
-                }
-
-                case NewArrayWithSpread: {
-                    JSGlobalObject* globalObject = m_graph.globalObjectFor(node-&gt;origin.semantic);
-                    if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
-                        // We've compiled assuming we're not having a bad time, so to be consistent
-                        // with AI we must say we produce an original array allocation structure.
-                        registerStructure(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous));
-                    } else
-                        registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
-                    break;
-                }
-
-                case Spread: {
-                    registerStructure(m_graph.m_vm.fixedArrayStructure.get());
-                    break;
-                }
-
-                case CreateRest: {
-                    if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
-                        JSGlobalObject* globalObject = m_graph.globalObjectFor(node-&gt;origin.semantic);
-                        registerStructure(globalObject-&gt;restParameterStructure());
-                    }
-                    break;
-                }
-                    
-                case NewTypedArray:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;typedArrayStructureConcurrently(node-&gt;typedArrayType()));
-                    break;
-                    
-                case ToString:
-                case CallStringConstructor:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;stringObjectStructure());
-                    break;
-                    
-                case CreateActivation:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;activationStructure());
-                    break;
-                    
-                case CreateDirectArguments:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;directArgumentsStructure());
-                    break;
-                    
-                case CreateScopedArguments:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;scopedArgumentsStructure());
-                    break;
-
-                case CreateClonedArguments:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;clonedArgumentsStructure());
-                    break;
-
-                case NewRegexp:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;regExpStructure());
-                    break;
-                case NewFunction:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;functionStructure());
-                    break;
-                case NewGeneratorFunction:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;generatorFunctionStructure());
-                    break;
-                case NewAsyncFunction:
-                    registerStructure(m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;asyncFunctionStructure());
-                    break;
-
-                default:
-                    break;
-                }
-            }
-        }
-        
-        return true;
-    }
-
-private:
-    void registerStructures(const StructureSet&amp; set)
-    {
-        for (Structure* structure : set)
-            registerStructure(structure);
-    }
-    
-    void registerStructure(Structure* structure)
-    {
-        if (structure)
-            m_graph.registerStructure(structure);
-    }
-
-    void assertAreRegistered(const StructureSet&amp; set)
-    {
-        for (Structure* structure : set)
-            assertIsRegistered(structure);
-    }
-
-    void assertIsRegistered(Structure* structure)
-    {
-        if (structure)
-            m_graph.assertIsRegistered(structure);
-    }
-};
-
-bool performStructureRegistration(Graph&amp; graph)
-{
-    return runPhase&lt;StructureRegistrationPhase&gt;(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
</del></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGStructureRegistrationPhaseh"></a>
<div class="delfile"><h4>Deleted: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -1,50 +0,0 @@
</span><del>-/*
- * 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. 
- */
-
-#pragma once
-
-#if ENABLE(DFG_JIT)
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// Registers any structures we know about as weak references, and sets watchpoints on any
-// such structures that we know of that are currently watchable. It's somewhat
-// counterintuitive, but this ends up being the cleanest and most effective way of reducing
-// structure checks on terminal structures:
-//
-// - We used to only set watchpoints on watchable structures if we knew that this would
-//   remove a structure check. Experiments show that switching from that, to blindly
-//   setting watchpoints on all watchable structures, was not a regression.
-//
-// - It makes abstract interpretation a whole lot easier. We just assume that watchable
-//   structures are unclobberable without having to do any other logic.
-
-bool performStructureRegistration(Graph&amp;);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
</del></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGTransitioncpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Transition::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><del>-    out.print(pointerDumpInContext(previous, context), &quot; -&gt; &quot;, pointerDumpInContext(next, context));
</del><ins>+    out.print(pointerDumpInContext(previous.get(), context), &quot; -&gt; &quot;, pointerDumpInContext(next.get(), context));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Transition::dump(PrintStream&amp; out) const
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGTransitionh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTransition.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;DFGRegisteredStructure.h&quot;
</ins><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -38,16 +39,12 @@
</span><span class="cx"> namespace DFG {
</span><span class="cx"> 
</span><span class="cx"> struct Transition {
</span><del>-    Structure* previous;
-    Structure* next;
</del><ins>+    RegisteredStructure previous;
+    RegisteredStructure next;
</ins><span class="cx">     
</span><del>-    Transition()
-        : previous(nullptr)
-        , next(nullptr)
-    {
-    }
</del><ins>+    Transition() = default;
</ins><span class="cx">     
</span><del>-    Transition(Structure* previous, Structure* next)
</del><ins>+    Transition(RegisteredStructure previous, RegisteredStructure next)
</ins><span class="cx">         : previous(previous)
</span><span class="cx">         , next(next)
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -468,23 +468,23 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void noticeStructureCheck(VariableAccessData* variable, Structure* structure)
</del><ins>+    void noticeStructureCheck(VariableAccessData* variable, RegisteredStructure structure)
</ins><span class="cx">     {
</span><del>-        HashMap&lt;VariableAccessData*, CheckData&gt;::AddResult result = m_map.add(variable, CheckData(structure));
</del><ins>+        HashMap&lt;VariableAccessData*, CheckData&gt;::AddResult result = m_map.add(variable, CheckData(structure.get()));
</ins><span class="cx">         if (result.isNewEntry)
</span><span class="cx">             return;
</span><del>-        if (result.iterator-&gt;value.m_structure == structure)
</del><ins>+        if (result.iterator-&gt;value.m_structure == structure.get())
</ins><span class="cx">             return;
</span><span class="cx">         result.iterator-&gt;value.m_structure = 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void noticeStructureCheck(VariableAccessData* variable, const StructureSet&amp; set)
</del><ins>+    void noticeStructureCheck(VariableAccessData* variable, RegisteredStructureSet set)
</ins><span class="cx">     {
</span><span class="cx">         if (set.size() != 1) {
</span><del>-            noticeStructureCheck(variable, 0);
</del><ins>+            noticeStructureCheck(variable, RegisteredStructure());
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        noticeStructureCheck(variable, set.onlyStructure());
</del><ins>+        noticeStructureCheck(variable, set.at(0));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void noticeCheckArray(VariableAccessData* variable, ArrayMode arrayMode)
</span><span class="lines">@@ -504,7 +504,7 @@
</span><span class="cx">         result.iterator-&gt;value.disableCheckArrayHoisting();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void noticeStructureCheckAccountingForArrayMode(VariableAccessData* variable, Structure* structure)
</del><ins>+    void noticeStructureCheckAccountingForArrayMode(VariableAccessData* variable, RegisteredStructure structure)
</ins><span class="cx">     {
</span><span class="cx">         HashMap&lt;VariableAccessData*, CheckData&gt;::iterator result = m_map.find(variable);
</span><span class="cx">         if (result == m_map.end())
</span><span class="lines">@@ -511,15 +511,15 @@
</span><span class="cx">             return;
</span><span class="cx">         if (!result-&gt;value.m_arrayModeHoistingOkay || !result-&gt;value.m_arrayModeIsValid)
</span><span class="cx">             return;
</span><del>-        if (result-&gt;value.m_arrayMode.structureWouldPassArrayModeFiltering(structure))
</del><ins>+        if (result-&gt;value.m_arrayMode.structureWouldPassArrayModeFiltering(structure.get()))
</ins><span class="cx">             return;
</span><span class="cx">         result-&gt;value.disableCheckArrayHoisting();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void noticeStructureCheckAccountingForArrayMode(VariableAccessData* variable, const StructureSet&amp; set)
</del><ins>+    void noticeStructureCheckAccountingForArrayMode(VariableAccessData* variable, RegisteredStructureSet set)
</ins><span class="cx">     {
</span><span class="cx">         for (unsigned i = 0; i &lt; set.size(); i++)
</span><del>-            noticeStructureCheckAccountingForArrayMode(variable, set[i]);
</del><ins>+            noticeStructureCheckAccountingForArrayMode(variable, set.at(i));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     HashMap&lt;VariableAccessData*, CheckData&gt; m_map;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGValidate.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGValidate.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGValidate.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -209,7 +209,7 @@
</span><span class="cx">                         || node-&gt;origin.forExit != previousNode-&gt;origin.forExit);
</span><span class="cx">                 }
</span><span class="cx">                 
</span><del>-                VALIDATE((node), !node-&gt;hasStructure() || !!node-&gt;structure());
</del><ins>+                VALIDATE((node), !node-&gt;hasStructure() || !!node-&gt;structure().get());
</ins><span class="cx">                 VALIDATE((node), !node-&gt;hasCellOperand() || node-&gt;cellOperand()-&gt;value().isCell());
</span><span class="cx">                 VALIDATE((node), !node-&gt;hasCellOperand() || !!node-&gt;cellOperand()-&gt;value());
</span><span class="cx">                 
</span><span class="lines">@@ -285,7 +285,7 @@
</span><span class="cx">                     }
</span><span class="cx">                     break;
</span><span class="cx">                 case MaterializeNewObject:
</span><del>-                    for (Structure* structure : node-&gt;structureSet()) {
</del><ins>+                    for (RegisteredStructure structure : node-&gt;structureSet()) {
</ins><span class="cx">                         // This only supports structures that are JSFinalObject or JSArray.
</span><span class="cx">                         VALIDATE(
</span><span class="cx">                             (node),
</span><span class="lines">@@ -565,7 +565,7 @@
</span><span class="cx">                     // CPS disallows int32 and double arrays. Those require weird type checks and
</span><span class="cx">                     // conversions. They are not needed in the DFG right now. We should add support
</span><span class="cx">                     // for these if the DFG ever needs it.
</span><del>-                    for (Structure* structure : node-&gt;structureSet()) {
</del><ins>+                    for (RegisteredStructure structure : node-&gt;structureSet()) {
</ins><span class="cx">                         VALIDATE((node), !hasInt32(structure-&gt;indexingType()));
</span><span class="cx">                         VALIDATE((node), !hasDouble(structure-&gt;indexingType()));
</span><span class="cx">                     }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -196,7 +196,9 @@
</span><span class="cx">         m_proc.addFastConstant(m_tagTypeNumber-&gt;key());
</span><span class="cx">         m_proc.addFastConstant(m_tagMask-&gt;key());
</span><span class="cx">         
</span><del>-        m_out.storePtr(m_out.constIntPtr(codeBlock()), addressFor(CallFrameSlot::codeBlock));
</del><ins>+        // We don't want the CodeBlock to have a weak pointer to itself because
+        // that would cause it to always get collected.
+        m_out.storePtr(m_out.constIntPtr(bitwise_cast&lt;intptr_t&gt;(codeBlock())), addressFor(CallFrameSlot::codeBlock));
</ins><span class="cx"> 
</span><span class="cx">         // Stack Overflow Check.
</span><span class="cx">         unsigned exitFrameSize = m_graph.requiredRegisterCountForExit() * sizeof(Register);
</span><span class="lines">@@ -1560,7 +1562,7 @@
</span><span class="cx">         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
</span><span class="cx"> 
</span><span class="cx">         m_out.appendTo(slowCase, continuation);
</span><del>-        ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, m_out.constIntPtr(globalObject), value));
</del><ins>+        ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, weakPointer(globalObject), value));
</ins><span class="cx">         m_out.jump(continuation);
</span><span class="cx"> 
</span><span class="cx">         m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -2664,7 +2666,7 @@
</span><span class="cx">             checkStructure(
</span><span class="cx">                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
</span><span class="cx">                 exitKind, m_node-&gt;structureSet(),
</span><del>-                [&amp;] (Structure* structure) {
</del><ins>+                [&amp;] (RegisteredStructure structure) {
</ins><span class="cx">                     return weakStructureID(structure);
</span><span class="cx">                 });
</span><span class="cx">             return;
</span><span class="lines">@@ -2684,7 +2686,7 @@
</span><span class="cx">             checkStructure(
</span><span class="cx">                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
</span><span class="cx">                 exitKind, m_node-&gt;structureSet(),
</span><del>-                [&amp;] (Structure* structure) {
</del><ins>+                [&amp;] (RegisteredStructure structure) {
</ins><span class="cx">                     return weakStructureID(structure);
</span><span class="cx">                 });
</span><span class="cx">             m_out.jump(continuation);
</span><span class="lines">@@ -2798,8 +2800,8 @@
</span><span class="cx">     {
</span><span class="cx">         m_ftlState.jitCode-&gt;common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
</span><span class="cx">         
</span><del>-        Structure* oldStructure = m_node-&gt;transition()-&gt;previous;
-        Structure* newStructure = m_node-&gt;transition()-&gt;next;
</del><ins>+        RegisteredStructure oldStructure = m_node-&gt;transition()-&gt;previous;
+        RegisteredStructure newStructure = m_node-&gt;transition()-&gt;next;
</ins><span class="cx">         ASSERT_UNUSED(oldStructure, oldStructure-&gt;indexingType() == newStructure-&gt;indexingType());
</span><span class="cx">         ASSERT(oldStructure-&gt;typeInfo().inlineTypeFlags() == newStructure-&gt;typeInfo().inlineTypeFlags());
</span><span class="cx">         ASSERT(oldStructure-&gt;typeInfo().type() == newStructure-&gt;typeInfo().type());
</span><span class="lines">@@ -3899,10 +3901,10 @@
</span><span class="cx">             // with one of the following indexing shapes: Int32, Contiguous, Double.
</span><span class="cx">             LValue structure = m_out.select(
</span><span class="cx">                 m_out.equal(indexingType, m_out.constInt32(ArrayWithInt32)),
</span><del>-                m_out.constIntPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithInt32)),
</del><ins>+                weakStructure(m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithInt32))),
</ins><span class="cx">                 m_out.select(m_out.equal(indexingType, m_out.constInt32(ArrayWithContiguous)),
</span><del>-                    m_out.constIntPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous)),
-                    m_out.constIntPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithDouble))));
</del><ins>+                    weakStructure(m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous))),
+                    weakStructure(m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithDouble)))));
</ins><span class="cx">             arrayResult = allocateJSArray(resultLength, structure, indexingType, false, false);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3994,13 +3996,13 @@
</span><span class="cx">     {
</span><span class="cx">         LValue scope = lowCell(m_node-&gt;child1());
</span><span class="cx">         SymbolTable* table = m_node-&gt;castOperand&lt;SymbolTable*&gt;();
</span><del>-        Structure* structure = m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;activationStructure();
</del><ins>+        RegisteredStructure structure = m_graph.registerStructure(m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;activationStructure());
</ins><span class="cx">         JSValue initializationValue = m_node-&gt;initializationValueForActivation();
</span><span class="cx">         ASSERT(initializationValue.isUndefined() || initializationValue == jsTDZValue());
</span><span class="cx">         if (table-&gt;singletonScope()-&gt;isStillValid()) {
</span><span class="cx">             LValue callResult = vmCall(
</span><span class="cx">                 Int64,
</span><del>-                m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
</del><ins>+                m_out.operation(operationCreateActivationDirect), m_callFrame, weakStructure(structure),
</ins><span class="cx">                 scope, weakPointer(table), m_out.constInt64(JSValue::encode(initializationValue)));
</span><span class="cx">             setJSValue(callResult);
</span><span class="cx">             return;
</span><span class="lines">@@ -4035,7 +4037,7 @@
</span><span class="cx">             [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                 return createLazyCallGenerator(
</span><span class="cx">                     operationCreateActivationDirect, locations[0].directGPR(),
</span><del>-                    CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
</del><ins>+                    CCallHelpers::TrustedImmPtr(structure.get()), locations[1].directGPR(),
</ins><span class="cx">                     CCallHelpers::TrustedImmPtr(table),
</span><span class="cx">                     CCallHelpers::TrustedImm64(JSValue::encode(initializationValue)));
</span><span class="cx">             },
</span><span class="lines">@@ -4065,10 +4067,10 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        Structure* structure =
</del><ins>+        RegisteredStructure structure = m_graph.registerStructure(
</ins><span class="cx">             isGeneratorFunction ? m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;generatorFunctionStructure() :
</span><span class="cx">             isAsyncFunction ? m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;asyncFunctionStructure() :
</span><del>-            m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;functionStructure();
</del><ins>+            m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;functionStructure());
</ins><span class="cx">         
</span><span class="cx">         LBasicBlock slowPath = m_out.newBlock();
</span><span class="cx">         LBasicBlock continuation = m_out.newBlock();
</span><span class="lines">@@ -4128,8 +4130,8 @@
</span><span class="cx">         // them be explicit arguments to this node.
</span><span class="cx">         // https://bugs.webkit.org/show_bug.cgi?id=142207
</span><span class="cx">         
</span><del>-        Structure* structure =
-            m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;directArgumentsStructure();
</del><ins>+        RegisteredStructure structure =
+            m_graph.registerStructure(m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;directArgumentsStructure());
</ins><span class="cx">         
</span><span class="cx">         unsigned minCapacity = m_graph.baselineCodeBlockFor(m_node-&gt;origin.semantic)-&gt;numParameters() - 1;
</span><span class="cx">         
</span><span class="lines">@@ -4170,7 +4172,7 @@
</span><span class="cx">             [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                 return createLazyCallGenerator(
</span><span class="cx">                     operationCreateDirectArguments, locations[0].directGPR(),
</span><del>-                    CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
</del><ins>+                    CCallHelpers::TrustedImmPtr(structure.get()), locations[1].directGPR(),
</ins><span class="cx">                     CCallHelpers::TrustedImm32(minCapacity));
</span><span class="cx">             }, length.value);
</span><span class="cx">         ValueFromBlock slowResult = m_out.anchor(callResult);
</span><span class="lines">@@ -4258,7 +4260,7 @@
</span><span class="cx">             LValue arrayLength = lowInt32(m_node-&gt;child1());
</span><span class="cx">             LBasicBlock loopStart = m_out.newBlock();
</span><span class="cx">             JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node-&gt;origin.semantic);
</span><del>-            Structure* structure = globalObject-&gt;restParameterStructure();
</del><ins>+            RegisteredStructure structure = m_graph.registerStructure(globalObject-&gt;restParameterStructure());
</ins><span class="cx">             ArrayValues arrayValues = allocateUninitializedContiguousJSArray(arrayLength, structure);
</span><span class="cx">             LValue array = arrayValues.array;
</span><span class="cx">             LValue butterfly = arrayValues.butterfly;
</span><span class="lines">@@ -4326,8 +4328,8 @@
</span><span class="cx">             speculate(m_graph.varArgChild(m_node, operandIndex));
</span><span class="cx">         
</span><span class="cx">         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node-&gt;origin.semantic);
</span><del>-        Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
-            m_node-&gt;indexingType());
</del><ins>+        RegisteredStructure structure = m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
+            m_node-&gt;indexingType()));
</ins><span class="cx"> 
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(m_node-&gt;indexingType())) {
</span><span class="cx">             unsigned numElements = m_node-&gt;numChildren();
</span><span class="lines">@@ -4372,7 +4374,7 @@
</span><span class="cx">         if (!m_node-&gt;numChildren()) {
</span><span class="cx">             setJSValue(vmCall(
</span><span class="cx">                 Int64, m_out.operation(operationNewEmptyArray), m_callFrame,
</span><del>-                m_out.constIntPtr(structure)));
</del><ins>+                weakStructure(structure)));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -4393,7 +4395,7 @@
</span><span class="cx">         
</span><span class="cx">         LValue result = vmCall(
</span><span class="cx">             Int64, m_out.operation(operationNewArray), m_callFrame,
</span><del>-            m_out.constIntPtr(structure), m_out.constIntPtr(buffer),
</del><ins>+            weakStructure(structure), m_out.constIntPtr(buffer),
</ins><span class="cx">             m_out.constIntPtr(m_node-&gt;numChildren()));
</span><span class="cx">         
</span><span class="cx">         m_out.storePtr(m_out.intPtrZero, m_out.absolute(scratchBuffer-&gt;activeLengthPtr()));
</span><span class="lines">@@ -4433,7 +4435,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            Structure* structure = m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous);
</del><ins>+            RegisteredStructure structure = m_graph.registerStructure(m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous));
</ins><span class="cx">             ArrayValues arrayValues = allocateUninitializedContiguousJSArray(length, structure);
</span><span class="cx">             LValue result = arrayValues.array;
</span><span class="cx">             LValue storage = arrayValues.butterfly;
</span><span class="lines">@@ -4655,8 +4657,8 @@
</span><span class="cx">     void compileNewArrayBuffer()
</span><span class="cx">     {
</span><span class="cx">         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node-&gt;origin.semantic);
</span><del>-        Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
-            m_node-&gt;indexingType());
</del><ins>+        RegisteredStructure structure = m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
+            m_node-&gt;indexingType()));
</ins><span class="cx">         
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(m_node-&gt;indexingType())) {
</span><span class="cx">             unsigned numElements = m_node-&gt;numConstants();
</span><span class="lines">@@ -4685,7 +4687,7 @@
</span><span class="cx">         
</span><span class="cx">         setJSValue(vmCall(
</span><span class="cx">             Int64, m_out.operation(operationNewArrayBuffer), m_callFrame,
</span><del>-            m_out.constIntPtr(structure), m_out.constIntPtr(m_node-&gt;startConstant()),
</del><ins>+            weakStructure(structure), m_out.constIntPtr(m_node-&gt;startConstant()),
</ins><span class="cx">             m_out.constIntPtr(m_node-&gt;numConstants())));
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -4694,14 +4696,14 @@
</span><span class="cx">         LValue publicLength = lowInt32(m_node-&gt;child1());
</span><span class="cx">         
</span><span class="cx">         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node-&gt;origin.semantic);
</span><del>-        Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
-            m_node-&gt;indexingType());
</del><ins>+        RegisteredStructure structure = m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(
+            m_node-&gt;indexingType()));
</ins><span class="cx">         
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(m_node-&gt;indexingType())) {
</span><span class="cx">             IndexingType indexingType = m_node-&gt;indexingType();
</span><span class="cx">             setJSValue(
</span><span class="cx">                 allocateJSArray(
</span><del>-                    publicLength, m_out.constIntPtr(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType)), m_out.constInt32(indexingType)).array);
</del><ins>+                    publicLength, weakPointer(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(indexingType)), m_out.constInt32(indexingType)).array);
</ins><span class="cx">             mutatorFence();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -4708,9 +4710,8 @@
</span><span class="cx">         
</span><span class="cx">         LValue structureValue = m_out.select(
</span><span class="cx">             m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)),
</span><del>-            m_out.constIntPtr(
-                globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)),
-            m_out.constIntPtr(structure));
</del><ins>+            weakStructure(m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage))),
+            weakStructure(structure));
</ins><span class="cx">         setJSValue(vmCall(Int64, m_out.operation(operationNewArrayWithSize), m_callFrame, structureValue, publicLength, m_out.intPtrZero));
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -4721,7 +4722,7 @@
</span><span class="cx">         
</span><span class="cx">         switch (m_node-&gt;child1().useKind()) {
</span><span class="cx">         case Int32Use: {
</span><del>-            Structure* structure = globalObject-&gt;typedArrayStructureConcurrently(type);
</del><ins>+            RegisteredStructure structure = m_graph.registerStructure(globalObject-&gt;typedArrayStructureConcurrently(type));
</ins><span class="cx"> 
</span><span class="cx">             LValue size = lowInt32(m_node-&gt;child1());
</span><span class="cx"> 
</span><span class="lines">@@ -4780,7 +4781,7 @@
</span><span class="cx">                 [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                     return createLazyCallGenerator(
</span><span class="cx">                         operationNewTypedArrayWithSizeForType(type), locations[0].directGPR(),
</span><del>-                        CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
</del><ins>+                        CCallHelpers::TrustedImmPtr(structure.get()), locations[1].directGPR(),
</ins><span class="cx">                         locations[2].directGPR());
</span><span class="cx">                 },
</span><span class="cx">                 size, storageValue);
</span><span class="lines">@@ -4812,7 +4813,7 @@
</span><span class="cx">     void compileAllocatePropertyStorage()
</span><span class="cx">     {
</span><span class="cx">         LValue object = lowCell(m_node-&gt;child1());
</span><del>-        setStorage(allocatePropertyStorage(object, m_node-&gt;transition()-&gt;previous));
</del><ins>+        setStorage(allocatePropertyStorage(object, m_node-&gt;transition()-&gt;previous.get()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void compileReallocatePropertyStorage()
</span><span class="lines">@@ -4823,7 +4824,7 @@
</span><span class="cx">         
</span><span class="cx">         setStorage(
</span><span class="cx">             reallocatePropertyStorage(
</span><del>-                object, oldStorage, transition-&gt;previous, transition-&gt;next));
</del><ins>+                object, oldStorage, transition-&gt;previous.get(), transition-&gt;next.get()));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileNukeStructureAndSetButterfly()
</span><span class="lines">@@ -5285,11 +5286,11 @@
</span><span class="cx">         LBasicBlock continuation = m_out.newBlock();
</span><span class="cx">         
</span><span class="cx">         Vector&lt;SwitchCase, 2&gt; cases;
</span><del>-        StructureSet baseSet;
</del><ins>+        RegisteredStructureSet baseSet;
</ins><span class="cx">         for (unsigned i = data.cases.size(); i--;) {
</span><span class="cx">             MultiGetByOffsetCase getCase = data.cases[i];
</span><span class="cx">             for (unsigned j = getCase.set().size(); j--;) {
</span><del>-                Structure* structure = getCase.set()[j];
</del><ins>+                RegisteredStructure structure = getCase.set()[j];
</ins><span class="cx">                 baseSet.add(structure);
</span><span class="cx">                 cases.append(SwitchCase(weakStructureID(structure), blocks[i], Weight(1)));
</span><span class="cx">             }
</span><span class="lines">@@ -5367,11 +5368,11 @@
</span><span class="cx">         LBasicBlock continuation = m_out.newBlock();
</span><span class="cx">         
</span><span class="cx">         Vector&lt;SwitchCase, 2&gt; cases;
</span><del>-        StructureSet baseSet;
</del><ins>+        RegisteredStructureSet baseSet;
</ins><span class="cx">         for (unsigned i = data.variants.size(); i--;) {
</span><span class="cx">             PutByIdVariant variant = data.variants[i];
</span><span class="cx">             for (unsigned j = variant.oldStructure().size(); j--;) {
</span><del>-                Structure* structure = variant.oldStructure()[j];
</del><ins>+                RegisteredStructure structure = m_graph.registerStructure(variant.oldStructure()[j]);
</ins><span class="cx">                 baseSet.add(structure);
</span><span class="cx">                 cases.append(SwitchCase(weakStructureID(structure), blocks[i], Weight(1)));
</span><span class="cx">             }
</span><span class="lines">@@ -5412,7 +5413,7 @@
</span><span class="cx">                 ASSERT(variant.oldStructureForTransition()-&gt;typeInfo().inlineTypeFlags() == variant.newStructure()-&gt;typeInfo().inlineTypeFlags());
</span><span class="cx">                 ASSERT(variant.oldStructureForTransition()-&gt;typeInfo().type() == variant.newStructure()-&gt;typeInfo().type());
</span><span class="cx">                 m_out.store32(
</span><del>-                    weakStructureID(variant.newStructure()), base, m_heaps.JSCell_structureID);
</del><ins>+                    weakStructureID(m_graph.registerStructure(variant.newStructure())), base, m_heaps.JSCell_structureID);
</ins><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             m_out.jump(continuation);
</span><span class="lines">@@ -7745,11 +7746,11 @@
</span><span class="cx">         LValue index = m_out.bitAnd(mask, unmaskedIndex);
</span><span class="cx">         LValue hashMapBucket = m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), buffer, m_out.zeroExt(index, Int64), ScaleEight));
</span><span class="cx">         ValueFromBlock bucketResult = m_out.anchor(hashMapBucket);
</span><del>-        m_out.branch(m_out.equal(hashMapBucket, m_out.constIntPtr(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::emptyValue())),
</del><ins>+        m_out.branch(m_out.equal(hashMapBucket, m_out.constIntPtr(bitwise_cast&lt;intptr_t&gt;(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::emptyValue()))),
</ins><span class="cx">             unsure(notPresentInTable), unsure(notEmptyValue));
</span><span class="cx"> 
</span><span class="cx">         m_out.appendTo(notEmptyValue, notDeletedValue);
</span><del>-        m_out.branch(m_out.equal(hashMapBucket, m_out.constIntPtr(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::deletedValue())),
</del><ins>+        m_out.branch(m_out.equal(hashMapBucket, m_out.constIntPtr(bitwise_cast&lt;intptr_t&gt;(HashMapImpl&lt;HashMapBucket&lt;HashMapBucketDataKey&gt;&gt;::deletedValue()))),
</ins><span class="cx">             unsure(loopAround), unsure(notDeletedValue));
</span><span class="cx"> 
</span><span class="cx">         m_out.appendTo(notDeletedValue, loopAround);
</span><span class="lines">@@ -8221,7 +8222,8 @@
</span><span class="cx"> 
</span><span class="cx">     void compileOverridesHasInstance()
</span><span class="cx">     {
</span><del>-        JSFunction* defaultHasInstanceFunction = jsCast&lt;JSFunction*&gt;(m_node-&gt;cellOperand()-&gt;value());
</del><ins>+        FrozenValue* defaultHasInstanceFunction = m_node-&gt;cellOperand();
+        ASSERT(defaultHasInstanceFunction-&gt;cell()-&gt;inherits(JSFunction::info()));
</ins><span class="cx"> 
</span><span class="cx">         LValue constructor = lowCell(m_node-&gt;child1());
</span><span class="cx">         LValue hasInstance = lowJSValue(m_node-&gt;child2());
</span><span class="lines">@@ -8232,7 +8234,7 @@
</span><span class="cx">         // Unlike in the DFG, we don't worry about cleaning this code up for the case where we have proven the hasInstanceValue is a constant as B3 should fix it for us.
</span><span class="cx"> 
</span><span class="cx">         ValueFromBlock notDefaultHasInstanceResult = m_out.anchor(m_out.booleanTrue);
</span><del>-        m_out.branch(m_out.notEqual(hasInstance, m_out.constIntPtr(defaultHasInstanceFunction)), unsure(continuation), unsure(defaultHasInstance));
</del><ins>+        m_out.branch(m_out.notEqual(hasInstance, frozenPointer(defaultHasInstanceFunction)), unsure(continuation), unsure(defaultHasInstance));
</ins><span class="cx"> 
</span><span class="cx">         LBasicBlock lastNext = m_out.appendTo(defaultHasInstance, continuation);
</span><span class="cx">         ValueFromBlock implementsDefaultHasInstanceResult = m_out.anchor(m_out.testIsZero32(
</span><span class="lines">@@ -8580,7 +8582,7 @@
</span><span class="cx">         LValue structure = lowCell(m_node-&gt;child1());
</span><span class="cx">         checkStructure(
</span><span class="cx">             structure, noValue(), BadCache, m_node-&gt;structureSet(),
</span><del>-            [this] (Structure* structure) {
</del><ins>+            [this] (RegisteredStructure structure) {
</ins><span class="cx">                 return weakStructure(structure);
</span><span class="cx">             });
</span><span class="cx">     }
</span><span class="lines">@@ -8605,7 +8607,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        const StructureSet&amp; set = m_node-&gt;structureSet();
</del><ins>+        RegisteredStructureSet set = m_node-&gt;structureSet();
</ins><span class="cx"> 
</span><span class="cx">         Vector&lt;LBasicBlock, 1&gt; blocks(set.size());
</span><span class="cx">         for (unsigned i = set.size(); i--;)
</span><span class="lines">@@ -8615,7 +8617,7 @@
</span><span class="cx">         
</span><span class="cx">         Vector&lt;SwitchCase, 1&gt; cases(set.size());
</span><span class="cx">         for (unsigned i = set.size(); i--;)
</span><del>-            cases[i] = SwitchCase(weakStructure(set[i]), blocks[i], Weight(1));
</del><ins>+            cases[i] = SwitchCase(weakStructure(set.at(i)), blocks[i], Weight(1));
</ins><span class="cx">         m_out.switchInstruction(
</span><span class="cx">             lowCell(m_graph.varArgChild(m_node, 0)), cases, dummyDefault, Weight(0));
</span><span class="cx">         
</span><span class="lines">@@ -8626,7 +8628,7 @@
</span><span class="cx">         for (unsigned i = set.size(); i--;) {
</span><span class="cx">             m_out.appendTo(blocks[i], i + 1 &lt; set.size() ? blocks[i + 1] : dummyDefault);
</span><span class="cx">             
</span><del>-            Structure* structure = set[i];
</del><ins>+            RegisteredStructure structure = set.at(i);
</ins><span class="cx">             
</span><span class="cx">             LValue object;
</span><span class="cx">             LValue butterfly;
</span><span class="lines">@@ -8708,7 +8710,7 @@
</span><span class="cx">                         [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                             return createLazyCallGenerator(
</span><span class="cx">                                 operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength,
</span><del>-                                locations[0].directGPR(), CCallHelpers::TrustedImmPtr(structure),
</del><ins>+                                locations[0].directGPR(), CCallHelpers::TrustedImmPtr(structure.get()),
</ins><span class="cx">                                 locations[1].directGPR(), locations[2].directGPR());
</span><span class="cx">                         },
</span><span class="cx">                         vectorLength, butterflyValue);
</span><span class="lines">@@ -8717,7 +8719,7 @@
</span><span class="cx">                         [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                             return createLazyCallGenerator(
</span><span class="cx">                                 operationNewObjectWithButterfly, locations[0].directGPR(),
</span><del>-                                CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR());
</del><ins>+                                CCallHelpers::TrustedImmPtr(structure.get()), locations[1].directGPR());
</ins><span class="cx">                         },
</span><span class="cx">                         butterflyValue);
</span><span class="cx">                 }
</span><span class="lines">@@ -8890,7 +8892,7 @@
</span><span class="cx">         LValue scope = lowCell(m_graph.varArgChild(m_node, 1));
</span><span class="cx">         SymbolTable* table = m_node-&gt;castOperand&lt;SymbolTable*&gt;();
</span><span class="cx">         ASSERT(table == m_graph.varArgChild(m_node, 0)-&gt;castConstant&lt;SymbolTable*&gt;());
</span><del>-        Structure* structure = m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;activationStructure();
</del><ins>+        RegisteredStructure structure = m_graph.registerStructure(m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;activationStructure());
</ins><span class="cx"> 
</span><span class="cx">         LBasicBlock slowPath = m_out.newBlock();
</span><span class="cx">         LBasicBlock continuation = m_out.newBlock();
</span><span class="lines">@@ -8917,7 +8919,7 @@
</span><span class="cx">             [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                 return createLazyCallGenerator(
</span><span class="cx">                     operationCreateActivationDirect, locations[0].directGPR(),
</span><del>-                    CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
</del><ins>+                    CCallHelpers::TrustedImmPtr(structure.get()), locations[1].directGPR(),
</ins><span class="cx">                     CCallHelpers::TrustedImmPtr(table),
</span><span class="cx">                     CCallHelpers::TrustedImm64(JSValue::encode(jsUndefined())));
</span><span class="cx">             }, scope);
</span><span class="lines">@@ -9042,11 +9044,12 @@
</span><span class="cx"> 
</span><span class="cx">     void compileNewRegexp()
</span><span class="cx">     {
</span><del>-        RegExp* regexp = m_node-&gt;castOperand&lt;RegExp*&gt;();
</del><ins>+        FrozenValue* regexp = m_node-&gt;cellOperand();
+        ASSERT(regexp-&gt;cell()-&gt;inherits(RegExp::info()));
</ins><span class="cx">         LValue result = vmCall(
</span><span class="cx">             pointerType(),
</span><span class="cx">             m_out.operation(operationNewRegexp), m_callFrame,
</span><del>-            m_out.constIntPtr(regexp));
</del><ins>+            frozenPointer(regexp));
</ins><span class="cx">         
</span><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span><span class="lines">@@ -9139,10 +9142,12 @@
</span><span class="cx">         CallSiteIndex callSiteIndex = m_ftlState.jitCode-&gt;common.addCodeOrigin(m_node-&gt;origin.semantic);
</span><span class="cx">         
</span><span class="cx">         m_out.storePtr(m_callFrame, packet, m_heaps.ShadowChicken_Packet_frame);
</span><del>-        m_out.storePtr(m_out.constIntPtr(ShadowChicken::Packet::tailMarker()), packet, m_heaps.ShadowChicken_Packet_callee);
</del><ins>+        m_out.storePtr(m_out.constIntPtr(bitwise_cast&lt;intptr_t&gt;(ShadowChicken::Packet::tailMarker())), packet, m_heaps.ShadowChicken_Packet_callee);
</ins><span class="cx">         m_out.store64(thisValue, packet, m_heaps.ShadowChicken_Packet_thisValue);
</span><span class="cx">         m_out.storePtr(scope, packet, m_heaps.ShadowChicken_Packet_scope);
</span><del>-        m_out.storePtr(m_out.constIntPtr(codeBlock()), packet, m_heaps.ShadowChicken_Packet_codeBlock);
</del><ins>+        // We don't want the CodeBlock to have a weak pointer to itself because
+        // that would cause it to always get collected.
+        m_out.storePtr(m_out.constIntPtr(bitwise_cast&lt;intptr_t&gt;(codeBlock())), packet, m_heaps.ShadowChicken_Packet_codeBlock);
</ins><span class="cx">         m_out.store32(m_out.constInt32(callSiteIndex.bits()), packet, m_heaps.ShadowChicken_Packet_callSiteIndex);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -9233,7 +9238,7 @@
</span><span class="cx">     template&lt;typename Functor&gt;
</span><span class="cx">     void checkStructure(
</span><span class="cx">         LValue structureDiscriminant, const FormattedValue&amp; formattedValue, ExitKind exitKind,
</span><del>-        const StructureSet&amp; set, const Functor&amp; weakStructureDiscriminant)
</del><ins>+        RegisteredStructureSet set, const Functor&amp; weakStructureDiscriminant)
</ins><span class="cx">     {
</span><span class="cx">         if (set.isEmpty()) {
</span><span class="cx">             terminate(exitKind);
</span><span class="lines">@@ -9368,16 +9373,18 @@
</span><span class="cx">             speculate(BadType, jsValueValue(value), edge.node(), isNotSymbol(value, provenType(edge)));
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        case InferredType::ObjectWithStructure:
</del><ins>+        case InferredType::ObjectWithStructure: {
+            RegisteredStructure structure = m_graph.registerStructure(type.structure());
</ins><span class="cx">             speculate(BadType, jsValueValue(value), edge.node(), isNotCell(value, provenType(edge)));
</span><del>-            if (!abstractValue(edge).m_structure.isSubsetOf(StructureSet(type.structure()))) {
</del><ins>+            if (!abstractValue(edge).m_structure.isSubsetOf(RegisteredStructureSet(structure))) {
</ins><span class="cx">                 speculate(
</span><span class="cx">                     BadType, jsValueValue(value), edge.node(),
</span><span class="cx">                     m_out.notEqual(
</span><span class="cx">                         m_out.load32(value, m_heaps.JSCell_structureID),
</span><del>-                        weakStructureID(type.structure())));
</del><ins>+                        weakStructureID(structure)));
</ins><span class="cx">             }
</span><span class="cx">             return;
</span><ins>+        }
</ins><span class="cx"> 
</span><span class="cx">         case InferredType::ObjectWithStructureOrOther: {
</span><span class="cx">             LBasicBlock cellCase = m_out.newBlock();
</span><span class="lines">@@ -9388,12 +9395,13 @@
</span><span class="cx"> 
</span><span class="cx">             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
</span><span class="cx"> 
</span><del>-            if (!abstractValue(edge).m_structure.isSubsetOf(StructureSet(type.structure()))) {
</del><ins>+            RegisteredStructure structure = m_graph.registerStructure(type.structure());
+            if (!abstractValue(edge).m_structure.isSubsetOf(RegisteredStructureSet(structure))) {
</ins><span class="cx">                 speculate(
</span><span class="cx">                     BadType, jsValueValue(value), edge.node(),
</span><span class="cx">                     m_out.notEqual(
</span><span class="cx">                         m_out.load32(value, m_heaps.JSCell_structureID),
</span><del>-                        weakStructureID(type.structure())));
</del><ins>+                        weakStructureID(structure)));
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             m_out.jump(continuation);
</span><span class="lines">@@ -10492,9 +10500,9 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LValue allocateObject(LValue allocator, Structure* structure, LValue butterfly, LBasicBlock slowPath)
</del><ins>+    LValue allocateObject(LValue allocator, RegisteredStructure structure, LValue butterfly, LBasicBlock slowPath)
</ins><span class="cx">     {
</span><del>-        return allocateObject(allocator, m_out.constIntPtr(structure), butterfly, slowPath);
</del><ins>+        return allocateObject(allocator, weakStructure(structure), butterfly, slowPath);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     LValue allocateObject(LValue allocator, LValue structure, LValue butterfly, LBasicBlock slowPath)
</span><span class="lines">@@ -10588,7 +10596,7 @@
</span><span class="cx">     
</span><span class="cx">     template&lt;typename ClassType&gt;
</span><span class="cx">     LValue allocateVariableSizedObject(
</span><del>-        LValue size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
</del><ins>+        LValue size, RegisteredStructure structure, LValue butterfly, LBasicBlock slowPath)
</ins><span class="cx">     {
</span><span class="cx">         LValue allocator = allocatorForSize(
</span><span class="cx">             *subspaceFor&lt;ClassType&gt;(vm()), size, slowPath);
</span><span class="lines">@@ -10604,9 +10612,9 @@
</span><span class="cx">         return allocateCell(allocator, structure, slowPath);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    LValue allocateObject(Structure* structure)
</del><ins>+    LValue allocateObject(RegisteredStructure structure)
</ins><span class="cx">     {
</span><del>-        size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</del><ins>+        size_t allocationSize = JSFinalObject::allocationSize(structure.get()-&gt;inlineCapacity());
</ins><span class="cx">         MarkedAllocator* allocator = subspaceFor&lt;JSFinalObject&gt;(vm())-&gt;allocatorFor(allocationSize);
</span><span class="cx">         
</span><span class="cx">         // FIXME: If the allocator is null, we could simply emit a normal C call to the allocator
</span><span class="lines">@@ -10629,7 +10637,7 @@
</span><span class="cx">             [=] (const Vector&lt;Location&gt;&amp; locations) -&gt; RefPtr&lt;LazySlowPath::Generator&gt; {
</span><span class="cx">                 return createLazyCallGenerator(
</span><span class="cx">                     operationNewObject, locations[0].directGPR(),
</span><del>-                    CCallHelpers::TrustedImmPtr(structure));
</del><ins>+                    CCallHelpers::TrustedImmPtr(structure.get()));
</ins><span class="cx">             });
</span><span class="cx">         ValueFromBlock slowResult = m_out.anchor(slowResultValue);
</span><span class="cx">         m_out.jump(continuation);
</span><span class="lines">@@ -10732,8 +10740,7 @@
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(largeCase, failCase);
</span><span class="cx">         ValueFromBlock largeStructure = m_out.anchor(
</span><del>-            m_out.constIntPtr(
-                globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)));
</del><ins>+            weakStructure(m_graph.registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage))));
</ins><span class="cx">         m_out.jump(slowCase);
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(failCase, slowCase);
</span><span class="lines">@@ -10762,12 +10769,12 @@
</span><span class="cx">             m_out.phi(pointerType(), fastButterfly, slowButterfly));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ArrayValues allocateUninitializedContiguousJSArray(LValue publicLength, Structure* structure)
</del><ins>+    ArrayValues allocateUninitializedContiguousJSArray(LValue publicLength, RegisteredStructure structure)
</ins><span class="cx">     {
</span><span class="cx">         bool shouldInitializeElements = false;
</span><span class="cx">         bool shouldLargeArraySizeCreateArrayStorage = false;
</span><span class="cx">         return allocateJSArray(
</span><del>-            publicLength, m_out.constIntPtr(structure), m_out.constInt32(structure-&gt;indexingType()), shouldInitializeElements,
</del><ins>+            publicLength, weakStructure(structure), m_out.constInt32(structure-&gt;indexingType()), shouldInitializeElements,
</ins><span class="cx">             shouldLargeArraySizeCreateArrayStorage);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -10909,7 +10916,7 @@
</span><span class="cx">                 m_out.appendTo(masqueradesCase);
</span><span class="cx">                 
</span><span class="cx">                 isTruthyObject = m_out.notEqual(
</span><del>-                    m_out.constIntPtr(m_graph.globalObjectFor(m_node-&gt;origin.semantic)),
</del><ins>+                    weakPointer(m_graph.globalObjectFor(m_node-&gt;origin.semantic)),
</ins><span class="cx">                     m_out.loadPtr(loadStructure(value), m_heaps.Structure_globalObject));
</span><span class="cx">             }
</span><span class="cx">             results.append(m_out.anchor(isTruthyObject));
</span><span class="lines">@@ -11008,7 +11015,7 @@
</span><span class="cx">             
</span><span class="cx">             results.append(m_out.anchor(
</span><span class="cx">                 m_out.equal(
</span><del>-                    m_out.constIntPtr(m_graph.globalObjectFor(m_node-&gt;origin.semantic)),
</del><ins>+                    weakPointer(m_graph.globalObjectFor(m_node-&gt;origin.semantic)),
</ins><span class="cx">                     m_out.loadPtr(structure, m_heaps.Structure_globalObject))));
</span><span class="cx">             m_out.jump(continuation);
</span><span class="cx">         }
</span><span class="lines">@@ -11930,12 +11937,12 @@
</span><span class="cx">         DFG_ASSERT(m_graph, m_node, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
</span><span class="cx">         
</span><span class="cx">         if (edge-&gt;op() == JSConstant) {
</span><del>-            JSValue value = edge-&gt;asJSValue();
-            if (!value.isCell()) {
</del><ins>+            FrozenValue* value = edge-&gt;constant();
+            if (!value-&gt;value().isCell()) {
</ins><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.intPtrZero;
</span><span class="cx">             }
</span><del>-            return m_out.constIntPtr(value.asCell());
</del><ins>+            return frozenPointer(value);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         LoweredNodeValue value = m_jsValueValues.get(edge.node());
</span><span class="lines">@@ -12900,10 +12907,10 @@
</span><span class="cx">     
</span><span class="cx">     void speculateStringObjectForStructureID(Edge edge, LValue structureID)
</span><span class="cx">     {
</span><del>-        Structure* stringObjectStructure =
-            m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;stringObjectStructure();
-        
-        if (abstractStructure(edge).isSubsetOf(StructureSet(stringObjectStructure)))
</del><ins>+        RegisteredStructure stringObjectStructure =
+            m_graph.registerStructure(m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;stringObjectStructure());
+
+        if (abstractStructure(edge).isSubsetOf(RegisteredStructureSet(stringObjectStructure)))
</ins><span class="cx">             return;
</span><span class="cx">         
</span><span class="cx">         speculate(
</span><span class="lines">@@ -13688,19 +13695,30 @@
</span><span class="cx"> 
</span><span class="cx">     LValue weakPointer(JSCell* pointer)
</span><span class="cx">     {
</span><ins>+        // There are weird relationships in how optimized CodeBlocks
+        // point to other CodeBlocks. We don't want to have them be
+        // part of the weak pointer set. For example, an optimized CodeBlock
+        // having a weak pointer to itself will cause it to get collected.
+        RELEASE_ASSERT(!jsDynamicCast&lt;CodeBlock*&gt;(pointer));
+
</ins><span class="cx">         addWeakReference(pointer);
</span><del>-        return m_out.constIntPtr(pointer);
</del><ins>+        return m_out.weakPointer(m_graph, pointer);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LValue weakStructureID(Structure* structure)
</del><ins>+    LValue frozenPointer(FrozenValue* value)
</ins><span class="cx">     {
</span><del>-        addWeakReference(structure);
</del><ins>+        return m_out.weakPointer(value);
+    }
+
+    LValue weakStructureID(RegisteredStructure structure)
+    {
</ins><span class="cx">         return m_out.constInt32(structure-&gt;id());
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    LValue weakStructure(Structure* structure)
</del><ins>+    LValue weakStructure(RegisteredStructure structure)
</ins><span class="cx">     {
</span><del>-        return weakPointer(structure);
</del><ins>+        ASSERT(!!structure.get());
+        return m_out.weakPointer(m_graph, structure.get());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     TypedPointer addressFor(LValue base, int operand, ptrdiff_t offset = 0)
</span><span class="lines">@@ -13808,7 +13826,9 @@
</span><span class="cx">         m_out.call(
</span><span class="cx">             Void,
</span><span class="cx">             m_out.constIntPtr(ftlUnreachable),
</span><del>-            m_out.constIntPtr(codeBlock()), m_out.constInt32(blockIndex),
</del><ins>+            // We don't want the CodeBlock to have a weak pointer to itself because
+            // that would cause it to always get collected.
+            m_out.constIntPtr(bitwise_cast&lt;intptr_t&gt;(codeBlock())), m_out.constInt32(blockIndex),
</ins><span class="cx">             m_out.constInt32(nodeIndex));
</span><span class="cx"> #endif
</span><span class="cx">         m_out.unreachable();
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOutput.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOutput.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOutput.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> #include &quot;FTLValueFromBlock.h&quot;
</span><span class="cx"> #include &quot;FTLWeight.h&quot;
</span><span class="cx"> #include &quot;FTLWeightedTarget.h&quot;
</span><ins>+#include &quot;HeapCell.h&quot;
</ins><span class="cx"> #include &lt;wtf/OrderMaker.h&gt;
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -104,9 +105,29 @@
</span><span class="cx"> 
</span><span class="cx">     LValue constBool(bool value);
</span><span class="cx">     LValue constInt32(int32_t value);
</span><ins>+
+    LValue weakPointer(DFG::Graph&amp; graph, JSCell* cell)
+    {
+        ASSERT(graph.m_plan.weakReferences.contains(cell));
+
+        if (sizeof(void*) == 8)
+            return constInt64(bitwise_cast&lt;intptr_t&gt;(cell));
+        return constInt32(bitwise_cast&lt;intptr_t&gt;(cell));
+    }
+
+    LValue weakPointer(DFG::FrozenValue* value)
+    {
+        RELEASE_ASSERT(value-&gt;value().isCell());
+
+        if (sizeof(void*) == 8)
+            return constInt64(bitwise_cast&lt;intptr_t&gt;(value-&gt;cell()));
+        return constInt32(bitwise_cast&lt;intptr_t&gt;(value-&gt;cell()));
+    }
+
</ins><span class="cx">     template&lt;typename T&gt;
</span><span class="cx">     LValue constIntPtr(T* value)
</span><span class="cx">     {
</span><ins>+        static_assert(!std::is_base_of&lt;HeapCell, T&gt;::value, &quot;To use a GC pointer, the graph must be aware of it. Use gcPointer instead and make sure the graph is aware of this reference.&quot;);
</ins><span class="cx">         if (sizeof(void*) == 8)
</span><span class="cx">             return constInt64(bitwise_cast&lt;intptr_t&gt;(value));
</span><span class="cx">         return constInt32(bitwise_cast&lt;intptr_t&gt;(value));
</span></span></pre></div>
<a id="branchessafari603branchSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WTF/ChangeLog (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WTF/ChangeLog        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/WTF/ChangeLog        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2017-01-27  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
+        Merge r211237. rdar://problem/30179506
+
+    2017-01-26  Saam Barati  &lt;sbarati@apple.com&gt;
+
+            Harden how the compiler references GC objects
+            https://bugs.webkit.org/show_bug.cgi?id=167277
+            &lt;rdar://problem/30179506&gt;
+
+            Reviewed by Filip Pizlo.
+
+            I made TinyPtrSet use bitwise_cast instead of static_cast
+            for its singleEntry() function so that it can work on pointer-like
+            types just as it can on actual pointer types.
+
+            An example of where this matters is when you have TinyPtrSet&lt;T&gt;
+            where T is defined to be a struct which wraps a pointer, e.g:
+
+            struct T {
+                void* m_pointer;
+            }
+
+            * wtf/TinyPtrSet.h:
+            (WTF::TinyPtrSet::singleEntry):
+
</ins><span class="cx"> 2017-01-26  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Merge r211168. rdar://problem/30154148
</span></span></pre></div>
<a id="branchessafari603branchSourceWTFwtfTinyPtrSeth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WTF/wtf/TinyPtrSet.h (211278 => 211279)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WTF/wtf/TinyPtrSet.h        2017-01-27 09:18:51 UTC (rev 211278)
+++ branches/safari-603-branch/Source/WTF/wtf/TinyPtrSet.h        2017-01-27 09:19:06 UTC (rev 211279)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> class TinyPtrSet {
</span><ins>+    static_assert(sizeof(T) == sizeof(void*), &quot;It's in the title of the class.&quot;);
</ins><span class="cx"> public:
</span><span class="cx">     TinyPtrSet()
</span><span class="cx">         : m_pointer(0)
</span><span class="lines">@@ -475,7 +476,7 @@
</span><span class="cx">     T singleEntry() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(isThin());
</span><del>-        return static_cast&lt;T&gt;(pointer());
</del><ins>+        return bitwise_cast&lt;T&gt;(pointer());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     OutOfLineList* list() const
</span></span></pre>
</div>
</div>

</body>
</html>