<!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>[169795] branches/ftlopt/Source/JavaScriptCore</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/169795">169795</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-06-10 21:52:59 -0700 (Tue, 10 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ftlopt] DFG should use its own notion of JSValue, which we should call FrozenValue, that will carry around a copy of its structure
https://bugs.webkit.org/show_bug.cgi?id=133426

Reviewed by Geoffrey Garen.
        
The impetus for this was to provide some sense and reason to race conditions arising from
cell constants having their structure changed on the main thread - this is harmess because
we defend against it, but when it goes wrong, it can be difficult to reproduce because it
requires a race. Giving the DFG the ability to &quot;freeze&quot; a cell's structure fixes this.
        
But this patch goes quite a bit further, and completely rationalizes how the DFG reasons
about constants. It no longer relies on the CodeBlock constant pool at all, which allows
for a more object-oriented approach: for example a Node that has a constant can tell you
what constant it has without needing a CodeBlock.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::computeExitSiteData):
* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
(JSC::exitKindIsCountable):
* bytecode/ExitKind.h:
(JSC::isWatchpoint): Deleted.
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::hasExitSite):
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::hasExitSite):
* dfg/DFGAbstractInterpreter.h:
(JSC::DFG::AbstractInterpreter::filterByValue):
(JSC::DFG::AbstractInterpreter::setBuiltInConstant):
(JSC::DFG::AbstractInterpreter::setConstant):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::filterByValue):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::setOSREntryValue):
(JSC::DFG::AbstractValue::set):
(JSC::DFG::AbstractValue::filterByValue):
(JSC::DFG::AbstractValue::setMostSpecific): Deleted.
* dfg/DFGAbstractValue.h:
* dfg/DFGArgumentsSimplificationPhase.cpp:
(JSC::DFG::ArgumentsSimplificationPhase::run):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
(JSC::DFG::BackwardsPropagationPhase::isNotPosZero):
(JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
(JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::ByteCodeParser):
(JSC::DFG::ByteCodeParser::getDirect):
(JSC::DFG::ByteCodeParser::get):
(JSC::DFG::ByteCodeParser::getLocal):
(JSC::DFG::ByteCodeParser::setLocal):
(JSC::DFG::ByteCodeParser::setArgument):
(JSC::DFG::ByteCodeParser::jsConstant):
(JSC::DFG::ByteCodeParser::weakJSConstant):
(JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck):
(JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::emitFunctionChecks):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::handleMinMax):
(JSC::DFG::ByteCodeParser::handleIntrinsic):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::prepareToParseBlock):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
(JSC::DFG::ByteCodeParser::addConstant): Deleted.
(JSC::DFG::ByteCodeParser::getJSConstantForValue): Deleted.
(JSC::DFG::ByteCodeParser::getJSConstant): Deleted.
(JSC::DFG::ByteCodeParser::isJSConstant): Deleted.
(JSC::DFG::ByteCodeParser::isInt32Constant): Deleted.
(JSC::DFG::ByteCodeParser::valueOfJSConstant): Deleted.
(JSC::DFG::ByteCodeParser::valueOfInt32Constant): Deleted.
(JSC::DFG::ByteCodeParser::constantUndefined): Deleted.
(JSC::DFG::ByteCodeParser::constantNull): Deleted.
(JSC::DFG::ByteCodeParser::one): Deleted.
(JSC::DFG::ByteCodeParser::constantNaN): Deleted.
(JSC::DFG::ByteCodeParser::cellConstant): Deleted.
(JSC::DFG::ByteCodeParser::inferredConstant): Deleted.
(JSC::DFG::ByteCodeParser::ConstantRecord::ConstantRecord): Deleted.
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::constantCSE):
(JSC::DFG::CSEPhase::checkFunctionElimination):
(JSC::DFG::CSEPhase::performNodeCSE):
(JSC::DFG::CSEPhase::weakConstantCSE): Deleted.
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGCommon.h:
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
(JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupMakeRope):
(JSC::DFG::FixupPhase::truncateConstantToInt32):
(JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteLength):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
* dfg/DFGFrozenValue.cpp: Added.
(JSC::DFG::FrozenValue::emptySingleton):
(JSC::DFG::FrozenValue::dumpInContext):
(JSC::DFG::FrozenValue::dump):
* dfg/DFGFrozenValue.h: Added.
(JSC::DFG::FrozenValue::FrozenValue):
(JSC::DFG::FrozenValue::operator!):
(JSC::DFG::FrozenValue::value):
(JSC::DFG::FrozenValue::structure):
(JSC::DFG::FrozenValue::strengthenTo):
(JSC::DFG::FrozenValue::strength):
(JSC::DFG::FrozenValue::freeze):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::tryGetActivation):
(JSC::DFG::Graph::tryGetFoldableView):
(JSC::DFG::Graph::registerFrozenValues):
(JSC::DFG::Graph::visitChildren):
(JSC::DFG::Graph::freezeFragile):
(JSC::DFG::Graph::freeze):
(JSC::DFG::Graph::freezeStrong):
(JSC::DFG::Graph::convertToConstant):
(JSC::DFG::Graph::convertToStrongConstant):
(JSC::DFG::Graph::assertIsWatched):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
(JSC::DFG::Graph::convertToConstant): Deleted.
(JSC::DFG::Graph::constantRegisterForConstant): Deleted.
(JSC::DFG::Graph::getJSConstantSpeculation): Deleted.
(JSC::DFG::Graph::isConstant): Deleted.
(JSC::DFG::Graph::isJSConstant): Deleted.
(JSC::DFG::Graph::isInt32Constant): Deleted.
(JSC::DFG::Graph::isDoubleConstant): Deleted.
(JSC::DFG::Graph::isNumberConstant): Deleted.
(JSC::DFG::Graph::isBooleanConstant): Deleted.
(JSC::DFG::Graph::isCellConstant): Deleted.
(JSC::DFG::Graph::isFunctionConstant): Deleted.
(JSC::DFG::Graph::isInternalFunctionConstant): Deleted.
(JSC::DFG::Graph::valueOfJSConstant): Deleted.
(JSC::DFG::Graph::valueOfInt32Constant): Deleted.
(JSC::DFG::Graph::valueOfNumberConstant): Deleted.
(JSC::DFG::Graph::valueOfBooleanConstant): Deleted.
(JSC::DFG::Graph::valueOfFunctionConstant): Deleted.
(JSC::DFG::Graph::mulImmediateShouldSpeculateInt32): Deleted.
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
* dfg/DFGInsertionSet.h:
(JSC::DFG::InsertionSet::insertConstant):
(JSC::DFG::InsertionSet::insertConstantForUse):
* dfg/DFGIntegerCheckCombiningPhase.cpp:
(JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGLazyJSValue.cpp:
(JSC::DFG::LazyJSValue::getValue):
(JSC::DFG::LazyJSValue::strictEqual):
(JSC::DFG::LazyJSValue::dumpInContext):
* dfg/DFGLazyJSValue.h:
(JSC::DFG::LazyJSValue::LazyJSValue):
(JSC::DFG::LazyJSValue::tryGetValue):
(JSC::DFG::LazyJSValue::value):
(JSC::DFG::LazyJSValue::switchLookupValue):
* dfg/DFGMinifiedNode.cpp:
(JSC::DFG::MinifiedNode::fromNode):
* dfg/DFGMinifiedNode.h:
(JSC::DFG::belongsInMinifiedGraph):
(JSC::DFG::MinifiedNode::hasConstant):
(JSC::DFG::MinifiedNode::constant):
(JSC::DFG::MinifiedNode::hasConstantNumber): Deleted.
(JSC::DFG::MinifiedNode::constantNumber): Deleted.
(JSC::DFG::MinifiedNode::hasWeakConstant): Deleted.
(JSC::DFG::MinifiedNode::weakConstant): Deleted.
* dfg/DFGNode.h:
(JSC::DFG::Node::hasConstant):
(JSC::DFG::Node::constant):
(JSC::DFG::Node::convertToConstant):
(JSC::DFG::Node::asJSValue):
(JSC::DFG::Node::isInt32Constant):
(JSC::DFG::Node::asInt32):
(JSC::DFG::Node::asUInt32):
(JSC::DFG::Node::isDoubleConstant):
(JSC::DFG::Node::isNumberConstant):
(JSC::DFG::Node::asNumber):
(JSC::DFG::Node::isMachineIntConstant):
(JSC::DFG::Node::asMachineInt):
(JSC::DFG::Node::isBooleanConstant):
(JSC::DFG::Node::asBoolean):
(JSC::DFG::Node::isCellConstant):
(JSC::DFG::Node::asCell):
(JSC::DFG::Node::dynamicCastConstant):
(JSC::DFG::Node::function):
(JSC::DFG::Node::isWeakConstant): Deleted.
(JSC::DFG::Node::constantNumber): Deleted.
(JSC::DFG::Node::convertToWeakConstant): Deleted.
(JSC::DFG::Node::weakConstant): Deleted.
(JSC::DFG::Node::valueOfJSConstant): Deleted.
* dfg/DFGNodeType.h:
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
(JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
(JSC::DFG::SpeculativeJIT::silentFill):
(JSC::DFG::SpeculativeJIT::compileIn):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleInt32Branch):
(JSC::DFG::SpeculativeJIT::compileCurrentBlock):
(JSC::DFG::SpeculativeJIT::compileDoubleRep):
(JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithMod):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::valueOfJSConstantAsImm64):
(JSC::DFG::SpeculativeJIT::initConstantInfo):
(JSC::DFG::SpeculativeJIT::isConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isJSConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isInt32Constant): Deleted.
(JSC::DFG::SpeculativeJIT::isDoubleConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isNumberConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isBooleanConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isFunctionConstant): Deleted.
(JSC::DFG::SpeculativeJIT::valueOfInt32Constant): Deleted.
(JSC::DFG::SpeculativeJIT::valueOfNumberConstant): Deleted.
(JSC::DFG::SpeculativeJIT::addressOfDoubleConstant): Deleted.
(JSC::DFG::SpeculativeJIT::valueOfJSConstant): Deleted.
(JSC::DFG::SpeculativeJIT::valueOfBooleanConstant): Deleted.
(JSC::DFG::SpeculativeJIT::valueOfFunctionConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isNullConstant): Deleted.
(JSC::DFG::SpeculativeJIT::isInteger): Deleted.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
* dfg/DFGValueStrength.cpp: Added.
(WTF::printInternal):
* dfg/DFGValueStrength.h: Added.
(JSC::DFG::merge):
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
(JSC::DFG::VariableEventStream::reconstruct):
* dfg/DFGVariableEventStream.h:
* dfg/DFGWatchableStructureWatchingPhase.cpp:
(JSC::DFG::WatchableStructureWatchingPhase::run):
(JSC::DFG::WatchableStructureWatchingPhase::tryWatch):
* dfg/DFGWatchpointCollectionPhase.cpp:
(JSC::DFG::WatchpointCollectionPhase::handle):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
(JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
(JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
(JSC::FTL::LowerDFGToLLVM::compileCheckFunction):
(JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
(JSC::FTL::LowerDFGToLLVM::lowInt32):
(JSC::FTL::LowerDFGToLLVM::lowCell):
(JSC::FTL::LowerDFGToLLVM::lowBoolean):
(JSC::FTL::LowerDFGToLLVM::lowJSValue):
(JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
(JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant): Deleted.
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dumpInContext):
(JSC::JSValue::dumpInContextAssumingStructure):
* runtime/JSCJSValue.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesftloptSourceJavaScriptCoreCMakeListstxt">branches/ftlopt/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreChangeLog">branches/ftlopt/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeCallLinkStatuscpp">branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeExitKindcpp">branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeExitKindh">branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeGetByIdStatuscpp">branches/ftlopt/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodePutByIdStatuscpp">branches/ftlopt/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGAbstractInterpreterh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGAbstractValuecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGAbstractValueh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGArgumentsSimplificationPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGByteCodeParsercpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGCFGSimplificationPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGCSEPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGClobberizeh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGCommonh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGCommon.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGDoesGCcpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGFixupPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGGraphcpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGGraphh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGInsertionSeth">branches/ftlopt/Source/JavaScriptCore/dfg/DFGInsertionSet.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGIntegerCheckCombiningPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGJITCompilercpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGLazyJSValuecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGLazyJSValueh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGMinifiedNodecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGMinifiedNodeh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGNodeh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGNodeTypeh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGOSRExitCompilercpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGSafeToExecuteh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJITcpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJITh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGValidatecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGVariableEventStreamcpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGVariableEventStreamh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreftlFTLCapabilitiescpp">branches/ftlopt/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreftlFTLLinkcpp">branches/ftlopt/Source/JavaScriptCore/ftl/FTLLink.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">branches/ftlopt/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreftlFTLOSRExitCompilercpp">branches/ftlopt/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeJSCJSValuecpp">branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeJSCJSValueh">branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGFrozenValuecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGFrozenValueh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGValueStrengthcpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGValueStrengthh">branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesftloptSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/CMakeLists.txt (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/CMakeLists.txt        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/CMakeLists.txt        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx">     dfg/DFGFixupPhase.cpp
</span><span class="cx">     dfg/DFGFlushFormat.cpp
</span><span class="cx">     dfg/DFGFlushedAt.cpp
</span><ins>+    dfg/DFGFrozenValue.cpp
</ins><span class="cx">     dfg/DFGFunctionWhitelist.cpp
</span><span class="cx">     dfg/DFGGraph.cpp
</span><span class="cx">     dfg/DFGGraphSafepoint.cpp
</span><span class="lines">@@ -202,6 +203,7 @@
</span><span class="cx">     dfg/DFGUseKind.cpp
</span><span class="cx">     dfg/DFGValidate.cpp
</span><span class="cx">     dfg/DFGValueSource.cpp
</span><ins>+    dfg/DFGValueStrength.cpp
</ins><span class="cx">     dfg/DFGVariableAccessData.cpp
</span><span class="cx">     dfg/DFGVariableAccessDataDump.cpp
</span><span class="cx">     dfg/DFGVariableEvent.cpp
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ChangeLog (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,307 @@
</span><span class="cx"> 2014-06-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        [ftlopt] DFG should use its own notion of JSValue, which we should call FrozenValue, that will carry around a copy of its structure
+        https://bugs.webkit.org/show_bug.cgi?id=133426
+
+        Reviewed by Geoffrey Garen.
+        
+        The impetus for this was to provide some sense and reason to race conditions arising from
+        cell constants having their structure changed on the main thread - this is harmess because
+        we defend against it, but when it goes wrong, it can be difficult to reproduce because it
+        requires a race. Giving the DFG the ability to &quot;freeze&quot; a cell's structure fixes this.
+        
+        But this patch goes quite a bit further, and completely rationalizes how the DFG reasons
+        about constants. It no longer relies on the CodeBlock constant pool at all, which allows
+        for a more object-oriented approach: for example a Node that has a constant can tell you
+        what constant it has without needing a CodeBlock.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeExitSiteData):
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        (JSC::exitKindIsCountable):
+        * bytecode/ExitKind.h:
+        (JSC::isWatchpoint): Deleted.
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::hasExitSite):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::hasExitSite):
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::filterByValue):
+        (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
+        (JSC::DFG::AbstractInterpreter::setConstant):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::filterByValue):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setOSREntryValue):
+        (JSC::DFG::AbstractValue::set):
+        (JSC::DFG::AbstractValue::filterByValue):
+        (JSC::DFG::AbstractValue::setMostSpecific): Deleted.
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
+        (JSC::DFG::BackwardsPropagationPhase::isNotPosZero):
+        (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
+        (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::ByteCodeParser):
+        (JSC::DFG::ByteCodeParser::getDirect):
+        (JSC::DFG::ByteCodeParser::get):
+        (JSC::DFG::ByteCodeParser::getLocal):
+        (JSC::DFG::ByteCodeParser::setLocal):
+        (JSC::DFG::ByteCodeParser::setArgument):
+        (JSC::DFG::ByteCodeParser::jsConstant):
+        (JSC::DFG::ByteCodeParser::weakJSConstant):
+        (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::handleMinMax):
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::prepareToParseBlock):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        (JSC::DFG::ByteCodeParser::addConstant): Deleted.
+        (JSC::DFG::ByteCodeParser::getJSConstantForValue): Deleted.
+        (JSC::DFG::ByteCodeParser::getJSConstant): Deleted.
+        (JSC::DFG::ByteCodeParser::isJSConstant): Deleted.
+        (JSC::DFG::ByteCodeParser::isInt32Constant): Deleted.
+        (JSC::DFG::ByteCodeParser::valueOfJSConstant): Deleted.
+        (JSC::DFG::ByteCodeParser::valueOfInt32Constant): Deleted.
+        (JSC::DFG::ByteCodeParser::constantUndefined): Deleted.
+        (JSC::DFG::ByteCodeParser::constantNull): Deleted.
+        (JSC::DFG::ByteCodeParser::one): Deleted.
+        (JSC::DFG::ByteCodeParser::constantNaN): Deleted.
+        (JSC::DFG::ByteCodeParser::cellConstant): Deleted.
+        (JSC::DFG::ByteCodeParser::inferredConstant): Deleted.
+        (JSC::DFG::ByteCodeParser::ConstantRecord::ConstantRecord): Deleted.
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::run):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::constantCSE):
+        (JSC::DFG::CSEPhase::checkFunctionElimination):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        (JSC::DFG::CSEPhase::weakConstantCSE): Deleted.
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+        (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupMakeRope):
+        (JSC::DFG::FixupPhase::truncateConstantToInt32):
+        (JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteLength):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGFrozenValue.cpp: Added.
+        (JSC::DFG::FrozenValue::emptySingleton):
+        (JSC::DFG::FrozenValue::dumpInContext):
+        (JSC::DFG::FrozenValue::dump):
+        * dfg/DFGFrozenValue.h: Added.
+        (JSC::DFG::FrozenValue::FrozenValue):
+        (JSC::DFG::FrozenValue::operator!):
+        (JSC::DFG::FrozenValue::value):
+        (JSC::DFG::FrozenValue::structure):
+        (JSC::DFG::FrozenValue::strengthenTo):
+        (JSC::DFG::FrozenValue::strength):
+        (JSC::DFG::FrozenValue::freeze):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::tryGetActivation):
+        (JSC::DFG::Graph::tryGetFoldableView):
+        (JSC::DFG::Graph::registerFrozenValues):
+        (JSC::DFG::Graph::visitChildren):
+        (JSC::DFG::Graph::freezeFragile):
+        (JSC::DFG::Graph::freeze):
+        (JSC::DFG::Graph::freezeStrong):
+        (JSC::DFG::Graph::convertToConstant):
+        (JSC::DFG::Graph::convertToStrongConstant):
+        (JSC::DFG::Graph::assertIsWatched):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
+        (JSC::DFG::Graph::convertToConstant): Deleted.
+        (JSC::DFG::Graph::constantRegisterForConstant): Deleted.
+        (JSC::DFG::Graph::getJSConstantSpeculation): Deleted.
+        (JSC::DFG::Graph::isConstant): Deleted.
+        (JSC::DFG::Graph::isJSConstant): Deleted.
+        (JSC::DFG::Graph::isInt32Constant): Deleted.
+        (JSC::DFG::Graph::isDoubleConstant): Deleted.
+        (JSC::DFG::Graph::isNumberConstant): Deleted.
+        (JSC::DFG::Graph::isBooleanConstant): Deleted.
+        (JSC::DFG::Graph::isCellConstant): Deleted.
+        (JSC::DFG::Graph::isFunctionConstant): Deleted.
+        (JSC::DFG::Graph::isInternalFunctionConstant): Deleted.
+        (JSC::DFG::Graph::valueOfJSConstant): Deleted.
+        (JSC::DFG::Graph::valueOfInt32Constant): Deleted.
+        (JSC::DFG::Graph::valueOfNumberConstant): Deleted.
+        (JSC::DFG::Graph::valueOfBooleanConstant): Deleted.
+        (JSC::DFG::Graph::valueOfFunctionConstant): Deleted.
+        (JSC::DFG::Graph::mulImmediateShouldSpeculateInt32): Deleted.
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertConstant):
+        (JSC::DFG::InsertionSet::insertConstantForUse):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGLazyJSValue.cpp:
+        (JSC::DFG::LazyJSValue::getValue):
+        (JSC::DFG::LazyJSValue::strictEqual):
+        (JSC::DFG::LazyJSValue::dumpInContext):
+        * dfg/DFGLazyJSValue.h:
+        (JSC::DFG::LazyJSValue::LazyJSValue):
+        (JSC::DFG::LazyJSValue::tryGetValue):
+        (JSC::DFG::LazyJSValue::value):
+        (JSC::DFG::LazyJSValue::switchLookupValue):
+        * dfg/DFGMinifiedNode.cpp:
+        (JSC::DFG::MinifiedNode::fromNode):
+        * dfg/DFGMinifiedNode.h:
+        (JSC::DFG::belongsInMinifiedGraph):
+        (JSC::DFG::MinifiedNode::hasConstant):
+        (JSC::DFG::MinifiedNode::constant):
+        (JSC::DFG::MinifiedNode::hasConstantNumber): Deleted.
+        (JSC::DFG::MinifiedNode::constantNumber): Deleted.
+        (JSC::DFG::MinifiedNode::hasWeakConstant): Deleted.
+        (JSC::DFG::MinifiedNode::weakConstant): Deleted.
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasConstant):
+        (JSC::DFG::Node::constant):
+        (JSC::DFG::Node::convertToConstant):
+        (JSC::DFG::Node::asJSValue):
+        (JSC::DFG::Node::isInt32Constant):
+        (JSC::DFG::Node::asInt32):
+        (JSC::DFG::Node::asUInt32):
+        (JSC::DFG::Node::isDoubleConstant):
+        (JSC::DFG::Node::isNumberConstant):
+        (JSC::DFG::Node::asNumber):
+        (JSC::DFG::Node::isMachineIntConstant):
+        (JSC::DFG::Node::asMachineInt):
+        (JSC::DFG::Node::isBooleanConstant):
+        (JSC::DFG::Node::asBoolean):
+        (JSC::DFG::Node::isCellConstant):
+        (JSC::DFG::Node::asCell):
+        (JSC::DFG::Node::dynamicCastConstant):
+        (JSC::DFG::Node::function):
+        (JSC::DFG::Node::isWeakConstant): Deleted.
+        (JSC::DFG::Node::constantNumber): Deleted.
+        (JSC::DFG::Node::convertToWeakConstant): Deleted.
+        (JSC::DFG::Node::weakConstant): Deleted.
+        (JSC::DFG::Node::valueOfJSConstant): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRExitCompiler.cpp:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
+        (JSC::DFG::SpeculativeJIT::silentFill):
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleInt32Branch):
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+        (JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+        (JSC::DFG::SpeculativeJIT::compileAdd):
+        (JSC::DFG::SpeculativeJIT::compileArithSub):
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::valueOfJSConstantAsImm64):
+        (JSC::DFG::SpeculativeJIT::initConstantInfo):
+        (JSC::DFG::SpeculativeJIT::isConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isJSConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isInt32Constant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isDoubleConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isNumberConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isBooleanConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isFunctionConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::valueOfInt32Constant): Deleted.
+        (JSC::DFG::SpeculativeJIT::valueOfNumberConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::addressOfDoubleConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::valueOfJSConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::valueOfBooleanConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::valueOfFunctionConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isNullConstant): Deleted.
+        (JSC::DFG::SpeculativeJIT::isInteger): Deleted.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * dfg/DFGValueStrength.cpp: Added.
+        (WTF::printInternal):
+        * dfg/DFGValueStrength.h: Added.
+        (JSC::DFG::merge):
+        * dfg/DFGVariableEventStream.cpp:
+        (JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
+        (JSC::DFG::VariableEventStream::reconstruct):
+        * dfg/DFGVariableEventStream.h:
+        * dfg/DFGWatchableStructureWatchingPhase.cpp:
+        (JSC::DFG::WatchableStructureWatchingPhase::run):
+        (JSC::DFG::WatchableStructureWatchingPhase::tryWatch):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
+        (JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
+        (JSC::FTL::LowerDFGToLLVM::lowInt32):
+        (JSC::FTL::LowerDFGToLLVM::lowCell):
+        (JSC::FTL::LowerDFGToLLVM::lowBoolean):
+        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
+        (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant): Deleted.
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::dumpInContext):
+        (JSC::JSValue::dumpInContextAssumingStructure):
+        * runtime/JSCJSValue.h:
+
+2014-06-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         Unreviewed, roll out http://trac.webkit.org/changeset/169786.
</span><span class="cx">         It broke a lot of tests on 32-bit.
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -397,6 +397,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGFixupPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGFlushedAt.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGFlushFormat.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGFrozenValue.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGFunctionWhitelist.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGGraph.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGGraphSafepoint.cpp&quot; /&gt;
</span><span class="lines">@@ -455,6 +456,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGUseKind.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGValidate.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGValueSource.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGValueStrength.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGVariableAccessData.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGVariableAccessDataDump.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGVariableEvent.cpp&quot; /&gt;
</span><span class="lines">@@ -961,6 +963,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGFlushedAt.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGFlushFormat.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGFPRInfo.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGFrozenValue.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGFunctionWhitelist.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGGenerationInfo.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGGPRInfo.h&quot; /&gt;
</span><span class="lines">@@ -1036,6 +1039,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGValidate.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGValueRecoveryOverride.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGValueSource.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGValueStrength.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGVariableAccessData.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGVariableAccessDataDump.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGVariableEvent.h&quot; /&gt;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -74,6 +74,8 @@
</span><span class="cx"> /* End PBXAggregateTarget section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXBuildFile section */
</span><ins>+                0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */; };
+                0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0123311944EA1B00843A0C /* DFGValueStrength.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0332BF18ADFAE1005F979A /* ExitingJITType.cpp */; };
</span><span class="cx">                 0F0332C318B01763005F979A /* GetByIdVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0332C118B01763005F979A /* GetByIdVariant.cpp */; };
</span><span class="cx">                 0F0332C418B01763005F979A /* GetByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0332C218B01763005F979A /* GetByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -316,6 +318,8 @@
</span><span class="cx">                 0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */; };
+                0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F69CC87193AC60A0045759E /* DFGFrozenValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */; };
</span><span class="cx">                 0F6B1CB6185FC9E900845D97 /* FTLJSCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2235,6 +2239,8 @@
</span><span class="cx"> /* End PBXCopyFilesBuildPhase section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXFileReference section */
</span><ins>+                0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValueStrength.cpp; path = dfg/DFGValueStrength.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F0123311944EA1B00843A0C /* DFGValueStrength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValueStrength.h; path = dfg/DFGValueStrength.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F0332BF18ADFAE1005F979A /* ExitingJITType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitingJITType.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F0332C118B01763005F979A /* GetByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetByIdVariant.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F0332C218B01763005F979A /* GetByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetByIdVariant.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2477,6 +2483,8 @@
</span><span class="cx">                 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGResurrectionForValidationPhase.h; path = dfg/DFGResurrectionForValidationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFrozenValue.cpp; path = dfg/DFGFrozenValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F69CC87193AC60A0045759E /* DFGFrozenValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFrozenValue.h; path = dfg/DFGFrozenValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLJSCall.cpp; path = ftl/FTLJSCall.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLJSCall.h; path = ftl/FTLJSCall.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5064,6 +5072,8 @@
</span><span class="cx">                                 0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */,
</span><span class="cx">                                 A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
</span><span class="cx">                                 A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
</span><ins>+                                0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */,
+                                0F69CC87193AC60A0045759E /* DFGFrozenValue.h */,
</ins><span class="cx">                                 2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
</span><span class="cx">                                 2A88067719107D5500CB0BBB /* DFGFunctionWhitelist.h */,
</span><span class="cx">                                 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */,
</span><span class="lines">@@ -5196,6 +5206,8 @@
</span><span class="cx">                                 0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,
</span><span class="cx">                                 0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */,
</span><span class="cx">                                 0F2BDC401522801700CD8910 /* DFGValueSource.h */,
</span><ins>+                                0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */,
+                                0F0123311944EA1B00843A0C /* DFGValueStrength.h */,
</ins><span class="cx">                                 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */,
</span><span class="cx">                                 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */,
</span><span class="cx">                                 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */,
</span><span class="lines">@@ -5924,6 +5936,7 @@
</span><span class="cx">                                 0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
</span><span class="cx">                                 0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
</span><span class="cx">                                 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
</span><ins>+                                0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
</ins><span class="cx">                                 0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */,
</span><span class="cx">                                 BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
</span><span class="cx">                                 0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
</span><span class="lines">@@ -6435,6 +6448,7 @@
</span><span class="cx">                                 FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
</span><span class="cx">                                 0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
</span><span class="cx">                                 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
</span><ins>+                                0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
</ins><span class="cx">                                 0FCEFACE1805E75500472CE4 /* LLVMAPI.h in Headers */,
</span><span class="cx">                                 0FCEFACF1805E75500472CE4 /* LLVMAPIFunctions.h in Headers */,
</span><span class="cx">                                 A7E5AB381799E4B200D2833D /* LLVMDisassembler.h in Headers */,
</span><span class="lines">@@ -7529,6 +7543,7 @@
</span><span class="cx">                                 147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
</span><span class="cx">                                 0F24E54017EA9F5900ABB217 /* AssemblyHelpers.cpp in Sources */,
</span><span class="cx">                                 14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
</span><ins>+                                0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */,
</ins><span class="cx">                                 14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
</span><span class="cx">                                 14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
</span><span class="cx">                                 14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
</span><span class="lines">@@ -7613,6 +7628,7 @@
</span><span class="cx">                                 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
</span><span class="cx">                                 0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
</span><span class="cx">                                 0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
</span><ins>+                                0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */,
</ins><span class="cx">                                 A78A9774179738B8009DF744 /* DFGFailedFinalizer.cpp in Sources */,
</span><span class="cx">                                 A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */,
</span><span class="cx">                                 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCallLinkStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -147,7 +147,6 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     exitSiteData.m_takesSlowPath =
</span><span class="cx">         profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitingJITType))
</span><del>-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitingJITType))
</del><span class="cx">         || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable, exitingJITType));
</span><span class="cx">     exitSiteData.m_badFunction =
</span><span class="cx">         profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction, exitingJITType));
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeExitKindcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -44,12 +44,8 @@
</span><span class="cx">         return &quot;BadExecutable&quot;;
</span><span class="cx">     case BadCache:
</span><span class="cx">         return &quot;BadCache&quot;;
</span><del>-    case BadCacheWatchpoint:
-        return &quot;BadCacheWatchpoint&quot;;
-    case BadWeakConstantCache:
-        return &quot;BadWeakConstantCache&quot;;
-    case BadWeakConstantCacheWatchpoint:
-        return &quot;BadWeakConstantCacheWatchpoint&quot;;
</del><ins>+    case BadConstantCache:
+        return &quot;BadConstantCache&quot;;
</ins><span class="cx">     case BadIndexingType:
</span><span class="cx">         return &quot;BadIndexingType&quot;;
</span><span class="cx">     case Overflow:
</span><span class="lines">@@ -72,8 +68,6 @@
</span><span class="cx">         return &quot;NotStringObject&quot;;
</span><span class="cx">     case Uncountable:
</span><span class="cx">         return &quot;Uncountable&quot;;
</span><del>-    case UncountableWatchpoint:
-        return &quot;UncountableWatchpoint&quot;;
</del><span class="cx">     case UncountableInvalidation:
</span><span class="cx">         return &quot;UncountableInvalidation&quot;;
</span><span class="cx">     case WatchdogTimerFired:
</span><span class="lines">@@ -92,7 +86,6 @@
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     case BadType:
</span><span class="cx">     case Uncountable:
</span><del>-    case UncountableWatchpoint:
</del><span class="cx">     case LoadFromHole: // Already counted directly by the baseline JIT.
</span><span class="cx">     case StoreToHole: // Already counted directly by the baseline JIT.
</span><span class="cx">     case OutOfBounds: // Already counted directly by the baseline JIT.
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeExitKindh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/ExitKind.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -34,9 +34,7 @@
</span><span class="cx">     BadFunction, // We exited because we made an incorrect assumption about what function we would see.
</span><span class="cx">     BadExecutable, // We exited because we made an incorrect assumption about what executable we would see.
</span><span class="cx">     BadCache, // We exited because an inline cache was wrong.
</span><del>-    BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
-    BadCacheWatchpoint, // Same as BadCache but from a watchpoint.
-    BadWeakConstantCacheWatchpoint, // Same as BadWeakConstantCache but from a watchpoint.
</del><ins>+    BadConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
</ins><span class="cx">     BadIndexingType, // We exited because an indexing type was wrong.
</span><span class="cx">     Overflow, // We exited because of overflow.
</span><span class="cx">     NegativeZero, // We exited because we encountered negative zero.
</span><span class="lines">@@ -49,7 +47,6 @@
</span><span class="cx">     NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
</span><span class="cx">     Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
</span><span class="cx">     UncountableInvalidation, // We exited because the code block was invalidated; this means that we've already counted the reasons why the code block was invalidated.
</span><del>-    UncountableWatchpoint, // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
</del><span class="cx">     WatchdogTimerFired, // We exited because we need to service the watchdog timer.
</span><span class="cx">     DebuggerEvent // We exited because we need to service the debugger.
</span><span class="cx"> };
</span><span class="lines">@@ -57,18 +54,6 @@
</span><span class="cx"> const char* exitKindToString(ExitKind);
</span><span class="cx"> bool exitKindIsCountable(ExitKind);
</span><span class="cx"> 
</span><del>-inline bool isWatchpoint(ExitKind kind)
-{
-    switch (kind) {
-    case BadCacheWatchpoint:
-    case BadWeakConstantCacheWatchpoint:
-    case UncountableWatchpoint:
-        return true;
-    default:
-        return false;
-    }
-}
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -51,9 +51,7 @@
</span><span class="cx"> bool GetByIdStatus::hasExitSite(const ConcurrentJITLocker&amp; locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType jitType)
</span><span class="cx"> {
</span><span class="cx">     return profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, jitType))
</span><del>-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, jitType))
-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, jitType))
-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, jitType));
</del><ins>+        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache, jitType));
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -51,9 +51,7 @@
</span><span class="cx"> bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker&amp; locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType exitType)
</span><span class="cx"> {
</span><span class="cx">     return profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitType))
</span><del>-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitType))
-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, exitType))
-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, exitType));
</del><ins>+        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache, exitType));
</ins><span class="cx">     
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGAbstractInterpreterh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -136,7 +136,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename T&gt;
</span><del>-    FiltrationResult filterByValue(T node, JSValue value)
</del><ins>+    FiltrationResult filterByValue(T node, FrozenValue value)
</ins><span class="cx">     {
</span><span class="cx">         return filterByValue(forNode(node), value);
</span><span class="cx">     }
</span><span class="lines">@@ -144,7 +144,7 @@
</span><span class="cx">     FiltrationResult filter(AbstractValue&amp;, const StructureSet&amp;);
</span><span class="cx">     FiltrationResult filterArrayModes(AbstractValue&amp;, ArrayModes);
</span><span class="cx">     FiltrationResult filter(AbstractValue&amp;, SpeculatedType);
</span><del>-    FiltrationResult filterByValue(AbstractValue&amp;, JSValue);
</del><ins>+    FiltrationResult filterByValue(AbstractValue&amp;, FrozenValue);
</ins><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     void clobberWorld(const CodeOrigin&amp;, unsigned indexInBlock);
</span><span class="lines">@@ -165,14 +165,14 @@
</span><span class="cx">     };
</span><span class="cx">     BooleanResult booleanResult(Node*, AbstractValue&amp;);
</span><span class="cx">     
</span><del>-    void setBuiltInConstant(Node* node, JSValue value)
</del><ins>+    void setBuiltInConstant(Node* node, FrozenValue value)
</ins><span class="cx">     {
</span><span class="cx">         AbstractValue&amp; abstractValue = forNode(node);
</span><span class="cx">         abstractValue.set(m_graph, value, m_state.structureClobberState());
</span><span class="cx">         abstractValue.fixTypeForRepresentation(node);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void setConstant(Node* node, JSValue value)
</del><ins>+    void setConstant(Node* node, FrozenValue value)
</ins><span class="cx">     {
</span><span class="cx">         setBuiltInConstant(node, value);
</span><span class="cx">         m_state.setFoundConstants(true);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -137,9 +137,8 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><del>-    case WeakJSConstant:
</del><span class="cx">     case PhantomArguments: {
</span><del>-        setBuiltInConstant(node, m_graph.valueOfJSConstant(node));
</del><ins>+        setBuiltInConstant(node, *node-&gt;constant());
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -855,32 +854,32 @@
</span><span class="cx">         AbstractValue&amp; abstractChild = forNode(node-&gt;child1());
</span><span class="cx">         if (child) {
</span><span class="cx">             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock-&gt;globalObjectFor(node-&gt;origin.semantic), child);
</span><del>-            setConstant(node, typeString);
</del><ins>+            setConstant(node, *m_graph.freeze(typeString));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (isFullNumberSpeculation(abstractChild.m_type)) {
</span><del>-            setConstant(node, vm-&gt;smallStrings.numberString());
</del><ins>+            setConstant(node, *m_graph.freeze(vm-&gt;smallStrings.numberString()));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (isStringSpeculation(abstractChild.m_type)) {
</span><del>-            setConstant(node, vm-&gt;smallStrings.stringString());
</del><ins>+            setConstant(node, *m_graph.freeze(vm-&gt;smallStrings.stringString()));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
</span><del>-            setConstant(node, vm-&gt;smallStrings.objectString());
</del><ins>+            setConstant(node, *m_graph.freeze(vm-&gt;smallStrings.objectString()));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (isFunctionSpeculation(abstractChild.m_type)) {
</span><del>-            setConstant(node, vm-&gt;smallStrings.functionString());
</del><ins>+            setConstant(node, *m_graph.freeze(vm-&gt;smallStrings.functionString()));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (isBooleanSpeculation(abstractChild.m_type)) {
</span><del>-            setConstant(node, vm-&gt;smallStrings.booleanString());
</del><ins>+            setConstant(node, *m_graph.freeze(vm-&gt;smallStrings.booleanString()));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1432,7 +1431,7 @@
</span><span class="cx">     case SkipScope: {
</span><span class="cx">         JSValue child = forNode(node-&gt;child1()).value();
</span><span class="cx">         if (child) {
</span><del>-            setConstant(node, JSValue(jsCast&lt;JSScope*&gt;(child.asCell())-&gt;next()));
</del><ins>+            setConstant(node, *m_graph.freeze(JSValue(jsCast&lt;JSScope*&gt;(child.asCell())-&gt;next())));
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         forNode(node).setType(SpecObjectOther);
</span><span class="lines">@@ -1479,7 +1478,7 @@
</span><span class="cx">                             Structure* structure = status[0].specificValue().asCell()-&gt;structure();
</span><span class="cx">                             m_graph.watchpoints().consider(structure);
</span><span class="cx">                         }
</span><del>-                        setConstant(node, status[0].specificValue());
</del><ins>+                        setConstant(node, *m_graph.freeze(status[0].specificValue()));
</ins><span class="cx">                     } else
</span><span class="cx">                         forNode(node).makeHeapTop();
</span><span class="cx">                     filter(node-&gt;child1(), status[0].structureSet());
</span><span class="lines">@@ -1763,14 +1762,14 @@
</span><span class="cx">     
</span><span class="cx">     case CheckFunction: {
</span><span class="cx">         JSValue value = forNode(node-&gt;child1()).value();
</span><del>-        if (value == node-&gt;function()) {
</del><ins>+        if (value == node-&gt;function()-&gt;value()) {
</ins><span class="cx">             m_state.setFoundConstants(true);
</span><span class="cx">             ASSERT(value);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         node-&gt;setCanExit(true); // Lies! We can do better.
</span><del>-        filterByValue(node-&gt;child1(), node-&gt;function());
</del><ins>+        filterByValue(node-&gt;child1(), *node-&gt;function());
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -2124,7 +2123,7 @@
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><span class="cx"> FiltrationResult AbstractInterpreter&lt;AbstractStateType&gt;::filterByValue(
</span><del>-    AbstractValue&amp; abstractValue, JSValue concreteValue)
</del><ins>+    AbstractValue&amp; abstractValue, FrozenValue concreteValue)
</ins><span class="cx"> {
</span><span class="cx">     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
</span><span class="cx">         return FiltrationOK;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -47,10 +47,10 @@
</span><span class="cx">     checkConsistency();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AbstractValue::setMostSpecific(Graph&amp; graph, JSValue value)
</del><ins>+void AbstractValue::setOSREntryValue(Graph&amp; graph, const FrozenValue&amp; value)
</ins><span class="cx"> {
</span><del>-    if (!!value &amp;&amp; value.isCell()) {
-        Structure* structure = value.asCell()-&gt;structure();
</del><ins>+    if (!!value &amp;&amp; value.value().isCell()) {
+        Structure* structure = value.structure();
</ins><span class="cx">         graph.watchpoints().consider(structure);
</span><span class="cx">         m_structure = structure;
</span><span class="cx">         m_arrayModes = asArrayModes(structure-&gt;indexingType());
</span><span class="lines">@@ -59,17 +59,17 @@
</span><span class="cx">         m_arrayModes = 0;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    m_type = speculationFromValue(value);
-    m_value = value;
</del><ins>+    m_type = speculationFromValue(value.value());
+    m_value = value.value();
</ins><span class="cx">         
</span><span class="cx">     checkConsistency();
</span><span class="cx">     assertIsWatched(graph);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AbstractValue::set(Graph&amp; graph, JSValue value, StructureClobberState clobberState)
</del><ins>+void AbstractValue::set(Graph&amp; graph, const FrozenValue&amp; value, StructureClobberState clobberState)
</ins><span class="cx"> {
</span><del>-    if (!!value &amp;&amp; value.isCell()) {
-        Structure* structure = value.asCell()-&gt;structure();
</del><ins>+    if (!!value &amp;&amp; value.value().isCell()) {
+        Structure* structure = value.structure();
</ins><span class="cx">         if (graph.watchpoints().consider(structure)) {
</span><span class="cx">             // We should be able to assume that the watchpoint for this has already been set.
</span><span class="cx">             // But we can't because our view of what structure a value has keeps changing. That's
</span><span class="lines">@@ -90,8 +90,8 @@
</span><span class="cx">         m_arrayModes = 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    m_type = speculationFromValue(value);
-    m_value = value;
</del><ins>+    m_type = speculationFromValue(value.value());
+    m_value = value.value();
</ins><span class="cx">     
</span><span class="cx">     checkConsistency();
</span><span class="cx">     assertIsWatched(graph);
</span><span class="lines">@@ -221,11 +221,11 @@
</span><span class="cx">     return normalizeClarity();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-FiltrationResult AbstractValue::filterByValue(JSValue value)
</del><ins>+FiltrationResult AbstractValue::filterByValue(const FrozenValue&amp; value)
</ins><span class="cx"> {
</span><del>-    FiltrationResult result = filter(speculationFromValue(value));
</del><ins>+    FiltrationResult result = filter(speculationFromValue(value.value()));
</ins><span class="cx">     if (m_type)
</span><del>-        m_value = value;
</del><ins>+        m_value = value.value();
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGAbstractValueh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayProfile.h&quot;
</span><span class="cx"> #include &quot;DFGFiltrationResult.h&quot;
</span><ins>+#include &quot;DFGFrozenValue.h&quot;
</ins><span class="cx"> #include &quot;DFGNodeFlags.h&quot;
</span><span class="cx"> #include &quot;DFGStructureAbstractValue.h&quot;
</span><span class="cx"> #include &quot;DFGStructureClobberState.h&quot;
</span><span class="lines">@@ -173,8 +174,9 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void setMostSpecific(Graph&amp;, JSValue);
-    void set(Graph&amp;, JSValue, StructureClobberState);
</del><ins>+    void setOSREntryValue(Graph&amp;, const FrozenValue&amp;);
+    
+    void set(Graph&amp;, const FrozenValue&amp;, StructureClobberState);
</ins><span class="cx">     void set(Graph&amp;, Structure*);
</span><span class="cx">     void set(Graph&amp;, const StructureSet&amp;);
</span><span class="cx">     
</span><span class="lines">@@ -262,7 +264,7 @@
</span><span class="cx">     
</span><span class="cx">     FiltrationResult filter(SpeculatedType type);
</span><span class="cx">     
</span><del>-    FiltrationResult filterByValue(JSValue value);
</del><ins>+    FiltrationResult filterByValue(const FrozenValue&amp; value);
</ins><span class="cx">     
</span><span class="cx">     bool validate(JSValue value) const
</span><span class="cx">     {
</span><span class="lines">@@ -349,7 +351,11 @@
</span><span class="cx">     // implies nothing about the structure. Oddly, JSValue() (i.e. the empty value)
</span><span class="cx">     // means either BOTTOM or TOP depending on the state of m_type: if m_type is
</span><span class="cx">     // BOTTOM then JSValue() means BOTTOM; if m_type is not BOTTOM then JSValue()
</span><del>-    // means TOP.
</del><ins>+    // means TOP. Also note that this value isn't necessarily known to the GC
+    // (strongly or even weakly - it may be an &quot;fragile&quot; value, see
+    // DFGValueStrength.h). If you perform any optimization based on a cell m_value
+    // that requires that the value be kept alive, you must call freeze() on that
+    // value, which will turn it into a weak value.
</ins><span class="cx">     JSValue m_value;
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGArgumentsSimplificationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -208,8 +208,7 @@
</span><span class="cx">                         // init_lazy_reg since it treats CreateArguments as reading
</span><span class="cx">                         // local variables. That could be fixed, but it's easier to
</span><span class="cx">                         // work around this here.
</span><del>-                        if (source-&gt;op() == JSConstant
-                            &amp;&amp; !source-&gt;valueOfJSConstant(codeBlock()))
</del><ins>+                        if (source-&gt;op() == JSConstant &amp;&amp; !*source-&gt;constant())
</ins><span class="cx">                             break;
</span><span class="cx">                         
</span><span class="cx">                         // If the variable is totally dead, then ignore it.
</span><span class="lines">@@ -511,7 +510,8 @@
</span><span class="cx">                         indexInBlock, SpecNone, CheckArgumentsNotCreated, origin);
</span><span class="cx">                     
</span><span class="cx">                     m_graph.convertToConstant(
</span><del>-                        node, jsNumber(origin.semantic.inlineCallFrame-&gt;arguments.size() - 1));
</del><ins>+                        node, m_graph.freeze(
+                            jsNumber(origin.semantic.inlineCallFrame-&gt;arguments.size() - 1)));
</ins><span class="cx">                     changed = true;
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="lines">@@ -528,12 +528,9 @@
</span><span class="cx">                     }
</span><span class="cx">                     if (!node-&gt;origin.semantic.inlineCallFrame)
</span><span class="cx">                         break;
</span><del>-                    if (!node-&gt;child1()-&gt;hasConstant())
</del><ins>+                    if (!node-&gt;child1()-&gt;isInt32Constant())
</ins><span class="cx">                         break;
</span><del>-                    JSValue value = node-&gt;child1()-&gt;valueOfJSConstant(codeBlock());
-                    if (!value.isInt32())
-                        break;
-                    int32_t index = value.asInt32();
</del><ins>+                    int32_t index = node-&gt;child1()-&gt;asInt32();
</ins><span class="cx">                     if (index &lt; 0
</span><span class="cx">                         || static_cast&lt;size_t&gt;(index + 1) &gt;=
</span><span class="cx">                             node-&gt;origin.semantic.inlineCallFrame-&gt;arguments.size())
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -67,17 +67,17 @@
</span><span class="cx"> private:
</span><span class="cx">     bool isNotNegZero(Node* node)
</span><span class="cx">     {
</span><del>-        if (!m_graph.isNumberConstant(node))
</del><ins>+        if (!node-&gt;isNumberConstant())
</ins><span class="cx">             return false;
</span><del>-        double value = m_graph.valueOfNumberConstant(node);
</del><ins>+        double value = node-&gt;asNumber();
</ins><span class="cx">         return (value || 1.0 / value &gt; 0.0);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool isNotPosZero(Node* node)
</span><span class="cx">     {
</span><del>-        if (!m_graph.isNumberConstant(node))
</del><ins>+        if (!node-&gt;isNumberConstant())
</ins><span class="cx">             return false;
</span><del>-        double value = m_graph.valueOfNumberConstant(node);
</del><ins>+        double value = node-&gt;asNumber();
</ins><span class="cx">         return (value || 1.0 / value &lt; 0.0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">     template&lt;int power&gt;
</span><span class="cx">     bool isWithinPowerOfTwoForConstant(Node* node)
</span><span class="cx">     {
</span><del>-        JSValue immediateValue = node-&gt;valueOfJSConstant(codeBlock());
</del><ins>+        JSValue immediateValue = node-&gt;asJSValue();
</ins><span class="cx">         if (!immediateValue.isNumber())
</span><span class="cx">             return false;
</span><span class="cx">         double immediate = immediateValue.asNumber();
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx">             Node* shiftAmount = node-&gt;child2().node();
</span><span class="cx">             if (shiftAmount-&gt;op() != JSConstant)
</span><span class="cx">                 return false;
</span><del>-            JSValue immediateValue = shiftAmount-&gt;valueOfJSConstant(codeBlock());
</del><ins>+            JSValue immediateValue = shiftAmount-&gt;asJSValue();
</ins><span class="cx">             if (!immediateValue.isInt32())
</span><span class="cx">                 return false;
</span><span class="cx">             return immediateValue.asInt32() &gt; 32 - power;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -132,18 +132,16 @@
</span><span class="cx">         , m_graph(graph)
</span><span class="cx">         , m_currentBlock(0)
</span><span class="cx">         , m_currentIndex(0)
</span><del>-        , m_constantUndefined(UINT_MAX)
-        , m_constantNull(UINT_MAX)
-        , m_constantNaN(UINT_MAX)
-        , m_constant1(UINT_MAX)
-        , m_constants(m_codeBlock-&gt;numberOfConstantRegisters())
</del><ins>+        , m_constantUndefined(graph.freeze(jsUndefined()))
+        , m_constantNull(graph.freeze(jsNull()))
+        , m_constantNaN(graph.freeze(jsNumber(PNaN)))
+        , m_constantOne(graph.freeze(jsNumber(1)))
</ins><span class="cx">         , m_numArguments(m_codeBlock-&gt;numParameters())
</span><span class="cx">         , m_numLocals(m_codeBlock-&gt;m_numCalleeRegisters)
</span><span class="cx">         , m_parameterSlots(0)
</span><span class="cx">         , m_numPassedVarArgs(0)
</span><span class="cx">         , m_inlineStackTop(0)
</span><span class="cx">         , m_haveBuiltOperandMaps(false)
</span><del>-        , m_emptyJSValueIndex(UINT_MAX)
</del><span class="cx">         , m_currentInstruction(0)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(m_profiledBlock);
</span><span class="lines">@@ -217,12 +215,7 @@
</span><span class="cx">     // Get/Set the operands/result of a bytecode instruction.
</span><span class="cx">     Node* getDirect(VirtualRegister operand)
</span><span class="cx">     {
</span><del>-        // Is this a constant?
-        if (operand.isConstant()) {
-            unsigned constant = operand.toConstantIndex();
-            ASSERT(constant &lt; m_constants.size());
-            return getJSConstant(constant);
-        }
</del><ins>+        ASSERT(!operand.isConstant());
</ins><span class="cx"> 
</span><span class="cx">         // Is this an argument?
</span><span class="cx">         if (operand.isArgument())
</span><span class="lines">@@ -234,13 +227,30 @@
</span><span class="cx"> 
</span><span class="cx">     Node* get(VirtualRegister operand)
</span><span class="cx">     {
</span><ins>+        if (operand.isConstant()) {
+            unsigned constantIndex = operand.toConstantIndex();
+            unsigned oldSize = m_constants.size();
+            if (constantIndex &gt;= oldSize || !m_constants[constantIndex]) {
+                JSValue value = m_inlineStackTop-&gt;m_codeBlock-&gt;getConstant(operand.offset());
+                if (constantIndex &gt;= oldSize) {
+                    m_constants.grow(constantIndex + 1);
+                    for (unsigned i = oldSize; i &lt; m_constants.size(); ++i)
+                        m_constants[i] = nullptr;
+                }
+                m_constants[constantIndex] =
+                    addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(value)));
+            }
+            ASSERT(m_constants[constantIndex]);
+            return m_constants[constantIndex];
+        }
+        
</ins><span class="cx">         if (inlineCallFrame()) {
</span><span class="cx">             if (!inlineCallFrame()-&gt;isClosureCall) {
</span><span class="cx">                 JSFunction* callee = inlineCallFrame()-&gt;calleeConstant();
</span><span class="cx">                 if (operand.offset() == JSStack::Callee)
</span><del>-                    return cellConstant(callee);
</del><ins>+                    return weakJSConstant(callee);
</ins><span class="cx">                 if (operand.offset() == JSStack::ScopeChain)
</span><del>-                    return cellConstant(callee-&gt;scope());
</del><ins>+                    return weakJSConstant(callee-&gt;scope());
</ins><span class="cx">             }
</span><span class="cx">         } else if (operand.offset() == JSStack::Callee)
</span><span class="cx">             return addToGraph(GetCallee);
</span><span class="lines">@@ -309,14 +319,7 @@
</span><span class="cx">                 if (JSValue value = set-&gt;inferredValue()) {
</span><span class="cx">                     addToGraph(FunctionReentryWatchpoint, OpInfo(m_codeBlock-&gt;symbolTable()));
</span><span class="cx">                     addToGraph(VariableWatchpoint, OpInfo(set));
</span><del>-                    // Note: this is very special from an OSR exit standpoint. We wouldn't be
-                    // able to do this for most locals, but it works here because we're dealing
-                    // with a flushed local. For most locals we would need to issue a GetLocal
-                    // here and ensure that we have uses in DFG IR wherever there would have
-                    // been uses in bytecode. Clearly this optimization does not do this. But
-                    // that's fine, because we don't need to track liveness for captured
-                    // locals, and this optimization only kicks in for captured locals.
-                    return inferredConstant(value);
</del><ins>+                    return weakJSConstant(value);
</ins><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -367,8 +370,7 @@
</span><span class="cx"> 
</span><span class="cx">         VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
</span><span class="cx">         variableAccessData-&gt;mergeStructureCheckHoistingFailed(
</span><del>-            m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-            || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
</del><ins>+            m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache));
</ins><span class="cx">         variableAccessData-&gt;mergeCheckArrayHoistingFailed(
</span><span class="cx">             m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
</span><span class="cx">         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
</span><span class="lines">@@ -424,8 +426,7 @@
</span><span class="cx">             variableAccessData-&gt;mergeShouldNeverUnbox(true);
</span><span class="cx">         
</span><span class="cx">         variableAccessData-&gt;mergeStructureCheckHoistingFailed(
</span><del>-            m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-            || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
</del><ins>+            m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache));
</ins><span class="cx">         variableAccessData-&gt;mergeCheckArrayHoistingFailed(
</span><span class="cx">             m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
</span><span class="cx">         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
</span><span class="lines">@@ -466,18 +467,6 @@
</span><span class="cx">         return findArgumentPositionForLocal(operand);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void addConstant(JSValue value)
-    {
-        unsigned constantIndex = m_codeBlock-&gt;addConstantLazily();
-        initializeLazyWriteBarrierForConstant(
-            m_graph.m_plan.writeBarriers,
-            m_codeBlock-&gt;constants()[constantIndex],
-            m_codeBlock,
-            constantIndex,
-            m_codeBlock-&gt;ownerExecutable(), 
-            value);
-    }
-    
</del><span class="cx">     void flush(VirtualRegister operand)
</span><span class="cx">     {
</span><span class="cx">         flushDirect(m_inlineStackTop-&gt;remapOperand(operand));
</span><span class="lines">@@ -554,32 +543,15 @@
</span><span class="cx">         flushForTerminal();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // NOTE: Only use this to construct constants that arise from non-speculative
-    // constant folding. I.e. creating constants using this if we had constant
-    // field inference would be a bad idea, since the bytecode parser's folding
-    // doesn't handle liveness preservation.
-    Node* getJSConstantForValue(JSValue constantValue)
</del><ins>+    // Assumes that the constant should be strongly marked.
+    Node* jsConstant(JSValue constantValue)
</ins><span class="cx">     {
</span><del>-        unsigned constantIndex;
-        if (!m_codeBlock-&gt;findConstant(constantValue, constantIndex)) {
-            addConstant(constantValue);
-            m_constants.append(ConstantRecord());
-        }
-        
-        ASSERT(m_constants.size() == m_codeBlock-&gt;numberOfConstantRegisters());
-        
-        return getJSConstant(constantIndex);
</del><ins>+        return addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(constantValue)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Node* getJSConstant(unsigned constant)
</del><ins>+    Node* weakJSConstant(JSValue constantValue)
</ins><span class="cx">     {
</span><del>-        Node* node = m_constants[constant].asJSValue;
-        if (node)
-            return node;
-
-        Node* result = addToGraph(JSConstant, OpInfo(constant));
-        m_constants[constant].asJSValue = result;
-        return result;
</del><ins>+        return addToGraph(JSConstant, OpInfo(m_graph.freeze(constantValue)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Helper functions to get/set the this value.
</span><span class="lines">@@ -593,149 +565,6 @@
</span><span class="cx">         set(m_inlineStackTop-&gt;m_codeBlock-&gt;thisRegister(), value);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Convenience methods for checking nodes for constants.
-    bool isJSConstant(Node* node)
-    {
-        return node-&gt;op() == JSConstant;
-    }
-    bool isInt32Constant(Node* node)
-    {
-        return isJSConstant(node) &amp;&amp; valueOfJSConstant(node).isInt32();
-    }
-    // Convenience methods for getting constant values.
-    JSValue valueOfJSConstant(Node* node)
-    {
-        ASSERT(isJSConstant(node));
-        return m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + node-&gt;constantNumber());
-    }
-    int32_t valueOfInt32Constant(Node* node)
-    {
-        ASSERT(isInt32Constant(node));
-        return valueOfJSConstant(node).asInt32();
-    }
-    
-    // This method returns a JSConstant with the value 'undefined'.
-    Node* constantUndefined()
-    {
-        // Has m_constantUndefined been set up yet?
-        if (m_constantUndefined == UINT_MAX) {
-            // Search the constant pool for undefined, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock-&gt;numberOfConstantRegisters();
-            for (m_constantUndefined = 0; m_constantUndefined &lt; numberOfConstants; ++m_constantUndefined) {
-                JSValue testMe = m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantUndefined);
-                if (testMe.isUndefined())
-                    return getJSConstant(m_constantUndefined);
-            }
-
-            // Add undefined to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(jsUndefined());
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock-&gt;numberOfConstantRegisters());
-        }
-
-        // m_constantUndefined must refer to an entry in the CodeBlock's constant pool that has the value 'undefined'.
-        ASSERT(m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantUndefined).isUndefined());
-        return getJSConstant(m_constantUndefined);
-    }
-
-    // This method returns a JSConstant with the value 'null'.
-    Node* constantNull()
-    {
-        // Has m_constantNull been set up yet?
-        if (m_constantNull == UINT_MAX) {
-            // Search the constant pool for null, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock-&gt;numberOfConstantRegisters();
-            for (m_constantNull = 0; m_constantNull &lt; numberOfConstants; ++m_constantNull) {
-                JSValue testMe = m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantNull);
-                if (testMe.isNull())
-                    return getJSConstant(m_constantNull);
-            }
-
-            // Add null to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(jsNull());
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock-&gt;numberOfConstantRegisters());
-        }
-
-        // m_constantNull must refer to an entry in the CodeBlock's constant pool that has the value 'null'.
-        ASSERT(m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantNull).isNull());
-        return getJSConstant(m_constantNull);
-    }
-
-    // This method returns a DoubleConstant with the value 1.
-    Node* one()
-    {
-        // Has m_constant1 been set up yet?
-        if (m_constant1 == UINT_MAX) {
-            // Search the constant pool for the value 1, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock-&gt;numberOfConstantRegisters();
-            for (m_constant1 = 0; m_constant1 &lt; numberOfConstants; ++m_constant1) {
-                JSValue testMe = m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constant1);
-                if (testMe.isInt32() &amp;&amp; testMe.asInt32() == 1)
-                    return getJSConstant(m_constant1);
-            }
-
-            // Add the value 1 to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(jsNumber(1));
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock-&gt;numberOfConstantRegisters());
-        }
-
-        // m_constant1 must refer to an entry in the CodeBlock's constant pool that has the integer value 1.
-        ASSERT(m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constant1).isInt32());
-        ASSERT(m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constant1).asInt32() == 1);
-        return getJSConstant(m_constant1);
-    }
-    
-    // This method returns a DoubleConstant with the value NaN.
-    Node* constantNaN()
-    {
-        JSValue nan = jsNaN();
-        
-        // Has m_constantNaN been set up yet?
-        if (m_constantNaN == UINT_MAX) {
-            // Search the constant pool for the value NaN, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock-&gt;numberOfConstantRegisters();
-            for (m_constantNaN = 0; m_constantNaN &lt; numberOfConstants; ++m_constantNaN) {
-                JSValue testMe = m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantNaN);
-                if (JSValue::encode(testMe) == JSValue::encode(nan))
-                    return getJSConstant(m_constantNaN);
-            }
-
-            // Add the value nan to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(nan);
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock-&gt;numberOfConstantRegisters());
-        }
-
-        // m_constantNaN must refer to an entry in the CodeBlock's constant pool that has the value nan.
-        ASSERT(m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantNaN).isDouble());
-        ASSERT(std::isnan(m_codeBlock-&gt;getConstant(FirstConstantRegisterIndex + m_constantNaN).asDouble()));
-        return getJSConstant(m_constantNaN);
-    }
-    
-    Node* cellConstant(JSCell* cell)
-    {
-        HashMap&lt;JSCell*, Node*&gt;::AddResult result = m_cellConstantNodes.add(cell, nullptr);
-        if (result.isNewEntry) {
-            ASSERT(!Heap::isZombified(cell));
-            result.iterator-&gt;value = addToGraph(WeakJSConstant, OpInfo(cell));
-        }
-        
-        return result.iterator-&gt;value;
-    }
-    
-    Node* inferredConstant(JSValue value)
-    {
-        if (value.isCell())
-            return cellConstant(value.asCell());
-        return getJSConstantForValue(value);
-    }
-    
</del><span class="cx">     InlineCallFrame* inlineCallFrame()
</span><span class="cx">     {
</span><span class="cx">         return m_inlineStackTop-&gt;m_inlineCallFrame;
</span><span class="lines">@@ -831,14 +660,14 @@
</span><span class="cx">     
</span><span class="cx">     Node* cellConstantWithStructureCheck(JSCell* object, Structure* structure)
</span><span class="cx">     {
</span><del>-        Node* objectNode = cellConstant(object);
</del><ins>+        Node* objectNode = weakJSConstant(object);
</ins><span class="cx">         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
</span><span class="cx">         return objectNode;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Node* cellConstantWithStructureCheck(JSCell* object)
</span><span class="cx">     {
</span><del>-        return cellConstantWithStructureCheck(object, object-&gt;structure());
</del><ins>+        return cellConstantWithStructureCheck(object, m_graph.freeze(object)-&gt;structure());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
</span><span class="lines">@@ -997,37 +826,12 @@
</span><span class="cx">     // The bytecode index of the current instruction being generated.
</span><span class="cx">     unsigned m_currentIndex;
</span><span class="cx"> 
</span><del>-    // We use these values during code generation, and to avoid the need for
-    // special handling we make sure they are available as constants in the
-    // CodeBlock's constant pool. These variables are initialized to
-    // UINT_MAX, and lazily updated to hold an index into the CodeBlock's
-    // constant pool, as necessary.
-    unsigned m_constantUndefined;
-    unsigned m_constantNull;
-    unsigned m_constantNaN;
-    unsigned m_constant1;
-    HashMap&lt;JSCell*, unsigned&gt; m_cellConstants;
-    HashMap&lt;JSCell*, Node*&gt; m_cellConstantNodes;
</del><ins>+    FrozenValue* m_constantUndefined;
+    FrozenValue* m_constantNull;
+    FrozenValue* m_constantNaN;
+    FrozenValue* m_constantOne;
+    Vector&lt;Node*, 16&gt; m_constants;
</ins><span class="cx"> 
</span><del>-    // A constant in the constant pool may be represented by more than one
-    // node in the graph, depending on the context in which it is being used.
-    struct ConstantRecord {
-        ConstantRecord()
-            : asInt32(0)
-            , asNumeric(0)
-            , asJSValue(0)
-        {
-        }
-
-        Node* asInt32;
-        Node* asNumeric;
-        Node* asJSValue;
-    };
-
-    // Track the index of the node whose result is the current value for every
-    // register value in the bytecode - argument, local, and temporary.
-    Vector&lt;ConstantRecord, 16&gt; m_constants;
-
</del><span class="cx">     // The number of arguments passed to the function.
</span><span class="cx">     unsigned m_numArguments;
</span><span class="cx">     // The number of locals (vars + temporaries) used in the function.
</span><span class="lines">@@ -1061,7 +865,6 @@
</span><span class="cx">         // (the machine code block, which is the transitive, though not necessarily
</span><span class="cx">         // direct, caller).
</span><span class="cx">         Vector&lt;unsigned&gt; m_identifierRemap;
</span><del>-        Vector&lt;unsigned&gt; m_constantRemap;
</del><span class="cx">         Vector&lt;unsigned&gt; m_constantBufferRemap;
</span><span class="cx">         Vector&lt;unsigned&gt; m_switchRemap;
</span><span class="cx">         
</span><span class="lines">@@ -1132,11 +935,7 @@
</span><span class="cx">             if (!m_inlineCallFrame)
</span><span class="cx">                 return operand;
</span><span class="cx">             
</span><del>-            if (operand.isConstant()) {
-                VirtualRegister result = VirtualRegister(m_constantRemap[operand.toConstantIndex()]);
-                ASSERT(result.isConstant());
-                return result;
-            }
</del><ins>+            ASSERT(!operand.isConstant());
</ins><span class="cx"> 
</span><span class="cx">             return VirtualRegister(operand.offset() + m_inlineCallFrame-&gt;stackOffset);
</span><span class="cx">         }
</span><span class="lines">@@ -1170,11 +969,6 @@
</span><span class="cx">     bool m_haveBuiltOperandMaps;
</span><span class="cx">     // Mapping between identifier names and numbers.
</span><span class="cx">     BorrowedIdentifierMap m_identifierMap;
</span><del>-    // Mapping between values and constant numbers.
-    JSValueMap m_jsValueMap;
-    // Index of the empty value, or UINT_MAX if there is no mapping. This is a horrible
-    // work-around for the fact that JSValueMap can't handle &quot;empty&quot; values.
-    unsigned m_emptyJSValueIndex;
</del><span class="cx">     
</span><span class="cx">     CodeBlock* m_dfgCodeBlock;
</span><span class="cx">     CallLinkStatus::ContextMap m_callContextMap;
</span><span class="lines">@@ -1222,10 +1016,8 @@
</span><span class="cx">     ASSERT(registerOffset &lt;= 0);
</span><span class="cx">     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</span><span class="cx">     
</span><del>-    if (m_graph.isConstant(callTarget)) {
-        callLinkStatus = CallLinkStatus(
-            m_graph.valueOfJSConstant(callTarget)).setIsProved(true);
-    }
</del><ins>+    if (callTarget-&gt;hasConstant())
+        callLinkStatus = CallLinkStatus(callTarget-&gt;asJSValue()).setIsProved(true);
</ins><span class="cx">     
</span><span class="cx">     if (!callLinkStatus.canOptimize()) {
</span><span class="cx">         // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
</span><span class="lines">@@ -1296,7 +1088,7 @@
</span><span class="cx">     ASSERT(callLinkStatus.canOptimize());
</span><span class="cx">     
</span><span class="cx">     if (JSFunction* function = callLinkStatus.function())
</span><del>-        addToGraph(CheckFunction, OpInfo(function), callTarget, thisArgument);
</del><ins>+        addToGraph(CheckFunction, OpInfo(m_graph.freeze(function)), callTarget, thisArgument);
</ins><span class="cx">     else {
</span><span class="cx">         ASSERT(callLinkStatus.structure());
</span><span class="cx">         ASSERT(callLinkStatus.executable());
</span><span class="lines">@@ -1453,6 +1245,7 @@
</span><span class="cx">     m_graph.m_inlineVariableData.append(inlineVariableData);
</span><span class="cx">     
</span><span class="cx">     parseCodeBlock();
</span><ins>+    prepareToParseBlock(); // Reset our state now that we're back to the outer code.
</ins><span class="cx">     
</span><span class="cx">     m_currentIndex = oldIndex;
</span><span class="cx">     
</span><span class="lines">@@ -1542,7 +1335,7 @@
</span><span class="cx"> bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis)
</span><span class="cx"> {
</span><span class="cx">     if (argumentCountIncludingThis == 1) { // Math.min()
</span><del>-        set(VirtualRegister(resultOperand), constantNaN());
</del><ins>+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">      
</span><span class="lines">@@ -1567,7 +1360,7 @@
</span><span class="cx">     switch (intrinsic) {
</span><span class="cx">     case AbsIntrinsic: {
</span><span class="cx">         if (argumentCountIncludingThis == 1) { // Math.abs()
</span><del>-            set(VirtualRegister(resultOperand), constantNaN());
</del><ins>+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
</ins><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1591,7 +1384,7 @@
</span><span class="cx">     case CosIntrinsic:
</span><span class="cx">     case SinIntrinsic: {
</span><span class="cx">         if (argumentCountIncludingThis == 1) {
</span><del>-            set(VirtualRegister(resultOperand), constantNaN());
</del><ins>+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
</ins><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -1738,19 +1531,19 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case DFGTrueIntrinsic: {
</span><del>-        set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true)));
</del><ins>+        set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case OSRExitIntrinsic: {
</span><span class="cx">         addToGraph(ForceOSRExit);
</span><del>-        set(VirtualRegister(resultOperand), constantUndefined());
</del><ins>+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case IsFinalTierIntrinsic: {
</span><span class="cx">         set(VirtualRegister(resultOperand),
</span><del>-            getJSConstantForValue(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
</del><ins>+            jsConstant(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -1845,7 +1638,7 @@
</span><span class="cx">         Node* result;
</span><span class="cx">         
</span><span class="cx">         if (argumentCountIncludingThis &lt;= 1)
</span><del>-            result = cellConstant(m_vm-&gt;smallStrings.emptyString());
</del><ins>+            result = jsConstant(m_vm-&gt;smallStrings.emptyString());
</ins><span class="cx">         else
</span><span class="cx">             result = addToGraph(ToString, get(virtualRegisterForArgument(1, registerOffset)));
</span><span class="cx">         
</span><span class="lines">@@ -1986,7 +1779,7 @@
</span><span class="cx">     
</span><span class="cx">     Node* loadedValue;
</span><span class="cx">     if (variant.specificValue())
</span><del>-        loadedValue = cellConstant(variant.specificValue().asCell());
</del><ins>+        loadedValue = weakJSConstant(variant.specificValue());
</ins><span class="cx">     else {
</span><span class="cx">         loadedValue = handleGetByOffset(
</span><span class="cx">             prediction, base, identifierNumber, variant.offset(),
</span><span class="lines">@@ -2160,9 +1953,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ByteCodeParser::prepareToParseBlock()
</span><span class="cx"> {
</span><del>-    for (unsigned i = 0; i &lt; m_constants.size(); ++i)
-        m_constants[i] = ConstantRecord();
-    m_cellConstantNodes.clear();
</del><ins>+    m_constants.resize(0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Node* ByteCodeParser::getScope(bool skipTop, unsigned skipCount)
</span><span class="lines">@@ -2194,8 +1985,7 @@
</span><span class="cx">             VariableAccessData* variable = newVariableAccessData(
</span><span class="cx">                 virtualRegisterForArgument(argument), m_codeBlock-&gt;isCaptured(virtualRegisterForArgument(argument)));
</span><span class="cx">             variable-&gt;mergeStructureCheckHoistingFailed(
</span><del>-                m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-                || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
</del><ins>+                m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache));
</ins><span class="cx">             variable-&gt;mergeCheckArrayHoistingFailed(
</span><span class="cx">                 m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
</span><span class="cx">             
</span><span class="lines">@@ -2241,13 +2031,15 @@
</span><span class="cx"> 
</span><span class="cx">         // === Function entry opcodes ===
</span><span class="cx"> 
</span><del>-        case op_enter:
</del><ins>+        case op_enter: {
+            Node* undefined = addToGraph(JSConstant, OpInfo(m_constantUndefined));
</ins><span class="cx">             // Initialize all locals to undefined.
</span><span class="cx">             for (int i = 0; i &lt; m_inlineStackTop-&gt;m_codeBlock-&gt;m_numVars; ++i)
</span><del>-                set(virtualRegisterForLocal(i), constantUndefined(), ImmediateNakedSet);
</del><ins>+                set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet);
</ins><span class="cx">             if (m_inlineStackTop-&gt;m_codeBlock-&gt;specializationKind() == CodeForConstruct)
</span><del>-                set(virtualRegisterForArgument(0), constantUndefined(), ImmediateNakedSet);
</del><ins>+                set(virtualRegisterForArgument(0), undefined, ImmediateNakedSet);
</ins><span class="cx">             NEXT_OPCODE(op_enter);
</span><ins>+        }
</ins><span class="cx">             
</span><span class="cx">         case op_touch_entry:
</span><span class="cx">             if (m_inlineStackTop-&gt;m_codeBlock-&gt;symbolTable()-&gt;m_functionEnteredOnce.isStillValid())
</span><span class="lines">@@ -2262,7 +2054,6 @@
</span><span class="cx">                     || cachedStructure-&gt;classInfo()-&gt;methodTable.toThis != JSObject::info()-&gt;methodTable.toThis
</span><span class="cx">                     || m_inlineStackTop-&gt;m_profiledBlock-&gt;couldTakeSlowCase(m_currentIndex)
</span><span class="cx">                     || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCache)
</span><del>-                    || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)
</del><span class="cx">                     || (op1-&gt;op() == GetLocal &amp;&amp; op1-&gt;variableAccessData()-&gt;structureCheckHoistingFailed())) {
</span><span class="cx">                     setThis(addToGraph(ToThis, op1));
</span><span class="cx">                 } else {
</span><span class="lines">@@ -2279,13 +2070,9 @@
</span><span class="cx">             int calleeOperand = currentInstruction[2].u.operand;
</span><span class="cx">             Node* callee = get(VirtualRegister(calleeOperand));
</span><span class="cx">             bool alreadyEmitted = false;
</span><del>-            if (callee-&gt;op() == WeakJSConstant) {
-                JSCell* cell = callee-&gt;weakConstant();
-                ASSERT(cell-&gt;inherits(JSFunction::info()));
-                
-                JSFunction* function = jsCast&lt;JSFunction*&gt;(cell);
</del><ins>+            if (JSFunction* function = callee-&gt;dynamicCastConstant&lt;JSFunction*&gt;()) {
</ins><span class="cx">                 if (Structure* structure = function-&gt;allocationStructure()) {
</span><del>-                    addToGraph(AllocationProfileWatchpoint, OpInfo(function));
</del><ins>+                    addToGraph(AllocationProfileWatchpoint, OpInfo(m_graph.freeze(function)));
</ins><span class="cx">                     // The callee is still live up to this point.
</span><span class="cx">                     addToGraph(Phantom, callee);
</span><span class="cx">                     set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(structure)));
</span><span class="lines">@@ -2357,10 +2144,11 @@
</span><span class="cx">                 || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadFunction)) {
</span><span class="cx">                 set(VirtualRegister(currentInstruction[1].u.operand), get(VirtualRegister(JSStack::Callee)));
</span><span class="cx">             } else {
</span><ins>+                FrozenValue* frozen = m_graph.freeze(cachedFunction);
</ins><span class="cx">                 ASSERT(cachedFunction-&gt;inherits(JSFunction::info()));
</span><span class="cx">                 Node* actualCallee = get(VirtualRegister(JSStack::Callee));
</span><del>-                addToGraph(CheckFunction, OpInfo(cachedFunction), actualCallee);
-                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(WeakJSConstant, OpInfo(cachedFunction)));
</del><ins>+                addToGraph(CheckFunction, OpInfo(frozen), actualCallee);
+                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(JSConstant, OpInfo(frozen)));
</ins><span class="cx">             }
</span><span class="cx">             NEXT_OPCODE(op_get_callee);
</span><span class="cx">         }
</span><span class="lines">@@ -2424,7 +2212,7 @@
</span><span class="cx">             int srcDst = currentInstruction[1].u.operand;
</span><span class="cx">             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
</span><span class="cx">             Node* op = get(srcDstVirtualRegister);
</span><del>-            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, one())));
</del><ins>+            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
</ins><span class="cx">             NEXT_OPCODE(op_inc);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2432,7 +2220,7 @@
</span><span class="cx">             int srcDst = currentInstruction[1].u.operand;
</span><span class="cx">             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
</span><span class="cx">             Node* op = get(srcDstVirtualRegister);
</span><del>-            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, one())));
</del><ins>+            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
</ins><span class="cx">             NEXT_OPCODE(op_dec);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2649,7 +2437,7 @@
</span><span class="cx"> 
</span><span class="cx">         case op_eq_null: {
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
</span><del>-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, constantNull()));
</del><ins>+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull))));
</ins><span class="cx">             NEXT_OPCODE(op_eq_null);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2669,7 +2457,7 @@
</span><span class="cx"> 
</span><span class="cx">         case op_neq_null: {
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
</span><del>-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, constantNull())));
</del><ins>+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)))));
</ins><span class="cx">             NEXT_OPCODE(op_neq_null);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2794,7 +2582,7 @@
</span><span class="cx">         case op_jeq_null: {
</span><span class="cx">             unsigned relativeOffset = currentInstruction[2].u.operand;
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
</span><del>-            Node* condition = addToGraph(CompareEqConstant, value, constantNull());
</del><ins>+            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
</ins><span class="cx">             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jeq_null))), condition);
</span><span class="cx">             LAST_OPCODE(op_jeq_null);
</span><span class="cx">         }
</span><span class="lines">@@ -2802,7 +2590,7 @@
</span><span class="cx">         case op_jneq_null: {
</span><span class="cx">             unsigned relativeOffset = currentInstruction[2].u.operand;
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
</span><del>-            Node* condition = addToGraph(CompareEqConstant, value, constantNull());
</del><ins>+            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
</ins><span class="cx">             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jneq_null), m_currentIndex + relativeOffset)), condition);
</span><span class="cx">             LAST_OPCODE(op_jneq_null);
</span><span class="cx">         }
</span><span class="lines">@@ -2891,7 +2679,7 @@
</span><span class="cx">                 unsigned target = m_currentIndex + table.branchOffsets[i];
</span><span class="cx">                 if (target == data.fallThrough.bytecodeIndex())
</span><span class="cx">                     continue;
</span><del>-                data.cases.append(SwitchCase::withBytecodeIndex(jsNumber(static_cast&lt;int32_t&gt;(table.min + i)), target));
</del><ins>+                data.cases.append(SwitchCase::withBytecodeIndex(m_graph.freeze(jsNumber(static_cast&lt;int32_t&gt;(table.min + i))), target));
</ins><span class="cx">             }
</span><span class="cx">             flushIfTerminal(data);
</span><span class="cx">             addToGraph(Switch, OpInfo(&amp;data), get(VirtualRegister(currentInstruction[3].u.operand)));
</span><span class="lines">@@ -3042,7 +2830,8 @@
</span><span class="cx">             ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer));
</span><span class="cx">             addToGraph(
</span><span class="cx">                 CheckFunction,
</span><del>-                OpInfo(actualPointerFor(m_inlineStackTop-&gt;m_codeBlock, currentInstruction[2].u.specialPointer)),
</del><ins>+                OpInfo(m_graph.freeze(static_cast&lt;JSCell*&gt;(actualPointerFor(
+                    m_inlineStackTop-&gt;m_codeBlock, currentInstruction[2].u.specialPointer)))),
</ins><span class="cx">                 get(VirtualRegister(currentInstruction[1].u.operand)));
</span><span class="cx">             addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr)));
</span><span class="cx">             LAST_OPCODE(op_jneq_ptr);
</span><span class="lines">@@ -3061,7 +2850,7 @@
</span><span class="cx">             case GlobalVar:
</span><span class="cx">             case GlobalPropertyWithVarInjectionChecks:
</span><span class="cx">             case GlobalVarWithVarInjectionChecks:
</span><del>-                set(VirtualRegister(dst), cellConstant(m_inlineStackTop-&gt;m_codeBlock-&gt;globalObject()));
</del><ins>+                set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop-&gt;m_codeBlock-&gt;globalObject()));
</ins><span class="cx">                 break;
</span><span class="cx">             case ClosureVar:
</span><span class="cx">             case ClosureVarWithVarInjectionChecks: {
</span><span class="lines">@@ -3069,7 +2858,7 @@
</span><span class="cx">                 if (activation
</span><span class="cx">                     &amp;&amp; activation-&gt;symbolTable()-&gt;m_functionEnteredOnce.isStillValid()) {
</span><span class="cx">                     addToGraph(FunctionReentryWatchpoint, OpInfo(activation-&gt;symbolTable()));
</span><del>-                    set(VirtualRegister(dst), cellConstant(activation));
</del><ins>+                    set(VirtualRegister(dst), weakJSConstant(activation));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 set(VirtualRegister(dst),
</span><span class="lines">@@ -3118,7 +2907,7 @@
</span><span class="cx">                 Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().onlyStructure());
</span><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx">                 if (JSValue specificValue = status[0].specificValue())
</span><del>-                    set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
</del><ins>+                    set(VirtualRegister(dst), weakJSConstant(specificValue.asCell()));
</ins><span class="cx">                 else
</span><span class="cx">                     set(VirtualRegister(dst), handleGetByOffset(prediction, base, identifierNumber, operand));
</span><span class="cx">                 break;
</span><span class="lines">@@ -3137,7 +2926,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
</span><del>-                set(VirtualRegister(dst), inferredConstant(specificValue));
</del><ins>+                set(VirtualRegister(dst), weakJSConstant(specificValue));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case ClosureVar:
</span><span class="lines">@@ -3153,7 +2942,7 @@
</span><span class="cx">                         if (JSValue value = watchpointSet-&gt;inferredValue()) {
</span><span class="cx">                             addToGraph(Phantom, scopeNode);
</span><span class="cx">                             addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
</span><del>-                            set(VirtualRegister(dst), inferredConstant(value));
</del><ins>+                            set(VirtualRegister(dst), weakJSConstant(value));
</ins><span class="cx">                             break;
</span><span class="cx">                         }
</span><span class="cx">                     }
</span><span class="lines">@@ -3254,7 +3043,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         case op_init_lazy_reg: {
</span><del>-            set(VirtualRegister(currentInstruction[1].u.operand), getJSConstantForValue(JSValue()));
</del><ins>+            set(VirtualRegister(currentInstruction[1].u.operand), jsConstant(JSValue()));
</ins><span class="cx">             ASSERT(operandIsLocal(currentInstruction[1].u.operand));
</span><span class="cx">             m_graph.m_lazyVars.set(VirtualRegister(currentInstruction[1].u.operand).toLocal());
</span><span class="cx">             NEXT_OPCODE(op_init_lazy_reg);
</span><span class="lines">@@ -3409,13 +3198,6 @@
</span><span class="cx">     
</span><span class="cx">     for (size_t i = 0; i &lt; m_codeBlock-&gt;numberOfIdentifiers(); ++i)
</span><span class="cx">         m_identifierMap.add(m_codeBlock-&gt;identifier(i).impl(), i);
</span><del>-    for (size_t i = 0; i &lt; m_codeBlock-&gt;numberOfConstantRegisters(); ++i) {
-        JSValue value = m_codeBlock-&gt;getConstant(i + FirstConstantRegisterIndex);
-        if (!value)
-            m_emptyJSValueIndex = i + FirstConstantRegisterIndex;
-        else
-            m_jsValueMap.add(JSValue::encode(value), i + FirstConstantRegisterIndex);
-    }
</del><span class="cx">     
</span><span class="cx">     m_haveBuiltOperandMaps = true;
</span><span class="cx"> }
</span><span class="lines">@@ -3513,7 +3295,6 @@
</span><span class="cx">         byteCodeParser-&gt;buildOperandMapsIfNecessary();
</span><span class="cx">         
</span><span class="cx">         m_identifierRemap.resize(codeBlock-&gt;numberOfIdentifiers());
</span><del>-        m_constantRemap.resize(codeBlock-&gt;numberOfConstantRegisters());
</del><span class="cx">         m_constantBufferRemap.resize(codeBlock-&gt;numberOfConstantBuffers());
</span><span class="cx">         m_switchRemap.resize(codeBlock-&gt;numberOfSwitchJumpTables());
</span><span class="cx"> 
</span><span class="lines">@@ -3524,24 +3305,6 @@
</span><span class="cx">                 byteCodeParser-&gt;m_graph.identifiers().addLazily(rep);
</span><span class="cx">             m_identifierRemap[i] = result.iterator-&gt;value;
</span><span class="cx">         }
</span><del>-        for (size_t i = 0; i &lt; codeBlock-&gt;numberOfConstantRegisters(); ++i) {
-            JSValue value = codeBlock-&gt;getConstant(i + FirstConstantRegisterIndex);
-            if (!value) {
-                if (byteCodeParser-&gt;m_emptyJSValueIndex == UINT_MAX) {
-                    byteCodeParser-&gt;m_emptyJSValueIndex = byteCodeParser-&gt;m_codeBlock-&gt;numberOfConstantRegisters() + FirstConstantRegisterIndex;
-                    byteCodeParser-&gt;addConstant(JSValue());
-                    byteCodeParser-&gt;m_constants.append(ConstantRecord());
-                }
-                m_constantRemap[i] = byteCodeParser-&gt;m_emptyJSValueIndex;
-                continue;
-            }
-            JSValueMap::AddResult result = byteCodeParser-&gt;m_jsValueMap.add(JSValue::encode(value), byteCodeParser-&gt;m_codeBlock-&gt;numberOfConstantRegisters() + FirstConstantRegisterIndex);
-            if (result.isNewEntry) {
-                byteCodeParser-&gt;addConstant(value);
-                byteCodeParser-&gt;m_constants.append(ConstantRecord());
-            }
-            m_constantRemap[i] = result.iterator-&gt;value;
-        }
</del><span class="cx">         for (unsigned i = 0; i &lt; codeBlock-&gt;numberOfConstantBuffers(); ++i) {
</span><span class="cx">             // If we inline the same code block multiple times, we don't want to needlessly
</span><span class="cx">             // duplicate its constant buffers.
</span><span class="lines">@@ -3572,13 +3335,10 @@
</span><span class="cx">         m_inlineCallFrame = 0;
</span><span class="cx"> 
</span><span class="cx">         m_identifierRemap.resize(codeBlock-&gt;numberOfIdentifiers());
</span><del>-        m_constantRemap.resize(codeBlock-&gt;numberOfConstantRegisters());
</del><span class="cx">         m_constantBufferRemap.resize(codeBlock-&gt;numberOfConstantBuffers());
</span><span class="cx">         m_switchRemap.resize(codeBlock-&gt;numberOfSwitchJumpTables());
</span><span class="cx">         for (size_t i = 0; i &lt; codeBlock-&gt;numberOfIdentifiers(); ++i)
</span><span class="cx">             m_identifierRemap[i] = i;
</span><del>-        for (size_t i = 0; i &lt; codeBlock-&gt;numberOfConstantRegisters(); ++i)
-            m_constantRemap[i] = i + FirstConstantRegisterIndex;
</del><span class="cx">         for (size_t i = 0; i &lt; codeBlock-&gt;numberOfConstantBuffers(); ++i)
</span><span class="cx">             m_constantBufferRemap[i] = i;
</span><span class="cx">         for (size_t i = 0; i &lt; codeBlock-&gt;numberOfSwitchJumpTables(); ++i)
</span><span class="lines">@@ -3586,14 +3346,13 @@
</span><span class="cx">         m_callsiteBlockHeadNeedsLinking = false;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    for (size_t i = 0; i &lt; m_constantRemap.size(); ++i)
-        ASSERT(m_constantRemap[i] &gt;= static_cast&lt;unsigned&gt;(FirstConstantRegisterIndex));
-    
</del><span class="cx">     byteCodeParser-&gt;m_inlineStackTop = this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ByteCodeParser::parseCodeBlock()
</span><span class="cx"> {
</span><ins>+    prepareToParseBlock();
+    
</ins><span class="cx">     CodeBlock* codeBlock = m_inlineStackTop-&gt;m_codeBlock;
</span><span class="cx">     
</span><span class="cx">     if (m_graph.compilation()) {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGCFGSimplificationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">                     
</span><span class="cx">                     // Switch on constant -&gt; jettison all other targets and merge.
</span><span class="cx">                     if (block-&gt;last()-&gt;child1()-&gt;hasConstant()) {
</span><del>-                        JSValue value = m_graph.valueOfJSConstant(block-&gt;last()-&gt;child1().node());
</del><ins>+                        FrozenValue* value = block-&gt;last()-&gt;child1()-&gt;constant();
</ins><span class="cx">                         TriState found = FalseTriState;
</span><span class="cx">                         BasicBlock* targetBlock = 0;
</span><span class="cx">                         for (unsigned i = data-&gt;cases.size(); found == FalseTriState &amp;&amp; i--;) {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGCSEPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -168,7 +168,7 @@
</span><span class="cx">             if (otherNode-&gt;op() != node-&gt;op())
</span><span class="cx">                 continue;
</span><span class="cx">             
</span><del>-            if (otherNode-&gt;constantNumber() != node-&gt;constantNumber())
</del><ins>+            if (otherNode-&gt;constant() != node-&gt;constant())
</ins><span class="cx">                 continue;
</span><span class="cx">             
</span><span class="cx">             return otherNode;
</span><span class="lines">@@ -176,21 +176,6 @@
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* weakConstantCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock-&gt;at(i);
-            if (otherNode-&gt;op() != WeakJSConstant)
-                continue;
-            
-            if (otherNode-&gt;weakConstant() != node-&gt;weakConstant())
-                continue;
-            
-            return otherNode;
-        }
-        return 0;
-    }
-    
</del><span class="cx">     Node* constantStoragePointerCSE(Node* node)
</span><span class="cx">     {
</span><span class="cx">         for (unsigned i = endIndexForPureCSE(); i--;) {
</span><span class="lines">@@ -420,7 +405,7 @@
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool checkFunctionElimination(JSCell* function, Node* child1)
</del><ins>+    bool checkFunctionElimination(FrozenValue* function, Node* child1)
</ins><span class="cx">     {
</span><span class="cx">         for (unsigned i = endIndexForPureCSE(); i--;) {
</span><span class="cx">             Node* node = m_currentBlock-&gt;at(i);
</span><span class="lines">@@ -1270,13 +1255,6 @@
</span><span class="cx">             setReplacement(constantCSE(node));
</span><span class="cx">             break;
</span><span class="cx">             
</span><del>-        case WeakJSConstant:
-            if (cseMode == StoreElimination)
-                break;
-            // FIXME: have CSE for weak constants against strong constants and vice-versa.
-            setReplacement(weakConstantCSE(node));
-            break;
-            
</del><span class="cx">         case ConstantStoragePointer:
</span><span class="cx">             if (cseMode == StoreElimination)
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGClobberize.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -76,7 +76,6 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><del>-    case WeakJSConstant:
</del><span class="cx">     case Identity:
</span><span class="cx">     case Phantom:
</span><span class="cx">     case HardPhantom:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGCommonh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGCommon.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGCommon.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGCommon.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -98,6 +98,8 @@
</span><span class="cx"> 
</span><span class="cx"> enum NoResultTag { NoResult };
</span><span class="cx"> 
</span><ins>+enum StructureWatchpointState { HaveNotStartedWatching, WatchingAllWatchableStructures };
+
</ins><span class="cx"> enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
</span><span class="cx"> 
</span><span class="cx"> // Describes the form you can expect the entire graph to be in.
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="cx">             case CheckFunction: {
</span><del>-                if (m_state.forNode(node-&gt;child1()).value() != node-&gt;function())
</del><ins>+                if (m_state.forNode(node-&gt;child1()).value() != node-&gt;function()-&gt;value())
</ins><span class="cx">                     break;
</span><span class="cx">                 node-&gt;convertToPhantom();
</span><span class="cx">                 eliminated = true;
</span><span class="lines">@@ -273,8 +273,11 @@
</span><span class="cx">             }
</span><span class="cx">             if (!node-&gt;shouldGenerate() || m_state.didClobber() || node-&gt;hasConstant())
</span><span class="cx">                 continue;
</span><del>-            JSValue value = m_state.forNode(node).value();
-            if (!value)
</del><ins>+            
+            // Interesting fact: this freezing that we do right here may turn an fragile value into
+            // a weak value. See DFGValueStrength.h.
+            FrozenValue* value = m_graph.freeze(m_state.forNode(node).value());
+            if (!*value)
</ins><span class="cx">                 continue;
</span><span class="cx">             
</span><span class="cx">             // Check if merging the abstract value of the constant into the abstract value
</span><span class="lines">@@ -283,7 +286,7 @@
</span><span class="cx">             // then we refuse to fold.
</span><span class="cx">             AbstractValue oldValue = m_state.forNode(node);
</span><span class="cx">             AbstractValue constantValue;
</span><del>-            constantValue.set(m_graph, value, m_state.structureClobberState());
</del><ins>+            constantValue.set(m_graph, *value, m_state.structureClobberState());
</ins><span class="cx">             constantValue.fixTypeForRepresentation(node);
</span><span class="cx">             if (oldValue.merge(constantValue))
</span><span class="cx">                 continue;
</span><span class="lines">@@ -330,7 +333,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (variant.specificValue()) {
</span><del>-            m_graph.convertToConstant(node, variant.specificValue());
</del><ins>+            m_graph.convertToConstant(node, m_graph.freeze(variant.specificValue()));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -453,7 +456,8 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         Node* weakConstant = m_insertionSet.insertNode(
</span><del>-            indexInBlock, speculationFromValue(cell), WeakJSConstant, origin, OpInfo(cell));
</del><ins>+            indexInBlock, speculationFromValue(cell), JSConstant, origin,
+            OpInfo(m_graph.freeze(cell)));
</ins><span class="cx">         
</span><span class="cx">         m_insertionSet.insertNode(
</span><span class="cx">             indexInBlock, SpecNone, CheckStructure, origin,
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -44,7 +44,6 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><del>-    case WeakJSConstant:
</del><span class="cx">     case Identity:
</span><span class="cx">     case GetCallee:
</span><span class="cx">     case GetLocal:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -851,7 +851,8 @@
</span><span class="cx">                     m_indexInBlock, SpecNone, Phantom, node-&gt;origin,
</span><span class="cx">                     Edge(node-&gt;child1().node(), OtherUse));
</span><span class="cx">                 observeUseKindOnNode&lt;OtherUse&gt;(node-&gt;child1().node());
</span><del>-                node-&gt;convertToWeakConstant(m_graph.globalThisObjectFor(node-&gt;origin.semantic));
</del><ins>+                m_graph.convertToConstant(
+                    node, m_graph.globalThisObjectFor(node-&gt;origin.semantic));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -1034,8 +1035,8 @@
</span><span class="cx">         
</span><span class="cx">         case PutGlobalVar: {
</span><span class="cx">             Node* globalObjectNode = m_insertionSet.insertNode(
</span><del>-                m_indexInBlock, SpecNone, WeakJSConstant, node-&gt;origin, 
-                OpInfo(m_graph.globalObjectFor(node-&gt;origin.semantic)));
</del><ins>+                m_indexInBlock, SpecNone, JSConstant, node-&gt;origin, 
+                OpInfo(m_graph.freeze(m_graph.globalObjectFor(node-&gt;origin.semantic))));
</ins><span class="cx">             // FIXME: This probably shouldn't have an unconditional barrier.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=133104
</span><span class="cx">             Node* barrierNode = m_graph.addNode(
</span><span class="lines">@@ -1067,7 +1068,6 @@
</span><span class="cx">         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
</span><span class="cx">         case SetArgument:
</span><span class="cx">         case JSConstant:
</span><del>-        case WeakJSConstant:
</del><span class="cx">         case GetLocal:
</span><span class="cx">         case GetCallee:
</span><span class="cx">         case Flush:
</span><span class="lines">@@ -1193,9 +1193,9 @@
</span><span class="cx">             if (!edge)
</span><span class="cx">                 break;
</span><span class="cx">             edge.setUseKind(KnownStringUse);
</span><del>-            if (!m_graph.isConstant(edge.node()))
</del><ins>+            JSString* string = edge-&gt;dynamicCastConstant&lt;JSString*&gt;();
+            if (!string)
</ins><span class="cx">                 continue;
</span><del>-            JSString* string = jsCast&lt;JSString*&gt;(m_graph.valueOfJSConstant(edge.node()).asCell());
</del><span class="cx">             if (string-&gt;length())
</span><span class="cx">                 continue;
</span><span class="cx">             
</span><span class="lines">@@ -1618,27 +1618,15 @@
</span><span class="cx">     {
</span><span class="cx">         Node* oldNode = edge.node();
</span><span class="cx">         
</span><del>-        ASSERT(oldNode-&gt;hasConstant());
-        JSValue value = m_graph.valueOfJSConstant(oldNode);
</del><ins>+        JSValue value = oldNode-&gt;asJSValue();
</ins><span class="cx">         if (value.isInt32())
</span><span class="cx">             return;
</span><span class="cx">         
</span><span class="cx">         value = jsNumber(JSC::toInt32(value.asNumber()));
</span><span class="cx">         ASSERT(value.isInt32());
</span><del>-        unsigned constantRegister;
-        if (!codeBlock()-&gt;findConstant(value, constantRegister)) {
-            constantRegister = codeBlock()-&gt;addConstantLazily();
-            initializeLazyWriteBarrierForConstant(
-                m_graph.m_plan.writeBarriers,
-                codeBlock()-&gt;constants()[constantRegister],
-                codeBlock(),
-                constantRegister,
-                codeBlock()-&gt;ownerExecutable(),
-                value);
-        }
</del><span class="cx">         edge.setNode(m_insertionSet.insertNode(
</span><span class="cx">             m_indexInBlock, SpecInt32, JSConstant, m_currentNode-&gt;origin,
</span><del>-            OpInfo(constantRegister)));
</del><ins>+            OpInfo(m_graph.freeze(value))));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
</span><span class="lines">@@ -1741,7 +1729,7 @@
</span><span class="cx">         
</span><span class="cx">         Node* shiftAmount = m_insertionSet.insertNode(
</span><span class="cx">             m_indexInBlock, SpecInt32, JSConstant, node-&gt;origin,
</span><del>-            OpInfo(m_graph.constantRegisterForConstant(jsNumber(logElementSize(type)))));
</del><ins>+            OpInfo(m_graph.freeze(jsNumber(logElementSize(type)))));
</ins><span class="cx">         
</span><span class="cx">         // We can use a BitLShift here because typed arrays will never have a byteLength
</span><span class="cx">         // that overflows int32.
</span><span class="lines">@@ -1915,7 +1903,7 @@
</span><span class="cx">                 DFG_ASSERT(m_graph, node, edge-&gt;op() == JSConstant);
</span><span class="cx">                 result = m_insertionSet.insertNode(
</span><span class="cx">                     m_indexInBlock, SpecMachineInt, Int52Constant, node-&gt;origin,
</span><del>-                    OpInfo(edge-&gt;constantNumber()));
</del><ins>+                    OpInfo(edge-&gt;constant()));
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             edge.setNode(result);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGFrozenValuecpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp (0 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DFGFrozenValue.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC { namespace DFG {
+
+FrozenValue* FrozenValue::emptySingleton()
+{
+    static FrozenValue empty;
+    return &amp;empty;
+}
+
+void FrozenValue::dumpInContext(PrintStream&amp; out, DumpContext* context) const
+{
+    if (!!m_value &amp;&amp; m_value.isCell())
+        out.print(m_strength, &quot;:&quot;);
+    m_value.dumpInContextAssumingStructure(out, context, m_structure);
+}
+
+void FrozenValue::dump(PrintStream&amp; out) const
+{
+    dumpInContext(out, 0);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGFrozenValueh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.h (0 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.h                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGFrozenValue.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGFrozenValue_h
+#define DFGFrozenValue_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGValueStrength.h&quot;
+#include &quot;JSCell.h&quot;
+#include &quot;JSCJSValue.h&quot;
+#include &quot;Structure.h&quot;
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class FrozenValue {
+public:
+    FrozenValue()
+        : m_structure(nullptr)
+        , m_strength(FragileValue)
+    {
+    }
+    
+    FrozenValue(JSValue value)
+        : m_value(value)
+        , m_structure(nullptr)
+        , m_strength(FragileValue)
+    {
+        RELEASE_ASSERT(!value || !value.isCell());
+    }
+    
+    FrozenValue(JSValue value, Structure* structure, ValueStrength strength)
+        : m_value(value)
+        , m_structure(structure)
+        , m_strength(strength)
+    {
+        ASSERT((!!value &amp;&amp; value.isCell()) == !!structure);
+        ASSERT(!value || !value.isCell() || value.asCell()-&gt;classInfo() == structure-&gt;classInfo());
+        ASSERT(!!structure || (strength == FragileValue));
+    }
+    
+    static FrozenValue* emptySingleton();
+    
+    bool operator!() const { return !m_value; }
+    
+    JSValue value() const { return m_value; }
+    Structure* structure() const { return m_structure; }
+    
+    void strengthenTo(ValueStrength strength)
+    {
+        if (!!m_value &amp;&amp; m_value.isCell())
+            m_strength = merge(m_strength, strength);
+    }
+    
+    // The strength of the value itself. The structure should be viewed as fragile
+    // except if it is watched, in which case it's weak. Note that currently we
+    // watch all watchable structures indiscriminantly, and so we also mark them
+    // weakly. We could improve on this: any optimization that makes use of a
+    // structure could signal that it has done so, and we could avoid watching
+    // watchable structures that we had never marked in such a way.
+    ValueStrength strength() const { return m_strength; }
+    
+    void dumpInContext(PrintStream&amp; out, DumpContext* context) const;
+    void dump(PrintStream&amp; out) const;
+    
+private:
+    friend class Graph;
+    
+    // This is a utility method for DFG::Graph::freeze(). You should almost always call
+    // Graph::freeze() directly. Calling this instead of Graph::freeze() can result in
+    // the same constant being viewed as having different structures during the course
+    // of compilation, which can sometimes cause bad things to happen. For example, we
+    // may observe that one version of the constant has an unwatchable structure but
+    // then a later version may start to have a watchable structure due to a transition.
+    // The point of freezing is to ensure that we generally only see one version of
+    // constants, but that requires freezing through the Graph.
+    static FrozenValue freeze(JSValue value)
+    {
+        return FrozenValue(
+            value,
+            (!!value &amp;&amp; value.isCell()) ? value.asCell()-&gt;structure() : nullptr,
+            FragileValue);
+    }
+
+    JSValue m_value;
+    Structure* m_structure;
+    ValueStrength m_strength;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGFrozenValue_h
+
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -60,19 +60,20 @@
</span><span class="cx">     , m_codeBlock(m_plan.codeBlock.get())
</span><span class="cx">     , m_profiledBlock(m_codeBlock-&gt;alternative())
</span><span class="cx">     , m_allocator(longLivedState.m_allocator)
</span><del>-    , m_mustHandleAbstractValues(OperandsLike, plan.mustHandleValues)
</del><ins>+    , m_mustHandleValues(OperandsLike, plan.mustHandleValues)
</ins><span class="cx">     , m_hasArguments(false)
</span><span class="cx">     , m_nextMachineLocal(0)
</span><span class="cx">     , m_machineCaptureStart(std::numeric_limits&lt;int&gt;::max())
</span><span class="cx">     , m_fixpointState(BeforeFixpoint)
</span><ins>+    , m_structureWatchpointState(HaveNotStartedWatching)
</ins><span class="cx">     , m_form(LoadStore)
</span><span class="cx">     , m_unificationState(LocallyUnified)
</span><span class="cx">     , m_refCountState(EverythingIsLive)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_profiledBlock);
</span><span class="cx">     
</span><del>-    for (unsigned i = m_mustHandleAbstractValues.size(); i--;)
-        m_mustHandleAbstractValues[i].setMostSpecific(*this, plan.mustHandleValues[i]);
</del><ins>+    for (unsigned i = m_mustHandleValues.size(); i--;)
+        m_mustHandleValues[i] = freezeFragile(plan.mustHandleValues[i]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Graph::~Graph()
</span><span class="lines">@@ -178,7 +179,6 @@
</span><span class="cx">     // (5) The arguments to the operation. The may be of the form:
</span><span class="cx">     //         @#   - a NodeIndex referencing a prior node in the graph.
</span><span class="cx">     //         arg# - an argument number.
</span><del>-    //         $#   - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }.
</del><span class="cx">     //         id#  - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
</span><span class="cx">     //         var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
</span><span class="cx">     out.printf(&quot;% 4d:%s&lt;%c%u:&quot;, (int)node-&gt;index(), skipped ? &quot;  skipped  &quot; : &quot;           &quot;, mustGenerate ? '!' : ' ', refCount);
</span><span class="lines">@@ -224,9 +224,10 @@
</span><span class="cx">     if (node-&gt;hasTransition())
</span><span class="cx">         out.print(comma, pointerDumpInContext(node-&gt;transition(), context));
</span><span class="cx">     if (node-&gt;hasFunction()) {
</span><del>-        out.print(comma, &quot;function(&quot;, RawPointer(node-&gt;function()), &quot;, &quot;);
-        if (node-&gt;function()-&gt;inherits(JSFunction::info())) {
-            JSFunction* function = jsCast&lt;JSFunction*&gt;(node-&gt;function());
</del><ins>+        out.print(comma, &quot;function(&quot;, pointerDump(node-&gt;function()), &quot;, &quot;);
+        if (node-&gt;function()-&gt;value().isCell()
+            &amp;&amp; node-&gt;function()-&gt;value().asCell()-&gt;inherits(JSFunction::info())) {
+            JSFunction* function = jsCast&lt;JSFunction*&gt;(node-&gt;function()-&gt;value().asCell());
</ins><span class="cx">             if (function-&gt;isHostFunction())
</span><span class="cx">                 out.print(&quot;&lt;host function&gt;&quot;);
</span><span class="cx">             else
</span><span class="lines">@@ -306,7 +307,7 @@
</span><span class="cx">         out.print(node-&gt;startConstant(), &quot;:[&quot;);
</span><span class="cx">         CommaPrinter anotherComma;
</span><span class="cx">         for (unsigned i = 0; i &lt; node-&gt;numConstants(); ++i)
</span><del>-            out.print(anotherComma, inContext(m_codeBlock-&gt;constantBuffer(node-&gt;startConstant())[i], context));
</del><ins>+            out.print(anotherComma, pointerDumpInContext(freeze(m_codeBlock-&gt;constantBuffer(node-&gt;startConstant())[i]), context));
</ins><span class="cx">         out.print(&quot;]&quot;);
</span><span class="cx">     }
</span><span class="cx">     if (node-&gt;hasIndexingType())
</span><span class="lines">@@ -323,13 +324,8 @@
</span><span class="cx">         out.print(comma, inContext(JSValue(node-&gt;typedArray()), context));
</span><span class="cx">     if (node-&gt;hasStoragePointer())
</span><span class="cx">         out.print(comma, RawPointer(node-&gt;storagePointer()));
</span><del>-    if (node-&gt;isConstant()) {
-        out.print(comma, &quot;$&quot;, node-&gt;constantNumber());
-        JSValue value = valueOfJSConstant(node);
-        out.print(&quot; = &quot;, inContext(value, context));
-    }
-    if (op == WeakJSConstant)
-        out.print(comma, RawPointer(node-&gt;weakConstant()), &quot; (&quot;, inContext(*node-&gt;weakConstant()-&gt;structure(), context), &quot;)&quot;);
</del><ins>+    if (node-&gt;isConstant())
+        out.print(comma, pointerDumpInContext(node-&gt;constant(), context));
</ins><span class="cx">     if (node-&gt;isJump())
</span><span class="cx">         out.print(comma, &quot;T:&quot;, *node-&gt;targetBlock());
</span><span class="cx">     if (node-&gt;isBranch())
</span><span class="lines">@@ -792,9 +788,7 @@
</span><span class="cx"> 
</span><span class="cx"> JSActivation* Graph::tryGetActivation(Node* node)
</span><span class="cx"> {
</span><del>-    if (!node-&gt;hasConstant())
-        return 0;
-    return jsDynamicCast&lt;JSActivation*&gt;(valueOfJSConstant(node));
</del><ins>+    return node-&gt;dynamicCastConstant&lt;JSActivation*&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WriteBarrierBase&lt;Unknown&gt;* Graph::tryGetRegisters(Node* node)
</span><span class="lines">@@ -809,13 +803,11 @@
</span><span class="cx"> 
</span><span class="cx"> JSArrayBufferView* Graph::tryGetFoldableView(Node* node)
</span><span class="cx"> {
</span><del>-    if (!node-&gt;hasConstant())
-        return 0;
-    JSArrayBufferView* view = jsDynamicCast&lt;JSArrayBufferView*&gt;(valueOfJSConstant(node));
</del><ins>+    JSArrayBufferView* view = node-&gt;dynamicCastConstant&lt;JSArrayBufferView*&gt;();
</ins><span class="cx">     if (!view)
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     if (!view-&gt;length())
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     WTF::loadLoadFence();
</span><span class="cx">     return view;
</span><span class="cx"> }
</span><span class="lines">@@ -832,8 +824,43 @@
</span><span class="cx">     return tryGetFoldableView(child(node, 0).node(), node-&gt;arrayMode());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Graph::registerFrozenValues()
+{
+    m_codeBlock-&gt;constants().resize(0);
+    for (FrozenValue* value : m_frozenValues) {
+        if (value-&gt;structure() &amp;&amp; value-&gt;structure()-&gt;dfgShouldWatch())
+            m_plan.weakReferences.addLazily(value-&gt;structure());
+        
+        switch (value-&gt;strength()) {
+        case FragileValue: {
+            break;
+        }
+        case WeakValue: {
+            m_plan.weakReferences.addLazily(value-&gt;value().asCell());
+            break;
+        }
+        case StrongValue: {
+            unsigned constantIndex = m_codeBlock-&gt;addConstantLazily();
+            initializeLazyWriteBarrierForConstant(
+                m_plan.writeBarriers,
+                m_codeBlock-&gt;constants()[constantIndex],
+                m_codeBlock,
+                constantIndex,
+                m_codeBlock-&gt;ownerExecutable(),
+                value-&gt;value());
+            break;
+        } }
+    }
+    m_codeBlock-&gt;constants().shrinkToFit();
+}
+
</ins><span class="cx"> void Graph::visitChildren(SlotVisitor&amp; visitor)
</span><span class="cx"> {
</span><ins>+    for (FrozenValue* value : m_frozenValues) {
+        visitor.appendUnbarrieredReadOnlyValue(value-&gt;value());
+        visitor.appendUnbarrieredReadOnlyPointer(value-&gt;structure());
+    }
+    
</ins><span class="cx">     for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
</span><span class="cx">         BasicBlock* block = this-&gt;block(blockIndex);
</span><span class="cx">         if (!block)
</span><span class="lines">@@ -843,15 +870,6 @@
</span><span class="cx">             Node* node = block-&gt;at(nodeIndex);
</span><span class="cx">             
</span><span class="cx">             switch (node-&gt;op()) {
</span><del>-            case JSConstant:
-            case WeakJSConstant:
-                visitor.appendUnbarrieredReadOnlyValue(valueOfJSConstant(node));
-                break;
-                
-            case CheckFunction:
-                visitor.appendUnbarrieredReadOnlyPointer(node-&gt;function());
-                break;
-                
</del><span class="cx">             case CheckExecutable:
</span><span class="cx">                 visitor.appendUnbarrieredReadOnlyPointer(node-&gt;executable());
</span><span class="cx">                 break;
</span><span class="lines">@@ -909,8 +927,58 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FrozenValue* Graph::freezeFragile(JSValue value)
+{
+    if (UNLIKELY(!value))
+        return FrozenValue::emptySingleton();
+    
+    auto result = m_frozenValueMap.add(JSValue::encode(value), nullptr);
+    if (LIKELY(!result.isNewEntry))
+        return result.iterator-&gt;value;
+    
+    return result.iterator-&gt;value = m_frozenValues.add(FrozenValue::freeze(value));
+}
+
+FrozenValue* Graph::freeze(JSValue value)
+{
+    FrozenValue* result = freezeFragile(value);
+    result-&gt;strengthenTo(WeakValue);
+    return result;
+}
+
+FrozenValue* Graph::freezeStrong(JSValue value)
+{
+    FrozenValue* result = freeze(value);
+    result-&gt;strengthenTo(StrongValue);
+    return result;
+}
+
+void Graph::convertToConstant(Node* node, FrozenValue* value)
+{
+    if (value-&gt;structure())
+        assertIsWatched(value-&gt;structure());
+    if (node-&gt;op() == GetLocal)
+        dethread();
+    else
+        ASSERT(!node-&gt;hasVariableAccessData(*this));
+    node-&gt;convertToConstant(value);
+}
+
+void Graph::convertToConstant(Node* node, JSValue value)
+{
+    convertToConstant(node, freeze(value));
+}
+
+void Graph::convertToStrongConstant(Node* node, JSValue value)
+{
+    convertToConstant(node, freezeStrong(value));
+}
+
</ins><span class="cx"> void Graph::assertIsWatched(Structure* structure)
</span><span class="cx"> {
</span><ins>+    if (m_structureWatchpointState == HaveNotStartedWatching)
+        return;
+    
</ins><span class="cx">     if (!structure-&gt;dfgShouldWatch())
</span><span class="cx">         return;
</span><span class="cx">     if (watchpoints().isWatched(structure-&gt;transitionWatchpointSet()))
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGGraph.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;DFGArgumentPosition.h&quot;
</span><span class="cx"> #include &quot;DFGBasicBlock.h&quot;
</span><span class="cx"> #include &quot;DFGDominators.h&quot;
</span><ins>+#include &quot;DFGFrozenValue.h&quot;
</ins><span class="cx"> #include &quot;DFGLongLivedState.h&quot;
</span><span class="cx"> #include &quot;DFGNaturalLoops.h&quot;
</span><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="lines">@@ -144,43 +145,16 @@
</span><span class="cx"> 
</span><span class="cx">     void dethread();
</span><span class="cx">     
</span><del>-    void convertToConstant(Node* node, unsigned constantNumber)
-    {
-        if (node-&gt;op() == GetLocal)
-            dethread();
-        else
-            ASSERT(!node-&gt;hasVariableAccessData(*this));
-        node-&gt;convertToConstant(constantNumber);
-    }
</del><ins>+    FrozenValue* freezeFragile(JSValue value);
+    FrozenValue* freeze(JSValue value); // We use weak freezing by default.
+    FrozenValue* freezeStrong(JSValue value); // Shorthand for freeze(value)-&gt;markStrongly().
</ins><span class="cx">     
</span><del>-    unsigned constantRegisterForConstant(JSValue value)
-    {
-        unsigned constantRegister;
-        if (!m_codeBlock-&gt;findConstant(value, constantRegister)) {
-            constantRegister = m_codeBlock-&gt;addConstantLazily();
-            initializeLazyWriteBarrierForConstant(
-                m_plan.writeBarriers,
-                m_codeBlock-&gt;constants()[constantRegister],
-                m_codeBlock,
-                constantRegister,
-                m_codeBlock-&gt;ownerExecutable(),
-                value);
-        }
-        return constantRegister;
-    }
</del><ins>+    void convertToConstant(Node* node, FrozenValue* value);
+    void convertToConstant(Node* node, JSValue value);
+    void convertToStrongConstant(Node* node, JSValue value);
</ins><span class="cx">     
</span><span class="cx">     void assertIsWatched(Structure* structure);
</span><span class="cx">     
</span><del>-    void convertToConstant(Node* node, JSValue value)
-    {
-        if (value.isCell())
-            assertIsWatched(value.asCell()-&gt;structure());
-        if (value.isObject())
-            node-&gt;convertToWeakConstant(value.asCell());
-        else
-            convertToConstant(node, constantRegisterForConstant(value));
-    }
-
</del><span class="cx">     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
</span><span class="cx">     void dump(PrintStream&amp; = WTF::dataFile(), DumpContext* = 0);
</span><span class="cx">     enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
</span><span class="lines">@@ -194,11 +168,6 @@
</span><span class="cx">     // preceding node. Returns true if anything was printed.
</span><span class="cx">     bool dumpCodeOrigin(PrintStream&amp;, const char* prefix, Node* previousNode, Node* currentNode, DumpContext* context);
</span><span class="cx"> 
</span><del>-    SpeculatedType getJSConstantSpeculation(Node* node)
-    {
-        return speculationFromValue(node-&gt;valueOfJSConstant(m_codeBlock));
-    }
-    
</del><span class="cx">     AddSpeculationMode addSpeculationMode(Node* add, bool leftShouldSpeculateInt32, bool rightShouldSpeculateInt32)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(add-&gt;op() == ValueAdd || add-&gt;op() == ArithAdd || add-&gt;op() == ArithSub);
</span><span class="lines">@@ -303,88 +272,6 @@
</span><span class="cx">             baselineCodeBlockFor(codeOrigin)-&gt;argumentIndexAfterCapture(argument));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    // Helper methods to check nodes for constants.
-    bool isConstant(Node* node)
-    {
-        return node-&gt;hasConstant();
-    }
-    bool isJSConstant(Node* node)
-    {
-        return node-&gt;hasConstant();
-    }
-    bool isInt32Constant(Node* node)
-    {
-        return node-&gt;isInt32Constant(m_codeBlock);
-    }
-    bool isDoubleConstant(Node* node)
-    {
-        return node-&gt;isDoubleConstant(m_codeBlock);
-    }
-    bool isNumberConstant(Node* node)
-    {
-        return node-&gt;isNumberConstant(m_codeBlock);
-    }
-    bool isBooleanConstant(Node* node)
-    {
-        return node-&gt;isBooleanConstant(m_codeBlock);
-    }
-    bool isCellConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        JSValue value = valueOfJSConstant(node);
-        return value.isCell() &amp;&amp; !!value;
-    }
-    bool isFunctionConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        if (!getJSFunction(valueOfJSConstant(node)))
-            return false;
-        return true;
-    }
-    bool isInternalFunctionConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        JSValue value = valueOfJSConstant(node);
-        if (!value.isCell() || !value)
-            return false;
-        JSCell* cell = value.asCell();
-        if (!cell-&gt;inherits(InternalFunction::info()))
-            return false;
-        return true;
-    }
-    // Helper methods get constant values from nodes.
-    JSValue valueOfJSConstant(Node* node)
-    {
-        return node-&gt;valueOfJSConstant(m_codeBlock);
-    }
-    int32_t valueOfInt32Constant(Node* node)
-    {
-        JSValue value = valueOfJSConstant(node);
-        if (!value.isInt32()) {
-            dataLog(&quot;Value isn't int32: &quot;, value, &quot;\n&quot;);
-            dump();
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-        return value.asInt32();
-    }
-    double valueOfNumberConstant(Node* node)
-    {
-        return valueOfJSConstant(node).asNumber();
-    }
-    bool valueOfBooleanConstant(Node* node)
-    {
-        return valueOfJSConstant(node).asBoolean();
-    }
-    JSFunction* valueOfFunctionConstant(Node* node)
-    {
-        JSCell* function = getJSFunction(valueOfJSConstant(node));
-        ASSERT(function);
-        return jsCast&lt;JSFunction*&gt;(function);
-    }
-
</del><span class="cx">     static const char *opName(NodeType);
</span><span class="cx">     
</span><span class="cx">     StructureSet* addStructureSet(const StructureSet&amp; structureSet)
</span><span class="lines">@@ -802,6 +689,8 @@
</span><span class="cx">     JSArrayBufferView* tryGetFoldableView(Node*, ArrayMode);
</span><span class="cx">     JSArrayBufferView* tryGetFoldableViewForChild1(Node*);
</span><span class="cx">     
</span><ins>+    void registerFrozenValues();
+    
</ins><span class="cx">     virtual void visitChildren(SlotVisitor&amp;) override;
</span><span class="cx">     
</span><span class="cx">     NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
</span><span class="lines">@@ -815,10 +704,14 @@
</span><span class="cx">     
</span><span class="cx">     NodeAllocator&amp; m_allocator;
</span><span class="cx"> 
</span><del>-    Operands&lt;AbstractValue&gt; m_mustHandleAbstractValues;
</del><ins>+    Operands&lt;FrozenValue*&gt; m_mustHandleValues;
</ins><span class="cx">     
</span><span class="cx">     Vector&lt; RefPtr&lt;BasicBlock&gt; , 8&gt; m_blocks;
</span><span class="cx">     Vector&lt;Edge, 16&gt; m_varArgChildren;
</span><ins>+
+    HashMap&lt;EncodedJSValue, FrozenValue*, EncodedJSValueHash, EncodedJSValueHashTraits&gt; m_frozenValueMap;
+    Bag&lt;FrozenValue&gt; m_frozenValues;
+    
</ins><span class="cx">     Vector&lt;StorageAccessData&gt; m_storageAccessData;
</span><span class="cx">     Vector&lt;Node*, 8&gt; m_arguments;
</span><span class="cx">     SegmentedVector&lt;VariableAccessData, 16&gt; m_variableAccessData;
</span><span class="lines">@@ -849,6 +742,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     OptimizationFixpointState m_fixpointState;
</span><ins>+    StructureWatchpointState m_structureWatchpointState;
</ins><span class="cx">     GraphForm m_form;
</span><span class="cx">     UnificationState m_unificationState;
</span><span class="cx">     RefCountState m_refCountState;
</span><span class="lines">@@ -861,7 +755,7 @@
</span><span class="cx">     {
</span><span class="cx">         ASSERT(immediate-&gt;hasConstant());
</span><span class="cx">         
</span><del>-        JSValue immediateValue = immediate-&gt;valueOfJSConstant(m_codeBlock);
</del><ins>+        JSValue immediateValue = immediate-&gt;asJSValue();
</ins><span class="cx">         if (!immediateValue.isNumber())
</span><span class="cx">             return DontSpeculateInt32;
</span><span class="cx">         
</span><span class="lines">@@ -878,30 +772,6 @@
</span><span class="cx">         
</span><span class="cx">         return bytecodeCanTruncateInteger(add-&gt;arithNodeFlags()) ? SpeculateInt32AndTruncateConstants : DontSpeculateInt32;
</span><span class="cx">     }
</span><del>-    
-    bool mulImmediateShouldSpeculateInt32(Node* mul, Node* variable, Node* immediate)
-    {
-        ASSERT(immediate-&gt;hasConstant());
-        
-        JSValue immediateValue = immediate-&gt;valueOfJSConstant(m_codeBlock);
-        if (!immediateValue.isInt32())
-            return false;
-        
-        if (!variable-&gt;shouldSpeculateInt32ForArithmetic())
-            return false;
-        
-        int32_t intImmediate = immediateValue.asInt32();
-        // Doubles have a 53 bit mantissa so we expect a multiplication of 2^31 (the highest
-        // magnitude possible int32 value) and any value less than 2^22 to not result in any
-        // rounding in a double multiplication - hence it will be equivalent to an integer
-        // multiplication, if we are doing int32 truncation afterwards (which is what
-        // canSpeculateInt32() implies).
-        const int32_t twoToThe22 = 1 &lt;&lt; 22;
-        if (intImmediate &lt;= -twoToThe22 || intImmediate &gt;= twoToThe22)
-            return mul-&gt;canSpeculateInt32() &amp;&amp; !nodeMayOverflow(mul-&gt;arithNodeFlags());
-
-        return mul-&gt;canSpeculateInt32();
-    }
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> #define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -151,17 +151,18 @@
</span><span class="cx">             continue;
</span><span class="cx">         if (block-&gt;bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex)
</span><span class="cx">             continue;
</span><del>-        for (size_t i = 0; i &lt; m_graph.m_mustHandleAbstractValues.size(); ++i) {
-            int operand = m_graph.m_mustHandleAbstractValues.operandForIndex(i);
</del><ins>+        for (size_t i = 0; i &lt; m_graph.m_mustHandleValues.size(); ++i) {
+            int operand = m_graph.m_mustHandleValues.operandForIndex(i);
</ins><span class="cx">             Node* node = block-&gt;variablesAtHead.operand(operand);
</span><span class="cx">             if (!node)
</span><span class="cx">                 continue;
</span><del>-            AbstractValue value = m_graph.m_mustHandleAbstractValues[i];
-            AbstractValue&amp; abstractValue = block-&gt;valuesAtHead.operand(operand);
</del><ins>+            AbstractValue source;
+            source.setOSREntryValue(m_graph, *m_graph.m_mustHandleValues[i]);
+            AbstractValue&amp; target = block-&gt;valuesAtHead.operand(operand);
</ins><span class="cx">             VariableAccessData* variable = node-&gt;variableAccessData();
</span><span class="cx">             FlushFormat format = variable-&gt;flushFormat();
</span><del>-            abstractValue.merge(value);
-            abstractValue.fixTypeForRepresentation(resultFor(format));
</del><ins>+            target.merge(source);
+            target.fixTypeForRepresentation(resultFor(format));
</ins><span class="cx">         }
</span><span class="cx">         block-&gt;cfaShouldRevisit = true;
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGInsertionSeth"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGInsertionSet.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGInsertionSet.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGInsertionSet.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -62,23 +62,21 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Node* insertConstant(
</span><del>-        size_t index, NodeOrigin origin, JSValue value,
</del><ins>+        size_t index, NodeOrigin origin, FrozenValue* value,
</ins><span class="cx">         NodeType op = JSConstant)
</span><span class="cx">     {
</span><del>-        unsigned constantReg =
-            m_graph.constantRegisterForConstant(value);
</del><span class="cx">         return insertNode(
</span><del>-            index, speculationFromValue(value), op, origin, OpInfo(constantReg));
</del><ins>+            index, speculationFromValue(value-&gt;value()), op, origin, OpInfo(value));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Node* insertConstant(
</span><del>-        size_t index, CodeOrigin origin, JSValue value, NodeType op = JSConstant)
</del><ins>+        size_t index, CodeOrigin origin, FrozenValue* value, NodeType op = JSConstant)
</ins><span class="cx">     {
</span><span class="cx">         return insertConstant(index, NodeOrigin(origin), value, op);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Edge insertConstantForUse(
</span><del>-        size_t index, NodeOrigin origin, JSValue value, UseKind useKind)
</del><ins>+        size_t index, NodeOrigin origin, FrozenValue* value, UseKind useKind)
</ins><span class="cx">     {
</span><span class="cx">         NodeType op;
</span><span class="cx">         if (isDouble(useKind))
</span><span class="lines">@@ -91,11 +89,31 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Edge insertConstantForUse(
</span><del>-        size_t index, CodeOrigin origin, JSValue value, UseKind useKind)
</del><ins>+        size_t index, CodeOrigin origin, FrozenValue* value, UseKind useKind)
</ins><span class="cx">     {
</span><span class="cx">         return insertConstantForUse(index, NodeOrigin(origin), value, useKind);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    Node* insertConstant(size_t index, NodeOrigin origin, JSValue value, NodeType op = JSConstant)
+    {
+        return insertConstant(index, origin, m_graph.freeze(value), op);
+    }
+    
+    Node* insertConstant(size_t index, CodeOrigin origin, JSValue value, NodeType op = JSConstant)
+    {
+        return insertConstant(index, origin, m_graph.freeze(value), op);
+    }
+    
+    Edge insertConstantForUse(size_t index, NodeOrigin origin, JSValue value, UseKind useKind)
+    {
+        return insertConstantForUse(index, origin, m_graph.freeze(value), useKind);
+    }
+    
+    Edge insertConstantForUse(size_t index, CodeOrigin origin, JSValue value, UseKind useKind)
+    {
+        return insertConstantForUse(index, NodeOrigin(origin), value, useKind);
+    }
+
</ins><span class="cx">     void execute(BasicBlock* block)
</span><span class="cx">     {
</span><span class="cx">         executeInsertions(*block, m_insertions);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGIntegerCheckCombiningPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -311,11 +311,11 @@
</span><span class="cx">             if (node-&gt;arithMode() != Arith::CheckOverflow
</span><span class="cx">                 &amp;&amp; node-&gt;arithMode() != Arith::CheckOverflowAndNegativeZero)
</span><span class="cx">                 break;
</span><del>-            if (!m_graph.isInt32Constant(node-&gt;child2().node()))
</del><ins>+            if (!node-&gt;child2()-&gt;isInt32Constant())
</ins><span class="cx">                 break;
</span><span class="cx">             return RangeKeyAndAddend(
</span><span class="cx">                 RangeKey::addition(node-&gt;child1()),
</span><del>-                m_graph.valueOfInt32Constant(node-&gt;child2().node()));
</del><ins>+                node-&gt;child2()-&gt;asInt32());
</ins><span class="cx">         }
</span><span class="cx">                 
</span><span class="cx">         case CheckInBounds: {
</span><span class="lines">@@ -325,15 +325,15 @@
</span><span class="cx">             
</span><span class="cx">             Edge index = node-&gt;child1();
</span><span class="cx">             
</span><del>-            if (m_graph.isInt32Constant(index.node())) {
</del><ins>+            if (index-&gt;isInt32Constant()) {
</ins><span class="cx">                 source = Edge();
</span><del>-                addend = m_graph.valueOfInt32Constant(index.node());
</del><ins>+                addend = index-&gt;asInt32();
</ins><span class="cx">             } else if (
</span><span class="cx">                 index-&gt;op() == ArithAdd
</span><span class="cx">                 &amp;&amp; index-&gt;isBinaryUseKind(Int32Use)
</span><del>-                &amp;&amp; m_graph.isInt32Constant(index-&gt;child2().node())) {
</del><ins>+                &amp;&amp; node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">                 source = index-&gt;child1();
</span><del>-                addend = m_graph.valueOfInt32Constant(index-&gt;child2().node());
</del><ins>+                addend = index-&gt;child2()-&gt;asInt32();
</ins><span class="cx">             } else {
</span><span class="cx">                 source = index;
</span><span class="cx">                 addend = 0;
</span><span class="lines">@@ -341,7 +341,7 @@
</span><span class="cx">             
</span><span class="cx">             return RangeKeyAndAddend(RangeKey::arrayBounds(source, key), addend);
</span><span class="cx">         }
</span><del>-                
</del><ins>+            
</ins><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -162,6 +162,8 @@
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx">     m_jitCode-&gt;common.doubleConstants = std::move(m_graph.m_doubleConstants);
</span><span class="cx"> #endif
</span><ins>+    
+    m_graph.registerFrozenValues();
</ins><span class="cx"> 
</span><span class="cx">     BitVector usedJumpTables;
</span><span class="cx">     for (Bag&lt;SwitchData&gt;::iterator iter = m_graph.m_switchData.begin(); !!iter; ++iter) {
</span><span class="lines">@@ -439,11 +441,7 @@
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx"> void* JITCompiler::addressOfDoubleConstant(Node* node)
</span><span class="cx"> {
</span><del>-    ASSERT(m_graph.isNumberConstant(node));
-    JSValue jsvalue = node-&gt;valueOfJSConstant(codeBlock());
-    ASSERT(jsvalue.isDouble());
-
-    double value = jsvalue.asDouble();
</del><ins>+    double value = node-&gt;asNumber();
</ins><span class="cx">     auto it = m_graph.m_doubleConstantsMap.find(value);
</span><span class="cx">     if (it != m_graph.m_doubleConstantsMap.end())
</span><span class="cx">         return it-&gt;value;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGLazyJSValuecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -36,14 +36,14 @@
</span><span class="cx"> {
</span><span class="cx">     switch (m_kind) {
</span><span class="cx">     case KnownValue:
</span><del>-        return value();
</del><ins>+        return value()-&gt;value();
</ins><span class="cx">     case SingleCharacterString:
</span><span class="cx">         return jsSingleCharacterString(&amp;vm, u.character);
</span><span class="cx">     case KnownStringImpl:
</span><span class="cx">         return jsString(&amp;vm, u.stringImpl);
</span><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><del>-    return value();
</del><ins>+    return JSValue();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static TriState equalToSingleCharacter(JSValue value, UChar character)
</span><span class="lines">@@ -81,11 +81,11 @@
</span><span class="cx">     case KnownValue:
</span><span class="cx">         switch (other.m_kind) {
</span><span class="cx">         case KnownValue:
</span><del>-            return JSValue::pureStrictEqual(value(), other.value());
</del><ins>+            return JSValue::pureStrictEqual(value()-&gt;value(), other.value()-&gt;value());
</ins><span class="cx">         case SingleCharacterString:
</span><del>-            return equalToSingleCharacter(value(), other.character());
</del><ins>+            return equalToSingleCharacter(value()-&gt;value(), other.character());
</ins><span class="cx">         case KnownStringImpl:
</span><del>-            return equalToStringImpl(value(), other.stringImpl());
</del><ins>+            return equalToStringImpl(value()-&gt;value(), other.stringImpl());
</ins><span class="cx">         }
</span><span class="cx">         break;
</span><span class="cx">     case SingleCharacterString:
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx"> {
</span><span class="cx">     switch (m_kind) {
</span><span class="cx">     case KnownValue:
</span><del>-        value().dumpInContext(out, context);
</del><ins>+        value()-&gt;dumpInContext(out, context);
</ins><span class="cx">         return;
</span><span class="cx">     case SingleCharacterString:
</span><span class="cx">         out.print(&quot;Lazy:SingleCharacterString(&quot;);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGLazyJSValueh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGLazyJSValue.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><del>-#include &quot;JSCJSValue.h&quot;
</del><ins>+#include &quot;DFGFrozenValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/text/StringImpl.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -44,10 +44,10 @@
</span><span class="cx"> 
</span><span class="cx"> class LazyJSValue {
</span><span class="cx"> public:
</span><del>-    LazyJSValue(JSValue value = JSValue())
</del><ins>+    LazyJSValue(FrozenValue* value = FrozenValue::emptySingleton())
</ins><span class="cx">         : m_kind(KnownValue)
</span><span class="cx">     {
</span><del>-        u.value = JSValue::encode(value);
</del><ins>+        u.value = value;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     static LazyJSValue singleCharacterString(UChar character)
</span><span class="lines">@@ -66,19 +66,19 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    JSValue tryGetValue() const
</del><ins>+    FrozenValue* tryGetValue(Graph&amp;) const
</ins><span class="cx">     {
</span><span class="cx">         if (m_kind == KnownValue)
</span><span class="cx">             return value();
</span><del>-        return JSValue();
</del><ins>+        return nullptr;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     JSValue getValue(VM&amp;) const;
</span><span class="cx">     
</span><del>-    JSValue value() const
</del><ins>+    FrozenValue* value() const
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(m_kind == KnownValue);
</span><del>-        return JSValue::decode(u.value);
</del><ins>+        return u.value;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     UChar character() const
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx">         // for a kind of value that can't.
</span><span class="cx">         switch (m_kind) {
</span><span class="cx">         case KnownValue:
</span><del>-            return value().asInt32();
</del><ins>+            return value()-&gt;value().asInt32();
</ins><span class="cx">         case SingleCharacterString:
</span><span class="cx">             return character();
</span><span class="cx">         default:
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     union {
</span><del>-        EncodedJSValue value;
</del><ins>+        FrozenValue* value;
</ins><span class="cx">         UChar character;
</span><span class="cx">         StringImpl* stringImpl;
</span><span class="cx">     } u;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGMinifiedNodecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -39,10 +39,8 @@
</span><span class="cx">     MinifiedNode result;
</span><span class="cx">     result.m_id = MinifiedID(node);
</span><span class="cx">     result.m_op = node-&gt;op();
</span><del>-    if (hasConstantNumber(node-&gt;op()))
-        result.m_info = node-&gt;constantNumber();
-    else if (hasWeakConstant(node-&gt;op()))
-        result.m_info = bitwise_cast&lt;uintptr_t&gt;(node-&gt;weakConstant());
</del><ins>+    if (hasConstant(node-&gt;op()))
+        result.m_info = JSValue::encode(node-&gt;asJSValue());
</ins><span class="cx">     else {
</span><span class="cx">         ASSERT(node-&gt;op() == PhantomArguments);
</span><span class="cx">         result.m_info = 0;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGMinifiedNodeh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGMinifiedNode.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -42,7 +42,6 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case Int52Constant:
</span><span class="cx">     case DoubleConstant:
</span><del>-    case WeakJSConstant:
</del><span class="cx">     case PhantomArguments:
</span><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="lines">@@ -59,24 +58,13 @@
</span><span class="cx">     MinifiedID id() const { return m_id; }
</span><span class="cx">     NodeType op() const { return m_op; }
</span><span class="cx">     
</span><del>-    bool hasConstant() const { return hasConstantNumber() || hasWeakConstant(); }
</del><ins>+    bool hasConstant() const { return hasConstant(m_op); }
</ins><span class="cx">     
</span><del>-    bool hasConstantNumber() const { return hasConstantNumber(m_op); }
-    
-    unsigned constantNumber() const
</del><ins>+    JSValue constant() const
</ins><span class="cx">     {
</span><del>-        ASSERT(hasConstantNumber(m_op));
-        return m_info;
</del><ins>+        return JSValue::decode(bitwise_cast&lt;EncodedJSValue&gt;(m_info));
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool hasWeakConstant() const { return hasWeakConstant(m_op); }
-    
-    JSCell* weakConstant() const
-    {
-        ASSERT(hasWeakConstant(m_op));
-        return bitwise_cast&lt;JSCell*&gt;(m_info);
-    }
-    
</del><span class="cx">     static MinifiedID getID(MinifiedNode* node) { return node-&gt;id(); }
</span><span class="cx">     static bool compareByNodeIndex(const MinifiedNode&amp; a, const MinifiedNode&amp; b)
</span><span class="cx">     {
</span><span class="lines">@@ -84,17 +72,13 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    static bool hasConstantNumber(NodeType type)
</del><ins>+    static bool hasConstant(NodeType type)
</ins><span class="cx">     {
</span><span class="cx">         return type == JSConstant || type == Int52Constant || type == DoubleConstant;
</span><span class="cx">     }
</span><del>-    static bool hasWeakConstant(NodeType type)
-    {
-        return type == WeakJSConstant;
-    }
</del><span class="cx">     
</span><span class="cx">     MinifiedID m_id;
</span><del>-    uintptr_t m_info;
</del><ins>+    uint64_t m_info;
</ins><span class="cx">     NodeType m_op;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGNode.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGNode.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGNode.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -406,11 +406,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isWeakConstant()
-    {
-        return op() == WeakJSConstant;
-    }
-    
</del><span class="cx">     bool isPhantomArguments()
</span><span class="cx">     {
</span><span class="cx">         return op() == PhantomArguments;
</span><span class="lines">@@ -422,7 +417,6 @@
</span><span class="cx">         case JSConstant:
</span><span class="cx">         case DoubleConstant:
</span><span class="cx">         case Int52Constant:
</span><del>-        case WeakJSConstant:
</del><span class="cx">         case PhantomArguments:
</span><span class="cx">             return true;
</span><span class="cx">         default:
</span><span class="lines">@@ -430,13 +424,16 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned constantNumber()
</del><ins>+    FrozenValue* constant()
</ins><span class="cx">     {
</span><del>-        ASSERT(isConstant());
-        return m_opInfo;
</del><ins>+        ASSERT(hasConstant());
+        if (op() == PhantomArguments)
+            return FrozenValue::emptySingleton();
+        return bitwise_cast&lt;FrozenValue*&gt;(m_opInfo);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void convertToConstant(unsigned constantNumber)
</del><ins>+    // Don't call this directly - use Graph::convertToConstant() instead!
+    void convertToConstant(FrozenValue* value)
</ins><span class="cx">     {
</span><span class="cx">         if (hasDoubleResult())
</span><span class="cx">             m_op = DoubleConstant;
</span><span class="lines">@@ -445,18 +442,10 @@
</span><span class="cx">         else
</span><span class="cx">             m_op = JSConstant;
</span><span class="cx">         m_flags &amp;= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
</span><del>-        m_opInfo = constantNumber;
</del><ins>+        m_opInfo = bitwise_cast&lt;uintptr_t&gt;(value);
</ins><span class="cx">         children.reset();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void convertToWeakConstant(JSCell* cell)
-    {
-        m_op = WeakJSConstant;
-        m_flags &amp;= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
-        m_opInfo = bitwise_cast&lt;uintptr_t&gt;(cell);
-        children.reset();
-    }
-    
</del><span class="cx">     void convertToConstantStoragePointer(void* pointer)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(op() == GetIndexedPropertyStorage);
</span><span class="lines">@@ -518,54 +507,79 @@
</span><span class="cx">         m_op = ToString;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    JSCell* weakConstant()
</del><ins>+    JSValue asJSValue()
</ins><span class="cx">     {
</span><del>-        ASSERT(op() == WeakJSConstant);
-        return bitwise_cast&lt;JSCell*&gt;(m_opInfo);
</del><ins>+        return constant()-&gt;value();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    JSValue valueOfJSConstant(CodeBlock* codeBlock)
</del><ins>+    bool isInt32Constant()
</ins><span class="cx">     {
</span><del>-        switch (op()) {
-        case WeakJSConstant:
-            return JSValue(weakConstant());
-        case JSConstant:
-        case DoubleConstant:
-        case Int52Constant:
-            return codeBlock-&gt;constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
-        case PhantomArguments:
-            return JSValue();
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return JSValue(); // Have to return something in release mode.
-        }
</del><ins>+        return isConstant() &amp;&amp; constant()-&gt;value().isInt32();
</ins><span class="cx">     }
</span><del>-
-    bool isInt32Constant(CodeBlock* codeBlock)
</del><ins>+    
+    int32_t asInt32()
</ins><span class="cx">     {
</span><del>-        return isConstant() &amp;&amp; valueOfJSConstant(codeBlock).isInt32();
</del><ins>+        return asJSValue().asInt32();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isDoubleConstant(CodeBlock* codeBlock)
</del><ins>+    uint32_t asUInt32()
</ins><span class="cx">     {
</span><del>-        bool result = isConstant() &amp;&amp; valueOfJSConstant(codeBlock).isDouble();
-        if (result)
-            ASSERT(!isInt32Constant(codeBlock));
-        return result;
</del><ins>+        return asInt32();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isNumberConstant(CodeBlock* codeBlock)
</del><ins>+    bool isDoubleConstant()
</ins><span class="cx">     {
</span><del>-        bool result = isConstant() &amp;&amp; valueOfJSConstant(codeBlock).isNumber();
-        ASSERT(result == (isInt32Constant(codeBlock) || isDoubleConstant(codeBlock)));
-        return result;
</del><ins>+        return isConstant() &amp;&amp; constant()-&gt;value().isDouble();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isBooleanConstant(CodeBlock* codeBlock)
</del><ins>+    bool isNumberConstant()
</ins><span class="cx">     {
</span><del>-        return isConstant() &amp;&amp; valueOfJSConstant(codeBlock).isBoolean();
</del><ins>+        return isConstant() &amp;&amp; constant()-&gt;value().isNumber();
</ins><span class="cx">     }
</span><span class="cx">     
</span><ins>+    double asNumber()
+    {
+        return asJSValue().asNumber();
+    }
+    
+    bool isMachineIntConstant()
+    {
+        return isConstant() &amp;&amp; constant()-&gt;value().isMachineInt();
+    }
+    
+    int64_t asMachineInt()
+    {
+        return asJSValue().asMachineInt();
+    }
+    
+    bool isBooleanConstant()
+    {
+        return isConstant() &amp;&amp; constant()-&gt;value().isBoolean();
+    }
+    
+    bool asBoolean()
+    {
+        return constant()-&gt;value().asBoolean();
+    }
+    
+    bool isCellConstant()
+    {
+        return isConstant() &amp;&amp; constant()-&gt;value().isCell();
+    }
+    
+    JSCell* asCell()
+    {
+        return constant()-&gt;value().asCell();
+    }
+    
+    template&lt;typename T&gt;
+    T dynamicCastConstant()
+    {
+        if (!isCellConstant())
+            return nullptr;
+        return jsDynamicCast&lt;T&gt;(asCell());
+    }
+    
</ins><span class="cx">     bool containsMovHint()
</span><span class="cx">     {
</span><span class="cx">         switch (op()) {
</span><span class="lines">@@ -1050,12 +1064,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JSCell* function()
</del><ins>+    FrozenValue* function()
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(hasFunction());
</span><del>-        JSCell* result = reinterpret_cast&lt;JSFunction*&gt;(m_opInfo);
-        ASSERT(JSValue(result).isFunction());
-        return result;
</del><ins>+        return reinterpret_cast&lt;FrozenValue*&gt;(m_opInfo);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasExecutable()
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGNodeType.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -41,10 +41,6 @@
</span><span class="cx">     macro(DoubleConstant, NodeResultDouble | NodeDoesNotExit) \
</span><span class="cx">     macro(Int52Constant, NodeResultInt52 | NodeDoesNotExit) \
</span><span class="cx">     \
</span><del>-    /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
-    /* code block. */\
-    macro(WeakJSConstant, NodeResultJS | NodeDoesNotExit) \
-    \
</del><span class="cx">     /* Marker to indicate that an operation was optimized entirely and all that is left */\
</span><span class="cx">     /* is to make one node alias another. CSE will later usually eliminate this node, */\
</span><span class="cx">     /* though it may choose not to if it would corrupt predictions (very rare). */\
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx">             
</span><span class="cx">             Profiler::OSRExit* profilerExit = compilation-&gt;addOSRExit(
</span><span class="cx">                 exitIndex, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
</span><del>-                exit.m_kind, isWatchpoint(exit.m_kind));
</del><ins>+                exit.m_kind, exit.m_kind == UncountableInvalidation);
</ins><span class="cx">             jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit-&gt;counterAddress()));
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -135,9 +135,8 @@
</span><span class="cx">         bool changed = false;
</span><span class="cx">         
</span><span class="cx">         switch (op) {
</span><del>-        case JSConstant:
-        case WeakJSConstant: {
-            SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node));
</del><ins>+        case JSConstant: {
+            SpeculatedType type = speculationFromValue(node-&gt;asJSValue());
</ins><span class="cx">             if (type == SpecInt52AsDouble &amp;&amp; enableInt52())
</span><span class="cx">                 type = SpecInt52;
</span><span class="cx">             changed |= setPrediction(type);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -109,7 +109,6 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><del>-    case WeakJSConstant:
</del><span class="cx">     case Identity:
</span><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -320,7 +320,7 @@
</span><span class="cx">         ASSERT(info.gpr() == source);
</span><span class="cx">         ASSERT(isJSInt32(info.registerFormat()));
</span><span class="cx">         if (node-&gt;hasConstant()) {
</span><del>-            ASSERT(isInt32Constant(node));
</del><ins>+            ASSERT(node-&gt;isInt32Constant());
</ins><span class="cx">             fillAction = SetInt32Constant;
</span><span class="cx">         } else
</span><span class="cx">             fillAction = Load32Payload;
</span><span class="lines">@@ -339,8 +339,7 @@
</span><span class="cx">     } else if (registerFormat == DataFormatCell) {
</span><span class="cx">         ASSERT(info.gpr() == source);
</span><span class="cx">         if (node-&gt;hasConstant()) {
</span><del>-            JSValue value = valueOfJSConstant(node);
-            ASSERT_UNUSED(value, value.isCell());
</del><ins>+            node-&gt;asCell(); // To get the assertion.
</ins><span class="cx">             fillAction = SetCellConstant;
</span><span class="cx">         } else {
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="lines">@@ -383,8 +382,9 @@
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">         ASSERT(info.gpr() == source);
</span><span class="cx">         if (node-&gt;hasConstant()) {
</span><del>-            if (valueOfJSConstant(node).isCell())
</del><ins>+            if (node-&gt;isCellConstant())
</ins><span class="cx">                 fillAction = SetTrustedJSConstant;
</span><ins>+            else
</ins><span class="cx">                 fillAction = SetJSConstant;
</span><span class="cx">         } else if (info.spillFormat() == DataFormatInt32) {
</span><span class="cx">             ASSERT(registerFormat == DataFormatJSInt32);
</span><span class="lines">@@ -442,7 +442,7 @@
</span><span class="cx">         
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     if (node-&gt;hasConstant()) {
</span><del>-        ASSERT(isNumberConstant(node));
</del><ins>+        node-&gt;asNumber(); // To get the assertion.
</ins><span class="cx">         fillAction = SetDoubleConstant;
</span><span class="cx">     } else {
</span><span class="cx">         ASSERT(info.spillFormat() == DataFormatNone || info.spillFormat() == DataFormatDouble);
</span><span class="lines">@@ -451,7 +451,7 @@
</span><span class="cx"> #elif USE(JSVALUE32_64)
</span><span class="cx">     ASSERT(info.registerFormat() == DataFormatDouble);
</span><span class="cx">     if (node-&gt;hasConstant()) {
</span><del>-        ASSERT(isNumberConstant(node));
</del><ins>+        node-&gt;asNumber(); // To get the assertion.
</ins><span class="cx">         fillAction = SetDoubleConstant;
</span><span class="cx">     } else
</span><span class="cx">         fillAction = LoadDouble;
</span><span class="lines">@@ -496,21 +496,21 @@
</span><span class="cx">     case DoNothingForFill:
</span><span class="cx">         break;
</span><span class="cx">     case SetInt32Constant:
</span><del>-        m_jit.move(Imm32(valueOfInt32Constant(plan.node())), plan.gpr());
</del><ins>+        m_jit.move(Imm32(plan.node()-&gt;asInt32()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     case SetInt52Constant:
</span><del>-        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt() &lt;&lt; JSValue::int52ShiftAmount), plan.gpr());
</del><ins>+        m_jit.move(Imm64(plan.node()-&gt;asMachineInt() &lt;&lt; JSValue::int52ShiftAmount), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx">     case SetStrictInt52Constant:
</span><del>-        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt()), plan.gpr());
</del><ins>+        m_jit.move(Imm64(plan.node()-&gt;asMachineInt()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx"> #endif // USE(JSVALUE64)
</span><span class="cx">     case SetBooleanConstant:
</span><del>-        m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.node())), plan.gpr());
</del><ins>+        m_jit.move(TrustedImm32(plan.node()-&gt;asBoolean()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx">     case SetCellConstant:
</span><del>-        m_jit.move(TrustedImmPtr(valueOfJSConstant(plan.node()).asCell()), plan.gpr());
</del><ins>+        m_jit.move(TrustedImmPtr(plan.node()-&gt;asCell()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     case SetTrustedJSConstant:
</span><span class="lines">@@ -520,7 +520,7 @@
</span><span class="cx">         m_jit.move(valueOfJSConstantAsImm64(plan.node()), plan.gpr());
</span><span class="cx">         break;
</span><span class="cx">     case SetDoubleConstant:
</span><del>-        m_jit.move(Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(plan.node()))), canTrample);
</del><ins>+        m_jit.move(Imm64(reinterpretDoubleToInt64(plan.node()-&gt;asNumber())), canTrample);
</ins><span class="cx">         m_jit.move64ToDouble(canTrample, plan.fpr());
</span><span class="cx">         break;
</span><span class="cx">     case Load32PayloadBoxInt:
</span><span class="lines">@@ -538,10 +538,10 @@
</span><span class="cx">         break;
</span><span class="cx"> #else
</span><span class="cx">     case SetJSConstantTag:
</span><del>-        m_jit.move(Imm32(valueOfJSConstant(plan.node()).tag()), plan.gpr());
</del><ins>+        m_jit.move(Imm32(plan.node()-&gt;asJSValue().tag()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx">     case SetJSConstantPayload:
</span><del>-        m_jit.move(Imm32(valueOfJSConstant(plan.node()).payload()), plan.gpr());
</del><ins>+        m_jit.move(Imm32(plan.node()-&gt;asJSValue().payload()), plan.gpr());
</ins><span class="cx">         break;
</span><span class="cx">     case SetInt32Tag:
</span><span class="cx">         m_jit.move(TrustedImm32(JSValue::Int32Tag), plan.gpr());
</span><span class="lines">@@ -553,7 +553,7 @@
</span><span class="cx">         m_jit.move(TrustedImm32(JSValue::BooleanTag), plan.gpr());
</span><span class="cx">         break;
</span><span class="cx">     case SetDoubleConstant:
</span><del>-        m_jit.loadDouble(addressOfDoubleConstant(plan.node()), plan.fpr());
</del><ins>+        m_jit.loadDouble(m_jit.addressOfDoubleConstant(plan.node()), plan.fpr());
</ins><span class="cx">         break;
</span><span class="cx"> #endif
</span><span class="cx">     case Load32Tag:
</span><span class="lines">@@ -855,12 +855,9 @@
</span><span class="cx"> {
</span><span class="cx">     SpeculateCellOperand base(this, node-&gt;child2());
</span><span class="cx">     GPRReg baseGPR = base.gpr();
</span><del>-        
-    if (isConstant(node-&gt;child1().node())) {
-        JSString* string =
-            jsDynamicCast&lt;JSString*&gt;(valueOfJSConstant(node-&gt;child1().node()));
-        if (string &amp;&amp; string-&gt;tryGetValueImpl()
-            &amp;&amp; string-&gt;tryGetValueImpl()-&gt;isAtomic()) {
</del><ins>+    
+    if (JSString* string = node-&gt;child1()-&gt;dynamicCastConstant&lt;JSString*&gt;()) {
+        if (string-&gt;tryGetValueImpl() &amp;&amp; string-&gt;tryGetValueImpl()-&gt;isAtomic()) {
</ins><span class="cx">             StructureStubInfo* stubInfo = m_jit.codeBlock()-&gt;addStubInfo();
</span><span class="cx">             
</span><span class="cx">             GPRTemporary result(this);
</span><span class="lines">@@ -1218,13 +1215,13 @@
</span><span class="cx">         notTaken = tmp;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (isBooleanConstant(node-&gt;child1().node())) {
-        bool imm = valueOfBooleanConstant(node-&gt;child1().node());
</del><ins>+    if (node-&gt;child1()-&gt;isBooleanConstant()) {
+        bool imm = node-&gt;child1()-&gt;asBoolean();
</ins><span class="cx">         SpeculateBooleanOperand op2(this, node-&gt;child2());
</span><span class="cx">         branch32(condition, JITCompiler::Imm32(static_cast&lt;int32_t&gt;(JSValue::encode(jsBoolean(imm)))), op2.gpr(), taken);
</span><del>-    } else if (isBooleanConstant(node-&gt;child2().node())) {
</del><ins>+    } else if (node-&gt;child2()-&gt;isBooleanConstant()) {
</ins><span class="cx">         SpeculateBooleanOperand op1(this, node-&gt;child1());
</span><del>-        bool imm = valueOfBooleanConstant(node-&gt;child2().node());
</del><ins>+        bool imm = node-&gt;child2()-&gt;asBoolean();
</ins><span class="cx">         branch32(condition, op1.gpr(), JITCompiler::Imm32(static_cast&lt;int32_t&gt;(JSValue::encode(jsBoolean(imm)))), taken);
</span><span class="cx">     } else {
</span><span class="cx">         SpeculateBooleanOperand op1(this, node-&gt;child1());
</span><span class="lines">@@ -1249,13 +1246,13 @@
</span><span class="cx">         notTaken = tmp;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (isInt32Constant(node-&gt;child1().node())) {
-        int32_t imm = valueOfInt32Constant(node-&gt;child1().node());
</del><ins>+    if (node-&gt;child1()-&gt;isInt32Constant()) {
+        int32_t imm = node-&gt;child1()-&gt;asInt32();
</ins><span class="cx">         SpeculateInt32Operand op2(this, node-&gt;child2());
</span><span class="cx">         branch32(condition, JITCompiler::Imm32(imm), op2.gpr(), taken);
</span><del>-    } else if (isInt32Constant(node-&gt;child2().node())) {
</del><ins>+    } else if (node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">         SpeculateInt32Operand op1(this, node-&gt;child1());
</span><del>-        int32_t imm = valueOfInt32Constant(node-&gt;child2().node());
</del><ins>+        int32_t imm = node-&gt;child2()-&gt;asInt32();
</ins><span class="cx">         branch32(condition, op1.gpr(), JITCompiler::Imm32(imm), taken);
</span><span class="cx">     } else {
</span><span class="cx">         SpeculateInt32Operand op1(this, node-&gt;child1());
</span><span class="lines">@@ -1415,11 +1412,6 @@
</span><span class="cx">                 m_minifiedGraph-&gt;append(MinifiedNode::fromNode(m_currentNode));
</span><span class="cx">                 break;
</span><span class="cx">                 
</span><del>-            case WeakJSConstant:
-                m_jit.addWeakReference(m_currentNode-&gt;weakConstant());
-                m_minifiedGraph-&gt;append(MinifiedNode::fromNode(m_currentNode));
-                break;
-                
</del><span class="cx">             case SetLocal:
</span><span class="cx">                 RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">                 break;
</span><span class="lines">@@ -2088,7 +2080,7 @@
</span><span class="cx"> {
</span><span class="cx">     switch (node-&gt;child1().useKind()) {
</span><span class="cx">     case NumberUse: {
</span><del>-        ASSERT(!isNumberConstant(node-&gt;child1().node())); // This should have been constant folded.
</del><ins>+        ASSERT(!node-&gt;child1()-&gt;isNumberConstant()); // This should have been constant folded.
</ins><span class="cx">     
</span><span class="cx">         if (isInt32Speculation(m_state.forNode(node-&gt;child1()).m_type)) {
</span><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1(), ManualOperandSpeculation);
</span><span class="lines">@@ -2285,7 +2277,7 @@
</span><span class="cx">     if (JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node)) {
</span><span class="cx">         uint32_t length = view-&gt;length();
</span><span class="cx">         Node* indexNode = m_jit.graph().child(node, 1).node();
</span><del>-        if (m_jit.graph().isInt32Constant(indexNode) &amp;&amp; static_cast&lt;uint32_t&gt;(m_jit.graph().valueOfInt32Constant(indexNode)) &lt; length)
</del><ins>+        if (indexNode-&gt;isInt32Constant() &amp;&amp; indexNode-&gt;asUInt32() &lt; length)
</ins><span class="cx">             return JITCompiler::Jump();
</span><span class="cx">         return m_jit.branch32(
</span><span class="cx">             MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Imm32(length));
</span><span class="lines">@@ -2381,7 +2373,7 @@
</span><span class="cx">     GPRReg valueGPR = InvalidGPRReg;
</span><span class="cx">     
</span><span class="cx">     if (valueUse-&gt;isConstant()) {
</span><del>-        JSValue jsValue = valueOfJSConstant(valueUse.node());
</del><ins>+        JSValue jsValue = valueUse-&gt;asJSValue();
</ins><span class="cx">         if (!jsValue.isNumber()) {
</span><span class="cx">             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
</span><span class="cx">             noResult(node);
</span><span class="lines">@@ -2669,8 +2661,8 @@
</span><span class="cx">     case Int32Use: {
</span><span class="cx">         ASSERT(!shouldCheckNegativeZero(node-&gt;arithMode()));
</span><span class="cx">         
</span><del>-        if (isInt32Constant(node-&gt;child1().node())) {
-            int32_t imm1 = valueOfInt32Constant(node-&gt;child1().node());
</del><ins>+        if (node-&gt;child1()-&gt;isInt32Constant()) {
+            int32_t imm1 = node-&gt;child1()-&gt;asInt32();
</ins><span class="cx">             SpeculateInt32Operand op2(this, node-&gt;child2());
</span><span class="cx">             GPRTemporary result(this);
</span><span class="cx"> 
</span><span class="lines">@@ -2684,9 +2676,9 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (isInt32Constant(node-&gt;child2().node())) {
</del><ins>+        if (node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1());
</span><del>-            int32_t imm2 = valueOfInt32Constant(node-&gt;child2().node());
</del><ins>+            int32_t imm2 = node-&gt;child2()-&gt;asInt32();
</ins><span class="cx">             GPRTemporary result(this);
</span><span class="cx">                 
</span><span class="cx">             if (!shouldCheckOverflow(node-&gt;arithMode())) {
</span><span class="lines">@@ -2865,9 +2857,9 @@
</span><span class="cx">     case Int32Use: {
</span><span class="cx">         ASSERT(!shouldCheckNegativeZero(node-&gt;arithMode()));
</span><span class="cx">         
</span><del>-        if (isNumberConstant(node-&gt;child2().node())) {
</del><ins>+        if (node-&gt;child2()-&gt;isNumberConstant()) {
</ins><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1());
</span><del>-            int32_t imm2 = valueOfInt32Constant(node-&gt;child2().node());
</del><ins>+            int32_t imm2 = node-&gt;child2()-&gt;asInt32();
</ins><span class="cx">             GPRTemporary result(this);
</span><span class="cx"> 
</span><span class="cx">             if (!shouldCheckOverflow(node-&gt;arithMode())) {
</span><span class="lines">@@ -2882,8 +2874,8 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">             
</span><del>-        if (isNumberConstant(node-&gt;child1().node())) {
-            int32_t imm1 = valueOfInt32Constant(node-&gt;child1().node());
</del><ins>+        if (node-&gt;child1()-&gt;isNumberConstant()) {
+            int32_t imm1 = node-&gt;child1()-&gt;asInt32();
</ins><span class="cx">             SpeculateInt32Operand op2(this, node-&gt;child2());
</span><span class="cx">             GPRTemporary result(this);
</span><span class="cx">                 
</span><span class="lines">@@ -3322,8 +3314,8 @@
</span><span class="cx">         // (in case of |dividend| &lt; |divisor|), so we speculate it as strict int32.
</span><span class="cx">         SpeculateStrictInt32Operand op1(this, node-&gt;child1());
</span><span class="cx">         
</span><del>-        if (isInt32Constant(node-&gt;child2().node())) {
-            int32_t divisor = valueOfInt32Constant(node-&gt;child2().node());
</del><ins>+        if (node-&gt;child2()-&gt;isInt32Constant()) {
+            int32_t divisor = node-&gt;child2()-&gt;asInt32();
</ins><span class="cx">             if (divisor &gt; 1 &amp;&amp; hasOneBitSet(divisor)) {
</span><span class="cx">                 unsigned logarithm = WTF::fastLog2(divisor);
</span><span class="cx">                 GPRReg dividendGPR = op1.gpr();
</span><span class="lines">@@ -3384,8 +3376,8 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx"> #if CPU(X86) || CPU(X86_64)
</span><del>-        if (isInt32Constant(node-&gt;child2().node())) {
-            int32_t divisor = valueOfInt32Constant(node-&gt;child2().node());
</del><ins>+        if (node-&gt;child2()-&gt;isInt32Constant()) {
+            int32_t divisor = node-&gt;child2()-&gt;asInt32();
</ins><span class="cx">             if (divisor &amp;&amp; divisor != -1) {
</span><span class="cx">                 GPRReg op1Gpr = op1.gpr();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -556,29 +556,6 @@
</span><span class="cx">     bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type &amp; SpecFullNumber); }
</span><span class="cx">     bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type &amp; SpecCell); }
</span><span class="cx">     
</span><del>-    // Checks/accessors for constant values.
-    bool isConstant(Node* node) { return m_jit.graph().isConstant(node); }
-    bool isJSConstant(Node* node) { return m_jit.graph().isJSConstant(node); }
-    bool isInt32Constant(Node* node) { return m_jit.graph().isInt32Constant(node); }
-    bool isDoubleConstant(Node* node) { return m_jit.graph().isDoubleConstant(node); }
-    bool isNumberConstant(Node* node) { return m_jit.graph().isNumberConstant(node); }
-    bool isBooleanConstant(Node* node) { return m_jit.graph().isBooleanConstant(node); }
-    bool isFunctionConstant(Node* node) { return m_jit.graph().isFunctionConstant(node); }
-    int32_t valueOfInt32Constant(Node* node) { return m_jit.graph().valueOfInt32Constant(node); }
-    double valueOfNumberConstant(Node* node) { return m_jit.graph().valueOfNumberConstant(node); }
-#if USE(JSVALUE32_64)
-    void* addressOfDoubleConstant(Node* node) { return m_jit.addressOfDoubleConstant(node); }
-#endif
-    JSValue valueOfJSConstant(Node* node) { return m_jit.graph().valueOfJSConstant(node); }
-    bool valueOfBooleanConstant(Node* node) { return m_jit.graph().valueOfBooleanConstant(node); }
-    JSFunction* valueOfFunctionConstant(Node* node) { return m_jit.graph().valueOfFunctionConstant(node); }
-    bool isNullConstant(Node* node)
-    {
-        if (!isConstant(node))
-            return false;
-        return valueOfJSConstant(node).isNull();
-    }
-
</del><span class="cx">     StringImpl* identifierUID(unsigned index)
</span><span class="cx">     {
</span><span class="cx">         return m_jit.graph().identifiers()[index];
</span><span class="lines">@@ -619,9 +596,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-    MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
</del><ins>+    static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
</ins><span class="cx">     {
</span><del>-        return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(node)));
</del><ins>+        return MacroAssembler::Imm64(JSValue::encode(node-&gt;asJSValue()));
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -957,7 +934,7 @@
</span><span class="cx">     }
</span><span class="cx">     void initConstantInfo(Node* node)
</span><span class="cx">     {
</span><del>-        ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node));
</del><ins>+        ASSERT(node-&gt;hasConstant());
</ins><span class="cx">         generationInfo(node).initConstant(node, node-&gt;refCount());
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1983,17 +1960,6 @@
</span><span class="cx"> 
</span><span class="cx">     void dump(const char* label = 0);
</span><span class="cx"> 
</span><del>-    bool isInteger(Node* node)
-    {
-        if (node-&gt;hasInt32Result())
-            return true;
-
-        if (isInt32Constant(node))
-            return true;
-
-        return generationInfo(node).isJSInt32();
-    }
-    
</del><span class="cx">     bool betterUseStrictInt52(Node* node)
</span><span class="cx">     {
</span><span class="cx">         return !generationInfo(node).isInt52();
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -58,11 +58,12 @@
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><span class="cx">             tagGPR = allocate();
</span><span class="cx">             payloadGPR = allocate();
</span><del>-            m_jit.move(Imm32(valueOfJSConstant(edge.node()).tag()), tagGPR);
-            m_jit.move(Imm32(valueOfJSConstant(edge.node()).payload()), payloadGPR);
</del><ins>+            JSValue value = edge-&gt;asJSValue();
+            m_jit.move(Imm32(value.tag()), tagGPR);
+            m_jit.move(Imm32(value.payload()), payloadGPR);
</ins><span class="cx">             m_gprs.retain(tagGPR, virtualRegister, SpillOrderConstant);
</span><span class="cx">             m_gprs.retain(payloadGPR, virtualRegister, SpillOrderConstant);
</span><del>-            info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(edge.node()) ? DataFormatJSInt32 : DataFormatJS);
</del><ins>+            info.fillJSValue(*m_stream, tagGPR, payloadGPR, DataFormatJS);
</ins><span class="cx">         } else {
</span><span class="cx">             DataFormat spillFormat = info.spillFormat();
</span><span class="cx">             ASSERT(spillFormat != DataFormatNone &amp;&amp; spillFormat != DataFormatStorage);
</span><span class="lines">@@ -736,7 +737,7 @@
</span><span class="cx">     VirtualRegister virtualRegister = edge-&gt;virtualRegister();
</span><span class="cx">     GenerationInfo&amp; info = generationInfoFromVirtualRegister(virtualRegister);
</span><span class="cx"> 
</span><del>-    if (edge-&gt;hasConstant() &amp;&amp; !isInt32Constant(edge.node())) {
</del><ins>+    if (edge-&gt;hasConstant() &amp;&amp; !edge-&gt;isInt32Constant()) {
</ins><span class="cx">         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
</span><span class="cx">         returnFormat = DataFormatInt32;
</span><span class="cx">         return allocate();
</span><span class="lines">@@ -745,9 +746,9 @@
</span><span class="cx">     switch (info.registerFormat()) {
</span><span class="cx">     case DataFormatNone: {
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            ASSERT(isInt32Constant(edge.node()));
</del><ins>+            ASSERT(edge-&gt;isInt32Constant());
</ins><span class="cx">             GPRReg gpr = allocate();
</span><del>-            m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
</del><ins>+            m_jit.move(MacroAssembler::Imm32(edge-&gt;asInt32()), gpr);
</ins><span class="cx">             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="cx">             info.fillInt32(*m_stream, gpr);
</span><span class="cx">             returnFormat = DataFormatInt32;
</span><span class="lines">@@ -835,9 +836,9 @@
</span><span class="cx">     if (info.registerFormat() == DataFormatNone) {
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            RELEASE_ASSERT(isNumberConstant(edge.node()));
</del><ins>+            RELEASE_ASSERT(edge-&gt;isNumberConstant());
</ins><span class="cx">             FPRReg fpr = fprAllocate();
</span><del>-            m_jit.loadDouble(addressOfDoubleConstant(edge.node()), fpr);
</del><ins>+            m_jit.loadDouble(m_jit.addressOfDoubleConstant(edge.node()), fpr);
</ins><span class="cx">             m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
</span><span class="cx">             info.fillDouble(*m_stream, fpr);
</span><span class="cx">             return fpr;
</span><span class="lines">@@ -874,7 +875,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue jsValue = valueOfJSConstant(edge.node());
</del><ins>+            JSValue jsValue = edge-&gt;asJSValue();
</ins><span class="cx">             GPRReg gpr = allocate();
</span><span class="cx">             if (jsValue.isCell()) {
</span><span class="cx">                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="lines">@@ -963,7 +964,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue jsValue = valueOfJSConstant(edge.node());
</del><ins>+            JSValue jsValue = edge-&gt;asJSValue();
</ins><span class="cx">             GPRReg gpr = allocate();
</span><span class="cx">             if (jsValue.isBoolean()) {
</span><span class="cx">                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="lines">@@ -1683,11 +1684,6 @@
</span><span class="cx">         initConstantInfo(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case WeakJSConstant:
-        m_jit.addWeakReference(node-&gt;weakConstant());
-        initConstantInfo(node);
-        break;
-
</del><span class="cx">     case Identity: {
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         break;
</span><span class="lines">@@ -1856,18 +1852,18 @@
</span><span class="cx">     case BitAnd:
</span><span class="cx">     case BitOr:
</span><span class="cx">     case BitXor:
</span><del>-        if (isInt32Constant(node-&gt;child1().node())) {
</del><ins>+        if (node-&gt;child1()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op2(this, node-&gt;child2());
</span><span class="cx">             GPRTemporary result(this, Reuse, op2);
</span><span class="cx"> 
</span><del>-            bitOp(op, valueOfInt32Constant(node-&gt;child1().node()), op2.gpr(), result.gpr());
</del><ins>+            bitOp(op, node-&gt;child1()-&gt;asInt32(), op2.gpr(), result.gpr());
</ins><span class="cx"> 
</span><span class="cx">             int32Result(result.gpr(), node);
</span><del>-        } else if (isInt32Constant(node-&gt;child2().node())) {
</del><ins>+        } else if (node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1());
</span><span class="cx">             GPRTemporary result(this, Reuse, op1);
</span><span class="cx"> 
</span><del>-            bitOp(op, valueOfInt32Constant(node-&gt;child2().node()), op1.gpr(), result.gpr());
</del><ins>+            bitOp(op, node-&gt;child2()-&gt;asInt32(), op1.gpr(), result.gpr());
</ins><span class="cx"> 
</span><span class="cx">             int32Result(result.gpr(), node);
</span><span class="cx">         } else {
</span><span class="lines">@@ -1886,11 +1882,11 @@
</span><span class="cx">     case BitRShift:
</span><span class="cx">     case BitLShift:
</span><span class="cx">     case BitURShift:
</span><del>-        if (isInt32Constant(node-&gt;child2().node())) {
</del><ins>+        if (node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1());
</span><span class="cx">             GPRTemporary result(this, Reuse, op1);
</span><span class="cx"> 
</span><del>-            shiftOp(op, op1.gpr(), valueOfInt32Constant(node-&gt;child2().node()) &amp; 0x1f, result.gpr());
</del><ins>+            shiftOp(op, op1.gpr(), node-&gt;child2()-&gt;asInt32() &amp; 0x1f, result.gpr());
</ins><span class="cx"> 
</span><span class="cx">             int32Result(result.gpr(), node);
</span><span class="cx">         } else {
</span><span class="lines">@@ -2158,7 +2154,7 @@
</span><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case CompareEqConstant:
</span><del>-        ASSERT(isNullConstant(node-&gt;child2().node()));
</del><ins>+        ASSERT(node-&gt;child2()-&gt;asJSValue().isNull());
</ins><span class="cx">         if (nonSpeculativeCompareNull(node, node-&gt;child1()))
</span><span class="cx">             return;
</span><span class="cx">         break;
</span><span class="lines">@@ -3651,7 +3647,7 @@
</span><span class="cx">         
</span><span class="cx">     case CheckFunction: {
</span><span class="cx">         SpeculateCellOperand function(this, node-&gt;child1());
</span><del>-        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node-&gt;function()));
</del><ins>+        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node-&gt;function()-&gt;value().asCell()));
</ins><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -80,21 +80,9 @@
</span><span class="cx">         GPRReg gpr = allocate();
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            if (isInt32Constant(edge.node())) {
-                info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
-                JSValue jsValue = jsNumber(valueOfInt32Constant(edge.node()));
-                m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
-            } else if (isNumberConstant(edge.node())) {
-                info.fillJSValue(*m_stream, gpr, DataFormatJSDouble);
-                JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(edge.node()));
-                m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
-            } else {
-                ASSERT(isJSConstant(edge.node()));
-                JSValue jsValue = valueOfJSConstant(edge.node());
-                m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
-                info.fillJSValue(*m_stream, gpr, DataFormatJS);
-            }
-
</del><ins>+            JSValue jsValue = edge-&gt;asJSValue();
+            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
+            info.fillJSValue(*m_stream, gpr, DataFormatJS);
</ins><span class="cx">             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="cx">         } else {
</span><span class="cx">             DataFormat spillFormat = info.spillFormat();
</span><span class="lines">@@ -726,7 +714,7 @@
</span><span class="cx">     VirtualRegister virtualRegister = edge-&gt;virtualRegister();
</span><span class="cx">     GenerationInfo&amp; info = generationInfoFromVirtualRegister(virtualRegister);
</span><span class="cx"> 
</span><del>-    if (edge-&gt;hasConstant() &amp;&amp; !isInt32Constant(edge.node())) {
</del><ins>+    if (edge-&gt;hasConstant() &amp;&amp; !edge-&gt;isInt32Constant()) {
</ins><span class="cx">         // Protect the silent spill/fill logic by failing early. If we &quot;speculate&quot; on
</span><span class="cx">         // the constant then the silent filler may think that we have an int32 and a
</span><span class="cx">         // constant, so it will try to fill this as an int32 constant. Bad things will
</span><span class="lines">@@ -742,8 +730,8 @@
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><span class="cx">             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><del>-            ASSERT(isInt32Constant(edge.node()));
-            m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
</del><ins>+            ASSERT(edge-&gt;isInt32Constant());
+            m_jit.move(MacroAssembler::Imm32(edge-&gt;asInt32()), gpr);
</ins><span class="cx">             info.fillInt32(*m_stream, gpr);
</span><span class="cx">             returnFormat = DataFormatInt32;
</span><span class="cx">             return gpr;
</span><span class="lines">@@ -878,7 +866,7 @@
</span><span class="cx"> 
</span><span class="cx">     switch (info.registerFormat()) {
</span><span class="cx">     case DataFormatNone: {
</span><del>-        if ((edge-&gt;hasConstant() &amp;&amp; !valueOfJSConstant(edge.node()).isMachineInt())) {
</del><ins>+        if (edge-&gt;hasConstant() &amp;&amp; !edge-&gt;isMachineIntConstant()) {
</ins><span class="cx">             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
</span><span class="cx">             return allocate();
</span><span class="cx">         }
</span><span class="lines">@@ -886,7 +874,7 @@
</span><span class="cx">         GPRReg gpr = allocate();
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue jsValue = valueOfJSConstant(edge.node());
</del><ins>+            JSValue jsValue = edge-&gt;asJSValue();
</ins><span class="cx">             ASSERT(jsValue.isMachineInt());
</span><span class="cx">             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="cx">             int64_t value = jsValue.asMachineInt();
</span><span class="lines">@@ -967,9 +955,9 @@
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><span class="cx">             GPRReg gpr = allocate();
</span><span class="cx"> 
</span><del>-            if (isNumberConstant(edge.node())) {
</del><ins>+            if (edge-&gt;isNumberConstant()) {
</ins><span class="cx">                 FPRReg fpr = fprAllocate();
</span><del>-                m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(edge.node()))), gpr);
</del><ins>+                m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(edge-&gt;asNumber())), gpr);
</ins><span class="cx">                 m_jit.move64ToDouble(gpr, fpr);
</span><span class="cx">                 unlock(gpr);
</span><span class="cx"> 
</span><span class="lines">@@ -1010,7 +998,7 @@
</span><span class="cx">         GPRReg gpr = allocate();
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue jsValue = valueOfJSConstant(edge.node());
</del><ins>+            JSValue jsValue = edge-&gt;asJSValue();
</ins><span class="cx">             if (jsValue.isCell()) {
</span><span class="cx">                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="cx">                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
</span><span class="lines">@@ -1091,7 +1079,7 @@
</span><span class="cx">         GPRReg gpr = allocate();
</span><span class="cx"> 
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue jsValue = valueOfJSConstant(edge.node());
</del><ins>+            JSValue jsValue = edge-&gt;asJSValue();
</ins><span class="cx">             if (jsValue.isBoolean()) {
</span><span class="cx">                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
</span><span class="cx">                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
</span><span class="lines">@@ -1791,11 +1779,6 @@
</span><span class="cx">         initConstantInfo(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case WeakJSConstant:
-        m_jit.addWeakReference(node-&gt;weakConstant());
-        initConstantInfo(node);
-        break;
-        
</del><span class="cx">     case Identity: {
</span><span class="cx">         // CSE should always eliminate this.
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -1959,18 +1942,18 @@
</span><span class="cx">     case BitAnd:
</span><span class="cx">     case BitOr:
</span><span class="cx">     case BitXor:
</span><del>-        if (isInt32Constant(node-&gt;child1().node())) {
</del><ins>+        if (node-&gt;child1()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op2(this, node-&gt;child2());
</span><span class="cx">             GPRTemporary result(this, Reuse, op2);
</span><span class="cx"> 
</span><del>-            bitOp(op, valueOfInt32Constant(node-&gt;child1().node()), op2.gpr(), result.gpr());
</del><ins>+            bitOp(op, node-&gt;child1()-&gt;asInt32(), op2.gpr(), result.gpr());
</ins><span class="cx"> 
</span><span class="cx">             int32Result(result.gpr(), node);
</span><del>-        } else if (isInt32Constant(node-&gt;child2().node())) {
</del><ins>+        } else if (node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1());
</span><span class="cx">             GPRTemporary result(this, Reuse, op1);
</span><span class="cx"> 
</span><del>-            bitOp(op, valueOfInt32Constant(node-&gt;child2().node()), op1.gpr(), result.gpr());
</del><ins>+            bitOp(op, node-&gt;child2()-&gt;asInt32(), op1.gpr(), result.gpr());
</ins><span class="cx"> 
</span><span class="cx">             int32Result(result.gpr(), node);
</span><span class="cx">         } else {
</span><span class="lines">@@ -1989,11 +1972,11 @@
</span><span class="cx">     case BitRShift:
</span><span class="cx">     case BitLShift:
</span><span class="cx">     case BitURShift:
</span><del>-        if (isInt32Constant(node-&gt;child2().node())) {
</del><ins>+        if (node-&gt;child2()-&gt;isInt32Constant()) {
</ins><span class="cx">             SpeculateInt32Operand op1(this, node-&gt;child1());
</span><span class="cx">             GPRTemporary result(this, Reuse, op1);
</span><span class="cx"> 
</span><del>-            shiftOp(op, op1.gpr(), valueOfInt32Constant(node-&gt;child2().node()) &amp; 0x1f, result.gpr());
</del><ins>+            shiftOp(op, op1.gpr(), node-&gt;child2()-&gt;asInt32() &amp; 0x1f, result.gpr());
</ins><span class="cx"> 
</span><span class="cx">             int32Result(result.gpr(), node);
</span><span class="cx">         } else {
</span><span class="lines">@@ -2263,7 +2246,7 @@
</span><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case CompareEqConstant:
</span><del>-        ASSERT(isNullConstant(node-&gt;child2().node()));
</del><ins>+        ASSERT(node-&gt;child2()-&gt;asJSValue().isNull());
</ins><span class="cx">         if (nonSpeculativeCompareNull(node, node-&gt;child1()))
</span><span class="cx">             return;
</span><span class="cx">         break;
</span><span class="lines">@@ -3719,7 +3702,7 @@
</span><span class="cx">         
</span><span class="cx">     case CheckFunction: {
</span><span class="cx">         SpeculateCellOperand function(this, node-&gt;child1());
</span><del>-        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node-&gt;function()));
</del><ins>+        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node-&gt;function()-&gt;value().asCell()));
</ins><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -3737,8 +3720,8 @@
</span><span class="cx">         ASSERT(node-&gt;structureSet().size());
</span><span class="cx">         
</span><span class="cx">         ExitKind exitKind;
</span><del>-        if (node-&gt;child1()-&gt;op() == WeakJSConstant)
-            exitKind = BadWeakConstantCache;
</del><ins>+        if (node-&gt;child1()-&gt;hasConstant())
+            exitKind = BadConstantCache;
</ins><span class="cx">         else
</span><span class="cx">             exitKind = BadCache;
</span><span class="cx">         
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -72,12 +72,9 @@
</span><span class="cx">         case BitOr:
</span><span class="cx">             handleCommutativity();
</span><span class="cx"> 
</span><del>-            if (m_node-&gt;child2()-&gt;isConstant()) {
-                JSValue op2 = m_graph.valueOfJSConstant(m_node-&gt;child2().node());
-                if (op2.isInt32() &amp;&amp; !op2.asInt32()) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
</del><ins>+            if (m_node-&gt;child2()-&gt;isInt32Constant() &amp;&amp; !m_node-&gt;child2()-&gt;asInt32()) {
+                convertToIdentityOverChild1();
+                break;
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="lines">@@ -89,38 +86,28 @@
</span><span class="cx">         case BitLShift:
</span><span class="cx">         case BitRShift:
</span><span class="cx">         case BitURShift:
</span><del>-            if (m_node-&gt;child2()-&gt;isConstant()) {
-                JSValue op2 = m_graph.valueOfJSConstant(m_node-&gt;child2().node());
-                if (op2.isInt32() &amp;&amp; !(op2.asInt32() &amp; 0x1f)) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
</del><ins>+            if (m_node-&gt;child2()-&gt;isInt32Constant() &amp;&amp; !(m_node-&gt;child2()-&gt;asInt32() &amp; 0x1f)) {
+                convertToIdentityOverChild1();
+                break;
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case UInt32ToNumber:
</span><span class="cx">             if (m_node-&gt;child1()-&gt;op() == BitURShift
</span><del>-                &amp;&amp; m_node-&gt;child1()-&gt;child2()-&gt;isConstant()) {
-                JSValue shiftAmount = m_graph.valueOfJSConstant(
-                    m_node-&gt;child1()-&gt;child2().node());
-                if (shiftAmount.isInt32() &amp;&amp; (shiftAmount.asInt32() &amp; 0x1f)) {
-                    m_node-&gt;convertToIdentity();
-                    m_changed = true;
-                    break;
-                }
</del><ins>+                &amp;&amp; m_node-&gt;child1()-&gt;child2()-&gt;isInt32Constant()
+                &amp;&amp; (m_node-&gt;child1()-&gt;child2()-&gt;asInt32() &amp; 0x1f)) {
+                m_node-&gt;convertToIdentity();
+                m_changed = true;
+                break;
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case ArithAdd:
</span><span class="cx">             handleCommutativity();
</span><span class="cx">             
</span><del>-            if (m_graph.isInt32Constant(m_node-&gt;child2().node())) {
-                int32_t value = m_graph.valueOfInt32Constant(
-                    m_node-&gt;child2().node());
-                if (!value) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
</del><ins>+            if (m_node-&gt;child2()-&gt;isInt32Constant() &amp;&amp; !m_node-&gt;child2()-&gt;asInt32()) {
+                convertToIdentityOverChild1();
+                break;
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="lines">@@ -129,9 +116,9 @@
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case ArithSub:
</span><del>-            if (m_graph.isInt32Constant(m_node-&gt;child2().node())
</del><ins>+            if (m_node-&gt;child2()-&gt;isInt32Constant()
</ins><span class="cx">                 &amp;&amp; m_node-&gt;isBinaryUseKind(Int32Use)) {
</span><del>-                int32_t value = m_graph.valueOfInt32Constant(m_node-&gt;child2().node());
</del><ins>+                int32_t value = m_node-&gt;child2()-&gt;asInt32();
</ins><span class="cx">                 if (-value != value) {
</span><span class="cx">                     m_node-&gt;setOp(ArithAdd);
</span><span class="cx">                     m_node-&gt;child2().setNode(
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGValidate.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -199,6 +199,34 @@
</span><span class="cx">                 
</span><span class="cx">                 if (node-&gt;hasStructure())
</span><span class="cx">                     VALIDATE((node), !!node-&gt;structure());
</span><ins>+                
+                if (node-&gt;hasFunction())
+                    VALIDATE((node), node-&gt;function()-&gt;value().isFunction());
+                
+                switch (node-&gt;op()) {
+                case MakeRope:
+                case ValueAdd:
+                case ArithAdd:
+                case ArithSub:
+                case ArithMul:
+                case ArithIMul:
+                case ArithDiv:
+                case ArithMod:
+                case ArithMin:
+                case ArithMax:
+                case CompareLess:
+                case CompareLessEq:
+                case CompareGreater:
+                case CompareGreaterEq:
+                case CompareEq:
+                case CompareEqConstant:
+                case CompareStrictEq:
+                    VALIDATE((node), !!node-&gt;child1());
+                    VALIDATE((node), !!node-&gt;child2());
+                    break;
+                default:
+                    break;
+                }
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGValueStrengthcpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.cpp (0 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.cpp                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DFGValueStrength.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream&amp; out, ValueStrength strength)
+{
+    switch (strength) {
+    case FragileValue:
+        out.print(&quot;Fragile&quot;);
+        return;
+    case WeakValue:
+        out.print(&quot;Weak&quot;);
+        return;
+    case StrongValue:
+        out.print(&quot;Strong&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGValueStrengthh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.h (0 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.h                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGValueStrength.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGValueStrength_h
+#define DFGValueStrength_h
+
+#if ENABLE(DFG_JIT)
+
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace DFG {
+
+enum ValueStrength {
+    // The value is known to the DFG but no optimizations have been performed that require the
+    // value to be kept alive. All OSR entry values are fragile until we do some optimization that
+    // uses them, like actually constant folding a variable to that value. By convention we say
+    // that all non-cells are fragile.
+    FragileValue,
+    
+    // The value has been used for optimization and it arose through inference. We don't want the
+    // fact that we optimized the code to result in the GC keeping this value alive unnecessarily,
+    // so we'd rather kill the code and recompile than keep the object alive longer.
+    WeakValue,
+    
+    // The code will keep this value alive. This is true of constants that were present in the
+    // source. String constants tend to be strong.
+    StrongValue
+};
+
+inline ValueStrength merge(ValueStrength a, ValueStrength b)
+{
+    switch (a) {
+    case FragileValue:
+        return b;
+    case WeakValue:
+        if (b == StrongValue)
+            return StrongValue;
+        return WeakValue;
+    case StrongValue:
+        return StrongValue;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&amp;, JSC::DFG::ValueStrength);
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGValueStrength_h
+
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGVariableEventStreamcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -81,23 +81,16 @@
</span><span class="cx"> 
</span><span class="cx"> } // namespace
</span><span class="cx"> 
</span><del>-bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery&amp; recovery, CodeBlock* codeBlock, MinifiedNode* node) const
</del><ins>+bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery&amp; recovery, MinifiedNode* node) const
</ins><span class="cx"> {
</span><span class="cx">     if (!node)
</span><span class="cx">         return false;
</span><span class="cx">     
</span><del>-    if (node-&gt;hasConstantNumber()) {
-        recovery = ValueRecovery::constant(
-            codeBlock-&gt;constantRegister(
-                FirstConstantRegisterIndex + node-&gt;constantNumber()).get());
</del><ins>+    if (node-&gt;hasConstant()) {
+        recovery = ValueRecovery::constant(node-&gt;constant());
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (node-&gt;hasWeakConstant()) {
-        recovery = ValueRecovery::constant(node-&gt;weakConstant());
-        return true;
-    }
-    
</del><span class="cx">     if (node-&gt;op() == PhantomArguments) {
</span><span class="cx">         recovery = ValueRecovery::argumentsThatWereNotCreated();
</span><span class="cx">         return true;
</span><span class="lines">@@ -187,7 +180,7 @@
</span><span class="cx">         
</span><span class="cx">         ASSERT(source.kind() == HaveNode);
</span><span class="cx">         MinifiedNode* node = graph.at(source.id());
</span><del>-        if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, node))
</del><ins>+        if (tryToSetConstantRecovery(valueRecoveries[i], node))
</ins><span class="cx">             continue;
</span><span class="cx">         
</span><span class="cx">         MinifiedGenerationInfo info = generationInfos.get(source.id());
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGVariableEventStreamh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGVariableEventStream.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">         unsigned index, Operands&lt;ValueRecovery&gt;&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool tryToSetConstantRecovery(ValueRecovery&amp;, CodeBlock*, MinifiedNode*) const;
</del><ins>+    bool tryToSetConstantRecovery(ValueRecovery&amp;, MinifiedNode*) const;
</ins><span class="cx">     
</span><span class="cx">     void logEvent(const VariableEvent&amp;);
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGWatchableStructureWatchingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -47,9 +47,12 @@
</span><span class="cx">         // These are pretty dumb, but needed to placate subsequent assertions. We con't actually
</span><span class="cx">         // have to watch these because there is no way to transition away from it, but they are
</span><span class="cx">         // watchable and so we will assert if they aren't watched.
</span><del>-        tryWatch(m_graph.m_vm.stringStructure.get()); 
</del><ins>+        tryWatch(m_graph.m_vm.stringStructure.get());
</ins><span class="cx">         tryWatch(m_graph.m_vm.getterSetterStructure.get());
</span><span class="cx">         
</span><ins>+        for (FrozenValue* value : m_graph.m_frozenValues)
+            tryWatch(value-&gt;structure());
+        
</ins><span class="cx">         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
</span><span class="cx">             BasicBlock* block = m_graph.block(blockIndex);
</span><span class="cx">             if (!block)
</span><span class="lines">@@ -59,17 +62,8 @@
</span><span class="cx">                 Node* node = block-&gt;at(nodeIndex);
</span><span class="cx">             
</span><span class="cx">                 switch (node-&gt;op()) {
</span><del>-                case JSConstant:
-                case WeakJSConstant:
-                    tryWatch(m_graph.valueOfJSConstant(node));
-                    break;
-                
-                case CheckFunction:
-                    tryWatch(node-&gt;function());
-                    break;
-                
</del><span class="cx">                 case CheckExecutable:
</span><del>-                    tryWatch(node-&gt;executable());
</del><ins>+                    tryWatch(node-&gt;executable()-&gt;structure());
</ins><span class="cx">                     break;
</span><span class="cx">                 
</span><span class="cx">                 case CheckStructure:
</span><span class="lines">@@ -93,7 +87,7 @@
</span><span class="cx">                 case MultiGetByOffset:
</span><span class="cx">                     for (unsigned i = node-&gt;multiGetByOffsetData().variants.size(); i--;) {
</span><span class="cx">                         GetByIdVariant&amp; variant = node-&gt;multiGetByOffsetData().variants[i];
</span><del>-                        tryWatch(variant.specificValue());
</del><ins>+                        tryWatch(m_graph.freeze(variant.specificValue())-&gt;structure());
</ins><span class="cx">                         tryWatch(variant.structureSet());
</span><span class="cx">                         // Don't need to watch anything in the structure chain because that would
</span><span class="cx">                         // have been decomposed into CheckStructure's. Don't need to watch the
</span><span class="lines">@@ -139,22 +133,12 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        m_graph.m_structureWatchpointState = WatchingAllWatchableStructures;
+        
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void tryWatch(JSValue value)
-    {
-        if (value.isCell())
-            tryWatch(value.asCell());
-    }
-    
-    void tryWatch(JSCell* cell)
-    {
-        if (cell)
-            tryWatch(cell-&gt;structure());
-    }
-    
</del><span class="cx">     void tryWatch(const StructureSet&amp; set)
</span><span class="cx">     {
</span><span class="cx">         for (unsigned i = set.size(); i--;)
</span><span class="lines">@@ -163,7 +147,8 @@
</span><span class="cx">     
</span><span class="cx">     void tryWatch(Structure* structure)
</span><span class="cx">     {
</span><del>-        m_graph.watchpoints().consider(structure);
</del><ins>+        if (structure)
+            m_graph.watchpoints().consider(structure);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case AllocationProfileWatchpoint:
</span><del>-            addLazily(jsCast&lt;JSFunction*&gt;(m_node-&gt;function())-&gt;allocationProfileWatchpointSet());
</del><ins>+            addLazily(jsCast&lt;JSFunction*&gt;(m_node-&gt;function()-&gt;value())-&gt;allocationProfileWatchpointSet());
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case VariableWatchpoint:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -44,7 +44,6 @@
</span><span class="cx">     
</span><span class="cx">     switch (node-&gt;op()) {
</span><span class="cx">     case JSConstant:
</span><del>-    case WeakJSConstant:
</del><span class="cx">     case GetMyArgumentsLength:
</span><span class="cx">     case GetLocal:
</span><span class="cx">     case SetLocal:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreftlFTLLinkcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ftl/FTLLink.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ftl/FTLLink.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/ftl/FTLLink.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -63,6 +63,8 @@
</span><span class="cx">     if (!graph.m_plan.inlineCallFrames-&gt;isEmpty())
</span><span class="cx">         state.jitCode-&gt;common.inlineCallFrames = graph.m_plan.inlineCallFrames;
</span><span class="cx">     
</span><ins>+    graph.registerFrozenValues();
+
</ins><span class="cx">     // Create the entrypoint. Note that we use this entrypoint totally differently
</span><span class="cx">     // depending on whether we're doing OSR entry or not.
</span><span class="cx">     CCallHelpers jit(&amp;vm, codeBlock);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -359,9 +359,6 @@
</span><span class="cx">         case Int52Constant:
</span><span class="cx">             compileInt52Constant();
</span><span class="cx">             break;
</span><del>-        case WeakJSConstant:
-            compileWeakJSConstant();
-            break;
</del><span class="cx">         case PhantomArguments:
</span><span class="cx">             compilePhantomArguments();
</span><span class="cx">             break;
</span><span class="lines">@@ -771,22 +768,17 @@
</span><span class="cx">     
</span><span class="cx">     void compileDoubleConstant()
</span><span class="cx">     {
</span><del>-        setDouble(m_out.constDouble(m_graph.valueOfNumberConstant(m_node)));
</del><ins>+        setDouble(m_out.constDouble(m_node-&gt;asNumber()));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileInt52Constant()
</span><span class="cx">     {
</span><del>-        int64_t value = m_graph.valueOfJSConstant(m_node).asMachineInt();
</del><ins>+        int64_t value = m_node-&gt;asMachineInt();
</ins><span class="cx">         
</span><span class="cx">         setInt52(m_out.constInt64(value &lt;&lt; JSValue::int52ShiftAmount));
</span><span class="cx">         setStrictInt52(m_out.constInt64(value));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void compileWeakJSConstant()
-    {
-        setJSValue(weakPointer(m_node-&gt;weakConstant()));
-    }
-    
</del><span class="cx">     void compilePhantomArguments()
</span><span class="cx">     {
</span><span class="cx">         setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
</span><span class="lines">@@ -1639,8 +1631,8 @@
</span><span class="cx">         LValue cell = lowCell(m_node-&gt;child1());
</span><span class="cx">         
</span><span class="cx">         ExitKind exitKind;
</span><del>-        if (m_node-&gt;child1()-&gt;op() == WeakJSConstant)
-            exitKind = BadWeakConstantCache;
</del><ins>+        if (m_node-&gt;child1()-&gt;hasConstant())
+            exitKind = BadConstantCache;
</ins><span class="cx">         else
</span><span class="cx">             exitKind = BadCache;
</span><span class="cx">         
</span><span class="lines">@@ -1678,7 +1670,7 @@
</span><span class="cx">         
</span><span class="cx">         speculate(
</span><span class="cx">             BadFunction, jsValueValue(cell), m_node-&gt;child1().node(),
</span><del>-            m_out.notEqual(cell, weakPointer(m_node-&gt;function())));
</del><ins>+            m_out.notEqual(cell, weakPointer(m_node-&gt;function()-&gt;value().asCell())));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileCheckExecutable()
</span><span class="lines">@@ -3459,7 +3451,7 @@
</span><span class="cx">     
</span><span class="cx">     void compileCompareEqConstant()
</span><span class="cx">     {
</span><del>-        ASSERT(m_graph.valueOfJSConstant(m_node-&gt;child2().node()).isNull());
</del><ins>+        ASSERT(m_node-&gt;child2()-&gt;asJSValue().isNull());
</ins><span class="cx">         setBoolean(
</span><span class="cx">             equalNullOrUndefined(
</span><span class="cx">                 m_node-&gt;child1(), AllCellsAreFalse, EqualNullOrUndefined));
</span><span class="lines">@@ -3552,7 +3544,7 @@
</span><span class="cx">     
</span><span class="cx">     void compileCompareStrictEqConstant()
</span><span class="cx">     {
</span><del>-        JSValue constant = m_graph.valueOfJSConstant(m_node-&gt;child2().node());
</del><ins>+        JSValue constant = m_node-&gt;child2()-&gt;asJSValue();
</ins><span class="cx"> 
</span><span class="cx">         setBoolean(
</span><span class="cx">             m_out.equal(
</span><span class="lines">@@ -4958,7 +4950,7 @@
</span><span class="cx">         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
</span><span class="cx">         
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue value = m_graph.valueOfJSConstant(edge.node());
</del><ins>+            JSValue value = edge-&gt;asJSValue();
</ins><span class="cx">             if (!value.isInt32()) {
</span><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.int32Zero;
</span><span class="lines">@@ -5072,7 +5064,7 @@
</span><span class="cx">         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
</span><span class="cx">         
</span><span class="cx">         if (edge-&gt;op() == JSConstant) {
</span><del>-            JSValue value = m_graph.valueOfJSConstant(edge.node());
</del><ins>+            JSValue value = edge-&gt;asJSValue();
</ins><span class="cx">             if (!value.isCell()) {
</span><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.intPtrZero;
</span><span class="lines">@@ -5135,7 +5127,7 @@
</span><span class="cx">         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
</span><span class="cx">         
</span><span class="cx">         if (edge-&gt;hasConstant()) {
</span><del>-            JSValue value = m_graph.valueOfJSConstant(edge.node());
</del><ins>+            JSValue value = edge-&gt;asJSValue();
</ins><span class="cx">             if (!value.isBoolean()) {
</span><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.booleanFalse;
</span><span class="lines">@@ -5181,8 +5173,8 @@
</span><span class="cx">         DFG_ASSERT(m_graph, m_node, edge.useKind() != Int52RepUse);
</span><span class="cx">         
</span><span class="cx">         if (edge-&gt;hasConstant())
</span><del>-            return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node())));
-        
</del><ins>+            return m_out.constInt64(JSValue::encode(edge-&gt;asJSValue()));
+
</ins><span class="cx">         LoweredNodeValue value = m_jsValueValues.get(edge.node());
</span><span class="cx">         if (isValid(value))
</span><span class="cx">             return value.value();
</span><span class="lines">@@ -6087,8 +6079,7 @@
</span><span class="cx">         case JSConstant:
</span><span class="cx">         case Int52Constant:
</span><span class="cx">         case DoubleConstant:
</span><del>-        case WeakJSConstant:
-            exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
</del><ins>+            exit.m_values[index] = ExitValue::constant(node-&gt;asJSValue());
</ins><span class="cx">             return true;
</span><span class="cx">         case PhantomArguments:
</span><span class="cx">             exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx">         
</span><span class="cx">         Profiler::OSRExit* profilerExit = compilation-&gt;addOSRExit(
</span><span class="cx">             exitID, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
</span><del>-            exit.m_kind, isWatchpoint(exit.m_kind));
</del><ins>+            exit.m_kind, exit.m_kind == UncountableInvalidation);
</ins><span class="cx">         jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit-&gt;counterAddress()));
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeJSCJSValuecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.cpp (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.cpp        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.cpp        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -191,6 +191,13 @@
</span><span class="cx"> 
</span><span class="cx"> void JSValue::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><ins>+    dumpInContextAssumingStructure(
+        out, context, (!!*this &amp;&amp; isCell()) ? asCell()-&gt;structure() : nullptr);
+}
+
+void JSValue::dumpInContextAssumingStructure(
+    PrintStream&amp; out, DumpContext* context, Structure* structure) const
+{
</ins><span class="cx">     if (!*this)
</span><span class="cx">         out.print(&quot;&lt;JSValue()&gt;&quot;);
</span><span class="cx">     else if (isInt32())
</span><span class="lines">@@ -207,7 +214,7 @@
</span><span class="cx">         out.printf(&quot;Double: %08x:%08x, %lf&quot;, u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
</span><span class="cx"> #endif
</span><span class="cx">     } else if (isCell()) {
</span><del>-        if (asCell()-&gt;inherits(JSString::info())) {
</del><ins>+        if (structure-&gt;classInfo()-&gt;isSubClassOf(JSString::info())) {
</ins><span class="cx">             JSString* string = jsCast&lt;JSString*&gt;(asCell());
</span><span class="cx">             out.print(&quot;String&quot;);
</span><span class="cx">             if (string-&gt;isRope())
</span><span class="lines">@@ -223,11 +230,11 @@
</span><span class="cx">             } else
</span><span class="cx">                 out.print(&quot; (unresolved)&quot;);
</span><span class="cx">             out.print(&quot;: &quot;, impl);
</span><del>-        } else if (asCell()-&gt;inherits(Structure::info()))
</del><ins>+        } else if (structure-&gt;classInfo()-&gt;isSubClassOf(Structure::info()))
</ins><span class="cx">             out.print(&quot;Structure: &quot;, inContext(*jsCast&lt;Structure*&gt;(asCell()), context));
</span><span class="cx">         else {
</span><span class="cx">             out.print(&quot;Cell: &quot;, RawPointer(asCell()));
</span><del>-            out.print(&quot; (&quot;, inContext(*asCell()-&gt;structure(), context), &quot;)&quot;);
</del><ins>+            out.print(&quot; (&quot;, inContext(*structure, context), &quot;)&quot;);
</ins><span class="cx">         }
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">         out.print(&quot;, ID: &quot;, asCell()-&gt;structureID());
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeJSCJSValueh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.h (169794 => 169795)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.h        2014-06-11 04:32:07 UTC (rev 169794)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/JSCJSValue.h        2014-06-11 04:52:59 UTC (rev 169795)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> class PropertyName;
</span><span class="cx"> class PropertySlot;
</span><span class="cx"> class PutPropertySlot;
</span><ins>+class Structure;
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> namespace DFG {
</span><span class="cx"> class JITCompiler;
</span><span class="lines">@@ -277,6 +278,7 @@
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void dump(PrintStream&amp;) const;
</span><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span><ins>+    void dumpInContextAssumingStructure(PrintStream&amp;, DumpContext*, Structure*) const;
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>