<!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>[211237] trunk/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/211237">211237</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2017-01-26 15:50:58 -0800 (Thu, 26 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.

Source/JavaScriptCore:

Since <a href="http://trac.webkit.org/projects/webkit/changeset/210971">r210971</a>, 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):

Source/WTF:

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):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureSetcpp">trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureSeth">trunk/Source/JavaScriptCore/bytecode/StructureSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModecpp">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayifySlowPathGeneratorh">trunk/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCallArrayAllocatorSlowPathGeneratorh">trunk/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCallCreateDirectArgumentsSlowPathGeneratorh">trunk/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommonDatacpp">trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDesiredWeakReferencescpp">trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilerh">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGMultiGetByOffsetDatacpp">trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGMultiGetByOffsetDatah">trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodecpp">trunk/Source/JavaScriptCore/dfg/DFGNode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOpInfoh">trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTransitioncpp">trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTransitionh">trunk/Source/JavaScriptCore/dfg/DFGTransition.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGValidatecpp">trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOutputh">trunk/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfTinyPtrSeth">trunk/Source/WTF/wtf/TinyPtrSet.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoredfgDFGRegisteredStructureh">trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGRegisteredStructureSetcpp">trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGRegisteredStructureSeth">trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhaseh">trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-01-26 23:50:58 UTC (rev 211237)
</span><span class="lines">@@ -1,3 +1,284 @@
</span><ins>+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):
+
</ins><span class="cx"> 2017-01-26  JF Bastien  &lt;jfbastien@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         OSR entry: delay outer-loop compilation when at inner-loop
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-26 23:50:58 UTC (rev 211237)
</span><span class="lines">@@ -520,8 +520,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">@@ -1441,6 +1439,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">@@ -1471,6 +1471,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">@@ -2977,8 +2978,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">@@ -3911,6 +3910,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">@@ -3941,6 +3942,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">@@ -7091,6 +7093,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">@@ -7123,8 +7128,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">@@ -8076,6 +8079,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">@@ -8291,7 +8295,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">@@ -8679,6 +8682,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">@@ -9997,7 +10001,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">@@ -10039,6 +10042,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="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCorebytecodeStructureSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCorebytecodeStructureSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureSet.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureSet.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/bytecode/StructureSet.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGArrayifySlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGCallArrayAllocatorSlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGCallCreateDirectArgumentsSlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGCommonDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGDesiredWeakReferencescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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,55 +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 (auto* node : *block) {
-            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">@@ -1468,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">@@ -1507,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="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGJITCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGMultiGetByOffsetDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGMultiGetByOffsetDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGMultiGetByOffsetData.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGOpInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGRegisteredStructurehfromrev211236trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhaseh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h (from rev 211236, trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h) (0 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructure.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGRegisteredStructureSetcppfromrev211236trunkSourceJavaScriptCorebytecodeStructureSetcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp (from rev 211236, trunk/Source/JavaScriptCore/bytecode/StructureSet.cpp) (0 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGRegisteredStructureSethfromrev211236trunkSourceJavaScriptCorebytecodeStructureSeth"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h (from rev 211236, trunk/Source/JavaScriptCore/bytecode/StructureSet.h) (0 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGRegisteredStructureSet.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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">@@ -2055,7 +2056,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">@@ -2146,7 +2147,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">@@ -2468,7 +2469,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">@@ -2478,13 +2479,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">@@ -2517,7 +2518,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">@@ -2526,13 +2527,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">@@ -2647,12 +2648,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">@@ -3900,7 +3901,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">@@ -5097,7 +5098,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">@@ -5109,11 +5110,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">@@ -6353,12 +6354,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">@@ -6391,10 +6392,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">@@ -6510,8 +6511,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">@@ -6552,7 +6553,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">@@ -6615,8 +6616,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">@@ -6681,8 +6682,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">@@ -6798,7 +6799,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">@@ -6825,8 +6826,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">@@ -6949,7 +6950,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">@@ -7266,17 +7267,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">@@ -7456,7 +7457,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">@@ -7580,7 +7581,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">@@ -7628,7 +7629,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">@@ -7857,10 +7858,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">@@ -7956,8 +7957,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">@@ -8401,10 +8402,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">@@ -9267,8 +9268,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="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGStructureAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</span><span class="lines">@@ -1,225 +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 (auto* node : *block) {
-                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="trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhaseh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGTransitioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGTransition.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGTransitionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTransition.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTransition.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGTransition.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</span><span class="lines">@@ -465,23 +465,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">@@ -501,7 +501,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">@@ -508,15 +508,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="trunkSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-01-26 23:50:58 UTC (rev 211237)
</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">@@ -4171,7 +4173,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">@@ -4259,7 +4261,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">@@ -4327,8 +4329,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">@@ -4373,7 +4375,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">@@ -4394,7 +4396,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">@@ -4434,7 +4436,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">@@ -4656,8 +4658,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">@@ -4686,7 +4688,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">@@ -4695,14 +4697,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">@@ -4709,9 +4711,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">@@ -4722,7 +4723,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">@@ -4781,7 +4782,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">@@ -4813,7 +4814,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">@@ -4824,7 +4825,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">@@ -5286,11 +5287,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">@@ -5368,11 +5369,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">@@ -5413,7 +5414,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">@@ -7746,11 +7747,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">@@ -8222,7 +8223,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">@@ -8233,7 +8235,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">@@ -8581,7 +8583,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">@@ -8606,7 +8608,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">@@ -8616,7 +8618,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">@@ -8627,7 +8629,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">@@ -8709,7 +8711,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">@@ -8718,7 +8720,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">@@ -8891,7 +8893,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">@@ -8918,7 +8920,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">@@ -9043,11 +9045,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">@@ -9140,10 +9143,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">@@ -9234,7 +9239,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">@@ -9369,16 +9374,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">@@ -9389,12 +9396,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">@@ -10493,9 +10501,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">@@ -10589,7 +10597,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">@@ -10605,9 +10613,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">@@ -10630,7 +10638,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">@@ -10733,8 +10741,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">@@ -10763,12 +10770,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">@@ -10910,7 +10917,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">@@ -11009,7 +11016,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">@@ -11931,12 +11938,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">@@ -12901,10 +12908,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">@@ -13689,19 +13696,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">@@ -13809,7 +13827,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="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2017-01-26 23:50:58 UTC (rev 211237)
</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="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/WTF/ChangeLog        2017-01-26 23:50:58 UTC (rev 211237)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+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-25  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Introduce an item-provider-based pasteboard wrapper
</span></span></pre></div>
<a id="trunkSourceWTFwtfTinyPtrSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/TinyPtrSet.h (211236 => 211237)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/TinyPtrSet.h        2017-01-26 23:50:28 UTC (rev 211236)
+++ trunk/Source/WTF/wtf/TinyPtrSet.h        2017-01-26 23:50:58 UTC (rev 211237)
</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>