Merge r169795, r169819, r169864, r169902, r169949, r169950, r170016, r170017, r170060, r170064 from ftlopt.

    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
    

Source/JavaScriptCore: 
    [ftlopt] Fold constant Phis
    https://bugs.webkit.org/show_bug.cgi?id=133967
    
    Reviewed by Mark Hahnenberg.
            
    It's surprising but we didn't really do this before. Or, rather, we only did it
    incidentally when we would likely crash if it ever happened.
            
    Making this work required cleaning up the validater a bit, so I did that too. I also added
    mayExit() validation for nodes that didn't have origin.forExit (i.e. nodes that end up in
    the Phi header of basic blocks). But this required beefing up mayExit() a bit.
    
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
    * dfg/DFGAdjacencyList.h:
    (JSC::DFG::AdjacencyList::isEmpty):
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::run):
    (JSC::DFG::ConstantFoldingPhase::foldConstants):
    (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
    * dfg/DFGInPlaceAbstractState.h:
    * dfg/DFGLICMPhase.cpp:
    (JSC::DFG::LICMPhase::run):
    (JSC::DFG::LICMPhase::attemptHoist):
    * dfg/DFGMayExit.cpp:
    (JSC::DFG::mayExit):
    * dfg/DFGValidate.cpp:
    (JSC::DFG::Validate::validate):
    (JSC::DFG::Validate::validateSSA):
    
    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] Get rid of NodeDoesNotExit and also get rid of StoreEliminationPhase
    https://bugs.webkit.org/show_bug.cgi?id=133985
    
    Reviewed by Michael Saboff and Mark Hahnenberg.
            
    Store elimination phase has never been very profitable, and now that LLVM can do dead
    store elimination for us, this phase is just completely pointless.
            
    This phase is also the primary user of NodeDoesNotExit, which is a flag that the CFA
    computes. It computes it poorly and we often get bugs in it. It's also a lot of code to
    maintain.
            
    This patch does introduce a new mayExit() calculator that is independent of the CFA and
    should be enough for most of the previous NodeDoesNotExit users. Currently it's only used
    for assertions in the DFG backend, but we could use it if we ever brought back any of the
    other optimizations that previously relied upon NodeDoesNotExit.
            
    This is performance-neutral, except for SunSpider, where it's a speed-up.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * dfg/DFGAbstractInterpreter.h:
    (JSC::DFG::AbstractInterpreter::filterEdgeByUse):
    (JSC::DFG::AbstractInterpreter::filterByType):
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::startExecuting):
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
    * dfg/DFGCSEPhase.cpp:
    (JSC::DFG::CSEPhase::CSEPhase):
    (JSC::DFG::CSEPhase::invalidationPointElimination):
    (JSC::DFG::CSEPhase::setLocalStoreElimination):
    (JSC::DFG::CSEPhase::performNodeCSE):
    (JSC::DFG::CSEPhase::performBlockCSE):
    (JSC::DFG::performCSE):
    (JSC::DFG::CSEPhase::globalVarStoreElimination): Deleted.
    (JSC::DFG::CSEPhase::scopedVarStoreElimination): Deleted.
    (JSC::DFG::CSEPhase::putStructureStoreElimination): Deleted.
    (JSC::DFG::CSEPhase::putByOffsetStoreElimination): Deleted.
    (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): Deleted.
    (JSC::DFG::performStoreElimination): Deleted.
    * dfg/DFGCSEPhase.h:
    * dfg/DFGFixupPhase.cpp:
    (JSC::DFG::FixupPhase::fixupNode):
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::resetExitStates): Deleted.
    * dfg/DFGGraph.h:
    * dfg/DFGMayExit.cpp: Added.
    (JSC::DFG::mayExit):
    * dfg/DFGMayExit.h: Added.
    * dfg/DFGNode.h:
    (JSC::DFG::Node::mergeFlags):
    (JSC::DFG::Node::filterFlags):
    (JSC::DFG::Node::setCanExit): Deleted.
    (JSC::DFG::Node::canExit): Deleted.
    * dfg/DFGNodeFlags.cpp:
    (JSC::DFG::dumpNodeFlags):
    * dfg/DFGNodeFlags.h:
    * dfg/DFGNodeType.h:
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::compileInThreadImpl):
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
    (JSC::DFG::SpeculativeJIT::bail):
    (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
    * dfg/DFGSpeculativeJIT32_64.cpp:
    (JSC::DFG::SpeculativeJIT::compile):
    * dfg/DFGSpeculativeJIT64.cpp:
    (JSC::DFG::SpeculativeJIT::compile):
    
    2014-06-15  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] Remove the DFG optimization fixpoint and remove some obvious reasons why we previously benefited from it
    https://bugs.webkit.org/show_bug.cgi?id=133931
    
    Reviewed by Oliver Hunt.
    
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Trigger constant-folding for GetMyArgumentByVal (which means turning it into GetLocalUnlinked) and correct the handling of Upsilon so we don't fold them away.
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::foldConstants): Implement constant-folding for GetMyArgumentByVal.
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::compileInThreadImpl): Remove the fixpoint.
    
    2014-06-15  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] DFG OSR entry should have a crystal-clear story for when it's safe to enter at a block with a set of values
    https://bugs.webkit.org/show_bug.cgi?id=133935
    
    Reviewed by Oliver Hunt.
    
    * bytecode/Operands.h:
    (JSC::Operands::Operands):
    (JSC::Operands::ensureLocals):
    * dfg/DFGAbstractValue.cpp:
    (JSC::DFG::AbstractValue::filter): Now we can compute intersections of abstract values!
    * dfg/DFGAbstractValue.h:
    (JSC::DFG::AbstractValue::makeFullTop): Completeness.
    (JSC::DFG::AbstractValue::bytecodeTop): Completeness.
    (JSC::DFG::AbstractValue::fullTop): Completeness. We end up using this one.
    * dfg/DFGBasicBlock.cpp:
    (JSC::DFG::BasicBlock::BasicBlock):
    (JSC::DFG::BasicBlock::ensureLocals):
    * dfg/DFGBasicBlock.h: Remember the intersection of all things ever proven.
    * dfg/DFGCFAPhase.cpp:
    (JSC::DFG::CFAPhase::run): Compute the intersection.
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::foldConstants): No need for the weirdo merge check since this fixes the root of the problem.
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::dumpBlockHeader): Better dumping.
    (JSC::DFG::Graph::dump): Better dumping.
    * dfg/DFGJITCompiler.h:
    (JSC::DFG::JITCompiler::noticeOSREntry): Use the intersected abstract value.
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::compileCurrentBlock): Assert if the intersected state indicates the block shouldn't execute.
    
    2014-06-12  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants
    https://bugs.webkit.org/show_bug.cgi?id=133821
    
    Reviewed by Mark Hahnenberg.
            
    This allows us to efficiently cache accesses that differ only in the prototypes on the path
    from the base to the prototype that has the field.
            
    It also simplifies a bunch of code - IntendedStructureChain is now just an intermediate
    data structure.
    
    * CMakeLists.txt:
    * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * bytecode/ConstantStructureCheck.cpp: Added.
    (JSC::ConstantStructureCheck::dumpInContext):
    (JSC::ConstantStructureCheck::dump):
    (JSC::structureFor):
    (JSC::areCompatible):
    (JSC::mergeInto):
    * bytecode/ConstantStructureCheck.h: Added.
    (JSC::ConstantStructureCheck::ConstantStructureCheck):
    (JSC::ConstantStructureCheck::operator!):
    (JSC::ConstantStructureCheck::constant):
    (JSC::ConstantStructureCheck::structure):
    * bytecode/GetByIdStatus.cpp:
    (JSC::GetByIdStatus::computeForStubInfo):
    * bytecode/GetByIdVariant.cpp:
    (JSC::GetByIdVariant::GetByIdVariant):
    (JSC::GetByIdVariant::operator=):
    (JSC::GetByIdVariant::attemptToMerge):
    (JSC::GetByIdVariant::dumpInContext):
    * bytecode/GetByIdVariant.h:
    (JSC::GetByIdVariant::constantChecks):
    (JSC::GetByIdVariant::alternateBase):
    (JSC::GetByIdVariant::GetByIdVariant): Deleted.
    (JSC::GetByIdVariant::chain): Deleted.
    * bytecode/PutByIdVariant.cpp:
    (JSC::PutByIdVariant::dumpInContext):
    * bytecode/PutByIdVariant.h:
    (JSC::PutByIdVariant::transition):
    (JSC::PutByIdVariant::constantChecks):
    (JSC::PutByIdVariant::structureChain): Deleted.
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::emitChecks):
    (JSC::DFG::ByteCodeParser::handleGetById):
    (JSC::DFG::ByteCodeParser::handlePutById):
    (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck): Deleted.
    (JSC::DFG::ByteCodeParser::structureChainIsStillValid): Deleted.
    (JSC::DFG::ByteCodeParser::emitPrototypeChecks): Deleted.
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::foldConstants):
    (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
    (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
    (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
    * dfg/DFGDesiredStructureChains.cpp: Removed.
    * dfg/DFGDesiredStructureChains.h: Removed.
    * dfg/DFGGraph.h:
    (JSC::DFG::Graph::watchpoints):
    (JSC::DFG::Graph::chains): Deleted.
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::isStillValid):
    (JSC::DFG::Plan::checkLivenessAndVisitChildren):
    (JSC::DFG::Plan::cancel):
    * dfg/DFGPlan.h:
    * ftl/FTLLowerDFGToLLVM.cpp:
    (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
    * runtime/IntendedStructureChain.cpp:
    (JSC::IntendedStructureChain::gatherChecks):
    * runtime/IntendedStructureChain.h:
    (JSC::IntendedStructureChain::at):
    (JSC::IntendedStructureChain::operator[]):
    
    2014-06-12  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] Constant folding and strength reduction should work in SSA
    https://bugs.webkit.org/show_bug.cgi?id=133839
    
    Reviewed by Oliver Hunt.
    
    * dfg/DFGAtTailAbstractState.cpp:
    (JSC::DFG::AtTailAbstractState::AtTailAbstractState):
    (JSC::DFG::AtTailAbstractState::forNode):
    * dfg/DFGAtTailAbstractState.h:
    * dfg/DFGConstantFoldingPhase.cpp:
    (JSC::DFG::ConstantFoldingPhase::foldConstants):
    * dfg/DFGGraph.cpp:
    (JSC::DFG::Graph::convertToConstant):
    * dfg/DFGIntegerCheckCombiningPhase.cpp:
    (JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend): Fix an unrelated regression that this uncovered.
    * dfg/DFGLICMPhase.cpp:
    (JSC::DFG::LICMPhase::LICMPhase):
    * dfg/DFGPlan.cpp:
    (JSC::DFG::Plan::compileInThreadImpl):
    
    2014-06-11  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base
    https://bugs.webkit.org/show_bug.cgi?id=133751
    
    Reviewed by Mark Hahnenberg.
    
    * bytecode/GetByIdStatus.cpp:
    (JSC::GetByIdStatus::appendVariant):
    (JSC::GetByIdStatus::computeForStubInfo):
    * bytecode/GetByIdVariant.cpp:
    (JSC::GetByIdVariant::attemptToMerge):
    * bytecode/GetByIdVariant.h:
    * bytecode/PutByIdStatus.cpp:
    (JSC::PutByIdStatus::computeFor):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
    (JSC::DFG::ByteCodeParser::handleGetById):
    (JSC::DFG::ByteCodeParser::handlePutById):
    * runtime/IntendedStructureChain.cpp:
    (JSC::IntendedStructureChain::IntendedStructureChain):
    (JSC::IntendedStructureChain::isStillValid):
    (JSC::IntendedStructureChain::isNormalized):
    (JSC::IntendedStructureChain::terminalPrototype):
    (JSC::IntendedStructureChain::operator==):
    (JSC::IntendedStructureChain::visitChildren):
    (JSC::IntendedStructureChain::dumpInContext):
    (JSC::IntendedStructureChain::chain): Deleted.
    * runtime/IntendedStructureChain.h:
    (JSC::IntendedStructureChain::prototype):
    (JSC::IntendedStructureChain::operator!=):
    (JSC::IntendedStructureChain::head): Deleted.
    
    2014-06-11  Matthew Mirman  <mmirman@apple.com>
    
   Readded native calling to the FTL and Split the DFG nodes 
   Call and Construct into NativeCall and NativeConstruct 
   to better represent their semantics.
   https://bugs.webkit.org/show_bug.cgi?id=133660
    
   Reviewed by Filip Pizlo.
    
   * dfg/DFGAbstractInterpreterInlines.h:
   (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 
   Added NativeCall and NativeConstruct case
   * dfg/DFGByteCodeParser.cpp:
   (JSC::DFG::ByteCodeParser::addCall): added NativeCall case. 
   (JSC::DFG::ByteCodeParser::handleCall): 
   set to return NativeCall or NativeConstruct instead of Call or Construct
   in the presence of a native function.
   * dfg/DFGClobberize.h:
   (JSC::DFG::clobberize): added NativeCall and NativeConstruct case.
   * dfg/DFGDoesGC.cpp:
   (JSC::DFG::doesGC): added NativeCall and NativeConstruct case.
   * dfg/DFGFixupPhase.cpp:
   (JSC::DFG::FixupPhase::fixupNode): added NativeCall and NativeConstruct case.
   * dfg/DFGNode.h:
   (JSC::DFG::Node::hasHeapPrediction): added NativeCall and NativeConstruct case.
   (JSC::DFG::Node::canBeKnownFunction): changed to NativeCall and NativeConstruct.
   (JSC::DFG::Node::hasKnownFunction): changed to NativeCall and NativeConstruct.
   * dfg/DFGNodeType.h: added NativeCall and NativeConstruct.
   * dfg/DFGPredictionPropagationPhase.cpp:
   (JSC::DFG::PredictionPropagationPhase::propagate): added NativeCall and NativeConstruct case.
   * dfg/DFGSafeToExecute.h:
   (JSC::DFG::safeToExecute): added NativeCall and NativeConstruct case.
   * dfg/DFGSpeculativeJIT32_64.cpp:
   (JSC::DFG::SpeculativeJIT::emitCall): ditto
   (JSC::DFG::SpeculativeJIT::compile): ditto
   * dfg/DFGSpeculativeJIT64.cpp:
   (JSC::DFG::SpeculativeJIT::emitCall): ditto
   (JSC::DFG::SpeculativeJIT::compile): ditto
   * ftl/FTLCapabilities.cpp:
   (JSC::FTL::canCompile): ditto
   * ftl/FTLLowerDFGToLLVM.cpp:  
   (JSC::FTL::LowerDFGToLLVM::lower): ditto
   (JSC::FTL::LowerDFGToLLVM::compileNode): ditto.
   (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct): Added.
   (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct): removed NativeCall and NativeConstruct functionality.
   (JSC::FTL::LowerDFGToLLVM::didOverflowStack): added NativeCall and NativeConstruct case.
   * runtime/JSCJSValue.h: added JS_EXPORT_PRIVATE to toInteger as it is apparently needed.
           
    2014-06-11  Matthew Mirman  <mmirman@apple.com>
    
    Ensured Native Calls and Construct and associated checks 
    are only emitted during ftl mode.
    https://bugs.webkit.org/show_bug.cgi?id=133718
            
    Reviewed by Filip Pizlo.
            
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::handleCall): Added check for ftl mode 
    before attaching the native function to Call or Construct.
            
    2014-06-10  Filip Pizlo  <fpizlo@apple.com>
    
    [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 "freeze" 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<AbstractStateType>::executeEffects):
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::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:

LayoutTests: 
    [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants
    https://bugs.webkit.org/show_bug.cgi?id=133821
    
    Reviewed by Mark Hahnenberg.
    
    * js/regress/poly-chain-access-different-prototypes-expected.txt: Added.
    * js/regress/poly-chain-access-different-prototypes-simple-expected.txt: Added.
    * js/regress/poly-chain-access-different-prototypes-simple.html: Added.
    * js/regress/poly-chain-access-different-prototypes.html: Added.
    * js/regress/script-tests/poly-chain-access-different-prototypes-simple.js: Added.
    * js/regress/script-tests/poly-chain-access-different-prototypes.js: Added.
    
    2014-06-11  Filip Pizlo  <fpizlo@apple.com>
    
    [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base
    https://bugs.webkit.org/show_bug.cgi?id=133751
    
    Reviewed by Mark Hahnenberg.
    
    * js/regress/poly-chain-access-expected.txt: Added.
    * js/regress/poly-chain-access-simpler-expected.txt: Added.
    * js/regress/poly-chain-access-simpler.html: Added.
    * js/regress/poly-chain-access.html: Added.
    * js/regress/script-tests/poly-chain-access-simpler.js: Added.
    * js/regress/script-tests/poly-chain-access.js: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@171613 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 4c27459..cf7bb20 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -68,6 +68,7 @@
     bytecode/CodeBlockJettisoningWatchpoint.cpp
     bytecode/CodeOrigin.cpp
     bytecode/CodeType.cpp
+    bytecode/ConstantStructureCheck.cpp
     bytecode/DFGExitProfile.cpp
     bytecode/DeferredCompilationCallback.cpp
     bytecode/ExecutionCounter.cpp
@@ -132,7 +133,6 @@
     dfg/DFGCriticalEdgeBreakingPhase.cpp
     dfg/DFGDCEPhase.cpp
     dfg/DFGDesiredIdentifiers.cpp
-    dfg/DFGDesiredStructureChains.cpp
     dfg/DFGDesiredTransitions.cpp
     dfg/DFGDesiredWatchpoints.cpp
     dfg/DFGDesiredWeakReferences.cpp
@@ -147,6 +147,7 @@
     dfg/DFGFixupPhase.cpp
     dfg/DFGFlushFormat.cpp
     dfg/DFGFlushedAt.cpp
+    dfg/DFGFrozenValue.cpp
     dfg/DFGFunctionWhitelist.cpp
     dfg/DFGGraph.cpp
     dfg/DFGGraphSafepoint.cpp
@@ -162,6 +163,7 @@
     dfg/DFGLivenessAnalysisPhase.cpp
     dfg/DFGLongLivedState.cpp
     dfg/DFGLoopPreHeaderCreationPhase.cpp
+    dfg/DFGMayExit.cpp
     dfg/DFGMinifiedNode.cpp
     dfg/DFGNaturalLoops.cpp
     dfg/DFGNode.cpp
@@ -203,6 +205,7 @@
     dfg/DFGUseKind.cpp
     dfg/DFGValidate.cpp
     dfg/DFGValueSource.cpp
+    dfg/DFGValueStrength.cpp
     dfg/DFGVariableAccessData.cpp
     dfg/DFGVariableAccessDataDump.cpp
     dfg/DFGVariableEvent.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 5df5930..d93fec5 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,651 @@
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r169795, r169819, r169864, r169902, r169949, r169950, r170016, r170017, r170060, r170064 from ftlopt.
+
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Fold constant Phis
+            https://bugs.webkit.org/show_bug.cgi?id=133967
+    
+            Reviewed by Mark Hahnenberg.
+            
+            It's surprising but we didn't really do this before. Or, rather, we only did it
+            incidentally when we would likely crash if it ever happened.
+            
+            Making this work required cleaning up the validater a bit, so I did that too. I also added
+            mayExit() validation for nodes that didn't have origin.forExit (i.e. nodes that end up in
+            the Phi header of basic blocks). But this required beefing up mayExit() a bit.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGAdjacencyList.h:
+            (JSC::DFG::AdjacencyList::isEmpty):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::run):
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
+            * dfg/DFGInPlaceAbstractState.h:
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::run):
+            (JSC::DFG::LICMPhase::attemptHoist):
+            * dfg/DFGMayExit.cpp:
+            (JSC::DFG::mayExit):
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validate):
+            (JSC::DFG::Validate::validateSSA):
+    
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Get rid of NodeDoesNotExit and also get rid of StoreEliminationPhase
+            https://bugs.webkit.org/show_bug.cgi?id=133985
+    
+            Reviewed by Michael Saboff and Mark Hahnenberg.
+            
+            Store elimination phase has never been very profitable, and now that LLVM can do dead
+            store elimination for us, this phase is just completely pointless.
+            
+            This phase is also the primary user of NodeDoesNotExit, which is a flag that the CFA
+            computes. It computes it poorly and we often get bugs in it. It's also a lot of code to
+            maintain.
+            
+            This patch does introduce a new mayExit() calculator that is independent of the CFA and
+            should be enough for most of the previous NodeDoesNotExit users. Currently it's only used
+            for assertions in the DFG backend, but we could use it if we ever brought back any of the
+            other optimizations that previously relied upon NodeDoesNotExit.
+            
+            This is performance-neutral, except for SunSpider, where it's a speed-up.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractInterpreter.h:
+            (JSC::DFG::AbstractInterpreter::filterEdgeByUse):
+            (JSC::DFG::AbstractInterpreter::filterByType):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::startExecuting):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::CSEPhase):
+            (JSC::DFG::CSEPhase::invalidationPointElimination):
+            (JSC::DFG::CSEPhase::setLocalStoreElimination):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::performBlockCSE):
+            (JSC::DFG::performCSE):
+            (JSC::DFG::CSEPhase::globalVarStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::scopedVarStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::putStructureStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::putByOffsetStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): Deleted.
+            (JSC::DFG::performStoreElimination): Deleted.
+            * dfg/DFGCSEPhase.h:
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::resetExitStates): Deleted.
+            * dfg/DFGGraph.h:
+            * dfg/DFGMayExit.cpp: Added.
+            (JSC::DFG::mayExit):
+            * dfg/DFGMayExit.h: Added.
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::mergeFlags):
+            (JSC::DFG::Node::filterFlags):
+            (JSC::DFG::Node::setCanExit): Deleted.
+            (JSC::DFG::Node::canExit): Deleted.
+            * dfg/DFGNodeFlags.cpp:
+            (JSC::DFG::dumpNodeFlags):
+            * dfg/DFGNodeFlags.h:
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+            (JSC::DFG::SpeculativeJIT::bail):
+            (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+    
+    2014-06-15  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Remove the DFG optimization fixpoint and remove some obvious reasons why we previously benefited from it
+            https://bugs.webkit.org/show_bug.cgi?id=133931
+    
+            Reviewed by Oliver Hunt.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Trigger constant-folding for GetMyArgumentByVal (which means turning it into GetLocalUnlinked) and correct the handling of Upsilon so we don't fold them away.
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants): Implement constant-folding for GetMyArgumentByVal.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl): Remove the fixpoint.
+    
+    2014-06-15  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG OSR entry should have a crystal-clear story for when it's safe to enter at a block with a set of values
+            https://bugs.webkit.org/show_bug.cgi?id=133935
+    
+            Reviewed by Oliver Hunt.
+    
+            * bytecode/Operands.h:
+            (JSC::Operands::Operands):
+            (JSC::Operands::ensureLocals):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::filter): Now we can compute intersections of abstract values!
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::makeFullTop): Completeness.
+            (JSC::DFG::AbstractValue::bytecodeTop): Completeness.
+            (JSC::DFG::AbstractValue::fullTop): Completeness. We end up using this one.
+            * dfg/DFGBasicBlock.cpp:
+            (JSC::DFG::BasicBlock::BasicBlock):
+            (JSC::DFG::BasicBlock::ensureLocals):
+            * dfg/DFGBasicBlock.h: Remember the intersection of all things ever proven.
+            * dfg/DFGCFAPhase.cpp:
+            (JSC::DFG::CFAPhase::run): Compute the intersection.
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants): No need for the weirdo merge check since this fixes the root of the problem.
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::dumpBlockHeader): Better dumping.
+            (JSC::DFG::Graph::dump): Better dumping.
+            * dfg/DFGJITCompiler.h:
+            (JSC::DFG::JITCompiler::noticeOSREntry): Use the intersected abstract value.
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::compileCurrentBlock): Assert if the intersected state indicates the block shouldn't execute.
+    
+    2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants
+            https://bugs.webkit.org/show_bug.cgi?id=133821
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This allows us to efficiently cache accesses that differ only in the prototypes on the path
+            from the base to the prototype that has the field.
+            
+            It also simplifies a bunch of code - IntendedStructureChain is now just an intermediate
+            data structure.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/ConstantStructureCheck.cpp: Added.
+            (JSC::ConstantStructureCheck::dumpInContext):
+            (JSC::ConstantStructureCheck::dump):
+            (JSC::structureFor):
+            (JSC::areCompatible):
+            (JSC::mergeInto):
+            * bytecode/ConstantStructureCheck.h: Added.
+            (JSC::ConstantStructureCheck::ConstantStructureCheck):
+            (JSC::ConstantStructureCheck::operator!):
+            (JSC::ConstantStructureCheck::constant):
+            (JSC::ConstantStructureCheck::structure):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            (JSC::GetByIdVariant::operator=):
+            (JSC::GetByIdVariant::attemptToMerge):
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::constantChecks):
+            (JSC::GetByIdVariant::alternateBase):
+            (JSC::GetByIdVariant::GetByIdVariant): Deleted.
+            (JSC::GetByIdVariant::chain): Deleted.
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::transition):
+            (JSC::PutByIdVariant::constantChecks):
+            (JSC::PutByIdVariant::structureChain): Deleted.
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitChecks):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck): Deleted.
+            (JSC::DFG::ByteCodeParser::structureChainIsStillValid): Deleted.
+            (JSC::DFG::ByteCodeParser::emitPrototypeChecks): Deleted.
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+            * dfg/DFGDesiredStructureChains.cpp: Removed.
+            * dfg/DFGDesiredStructureChains.h: Removed.
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::watchpoints):
+            (JSC::DFG::Graph::chains): Deleted.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::isStillValid):
+            (JSC::DFG::Plan::checkLivenessAndVisitChildren):
+            (JSC::DFG::Plan::cancel):
+            * dfg/DFGPlan.h:
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::gatherChecks):
+            * runtime/IntendedStructureChain.h:
+            (JSC::IntendedStructureChain::at):
+            (JSC::IntendedStructureChain::operator[]):
+    
+    2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Constant folding and strength reduction should work in SSA
+            https://bugs.webkit.org/show_bug.cgi?id=133839
+    
+            Reviewed by Oliver Hunt.
+    
+            * dfg/DFGAtTailAbstractState.cpp:
+            (JSC::DFG::AtTailAbstractState::AtTailAbstractState):
+            (JSC::DFG::AtTailAbstractState::forNode):
+            * dfg/DFGAtTailAbstractState.h:
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::convertToConstant):
+            * dfg/DFGIntegerCheckCombiningPhase.cpp:
+            (JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend): Fix an unrelated regression that this uncovered.
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::LICMPhase):
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+    
+    2014-06-11  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base
+            https://bugs.webkit.org/show_bug.cgi?id=133751
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::appendVariant):
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::attemptToMerge):
+            * bytecode/GetByIdVariant.h:
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeFor):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::IntendedStructureChain):
+            (JSC::IntendedStructureChain::isStillValid):
+            (JSC::IntendedStructureChain::isNormalized):
+            (JSC::IntendedStructureChain::terminalPrototype):
+            (JSC::IntendedStructureChain::operator==):
+            (JSC::IntendedStructureChain::visitChildren):
+            (JSC::IntendedStructureChain::dumpInContext):
+            (JSC::IntendedStructureChain::chain): Deleted.
+            * runtime/IntendedStructureChain.h:
+            (JSC::IntendedStructureChain::prototype):
+            (JSC::IntendedStructureChain::operator!=):
+            (JSC::IntendedStructureChain::head): Deleted.
+    
+    2014-06-11  Matthew Mirman  <mmirman@apple.com>
+    
+           Readded native calling to the FTL and Split the DFG nodes 
+           Call and Construct into NativeCall and NativeConstruct 
+           to better represent their semantics.
+           https://bugs.webkit.org/show_bug.cgi?id=133660
+    
+           Reviewed by Filip Pizlo.
+    
+           * dfg/DFGAbstractInterpreterInlines.h:
+           (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 
+           Added NativeCall and NativeConstruct case
+           * dfg/DFGByteCodeParser.cpp:
+           (JSC::DFG::ByteCodeParser::addCall): added NativeCall case. 
+           (JSC::DFG::ByteCodeParser::handleCall): 
+           set to return NativeCall or NativeConstruct instead of Call or Construct
+           in the presence of a native function.
+           * dfg/DFGClobberize.h:
+           (JSC::DFG::clobberize): added NativeCall and NativeConstruct case.
+           * dfg/DFGDoesGC.cpp:
+           (JSC::DFG::doesGC): added NativeCall and NativeConstruct case.
+           * dfg/DFGFixupPhase.cpp:
+           (JSC::DFG::FixupPhase::fixupNode): added NativeCall and NativeConstruct case.
+           * dfg/DFGNode.h:
+           (JSC::DFG::Node::hasHeapPrediction): added NativeCall and NativeConstruct case.
+           (JSC::DFG::Node::canBeKnownFunction): changed to NativeCall and NativeConstruct.
+           (JSC::DFG::Node::hasKnownFunction): changed to NativeCall and NativeConstruct.
+           * dfg/DFGNodeType.h: added NativeCall and NativeConstruct.
+           * dfg/DFGPredictionPropagationPhase.cpp:
+           (JSC::DFG::PredictionPropagationPhase::propagate): added NativeCall and NativeConstruct case.
+           * dfg/DFGSafeToExecute.h:
+           (JSC::DFG::safeToExecute): added NativeCall and NativeConstruct case.
+           * dfg/DFGSpeculativeJIT32_64.cpp:
+           (JSC::DFG::SpeculativeJIT::emitCall): ditto
+           (JSC::DFG::SpeculativeJIT::compile): ditto
+           * dfg/DFGSpeculativeJIT64.cpp:
+           (JSC::DFG::SpeculativeJIT::emitCall): ditto
+           (JSC::DFG::SpeculativeJIT::compile): ditto
+           * ftl/FTLCapabilities.cpp:
+           (JSC::FTL::canCompile): ditto
+           * ftl/FTLLowerDFGToLLVM.cpp:  
+           (JSC::FTL::LowerDFGToLLVM::lower): ditto
+           (JSC::FTL::LowerDFGToLLVM::compileNode): ditto.
+           (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct): Added.
+           (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct): removed NativeCall and NativeConstruct functionality.
+           (JSC::FTL::LowerDFGToLLVM::didOverflowStack): added NativeCall and NativeConstruct case.
+           * runtime/JSCJSValue.h: added JS_EXPORT_PRIVATE to toInteger as it is apparently needed.
+           
+    2014-06-11  Matthew Mirman  <mmirman@apple.com>
+    
+            Ensured Native Calls and Construct and associated checks 
+            are only emitted during ftl mode.
+            https://bugs.webkit.org/show_bug.cgi?id=133718
+            
+            Reviewed by Filip Pizlo.
+            
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall): Added check for ftl mode 
+            before attaching the native function to Call or Construct.
+            
+    2014-06-10  Filip Pizlo  <fpizlo@apple.com>
+    
+            [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 "freeze" 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<AbstractStateType>::executeEffects):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::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-07-24  Brent Fulgham  <bfulgham@apple.com>
 
         [Win] Correct build order in JavaScriptCore.submit.sln
@@ -3567,6 +4215,650 @@
         Add a version of reifyStaticProperties that takes an array of HashTableValues
         rather than a HashTable.
 
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] Fold constant Phis
+        https://bugs.webkit.org/show_bug.cgi?id=133967
+
+        Reviewed by Mark Hahnenberg.
+        
+        It's surprising but we didn't really do this before. Or, rather, we only did it
+        incidentally when we would likely crash if it ever happened.
+        
+        Making this work required cleaning up the validater a bit, so I did that too. I also added
+        mayExit() validation for nodes that didn't have origin.forExit (i.e. nodes that end up in
+        the Phi header of basic blocks). But this required beefing up mayExit() a bit.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAdjacencyList.h:
+        (JSC::DFG::AdjacencyList::isEmpty):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::run):
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
+        * dfg/DFGInPlaceAbstractState.h:
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::run):
+        (JSC::DFG::LICMPhase::attemptHoist):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::validateSSA):
+
+2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] Get rid of NodeDoesNotExit and also get rid of StoreEliminationPhase
+        https://bugs.webkit.org/show_bug.cgi?id=133985
+
+        Reviewed by Michael Saboff and Mark Hahnenberg.
+        
+        Store elimination phase has never been very profitable, and now that LLVM can do dead
+        store elimination for us, this phase is just completely pointless.
+        
+        This phase is also the primary user of NodeDoesNotExit, which is a flag that the CFA
+        computes. It computes it poorly and we often get bugs in it. It's also a lot of code to
+        maintain.
+        
+        This patch does introduce a new mayExit() calculator that is independent of the CFA and
+        should be enough for most of the previous NodeDoesNotExit users. Currently it's only used
+        for assertions in the DFG backend, but we could use it if we ever brought back any of the
+        other optimizations that previously relied upon NodeDoesNotExit.
+        
+        This is performance-neutral, except for SunSpider, where it's a speed-up.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::filterEdgeByUse):
+        (JSC::DFG::AbstractInterpreter::filterByType):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::startExecuting):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::CSEPhase):
+        (JSC::DFG::CSEPhase::invalidationPointElimination):
+        (JSC::DFG::CSEPhase::setLocalStoreElimination):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        (JSC::DFG::CSEPhase::performBlockCSE):
+        (JSC::DFG::performCSE):
+        (JSC::DFG::CSEPhase::globalVarStoreElimination): Deleted.
+        (JSC::DFG::CSEPhase::scopedVarStoreElimination): Deleted.
+        (JSC::DFG::CSEPhase::putStructureStoreElimination): Deleted.
+        (JSC::DFG::CSEPhase::putByOffsetStoreElimination): Deleted.
+        (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): Deleted.
+        (JSC::DFG::performStoreElimination): Deleted.
+        * dfg/DFGCSEPhase.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::resetExitStates): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGMayExit.cpp: Added.
+        (JSC::DFG::mayExit):
+        * dfg/DFGMayExit.h: Added.
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::mergeFlags):
+        (JSC::DFG::Node::filterFlags):
+        (JSC::DFG::Node::setCanExit): Deleted.
+        (JSC::DFG::Node::canExit): Deleted.
+        * dfg/DFGNodeFlags.cpp:
+        (JSC::DFG::dumpNodeFlags):
+        * dfg/DFGNodeFlags.h:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+        (JSC::DFG::SpeculativeJIT::bail):
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-06-15  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] Remove the DFG optimization fixpoint and remove some obvious reasons why we previously benefited from it
+        https://bugs.webkit.org/show_bug.cgi?id=133931
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Trigger constant-folding for GetMyArgumentByVal (which means turning it into GetLocalUnlinked) and correct the handling of Upsilon so we don't fold them away.
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants): Implement constant-folding for GetMyArgumentByVal.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl): Remove the fixpoint.
+
+2014-06-15  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] DFG OSR entry should have a crystal-clear story for when it's safe to enter at a block with a set of values
+        https://bugs.webkit.org/show_bug.cgi?id=133935
+
+        Reviewed by Oliver Hunt.
+
+        * bytecode/Operands.h:
+        (JSC::Operands::Operands):
+        (JSC::Operands::ensureLocals):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::filter): Now we can compute intersections of abstract values!
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::makeFullTop): Completeness.
+        (JSC::DFG::AbstractValue::bytecodeTop): Completeness.
+        (JSC::DFG::AbstractValue::fullTop): Completeness. We end up using this one.
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::BasicBlock):
+        (JSC::DFG::BasicBlock::ensureLocals):
+        * dfg/DFGBasicBlock.h: Remember the intersection of all things ever proven.
+        * dfg/DFGCFAPhase.cpp:
+        (JSC::DFG::CFAPhase::run): Compute the intersection.
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants): No need for the weirdo merge check since this fixes the root of the problem.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dumpBlockHeader): Better dumping.
+        (JSC::DFG::Graph::dump): Better dumping.
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::noticeOSREntry): Use the intersected abstract value.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock): Assert if the intersected state indicates the block shouldn't execute.
+
+2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants
+        https://bugs.webkit.org/show_bug.cgi?id=133821
+
+        Reviewed by Mark Hahnenberg.
+        
+        This allows us to efficiently cache accesses that differ only in the prototypes on the path
+        from the base to the prototype that has the field.
+        
+        It also simplifies a bunch of code - IntendedStructureChain is now just an intermediate
+        data structure.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/ConstantStructureCheck.cpp: Added.
+        (JSC::ConstantStructureCheck::dumpInContext):
+        (JSC::ConstantStructureCheck::dump):
+        (JSC::structureFor):
+        (JSC::areCompatible):
+        (JSC::mergeInto):
+        * bytecode/ConstantStructureCheck.h: Added.
+        (JSC::ConstantStructureCheck::ConstantStructureCheck):
+        (JSC::ConstantStructureCheck::operator!):
+        (JSC::ConstantStructureCheck::constant):
+        (JSC::ConstantStructureCheck::structure):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/GetByIdVariant.cpp:
+        (JSC::GetByIdVariant::GetByIdVariant):
+        (JSC::GetByIdVariant::operator=):
+        (JSC::GetByIdVariant::attemptToMerge):
+        (JSC::GetByIdVariant::dumpInContext):
+        * bytecode/GetByIdVariant.h:
+        (JSC::GetByIdVariant::constantChecks):
+        (JSC::GetByIdVariant::alternateBase):
+        (JSC::GetByIdVariant::GetByIdVariant): Deleted.
+        (JSC::GetByIdVariant::chain): Deleted.
+        * bytecode/PutByIdVariant.cpp:
+        (JSC::PutByIdVariant::dumpInContext):
+        * bytecode/PutByIdVariant.h:
+        (JSC::PutByIdVariant::transition):
+        (JSC::PutByIdVariant::constantChecks):
+        (JSC::PutByIdVariant::structureChain): Deleted.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitChecks):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck): Deleted.
+        (JSC::DFG::ByteCodeParser::structureChainIsStillValid): Deleted.
+        (JSC::DFG::ByteCodeParser::emitPrototypeChecks): Deleted.
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+        * dfg/DFGDesiredStructureChains.cpp: Removed.
+        * dfg/DFGDesiredStructureChains.h: Removed.
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::watchpoints):
+        (JSC::DFG::Graph::chains): Deleted.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::isStillValid):
+        (JSC::DFG::Plan::checkLivenessAndVisitChildren):
+        (JSC::DFG::Plan::cancel):
+        * dfg/DFGPlan.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        * runtime/IntendedStructureChain.cpp:
+        (JSC::IntendedStructureChain::gatherChecks):
+        * runtime/IntendedStructureChain.h:
+        (JSC::IntendedStructureChain::at):
+        (JSC::IntendedStructureChain::operator[]):
+
+2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] Constant folding and strength reduction should work in SSA
+        https://bugs.webkit.org/show_bug.cgi?id=133839
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGAtTailAbstractState.cpp:
+        (JSC::DFG::AtTailAbstractState::AtTailAbstractState):
+        (JSC::DFG::AtTailAbstractState::forNode):
+        * dfg/DFGAtTailAbstractState.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::convertToConstant):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend): Fix an unrelated regression that this uncovered.
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::LICMPhase):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+
+2014-06-11  Filip Pizlo  <fpizlo@apple.com>
+
+        [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base
+        https://bugs.webkit.org/show_bug.cgi?id=133751
+
+        Reviewed by Mark Hahnenberg.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::appendVariant):
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/GetByIdVariant.cpp:
+        (JSC::GetByIdVariant::attemptToMerge):
+        * bytecode/GetByIdVariant.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * runtime/IntendedStructureChain.cpp:
+        (JSC::IntendedStructureChain::IntendedStructureChain):
+        (JSC::IntendedStructureChain::isStillValid):
+        (JSC::IntendedStructureChain::isNormalized):
+        (JSC::IntendedStructureChain::terminalPrototype):
+        (JSC::IntendedStructureChain::operator==):
+        (JSC::IntendedStructureChain::visitChildren):
+        (JSC::IntendedStructureChain::dumpInContext):
+        (JSC::IntendedStructureChain::chain): Deleted.
+        * runtime/IntendedStructureChain.h:
+        (JSC::IntendedStructureChain::prototype):
+        (JSC::IntendedStructureChain::operator!=):
+        (JSC::IntendedStructureChain::head): Deleted.
+
+2014-06-11  Matthew Mirman  <mmirman@apple.com>
+
+       Readded native calling to the FTL and Split the DFG nodes 
+       Call and Construct into NativeCall and NativeConstruct 
+       to better represent their semantics.
+       https://bugs.webkit.org/show_bug.cgi?id=133660
+
+       Reviewed by Filip Pizlo.
+
+       * dfg/DFGAbstractInterpreterInlines.h:
+       (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 
+       Added NativeCall and NativeConstruct case
+       * dfg/DFGByteCodeParser.cpp:
+       (JSC::DFG::ByteCodeParser::addCall): added NativeCall case. 
+       (JSC::DFG::ByteCodeParser::handleCall): 
+       set to return NativeCall or NativeConstruct instead of Call or Construct
+       in the presence of a native function.
+       * dfg/DFGClobberize.h:
+       (JSC::DFG::clobberize): added NativeCall and NativeConstruct case.
+       * dfg/DFGDoesGC.cpp:
+       (JSC::DFG::doesGC): added NativeCall and NativeConstruct case.
+       * dfg/DFGFixupPhase.cpp:
+       (JSC::DFG::FixupPhase::fixupNode): added NativeCall and NativeConstruct case.
+       * dfg/DFGNode.h:
+       (JSC::DFG::Node::hasHeapPrediction): added NativeCall and NativeConstruct case.
+       (JSC::DFG::Node::canBeKnownFunction): changed to NativeCall and NativeConstruct.
+       (JSC::DFG::Node::hasKnownFunction): changed to NativeCall and NativeConstruct.
+       * dfg/DFGNodeType.h: added NativeCall and NativeConstruct.
+       * dfg/DFGPredictionPropagationPhase.cpp:
+       (JSC::DFG::PredictionPropagationPhase::propagate): added NativeCall and NativeConstruct case.
+       * dfg/DFGSafeToExecute.h:
+       (JSC::DFG::safeToExecute): added NativeCall and NativeConstruct case.
+       * dfg/DFGSpeculativeJIT32_64.cpp:
+       (JSC::DFG::SpeculativeJIT::emitCall): ditto
+       (JSC::DFG::SpeculativeJIT::compile): ditto
+       * dfg/DFGSpeculativeJIT64.cpp:
+       (JSC::DFG::SpeculativeJIT::emitCall): ditto
+       (JSC::DFG::SpeculativeJIT::compile): ditto
+       * ftl/FTLCapabilities.cpp:
+       (JSC::FTL::canCompile): ditto
+       * ftl/FTLLowerDFGToLLVM.cpp:  
+       (JSC::FTL::LowerDFGToLLVM::lower): ditto
+       (JSC::FTL::LowerDFGToLLVM::compileNode): ditto.
+       (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct): Added.
+       (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct): removed NativeCall and NativeConstruct functionality.
+       (JSC::FTL::LowerDFGToLLVM::didOverflowStack): added NativeCall and NativeConstruct case.
+       * runtime/JSCJSValue.h: added JS_EXPORT_PRIVATE to toInteger as it is apparently needed.
+       
+2014-06-11  Matthew Mirman  <mmirman@apple.com>
+
+        Ensured Native Calls and Construct and associated checks 
+        are only emitted during ftl mode.
+        https://bugs.webkit.org/show_bug.cgi?id=133718
+        
+        Reviewed by Filip Pizlo.
+        
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleCall): Added check for ftl mode 
+        before attaching the native function to Call or Construct.
+        
+2014-06-10  Filip Pizlo  <fpizlo@apple.com>
+
+        [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 "freeze" 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<AbstractStateType>::executeEffects):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::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  <fpizlo@apple.com>
 
         Prediction propagator should make sure everyone knows that a variable that is in an argument position where other versions of that variable are not MachineInts cannot possibly be flushed as Int52
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
index eac7baa..aa19ac7 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
@@ -321,6 +321,7 @@
     <ClCompile Include="..\bytecode\CodeBlockJettisoningWatchpoint.cpp" />
     <ClCompile Include="..\bytecode\CodeOrigin.cpp" />
     <ClCompile Include="..\bytecode\CodeType.cpp" />
+    <ClCompile Include="..\bytecode\ConstantStructureCheck.cpp" />
     <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" />
     <ClCompile Include="..\bytecode\DFGExitProfile.cpp" />
     <ClCompile Include="..\bytecode\ExecutionCounter.cpp" />
@@ -382,7 +383,6 @@
     <ClCompile Include="..\dfg\DFGCSEPhase.cpp" />
     <ClCompile Include="..\dfg\DFGDCEPhase.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredIdentifiers.cpp" />
-    <ClCompile Include="..\dfg\DFGDesiredStructureChains.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredTransitions.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredWatchpoints.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredWeakReferences.cpp" />
@@ -397,6 +397,7 @@
     <ClCompile Include="..\dfg\DFGFixupPhase.cpp" />
     <ClCompile Include="..\dfg\DFGFlushedAt.cpp" />
     <ClCompile Include="..\dfg\DFGFlushFormat.cpp" />
+    <ClCompile Include="..\dfg\DFGFrozenValue.cpp" />
     <ClCompile Include="..\dfg\DFGFunctionWhitelist.cpp" />
     <ClCompile Include="..\dfg\DFGGraph.cpp" />
     <ClCompile Include="..\dfg\DFGGraphSafepoint.cpp" />
@@ -412,6 +413,7 @@
     <ClCompile Include="..\dfg\DFGLivenessAnalysisPhase.cpp" />
     <ClCompile Include="..\dfg\DFGLongLivedState.cpp" />
     <ClCompile Include="..\dfg\DFGLoopPreHeaderCreationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGMayExit.cpp" />
     <ClCompile Include="..\dfg\DFGMinifiedNode.cpp" />
     <ClCompile Include="..\dfg\DFGNaturalLoops.cpp" />
     <ClCompile Include="..\dfg\DFGNode.cpp" />
@@ -455,6 +457,7 @@
     <ClCompile Include="..\dfg\DFGUseKind.cpp" />
     <ClCompile Include="..\dfg\DFGValidate.cpp" />
     <ClCompile Include="..\dfg\DFGValueSource.cpp" />
+    <ClCompile Include="..\dfg\DFGValueStrength.cpp" />
     <ClCompile Include="..\dfg\DFGVariableAccessData.cpp" />
     <ClCompile Include="..\dfg\DFGVariableAccessDataDump.cpp" />
     <ClCompile Include="..\dfg\DFGVariableEvent.cpp" />
@@ -901,6 +904,7 @@
     <ClInclude Include="..\bytecode\CodeOrigin.h" />
     <ClInclude Include="..\bytecode\CodeType.h" />
     <ClInclude Include="..\bytecode\Comment.h" />
+    <ClInclude Include="..\bytecode\ConstantStructureCheck.h" />
     <ClInclude Include="..\bytecode\DataFormat.h" />
     <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" />
     <ClInclude Include="..\bytecode\DFGExitProfile.h" />
@@ -988,7 +992,6 @@
     <ClInclude Include="..\dfg\DFGCSEPhase.h" />
     <ClInclude Include="..\dfg\DFGDCEPhase.h" />
     <ClInclude Include="..\dfg\DFGDesiredIdentifiers.h" />
-    <ClInclude Include="..\dfg\DFGDesiredStructureChains.h" />
     <ClInclude Include="..\dfg\DFGDesiredTransitions.h" />
     <ClInclude Include="..\dfg\DFGDesiredWatchpoints.h" />
     <ClInclude Include="..\dfg\DFGDesiredWeakReferences.h" />
@@ -1008,6 +1011,7 @@
     <ClInclude Include="..\dfg\DFGFlushedAt.h" />
     <ClInclude Include="..\dfg\DFGFlushFormat.h" />
     <ClInclude Include="..\dfg\DFGFPRInfo.h" />
+    <ClInclude Include="..\dfg\DFGFrozenValue.h" />
     <ClInclude Include="..\dfg\DFGFunctionWhitelist.h" />
     <ClInclude Include="..\dfg\DFGGenerationInfo.h" />
     <ClInclude Include="..\dfg\DFGGPRInfo.h" />
@@ -1026,6 +1030,7 @@
     <ClInclude Include="..\dfg\DFGLivenessAnalysisPhase.h" />
     <ClInclude Include="..\dfg\DFGLongLivedState.h" />
     <ClInclude Include="..\dfg\DFGLoopPreHeaderCreationPhase.h" />
+    <ClInclude Include="..\dfg\DFGMayExit.h" />
     <ClInclude Include="..\dfg\DFGMergeMode.h" />
     <ClInclude Include="..\dfg\DFGMinifiedGraph.h" />
     <ClInclude Include="..\dfg\DFGMinifiedID.h" />
@@ -1083,6 +1088,7 @@
     <ClInclude Include="..\dfg\DFGValidate.h" />
     <ClInclude Include="..\dfg\DFGValueRecoveryOverride.h" />
     <ClInclude Include="..\dfg\DFGValueSource.h" />
+    <ClInclude Include="..\dfg\DFGValueStrength.h" />
     <ClInclude Include="..\dfg\DFGVariableAccessData.h" />
     <ClInclude Include="..\dfg\DFGVariableAccessDataDump.h" />
     <ClInclude Include="..\dfg\DFGVariableEvent.h" />
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 468f5ca..e455140 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -74,6 +74,8 @@
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+		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, ); }; };
 		0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0332BF18ADFAE1005F979A /* ExitingJITType.cpp */; };
 		0F0332C318B01763005F979A /* GetByIdVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0332C118B01763005F979A /* GetByIdVariant.cpp */; };
 		0F0332C418B01763005F979A /* GetByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0332C218B01763005F979A /* GetByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -252,6 +254,8 @@
 		0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */; };
 		0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */; };
+		0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -293,6 +297,8 @@
 		0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */; };
 		0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5780A118FE1E98001E72D9 /* PureNaN.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */; };
+		0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F5A1273192D9FDF008764A3 /* DFGDoesGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */; };
 		0F5A1274192D9FDF008764A3 /* DFGDoesGC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A52CF17ADD717008ECB2D /* CopyToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -319,6 +325,8 @@
 		0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		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, ); }; };
 		0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */; };
 		0F6B1CB6185FC9E900845D97 /* FTLJSCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1725,8 +1733,6 @@
 		A7386556118697B400540279 /* ThunkGenerators.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386553118697B400540279 /* ThunkGenerators.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */; };
 		A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */; };
-		A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */ = {isa = PBXBuildFile; fileRef = A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; };
@@ -2242,6 +2248,8 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValueStrength.cpp; path = dfg/DFGValueStrength.cpp; sourceTree = "<group>"; };
+		0F0123311944EA1B00843A0C /* DFGValueStrength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValueStrength.h; path = dfg/DFGValueStrength.h; sourceTree = "<group>"; };
 		0F0332BF18ADFAE1005F979A /* ExitingJITType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitingJITType.cpp; sourceTree = "<group>"; };
 		0F0332C118B01763005F979A /* GetByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetByIdVariant.cpp; sourceTree = "<group>"; };
 		0F0332C218B01763005F979A /* GetByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetByIdVariant.h; sourceTree = "<group>"; };
@@ -2419,6 +2427,8 @@
 		0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFGSimplificationPhase.h; path = dfg/DFGCFGSimplificationPhase.h; sourceTree = "<group>"; };
 		0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValidate.cpp; path = dfg/DFGValidate.cpp; sourceTree = "<group>"; };
 		0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValidate.h; path = dfg/DFGValidate.h; sourceTree = "<group>"; };
+		0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantStructureCheck.cpp; sourceTree = "<group>"; };
+		0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantStructureCheck.h; sourceTree = "<group>"; };
 		0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; };
 		0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; };
 		0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; };
@@ -2461,6 +2471,8 @@
 		0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionCounter.cpp; sourceTree = "<group>"; };
 		0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerator.h; sourceTree = "<group>"; };
 		0F5780A118FE1E98001E72D9 /* PureNaN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PureNaN.h; sourceTree = "<group>"; };
+		0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMayExit.cpp; path = dfg/DFGMayExit.cpp; sourceTree = "<group>"; };
+		0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMayExit.h; path = dfg/DFGMayExit.h; sourceTree = "<group>"; };
 		0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDoesGC.cpp; path = dfg/DFGDoesGC.cpp; sourceTree = "<group>"; };
 		0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDoesGC.h; path = dfg/DFGDoesGC.h; sourceTree = "<group>"; };
 		0F5A52CF17ADD717008ECB2D /* CopyToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyToken.h; sourceTree = "<group>"; };
@@ -2487,6 +2499,8 @@
 		0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGResurrectionForValidationPhase.h; path = dfg/DFGResurrectionForValidationPhase.h; sourceTree = "<group>"; };
 		0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
 		0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
+		0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFrozenValue.cpp; path = dfg/DFGFrozenValue.cpp; sourceTree = "<group>"; };
+		0F69CC87193AC60A0045759E /* DFGFrozenValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFrozenValue.h; path = dfg/DFGFrozenValue.h; sourceTree = "<group>"; };
 		0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLJSCall.cpp; path = ftl/FTLJSCall.cpp; sourceTree = "<group>"; };
 		0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLJSCall.h; path = ftl/FTLJSCall.h; sourceTree = "<group>"; };
 		0F6B1CB71861244C00845D97 /* ArityCheckMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckMode.h; sourceTree = "<group>"; };
@@ -3371,8 +3385,6 @@
 		A7386553118697B400540279 /* ThunkGenerators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerators.h; sourceTree = "<group>"; };
 		A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyJSValue.cpp; path = dfg/DFGLazyJSValue.cpp; sourceTree = "<group>"; };
 		A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyJSValue.h; path = dfg/DFGLazyJSValue.h; sourceTree = "<group>"; };
-		A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredStructureChains.cpp; path = dfg/DFGDesiredStructureChains.cpp; sourceTree = "<group>"; };
-		A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredStructureChains.h; path = dfg/DFGDesiredStructureChains.h; sourceTree = "<group>"; };
 		A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSaneStringGetByValSlowPathGenerator.h; path = dfg/DFGSaneStringGetByValSlowPathGenerator.h; sourceTree = "<group>"; };
 		A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefPrivate.h; sourceTree = "<group>"; };
 		A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectMapRefPrivate.cpp; sourceTree = "<group>"; };
@@ -5052,8 +5064,6 @@
 				0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */,
 				0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */,
 				0F8F2B98172F04FD007DBDA5 /* DFGDesiredIdentifiers.h */,
-				A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */,
-				A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */,
 				C2C0F7CB17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp */,
 				C2C0F7CC17BBFC5B00464FE4 /* DFGDesiredTransitions.h */,
 				0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */,
@@ -5086,6 +5096,8 @@
 				0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */,
 				A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
 				A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
+				0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */,
+				0F69CC87193AC60A0045759E /* DFGFrozenValue.h */,
 				2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
 				2A88067719107D5500CB0BBB /* DFGFunctionWhitelist.h */,
 				86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */,
@@ -5120,6 +5132,8 @@
 				0FB4B51D16B62772003F696B /* DFGLongLivedState.h */,
 				A767B5B317A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp */,
 				A767B5B417A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h */,
+				0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */,
+				0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */,
 				A704D90217A0BAA8006BA554 /* DFGMergeMode.h */,
 				0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */,
 				0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
@@ -5218,6 +5232,8 @@
 				0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,
 				0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */,
 				0F2BDC401522801700CD8910 /* DFGValueSource.h */,
+				0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */,
+				0F0123311944EA1B00843A0C /* DFGValueStrength.h */,
 				0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */,
 				0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */,
 				0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */,
@@ -5363,6 +5379,8 @@
 				0FBD7E671447998F00481315 /* CodeOrigin.h */,
 				0F8F943F1667632D00D61971 /* CodeType.cpp */,
 				0F0B83A514BCF50400885B4F /* CodeType.h */,
+				0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */,
+				0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */,
 				0F426A4A1460CD6B00131F8F /* DataFormat.h */,
 				0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */,
 				0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */,
@@ -5949,6 +5967,7 @@
 				0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
 				0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
 				0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
+				0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
 				0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */,
 				BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
 				0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
@@ -6044,7 +6063,6 @@
 				0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
 				0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */,
 				0F8F2B9A172F0501007DBDA5 /* DFGDesiredIdentifiers.h in Headers */,
-				A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */,
 				C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */,
 				0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */,
 				C2981FD917BAEE4B00A3BC98 /* DFGDesiredWeakReferences.h in Headers */,
@@ -6146,6 +6164,7 @@
 				A70447EE17A0BD7000F5898E /* DumpContext.h in Headers */,
 				99E45A2418A1B2590026D88F /* EmptyInputCursor.h in Headers */,
 				99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */,
+				0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */,
 				BC3046070E1F497F003232CF /* Error.h in Headers */,
 				BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
 				FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */,
@@ -6461,6 +6480,7 @@
 				FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
 				0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
 				0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
+				0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
 				0FCEFACE1805E75500472CE4 /* LLVMAPI.h in Headers */,
 				0FCEFACF1805E75500472CE4 /* LLVMAPIFunctions.h in Headers */,
 				A7E5AB381799E4B200D2833D /* LLVMDisassembler.h in Headers */,
@@ -6495,6 +6515,7 @@
 				BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
 				90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
 				0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
+				0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */,
 				7C008CE7187631B600955C24 /* Microtask.h in Headers */,
 				86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */,
 				86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */,
@@ -7558,6 +7579,7 @@
 				147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
 				0F24E54017EA9F5900ABB217 /* AssemblyHelpers.cpp in Sources */,
 				14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
+				0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */,
 				14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
 				14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
 				14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
@@ -7632,7 +7654,6 @@
 				0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
 				0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
 				0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */,
-				A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */,
 				C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */,
 				0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */,
 				C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */,
@@ -7642,6 +7663,7 @@
 				0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
 				0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
 				0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
+				0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */,
 				A78A9774179738B8009DF744 /* DFGFailedFinalizer.cpp in Sources */,
 				A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */,
 				0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
@@ -7708,6 +7730,7 @@
 				0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */,
 				0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */,
 				0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
+				0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */,
 				0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
 				0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
 				0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
@@ -7870,6 +7893,7 @@
 				A503FA1B188E0FB000110F14 /* JSJavaScriptCallFrame.cpp in Sources */,
 				A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */,
 				14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */,
+				0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */,
 				C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
 				A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */,
 				A74DEF95182D991400522C22 /* JSMapIterator.cpp in Sources */,
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
index 63953d5..265ef15b 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
@@ -143,7 +143,6 @@
 #if ENABLE(DFG_JIT)
     exitSiteData.m_takesSlowPath =
         profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitingJITType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitingJITType))
         || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable, exitingJITType));
     exitSiteData.m_badFunction =
         profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction, exitingJITType));
diff --git a/Source/JavaScriptCore/bytecode/ConstantStructureCheck.cpp b/Source/JavaScriptCore/bytecode/ConstantStructureCheck.cpp
new file mode 100644
index 0000000..d755c06
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ConstantStructureCheck.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 "config.h"
+#include "ConstantStructureCheck.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+void ConstantStructureCheck::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    out.print(
+        "(Check if ", inContext(JSValue(m_constant), context), " has structure ",
+        pointerDumpInContext(m_structure, context), ")");
+}
+
+void ConstantStructureCheck::dump(PrintStream& out) const
+{
+    dumpInContext(out, nullptr);
+}
+
+Structure* structureFor(const ConstantStructureCheckVector& vector, JSCell* constant)
+{
+    for (unsigned i = vector.size(); i--;) {
+        if (vector[i].constant() == constant)
+            return vector[i].structure();
+    }
+    return nullptr;
+}
+
+bool areCompatible(const ConstantStructureCheckVector& a, const ConstantStructureCheckVector& b)
+{
+    for (unsigned i = a.size(); i--;) {
+        Structure* otherStructure = structureFor(b, a[i].constant());
+        if (!otherStructure)
+            continue;
+        if (a[i].structure() != otherStructure)
+            return false;
+    }
+    return true;
+}
+
+void mergeInto(const ConstantStructureCheckVector& source, ConstantStructureCheckVector& target)
+{
+    for (unsigned i = source.size(); i--;) {
+        if (structureFor(target, source[i].constant()))
+            continue;
+        target.append(source[i]);
+    }
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/ConstantStructureCheck.h b/Source/JavaScriptCore/bytecode/ConstantStructureCheck.h
new file mode 100644
index 0000000..b200c95
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ConstantStructureCheck.h
@@ -0,0 +1,74 @@
+/*
+ * 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 ConstantStructureCheck_h
+#define ConstantStructureCheck_h
+
+#include "DumpContext.h"
+#include "JSCell.h"
+#include "Structure.h"
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class ConstantStructureCheck {
+public:
+    ConstantStructureCheck()
+        : m_constant(nullptr)
+        , m_structure(nullptr)
+    {
+    }
+    
+    ConstantStructureCheck(JSCell* constant, Structure* structure)
+        : m_constant(constant)
+        , m_structure(structure)
+    {
+        ASSERT(!!m_constant == !!m_structure);
+    }
+    
+    bool operator!() const { return !m_constant; }
+    
+    JSCell* constant() const { return m_constant; }
+    Structure* structure() const { return m_structure; }
+    
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
+    
+private:
+    JSCell* m_constant;
+    Structure* m_structure;
+};
+
+typedef Vector<ConstantStructureCheck, 2> ConstantStructureCheckVector;
+
+Structure* structureFor(const ConstantStructureCheckVector& vector, JSCell* constant);
+bool areCompatible(const ConstantStructureCheckVector&, const ConstantStructureCheckVector&);
+void mergeInto(const ConstantStructureCheckVector& source, ConstantStructureCheckVector& target);
+
+} // namespace JSC
+
+#endif // ConstantStructureCheck_h
+
diff --git a/Source/JavaScriptCore/bytecode/ExitKind.cpp b/Source/JavaScriptCore/bytecode/ExitKind.cpp
index 350aa58..efd7c10 100644
--- a/Source/JavaScriptCore/bytecode/ExitKind.cpp
+++ b/Source/JavaScriptCore/bytecode/ExitKind.cpp
@@ -44,12 +44,8 @@
         return "BadExecutable";
     case BadCache:
         return "BadCache";
-    case BadCacheWatchpoint:
-        return "BadCacheWatchpoint";
-    case BadWeakConstantCache:
-        return "BadWeakConstantCache";
-    case BadWeakConstantCacheWatchpoint:
-        return "BadWeakConstantCacheWatchpoint";
+    case BadConstantCache:
+        return "BadConstantCache";
     case BadIndexingType:
         return "BadIndexingType";
     case Overflow:
@@ -72,8 +68,6 @@
         return "NotStringObject";
     case Uncountable:
         return "Uncountable";
-    case UncountableWatchpoint:
-        return "UncountableWatchpoint";
     case UncountableInvalidation:
         return "UncountableInvalidation";
     case WatchdogTimerFired:
@@ -92,7 +86,6 @@
         RELEASE_ASSERT_NOT_REACHED();
     case BadType:
     case Uncountable:
-    case UncountableWatchpoint:
     case LoadFromHole: // Already counted directly by the baseline JIT.
     case StoreToHole: // Already counted directly by the baseline JIT.
     case OutOfBounds: // Already counted directly by the baseline JIT.
diff --git a/Source/JavaScriptCore/bytecode/ExitKind.h b/Source/JavaScriptCore/bytecode/ExitKind.h
index 6ac78a2..5296812 100644
--- a/Source/JavaScriptCore/bytecode/ExitKind.h
+++ b/Source/JavaScriptCore/bytecode/ExitKind.h
@@ -34,9 +34,7 @@
     BadFunction, // We exited because we made an incorrect assumption about what function we would see.
     BadExecutable, // We exited because we made an incorrect assumption about what executable we would see.
     BadCache, // We exited because an inline cache was wrong.
-    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.
+    BadConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
     BadIndexingType, // We exited because an indexing type was wrong.
     Overflow, // We exited because of overflow.
     NegativeZero, // We exited because we encountered negative zero.
@@ -49,7 +47,6 @@
     NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
     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.
     UncountableInvalidation, // We exited because the code block was invalidated; this means that we've already counted the reasons why the code block was invalidated.
-    UncountableWatchpoint, // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
     WatchdogTimerFired, // We exited because we need to service the watchdog timer.
     DebuggerEvent // We exited because we need to service the debugger.
 };
@@ -57,18 +54,6 @@
 const char* exitKindToString(ExitKind);
 bool exitKindIsCountable(ExitKind);
 
-inline bool isWatchpoint(ExitKind kind)
-{
-    switch (kind) {
-    case BadCacheWatchpoint:
-    case BadWeakConstantCacheWatchpoint:
-    case UncountableWatchpoint:
-        return true;
-    default:
-        return false;
-    }
-}
-
 } // namespace JSC
 
 namespace WTF {
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
index 7bb0f3f..969acda 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
@@ -39,10 +39,20 @@
 
 bool GetByIdStatus::appendVariant(const GetByIdVariant& variant)
 {
+    // Attempt to merge this variant with an already existing variant.
+    for (unsigned i = 0; i < m_variants.size(); ++i) {
+        if (m_variants[i].attemptToMerge(variant))
+            return true;
+    }
+    
+    // Make sure there is no overlap. We should have pruned out opportunities for
+    // overlap but it's possible that an inline cache got into a weird state. We are
+    // defensive and bail if we detect crazy.
     for (unsigned i = 0; i < m_variants.size(); ++i) {
         if (m_variants[i].structureSet().overlaps(variant.structureSet()))
             return false;
     }
+    
     m_variants.append(variant);
     return true;
 }
@@ -51,9 +61,7 @@
 bool GetByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType jitType)
 {
     return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, jitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, jitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, jitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, jitType));
+        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache, jitType));
 }
 #endif
 
@@ -185,10 +193,12 @@
                     profiledBlock, structure, list->at(listIndex).chain(),
                     list->at(listIndex).chainCount()));
                 
-                if (!chain->isStillValid())
-                    return GetByIdStatus(slowPathState, true);
+                if (!chain->isStillValid()) {
+                    // This won't ever run again so skip it.
+                    continue;
+                }
                 
-                if (chain->head()->takesSlowPathInDFGForImpureProperty())
+                if (structure->takesSlowPathInDFGForImpureProperty())
                     return GetByIdStatus(slowPathState, true);
                 
                 size_t chainSize = chain->size();
@@ -215,35 +225,6 @@
             
             if (!isValidOffset(myOffset))
                 return GetByIdStatus(slowPathState, true);
-
-            if (!chain && !list->at(listIndex).doesCalls()) {
-                // For non-chain, non-getter accesses, we try to do some coalescing.
-                bool found = false;
-                for (unsigned variantIndex = 0; variantIndex < result.m_variants.size(); ++variantIndex) {
-                    GetByIdVariant& variant = result.m_variants[variantIndex];
-                    if (variant.m_chain)
-                        continue;
-                
-                    if (variant.m_offset != myOffset)
-                        continue;
-                
-                    if (variant.callLinkStatus())
-                        continue;
-                
-                    found = true;
-                    if (variant.m_structureSet.contains(structure))
-                        break;
-                
-                    if (variant.m_specificValue != JSValue(specificValue))
-                        variant.m_specificValue = JSValue();
-                
-                    variant.m_structureSet.add(structure);
-                    break;
-                }
-            
-                if (found)
-                    continue;
-            }
             
             std::unique_ptr<CallLinkStatus> callLinkStatus;
             switch (list->at(listIndex).type()) {
@@ -270,8 +251,9 @@
             }
             
             GetByIdVariant variant(
-                StructureSet(structure), myOffset, specificValue, chain,
+                StructureSet(structure), myOffset, specificValue, chain.get(),
                 std::move(callLinkStatus));
+            
             if (!result.appendVariant(variant))
                 return GetByIdStatus(slowPathState, true);
         }
diff --git a/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp b/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp
index 7c7e128..92b98b6 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp
+++ b/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp
@@ -28,9 +28,31 @@
 
 #include "CallLinkStatus.h"
 #include "JSCInlines.h"
+#include <wtf/ListDump.h>
 
 namespace JSC {
 
+GetByIdVariant::GetByIdVariant(
+    const StructureSet& structureSet, PropertyOffset offset, JSValue specificValue,
+    const IntendedStructureChain* chain, std::unique_ptr<CallLinkStatus> callLinkStatus)
+    : m_structureSet(structureSet)
+    , m_alternateBase(nullptr)
+    , m_specificValue(specificValue)
+    , m_offset(offset)
+    , m_callLinkStatus(std::move(callLinkStatus))
+{
+    if (!structureSet.size()) {
+        ASSERT(offset == invalidOffset);
+        ASSERT(!specificValue);
+        ASSERT(!chain);
+    }
+    
+    if (chain && chain->size()) {
+        m_alternateBase = chain->terminalPrototype();
+        chain->gatherChecks(m_constantChecks);
+    }
+}
+
 GetByIdVariant::~GetByIdVariant() { }
 
 GetByIdVariant::GetByIdVariant(const GetByIdVariant& other)
@@ -41,7 +63,8 @@
 GetByIdVariant& GetByIdVariant::operator=(const GetByIdVariant& other)
 {
     m_structureSet = other.m_structureSet;
-    m_chain = other.m_chain;
+    m_constantChecks = other.m_constantChecks;
+    m_alternateBase = other.m_alternateBase;
     m_specificValue = other.m_specificValue;
     m_offset = other.m_offset;
     if (other.m_callLinkStatus)
@@ -51,6 +74,26 @@
     return *this;
 }
 
+bool GetByIdVariant::attemptToMerge(const GetByIdVariant& other)
+{
+    if (m_alternateBase != other.m_alternateBase)
+        return false;
+    if (m_offset != other.m_offset)
+        return false;
+    if (m_callLinkStatus || other.m_callLinkStatus)
+        return false;
+    if (!areCompatible(m_constantChecks, other.m_constantChecks))
+        return false;
+    
+    if (m_specificValue != other.m_specificValue)
+        m_specificValue = JSValue();
+
+    mergeInto(other.m_constantChecks, m_constantChecks);
+    m_structureSet.merge(other.m_structureSet);
+    
+    return true;
+}
+
 void GetByIdVariant::dump(PrintStream& out) const
 {
     dumpInContext(out, 0);
@@ -65,10 +108,12 @@
     
     out.print(
         "<", inContext(structureSet(), context), ", ",
-        pointerDumpInContext(chain(), context), ", ",
-        inContext(specificValue(), context), ", ", offset());
+        "[", listDumpInContext(m_constantChecks, context), "], ",
+        "alternateBase = ", inContext(JSValue(m_alternateBase), context), ", ",
+        "specificValue = ", inContext(specificValue(), context), ", ",
+        "offset = ", offset());
     if (m_callLinkStatus)
-        out.print("call: ", *m_callLinkStatus);
+        out.print("call = ", *m_callLinkStatus);
     out.print(">");
 }
 
diff --git a/Source/JavaScriptCore/bytecode/GetByIdVariant.h b/Source/JavaScriptCore/bytecode/GetByIdVariant.h
index f30448b..9593a40 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdVariant.h
+++ b/Source/JavaScriptCore/bytecode/GetByIdVariant.h
@@ -27,6 +27,7 @@
 #define GetByIdVariant_h
 
 #include "CallLinkStatus.h"
+#include "ConstantStructureCheck.h"
 #include "IntendedStructureChain.h"
 #include "JSCJSValue.h"
 #include "PropertyOffset.h"
@@ -43,20 +44,8 @@
     GetByIdVariant(
         const StructureSet& structureSet = StructureSet(),
         PropertyOffset offset = invalidOffset, JSValue specificValue = JSValue(),
-        PassRefPtr<IntendedStructureChain> chain = nullptr,
-        std::unique_ptr<CallLinkStatus> callLinkStatus = nullptr)
-        : m_structureSet(structureSet)
-        , m_chain(chain)
-        , m_specificValue(specificValue)
-        , m_offset(offset)
-        , m_callLinkStatus(std::move(callLinkStatus))
-    {
-        if (!structureSet.size()) {
-            ASSERT(offset == invalidOffset);
-            ASSERT(!specificValue);
-            ASSERT(!chain);
-        }
-    }
+        const IntendedStructureChain* chain = nullptr,
+        std::unique_ptr<CallLinkStatus> callLinkStatus = nullptr);
     
     ~GetByIdVariant();
     
@@ -66,11 +55,14 @@
     bool isSet() const { return !!m_structureSet.size(); }
     bool operator!() const { return !isSet(); }
     const StructureSet& structureSet() const { return m_structureSet; }
-    IntendedStructureChain* chain() const { return const_cast<IntendedStructureChain*>(m_chain.get()); }
+    const ConstantStructureCheckVector& constantChecks() const { return m_constantChecks; }
+    JSObject* alternateBase() const { return m_alternateBase; }
     JSValue specificValue() const { return m_specificValue; }
     PropertyOffset offset() const { return m_offset; }
     CallLinkStatus* callLinkStatus() const { return m_callLinkStatus.get(); }
     
+    bool attemptToMerge(const GetByIdVariant& other);
+    
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     
@@ -78,7 +70,8 @@
     friend class GetByIdStatus;
     
     StructureSet m_structureSet;
-    RefPtr<IntendedStructureChain> m_chain;
+    ConstantStructureCheckVector m_constantChecks;
+    JSObject* m_alternateBase;
     JSValue m_specificValue;
     PropertyOffset m_offset;
     std::unique_ptr<CallLinkStatus> m_callLinkStatus;
diff --git a/Source/JavaScriptCore/bytecode/Operands.h b/Source/JavaScriptCore/bytecode/Operands.h
index f21e05f5..92a9564 100644
--- a/Source/JavaScriptCore/bytecode/Operands.h
+++ b/Source/JavaScriptCore/bytecode/Operands.h
@@ -52,10 +52,10 @@
 public:
     Operands() { }
     
-    explicit Operands(size_t numArguments, size_t numLocals)
+    explicit Operands(size_t numArguments, size_t numLocals, const T& initialValue = Traits::defaultValue())
     {
-        m_arguments.fill(Traits::defaultValue(), numArguments);
-        m_locals.fill(Traits::defaultValue(), numLocals);
+        m_arguments.fill(initialValue, numArguments);
+        m_locals.fill(initialValue, numLocals);
     }
     
     template<typename U, typename OtherTraits>
@@ -96,7 +96,7 @@
         return local(idx);
     }
     
-    void ensureLocals(size_t size)
+    void ensureLocals(size_t size, const T& ensuredValue = Traits::defaultValue())
     {
         if (size <= m_locals.size())
             return;
@@ -104,7 +104,7 @@
         size_t oldSize = m_locals.size();
         m_locals.resize(size);
         for (size_t i = oldSize; i < m_locals.size(); ++i)
-            m_locals[i] = Traits::defaultValue();
+            m_locals[i] = ensuredValue;
     }
     
     void setLocal(size_t idx, const T& value)
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
index 5743750..6f7cfea 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
@@ -51,9 +51,7 @@
 bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType exitType)
 {
     return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, exitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, exitType));
+        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache, exitType));
     
 }
 #endif
@@ -307,7 +305,7 @@
         // dictionaries if we have evidence to suggest that those objects were never used as
         // prototypes in a cacheable prototype access - i.e. there's a good chance that some of
         // the other checks below will fail.
-        if (!chain->isNormalized())
+        if (structure->isProxy() || !chain->isNormalized())
             return PutByIdStatus(TakesSlowPath);
     }
     
diff --git a/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp b/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
index f83c102..5f1c338 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdVariant.cpp
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "PutByIdVariant.h"
 
+#include <wtf/ListDump.h>
+
 namespace JSC {
 
 void PutByIdVariant::dump(PrintStream& out) const
@@ -48,8 +50,8 @@
     case Transition:
         out.print(
             "<Transition: ", pointerDumpInContext(oldStructure(), context), " -> ",
-            pointerDumpInContext(newStructure(), context), ", ",
-            pointerDumpInContext(structureChain(), context), ", ", offset(), ">");
+            pointerDumpInContext(newStructure(), context), ", [",
+            listDumpInContext(constantChecks(), context), "], ", offset(), ">");
         return;
     }
     
diff --git a/Source/JavaScriptCore/bytecode/PutByIdVariant.h b/Source/JavaScriptCore/bytecode/PutByIdVariant.h
index eba95e8..68a3391 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdVariant.h
+++ b/Source/JavaScriptCore/bytecode/PutByIdVariant.h
@@ -64,7 +64,8 @@
         result.m_kind = Transition;
         result.m_oldStructure = oldStructure;
         result.m_newStructure = newStructure;
-        result.m_structureChain = structureChain;
+        if (structureChain)
+            structureChain->gatherChecks(result.m_constantChecks);
         result.m_offset = offset;
         return result;
     }
@@ -92,10 +93,10 @@
         return m_newStructure;
     }
     
-    IntendedStructureChain* structureChain() const
+    const ConstantStructureCheckVector& constantChecks() const
     {
         ASSERT(kind() == Transition);
-        return m_structureChain.get();
+        return m_constantChecks;
     }
     
     PropertyOffset offset() const
@@ -111,7 +112,7 @@
     Kind m_kind;
     Structure* m_oldStructure;
     Structure* m_newStructure;
-    RefPtr<IntendedStructureChain> m_structureChain;
+    ConstantStructureCheckVector m_constantChecks;
     PropertyOffset m_offset;
 };
 
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
index 01f5a48..75fd621 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
@@ -88,12 +88,8 @@
     bool execute(unsigned indexInBlock);
     bool execute(Node*);
     
-    // Indicate the start of execution of the node. It resets any state in the node,
-    // that is progressively built up by executeEdges() and executeEffects(). In
-    // particular, this resets canExit(), so if you want to "know" between calls of
-    // startExecuting() and executeEdges()/Effects() whether the last run of the
-    // analysis concluded that the node can exit, you should probably set that
-    // information aside prior to calling startExecuting().
+    // Indicate the start of execution of the node. It resets any state in the node
+    // that is progressively built up by executeEdges() and executeEffects().
     bool startExecuting(Node*);
     bool startExecuting(unsigned indexInBlock);
     
@@ -103,10 +99,14 @@
     void executeEdges(Node*);
     void executeEdges(unsigned indexInBlock);
     
-    ALWAYS_INLINE void filterEdgeByUse(Node* node, Edge& edge)
+    ALWAYS_INLINE void filterEdgeByUse(Edge& edge)
     {
         ASSERT(mayHaveTypeCheck(edge.useKind()) || !needsTypeCheck(edge));
-        filterByType(node, edge, typeFilterFor(edge.useKind()));
+        filterByType(edge, typeFilterFor(edge.useKind()));
+    }
+    ALWAYS_INLINE void filterEdgeByUse(Node*, Edge& edge)
+    {
+        filterEdgeByUse(edge);
     }
     
     // Abstractly execute the effects of the given node. This changes the abstract
@@ -136,7 +136,7 @@
     }
     
     template<typename T>
-    FiltrationResult filterByValue(T node, JSValue value)
+    FiltrationResult filterByValue(T node, FrozenValue value)
     {
         return filterByValue(forNode(node), value);
     }
@@ -144,7 +144,7 @@
     FiltrationResult filter(AbstractValue&, const StructureSet&);
     FiltrationResult filterArrayModes(AbstractValue&, ArrayModes);
     FiltrationResult filter(AbstractValue&, SpeculatedType);
-    FiltrationResult filterByValue(AbstractValue&, JSValue);
+    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
     
 private:
     void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
@@ -165,26 +165,25 @@
     };
     BooleanResult booleanResult(Node*, AbstractValue&);
     
-    void setBuiltInConstant(Node* node, JSValue value)
+    void setBuiltInConstant(Node* node, FrozenValue value)
     {
         AbstractValue& abstractValue = forNode(node);
         abstractValue.set(m_graph, value, m_state.structureClobberState());
         abstractValue.fixTypeForRepresentation(node);
     }
     
-    void setConstant(Node* node, JSValue value)
+    void setConstant(Node* node, FrozenValue value)
     {
         setBuiltInConstant(node, value);
         m_state.setFoundConstants(true);
     }
     
-    ALWAYS_INLINE void filterByType(Node* node, Edge& edge, SpeculatedType type)
+    ALWAYS_INLINE void filterByType(Edge& edge, SpeculatedType type)
     {
         AbstractValue& value = forNode(edge);
-        if (!value.isType(type)) {
-            node->setCanExit(true);
+        if (!value.isType(type))
             edge.setProofStatus(NeedsCheck);
-        } else
+        else
             edge.setProofStatus(IsProved);
         
         filter(value, type);
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index ba7403f..a780871 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -87,8 +87,6 @@
     
     m_state.setDidClobber(false);
     
-    node->setCanExit(false);
-    
     return node->shouldGenerate();
 }
 
@@ -137,9 +135,8 @@
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-    case WeakJSConstant:
     case PhantomArguments: {
-        setBuiltInConstant(node, m_graph.valueOfJSConstant(node));
+        setBuiltInConstant(node, *node->constant());
         break;
     }
         
@@ -177,10 +174,6 @@
     case GetLocal: {
         VariableAccessData* variableAccessData = node->variableAccessData();
         AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
-        if (!variableAccessData->isCaptured()) {
-            if (value.isClear())
-                node->setCanExit(true);
-        }
         if (value.value())
             m_state.setFoundConstants(true);
         forNode(node) = value;
@@ -271,7 +264,6 @@
             }
         }
         forNode(node).setType(SpecInt32);
-        node->setCanExit(true);
         break;
     }
         
@@ -305,7 +297,6 @@
                 break;
             }
         }
-        node->setCanExit(true);
         forNode(node).setType(SpecInt32);
         break;
     }
@@ -392,8 +383,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (left && right && left.isMachineInt() && right.isMachineInt()) {
@@ -404,9 +393,6 @@
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            if (!forNode(node->child1()).isType(SpecInt32)
-                || !forNode(node->child2()).isType(SpecInt32))
-                node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -425,7 +411,6 @@
     }
         
     case MakeRope: {
-        node->setCanExit(true);
         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
         break;
     }
@@ -447,8 +432,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (left && right && left.isMachineInt() && right.isMachineInt()) {
@@ -459,9 +442,6 @@
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            if (!forNode(node->child1()).isType(SpecInt32)
-                || !forNode(node->child2()).isType(SpecInt32))
-                node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -500,8 +480,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (child && child.isMachineInt()) {
@@ -517,10 +495,6 @@
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
-                node->setCanExit(true);
-            if (shouldCheckNegativeZero(node->arithMode()))
-                node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (child && child.isNumber()) {
@@ -558,8 +532,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (left && right && left.isMachineInt() && right.isMachineInt()) {
@@ -573,7 +545,6 @@
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -609,7 +580,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -645,7 +615,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -673,7 +642,6 @@
                 break;
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -703,7 +671,6 @@
                 break;
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -735,7 +702,6 @@
                 }
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (child && child.isNumber()) {
@@ -800,20 +766,6 @@
             setConstant(node, jsBoolean(true));
             break;
         default:
-            switch (node->child1().useKind()) {
-            case BooleanUse:
-            case Int32Use:
-            case DoubleRepUse:
-            case UntypedUse:
-            case StringUse:
-                break;
-            case ObjectOrOtherUse:
-                node->setCanExit(true);
-                break;
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
-            }
             forNode(node).setType(SpecBoolean);
             break;
         }
@@ -826,9 +778,6 @@
     case IsString:
     case IsObject:
     case IsFunction: {
-        node->setCanExit(
-            node->op() == IsUndefined
-            && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic));
         JSValue child = forNode(node->child1()).value();
         if (child) {
             bool constantWasSet = true;
@@ -873,46 +822,35 @@
         AbstractValue& abstractChild = forNode(node->child1());
         if (child) {
             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
-            setConstant(node, typeString);
+            setConstant(node, *m_graph.freeze(typeString));
             break;
         }
         
         if (isFullNumberSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.numberString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.numberString()));
             break;
         }
         
         if (isStringSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.stringString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.stringString()));
             break;
         }
         
         if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.objectString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.objectString()));
             break;
         }
         
         if (isFunctionSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.functionString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.functionString()));
             break;
         }
         
         if (isBooleanSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.booleanString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.booleanString()));
             break;
         }
 
-        switch (node->child1().useKind()) {
-        case StringUse:
-        case CellUse:
-            node->setCanExit(true);
-            break;
-        case UntypedUse:
-            break;
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-        }
         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
         break;
     }
@@ -972,14 +910,6 @@
         }
         
         forNode(node).setType(SpecBoolean);
-        
-        // This is overly conservative. But the only thing this prevents is store elimination,
-        // and how likely is it, really, that you'll have redundant stores across a comparison
-        // operation? Comparison operations are typically at the end of basic blocks, so
-        // unless we have global store elimination (super unlikely given how unprofitable that
-        // optimization is to begin with), you aren't going to be wanting to store eliminate
-        // across an equality op.
-        node->setCanExit(true);
         break;
     }
             
@@ -1012,12 +942,10 @@
         }
         
         forNode(node).setType(SpecBoolean);
-        node->setCanExit(true); // This is overly conservative.
         break;
     }
         
     case StringCharCodeAt:
-        node->setCanExit(true);
         forNode(node).setType(SpecInt32);
         break;
         
@@ -1026,12 +954,10 @@
         break;
 
     case StringCharAt:
-        node->setCanExit(true);
         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
         break;
             
     case GetByVal: {
-        node->setCanExit(true);
         switch (node->arrayMode().type()) {
         case Array::SelectUsingPredictions:
         case Array::Unprofiled:
@@ -1130,7 +1056,6 @@
     case PutByValDirect:
     case PutByVal:
     case PutByValAlias: {
-        node->setCanExit(true);
         switch (node->arrayMode().modeForPut().type()) {
         case Array::ForceExit:
             m_state.setIsValid(false);
@@ -1162,13 +1087,11 @@
     }
             
     case ArrayPush:
-        node->setCanExit(true);
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(SpecBytecodeNumber);
         break;
             
     case ArrayPop:
-        node->setCanExit(true);
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
@@ -1199,7 +1122,6 @@
         // constant propagation, but we can do better:
         // We can specialize the source variable's value on each direction of
         // the branch.
-        node->setCanExit(true); // This is overly conservative.
         m_state.setBranchDirection(TakeBoth);
         break;
     }
@@ -1217,7 +1139,6 @@
     case Throw:
     case ThrowReferenceError:
         m_state.setIsValid(false);
-        node->setCanExit(true);
         break;
             
     case ToPrimitive: {
@@ -1254,10 +1175,8 @@
             filter(
                 node->child1(),
                 m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
-            node->setCanExit(true); // We could be more precise but it's likely not worth it.
             break;
         case StringOrStringObjectUse:
-            node->setCanExit(true); // We could be more precise but it's likely not worth it.
             break;
         case CellUse:
         case UntypedUse:
@@ -1278,21 +1197,18 @@
     }
             
     case NewArray:
-        node->setCanExit(true);
         forNode(node).set(
             m_graph,
             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
         break;
         
     case NewArrayBuffer:
-        node->setCanExit(true);
         forNode(node).set(
             m_graph,
             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
         break;
 
     case NewArrayWithSize:
-        node->setCanExit(true);
         forNode(node).setType(SpecArray);
         break;
         
@@ -1336,7 +1252,6 @@
     }
         
     case AllocationProfileWatchpoint:
-        node->setCanExit(true);
         break;
 
     case NewObject:
@@ -1369,8 +1284,6 @@
                 m_state.variables().operand(
                     m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
             m_state.setFoundConstants(true);
-        else
-            node->setCanExit(true);
         break;
         
     case GetMyArgumentsLength:
@@ -1384,10 +1297,6 @@
             m_state.setDidClobber(true); // Pretend that we clobbered to prevent constant folding.
         } else
             forNode(node).setType(SpecInt32);
-        node->setCanExit(
-            !isEmptySpeculation(
-                m_state.variables().operand(
-                    m_graph.argumentsRegisterFor(node->origin.semantic)).m_type));
         break;
         
     case GetMyArgumentsLengthSafe:
@@ -1399,16 +1308,25 @@
         forNode(node).makeHeapTop();
         break;
         
-    case GetMyArgumentByVal:
-        node->setCanExit(true);
-        // We know that this executable does not escape its arguments, so we can optimize
-        // the arguments a bit. Note that this ends up being further optimized by the
-        // ArgumentsSimplificationPhase.
+    case GetMyArgumentByVal: {
+        InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
+        JSValue value = forNode(node->child1()).m_value;
+        if (inlineCallFrame && value && value.isInt32()) {
+            int32_t index = value.asInt32();
+            if (index >= 0
+                && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
+                forNode(node) = m_state.variables().operand(
+                    inlineCallFrame->stackOffset +
+                    m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index));
+                m_state.setFoundConstants(true);
+                break;
+            }
+        }
         forNode(node).makeHeapTop();
         break;
+    }
         
     case GetMyArgumentByValSafe:
-        node->setCanExit(true);
         // This potentially clobbers all structures if the property we're accessing has
         // a getter. We don't speculate against this.
         clobberWorld(node->origin.semantic, clobberLimit);
@@ -1450,7 +1368,7 @@
     case SkipScope: {
         JSValue child = forNode(node->child1()).value();
         if (child) {
-            setConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()));
+            setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
             break;
         }
         forNode(node).setType(SpecObjectOther);
@@ -1471,7 +1389,6 @@
             
     case GetById:
     case GetByIdFlush:
-        node->setCanExit(true);
         if (!node->prediction()) {
             m_state.setIsValid(false);
             break;
@@ -1490,14 +1407,15 @@
                     // Assert things that we can't handle and that the computeFor() method
                     // above won't be able to return.
                     ASSERT(status[0].structureSet().size() == 1);
-                    ASSERT(!status[0].chain());
+                    ASSERT(status[0].constantChecks().isEmpty());
+                    ASSERT(!status[0].alternateBase());
                     
                     if (status[0].specificValue()) {
                         if (status[0].specificValue().isCell()) {
                             Structure* structure = status[0].specificValue().asCell()->structure();
                             m_graph.watchpoints().consider(structure);
                         }
-                        setConstant(node, status[0].specificValue());
+                        setConstant(node, *m_graph.freeze(status[0].specificValue()));
                     } else
                         forNode(node).makeHeapTop();
                     filter(node->child1(), status[0].structureSet());
@@ -1512,7 +1430,6 @@
         break;
             
     case GetArrayLength:
-        node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
         forNode(node).setType(SpecInt32);
         break;
         
@@ -1521,7 +1438,6 @@
         // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
         // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
         // https://bugs.webkit.org/show_bug.cgi?id=106201
-        node->setCanExit(true);
         break;
     }
 
@@ -1541,8 +1457,6 @@
             break;
         }
 
-        node->setCanExit(true);
-
         filter(value, set);
         break;
     }
@@ -1565,7 +1479,6 @@
             m_state.setFoundConstants(true);
             break;
         }
-        node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
         switch (node->arrayMode().type()) {
         case Array::String:
             filter(node->child1(), SpecString);
@@ -1620,7 +1533,6 @@
         }
         ASSERT(node->arrayMode().conversion() == Array::Convert
             || node->arrayMode().conversion() == Array::RageConvert);
-        node->setCanExit(true);
         clobberStructures(clobberLimit);
         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
         break;
@@ -1629,7 +1541,6 @@
         AbstractValue& value = forNode(node->child1());
         if (value.m_structure.isSubsetOf(StructureSet(node->structure())))
             m_state.setFoundConstants(true);
-        node->setCanExit(true);
         clobberStructures(clobberLimit);
         
         // We have a bunch of options of how to express the abstract set at this point. Let set S
@@ -1698,7 +1609,7 @@
                 if (!variant.structureSet().contains(structure))
                     continue;
                 
-                if (variant.chain())
+                if (variant.alternateBase())
                     break;
                 
                 filter(value, structure);
@@ -1781,14 +1692,13 @@
     
     case CheckFunction: {
         JSValue value = forNode(node->child1()).value();
-        if (value == node->function()) {
+        if (value == node->function()->value()) {
             m_state.setFoundConstants(true);
             ASSERT(value);
             break;
         }
         
-        node->setCanExit(true); // Lies! We can do better.
-        filterByValue(node->child1(), node->function());
+        filterByValue(node->child1(), *node->function());
         break;
     }
         
@@ -1800,15 +1710,12 @@
             m_state.setFoundConstants(true);
             break;
         }
-        
-        node->setCanExit(true);
         break;
     }
         
     case PutById:
     case PutByIdFlush:
     case PutByIdDirect:
-        node->setCanExit(true);
         // This use of onlyStructure() should be replaced by giving PutByIdStatus the ability
         // to compute things based on a StructureSet, and then to factor ByteCodeParser's
         // ability to generate code based on a PutByIdStatus out of ByteCodeParser so that
@@ -1853,7 +1760,6 @@
         
     case VariableWatchpoint:
     case VarInjectionWatchpoint:
-        node->setCanExit(true);
         break;
             
     case PutGlobalVar:
@@ -1861,26 +1767,25 @@
         break;
             
     case CheckHasInstance:
-        node->setCanExit(true);
         // Sadly, we don't propagate the fact that we've done CheckHasInstance
         break;
             
     case InstanceOf:
-        node->setCanExit(true);
         // Again, sadly, we don't propagate the fact that we've done InstanceOf
         forNode(node).setType(SpecBoolean);
         break;
             
     case Phi:
         RELEASE_ASSERT(m_graph.m_form == SSA);
-        // The state of this node would have already been decided.
+        // The state of this node would have already been decided, but it may have become a
+        // constant, in which case we'd like to know.
+        if (forNode(node).m_value)
+            m_state.setFoundConstants(true);
         break;
         
     case Upsilon: {
         m_state.createValueForNode(node->phi());
-        AbstractValue value = forNode(node->child1());
-        forNode(node) = value;
-        forNode(node->phi()) = value;
+        forNode(node->phi()) = forNode(node->child1());
         break;
     }
         
@@ -1890,24 +1795,22 @@
             
     case Call:
     case Construct:
-        node->setCanExit(true);
+    case NativeCall:
+    case NativeConstruct:
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
 
     case ForceOSRExit:
-        node->setCanExit(true);
         m_state.setIsValid(false);
         break;
         
     case InvalidationPoint:
-        node->setCanExit(true);
         forAllValues(clobberLimit, AbstractValue::observeInvalidationPointFor);
         m_state.setStructureClobberState(StructuresAreWatched);
         break;
 
     case CheckWatchdogTimer:
-        node->setCanExit(true);
         break;
 
     case Breakpoint:
@@ -1933,7 +1836,6 @@
     case CheckTierUpAndOSREnter:
     case LoopHint:
         // We pretend that it can exit because it may want to get all state.
-        node->setCanExit(true);
         break;
 
     case ZombieHint:
@@ -2143,7 +2045,7 @@
 
 template<typename AbstractStateType>
 FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
-    AbstractValue& abstractValue, JSValue concreteValue)
+    AbstractValue& abstractValue, FrozenValue concreteValue)
 {
     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
         return FiltrationOK;
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp b/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
index b141206..d2e4e5d 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
@@ -47,10 +47,10 @@
     checkConsistency();
 }
 
-void AbstractValue::setMostSpecific(Graph& graph, JSValue value)
+void AbstractValue::setOSREntryValue(Graph& graph, const FrozenValue& value)
 {
-    if (!!value && value.isCell()) {
-        Structure* structure = value.asCell()->structure();
+    if (!!value && value.value().isCell()) {
+        Structure* structure = value.structure();
         graph.watchpoints().consider(structure);
         m_structure = structure;
         m_arrayModes = asArrayModes(structure->indexingType());
@@ -59,17 +59,17 @@
         m_arrayModes = 0;
     }
         
-    m_type = speculationFromValue(value);
-    m_value = value;
+    m_type = speculationFromValue(value.value());
+    m_value = value.value();
         
     checkConsistency();
     assertIsWatched(graph);
 }
 
-void AbstractValue::set(Graph& graph, JSValue value, StructureClobberState clobberState)
+void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState)
 {
-    if (!!value && value.isCell()) {
-        Structure* structure = value.asCell()->structure();
+    if (!!value && value.value().isCell()) {
+        Structure* structure = value.structure();
         if (graph.watchpoints().consider(structure)) {
             // We should be able to assume that the watchpoint for this has already been set.
             // But we can't because our view of what structure a value has keeps changing. That's
@@ -90,8 +90,8 @@
         m_arrayModes = 0;
     }
     
-    m_type = speculationFromValue(value);
-    m_value = value;
+    m_type = speculationFromValue(value.value());
+    m_value = value.value();
     
     checkConsistency();
     assertIsWatched(graph);
@@ -233,14 +233,47 @@
     return normalizeClarity();
 }
 
-FiltrationResult AbstractValue::filterByValue(JSValue value)
+FiltrationResult AbstractValue::filterByValue(const FrozenValue& value)
 {
-    FiltrationResult result = filter(speculationFromValue(value));
+    FiltrationResult result = filter(speculationFromValue(value.value()));
     if (m_type)
-        m_value = value;
+        m_value = value.value();
     return result;
 }
 
+FiltrationResult AbstractValue::filter(const AbstractValue& other)
+{
+    m_type &= other.m_type;
+    m_structure.filter(other.m_structure);
+    m_arrayModes &= other.m_arrayModes;
+
+    m_structure.filter(m_type);
+    filterArrayModesByType();
+    filterValueByType();
+    
+    if (normalizeClarity() == Contradiction)
+        return Contradiction;
+    
+    if (m_value == other.m_value)
+        return FiltrationOK;
+    
+    // Neither of us are BOTTOM, so an empty value means TOP.
+    if (!m_value) {
+        // We previously didn't prove a value but now we have done so.
+        m_value = other.m_value; 
+        return FiltrationOK;
+    }
+    
+    if (!other.m_value) {
+        // We had proved a value but the other guy hadn't, so keep our proof.
+        return FiltrationOK;
+    }
+    
+    // We both proved there to be a specific value but they are different.
+    clear();
+    return Contradiction;
+}
+
 void AbstractValue::filterValueByType()
 {
     // We could go further, and ensure that if the futurePossibleStructure contravenes
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index f71f073..003e1ab 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -30,6 +30,7 @@
 
 #include "ArrayProfile.h"
 #include "DFGFiltrationResult.h"
+#include "DFGFrozenValue.h"
 #include "DFGNodeFlags.h"
 #include "DFGStructureAbstractValue.h"
 #include "DFGStructureClobberState.h"
@@ -72,6 +73,11 @@
         makeTop(SpecBytecodeTop);
     }
     
+    void makeFullTop()
+    {
+        makeTop(SpecFullTop);
+    }
+    
     void clobberStructures()
     {
         if (m_type & SpecCell) {
@@ -173,8 +179,23 @@
         return result;
     }
     
-    void setMostSpecific(Graph&, JSValue);
-    void set(Graph&, JSValue, StructureClobberState);
+    static AbstractValue bytecodeTop()
+    {
+        AbstractValue result;
+        result.makeBytecodeTop();
+        return result;
+    }
+    
+    static AbstractValue fullTop()
+    {
+        AbstractValue result;
+        result.makeFullTop();
+        return result;
+    }
+    
+    void setOSREntryValue(Graph&, const FrozenValue&);
+    
+    void set(Graph&, const FrozenValue&, StructureClobberState);
     void set(Graph&, Structure*);
     void set(Graph&, const StructureSet&);
     
@@ -257,12 +278,10 @@
     }
     
     FiltrationResult filter(Graph&, const StructureSet&);
-    
     FiltrationResult filterArrayModes(ArrayModes);
-    
     FiltrationResult filter(SpeculatedType);
-    
-    FiltrationResult filterByValue(JSValue);
+    FiltrationResult filterByValue(const FrozenValue& value);
+    FiltrationResult filter(const AbstractValue&);
     
     bool validate(JSValue value) const
     {
@@ -349,7 +368,11 @@
     // implies nothing about the structure. Oddly, JSValue() (i.e. the empty value)
     // means either BOTTOM or TOP depending on the state of m_type: if m_type is
     // BOTTOM then JSValue() means BOTTOM; if m_type is not BOTTOM then JSValue()
-    // means TOP.
+    // means TOP. Also note that this value isn't necessarily known to the GC
+    // (strongly or even weakly - it may be an "fragile" 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.
     JSValue m_value;
 
 private:
diff --git a/Source/JavaScriptCore/dfg/DFGAdjacencyList.h b/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
index 38e74da..6bbfefd 100644
--- a/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
+++ b/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
@@ -65,6 +65,8 @@
         setNumChildren(numChildren);
     }
     
+    bool isEmpty() const { return !child1(); }
+    
     const Edge& child(unsigned i) const
     {
         ASSERT(i < Size);
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
index a52404e..920c466 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
@@ -208,8 +208,7 @@
                         // init_lazy_reg since it treats CreateArguments as reading
                         // local variables. That could be fixed, but it's easier to
                         // work around this here.
-                        if (source->op() == JSConstant
-                            && !source->valueOfJSConstant(codeBlock()))
+                        if (source->op() == JSConstant && !*source->constant())
                             break;
                         
                         // If the variable is totally dead, then ignore it.
@@ -511,7 +510,8 @@
                         indexInBlock, SpecNone, CheckArgumentsNotCreated, origin);
                     
                     m_graph.convertToConstant(
-                        node, jsNumber(origin.semantic.inlineCallFrame->arguments.size() - 1));
+                        node, m_graph.freeze(
+                            jsNumber(origin.semantic.inlineCallFrame->arguments.size() - 1)));
                     changed = true;
                     break;
                 }
@@ -528,12 +528,9 @@
                     }
                     if (!node->origin.semantic.inlineCallFrame)
                         break;
-                    if (!node->child1()->hasConstant())
+                    if (!node->child1()->isInt32Constant())
                         break;
-                    JSValue value = node->child1()->valueOfJSConstant(codeBlock());
-                    if (!value.isInt32())
-                        break;
-                    int32_t index = value.asInt32();
+                    int32_t index = node->child1()->asInt32();
                     if (index < 0
                         || static_cast<size_t>(index + 1) >=
                             node->origin.semantic.inlineCallFrame->arguments.size())
diff --git a/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.cpp
index ef6381e..9d8c710 100644
--- a/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.cpp
@@ -32,8 +32,9 @@
 
 namespace JSC { namespace DFG {
 
-AtTailAbstractState::AtTailAbstractState()
-    : m_block(0)
+AtTailAbstractState::AtTailAbstractState(Graph& graph)
+    : m_graph(graph)
+    , m_block(0)
 {
 }
 
@@ -47,7 +48,7 @@
 AbstractValue& AtTailAbstractState::forNode(Node* node)
 {
     HashMap<Node*, AbstractValue>::iterator iter = m_block->ssa->valuesAtTail.find(node);
-    ASSERT(iter != m_block->ssa->valuesAtTail.end());
+    DFG_ASSERT(m_graph, node, iter != m_block->ssa->valuesAtTail.end());
     return iter->value;
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h b/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h
index 9bf09da..cd6a080 100644
--- a/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h
@@ -36,7 +36,7 @@
 
 class AtTailAbstractState {
 public:
-    AtTailAbstractState();
+    AtTailAbstractState(Graph&);
     
     ~AtTailAbstractState();
     
@@ -63,6 +63,7 @@
     void setFoundConstants(bool) { }
 
 private:
+    Graph& m_graph;
     BasicBlock* m_block;
 };
 
diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
index 9d063fd..e2d3a83 100644
--- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
@@ -67,17 +67,17 @@
 private:
     bool isNotNegZero(Node* node)
     {
-        if (!m_graph.isNumberConstant(node))
+        if (!node->isNumberConstant())
             return false;
-        double value = m_graph.valueOfNumberConstant(node);
+        double value = node->asNumber();
         return (value || 1.0 / value > 0.0);
     }
     
     bool isNotPosZero(Node* node)
     {
-        if (!m_graph.isNumberConstant(node))
+        if (!node->isNumberConstant())
             return false;
-        double value = m_graph.valueOfNumberConstant(node);
+        double value = node->asNumber();
         return (value || 1.0 / value < 0.0);
     }
 
@@ -85,7 +85,7 @@
     template<int power>
     bool isWithinPowerOfTwoForConstant(Node* node)
     {
-        JSValue immediateValue = node->valueOfJSConstant(codeBlock());
+        JSValue immediateValue = node->asJSValue();
         if (!immediateValue.isNumber())
             return false;
         double immediate = immediateValue.asNumber();
@@ -130,7 +130,7 @@
             Node* shiftAmount = node->child2().node();
             if (shiftAmount->op() != JSConstant)
                 return false;
-            JSValue immediateValue = shiftAmount->valueOfJSConstant(codeBlock());
+            JSValue immediateValue = shiftAmount->asJSValue();
             if (!immediateValue.isInt32())
                 return false;
             return immediateValue.asInt32() > 32 - power;
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp b/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
index fadf622..733f8c2 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
@@ -52,6 +52,8 @@
     , variablesAtTail(numArguments, numLocals)
     , valuesAtHead(numArguments, numLocals)
     , valuesAtTail(numArguments, numLocals)
+    , intersectionOfPastValuesAtHead(numArguments, numLocals, AbstractValue::fullTop())
+    , intersectionOfCFAHasVisited(true)
     , executionCount(executionCount)
 {
 }
@@ -64,6 +66,7 @@
     variablesAtTail.ensureLocals(newNumLocals);
     valuesAtHead.ensureLocals(newNumLocals);
     valuesAtTail.ensureLocals(newNumLocals);
+    intersectionOfPastValuesAtHead.ensureLocals(newNumLocals, AbstractValue::fullTop());
 }
 
 bool BasicBlock::isInPhis(Node* node) const
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
index 27f5877..a648a89 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
@@ -134,6 +134,26 @@
     Operands<AbstractValue> valuesAtHead;
     Operands<AbstractValue> valuesAtTail;
     
+    // The intersection of assumptions we have made previously at the head of this block. Note
+    // that under normal circumstances, each time we run the CFA, we will get strictly more precise
+    // results. But we don't actually require this to be the case. It's fine for the CFA to loosen
+    // up for any odd reason. It's fine when this happens, because anything that the CFA proves
+    // must be true from that point forward, except if some registered watchpoint fires, in which
+    // case the code won't ever run. So, the CFA proving something less precise later on is just an
+    // outcome of the CFA being imperfect; the more precise thing that it had proved earlier is no
+    // less true.
+    //
+    // But for the purpose of OSR entry, we need to make sure that we remember what assumptions we
+    // had used for optimizing any given basic block. That's what this is for.
+    //
+    // It's interesting that we could use this to make the CFA more precise: all future CFAs could
+    // filter their results with this thing to sort of maintain maximal precision. Because we
+    // expect CFA to usually be monotonically more precise each time we run it to fixpoint, this
+    // would not be a productive optimization: it would make setting up a basic block more
+    // expensive and would only benefit bizarre pathological cases.
+    Operands<AbstractValue> intersectionOfPastValuesAtHead;
+    bool intersectionOfCFAHasVisited;
+    
     float executionCount;
     
     // These fields are reserved for NaturalLoops.
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 6b70e50..216427e 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -132,18 +132,16 @@
         , m_graph(graph)
         , m_currentBlock(0)
         , m_currentIndex(0)
-        , m_constantUndefined(UINT_MAX)
-        , m_constantNull(UINT_MAX)
-        , m_constantNaN(UINT_MAX)
-        , m_constant1(UINT_MAX)
-        , m_constants(m_codeBlock->numberOfConstantRegisters())
+        , m_constantUndefined(graph.freeze(jsUndefined()))
+        , m_constantNull(graph.freeze(jsNull()))
+        , m_constantNaN(graph.freeze(jsNumber(PNaN)))
+        , m_constantOne(graph.freeze(jsNumber(1)))
         , m_numArguments(m_codeBlock->numParameters())
         , m_numLocals(m_codeBlock->m_numCalleeRegisters)
         , m_parameterSlots(0)
         , m_numPassedVarArgs(0)
         , m_inlineStackTop(0)
         , m_haveBuiltOperandMaps(false)
-        , m_emptyJSValueIndex(UINT_MAX)
         , m_currentInstruction(0)
     {
         ASSERT(m_profiledBlock);
@@ -194,7 +192,7 @@
     void handlePutById(
         Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus&,
         bool isDirect);
-    Node* emitPrototypeChecks(Structure*, IntendedStructureChain*);
+    void emitChecks(const ConstantStructureCheckVector&);
 
     Node* getScope(bool skipTop, unsigned skipCount);
     
@@ -217,12 +215,7 @@
     // Get/Set the operands/result of a bytecode instruction.
     Node* getDirect(VirtualRegister operand)
     {
-        // Is this a constant?
-        if (operand.isConstant()) {
-            unsigned constant = operand.toConstantIndex();
-            ASSERT(constant < m_constants.size());
-            return getJSConstant(constant);
-        }
+        ASSERT(!operand.isConstant());
 
         // Is this an argument?
         if (operand.isArgument())
@@ -234,13 +227,30 @@
 
     Node* get(VirtualRegister operand)
     {
+        if (operand.isConstant()) {
+            unsigned constantIndex = operand.toConstantIndex();
+            unsigned oldSize = m_constants.size();
+            if (constantIndex >= oldSize || !m_constants[constantIndex]) {
+                JSValue value = m_inlineStackTop->m_codeBlock->getConstant(operand.offset());
+                if (constantIndex >= oldSize) {
+                    m_constants.grow(constantIndex + 1);
+                    for (unsigned i = oldSize; i < 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];
+        }
+        
         if (inlineCallFrame()) {
             if (!inlineCallFrame()->isClosureCall) {
                 JSFunction* callee = inlineCallFrame()->calleeConstant();
                 if (operand.offset() == JSStack::Callee)
-                    return cellConstant(callee);
+                    return weakJSConstant(callee);
                 if (operand.offset() == JSStack::ScopeChain)
-                    return cellConstant(callee->scope());
+                    return weakJSConstant(callee->scope());
             }
         } else if (operand.offset() == JSStack::Callee)
             return addToGraph(GetCallee);
@@ -309,14 +319,7 @@
                 if (JSValue value = set->inferredValue()) {
                     addToGraph(FunctionReentryWatchpoint, OpInfo(m_codeBlock->symbolTable()));
                     addToGraph(VariableWatchpoint, OpInfo(set));
-                    // 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);
+                    return weakJSConstant(value);
                 }
             }
         }
@@ -367,8 +370,7 @@
 
         VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
         variableAccessData->mergeStructureCheckHoistingFailed(
-            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-            || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
+            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
         variableAccessData->mergeCheckArrayHoistingFailed(
             m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
@@ -424,8 +426,7 @@
             variableAccessData->mergeShouldNeverUnbox(true);
         
         variableAccessData->mergeStructureCheckHoistingFailed(
-            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-            || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
+            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
         variableAccessData->mergeCheckArrayHoistingFailed(
             m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
@@ -466,18 +467,6 @@
         return findArgumentPositionForLocal(operand);
     }
 
-    void addConstant(JSValue value)
-    {
-        unsigned constantIndex = m_codeBlock->addConstantLazily();
-        initializeLazyWriteBarrierForConstant(
-            m_graph.m_plan.writeBarriers,
-            m_codeBlock->constants()[constantIndex],
-            m_codeBlock,
-            constantIndex,
-            m_codeBlock->ownerExecutable(), 
-            value);
-    }
-    
     void flush(VirtualRegister operand)
     {
         flushDirect(m_inlineStackTop->remapOperand(operand));
@@ -554,32 +543,15 @@
         flushForTerminal();
     }
 
-    // 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)
+    // Assumes that the constant should be strongly marked.
+    Node* jsConstant(JSValue constantValue)
     {
-        unsigned constantIndex;
-        if (!m_codeBlock->findConstant(constantValue, constantIndex)) {
-            addConstant(constantValue);
-            m_constants.append(ConstantRecord());
-        }
-        
-        ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
-        
-        return getJSConstant(constantIndex);
+        return addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(constantValue)));
     }
 
-    Node* getJSConstant(unsigned constant)
+    Node* weakJSConstant(JSValue constantValue)
     {
-        Node* node = m_constants[constant].asJSValue;
-        if (node)
-            return node;
-
-        Node* result = addToGraph(JSConstant, OpInfo(constant));
-        m_constants[constant].asJSValue = result;
-        return result;
+        return addToGraph(JSConstant, OpInfo(m_graph.freeze(constantValue)));
     }
 
     // Helper functions to get/set the this value.
@@ -593,149 +565,6 @@
         set(m_inlineStackTop->m_codeBlock->thisRegister(), value);
     }
 
-    // Convenience methods for checking nodes for constants.
-    bool isJSConstant(Node* node)
-    {
-        return node->op() == JSConstant;
-    }
-    bool isInt32Constant(Node* node)
-    {
-        return isJSConstant(node) && valueOfJSConstant(node).isInt32();
-    }
-    // Convenience methods for getting constant values.
-    JSValue valueOfJSConstant(Node* node)
-    {
-        ASSERT(isJSConstant(node));
-        return m_codeBlock->getConstant(FirstConstantRegisterIndex + node->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->numberOfConstantRegisters();
-            for (m_constantUndefined = 0; m_constantUndefined < numberOfConstants; ++m_constantUndefined) {
-                JSValue testMe = m_codeBlock->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->numberOfConstantRegisters());
-        }
-
-        // m_constantUndefined must refer to an entry in the CodeBlock's constant pool that has the value 'undefined'.
-        ASSERT(m_codeBlock->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->numberOfConstantRegisters();
-            for (m_constantNull = 0; m_constantNull < numberOfConstants; ++m_constantNull) {
-                JSValue testMe = m_codeBlock->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->numberOfConstantRegisters());
-        }
-
-        // m_constantNull must refer to an entry in the CodeBlock's constant pool that has the value 'null'.
-        ASSERT(m_codeBlock->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->numberOfConstantRegisters();
-            for (m_constant1 = 0; m_constant1 < numberOfConstants; ++m_constant1) {
-                JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1);
-                if (testMe.isInt32() && 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->numberOfConstantRegisters());
-        }
-
-        // m_constant1 must refer to an entry in the CodeBlock's constant pool that has the integer value 1.
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).isInt32());
-        ASSERT(m_codeBlock->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->numberOfConstantRegisters();
-            for (m_constantNaN = 0; m_constantNaN < numberOfConstants; ++m_constantNaN) {
-                JSValue testMe = m_codeBlock->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->numberOfConstantRegisters());
-        }
-
-        // m_constantNaN must refer to an entry in the CodeBlock's constant pool that has the value nan.
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).isDouble());
-        ASSERT(std::isnan(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).asDouble()));
-        return getJSConstant(m_constantNaN);
-    }
-    
-    Node* cellConstant(JSCell* cell)
-    {
-        HashMap<JSCell*, Node*>::AddResult result = m_cellConstantNodes.add(cell, nullptr);
-        if (result.isNewEntry) {
-            ASSERT(!Heap::isZombified(cell));
-            result.iterator->value = addToGraph(WeakJSConstant, OpInfo(cell));
-        }
-        
-        return result.iterator->value;
-    }
-    
-    Node* inferredConstant(JSValue value)
-    {
-        if (value.isCell())
-            return cellConstant(value.asCell());
-        return getJSConstantForValue(value);
-    }
-    
     InlineCallFrame* inlineCallFrame()
     {
         return m_inlineStackTop->m_inlineCallFrame;
@@ -820,7 +649,7 @@
         if (parameterSlots > m_parameterSlots)
             m_parameterSlots = parameterSlots;
 
-        int dummyThisArgument = op == Call ? 0 : 1;
+        int dummyThisArgument = op == Call || op == NativeCall ? 0 : 1;
         for (int i = 0 + dummyThisArgument; i < argCount; ++i)
             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
 
@@ -831,16 +660,11 @@
     
     Node* cellConstantWithStructureCheck(JSCell* object, Structure* structure)
     {
-        Node* objectNode = cellConstant(object);
+        Node* objectNode = weakJSConstant(object);
         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
         return objectNode;
     }
     
-    Node* cellConstantWithStructureCheck(JSCell* object)
-    {
-        return cellConstantWithStructureCheck(object, object->structure());
-    }
-
     SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
     {
         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
@@ -971,22 +795,6 @@
         return node;
     }
     
-    bool structureChainIsStillValid(bool direct, Structure* previousStructure, StructureChain* chain)
-    {
-        if (direct)
-            return true;
-        
-        if (!previousStructure->storedPrototype().isNull() && previousStructure->storedPrototype().asCell()->structure() != chain->head()->get())
-            return false;
-        
-        for (WriteBarrier<Structure>* it = chain->head(); *it; ++it) {
-            if (!(*it)->storedPrototype().isNull() && (*it)->storedPrototype().asCell()->structure() != it[1].get())
-                return false;
-        }
-        
-        return true;
-    }
-    
     void buildOperandMapsIfNecessary();
     
     VM* m_vm;
@@ -999,36 +807,11 @@
     // The bytecode index of the current instruction being generated.
     unsigned m_currentIndex;
 
-    // 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<JSCell*, unsigned> m_cellConstants;
-    HashMap<JSCell*, Node*> m_cellConstantNodes;
-
-    // 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<ConstantRecord, 16> m_constants;
+    FrozenValue* m_constantUndefined;
+    FrozenValue* m_constantNull;
+    FrozenValue* m_constantNaN;
+    FrozenValue* m_constantOne;
+    Vector<Node*, 16> m_constants;
 
     // The number of arguments passed to the function.
     unsigned m_numArguments;
@@ -1063,7 +846,6 @@
         // (the machine code block, which is the transitive, though not necessarily
         // direct, caller).
         Vector<unsigned> m_identifierRemap;
-        Vector<unsigned> m_constantRemap;
         Vector<unsigned> m_constantBufferRemap;
         Vector<unsigned> m_switchRemap;
         
@@ -1134,11 +916,7 @@
             if (!m_inlineCallFrame)
                 return operand;
             
-            if (operand.isConstant()) {
-                VirtualRegister result = VirtualRegister(m_constantRemap[operand.toConstantIndex()]);
-                ASSERT(result.isConstant());
-                return result;
-            }
+            ASSERT(!operand.isConstant());
 
             return VirtualRegister(operand.offset() + m_inlineCallFrame->stackOffset);
         }
@@ -1172,11 +950,6 @@
     bool m_haveBuiltOperandMaps;
     // Mapping between identifier names and numbers.
     BorrowedIdentifierMap m_identifierMap;
-    // 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 "empty" values.
-    unsigned m_emptyJSValueIndex;
     
     CodeBlock* m_dfgCodeBlock;
     CallLinkStatus::ContextMap m_callContextMap;
@@ -1224,10 +997,8 @@
     ASSERT(registerOffset <= 0);
     CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
     
-    if (m_graph.isConstant(callTarget)) {
-        callLinkStatus = CallLinkStatus(
-            m_graph.valueOfJSConstant(callTarget)).setIsProved(true);
-    }
+    if (callTarget->hasConstant())
+        callLinkStatus = CallLinkStatus(callTarget->asJSValue()).setIsProved(true);
     
     if (!callLinkStatus.canOptimize()) {
         // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
@@ -1273,13 +1044,24 @@
         if (m_graph.compilation())
             m_graph.compilation()->noticeInlinedCall();
         return;
-    } else if (JSFunction* function = callLinkStatus.function())
-        if (function->isHostFunction()) {
+    } else if (isFTL(m_graph.m_plan.mode)) {
+        JSFunction* function = callLinkStatus.function();
+        if (function && function->isHostFunction()) {
             emitFunctionChecks(callLinkStatus, callTarget, registerOffset, specializationKind);
             knownFunction = function;
+
+            if (op == Call) 
+                op = NativeCall;
+            else {
+                ASSERT(op == Construct);
+                op = NativeConstruct;
+            }
         }
-    
-    addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset)->giveKnownFunction(knownFunction);
+    }
+    Node* call = addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset);
+
+    if (knownFunction) 
+        call->giveKnownFunction(knownFunction);
 }
 
 void ByteCodeParser::emitFunctionChecks(const CallLinkStatus& callLinkStatus, Node* callTarget, int registerOffset, CodeSpecializationKind kind)
@@ -1298,7 +1080,7 @@
     ASSERT(callLinkStatus.canOptimize());
     
     if (JSFunction* function = callLinkStatus.function())
-        addToGraph(CheckFunction, OpInfo(function), callTarget, thisArgument);
+        addToGraph(CheckFunction, OpInfo(m_graph.freeze(function)), callTarget, thisArgument);
     else {
         ASSERT(callLinkStatus.structure());
         ASSERT(callLinkStatus.executable());
@@ -1455,6 +1237,7 @@
     m_graph.m_inlineVariableData.append(inlineVariableData);
     
     parseCodeBlock();
+    prepareToParseBlock(); // Reset our state now that we're back to the outer code.
     
     m_currentIndex = oldIndex;
     
@@ -1544,7 +1327,7 @@
 bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis)
 {
     if (argumentCountIncludingThis == 1) { // Math.min()
-        set(VirtualRegister(resultOperand), constantNaN());
+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
         return true;
     }
      
@@ -1569,7 +1352,7 @@
     switch (intrinsic) {
     case AbsIntrinsic: {
         if (argumentCountIncludingThis == 1) { // Math.abs()
-            set(VirtualRegister(resultOperand), constantNaN());
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
             return true;
         }
 
@@ -1593,7 +1376,7 @@
     case CosIntrinsic:
     case SinIntrinsic: {
         if (argumentCountIncludingThis == 1) {
-            set(VirtualRegister(resultOperand), constantNaN());
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
             return true;
         }
         
@@ -1740,19 +1523,19 @@
     }
         
     case DFGTrueIntrinsic: {
-        set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true)));
+        set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
         return true;
     }
         
     case OSRExitIntrinsic: {
         addToGraph(ForceOSRExit);
-        set(VirtualRegister(resultOperand), constantUndefined());
+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
         return true;
     }
         
     case IsFinalTierIntrinsic: {
         set(VirtualRegister(resultOperand),
-            getJSConstantForValue(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
+            jsConstant(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
         return true;
     }
         
@@ -1762,7 +1545,7 @@
             if (node->hasHeapPrediction())
                 node->setHeapPrediction(SpecInt32);
         }
-        set(VirtualRegister(resultOperand), constantUndefined());
+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
         return true;
     }
         
@@ -1868,7 +1651,7 @@
         Node* result;
         
         if (argumentCountIncludingThis <= 1)
-            result = cellConstant(m_vm->smallStrings.emptyString());
+            result = jsConstant(m_vm->smallStrings.emptyString());
         else
             result = addToGraph(ToString, get(virtualRegisterForArgument(1, registerOffset)));
         
@@ -1924,20 +1707,10 @@
     return result;
 }
 
-Node* ByteCodeParser::emitPrototypeChecks(
-    Structure* structure, IntendedStructureChain* chain)
+void ByteCodeParser::emitChecks(const ConstantStructureCheckVector& vector)
 {
-    ASSERT(structure);
-    Node* base = 0;
-    m_graph.chains().addLazily(chain);
-    Structure* currentStructure = structure;
-    JSObject* currentObject = 0;
-    for (unsigned i = 0; i < chain->size(); ++i) {
-        currentObject = asObject(currentStructure->prototypeForLookup(m_inlineStackTop->m_codeBlock));
-        currentStructure = chain->at(i);
-        base = cellConstantWithStructureCheck(currentObject, currentStructure);
-    }
-    return base;
+    for (unsigned i = 0; i < vector.size(); ++i)
+        cellConstantWithStructureCheck(vector[i].constant(), vector[i].structure());
 }
 
 void ByteCodeParser::handleGetById(
@@ -1966,13 +1739,8 @@
         // 1) Emit prototype structure checks for all chains. This could sort of maybe not be
         //    optimal, if there is some rarely executed case in the chain that requires a lot
         //    of checks and those checks are not watchpointable.
-        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) {
-            if (getByIdStatus[variantIndex].chain()) {
-                emitPrototypeChecks(
-                    getByIdStatus[variantIndex].structureSet().onlyStructure(),
-                    getByIdStatus[variantIndex].chain());
-            }
-        }
+        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;)
+            emitChecks(getByIdStatus[variantIndex].constantChecks());
         
         // 2) Emit a MultiGetByOffset
         MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add();
@@ -1993,10 +1761,10 @@
                 
     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base);
     
-    if (variant.chain()) {
-        base = emitPrototypeChecks(
-            variant.structureSet().onlyStructure(), variant.chain());
-    }
+    emitChecks(variant.constantChecks());
+
+    if (variant.alternateBase())
+        base = weakJSConstant(variant.alternateBase());
     
     // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
     // ensure that the base of the original get_by_id is kept alive until we're done with
@@ -2009,7 +1777,7 @@
     
     Node* loadedValue;
     if (variant.specificValue())
-        loadedValue = cellConstant(variant.specificValue().asCell());
+        loadedValue = weakJSConstant(variant.specificValue());
     else {
         loadedValue = handleGetByOffset(
             prediction, base, identifierNumber, variant.offset(),
@@ -2093,11 +1861,7 @@
             for (unsigned variantIndex = putByIdStatus.numVariants(); variantIndex--;) {
                 if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition)
                     continue;
-                if (!putByIdStatus[variantIndex].structureChain())
-                    continue;
-                emitPrototypeChecks(
-                    putByIdStatus[variantIndex].oldStructure(),
-                    putByIdStatus[variantIndex].structureChain());
+                emitChecks(putByIdStatus[variantIndex].constantChecks());
             }
         }
         
@@ -2124,16 +1888,8 @@
         return;
     }
 
-    if (variant.structureChain() && !variant.structureChain()->isStillValid()) {
-        emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
-        return;
-    }
-    
-    m_graph.chains().addLazily(variant.structureChain());
-                
     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
-    if (!isDirect)
-        emitPrototypeChecks(variant.oldStructure(), variant.structureChain());
+    emitChecks(variant.constantChecks());
 
     ASSERT(variant.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
     
@@ -2183,9 +1939,7 @@
 
 void ByteCodeParser::prepareToParseBlock()
 {
-    for (unsigned i = 0; i < m_constants.size(); ++i)
-        m_constants[i] = ConstantRecord();
-    m_cellConstantNodes.clear();
+    m_constants.resize(0);
 }
 
 Node* ByteCodeParser::getScope(bool skipTop, unsigned skipCount)
@@ -2217,8 +1971,7 @@
             VariableAccessData* variable = newVariableAccessData(
                 virtualRegisterForArgument(argument), m_codeBlock->isCaptured(virtualRegisterForArgument(argument)));
             variable->mergeStructureCheckHoistingFailed(
-                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
+                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
             variable->mergeCheckArrayHoistingFailed(
                 m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
             
@@ -2264,13 +2017,15 @@
 
         // === Function entry opcodes ===
 
-        case op_enter:
+        case op_enter: {
+            Node* undefined = addToGraph(JSConstant, OpInfo(m_constantUndefined));
             // Initialize all locals to undefined.
             for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
-                set(virtualRegisterForLocal(i), constantUndefined(), ImmediateNakedSet);
+                set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet);
             if (m_inlineStackTop->m_codeBlock->specializationKind() == CodeForConstruct)
-                set(virtualRegisterForArgument(0), constantUndefined(), ImmediateNakedSet);
+                set(virtualRegisterForArgument(0), undefined, ImmediateNakedSet);
             NEXT_OPCODE(op_enter);
+        }
             
         case op_touch_entry:
             if (m_inlineStackTop->m_codeBlock->symbolTable()->m_functionEnteredOnce.isStillValid())
@@ -2285,7 +2040,6 @@
                     || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis
                     || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
                     || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-                    || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)
                     || (op1->op() == GetLocal && op1->variableAccessData()->structureCheckHoistingFailed())) {
                     setThis(addToGraph(ToThis, op1));
                 } else {
@@ -2302,13 +2056,9 @@
             int calleeOperand = currentInstruction[2].u.operand;
             Node* callee = get(VirtualRegister(calleeOperand));
             bool alreadyEmitted = false;
-            if (callee->op() == WeakJSConstant) {
-                JSCell* cell = callee->weakConstant();
-                ASSERT(cell->inherits(JSFunction::info()));
-                
-                JSFunction* function = jsCast<JSFunction*>(cell);
+            if (JSFunction* function = callee->dynamicCastConstant<JSFunction*>()) {
                 if (Structure* structure = function->allocationStructure()) {
-                    addToGraph(AllocationProfileWatchpoint, OpInfo(function));
+                    addToGraph(AllocationProfileWatchpoint, OpInfo(m_graph.freeze(function)));
                     // The callee is still live up to this point.
                     addToGraph(Phantom, callee);
                     set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(structure)));
@@ -2380,10 +2130,11 @@
                 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadFunction)) {
                 set(VirtualRegister(currentInstruction[1].u.operand), get(VirtualRegister(JSStack::Callee)));
             } else {
+                FrozenValue* frozen = m_graph.freeze(cachedFunction);
                 ASSERT(cachedFunction->inherits(JSFunction::info()));
                 Node* actualCallee = get(VirtualRegister(JSStack::Callee));
-                addToGraph(CheckFunction, OpInfo(cachedFunction), actualCallee);
-                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(WeakJSConstant, OpInfo(cachedFunction)));
+                addToGraph(CheckFunction, OpInfo(frozen), actualCallee);
+                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(JSConstant, OpInfo(frozen)));
             }
             NEXT_OPCODE(op_get_callee);
         }
@@ -2447,7 +2198,7 @@
             int srcDst = currentInstruction[1].u.operand;
             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
             Node* op = get(srcDstVirtualRegister);
-            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, one())));
+            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
             NEXT_OPCODE(op_inc);
         }
 
@@ -2455,7 +2206,7 @@
             int srcDst = currentInstruction[1].u.operand;
             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
             Node* op = get(srcDstVirtualRegister);
-            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, one())));
+            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
             NEXT_OPCODE(op_dec);
         }
 
@@ -2672,7 +2423,7 @@
 
         case op_eq_null: {
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, constantNull()));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull))));
             NEXT_OPCODE(op_eq_null);
         }
 
@@ -2692,7 +2443,7 @@
 
         case op_neq_null: {
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, constantNull())));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)))));
             NEXT_OPCODE(op_neq_null);
         }
 
@@ -2817,7 +2568,7 @@
         case op_jeq_null: {
             unsigned relativeOffset = currentInstruction[2].u.operand;
             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
-            Node* condition = addToGraph(CompareEqConstant, value, constantNull());
+            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jeq_null))), condition);
             LAST_OPCODE(op_jeq_null);
         }
@@ -2825,7 +2576,7 @@
         case op_jneq_null: {
             unsigned relativeOffset = currentInstruction[2].u.operand;
             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
-            Node* condition = addToGraph(CompareEqConstant, value, constantNull());
+            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jneq_null), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jneq_null);
         }
@@ -2914,7 +2665,7 @@
                 unsigned target = m_currentIndex + table.branchOffsets[i];
                 if (target == data.fallThrough.bytecodeIndex())
                     continue;
-                data.cases.append(SwitchCase::withBytecodeIndex(jsNumber(static_cast<int32_t>(table.min + i)), target));
+                data.cases.append(SwitchCase::withBytecodeIndex(m_graph.freeze(jsNumber(static_cast<int32_t>(table.min + i))), target));
             }
             flushIfTerminal(data);
             addToGraph(Switch, OpInfo(&data), get(VirtualRegister(currentInstruction[3].u.operand)));
@@ -3065,7 +2816,8 @@
             ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer));
             addToGraph(
                 CheckFunction,
-                OpInfo(actualPointerFor(m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)),
+                OpInfo(m_graph.freeze(static_cast<JSCell*>(actualPointerFor(
+                    m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)))),
                 get(VirtualRegister(currentInstruction[1].u.operand)));
             addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr)));
             LAST_OPCODE(op_jneq_ptr);
@@ -3084,7 +2836,7 @@
             case GlobalVar:
             case GlobalPropertyWithVarInjectionChecks:
             case GlobalVarWithVarInjectionChecks:
-                set(VirtualRegister(dst), cellConstant(m_inlineStackTop->m_codeBlock->globalObject()));
+                set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop->m_codeBlock->globalObject()));
                 break;
             case ClosureVar:
             case ClosureVarWithVarInjectionChecks: {
@@ -3092,7 +2844,7 @@
                 if (activation
                     && activation->symbolTable()->m_functionEnteredOnce.isStillValid()) {
                     addToGraph(FunctionReentryWatchpoint, OpInfo(activation->symbolTable()));
-                    set(VirtualRegister(dst), cellConstant(activation));
+                    set(VirtualRegister(dst), weakJSConstant(activation));
                     break;
                 }
                 set(VirtualRegister(dst),
@@ -3141,7 +2893,7 @@
                 Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().onlyStructure());
                 addToGraph(Phantom, get(VirtualRegister(scope)));
                 if (JSValue specificValue = status[0].specificValue())
-                    set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
+                    set(VirtualRegister(dst), weakJSConstant(specificValue.asCell()));
                 else
                     set(VirtualRegister(dst), handleGetByOffset(prediction, base, identifierNumber, operand));
                 break;
@@ -3160,7 +2912,7 @@
                 }
                 
                 addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
-                set(VirtualRegister(dst), inferredConstant(specificValue));
+                set(VirtualRegister(dst), weakJSConstant(specificValue));
                 break;
             }
             case ClosureVar:
@@ -3176,7 +2928,7 @@
                         if (JSValue value = watchpointSet->inferredValue()) {
                             addToGraph(Phantom, scopeNode);
                             addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
-                            set(VirtualRegister(dst), inferredConstant(value));
+                            set(VirtualRegister(dst), weakJSConstant(value));
                             break;
                         }
                     }
@@ -3277,7 +3029,7 @@
         }
             
         case op_init_lazy_reg: {
-            set(VirtualRegister(currentInstruction[1].u.operand), getJSConstantForValue(JSValue()));
+            set(VirtualRegister(currentInstruction[1].u.operand), jsConstant(JSValue()));
             ASSERT(operandIsLocal(currentInstruction[1].u.operand));
             m_graph.m_lazyVars.set(VirtualRegister(currentInstruction[1].u.operand).toLocal());
             NEXT_OPCODE(op_init_lazy_reg);
@@ -3432,13 +3184,6 @@
     
     for (size_t i = 0; i < m_codeBlock->numberOfIdentifiers(); ++i)
         m_identifierMap.add(m_codeBlock->identifier(i).impl(), i);
-    for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i) {
-        JSValue value = m_codeBlock->getConstant(i + FirstConstantRegisterIndex);
-        if (!value)
-            m_emptyJSValueIndex = i + FirstConstantRegisterIndex;
-        else
-            m_jsValueMap.add(JSValue::encode(value), i + FirstConstantRegisterIndex);
-    }
     
     m_haveBuiltOperandMaps = true;
 }
@@ -3536,7 +3281,6 @@
         byteCodeParser->buildOperandMapsIfNecessary();
         
         m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
-        m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
         m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
         m_switchRemap.resize(codeBlock->numberOfSwitchJumpTables());
 
@@ -3547,24 +3291,6 @@
                 byteCodeParser->m_graph.identifiers().addLazily(rep);
             m_identifierRemap[i] = result.iterator->value;
         }
-        for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) {
-            JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex);
-            if (!value) {
-                if (byteCodeParser->m_emptyJSValueIndex == UINT_MAX) {
-                    byteCodeParser->m_emptyJSValueIndex = byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex;
-                    byteCodeParser->addConstant(JSValue());
-                    byteCodeParser->m_constants.append(ConstantRecord());
-                }
-                m_constantRemap[i] = byteCodeParser->m_emptyJSValueIndex;
-                continue;
-            }
-            JSValueMap::AddResult result = byteCodeParser->m_jsValueMap.add(JSValue::encode(value), byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex);
-            if (result.isNewEntry) {
-                byteCodeParser->addConstant(value);
-                byteCodeParser->m_constants.append(ConstantRecord());
-            }
-            m_constantRemap[i] = result.iterator->value;
-        }
         for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) {
             // If we inline the same code block multiple times, we don't want to needlessly
             // duplicate its constant buffers.
@@ -3595,13 +3321,10 @@
         m_inlineCallFrame = 0;
 
         m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
-        m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
         m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
         m_switchRemap.resize(codeBlock->numberOfSwitchJumpTables());
         for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i)
             m_identifierRemap[i] = i;
-        for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i)
-            m_constantRemap[i] = i + FirstConstantRegisterIndex;
         for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i)
             m_constantBufferRemap[i] = i;
         for (size_t i = 0; i < codeBlock->numberOfSwitchJumpTables(); ++i)
@@ -3609,14 +3332,13 @@
         m_callsiteBlockHeadNeedsLinking = false;
     }
     
-    for (size_t i = 0; i < m_constantRemap.size(); ++i)
-        ASSERT(m_constantRemap[i] >= static_cast<unsigned>(FirstConstantRegisterIndex));
-    
     byteCodeParser->m_inlineStackTop = this;
 }
 
 void ByteCodeParser::parseCodeBlock()
 {
+    prepareToParseBlock();
+    
     CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
     
     if (m_graph.compilation()) {
diff --git a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
index 46b6021..78c3e9f 100644
--- a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
@@ -79,6 +79,19 @@
             performForwardCFA();
         } while (m_changed);
         
+        if (m_graph.m_form != SSA) {
+            // Make sure we record the intersection of all proofs that we ever allowed the
+            // compiler to rely upon.
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                block->intersectionOfCFAHasVisited &= block->cfaHasVisited;
+                for (unsigned i = block->intersectionOfPastValuesAtHead.size(); i--;)
+                    block->intersectionOfPastValuesAtHead[i].filter(block->valuesAtHead[i]);
+            }
+        }
+        
         return true;
     }
     
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
index 8d29fbc..c7dd0b1 100644
--- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
@@ -150,7 +150,7 @@
                     
                     // Switch on constant -> jettison all other targets and merge.
                     if (block->last()->child1()->hasConstant()) {
-                        JSValue value = m_graph.valueOfJSConstant(block->last()->child1().node());
+                        FrozenValue* value = block->last()->child1()->constant();
                         TriState found = FalseTriState;
                         BasicBlock* targetBlock = 0;
                         for (unsigned i = data->cases.size(); found == FalseTriState && i--;) {
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 5f0670e..8726b5a 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -39,13 +39,10 @@
 
 namespace JSC { namespace DFG {
 
-enum CSEMode { NormalCSE, StoreElimination };
-
-template<CSEMode cseMode>
 class CSEPhase : public Phase {
 public:
     CSEPhase(Graph& graph)
-        : Phase(graph, cseMode == NormalCSE ? "common subexpression elimination" : "store elimination")
+        : Phase(graph, "common subexpression elimination")
     {
     }
     
@@ -168,22 +165,7 @@
             if (otherNode->op() != node->op())
                 continue;
             
-            if (otherNode->constantNumber() != node->constantNumber())
-                continue;
-            
-            return otherNode;
-        }
-        return 0;
-    }
-    
-    Node* weakConstantCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock->at(i);
-            if (otherNode->op() != WeakJSConstant)
-                continue;
-            
-            if (otherNode->weakConstant() != node->weakConstant())
+            if (otherNode->constant() != node->constant())
                 continue;
             
             return otherNode;
@@ -313,68 +295,6 @@
         return false;
     }
     
-    Node* globalVarStoreElimination(WriteBarrier<Unknown>* registerPointer)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case PutGlobalVar:
-                if (node->registerPointer() == registerPointer)
-                    return node;
-                break;
-                
-            case GetGlobalVar:
-                if (node->registerPointer() == registerPointer)
-                    return 0;
-                break;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node) || node->canExit())
-                return 0;
-        }
-        return 0;
-    }
-    
-    Node* scopedVarStoreElimination(Node* scope, Node* registers, int varNumber)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case PutClosureVar: {
-                if (node->varNumber() != varNumber)
-                    break;
-                if (node->child1() == scope && node->child2() == registers)
-                    return node;
-                return 0;
-            }
-                
-            case GetClosureVar: {
-                // Let's be conservative.
-                if (node->varNumber() == varNumber)
-                    return 0;
-                break;
-            }
-                
-            case GetLocal:
-            case SetLocal: {
-                VariableAccessData* variableAccessData = node->variableAccessData();
-                if (variableAccessData->isCaptured()
-                    && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
-                    return 0;
-                break;
-            }
-
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node) || node->canExit())
-                return 0;
-        }
-        return 0;
-    }
-    
     Node* getByValLoadElimination(Node* child1, Node* child2, ArrayMode arrayMode)
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -420,7 +340,7 @@
         return 0;
     }
 
-    bool checkFunctionElimination(JSCell* function, Node* child1)
+    bool checkFunctionElimination(FrozenValue* function, Node* child1)
     {
         for (unsigned i = endIndexForPureCSE(); i--;) {
             Node* node = m_currentBlock->at(i);
@@ -556,73 +476,6 @@
         return false;
     }
     
-    Node* putStructureStoreElimination(Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1)
-                break;
-            switch (node->op()) {
-            case CheckStructure:
-                return 0;
-                
-            case PhantomPutStructure:
-                if (node->child1() == child1) // No need to retrace our steps.
-                    return 0;
-                break;
-                
-            case PutStructure:
-                if (node->child1() == child1)
-                    return node;
-                break;
-                
-            // PutStructure needs to execute if we GC. Hence this needs to
-            // be careful with respect to nodes that GC.
-            case CreateArguments:
-            case TearOffArguments:
-            case NewFunctionNoCheck:
-            case NewFunction:
-            case NewFunctionExpression:
-            case CreateActivation:
-            case TearOffActivation:
-            case ToPrimitive:
-            case NewRegexp:
-            case NewArrayBuffer:
-            case NewArray:
-            case NewObject:
-            case CreateThis:
-            case AllocatePropertyStorage:
-            case ReallocatePropertyStorage:
-            case TypeOf:
-            case ToString:
-            case NewStringObject:
-            case MakeRope:
-            case NewTypedArray:
-            case MultiPutByOffset:
-                return 0;
-                
-            // This either exits, causes a GC (lazy string allocation), or clobbers
-            // the world. The chances of it not doing any of those things are so
-            // slim that we might as well not even try to reason about it.
-            case GetByVal:
-                return 0;
-                
-            case GetIndexedPropertyStorage:
-                if (node->arrayMode().getIndexedPropertyStorageMayTriggerGC())
-                    return 0;
-                break;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node) || node->canExit())
-                return 0;
-            if (edgesUseStructure(m_graph, node))
-                return 0;
-        }
-        return 0;
-    }
-    
     Node* getByOffsetLoadElimination(unsigned identifierNumber, Node* base)
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -713,55 +566,6 @@
         return 0;
     }
     
-    Node* putByOffsetStoreElimination(unsigned identifierNumber, Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1)
-                break;
-
-            switch (node->op()) {
-            case GetByOffset:
-                if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber)
-                    return 0;
-                break;
-                
-            case PutByOffset:
-                if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber) {
-                    if (node->child1() == child1) // Must be same property storage.
-                        return node;
-                    return 0;
-                }
-                break;
-                
-            case MultiPutByOffset:
-                if (node->multiPutByOffsetData().identifierNumber == identifierNumber)
-                    return 0;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-            case GetByVal:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
-            if (node->canExit())
-                return 0;
-        }
-        return 0;
-    }
-    
     Node* getPropertyStorageLoadElimination(Node* child1)
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -944,7 +748,7 @@
         return 0;
     }
     
-    bool uncapturedSetLocalStoreElimination(VirtualRegister local, Node* expectedNode)
+    Node* uncapturedSetLocalStoreElimination(VirtualRegister local)
     {
         for (unsigned i = m_indexInBlock; i--;) {
             Node* node = m_currentBlock->at(i);
@@ -952,26 +756,24 @@
             case GetLocal:
             case Flush:
                 if (node->local() == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case GetLocalUnlinked:
                 if (node->unlinkedLocal() == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case SetLocal: {
                 if (node->local() != local)
                     break;
-                if (node != expectedNode)
-                    return false;
-                return true;
+                return node;
             }
                 
             case GetClosureVar:
             case PutClosureVar:
                 if (static_cast<VirtualRegister>(node->varNumber()) == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case GetMyScope:
@@ -979,24 +781,24 @@
                 if (node->origin.semantic.inlineCallFrame)
                     break;
                 if (m_graph.uncheckedActivationRegister() == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case CheckArgumentsNotCreated:
             case GetMyArgumentsLength:
             case GetMyArgumentsLengthSafe:
                 if (m_graph.uncheckedArgumentsRegisterFor(node->origin.semantic) == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case GetMyArgumentByVal:
             case GetMyArgumentByValSafe:
-                return false;
+                return nullptr;
                 
             case GetByVal:
                 // If this is accessing arguments then it's potentially accessing locals.
                 if (node->arrayMode().type() == Array::Arguments)
-                    return false;
+                    return nullptr;
                 break;
                 
             case CreateArguments:
@@ -1006,19 +808,18 @@
                 // are live. We could be clever here and check if the local qualifies as an
                 // argument register. But that seems like it would buy us very little since
                 // any kind of tear offs are rare to begin with.
-                return false;
+                return nullptr;
                 
             default:
                 break;
             }
             if (m_graph.clobbersWorld(node))
-                return false;
+                return nullptr;
         }
-        RELEASE_ASSERT_NOT_REACHED();
-        return false;
+        return nullptr;
     }
 
-    bool capturedSetLocalStoreElimination(VirtualRegister local, Node* expectedNode)
+    Node* capturedSetLocalStoreElimination(VirtualRegister local)
     {
         for (unsigned i = m_indexInBlock; i--;) {
             Node* node = m_currentBlock->at(i);
@@ -1026,20 +827,18 @@
             case GetLocal:
             case Flush:
                 if (node->local() == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case GetLocalUnlinked:
                 if (node->unlinkedLocal() == local)
-                    return false;
+                    return nullptr;
                 break;
                 
             case SetLocal: {
                 if (node->local() != local)
                     break;
-                if (node != expectedNode)
-                    return false;
-                return true;
+                return node;
             }
                 
             case Phantom:
@@ -1052,18 +851,17 @@
                 break;
                 
             default:
-                return false;
+                return nullptr;
             }
         }
-        RELEASE_ASSERT_NOT_REACHED();
-        return false;
+        return nullptr;
     }
     
-    bool setLocalStoreElimination(VariableAccessData* variableAccessData, Node* expectedNode)
+    Node* setLocalStoreElimination(VariableAccessData* variableAccessData)
     {
         if (variableAccessData->isCaptured())
-            return capturedSetLocalStoreElimination(variableAccessData->local(), expectedNode);
-        return uncapturedSetLocalStoreElimination(variableAccessData->local(), expectedNode);
+            return capturedSetLocalStoreElimination(variableAccessData->local());
+        return uncapturedSetLocalStoreElimination(variableAccessData->local());
     }
     
     bool invalidationPointElimination()
@@ -1143,14 +941,11 @@
     
     void performNodeCSE(Node* node)
     {
-        if (cseMode == NormalCSE)
-            m_graph.performSubstitution(node);
+        m_graph.performSubstitution(node);
         
         switch (node->op()) {
         
         case Identity:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(node->child1().node());
             break;
             
@@ -1189,8 +984,6 @@
         case ValueRep:
         case Int52Rep:
         case BooleanToNumber:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(pureCSE(node));
             break;
             
@@ -1202,8 +995,6 @@
         case ArithMod:
         case UInt32ToNumber:
         case DoubleAsInt32: {
-            if (cseMode == StoreElimination)
-                break;
             Node* candidate = pureCSE(node);
             if (!candidate)
                 break;
@@ -1217,14 +1008,10 @@
         }
             
         case GetCallee:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getCalleeLoadElimination());
             break;
 
         case GetLocal: {
-            if (cseMode == StoreElimination)
-                break;
             VariableAccessData* variableAccessData = node->variableAccessData();
             if (!variableAccessData->isCaptured())
                 break;
@@ -1251,83 +1038,28 @@
         }
             
         case GetLocalUnlinked: {
-            if (cseMode == StoreElimination)
-                break;
             Node* relevantLocalOpIgnored;
             setReplacement(getLocalLoadElimination(node->unlinkedLocal(), relevantLocalOpIgnored, true));
             break;
         }
             
-        case Flush: {
-            ASSERT(m_graph.m_form != SSA);
-            VariableAccessData* variableAccessData = node->variableAccessData();
-            if (!node->child1()) {
-                // FIXME: It's silly that we punt on flush-eliminating here. We don't really
-                // need child1 to figure out what's going on.
-                // https://bugs.webkit.org/show_bug.cgi?id=130521
-                break;
-            }
-            Node* replacement = node->child1().node();
-            if (replacement->op() != SetLocal)
-                break;
-            ASSERT(replacement->variableAccessData() == variableAccessData);
-            // FIXME: We should be able to remove SetLocals that can exit; we just need
-            // to replace them with appropriate type checks.
-            if (cseMode == NormalCSE) {
-                // Need to be conservative at this time; if the SetLocal has any chance of performing
-                // any speculations then we cannot do anything.
-                FlushFormat format = variableAccessData->flushFormat();
-                ASSERT(format != DeadFlush);
-                if (format != FlushedJSValue)
-                    break;
-            } else {
-                if (replacement->canExit())
-                    break;
-            }
-            if (!setLocalStoreElimination(variableAccessData, replacement))
-                break;
-            ASSERT(replacement->op() == SetLocal);
-            node->convertToPhantom();
-            Node* dataNode = replacement->child1().node();
-            ASSERT(dataNode->hasResult());
-            node->child1() = dataNode->defaultEdge();
-            m_graph.dethread();
-            m_changed = true;
-            break;
-        }
-            
         case JSConstant:
         case DoubleConstant:
         case Int52Constant:
-            if (cseMode == StoreElimination)
-                break;
             // This is strange, but necessary. Some phases will convert nodes to constants,
             // which may result in duplicated constants. We use CSE to clean this up.
             setReplacement(constantCSE(node));
             break;
             
-        case WeakJSConstant:
-            if (cseMode == StoreElimination)
-                break;
-            // FIXME: have CSE for weak constants against strong constants and vice-versa.
-            setReplacement(weakConstantCSE(node));
-            break;
-            
         case ConstantStoragePointer:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(constantStoragePointerCSE(node));
             break;
             
         case GetArrayLength:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getArrayLengthElimination(node->child1().node()));
             break;
 
         case GetMyScope:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getMyScopeLoadElimination());
             break;
             
@@ -1338,8 +1070,6 @@
         case CompareGreater:
         case CompareGreaterEq:
         case CompareEq: {
-            if (cseMode == StoreElimination)
-                break;
             if (m_graph.isPredictedNumerical(node)) {
                 Node* replacement = pureCSE(node);
                 if (replacement && m_graph.isPredictedNumerical(replacement))
@@ -1351,49 +1081,26 @@
         // Finally handle heap accesses. These are not quite pure, but we can still
         // optimize them provided that some subtle conditions are met.
         case GetGlobalVar:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(globalVarLoadElimination(node->registerPointer()));
             break;
 
         case GetClosureVar: {
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(scopedVarLoadElimination(node->child1().node(), node->varNumber()));
             break;
         }
 
         case VarInjectionWatchpoint:
-            if (cseMode == StoreElimination)
-                break;
             if (varInjectionWatchpointElimination())
                 eliminate();
             break;
             
-        case PutGlobalVar:
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(globalVarStoreElimination(node->registerPointer()));
-            break;
-            
-        case PutClosureVar: {
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(scopedVarStoreElimination(node->child1().node(), node->child2().node(), node->varNumber()));
-            break;
-        }
-
         case GetByVal:
-            if (cseMode == StoreElimination)
-                break;
             if (m_graph.byValIsPure(node))
                 setReplacement(getByValLoadElimination(node->child1().node(), node->child2().node(), node->arrayMode()));
             break;
                 
         case PutByValDirect:
         case PutByVal: {
-            if (cseMode == StoreElimination)
-                break;
             Edge child1 = m_graph.varArgChild(node, 0);
             Edge child2 = m_graph.varArgChild(node, 1);
             if (node->arrayMode().canCSEStorage()) {
@@ -1406,42 +1113,26 @@
         }
             
         case CheckStructure:
-            if (cseMode == StoreElimination)
-                break;
             if (checkStructureElimination(node->structureSet(), node->child1().node()))
                 eliminate();
             break;
             
-        case PutStructure:
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(putStructureStoreElimination(node->child1().node()), PhantomPutStructure);
-            break;
-
         case CheckFunction:
-            if (cseMode == StoreElimination)
-                break;
             if (checkFunctionElimination(node->function(), node->child1().node()))
                 eliminate();
             break;
                 
         case CheckExecutable:
-            if (cseMode == StoreElimination)
-                break;
             if (checkExecutableElimination(node->executable(), node->child1().node()))
                 eliminate();
             break;
                 
         case CheckArray:
-            if (cseMode == StoreElimination)
-                break;
             if (checkArrayElimination(node->child1().node(), node->arrayMode()))
                 eliminate();
             break;
             
         case GetIndexedPropertyStorage: {
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getIndexedPropertyStorageLoadElimination(node->child1().node(), node->arrayMode()));
             break;
         }
@@ -1449,42 +1140,26 @@
         case GetTypedArrayByteOffset:
         case GetGetter:
         case GetSetter: {
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getInternalFieldLoadElimination(node->op(), node->child1().node()));
             break;
         }
 
         case GetButterfly:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getPropertyStorageLoadElimination(node->child1().node()));
             break;
 
         case GetByOffset:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child2().node()));
             break;
             
         case GetGetterSetterByOffset:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getGetterSetterByOffsetLoadElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child2().node()));
             break;
             
         case MultiGetByOffset:
-            if (cseMode == StoreElimination)
-                break;
             setReplacement(getByOffsetLoadElimination(node->multiGetByOffsetData().identifierNumber, node->child1().node()));
             break;
             
-        case PutByOffset:
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(putByOffsetStoreElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child1().node()));
-            break;
-            
         case InvalidationPoint:
             if (invalidationPointElimination())
                 eliminate();
@@ -1498,6 +1173,23 @@
             eliminateIrrelevantPhantomChildren(node);
             break;
             
+        case Flush:
+            // This is needed for arguments simplification to work. We need to eliminate the
+            // redundancy between op_enter's undefined-all-the-things and the subsequent
+            // op_init_lazy_reg.
+            
+            ASSERT(m_graph.m_form != SSA);
+            
+            if (Node* setLocal = setLocalStoreElimination(node->variableAccessData())) {
+                node->convertToPhantom();
+                Node* dataNode = setLocal->child1().node();
+                ASSERT(dataNode->hasResult());
+                node->child1() = dataNode->defaultEdge();
+                m_graph.dethread();
+                m_changed = true;
+            }
+            break;
+            
         default:
             // do nothing.
             break;
@@ -1521,12 +1213,6 @@
             m_currentNode = block->at(m_indexInBlock);
             performNodeCSE(m_currentNode);
         }
-        
-        if (!ASSERT_DISABLED && cseMode == StoreElimination) {
-            // Nobody should have replacements set.
-            for (unsigned i = 0; i < block->size(); ++i)
-                ASSERT(!block->at(i)->misc.replacement);
-        }
     }
     
     BasicBlock* m_currentBlock;
@@ -1539,13 +1225,7 @@
 bool performCSE(Graph& graph)
 {
     SamplingRegion samplingRegion("DFG CSE Phase");
-    return runPhase<CSEPhase<NormalCSE>>(graph);
-}
-
-bool performStoreElimination(Graph& graph)
-{
-    SamplingRegion samplingRegion("DFG Store Elimination Phase");
-    return runPhase<CSEPhase<StoreElimination>>(graph);
+    return runPhase<CSEPhase>(graph);
 }
 
 } } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.h b/Source/JavaScriptCore/dfg/DFGCSEPhase.h
index 8f857ad..3e88479 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.h
@@ -40,9 +40,6 @@
 // on a few benchmarks, and is relatively cheap to run.
 bool performCSE(Graph&);
 
-// Perform just block-local store elimination.
-bool performStoreElimination(Graph&);
-
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index ed967a5..9dd040b 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -76,7 +76,6 @@
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-    case WeakJSConstant:
     case Identity:
     case Phantom:
     case HardPhantom:
@@ -202,6 +201,8 @@
     case ArrayPop:
     case Call:
     case Construct:
+    case NativeCall:
+    case NativeConstruct:
     case ToPrimitive:
     case In:
     case GetMyArgumentsLengthSafe:
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 5b08fe4..c2574f2 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -146,6 +146,8 @@
     FixupPass
 };
 
+enum StructureWatchpointState { HaveNotStartedWatching, WatchingAllWatchableStructures };
+
 enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
 
 // Describes the form you can expect the entire graph to be in.
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index 39cd8bf..339bb44 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -62,6 +62,16 @@
                 changed |= foldConstants(block);
         }
         
+        if (changed && m_graph.m_form == SSA) {
+            // It's now possible that we have Upsilons pointed at JSConstants. Fix that.
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                fixUpsilons(block);
+            }
+        }
+         
         return changed;
     }
 
@@ -123,7 +133,7 @@
             }
                 
             case CheckFunction: {
-                if (m_state.forNode(node->child1()).value() != node->function())
+                if (m_state.forNode(node->child1()).value() != node->function()->value())
                     break;
                 node->convertToPhantom();
                 eliminated = true;
@@ -157,7 +167,7 @@
                     if (!variant.structureSet().contains(structure))
                         continue;
                     
-                    if (variant.chain())
+                    if (variant.alternateBase())
                         break;
                     
                     emitGetByOffset(indexInBlock, node, structure, variant, data.identifierNumber);
@@ -204,7 +214,8 @@
                 GetByIdStatus status = GetByIdStatus::computeFor(
                     vm(), structure, m_graph.identifiers()[identifierNumber]);
                 
-                if (!status.isSimple() || status.numVariants() != 1) {
+                if (!status.isSimple() || status.numVariants() != 1 ||
+                    !status[0].constantChecks().isEmpty() || status[0].alternateBase()) {
                     // FIXME: We could handle prototype cases.
                     // https://bugs.webkit.org/show_bug.cgi?id=110386
                     break;
@@ -252,6 +263,34 @@
                 node->convertToIdentity();
                 break;
             }
+                
+            case GetMyArgumentByVal: {
+                InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
+                JSValue value = m_state.forNode(node->child1()).m_value;
+                if (inlineCallFrame && value && value.isInt32()) {
+                    int32_t index = value.asInt32();
+                    if (index >= 0
+                        && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
+                        // Roll the interpreter over this.
+                        m_interpreter.execute(indexInBlock);
+                        eliminated = true;
+                        
+                        int operand =
+                            inlineCallFrame->stackOffset +
+                            m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index);
+                        
+                        m_insertionSet.insertNode(
+                            indexInBlock, SpecNone, CheckArgumentsNotCreated, node->origin);
+                        m_insertionSet.insertNode(
+                            indexInBlock, SpecNone, Phantom, node->origin, node->children);
+                        
+                        node->convertToGetLocalUnlinked(VirtualRegister(operand));
+                        break;
+                    }
+                }
+                
+                break;
+            }
 
             default:
                 break;
@@ -280,32 +319,21 @@
             }
             if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant())
                 continue;
-            JSValue value = m_state.forNode(node).value();
-            if (!value)
+            
+            // 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)
                 continue;
             
-            // Check if merging the abstract value of the constant into the abstract value
-            // we've proven for this node wouldn't widen the proof. If it widens the proof
-            // (i.e. says that the set contains more things in it than it previously did)
-            // then we refuse to fold.
-            AbstractValue oldValue = m_state.forNode(node);
-            AbstractValue constantValue;
-            constantValue.set(m_graph, value, m_state.structureClobberState());
-            constantValue.fixTypeForRepresentation(node);
-            if (oldValue.merge(constantValue))
-                continue;
-                
             NodeOrigin origin = node->origin;
             AdjacencyList children = node->children;
             
-            if (node->op() == GetLocal)
-                m_graph.dethread();
-            else
-                ASSERT(!node->hasVariableAccessData(m_graph));
-            
             m_graph.convertToConstant(node, value);
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, Phantom, origin, children);
+            if (!children.isEmpty()) {
+                m_insertionSet.insertNode(
+                    indexInBlock, SpecNone, Phantom, origin, children);
+            }
             
             changed = true;
         }
@@ -323,7 +351,7 @@
 
         bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
         
-        ASSERT(!variant.chain());
+        ASSERT(!variant.alternateBase());
         ASSERT_UNUSED(structure, variant.structureSet().contains(structure));
         
         // Now before we do anything else, push the CFA forward over the GetById
@@ -337,7 +365,7 @@
         }
         
         if (variant.specificValue()) {
-            m_graph.convertToConstant(node, variant.specificValue());
+            m_graph.convertToConstant(node, m_graph.freeze(variant.specificValue()));
             return;
         }
         
@@ -386,23 +414,11 @@
         if (variant.kind() == PutByIdVariant::Transition) {
             transition = m_graph.m_transitions.add(structure, variant.newStructure());
 
-            if (node->op() == PutById) {
-                if (!structure->storedPrototype().isNull()) {
-                    addStructureTransitionCheck(
-                        origin, indexInBlock,
-                        structure->storedPrototype().asCell());
-                }
-
-                m_graph.chains().addLazily(variant.structureChain());
-
-                for (unsigned i = 0; i < variant.structureChain()->size(); ++i) {
-                    JSValue prototype = variant.structureChain()->at(i)->storedPrototype();
-                    if (prototype.isNull())
-                        continue;
-                    ASSERT(prototype.isCell());
-                    addStructureTransitionCheck(
-                        origin, indexInBlock, prototype.asCell());
-                }
+            for (unsigned i = 0; i < variant.constantChecks().size(); ++i) {
+                addStructureTransitionCheck(
+                    origin, indexInBlock,
+                    variant.constantChecks()[i].constant(),
+                    variant.constantChecks()[i].structure());
             }
         }
 
@@ -454,17 +470,39 @@
         m_graph.m_storageAccessData.append(storageAccessData);
     }
 
-    void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell)
+    void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell, Structure* structure)
     {
         if (m_graph.watchpoints().consider(cell->structure()))
             return;
 
         Node* weakConstant = m_insertionSet.insertNode(
-            indexInBlock, speculationFromValue(cell), WeakJSConstant, origin, OpInfo(cell));
+            indexInBlock, speculationFromValue(cell), JSConstant, origin,
+            OpInfo(m_graph.freeze(cell)));
         
         m_insertionSet.insertNode(
             indexInBlock, SpecNone, CheckStructure, origin,
-            OpInfo(m_graph.addStructureSet(cell->structure())), Edge(weakConstant, CellUse));
+            OpInfo(m_graph.addStructureSet(structure)), Edge(weakConstant, CellUse));
+    }
+    
+    void fixUpsilons(BasicBlock* block)
+    {
+        for (unsigned nodeIndex = block->size(); nodeIndex--;) {
+            Node* node = block->at(nodeIndex);
+            if (node->op() != Upsilon)
+                continue;
+            switch (node->phi()->op()) {
+            case Phi:
+                break;
+            case JSConstant:
+            case DoubleConstant:
+            case Int52Constant:
+                node->convertToPhantom();
+                break;
+            default:
+                DFG_CRASH(m_graph, node, "Bad Upsilon phi() pointer");
+                break;
+            }
+        }
     }
     
     InPlaceAbstractState m_state;
diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
index 54c1769..8c44b65 100644
--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
@@ -46,7 +46,6 @@
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-    case WeakJSConstant:
     case Identity:
     case GetCallee:
     case GetLocal:
@@ -119,6 +118,8 @@
     case CompareStrictEq:
     case Call:
     case Construct:
+    case NativeCall:
+    case NativeConstruct:
     case Breakpoint:
     case ProfileWillCall:
     case ProfileDidCall:
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 4c49417..6496905 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -712,38 +712,6 @@
                 fixIntOrBooleanEdge(node->child1());
             else if (node->child1()->shouldSpeculateNumberOrBoolean())
                 fixDoubleOrBooleanEdge(node->child1());
-
-            Node* logicalNot = node->child1().node();
-            if (logicalNot->op() == LogicalNot) {
-                
-                // Make sure that OSR exit can't observe the LogicalNot. If it can,
-                // then we must compute it and cannot peephole around it.
-                bool found = false;
-                bool ok = true;
-                for (unsigned i = m_indexInBlock; i--;) {
-                    Node* candidate = m_block->at(i);
-                    if (candidate == logicalNot) {
-                        found = true;
-                        break;
-                    }
-                    if (candidate->canExit()) {
-                        ok = false;
-                        found = true;
-                        break;
-                    }
-                }
-                ASSERT_UNUSED(found, found);
-                
-                if (ok) {
-                    Edge newChildEdge = logicalNot->child1();
-                    if (newChildEdge->hasBooleanResult()) {
-                        node->children.setChild1(newChildEdge);
-                        
-                        BranchData* data = node->branchData();
-                        std::swap(data->taken, data->notTaken);
-                    }
-                }
-            }
             break;
         }
             
@@ -848,7 +816,8 @@
                     m_indexInBlock, SpecNone, Phantom, node->origin,
                     Edge(node->child1().node(), OtherUse));
                 observeUseKindOnNode<OtherUse>(node->child1().node());
-                node->convertToWeakConstant(m_graph.globalThisObjectFor(node->origin.semantic));
+                m_graph.convertToConstant(
+                    node, m_graph.globalThisObjectFor(node->origin.semantic));
                 break;
             }
             
@@ -1040,8 +1009,8 @@
         
         case PutGlobalVar: {
             Node* globalObjectNode = m_insertionSet.insertNode(
-                m_indexInBlock, SpecNone, WeakJSConstant, node->origin, 
-                OpInfo(m_graph.globalObjectFor(node->origin.semantic)));
+                m_indexInBlock, SpecNone, JSConstant, node->origin, 
+                OpInfo(m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic))));
             // FIXME: This probably shouldn't have an unconditional barrier.
             // https://bugs.webkit.org/show_bug.cgi?id=133104
             Node* barrierNode = m_graph.addNode(
@@ -1073,7 +1042,6 @@
         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
         case SetArgument:
         case JSConstant:
-        case WeakJSConstant:
         case GetLocal:
         case GetCallee:
         case Flush:
@@ -1088,6 +1056,8 @@
         case AllocationProfileWatchpoint:
         case Call:
         case Construct:
+        case NativeCall:
+        case NativeConstruct:
         case NewObject:
         case NewArrayBuffer:
         case NewRegexp:
@@ -1199,9 +1169,9 @@
             if (!edge)
                 break;
             edge.setUseKind(KnownStringUse);
-            if (!m_graph.isConstant(edge.node()))
+            JSString* string = edge->dynamicCastConstant<JSString*>();
+            if (!string)
                 continue;
-            JSString* string = jsCast<JSString*>(m_graph.valueOfJSConstant(edge.node()).asCell());
             if (string->length())
                 continue;
             
@@ -1666,27 +1636,15 @@
     {
         Node* oldNode = edge.node();
         
-        ASSERT(oldNode->hasConstant());
-        JSValue value = m_graph.valueOfJSConstant(oldNode);
+        JSValue value = oldNode->asJSValue();
         if (value.isInt32())
             return;
         
         value = jsNumber(JSC::toInt32(value.asNumber()));
         ASSERT(value.isInt32());
-        unsigned constantRegister;
-        if (!codeBlock()->findConstant(value, constantRegister)) {
-            constantRegister = codeBlock()->addConstantLazily();
-            initializeLazyWriteBarrierForConstant(
-                m_graph.m_plan.writeBarriers,
-                codeBlock()->constants()[constantRegister],
-                codeBlock(),
-                constantRegister,
-                codeBlock()->ownerExecutable(),
-                value);
-        }
         edge.setNode(m_insertionSet.insertNode(
             m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
-            OpInfo(constantRegister)));
+            OpInfo(m_graph.freeze(value))));
     }
     
     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
@@ -1789,7 +1747,7 @@
         
         Node* shiftAmount = m_insertionSet.insertNode(
             m_indexInBlock, SpecInt32, JSConstant, node->origin,
-            OpInfo(m_graph.constantRegisterForConstant(jsNumber(logElementSize(type)))));
+            OpInfo(m_graph.freeze(jsNumber(logElementSize(type)))));
         
         // We can use a BitLShift here because typed arrays will never have a byteLength
         // that overflows int32.
@@ -1933,11 +1891,10 @@
             
             addRequiredPhantom(edge.node());
 
-            if (edge->op() == JSConstant && m_graph.isNumberConstant(edge.node())) {
+            if (edge->isNumberConstant()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecBytecodeDouble, DoubleConstant, node->origin,
-                    OpInfo(m_graph.constantRegisterForConstant(
-                        jsDoubleNumber(m_graph.valueOfNumberConstant(edge.node())))));
+                    OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
             } else if (edge->hasInt52Result()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecInt52AsDouble, DoubleRep, node->origin,
@@ -1958,10 +1915,10 @@
             
             addRequiredPhantom(edge.node());
 
-            if (edge->op() == JSConstant && m_graph.isMachineIntConstant(edge.node())) {
+            if (edge->isMachineIntConstant()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecMachineInt, Int52Constant, node->origin,
-                    OpInfo(edge->constantNumber()));
+                    OpInfo(edge->constant()));
             } else if (edge->hasDoubleResult()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecMachineInt, Int52Rep, node->origin,
diff --git a/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp b/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp
similarity index 71%
rename from Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp
rename to Source/JavaScriptCore/dfg/DFGFrozenValue.cpp
index 259a5db..a62c38d 100644
--- a/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * 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
@@ -24,7 +24,7 @@
  */
 
 #include "config.h"
-#include "DFGDesiredStructureChains.h"
+#include "DFGFrozenValue.h"
 
 #if ENABLE(DFG_JIT)
 
@@ -32,25 +32,24 @@
 
 namespace JSC { namespace DFG {
 
-DesiredStructureChains::DesiredStructureChains() { }
-DesiredStructureChains::~DesiredStructureChains() { }
-
-bool DesiredStructureChains::areStillValid() const
+FrozenValue* FrozenValue::emptySingleton()
 {
-    for (unsigned i = 0; i < m_vector.size(); ++i) {
-        if (!m_vector[i]->isStillValid())
-            return false;
-    }
-    return true;
+    static FrozenValue empty;
+    return &empty;
 }
 
-void DesiredStructureChains::visitChildren(SlotVisitor& visitor)
+void FrozenValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
-    for (unsigned i = m_vector.size(); i--;)
-        m_vector[i]->visitChildren(visitor);
+    if (!!m_value && m_value.isCell())
+        out.print(m_strength, ":");
+    m_value.dumpInContextAssumingStructure(out, context, m_structure);
+}
+
+void FrozenValue::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
 }
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
-
diff --git a/Source/JavaScriptCore/dfg/DFGFrozenValue.h b/Source/JavaScriptCore/dfg/DFGFrozenValue.h
new file mode 100644
index 0000000..d08586f
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGFrozenValue.h
@@ -0,0 +1,119 @@
+/*
+ * 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 "DFGValueStrength.h"
+#include "JSCell.h"
+#include "JSCJSValue.h"
+#include "Structure.h"
+
+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 && value.isCell()) == !!structure);
+        ASSERT(!value || !value.isCell() || value.asCell()->classInfo() == structure->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 && 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& out, DumpContext* context) const;
+    void dump(PrintStream& 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 && value.isCell()) ? value.asCell()->structure() : nullptr,
+            FragileValue);
+    }
+
+    JSValue m_value;
+    Structure* m_structure;
+    ValueStrength m_strength;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGFrozenValue_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 412e35e..94bd0e5 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -60,19 +60,20 @@
     , m_codeBlock(m_plan.codeBlock.get())
     , m_profiledBlock(m_codeBlock->alternative())
     , m_allocator(longLivedState.m_allocator)
-    , m_mustHandleAbstractValues(OperandsLike, plan.mustHandleValues)
+    , m_mustHandleValues(OperandsLike, plan.mustHandleValues)
     , m_hasArguments(false)
     , m_nextMachineLocal(0)
     , m_machineCaptureStart(std::numeric_limits<int>::max())
     , m_fixpointState(BeforeFixpoint)
+    , m_structureWatchpointState(HaveNotStartedWatching)
     , m_form(LoadStore)
     , m_unificationState(LocallyUnified)
     , m_refCountState(EverythingIsLive)
 {
     ASSERT(m_profiledBlock);
     
-    for (unsigned i = m_mustHandleAbstractValues.size(); i--;)
-        m_mustHandleAbstractValues[i].setMostSpecific(*this, plan.mustHandleValues[i]);
+    for (unsigned i = m_mustHandleValues.size(); i--;)
+        m_mustHandleValues[i] = freezeFragile(plan.mustHandleValues[i]);
 }
 
 Graph::~Graph()
@@ -178,7 +179,6 @@
     // (5) The arguments to the operation. The may be of the form:
     //         @#   - a NodeIndex referencing a prior node in the graph.
     //         arg# - an argument number.
-    //         $#   - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }.
     //         id#  - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
     //         var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
     out.printf("% 4d:%s<%c%u:", (int)node->index(), skipped ? "  skipped  " : "           ", mustGenerate ? '!' : ' ', refCount);
@@ -224,9 +224,10 @@
     if (node->hasTransition())
         out.print(comma, pointerDumpInContext(node->transition(), context));
     if (node->hasFunction()) {
-        out.print(comma, "function(", RawPointer(node->function()), ", ");
-        if (node->function()->inherits(JSFunction::info())) {
-            JSFunction* function = jsCast<JSFunction*>(node->function());
+        out.print(comma, "function(", pointerDump(node->function()), ", ");
+        if (node->function()->value().isCell()
+            && node->function()->value().asCell()->inherits(JSFunction::info())) {
+            JSFunction* function = jsCast<JSFunction*>(node->function()->value().asCell());
             if (function->isHostFunction())
                 out.print("<host function>");
             else
@@ -306,7 +307,7 @@
         out.print(node->startConstant(), ":[");
         CommaPrinter anotherComma;
         for (unsigned i = 0; i < node->numConstants(); ++i)
-            out.print(anotherComma, inContext(m_codeBlock->constantBuffer(node->startConstant())[i], context));
+            out.print(anotherComma, pointerDumpInContext(freeze(m_codeBlock->constantBuffer(node->startConstant())[i]), context));
         out.print("]");
     }
     if (node->hasIndexingType())
@@ -323,13 +324,8 @@
         out.print(comma, inContext(JSValue(node->typedArray()), context));
     if (node->hasStoragePointer())
         out.print(comma, RawPointer(node->storagePointer()));
-    if (node->isConstant()) {
-        out.print(comma, "$", node->constantNumber());
-        JSValue value = valueOfJSConstant(node);
-        out.print(" = ", inContext(value, context));
-    }
-    if (op == WeakJSConstant)
-        out.print(comma, RawPointer(node->weakConstant()), " (", inContext(*node->weakConstant()->structure(), context), ")");
+    if (node->isConstant())
+        out.print(comma, pointerDumpInContext(node->constant(), context));
     if (node->isJump())
         out.print(comma, "T:", *node->targetBlock());
     if (node->isBranch())
@@ -368,7 +364,7 @@
 
 void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BasicBlock* block, PhiNodeDumpMode phiNodeDumpMode, DumpContext* context)
 {
-    out.print(prefix, "Block ", *block, " (", inContext(block->at(0)->origin.semantic, context), "):", block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "", block->cfaHasVisited ? "" : " (CFA-unreachable)", "\n");
+    out.print(prefix, "Block ", *block, " (", inContext(block->at(0)->origin.semantic, context), "):", block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
     if (block->executionCount == block->executionCount)
         out.print(prefix, "  Execution count: ", block->executionCount, "\n");
     out.print(prefix, "  Predecessors:");
@@ -451,7 +447,12 @@
         if (!block)
             continue;
         dumpBlockHeader(out, "", block, DumpAllPhis, context);
-        out.print("  States: ", block->cfaStructureClobberStateAtHead, "\n");
+        out.print("  States: ", block->cfaStructureClobberStateAtHead);
+        if (!block->cfaHasVisited)
+            out.print(", CurrentlyCFAUnreachable");
+        if (!block->intersectionOfCFAHasVisited)
+            out.print(", CFAUnreachable");
+        out.print("\n");
         switch (m_form) {
         case LoadStore:
         case ThreadedCPS: {
@@ -461,6 +462,12 @@
             else
                 out.print("<empty>");
             out.print("\n");
+            out.print("  Intersected Vars Before: ");
+            if (block->intersectionOfCFAHasVisited)
+                out.print(inContext(block->intersectionOfPastValuesAtHead, context));
+            else
+                out.print("<empty>");
+            out.print("\n");
             out.print("  Var Links: ", block->variablesAtHead, "\n");
             break;
         }
@@ -477,7 +484,10 @@
             dump(out, "", block->at(i), context);
             lastNode = block->at(i);
         }
-        out.print("  States: ", block->cfaBranchDirection, ", ", block->cfaStructureClobberStateAtTail, "\n");
+        out.print("  States: ", block->cfaBranchDirection, ", ", block->cfaStructureClobberStateAtTail);
+        if (!block->cfaDidFinish)
+            out.print(", CFAInvalidated");
+        out.print("\n");
         switch (m_form) {
         case LoadStore:
         case ThreadedCPS: {
@@ -588,17 +598,6 @@
     }
 }
 
-void Graph::resetExitStates()
-{
-    for (BlockIndex blockIndex = 0; blockIndex < m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = m_blocks[blockIndex].get();
-        if (!block)
-            continue;
-        for (unsigned indexInBlock = block->size(); indexInBlock--;)
-            block->at(indexInBlock)->setCanExit(true);
-    }
-}
-
 void Graph::invalidateCFG()
 {
     m_dominators.invalidate();
@@ -792,9 +791,7 @@
 
 JSActivation* Graph::tryGetActivation(Node* node)
 {
-    if (!node->hasConstant())
-        return 0;
-    return jsDynamicCast<JSActivation*>(valueOfJSConstant(node));
+    return node->dynamicCastConstant<JSActivation*>();
 }
 
 WriteBarrierBase<Unknown>* Graph::tryGetRegisters(Node* node)
@@ -809,13 +806,11 @@
 
 JSArrayBufferView* Graph::tryGetFoldableView(Node* node)
 {
-    if (!node->hasConstant())
-        return 0;
-    JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(valueOfJSConstant(node));
+    JSArrayBufferView* view = node->dynamicCastConstant<JSArrayBufferView*>();
     if (!view)
-        return 0;
+        return nullptr;
     if (!view->length())
-        return 0;
+        return nullptr;
     WTF::loadLoadFence();
     return view;
 }
@@ -832,8 +827,43 @@
     return tryGetFoldableView(child(node, 0).node(), node->arrayMode());
 }
 
+void Graph::registerFrozenValues()
+{
+    m_codeBlock->constants().resize(0);
+    for (FrozenValue* value : m_frozenValues) {
+        if (value->structure() && value->structure()->dfgShouldWatch())
+            m_plan.weakReferences.addLazily(value->structure());
+        
+        switch (value->strength()) {
+        case FragileValue: {
+            break;
+        }
+        case WeakValue: {
+            m_plan.weakReferences.addLazily(value->value().asCell());
+            break;
+        }
+        case StrongValue: {
+            unsigned constantIndex = m_codeBlock->addConstantLazily();
+            initializeLazyWriteBarrierForConstant(
+                m_plan.writeBarriers,
+                m_codeBlock->constants()[constantIndex],
+                m_codeBlock,
+                constantIndex,
+                m_codeBlock->ownerExecutable(),
+                value->value());
+            break;
+        } }
+    }
+    m_codeBlock->constants().shrinkToFit();
+}
+
 void Graph::visitChildren(SlotVisitor& visitor)
 {
+    for (FrozenValue* value : m_frozenValues) {
+        visitor.appendUnbarrieredReadOnlyValue(value->value());
+        visitor.appendUnbarrieredReadOnlyPointer(value->structure());
+    }
+    
     for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
         BasicBlock* block = this->block(blockIndex);
         if (!block)
@@ -843,15 +873,6 @@
             Node* node = block->at(nodeIndex);
             
             switch (node->op()) {
-            case JSConstant:
-            case WeakJSConstant:
-                visitor.appendUnbarrieredReadOnlyValue(valueOfJSConstant(node));
-                break;
-                
-            case CheckFunction:
-                visitor.appendUnbarrieredReadOnlyPointer(node->function());
-                break;
-                
             case CheckExecutable:
                 visitor.appendUnbarrieredReadOnlyPointer(node->executable());
                 break;
@@ -909,8 +930,60 @@
     }
 }
 
+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->value;
+    
+    return result.iterator->value = m_frozenValues.add(FrozenValue::freeze(value));
+}
+
+FrozenValue* Graph::freeze(JSValue value)
+{
+    FrozenValue* result = freezeFragile(value);
+    result->strengthenTo(WeakValue);
+    return result;
+}
+
+FrozenValue* Graph::freezeStrong(JSValue value)
+{
+    FrozenValue* result = freeze(value);
+    result->strengthenTo(StrongValue);
+    return result;
+}
+
+void Graph::convertToConstant(Node* node, FrozenValue* value)
+{
+    if (value->structure())
+        assertIsWatched(value->structure());
+    if (m_form == ThreadedCPS) {
+        if (node->op() == GetLocal)
+            dethread();
+        else
+            ASSERT(!node->hasVariableAccessData(*this));
+    }
+    node->convertToConstant(value);
+}
+
+void Graph::convertToConstant(Node* node, JSValue value)
+{
+    convertToConstant(node, freeze(value));
+}
+
+void Graph::convertToStrongConstant(Node* node, JSValue value)
+{
+    convertToConstant(node, freezeStrong(value));
+}
+
 void Graph::assertIsWatched(Structure* structure)
 {
+    if (m_structureWatchpointState == HaveNotStartedWatching)
+        return;
+    
     if (!structure->dfgShouldWatch())
         return;
     if (watchpoints().isWatched(structure->transitionWatchpointSet()))
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 3e596e4..5a55c8a 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -33,6 +33,7 @@
 #include "DFGArgumentPosition.h"
 #include "DFGBasicBlock.h"
 #include "DFGDominators.h"
+#include "DFGFrozenValue.h"
 #include "DFGLongLivedState.h"
 #include "DFGNaturalLoops.h"
 #include "DFGNode.h"
@@ -145,43 +146,16 @@
 
     void dethread();
     
-    void convertToConstant(Node* node, unsigned constantNumber)
-    {
-        if (node->op() == GetLocal)
-            dethread();
-        else
-            ASSERT(!node->hasVariableAccessData(*this));
-        node->convertToConstant(constantNumber);
-    }
+    FrozenValue* freezeFragile(JSValue value);
+    FrozenValue* freeze(JSValue value); // We use weak freezing by default.
+    FrozenValue* freezeStrong(JSValue value); // Shorthand for freeze(value)->markStrongly().
     
-    unsigned constantRegisterForConstant(JSValue value)
-    {
-        unsigned constantRegister;
-        if (!m_codeBlock->findConstant(value, constantRegister)) {
-            constantRegister = m_codeBlock->addConstantLazily();
-            initializeLazyWriteBarrierForConstant(
-                m_plan.writeBarriers,
-                m_codeBlock->constants()[constantRegister],
-                m_codeBlock,
-                constantRegister,
-                m_codeBlock->ownerExecutable(),
-                value);
-        }
-        return constantRegister;
-    }
+    void convertToConstant(Node* node, FrozenValue* value);
+    void convertToConstant(Node* node, JSValue value);
+    void convertToStrongConstant(Node* node, JSValue value);
     
     void assertIsWatched(Structure* structure);
     
-    void convertToConstant(Node* node, JSValue value)
-    {
-        if (value.isCell())
-            assertIsWatched(value.asCell()->structure());
-        if (value.isObject())
-            node->convertToWeakConstant(value.asCell());
-        else
-            convertToConstant(node, constantRegisterForConstant(value));
-    }
-
     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
     void dump(PrintStream& = WTF::dataFile(), DumpContext* = 0);
     enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
@@ -195,11 +169,6 @@
     // preceding node. Returns true if anything was printed.
     bool dumpCodeOrigin(PrintStream&, const char* prefix, Node* previousNode, Node* currentNode, DumpContext*);
 
-    SpeculatedType getJSConstantSpeculation(Node* node)
-    {
-        return speculationFromValue(node->valueOfJSConstant(m_codeBlock));
-    }
-    
     AddSpeculationMode addSpeculationMode(Node* add, bool leftShouldSpeculateInt32, bool rightShouldSpeculateInt32, PredictionPass pass)
     {
         ASSERT(add->op() == ValueAdd || add->op() == ArithAdd || add->op() == ArithSub);
@@ -315,92 +284,6 @@
             baselineCodeBlockFor(codeOrigin)->argumentIndexAfterCapture(argument));
     }
     
-    // Helper methods to check nodes for constants.
-    bool isConstant(Node* node)
-    {
-        return node->hasConstant();
-    }
-    bool isJSConstant(Node* node)
-    {
-        return node->hasConstant();
-    }
-    bool isInt32Constant(Node* node)
-    {
-        return node->isInt32Constant(m_codeBlock);
-    }
-    bool isDoubleConstant(Node* node)
-    {
-        return node->isDoubleConstant(m_codeBlock);
-    }
-    bool isNumberConstant(Node* node)
-    {
-        return node->isNumberConstant(m_codeBlock);
-    }
-    bool isMachineIntConstant(Node* node)
-    {
-        return node->isMachineIntConstant(m_codeBlock);
-    }
-    bool isBooleanConstant(Node* node)
-    {
-        return node->isBooleanConstant(m_codeBlock);
-    }
-    bool isCellConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        JSValue value = valueOfJSConstant(node);
-        return value.isCell() && !!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->inherits(InternalFunction::info()))
-            return false;
-        return true;
-    }
-    // Helper methods get constant values from nodes.
-    JSValue valueOfJSConstant(Node* node)
-    {
-        return node->valueOfJSConstant(m_codeBlock);
-    }
-    int32_t valueOfInt32Constant(Node* node)
-    {
-        JSValue value = valueOfJSConstant(node);
-        if (!value.isInt32()) {
-            dataLog("Value isn't int32: ", value, "\n");
-            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<JSFunction*>(function);
-    }
-
     static const char *opName(NodeType);
     
     StructureSet* addStructureSet(const StructureSet& structureSet)
@@ -686,8 +569,6 @@
     void determineReachability();
     void resetReachability();
     
-    void resetExitStates();
-    
     unsigned varArgNumChildren(Node* node)
     {
         ASSERT(node->flags() & NodeHasVarArgs);
@@ -800,7 +681,6 @@
     
     DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
     DesiredWatchpoints& watchpoints() { return m_plan.watchpoints; }
-    DesiredStructureChains& chains() { return m_plan.chains; }
     
     FullBytecodeLiveness& livenessFor(CodeBlock*);
     FullBytecodeLiveness& livenessFor(InlineCallFrame*);
@@ -818,6 +698,8 @@
     JSArrayBufferView* tryGetFoldableView(Node*, ArrayMode);
     JSArrayBufferView* tryGetFoldableViewForChild1(Node*);
     
+    void registerFrozenValues();
+    
     virtual void visitChildren(SlotVisitor&) override;
     
     NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
@@ -831,10 +713,14 @@
     
     NodeAllocator& m_allocator;
 
-    Operands<AbstractValue> m_mustHandleAbstractValues;
+    Operands<FrozenValue*> m_mustHandleValues;
     
     Vector< RefPtr<BasicBlock> , 8> m_blocks;
     Vector<Edge, 16> m_varArgChildren;
+
+    HashMap<EncodedJSValue, FrozenValue*, EncodedJSValueHash, EncodedJSValueHashTraits> m_frozenValueMap;
+    Bag<FrozenValue> m_frozenValues;
+    
     Vector<StorageAccessData> m_storageAccessData;
     Vector<Node*, 8> m_arguments;
     SegmentedVector<VariableAccessData, 16> m_variableAccessData;
@@ -865,6 +751,7 @@
 #endif
     
     OptimizationFixpointState m_fixpointState;
+    StructureWatchpointState m_structureWatchpointState;
     GraphForm m_form;
     UnificationState m_unificationState;
     RefCountState m_refCountState;
@@ -877,7 +764,7 @@
     {
         ASSERT(immediate->hasConstant());
         
-        JSValue immediateValue = immediate->valueOfJSConstant(m_codeBlock);
+        JSValue immediateValue = immediate->asJSValue();
         if (!immediateValue.isNumber() && !immediateValue.isBoolean())
             return DontSpeculateInt32;
         
diff --git a/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
index feda66d..b5cd536 100644
--- a/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
@@ -151,17 +151,18 @@
             continue;
         if (block->bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex)
             continue;
-        for (size_t i = 0; i < m_graph.m_mustHandleAbstractValues.size(); ++i) {
-            int operand = m_graph.m_mustHandleAbstractValues.operandForIndex(i);
+        for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) {
+            int operand = m_graph.m_mustHandleValues.operandForIndex(i);
             Node* node = block->variablesAtHead.operand(operand);
             if (!node)
                 continue;
-            AbstractValue value = m_graph.m_mustHandleAbstractValues[i];
-            AbstractValue& abstractValue = block->valuesAtHead.operand(operand);
+            AbstractValue source;
+            source.setOSREntryValue(m_graph, *m_graph.m_mustHandleValues[i]);
+            AbstractValue& target = block->valuesAtHead.operand(operand);
             VariableAccessData* variable = node->variableAccessData();
             FlushFormat format = variable->flushFormat();
-            abstractValue.merge(value);
-            abstractValue.fixTypeForRepresentation(resultFor(format));
+            target.merge(source);
+            target.fixTypeForRepresentation(resultFor(format));
         }
         block->cfaShouldRevisit = true;
     }
diff --git a/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h b/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h
index 9a54623..297418f 100644
--- a/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h
@@ -128,6 +128,12 @@
     void setStructureClobberState(StructureClobberState value) { m_structureClobberState = value; }
     void setIsValid(bool isValid) { m_isValid = isValid; }
     void setBranchDirection(BranchDirection branchDirection) { m_branchDirection = branchDirection; }
+    
+    // This method is evil - it causes a huge maintenance headache and there is a gross amount of
+    // code devoted to it. It would be much nicer to just always run the constant folder on each
+    // block. But, the last time we did it, it was a 1% SunSpider regression:
+    // https://bugs.webkit.org/show_bug.cgi?id=133947
+    // So, we should probably keep this method.
     void setFoundConstants(bool foundConstants) { m_foundConstants = foundConstants; }
 
 private:
diff --git a/Source/JavaScriptCore/dfg/DFGInsertionSet.h b/Source/JavaScriptCore/dfg/DFGInsertionSet.h
index a44616b..3c8483a 100644
--- a/Source/JavaScriptCore/dfg/DFGInsertionSet.h
+++ b/Source/JavaScriptCore/dfg/DFGInsertionSet.h
@@ -62,23 +62,21 @@
     }
     
     Node* insertConstant(
-        size_t index, NodeOrigin origin, JSValue value,
+        size_t index, NodeOrigin origin, FrozenValue* value,
         NodeType op = JSConstant)
     {
-        unsigned constantReg =
-            m_graph.constantRegisterForConstant(value);
         return insertNode(
-            index, speculationFromValue(value), op, origin, OpInfo(constantReg));
+            index, speculationFromValue(value->value()), op, origin, OpInfo(value));
     }
     
     Node* insertConstant(
-        size_t index, CodeOrigin origin, JSValue value, NodeType op = JSConstant)
+        size_t index, CodeOrigin origin, FrozenValue* value, NodeType op = JSConstant)
     {
         return insertConstant(index, NodeOrigin(origin), value, op);
     }
     
     Edge insertConstantForUse(
-        size_t index, NodeOrigin origin, JSValue value, UseKind useKind)
+        size_t index, NodeOrigin origin, FrozenValue* value, UseKind useKind)
     {
         NodeType op;
         if (isDouble(useKind))
@@ -91,7 +89,27 @@
     }
     
     Edge insertConstantForUse(
-        size_t index, CodeOrigin origin, JSValue value, UseKind useKind)
+        size_t index, CodeOrigin origin, FrozenValue* value, UseKind useKind)
+    {
+        return insertConstantForUse(index, NodeOrigin(origin), value, useKind);
+    }
+
+    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);
     }
diff --git a/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp b/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp
index 96fdc68..36f8f0e 100644
--- a/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp
@@ -311,11 +311,11 @@
             if (node->arithMode() != Arith::CheckOverflow
                 && node->arithMode() != Arith::CheckOverflowAndNegativeZero)
                 break;
-            if (!m_graph.isInt32Constant(node->child2().node()))
+            if (!node->child2()->isInt32Constant())
                 break;
             return RangeKeyAndAddend(
                 RangeKey::addition(node->child1()),
-                m_graph.valueOfInt32Constant(node->child2().node()));
+                node->child2()->asInt32());
         }
                 
         case CheckInBounds: {
@@ -325,15 +325,15 @@
             
             Edge index = node->child1();
             
-            if (m_graph.isInt32Constant(index.node())) {
+            if (index->isInt32Constant()) {
                 source = Edge();
-                addend = m_graph.valueOfInt32Constant(index.node());
+                addend = index->asInt32();
             } else if (
                 index->op() == ArithAdd
                 && index->isBinaryUseKind(Int32Use)
-                && m_graph.isInt32Constant(index->child2().node())) {
+                && index->child2()->isInt32Constant()) {
                 source = index->child1();
-                addend = m_graph.valueOfInt32Constant(index->child2().node());
+                addend = index->child2()->asInt32();
             } else {
                 source = index;
                 addend = 0;
@@ -341,7 +341,7 @@
             
             return RangeKeyAndAddend(RangeKey::arrayBounds(source, key), addend);
         }
-                
+            
         default:
             break;
         }
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 6d2c207..91ad212 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -162,6 +162,8 @@
 #if USE(JSVALUE32_64)
     m_jitCode->common.doubleConstants = WTF::move(m_graph.m_doubleConstants);
 #endif
+    
+    m_graph.registerFrozenValues();
 
     BitVector usedJumpTables;
     for (Bag<SwitchData>::iterator iter = m_graph.m_switchData.begin(); !!iter; ++iter) {
@@ -439,11 +441,7 @@
 #if USE(JSVALUE32_64)
 void* JITCompiler::addressOfDoubleConstant(Node* node)
 {
-    ASSERT(m_graph.isNumberConstant(node));
-    JSValue jsvalue = node->valueOfJSConstant(codeBlock());
-    ASSERT(jsvalue.isDouble());
-
-    double value = jsvalue.asDouble();
+    double value = node->asNumber();
     int64_t valueBits = bitwise_cast<int64_t>(value);
     auto it = m_graph.m_doubleConstantsMap.find(valueBits);
     if (it != m_graph.m_doubleConstantsMap.end())
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index 24c27de..70aae71 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -271,12 +271,12 @@
     void noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
     {
         // OSR entry is not allowed into blocks deemed unreachable by control flow analysis.
-        if (!basicBlock.cfaHasVisited)
+        if (!basicBlock.intersectionOfCFAHasVisited)
             return;
         
         OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
         
-        entry->m_expectedValues = basicBlock.valuesAtHead;
+        entry->m_expectedValues = basicBlock.intersectionOfPastValuesAtHead;
         
         // Fix the expected values: in our protocol, a dead variable will have an expected
         // value of (None, []). But the old JIT may stash some values there. So we really
diff --git a/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp b/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
index 334e6ba..5d12da6 100644
--- a/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
@@ -62,13 +62,14 @@
 public:
     LICMPhase(Graph& graph)
         : Phase(graph, "LICM")
+        , m_state(graph)
         , m_interpreter(graph, m_state)
     {
     }
     
     bool run()
     {
-        ASSERT(m_graph.m_form == SSA);
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
         
         m_graph.m_dominators.computeIfNecessary(m_graph);
         m_graph.m_naturalLoops.computeIfNecessary(m_graph);
@@ -123,11 +124,11 @@
                 BasicBlock* predecessor = header->predecessors[i];
                 if (m_graph.m_dominators.dominates(header, predecessor))
                     continue;
-                RELEASE_ASSERT(!preHeader || preHeader == predecessor);
+                DFG_ASSERT(m_graph, nullptr, !preHeader || preHeader == predecessor);
                 preHeader = predecessor;
             }
             
-            RELEASE_ASSERT(preHeader->last()->op() == Jump);
+            DFG_ASSERT(m_graph, preHeader->last(), preHeader->last()->op() == Jump);
             
             data.preHeader = preHeader;
         }
@@ -267,7 +268,7 @@
         // It just so happens that all of the nodes we currently know how to hoist
         // don't have var-arg children. That may change and then we can fix this
         // code. But for now we just assert that's the case.
-        RELEASE_ASSERT(!(node->flags() & NodeHasVarArgs));
+        DFG_ASSERT(m_graph, node, !(node->flags() & NodeHasVarArgs));
         
         nodeRef = m_graph.addNode(SpecNone, Phantom, originalOrigin, node->children);
         
diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
index 76d2c51..244c7ed 100644
--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,14 +36,14 @@
 {
     switch (m_kind) {
     case KnownValue:
-        return value();
+        return value()->value();
     case SingleCharacterString:
         return jsSingleCharacterString(&vm, u.character);
     case KnownStringImpl:
         return jsString(&vm, u.stringImpl);
     }
     RELEASE_ASSERT_NOT_REACHED();
-    return value();
+    return JSValue();
 }
 
 static TriState equalToSingleCharacter(JSValue value, UChar character)
@@ -81,11 +81,11 @@
     case KnownValue:
         switch (other.m_kind) {
         case KnownValue:
-            return JSValue::pureStrictEqual(value(), other.value());
+            return JSValue::pureStrictEqual(value()->value(), other.value()->value());
         case SingleCharacterString:
-            return equalToSingleCharacter(value(), other.character());
+            return equalToSingleCharacter(value()->value(), other.character());
         case KnownStringImpl:
-            return equalToStringImpl(value(), other.stringImpl());
+            return equalToStringImpl(value()->value(), other.stringImpl());
         }
         break;
     case SingleCharacterString:
@@ -117,7 +117,7 @@
 {
     switch (m_kind) {
     case KnownValue:
-        value().dumpInContext(out, context);
+        value()->dumpInContext(out, context);
         return;
     case SingleCharacterString:
         out.print("Lazy:SingleCharacterString(");
diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.h b/Source/JavaScriptCore/dfg/DFGLazyJSValue.h
index a391855..0b8187b 100644
--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.h
+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "JSCJSValue.h"
+#include "DFGFrozenValue.h"
 #include <wtf/text/StringImpl.h>
 
 namespace JSC { namespace DFG {
@@ -44,10 +44,10 @@
 
 class LazyJSValue {
 public:
-    LazyJSValue(JSValue value = JSValue())
+    LazyJSValue(FrozenValue* value = FrozenValue::emptySingleton())
         : m_kind(KnownValue)
     {
-        u.value = JSValue::encode(value);
+        u.value = value;
     }
     
     static LazyJSValue singleCharacterString(UChar character)
@@ -66,19 +66,19 @@
         return result;
     }
     
-    JSValue tryGetValue() const
+    FrozenValue* tryGetValue(Graph&) const
     {
         if (m_kind == KnownValue)
             return value();
-        return JSValue();
+        return nullptr;
     }
     
     JSValue getValue(VM&) const;
     
-    JSValue value() const
+    FrozenValue* value() const
     {
         ASSERT(m_kind == KnownValue);
-        return JSValue::decode(u.value);
+        return u.value;
     }
     
     UChar character() const
@@ -102,7 +102,7 @@
         // for a kind of value that can't.
         switch (m_kind) {
         case KnownValue:
-            return value().asInt32();
+            return value()->value().asInt32();
         case SingleCharacterString:
             return character();
         default:
@@ -116,7 +116,7 @@
     
 private:
     union {
-        EncodedJSValue value;
+        FrozenValue* value;
         UChar character;
         StringImpl* stringImpl;
     } u;
diff --git a/Source/JavaScriptCore/dfg/DFGMayExit.cpp b/Source/JavaScriptCore/dfg/DFGMayExit.cpp
new file mode 100644
index 0000000..188c858
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGMayExit.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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 "config.h"
+#include "DFGMayExit.h"
+
+#include "DFGGraph.h"
+#include "DFGNode.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+class EdgeMayExit {
+public:
+    EdgeMayExit()
+        : m_result(false)
+    {
+    }
+    
+    void operator()(Node*, Edge edge)
+    {
+        m_result |= edge.willHaveCheck();
+    }
+    
+    bool result() const { return m_result; }
+    
+private:
+    bool m_result;
+};
+
+} // anonymous namespace
+
+bool mayExit(Graph& graph, Node* node)
+{
+    switch (node->op()) {
+    case SetArgument:
+    case JSConstant:
+    case DoubleConstant:
+    case Int52Constant:
+    case MovHint:
+    case SetLocal:
+    case Flush:
+    case Phantom:
+    case Check:
+    case HardPhantom:
+    case GetLocal:
+    case LoopHint:
+    case PhantomArguments:
+    case Phi:
+    case Upsilon:
+    case ZombieHint:
+        break;
+        
+    default:
+        // If in doubt, return true.
+        return true;
+    }
+
+    EdgeMayExit functor;
+    DFG_NODE_DO_TO_CHILDREN(graph, node, functor);
+    return functor.result();
+}
+
+} } // namespace JSC::DFG
+
diff --git a/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h b/Source/JavaScriptCore/dfg/DFGMayExit.h
similarity index 70%
rename from Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h
rename to Source/JavaScriptCore/dfg/DFGMayExit.h
index 9343710..e5ae040 100644
--- a/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h
+++ b/Source/JavaScriptCore/dfg/DFGMayExit.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * 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
@@ -23,37 +23,24 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGDesiredStructureChains_h
-#define DFGDesiredStructureChains_h
+#ifndef DFGMayExit_h
+#define DFGMayExit_h
 
 #if ENABLE(DFG_JIT)
 
-#include "IntendedStructureChain.h"
-#include <wtf/Vector.h>
-
 namespace JSC { namespace DFG {
 
-class DesiredStructureChains {
-public:
-    DesiredStructureChains();
-    ~DesiredStructureChains();
-    
-    void addLazily(PassRefPtr<IntendedStructureChain> chain)
-    {
-        m_vector.append(chain);
-    }
-    
-    bool areStillValid() const;
-    
-    void visitChildren(SlotVisitor&);
-    
-private:
-    Vector<RefPtr<IntendedStructureChain>> m_vector;
-};
+class Graph;
+struct Node;
+
+// A *very* conservative approximation of whether or not a node could possibly exit. Usually
+// returns true except in cases where we obviously don't expect an exit.
+
+bool mayExit(Graph&, Node*);
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
 
-#endif // DFGDesiredStructureChains_h
+#endif // DFGMayExit_h
 
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp b/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
index 4d433aa..72b52be 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,10 +39,8 @@
     MinifiedNode result;
     result.m_id = MinifiedID(node);
     result.m_op = node->op();
-    if (hasConstantNumber(node->op()))
-        result.m_info = node->constantNumber();
-    else if (hasWeakConstant(node->op()))
-        result.m_info = bitwise_cast<uintptr_t>(node->weakConstant());
+    if (hasConstant(node->op()))
+        result.m_info = JSValue::encode(node->asJSValue());
     else {
         ASSERT(node->op() == PhantomArguments);
         result.m_info = 0;
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedNode.h b/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
index 0cc35ef..8b3c570 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 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
@@ -42,7 +42,6 @@
     case JSConstant:
     case Int52Constant:
     case DoubleConstant:
-    case WeakJSConstant:
     case PhantomArguments:
         return true;
     default:
@@ -59,22 +58,11 @@
     MinifiedID id() const { return m_id; }
     NodeType op() const { return m_op; }
     
-    bool hasConstant() const { return hasConstantNumber() || hasWeakConstant(); }
+    bool hasConstant() const { return hasConstant(m_op); }
     
-    bool hasConstantNumber() const { return hasConstantNumber(m_op); }
-    
-    unsigned constantNumber() const
+    JSValue constant() const
     {
-        ASSERT(hasConstantNumber(m_op));
-        return m_info;
-    }
-    
-    bool hasWeakConstant() const { return hasWeakConstant(m_op); }
-    
-    JSCell* weakConstant() const
-    {
-        ASSERT(hasWeakConstant(m_op));
-        return bitwise_cast<JSCell*>(m_info);
+        return JSValue::decode(bitwise_cast<EncodedJSValue>(m_info));
     }
     
     static MinifiedID getID(MinifiedNode* node) { return node->id(); }
@@ -84,17 +72,13 @@
     }
     
 private:
-    static bool hasConstantNumber(NodeType type)
+    static bool hasConstant(NodeType type)
     {
         return type == JSConstant || type == Int52Constant || type == DoubleConstant;
     }
-    static bool hasWeakConstant(NodeType type)
-    {
-        return type == WeakJSConstant;
-    }
     
     MinifiedID m_id;
-    uintptr_t m_info;
+    uint64_t m_info;
     NodeType m_op;
 };
 
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 4404565..fa62cb1 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -323,7 +323,6 @@
     
     bool mergeFlags(NodeFlags flags)
     {
-        ASSERT(!(flags & NodeDoesNotExit));
         NodeFlags newFlags = m_flags | flags;
         if (newFlags == m_flags)
             return false;
@@ -333,7 +332,6 @@
     
     bool filterFlags(NodeFlags flags)
     {
-        ASSERT(flags & NodeDoesNotExit);
         NodeFlags newFlags = m_flags & flags;
         if (newFlags == m_flags)
             return false;
@@ -381,19 +379,6 @@
         return m_flags & NodeMustGenerate;
     }
     
-    void setCanExit(bool exits)
-    {
-        if (exits)
-            m_flags &= ~NodeDoesNotExit;
-        else
-            m_flags |= NodeDoesNotExit;
-    }
-    
-    bool canExit()
-    {
-        return !(m_flags & NodeDoesNotExit);
-    }
-    
     bool isConstant()
     {
         switch (op()) {
@@ -406,11 +391,6 @@
         }
     }
     
-    bool isWeakConstant()
-    {
-        return op() == WeakJSConstant;
-    }
-    
     bool isPhantomArguments()
     {
         return op() == PhantomArguments;
@@ -422,7 +402,6 @@
         case JSConstant:
         case DoubleConstant:
         case Int52Constant:
-        case WeakJSConstant:
         case PhantomArguments:
             return true;
         default:
@@ -430,13 +409,16 @@
         }
     }
 
-    unsigned constantNumber()
+    FrozenValue* constant()
     {
-        ASSERT(isConstant());
-        return m_opInfo;
+        ASSERT(hasConstant());
+        if (op() == PhantomArguments)
+            return FrozenValue::emptySingleton();
+        return bitwise_cast<FrozenValue*>(m_opInfo);
     }
     
-    void convertToConstant(unsigned constantNumber)
+    // Don't call this directly - use Graph::convertToConstant() instead!
+    void convertToConstant(FrozenValue* value)
     {
         if (hasDoubleResult())
             m_op = DoubleConstant;
@@ -445,15 +427,7 @@
         else
             m_op = JSConstant;
         m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
-        m_opInfo = constantNumber;
-        children.reset();
-    }
-    
-    void convertToWeakConstant(JSCell* cell)
-    {
-        m_op = WeakJSConstant;
-        m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
-        m_opInfo = bitwise_cast<uintptr_t>(cell);
+        m_opInfo = bitwise_cast<uintptr_t>(value);
         children.reset();
     }
     
@@ -518,59 +492,79 @@
         m_op = ToString;
     }
     
-    JSCell* weakConstant()
+    JSValue asJSValue()
     {
-        ASSERT(op() == WeakJSConstant);
-        return bitwise_cast<JSCell*>(m_opInfo);
+        return constant()->value();
+    }
+     
+    bool isInt32Constant()
+    {
+        return isConstant() && constant()->value().isInt32();
+    }
+     
+    int32_t asInt32()
+    {
+        return asJSValue().asInt32();
+    }
+     
+    uint32_t asUInt32()
+    {
+        return asInt32();
+    }
+     
+    bool isDoubleConstant()
+    {
+        return isConstant() && constant()->value().isDouble();
+    }
+     
+    bool isNumberConstant()
+    {
+        return isConstant() && constant()->value().isNumber();
     }
     
-    JSValue valueOfJSConstant(CodeBlock* codeBlock)
+    double asNumber()
     {
-        switch (op()) {
-        case WeakJSConstant:
-            return JSValue(weakConstant());
-        case JSConstant:
-        case DoubleConstant:
-        case Int52Constant:
-            return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
-        case PhantomArguments:
-            return JSValue();
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return JSValue(); // Have to return something in release mode.
-        }
+        return asJSValue().asNumber();
     }
-
-    bool isInt32Constant(CodeBlock* codeBlock)
+     
+    bool isMachineIntConstant()
     {
-        return isConstant() && valueOfJSConstant(codeBlock).isInt32();
+        return isConstant() && constant()->value().isMachineInt();
     }
-    
-    bool isDoubleConstant(CodeBlock* codeBlock)
+     
+    int64_t asMachineInt()
     {
-        bool result = isConstant() && valueOfJSConstant(codeBlock).isDouble();
-        if (result)
-            ASSERT(!isInt32Constant(codeBlock));
-        return result;
+        return asJSValue().asMachineInt();
     }
-    
-    bool isNumberConstant(CodeBlock* codeBlock)
+     
+    bool isBooleanConstant()
     {
-        bool result = isConstant() && valueOfJSConstant(codeBlock).isNumber();
-        ASSERT(result == (isInt32Constant(codeBlock) || isDoubleConstant(codeBlock)));
-        return result;
+        return isConstant() && constant()->value().isBoolean();
     }
-    
-    bool isMachineIntConstant(CodeBlock* codeBlock)
+     
+    bool asBoolean()
     {
-        return isConstant() && valueOfJSConstant(codeBlock).isMachineInt();
+        return constant()->value().asBoolean();
     }
-    
-    bool isBooleanConstant(CodeBlock* codeBlock)
+     
+    bool isCellConstant()
     {
-        return isConstant() && valueOfJSConstant(codeBlock).isBoolean();
+        return isConstant() && constant()->value().isCell();
     }
-    
+     
+    JSCell* asCell()
+    {
+        return constant()->value().asCell();
+    }
+     
+    template<typename T>
+    T dynamicCastConstant()
+    {
+        if (!isCellConstant())
+            return nullptr;
+        return jsDynamicCast<T>(asCell());
+    }
+     
     bool containsMovHint()
     {
         switch (op()) {
@@ -983,6 +977,8 @@
         case GetMyArgumentByValSafe:
         case Call:
         case Construct:
+        case NativeCall:
+        case NativeConstruct:
         case GetByOffset:
         case MultiGetByOffset:
         case GetClosureVar:
@@ -1019,8 +1015,8 @@
     bool canBeKnownFunction()
     {
         switch (op()) {
-        case Construct:
-        case Call:
+        case NativeConstruct:
+        case NativeCall:
             return true;
         default:
             return false;
@@ -1030,8 +1026,8 @@
     bool hasKnownFunction()
     {
         switch (op()) {
-        case Construct:
-        case Call:
+        case NativeConstruct:
+        case NativeCall:
             return (bool)m_opInfo;
         default:
             return false;
@@ -1061,12 +1057,10 @@
         }
     }
 
-    JSCell* function()
+    FrozenValue* function()
     {
         ASSERT(hasFunction());
-        JSCell* result = reinterpret_cast<JSFunction*>(m_opInfo);
-        ASSERT(JSValue(result).isFunction());
-        return result;
+        return reinterpret_cast<FrozenValue*>(m_opInfo);
     }
     
     bool hasExecutable()
diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp b/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
index e3181ca..6beb771 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
+++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
@@ -109,9 +109,6 @@
     if (flags & NodeBytecodeUsesAsArrayIndex)
         out.print(comma, "ReallyWantsInt");
     
-    if (!(flags & NodeDoesNotExit))
-        out.print(comma, "CanExit");
-    
     if (flags & NodeIsFlushed)
         out.print(comma, "IsFlushed");
     
diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.h b/Source/JavaScriptCore/dfg/DFGNodeFlags.h
index 8243b75..30abaff 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeFlags.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.h
@@ -66,11 +66,9 @@
 
 #define NodeArithFlagsMask               (NodeBehaviorMask | NodeBytecodeBackPropMask)
 
-#define NodeDoesNotExit                 0x10000 // This flag is negated to make it natural for the default to be that a node does exit.
+#define NodeRelevantToOSR               0x10000
 
-#define NodeRelevantToOSR               0x20000
-
-#define NodeIsFlushed                   0x40000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush.
+#define NodeIsFlushed                   0x20000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush.
 
 typedef uint32_t NodeFlags;
 
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 8bf72f8..d25023c 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -35,15 +35,11 @@
 // This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
 #define FOR_EACH_DFG_OP(macro) \
     /* A constant in the CodeBlock's constant pool. */\
-    macro(JSConstant, NodeResultJS | NodeDoesNotExit) \
+    macro(JSConstant, NodeResultJS) \
     \
     /* Constants with specific representations. */\
-    macro(DoubleConstant, NodeResultDouble | NodeDoesNotExit) \
-    macro(Int52Constant, NodeResultInt52 | NodeDoesNotExit) \
-    \
-    /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
-    /* code block. */\
-    macro(WeakJSConstant, NodeResultJS | NodeDoesNotExit) \
+    macro(DoubleConstant, NodeResultDouble) \
+    macro(Int52Constant, NodeResultInt52) \
     \
     /* Marker to indicate that an operation was optimized entirely and all that is left */\
     /* is to make one node alias another. CSE will later usually eliminate this node, */\
@@ -60,16 +56,16 @@
     /* VariableAccessData, and thus will share predictions. */\
     macro(GetLocal, NodeResultJS) \
     macro(SetLocal, 0) \
-    macro(MovHint, NodeDoesNotExit) \
-    macro(ZombieHint, NodeDoesNotExit) \
+    macro(MovHint, 0) \
+    macro(ZombieHint, 0) \
     macro(GetArgument, NodeResultJS | NodeMustGenerate) \
     macro(Phantom, NodeMustGenerate) \
     macro(HardPhantom, NodeMustGenerate) /* Like Phantom, but we never remove any of its children. */ \
     macro(Check, 0) /* Used if we want just a type check but not liveness. DCE eithers kills this or converts it to Phantom. */\
-    macro(Upsilon, NodeDoesNotExit | NodeRelevantToOSR) \
-    macro(Phi, NodeDoesNotExit | NodeRelevantToOSR) \
-    macro(Flush, NodeMustGenerate | NodeDoesNotExit) \
-    macro(PhantomLocal, NodeMustGenerate | NodeDoesNotExit) \
+    macro(Upsilon, NodeRelevantToOSR) \
+    macro(Phi, NodeRelevantToOSR) \
+    macro(Flush, NodeMustGenerate) \
+    macro(PhantomLocal, NodeMustGenerate) \
     \
     /* Hint that this is where bytecode thinks is a good place to OSR. Note that this */\
     /* will exist even in inlined loops. This has no execution semantics but it must */\
@@ -92,7 +88,7 @@
     macro(GetLocalUnlinked, NodeResultJS) \
     \
     /* Marker for an argument being set at the prologue of a function. */\
-    macro(SetArgument, NodeDoesNotExit) \
+    macro(SetArgument, 0) \
     \
     /* Marker of location in the IR where we may possibly perform jump replacement to */\
     /* invalidate this code block. */\
@@ -159,9 +155,9 @@
     macro(CheckStructure, NodeMustGenerate) \
     macro(CheckExecutable, NodeMustGenerate) \
     macro(PutStructure, NodeMustGenerate) \
-    macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
-    macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
-    macro(ReallocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
+    macro(PhantomPutStructure, NodeMustGenerate) \
+    macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
+    macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
     macro(GetButterfly, NodeResultStorage) \
     macro(CheckArray, NodeMustGenerate) \
     macro(Arrayify, NodeMustGenerate) \
@@ -220,6 +216,8 @@
     /* Calls. */\
     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
     macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
+    macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
+    macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
     \
     /* Allocations. */\
     macro(NewObject, NodeResultJS) \
@@ -258,7 +256,7 @@
     /* Nodes used for arguments. Similar to activation support, only it makes even less */\
     /* sense. */\
     macro(CreateArguments, NodeResultJS) \
-    macro(PhantomArguments, NodeResultJS | NodeDoesNotExit) \
+    macro(PhantomArguments, NodeResultJS) \
     macro(TearOffArguments, NodeMustGenerate) \
     macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
     macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
index 6f7ef0d..cb88962 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
@@ -88,7 +88,7 @@
             
             Profiler::OSRExit* profilerExit = compilation->addOSRExit(
                 exitIndex, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
-                exit.m_kind, isWatchpoint(exit.m_kind));
+                exit.m_kind, exit.m_kind == UncountableInvalidation);
             jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
         }
         
diff --git a/Source/JavaScriptCore/dfg/DFGPlan.cpp b/Source/JavaScriptCore/dfg/DFGPlan.cpp
index a6129c3..a9ad6e5 100644
--- a/Source/JavaScriptCore/dfg/DFGPlan.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPlan.cpp
@@ -239,34 +239,35 @@
     performInvalidationPointInjection(dfg);
     performTypeCheckHoisting(dfg);
     
-    unsigned count = 1;
     dfg.m_fixpointState = FixpointNotConverged;
-    for (;; ++count) {
-        if (logCompilationChanges(mode))
-            dataLogF("DFG beginning optimization fixpoint iteration #%u.\n", count);
-        bool changed = false;
+    
+    // For now we're back to avoiding a fixpoint. Note that we've ping-ponged on this decision
+    // many times. For maximum throughput, it's best to fixpoint. But the throughput benefit is
+    // small and not likely to show up in FTL anyway. On the other hand, not fixpointing means
+    // that the compiler compiles more quickly. We want the third tier to compile quickly, which
+    // not fixpointing accomplishes; and the fourth tier shouldn't need a fixpoint.
+    if (validationEnabled())
+        validate(dfg);
         
-        if (validationEnabled())
-            validate(dfg);
-        
-        changed |= performStrengthReduction(dfg);
+    performStrengthReduction(dfg);
+    performCSE(dfg);
+    performArgumentsSimplification(dfg);
+    performCPSRethreading(dfg);
+    performCFA(dfg);
+    performConstantFolding(dfg);
+    bool changed = false;
+    changed |= performCFGSimplification(dfg);
+    changed |= performCSE(dfg);
+    
+    if (validationEnabled())
+        validate(dfg);
+
+    performCPSRethreading(dfg);
+    if (changed) {
         performCFA(dfg);
-        changed |= performConstantFolding(dfg);
-        changed |= performArgumentsSimplification(dfg);
-        changed |= performCFGSimplification(dfg);
-        changed |= performCSE(dfg);
-        
-        if (!changed)
-            break;
-        
-        performCPSRethreading(dfg);
+        performConstantFolding(dfg);
     }
     
-    if (logCompilationChanges(mode))
-        dataLogF("DFG optimization fixpoint converged in %u iterations.\n", count);
-
-    dfg.m_fixpointState = FixpointConverged;
-
     // If we're doing validation, then run some analyses, to give them an opportunity
     // to self-validate. Now is as good a time as any to do this.
     if (validationEnabled()) {
@@ -276,10 +277,11 @@
 
     switch (mode) {
     case DFGMode: {
+        dfg.m_fixpointState = FixpointConverged;
+    
         performTierUpCheckInjection(dfg);
 
         performStoreBarrierElision(dfg);
-        performStoreElimination(dfg);
         performCPSRethreading(dfg);
         performDCE(dfg);
         performStackLayout(dfg);
@@ -320,12 +322,20 @@
         performStoreBarrierElision(dfg);
         performLivenessAnalysis(dfg);
         performCFA(dfg);
+        performConstantFolding(dfg);
+        if (performStrengthReduction(dfg)) {
+            // State-at-tail and state-at-head will be invalid if we did strength reduction since
+            // it might increase live ranges.
+            performLivenessAnalysis(dfg);
+            performCFA(dfg);
+        }
         performLICM(dfg);
         performIntegerCheckCombining(dfg);
         performCSE(dfg);
         
         // At this point we're not allowed to do any further code motion because our reasoning
         // about code motion assumes that it's OK to insert GC points in random places.
+        dfg.m_fixpointState = FixpointConverged;
         
         performStoreBarrierElision(dfg);
         performLivenessAnalysis(dfg);
@@ -406,8 +416,6 @@
         return false;
     if (!watchpoints.areStillValid())
         return false;
-    if (!chains.areStillValid())
-        return false;
     return true;
 }
 
@@ -477,7 +485,6 @@
     codeBlocks.mark(codeBlock.get());
     codeBlocks.mark(profiledDFGCodeBlock.get());
     
-    chains.visitChildren(visitor);
     weakReferences.visitChildren(visitor);
     writeBarriers.visitChildren(visitor);
     transitions.visitChildren(visitor);
@@ -506,7 +513,6 @@
     inlineCallFrames = nullptr;
     watchpoints = DesiredWatchpoints();
     identifiers = DesiredIdentifiers();
-    chains = DesiredStructureChains();
     weakReferences = DesiredWeakReferences();
     writeBarriers = DesiredWriteBarriers();
     transitions = DesiredTransitions();
diff --git a/Source/JavaScriptCore/dfg/DFGPlan.h b/Source/JavaScriptCore/dfg/DFGPlan.h
index a2fdced..f2de086 100644
--- a/Source/JavaScriptCore/dfg/DFGPlan.h
+++ b/Source/JavaScriptCore/dfg/DFGPlan.h
@@ -30,7 +30,6 @@
 #include "DFGCompilationKey.h"
 #include "DFGCompilationMode.h"
 #include "DFGDesiredIdentifiers.h"
-#include "DFGDesiredStructureChains.h"
 #include "DFGDesiredTransitions.h"
 #include "DFGDesiredWatchpoints.h"
 #include "DFGDesiredWeakReferences.h"
@@ -92,7 +91,6 @@
     RefPtr<InlineCallFrameSet> inlineCallFrames;
     DesiredWatchpoints watchpoints;
     DesiredIdentifiers identifiers;
-    DesiredStructureChains chains;
     DesiredWeakReferences weakReferences;
     DesiredWriteBarriers writeBarriers;
     DesiredTransitions transitions;
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index dd0e387..3c4e44be 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -141,9 +141,8 @@
         bool changed = false;
         
         switch (op) {
-        case JSConstant:
-        case WeakJSConstant: {
-            SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node));
+        case JSConstant: {
+            SpeculatedType type = speculationFromValue(node->asJSValue());
             if (type == SpecInt52AsDouble && enableInt52())
                 type = SpecInt52;
             changed |= setPrediction(type);
@@ -188,6 +187,8 @@
         case MultiGetByOffset:
         case Call:
         case Construct:
+        case NativeCall:
+        case NativeConstruct:
         case GetGlobalVar:
         case GetClosureVar: {
             changed |= setPrediction(node->getHeapPrediction());
diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
index 9dc4352..0054147 100644
--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
@@ -111,7 +111,6 @@
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-    case WeakJSConstant:
     case Identity:
     case ToThis:
     case CreateThis:
@@ -260,7 +259,11 @@
     case GetGetter:
     case GetSetter:
         return true;
-        
+
+    case NativeCall:
+    case NativeConstruct:
+        return false; // TODO: add a check for already checked.  https://bugs.webkit.org/show_bug.cgi?id=133769
+
     case GetByVal:
     case GetIndexedPropertyStorage:
     case GetArrayLength:
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index bed0da1..7cbafdca 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -33,6 +33,7 @@
 #include "DFGArrayifySlowPathGenerator.h"
 #include "DFGBinarySwitch.h"
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
+#include "DFGMayExit.h"
 #include "DFGSaneStringGetByValSlowPathGenerator.h"
 #include "DFGSlowPathGenerator.h"
 #include "LinkBuffer.h"
@@ -215,6 +216,8 @@
         return;
     speculationCheck(kind, jsValueRegs, node, m_jit.jump());
     m_compileOkay = false;
+    if (verboseCompilationEnabled())
+        dataLog("Bailing compilation.\n");
 }
 
 void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Edge nodeUse)
@@ -321,7 +324,7 @@
         ASSERT(info.gpr() == source);
         ASSERT(isJSInt32(info.registerFormat()));
         if (node->hasConstant()) {
-            ASSERT(isInt32Constant(node));
+            ASSERT(node->isInt32Constant());
             fillAction = SetInt32Constant;
         } else
             fillAction = Load32Payload;
@@ -332,7 +335,7 @@
 #elif USE(JSVALUE32_64)
         ASSERT(info.gpr() == source);
         if (node->hasConstant()) {
-            ASSERT(isBooleanConstant(node));
+            ASSERT(node->isBooleanConstant());
             fillAction = SetBooleanConstant;
         } else
             fillAction = Load32Payload;
@@ -340,8 +343,7 @@
     } else if (registerFormat == DataFormatCell) {
         ASSERT(info.gpr() == source);
         if (node->hasConstant()) {
-            JSValue value = valueOfJSConstant(node);
-            ASSERT_UNUSED(value, value.isCell());
+            node->asCell(); // To get the assertion.
             fillAction = SetCellConstant;
         } else {
 #if USE(JSVALUE64)
@@ -384,8 +386,9 @@
 #if USE(JSVALUE64)
         ASSERT(info.gpr() == source);
         if (node->hasConstant()) {
-            if (valueOfJSConstant(node).isCell())
+            if (node->isCellConstant())
                 fillAction = SetTrustedJSConstant;
+            else
                 fillAction = SetJSConstant;
         } else if (info.spillFormat() == DataFormatInt32) {
             ASSERT(registerFormat == DataFormatJSInt32);
@@ -443,7 +446,7 @@
         
 #if USE(JSVALUE64)
     if (node->hasConstant()) {
-        ASSERT(isNumberConstant(node));
+        node->asNumber(); // To get the assertion.
         fillAction = SetDoubleConstant;
     } else {
         ASSERT(info.spillFormat() == DataFormatNone || info.spillFormat() == DataFormatDouble);
@@ -452,7 +455,7 @@
 #elif USE(JSVALUE32_64)
     ASSERT(info.registerFormat() == DataFormatDouble);
     if (node->hasConstant()) {
-        ASSERT(isNumberConstant(node));
+        node->asNumber(); // To get the assertion.
         fillAction = SetDoubleConstant;
     } else
         fillAction = LoadDouble;
@@ -497,21 +500,21 @@
     case DoNothingForFill:
         break;
     case SetInt32Constant:
-        m_jit.move(Imm32(valueOfInt32Constant(plan.node())), plan.gpr());
+        m_jit.move(Imm32(plan.node()->asInt32()), plan.gpr());
         break;
 #if USE(JSVALUE64)
     case SetInt52Constant:
-        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt() << JSValue::int52ShiftAmount), plan.gpr());
+        m_jit.move(Imm64(plan.node()->asMachineInt() << JSValue::int52ShiftAmount), plan.gpr());
         break;
     case SetStrictInt52Constant:
-        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt()), plan.gpr());
+        m_jit.move(Imm64(plan.node()->asMachineInt()), plan.gpr());
         break;
 #endif // USE(JSVALUE64)
     case SetBooleanConstant:
-        m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.node())), plan.gpr());
+        m_jit.move(TrustedImm32(plan.node()->asBoolean()), plan.gpr());
         break;
     case SetCellConstant:
-        m_jit.move(TrustedImmPtr(valueOfJSConstant(plan.node()).asCell()), plan.gpr());
+        m_jit.move(TrustedImmPtr(plan.node()->asCell()), plan.gpr());
         break;
 #if USE(JSVALUE64)
     case SetTrustedJSConstant:
@@ -521,7 +524,7 @@
         m_jit.move(valueOfJSConstantAsImm64(plan.node()), plan.gpr());
         break;
     case SetDoubleConstant:
-        m_jit.move(Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(plan.node()))), canTrample);
+        m_jit.move(Imm64(reinterpretDoubleToInt64(plan.node()->asNumber())), canTrample);
         m_jit.move64ToDouble(canTrample, plan.fpr());
         break;
     case Load32PayloadBoxInt:
@@ -539,10 +542,10 @@
         break;
 #else
     case SetJSConstantTag:
-        m_jit.move(Imm32(valueOfJSConstant(plan.node()).tag()), plan.gpr());
+        m_jit.move(Imm32(plan.node()->asJSValue().tag()), plan.gpr());
         break;
     case SetJSConstantPayload:
-        m_jit.move(Imm32(valueOfJSConstant(plan.node()).payload()), plan.gpr());
+        m_jit.move(Imm32(plan.node()->asJSValue().payload()), plan.gpr());
         break;
     case SetInt32Tag:
         m_jit.move(TrustedImm32(JSValue::Int32Tag), plan.gpr());
@@ -554,7 +557,7 @@
         m_jit.move(TrustedImm32(JSValue::BooleanTag), plan.gpr());
         break;
     case SetDoubleConstant:
-        m_jit.loadDouble(TrustedImmPtr(addressOfDoubleConstant(plan.node())), plan.fpr());
+        m_jit.loadDouble(TrustedImmPtr(m_jit.addressOfDoubleConstant(plan.node())), plan.fpr());
         break;
 #endif
     case Load32Tag:
@@ -856,12 +859,9 @@
 {
     SpeculateCellOperand base(this, node->child2());
     GPRReg baseGPR = base.gpr();
-        
-    if (isConstant(node->child1().node())) {
-        JSString* string =
-            jsDynamicCast<JSString*>(valueOfJSConstant(node->child1().node()));
-        if (string && string->tryGetValueImpl()
-            && string->tryGetValueImpl()->isAtomic()) {
+    
+    if (JSString* string = node->child1()->dynamicCastConstant<JSString*>()) {
+        if (string->tryGetValueImpl() && string->tryGetValueImpl()->isAtomic()) {
             StructureStubInfo* stubInfo = m_jit.codeBlock()->addStubInfo();
             
             GPRTemporary result(this);
@@ -1219,13 +1219,13 @@
         notTaken = tmp;
     }
 
-    if (isBooleanConstant(node->child1().node())) {
-        bool imm = valueOfBooleanConstant(node->child1().node());
+    if (node->child1()->isBooleanConstant()) {
+        bool imm = node->child1()->asBoolean();
         SpeculateBooleanOperand op2(this, node->child2());
         branch32(condition, JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), op2.gpr(), taken);
-    } else if (isBooleanConstant(node->child2().node())) {
+    } else if (node->child2()->isBooleanConstant()) {
         SpeculateBooleanOperand op1(this, node->child1());
-        bool imm = valueOfBooleanConstant(node->child2().node());
+        bool imm = node->child2()->asBoolean();
         branch32(condition, op1.gpr(), JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), taken);
     } else {
         SpeculateBooleanOperand op1(this, node->child1());
@@ -1250,13 +1250,13 @@
         notTaken = tmp;
     }
 
-    if (isInt32Constant(node->child1().node())) {
-        int32_t imm = valueOfInt32Constant(node->child1().node());
+    if (node->child1()->isInt32Constant()) {
+        int32_t imm = node->child1()->asInt32();
         SpeculateInt32Operand op2(this, node->child2());
         branch32(condition, JITCompiler::Imm32(imm), op2.gpr(), taken);
-    } else if (isInt32Constant(node->child2().node())) {
+    } else if (node->child2()->isInt32Constant()) {
         SpeculateInt32Operand op1(this, node->child1());
-        int32_t imm = valueOfInt32Constant(node->child2().node());
+        int32_t imm = node->child2()->asInt32();
         branch32(condition, op1.gpr(), JITCompiler::Imm32(imm), taken);
     } else {
         SpeculateInt32Operand op1(this, node->child1());
@@ -1341,6 +1341,8 @@
 
 void SpeculativeJIT::bail(AbortReason reason)
 {
+    if (verboseCompilationEnabled())
+        dataLog("Bailing compilation.\n");
     m_compileOkay = true;
     m_jit.abortWithReason(reason, m_lastGeneratedNode);
     clearGenerationInfo();
@@ -1357,7 +1359,7 @@
     
     m_jit.blockHeads()[m_block->index] = m_jit.label();
 
-    if (!m_block->cfaHasVisited) {
+    if (!m_block->intersectionOfCFAHasVisited) {
         // Don't generate code for basic blocks that are unreachable according to CFA.
         // But to be sure that nobody has generated a jump to this block, drop in a
         // breakpoint here.
@@ -1404,8 +1406,12 @@
             bail(DFGBailedAtTopOfBlock);
             return;
         }
+
+        if (ASSERT_DISABLED)
+            m_canExit = true; // Essentially disable the assertions.
+        else
+            m_canExit = mayExit(m_jit.graph(), m_currentNode);
         
-        m_canExit = m_currentNode->canExit();
         bool shouldExecuteEffects = m_interpreter.startExecuting(m_currentNode);
         m_jit.setForNode(m_currentNode);
         m_codeOriginForExitTarget = m_currentNode->origin.forExit;
@@ -1417,11 +1423,6 @@
                 m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
                 break;
                 
-            case WeakJSConstant:
-                m_jit.addWeakReference(m_currentNode->weakConstant());
-                m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
-                break;
-                
             case SetLocal:
                 RELEASE_ASSERT_NOT_REACHED();
                 break;
@@ -2071,7 +2072,7 @@
 {
     switch (node->child1().useKind()) {
     case NumberUse: {
-        ASSERT(!isNumberConstant(node->child1().node())); // This should have been constant folded.
+        ASSERT(!node->child1()->isNumberConstant()); // This should have been constant folded.
     
         if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
             SpeculateInt32Operand op1(this, node->child1(), ManualOperandSpeculation);
@@ -2268,7 +2269,7 @@
     if (JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node)) {
         uint32_t length = view->length();
         Node* indexNode = m_jit.graph().child(node, 1).node();
-        if (m_jit.graph().isInt32Constant(indexNode) && static_cast<uint32_t>(m_jit.graph().valueOfInt32Constant(indexNode)) < length)
+        if (indexNode->isInt32Constant() && indexNode->asUInt32() < length)
             return JITCompiler::Jump();
         return m_jit.branch32(
             MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Imm32(length));
@@ -2364,7 +2365,7 @@
     GPRReg valueGPR = InvalidGPRReg;
     
     if (valueUse->isConstant()) {
-        JSValue jsValue = valueOfJSConstant(valueUse.node());
+        JSValue jsValue = valueUse->asJSValue();
         if (!jsValue.isNumber()) {
             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
             noResult(node);
@@ -2652,8 +2653,8 @@
     case Int32Use: {
         ASSERT(!shouldCheckNegativeZero(node->arithMode()));
         
-        if (isInt32Constant(node->child1().node())) {
-            int32_t imm1 = valueOfInt32Constant(node->child1().node());
+        if (node->child1()->isInt32Constant()) {
+            int32_t imm1 = node->child1()->asInt32();
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this);
 
@@ -2667,9 +2668,9 @@
             return;
         }
         
-        if (isInt32Constant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
-            int32_t imm2 = valueOfInt32Constant(node->child2().node());
+            int32_t imm2 = node->child2()->asInt32();
             GPRTemporary result(this);
                 
             if (!shouldCheckOverflow(node->arithMode())) {
@@ -2848,9 +2849,9 @@
     case Int32Use: {
         ASSERT(!shouldCheckNegativeZero(node->arithMode()));
         
-        if (isNumberConstant(node->child2().node())) {
+        if (node->child2()->isNumberConstant()) {
             SpeculateInt32Operand op1(this, node->child1());
-            int32_t imm2 = valueOfInt32Constant(node->child2().node());
+            int32_t imm2 = node->child2()->asInt32();
             GPRTemporary result(this);
 
             if (!shouldCheckOverflow(node->arithMode())) {
@@ -2865,8 +2866,8 @@
             return;
         }
             
-        if (isNumberConstant(node->child1().node())) {
-            int32_t imm1 = valueOfInt32Constant(node->child1().node());
+        if (node->child1()->isNumberConstant()) {
+            int32_t imm1 = node->child1()->asInt32();
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this);
                 
@@ -3279,8 +3280,8 @@
         // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
         SpeculateStrictInt32Operand op1(this, node->child1());
         
-        if (isInt32Constant(node->child2().node())) {
-            int32_t divisor = valueOfInt32Constant(node->child2().node());
+        if (node->child2()->isInt32Constant()) {
+            int32_t divisor = node->child2()->asInt32();
             if (divisor > 1 && hasOneBitSet(divisor)) {
                 unsigned logarithm = WTF::fastLog2(divisor);
                 GPRReg dividendGPR = op1.gpr();
@@ -3341,8 +3342,8 @@
         }
         
 #if CPU(X86) || CPU(X86_64)
-        if (isInt32Constant(node->child2().node())) {
-            int32_t divisor = valueOfInt32Constant(node->child2().node());
+        if (node->child2()->isInt32Constant()) {
+            int32_t divisor = node->child2()->asInt32();
             if (divisor && divisor != -1) {
                 GPRReg op1Gpr = op1.gpr();
 
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 337e466..8f33cb2 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -556,29 +556,6 @@
     bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
     bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
     
-    // 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();
-    }
-
     StringImpl* identifierUID(unsigned index)
     {
         return m_jit.graph().identifiers()[index];
@@ -619,9 +596,9 @@
 #endif
 
 #if USE(JSVALUE64)
-    MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
+    static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
     {
-        return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(node)));
+        return MacroAssembler::Imm64(JSValue::encode(node->asJSValue()));
     }
 #endif
 
@@ -957,7 +934,7 @@
     }
     void initConstantInfo(Node* node)
     {
-        ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node));
+        ASSERT(node->hasConstant());
         generationInfo(node).initConstant(node, node->refCount());
     }
     
@@ -1993,17 +1970,6 @@
 
     void dump(const char* label = 0);
 
-    bool isInteger(Node* node)
-    {
-        if (node->hasInt32Result())
-            return true;
-
-        if (isInt32Constant(node))
-            return true;
-
-        return generationInfo(node).isJSInt32();
-    }
-    
     bool betterUseStrictInt52(Node* node)
     {
         return !generationInfo(node).isInt52();
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 28e4ebb..c9cc105 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -58,11 +58,12 @@
         if (edge->hasConstant()) {
             tagGPR = allocate();
             payloadGPR = allocate();
-            m_jit.move(Imm32(valueOfJSConstant(edge.node()).tag()), tagGPR);
-            m_jit.move(Imm32(valueOfJSConstant(edge.node()).payload()), payloadGPR);
+            JSValue value = edge->asJSValue();
+            m_jit.move(Imm32(value.tag()), tagGPR);
+            m_jit.move(Imm32(value.payload()), payloadGPR);
             m_gprs.retain(tagGPR, virtualRegister, SpillOrderConstant);
             m_gprs.retain(payloadGPR, virtualRegister, SpillOrderConstant);
-            info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(edge.node()) ? DataFormatJSInt32 : DataFormatJS);
+            info.fillJSValue(*m_stream, tagGPR, payloadGPR, DataFormatJS);
         } else {
             DataFormat spillFormat = info.spillFormat();
             ASSERT(spillFormat != DataFormatNone && spillFormat != DataFormatStorage);
@@ -638,14 +639,15 @@
 
 void SpeculativeJIT::emitCall(Node* node)
 {
-    if (node->op() != Call)
+    bool isCall = node->op() == Call;
+    if (!isCall)
         ASSERT(node->op() == Construct);
 
     // For constructors, the this argument is not passed but we have to make space
     // for it.
-    int dummyThisArgument = node->op() == Call ? 0 : 1;
+    int dummyThisArgument = isCall ? 0 : 1;
 
-    CallLinkInfo::CallType callType = node->op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
+    CallLinkInfo::CallType callType = isCall ? CallLinkInfo::Call : CallLinkInfo::Construct;
 
     Edge calleeEdge = m_jit.graph().m_varArgChildren[node->firstChild()];
     JSValueOperand callee(this, calleeEdge);
@@ -736,7 +738,7 @@
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
-    if (edge->hasConstant() && !isInt32Constant(edge.node())) {
+    if (edge->hasConstant() && !edge->isInt32Constant()) {
         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
         returnFormat = DataFormatInt32;
         return allocate();
@@ -745,9 +747,9 @@
     switch (info.registerFormat()) {
     case DataFormatNone: {
         if (edge->hasConstant()) {
-            ASSERT(isInt32Constant(edge.node()));
+            ASSERT(edge->isInt32Constant());
             GPRReg gpr = allocate();
-            m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
+            m_jit.move(MacroAssembler::Imm32(edge->asInt32()), gpr);
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
             info.fillInt32(*m_stream, gpr);
             returnFormat = DataFormatInt32;
@@ -835,9 +837,9 @@
     if (info.registerFormat() == DataFormatNone) {
 
         if (edge->hasConstant()) {
-            RELEASE_ASSERT(isNumberConstant(edge.node()));
+            RELEASE_ASSERT(edge->isNumberConstant());
             FPRReg fpr = fprAllocate();
-            m_jit.loadDouble(TrustedImmPtr(addressOfDoubleConstant(edge.node())), fpr);
+            m_jit.loadDouble(TrustedImmPtr(m_jit.addressOfDoubleConstant(edge.node())), fpr);
             m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
             info.fillDouble(*m_stream, fpr);
             return fpr;
@@ -874,7 +876,7 @@
         }
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             GPRReg gpr = allocate();
             if (jsValue.isCell()) {
                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
@@ -963,7 +965,7 @@
         }
         
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             GPRReg gpr = allocate();
             if (jsValue.isBoolean()) {
                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
@@ -1683,11 +1685,6 @@
         initConstantInfo(node);
         break;
 
-    case WeakJSConstant:
-        m_jit.addWeakReference(node->weakConstant());
-        initConstantInfo(node);
-        break;
-
     case Identity: {
         RELEASE_ASSERT_NOT_REACHED();
         break;
@@ -1699,9 +1696,7 @@
         // If the CFA is tracking this variable and it found that the variable
         // cannot have been assigned, then don't attempt to proceed.
         if (value.isClear()) {
-            // FIXME: We should trap instead.
-            // https://bugs.webkit.org/show_bug.cgi?id=110383
-            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+            m_compileOkay = false;
             break;
         }
         
@@ -1856,18 +1851,18 @@
     case BitAnd:
     case BitOr:
     case BitXor:
-        if (isInt32Constant(node->child1().node())) {
+        if (node->child1()->isInt32Constant()) {
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this, Reuse, op2);
 
-            bitOp(op, valueOfInt32Constant(node->child1().node()), op2.gpr(), result.gpr());
+            bitOp(op, node->child1()->asInt32(), op2.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
-        } else if (isInt32Constant(node->child2().node())) {
+        } else if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            bitOp(op, valueOfInt32Constant(node->child2().node()), op1.gpr(), result.gpr());
+            bitOp(op, node->child2()->asInt32(), op1.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -1886,11 +1881,11 @@
     case BitRShift:
     case BitLShift:
     case BitURShift:
-        if (isInt32Constant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            shiftOp(op, op1.gpr(), valueOfInt32Constant(node->child2().node()) & 0x1f, result.gpr());
+            shiftOp(op, op1.gpr(), node->child2()->asInt32() & 0x1f, result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -2158,7 +2153,7 @@
         break;
         
     case CompareEqConstant:
-        ASSERT(isNullConstant(node->child2().node()));
+        ASSERT(node->child2()->asJSValue().isNull());
         if (nonSpeculativeCompareNull(node, node->child1()))
             return;
         break;
@@ -3693,7 +3688,7 @@
         
     case CheckFunction: {
         SpeculateCellOperand function(this, node->child1());
-        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()));
+        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()->value().asCell()));
         noResult(node);
         break;
     }
@@ -4644,7 +4639,8 @@
         // This is a no-op.
         noResult(node);
         break;
-
+        
+        
     case Unreachable:
         RELEASE_ASSERT_NOT_REACHED();
         break;
@@ -4664,6 +4660,8 @@
     case ArithIMul:
     case MultiGetByOffset:
     case MultiPutByOffset:
+    case NativeCall:
+    case NativeConstruct:
         RELEASE_ASSERT_NOT_REACHED();
         break;
     }
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 4d08a1f..da9e3c2 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -80,21 +80,9 @@
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            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);
-            }
-
+            JSValue jsValue = edge->asJSValue();
+            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
+            info.fillJSValue(*m_stream, gpr, DataFormatJS);
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
         } else {
             DataFormat spillFormat = info.spillFormat();
@@ -637,14 +625,16 @@
 
 void SpeculativeJIT::emitCall(Node* node)
 {
-    if (node->op() != Call)
+
+    bool isCall = node->op() == Call;
+    if (!isCall)
         RELEASE_ASSERT(node->op() == Construct);
 
     // For constructors, the this argument is not passed but we have to make space
     // for it.
-    int dummyThisArgument = node->op() == Call ? 0 : 1;
+    int dummyThisArgument = isCall ? 0 : 1;
     
-    CallLinkInfo::CallType callType = node->op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
+    CallLinkInfo::CallType callType = isCall ? CallLinkInfo::Call : CallLinkInfo::Construct;
     
     Edge calleeEdge = m_jit.graph().m_varArgChildren[node->firstChild()];
     JSValueOperand callee(this, calleeEdge);
@@ -726,7 +716,7 @@
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
-    if (edge->hasConstant() && !isInt32Constant(edge.node())) {
+    if (edge->hasConstant() && !edge->isInt32Constant()) {
         // Protect the silent spill/fill logic by failing early. If we "speculate" on
         // the constant then the silent filler may think that we have an int32 and a
         // constant, so it will try to fill this as an int32 constant. Bad things will
@@ -742,8 +732,8 @@
 
         if (edge->hasConstant()) {
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-            ASSERT(isInt32Constant(edge.node()));
-            m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
+            ASSERT(edge->isInt32Constant());
+            m_jit.move(MacroAssembler::Imm32(edge->asInt32()), gpr);
             info.fillInt32(*m_stream, gpr);
             returnFormat = DataFormatInt32;
             return gpr;
@@ -878,7 +868,7 @@
 
     switch (info.registerFormat()) {
     case DataFormatNone: {
-        if ((edge->hasConstant() && !valueOfJSConstant(edge.node()).isMachineInt())) {
+        if (edge->hasConstant() && !edge->isMachineIntConstant()) {
             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
             return allocate();
         }
@@ -886,7 +876,7 @@
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             ASSERT(jsValue.isMachineInt());
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
             int64_t value = jsValue.asMachineInt();
@@ -967,9 +957,9 @@
         if (edge->hasConstant()) {
             GPRReg gpr = allocate();
 
-            if (isNumberConstant(edge.node())) {
+            if (edge->isNumberConstant()) {
                 FPRReg fpr = fprAllocate();
-                m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(edge.node()))), gpr);
+                m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(edge->asNumber())), gpr);
                 m_jit.move64ToDouble(gpr, fpr);
                 unlock(gpr);
 
@@ -1010,7 +1000,7 @@
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             if (jsValue.isCell()) {
                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
@@ -1096,7 +1086,7 @@
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             if (jsValue.isBoolean()) {
                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
@@ -1796,11 +1786,6 @@
         initConstantInfo(node);
         break;
 
-    case WeakJSConstant:
-        m_jit.addWeakReference(node->weakConstant());
-        initConstantInfo(node);
-        break;
-        
     case Identity: {
         // CSE should always eliminate this.
         RELEASE_ASSERT_NOT_REACHED();
@@ -1813,9 +1798,7 @@
         // If the CFA is tracking this variable and it found that the variable
         // cannot have been assigned, then don't attempt to proceed.
         if (value.isClear()) {
-            // FIXME: We should trap instead.
-            // https://bugs.webkit.org/show_bug.cgi?id=110383
-            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+            m_compileOkay = false;
             break;
         }
         
@@ -1964,18 +1947,18 @@
     case BitAnd:
     case BitOr:
     case BitXor:
-        if (isInt32Constant(node->child1().node())) {
+        if (node->child1()->isInt32Constant()) {
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this, Reuse, op2);
 
-            bitOp(op, valueOfInt32Constant(node->child1().node()), op2.gpr(), result.gpr());
+            bitOp(op, node->child1()->asInt32(), op2.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
-        } else if (isInt32Constant(node->child2().node())) {
+        } else if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            bitOp(op, valueOfInt32Constant(node->child2().node()), op1.gpr(), result.gpr());
+            bitOp(op, node->child2()->asInt32(), op1.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -1994,11 +1977,11 @@
     case BitRShift:
     case BitLShift:
     case BitURShift:
-        if (isInt32Constant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            shiftOp(op, op1.gpr(), valueOfInt32Constant(node->child2().node()) & 0x1f, result.gpr());
+            shiftOp(op, op1.gpr(), node->child2()->asInt32() & 0x1f, result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -2307,7 +2290,7 @@
         break;
         
     case CompareEqConstant:
-        ASSERT(isNullConstant(node->child2().node()));
+        ASSERT(node->child2()->asJSValue().isNull());
         if (nonSpeculativeCompareNull(node, node->child1()))
             return;
         break;
@@ -3804,7 +3787,7 @@
         
     case CheckFunction: {
         SpeculateCellOperand function(this, node->child1());
-        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()));
+        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()->value().asCell()));
         noResult(node);
         break;
     }
@@ -3822,8 +3805,8 @@
         ASSERT(node->structureSet().size());
         
         ExitKind exitKind;
-        if (node->child1()->op() == WeakJSConstant)
-            exitKind = BadWeakConstantCache;
+        if (node->child1()->hasConstant())
+            exitKind = BadConstantCache;
         else
             exitKind = BadCache;
         
@@ -4757,7 +4740,9 @@
         RELEASE_ASSERT_NOT_REACHED();
         break;
 #endif // ENABLE(FTL_JIT)
-        
+
+    case NativeCall:
+    case NativeConstruct:    
     case LastNodeType:
     case Phi:
     case Upsilon:
diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
index 1f837d3..f0c09f1 100644
--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
@@ -72,12 +72,9 @@
         case BitOr:
             handleCommutativity();
 
-            if (m_node->child2()->isConstant()) {
-                JSValue op2 = m_graph.valueOfJSConstant(m_node->child2().node());
-                if (op2.isInt32() && !op2.asInt32()) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
+            if (m_node->child2()->isInt32Constant() && !m_node->child2()->asInt32()) {
+                convertToIdentityOverChild1();
+                break;
             }
             break;
             
@@ -89,39 +86,29 @@
         case BitLShift:
         case BitRShift:
         case BitURShift:
-            if (m_node->child2()->isConstant()) {
-                JSValue op2 = m_graph.valueOfJSConstant(m_node->child2().node());
-                if (op2.isInt32() && !(op2.asInt32() & 0x1f)) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
+            if (m_node->child2()->isInt32Constant() && !(m_node->child2()->asInt32() & 0x1f)) {
+                convertToIdentityOverChild1();
+                break;
             }
             break;
             
         case UInt32ToNumber:
             if (m_node->child1()->op() == BitURShift
-                && m_node->child1()->child2()->isConstant()) {
-                JSValue shiftAmount = m_graph.valueOfJSConstant(
-                    m_node->child1()->child2().node());
-                if (shiftAmount.isInt32() && (shiftAmount.asInt32() & 0x1f)
-                    && m_node->arithMode() != Arith::DoOverflow) {
-                    m_node->convertToIdentity();
-                    m_changed = true;
-                    break;
-                }
+                && m_node->child1()->child2()->isInt32Constant()
+                && (m_node->child1()->child2()->asInt32() & 0x1f)
+                && m_node->arithMode() != Arith::DoOverflow) {
+                m_node->convertToIdentity();
+                m_changed = true;
+                break;
             }
             break;
             
         case ArithAdd:
             handleCommutativity();
             
-            if (m_graph.isInt32Constant(m_node->child2().node())) {
-                int32_t value = m_graph.valueOfInt32Constant(
-                    m_node->child2().node());
-                if (!value) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
+            if (m_node->child2()->isInt32Constant() && !m_node->child2()->asInt32()) {
+                convertToIdentityOverChild1();
+                break;
             }
             break;
             
@@ -130,9 +117,9 @@
             break;
             
         case ArithSub:
-            if (m_graph.isInt32Constant(m_node->child2().node())
+            if (m_node->child2()->isInt32Constant()
                 && m_node->isBinaryUseKind(Int32Use)) {
-                int32_t value = m_graph.valueOfInt32Constant(m_node->child2().node());
+                int32_t value = m_node->child2()->asInt32();
                 if (-value != value) {
                     m_node->setOp(ArithAdd);
                     m_node->child2().setNode(
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.cpp b/Source/JavaScriptCore/dfg/DFGValidate.cpp
index ecd4d87..c8a531f 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValidate.cpp
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "CodeBlockWithJITType.h"
+#include "DFGMayExit.h"
 #include "JSCInlines.h"
 #include <wtf/Assertions.h>
 #include <wtf/BitVector.h>
@@ -197,13 +198,41 @@
             for (size_t i = 0; i < block->size(); ++i) {
                 Node* node = block->at(i);
                 
-                if (node->hasStructure())
-                    VALIDATE((node), !!node->structure());
-                
+                VALIDATE((node), !mayExit(m_graph, node) || node->origin.forExit.isSet());
+                VALIDATE((node), !node->hasStructure() || !!node->structure());
+                VALIDATE((node), !node->hasFunction() || node->function()->value().isFunction());
+                 
+                if (!(node->flags() & NodeHasVarArgs)) {
+                    if (!node->child2())
+                        VALIDATE((node), !node->child3());
+                    if (!node->child1())
+                        VALIDATE((node), !node->child2());
+                }
+                 
                 switch (node->op()) {
                 case Identity:
                     VALIDATE((node), canonicalResultRepresentation(node->result()) == canonicalResultRepresentation(node->child1()->result()));
                     break;
+                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->child1());
+                    VALIDATE((node), !!node->child2());
+                    break;
                 default:
                     break;
                 }
@@ -427,18 +456,18 @@
                 continue;
             
             unsigned nodeIndex = 0;
-            for (; nodeIndex < block->size() && !block->at(nodeIndex)->origin.isSet(); nodeIndex++) { }
+            for (; nodeIndex < block->size() && !block->at(nodeIndex)->origin.forExit.isSet(); nodeIndex++) { }
             
             VALIDATE((block), nodeIndex < block->size());
             
             for (; nodeIndex < block->size(); nodeIndex++)
-                VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->origin.isSet());
+                VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->origin.forExit.isSet());
             
             for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                 Node* node = block->at(nodeIndex);
                 switch (node->op()) {
                 case Phi:
-                    VALIDATE((node), !node->origin.isSet());
+                    VALIDATE((node), !node->origin.forExit.isSet());
                     break;
                     
                 default:
diff --git a/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h b/Source/JavaScriptCore/dfg/DFGValueStrength.cpp
similarity index 67%
copy from Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h
copy to Source/JavaScriptCore/dfg/DFGValueStrength.cpp
index 9343710..830b6ee 100644
--- a/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h
+++ b/Source/JavaScriptCore/dfg/DFGValueStrength.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * 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
@@ -23,37 +23,32 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGDesiredStructureChains_h
-#define DFGDesiredStructureChains_h
+#include "config.h"
+#include "DFGValueStrength.h"
 
 #if ENABLE(DFG_JIT)
 
-#include "IntendedStructureChain.h"
-#include <wtf/Vector.h>
+namespace WTF {
 
-namespace JSC { namespace DFG {
+using namespace JSC::DFG;
 
-class DesiredStructureChains {
-public:
-    DesiredStructureChains();
-    ~DesiredStructureChains();
-    
-    void addLazily(PassRefPtr<IntendedStructureChain> chain)
-    {
-        m_vector.append(chain);
+void printInternal(PrintStream& out, ValueStrength strength)
+{
+    switch (strength) {
+    case FragileValue:
+        out.print("Fragile");
+        return;
+    case WeakValue:
+        out.print("Weak");
+        return;
+    case StrongValue:
+        out.print("Strong");
+        return;
     }
-    
-    bool areStillValid() const;
-    
-    void visitChildren(SlotVisitor&);
-    
-private:
-    Vector<RefPtr<IntendedStructureChain>> m_vector;
-};
+    RELEASE_ASSERT_NOT_REACHED();
+}
 
-} } // namespace JSC::DFG
+} // namespace WTF
 
 #endif // ENABLE(DFG_JIT)
 
-#endif // DFGDesiredStructureChains_h
-
diff --git a/Source/JavaScriptCore/dfg/DFGValueStrength.h b/Source/JavaScriptCore/dfg/DFGValueStrength.h
new file mode 100644
index 0000000..a82dc40
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGValueStrength.h
@@ -0,0 +1,78 @@
+/*
+ * 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 <wtf/PrintStream.h>
+
+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&, JSC::DFG::ValueStrength);
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGValueStrength_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
index c209ce4..8981de7 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -81,20 +81,13 @@
 
 } // namespace
 
-bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, CodeBlock* codeBlock, MinifiedNode* node) const
+bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, MinifiedNode* node) const
 {
     if (!node)
         return false;
     
-    if (node->hasConstantNumber()) {
-        recovery = ValueRecovery::constant(
-            codeBlock->constantRegister(
-                FirstConstantRegisterIndex + node->constantNumber()).get());
-        return true;
-    }
-    
-    if (node->hasWeakConstant()) {
-        recovery = ValueRecovery::constant(node->weakConstant());
+    if (node->hasConstant()) {
+        recovery = ValueRecovery::constant(node->constant());
         return true;
     }
     
@@ -187,7 +180,7 @@
         
         ASSERT(source.kind() == HaveNode);
         MinifiedNode* node = graph.at(source.id());
-        if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, node))
+        if (tryToSetConstantRecovery(valueRecoveries[i], node))
             continue;
         
         MinifiedGenerationInfo info = generationInfos.get(source.id());
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.h b/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
index 2bcf549..9cb78cb 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 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
@@ -48,7 +48,7 @@
         unsigned index, Operands<ValueRecovery>&) const;
 
 private:
-    bool tryToSetConstantRecovery(ValueRecovery&, CodeBlock*, MinifiedNode*) const;
+    bool tryToSetConstantRecovery(ValueRecovery&, MinifiedNode*) const;
     
     void logEvent(const VariableEvent&);
 };
diff --git a/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp b/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp
index 4771a9a..76f43b7 100644
--- a/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp
@@ -47,9 +47,12 @@
         // These are pretty dumb, but needed to placate subsequent assertions. We con't actually
         // have to watch these because there is no way to transition away from it, but they are
         // watchable and so we will assert if they aren't watched.
-        tryWatch(m_graph.m_vm.stringStructure.get()); 
+        tryWatch(m_graph.m_vm.stringStructure.get());
         tryWatch(m_graph.m_vm.getterSetterStructure.get());
         
+        for (FrozenValue* value : m_graph.m_frozenValues)
+            tryWatch(value->structure());
+        
         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
             BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
@@ -59,17 +62,8 @@
                 Node* node = block->at(nodeIndex);
             
                 switch (node->op()) {
-                case JSConstant:
-                case WeakJSConstant:
-                    tryWatch(m_graph.valueOfJSConstant(node));
-                    break;
-                
-                case CheckFunction:
-                    tryWatch(node->function());
-                    break;
-                
                 case CheckExecutable:
-                    tryWatch(node->executable());
+                    tryWatch(node->executable()->structure());
                     break;
                 
                 case CheckStructure:
@@ -93,7 +87,7 @@
                 case MultiGetByOffset:
                     for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
                         GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
-                        tryWatch(variant.specificValue());
+                        tryWatch(m_graph.freeze(variant.specificValue())->structure());
                         tryWatch(variant.structureSet());
                         // Don't need to watch anything in the structure chain because that would
                         // have been decomposed into CheckStructure's. Don't need to watch the
@@ -139,22 +133,12 @@
             }
         }
         
+        m_graph.m_structureWatchpointState = WatchingAllWatchableStructures;
+        
         return true;
     }
 
 private:
-    void tryWatch(JSValue value)
-    {
-        if (value.isCell())
-            tryWatch(value.asCell());
-    }
-    
-    void tryWatch(JSCell* cell)
-    {
-        if (cell)
-            tryWatch(cell->structure());
-    }
-    
     void tryWatch(const StructureSet& set)
     {
         for (unsigned i = set.size(); i--;)
@@ -163,7 +147,8 @@
     
     void tryWatch(Structure* structure)
     {
-        m_graph.watchpoints().consider(structure);
+        if (structure)
+            m_graph.watchpoints().consider(structure);
     }
 };
 
diff --git a/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp b/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp
index 99afa4d..0c48489 100644
--- a/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp
@@ -114,7 +114,7 @@
             break;
             
         case AllocationProfileWatchpoint:
-            addLazily(jsCast<JSFunction*>(m_node->function())->allocationProfileWatchpointSet());
+            addLazily(jsCast<JSFunction*>(m_node->function()->value())->allocationProfileWatchpointSet());
             break;
             
         case VariableWatchpoint:
diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
index 252076e..567cc12 100644
--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
@@ -44,7 +44,6 @@
     
     switch (node->op()) {
     case JSConstant:
-    case WeakJSConstant:
     case GetMyArgumentsLength:
     case GetLocal:
     case SetLocal:
@@ -119,6 +118,8 @@
     case StoreBarrierWithNullCheck:
     case Call:
     case Construct:
+    case NativeCall:
+    case NativeConstruct:
     case ValueToInt32:
     case Branch:
     case LogicalNot:
diff --git a/Source/JavaScriptCore/ftl/FTLLink.cpp b/Source/JavaScriptCore/ftl/FTLLink.cpp
index b1b74ee..71b9698 100644
--- a/Source/JavaScriptCore/ftl/FTLLink.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLink.cpp
@@ -63,6 +63,8 @@
     if (!graph.m_plan.inlineCallFrames->isEmpty())
         state.jitCode->common.inlineCallFrames = graph.m_plan.inlineCallFrames;
     
+    graph.registerFrozenValues();
+
     // Create the entrypoint. Note that we use this entrypoint totally differently
     // depending on whether we're doing OSR entry or not.
     CCallHelpers jit(&vm, codeBlock);
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
index d8cd259..7d619e3 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
@@ -153,13 +153,8 @@
                 Node* m_node = block->at(nodeIndex);
                 if (m_node->hasKnownFunction()) {
                     int numArgs = m_node->numChildren();
-                    NativeFunction func = m_node->knownFunction()->nativeFunction();
-                    Dl_info info;
-                    if (dladdr((void*)func, &info)) {
-                        LValue callee = getFunctionBySymbol(info.dli_sname);
-                        if (callee && numArgs > maxNumberOfArguments)
-                            maxNumberOfArguments = numArgs;
-                    }
+                    if (numArgs > maxNumberOfArguments)
+                        maxNumberOfArguments = numArgs;
                 }
             }
         }
@@ -358,9 +353,6 @@
         case Int52Constant:
             compileInt52Constant();
             break;
-        case WeakJSConstant:
-            compileWeakJSConstant();
-            break;
         case PhantomArguments:
             compilePhantomArguments();
             break;
@@ -639,6 +631,10 @@
         case Construct:
             compileCallOrConstruct();
             break;
+        case NativeCall:
+        case NativeConstruct:
+            compileNativeCallOrConstruct();
+            break;
         case Jump:
             compileJump();
             break;
@@ -773,22 +769,17 @@
     
     void compileDoubleConstant()
     {
-        setDouble(m_out.constDouble(m_graph.valueOfNumberConstant(m_node)));
+        setDouble(m_out.constDouble(m_node->asNumber()));
     }
     
     void compileInt52Constant()
     {
-        int64_t value = m_graph.valueOfJSConstant(m_node).asMachineInt();
+        int64_t value = m_node->asMachineInt();
         
         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
         setStrictInt52(m_out.constInt64(value));
     }
 
-    void compileWeakJSConstant()
-    {
-        setJSValue(weakPointer(m_node->weakConstant()));
-    }
-    
     void compilePhantomArguments()
     {
         setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
@@ -1685,8 +1676,8 @@
         LValue cell = lowCell(m_node->child1());
         
         ExitKind exitKind;
-        if (m_node->child1()->op() == WeakJSConstant)
-            exitKind = BadWeakConstantCache;
+        if (m_node->child1()->hasConstant())
+            exitKind = BadConstantCache;
         else
             exitKind = BadCache;
         
@@ -1724,7 +1715,7 @@
         
         speculate(
             BadFunction, jsValueValue(cell), m_node->child1().node(),
-            m_out.notEqual(cell, weakPointer(m_node->function())));
+            m_out.notEqual(cell, weakPointer(m_node->function()->value().asCell())));
     }
     
     void compileCheckExecutable()
@@ -3295,8 +3286,8 @@
                 result = m_out.constInt64(JSValue::encode(variant.specificValue()));
             else {
                 LValue propertyBase;
-                if (variant.chain())
-                    propertyBase = weakPointer(variant.chain()->terminalPrototype());
+                if (variant.alternateBase())
+                    propertyBase = weakPointer(variant.alternateBase());
                 else
                     propertyBase = base;
                 if (!isInlineOffset(variant.offset()))
@@ -3505,7 +3496,7 @@
     
     void compileCompareEqConstant()
     {
-        ASSERT(m_graph.valueOfJSConstant(m_node->child2().node()).isNull());
+        ASSERT(m_node->child2()->asJSValue().isNull());
         setBoolean(
             equalNullOrUndefined(
                 m_node->child1(), AllCellsAreFalse, EqualNullOrUndefined));
@@ -3598,7 +3589,7 @@
     
     void compileCompareStrictEqConstant()
     {
-        JSValue constant = m_graph.valueOfJSConstant(m_node->child2().node());
+        JSValue constant = m_node->child2()->asJSValue();
 
         setBoolean(
             m_out.equal(
@@ -3631,16 +3622,66 @@
         setBoolean(m_out.bitNot(boolify(m_node->child1())));
     }
 
+    void compileNativeCallOrConstruct() 
+    {
+        int dummyThisArgument = m_node->op() == NativeCall ? 0 : 1;
+        int numPassedArgs = m_node->numChildren() - 1;
+        int numArgs = numPassedArgs + dummyThisArgument;
+
+        ASSERT(m_node->hasKnownFunction());
+
+        JSFunction* knownFunction = m_node->knownFunction();
+        NativeFunction function = knownFunction->nativeFunction();
+
+        Dl_info info;
+        if (!dladdr((void*)function, &info))
+            ASSERT(false); // if we couldn't find the native function this doesn't bode well.
+
+        LValue callee = getFunctionBySymbol(info.dli_sname);
+
+        bool notInlinable;
+        if ((notInlinable = !callee))
+            callee = m_out.operation(function);
+
+        JSScope* scope = knownFunction->scopeUnchecked();
+        m_out.storePtr(m_callFrame, m_execStorage, m_heaps.CallFrame_callerFrame);
+        m_out.storePtr(constNull(m_out.intPtr), addressFor(m_execStorage, JSStack::CodeBlock));
+        m_out.storePtr(weakPointer(scope), addressFor(m_execStorage, JSStack::ScopeChain));
+        m_out.storePtr(weakPointer(knownFunction), addressFor(m_execStorage, JSStack::Callee));
+
+        m_out.store64(m_out.constInt64(numArgs), addressFor(m_execStorage, JSStack::ArgumentCount));
+
+        if (dummyThisArgument) 
+            m_out.storePtr(getUndef(m_out.int64), addressFor(m_execStorage, JSStack::ThisArgument));
+        
+        for (int i = 0; i < numPassedArgs; ++i) {
+            m_out.storePtr(lowJSValue(m_graph.varArgChild(m_node, 1 + i)),
+                addressFor(m_execStorage, dummyThisArgument ? JSStack::FirstArgument : JSStack::ThisArgument, i * sizeof(Register)));
+        }
+
+        LValue calleeCallFrame = m_out.address(m_execState, m_heaps.CallFrame_callerFrame).value();
+        m_out.storePtr(m_out.ptrToInt(calleeCallFrame, m_out.intPtr), m_out.absolute(&vm().topCallFrame));
+
+        LType typeCalleeArg;
+        getParamTypes(getElementType(typeOf(callee)), &typeCalleeArg);
+
+        LValue argument = notInlinable 
+            ? m_out.ptrToInt(calleeCallFrame, typeCalleeArg) 
+            : m_out.bitCast(calleeCallFrame, typeCalleeArg);
+        LValue call = vmCall(callee, argument);
+
+        if (Options::verboseCompilation())
+            dataLog("Native calling: ", info.dli_sname, "\n");
+
+        setJSValue(call);
+    }
+
     void compileCallOrConstruct()
     {
         int dummyThisArgument = m_node->op() == Call ? 0 : 1;
         int numPassedArgs = m_node->numChildren() - 1;
         int numArgs = numPassedArgs + dummyThisArgument;
 
-        if (m_node->hasKnownFunction()
-            && possiblyCompileInlineableNativeCall(dummyThisArgument, numPassedArgs, numArgs))
-            return;
-
         LValue jsCallee = lowJSValue(m_graph.varArgChild(m_node, 0));
 
         unsigned stackmapID = m_stackmapIDs++;
@@ -4019,50 +4060,6 @@
 #endif
     }
     
-    bool possiblyCompileInlineableNativeCall(int dummyThisArgument, int numPassedArgs, int numArgs)
-    {
-        JSFunction* knownFunction = m_node->knownFunction();
-        NativeFunction function = knownFunction->nativeFunction();
-        Dl_info info;
-        if (dladdr((void*)function, &info)) {
-            LValue callee = getFunctionBySymbol(info.dli_sname);
-            LType typeCallee;
-            if (callee && (typeCallee = typeOf(callee)) && (typeCallee = getElementType(typeCallee))) {
-
-                JSScope* scope = knownFunction->scopeUnchecked();
-                m_out.storePtr(m_callFrame, m_execStorage, m_heaps.CallFrame_callerFrame);
-                m_out.storePtr(constNull(m_out.intPtr), addressFor(m_execStorage, JSStack::CodeBlock));
-                m_out.storePtr(weakPointer(scope), addressFor(m_execStorage, JSStack::ScopeChain));
-                m_out.storePtr(weakPointer(knownFunction), addressFor(m_execStorage, JSStack::Callee));
-
-                m_out.store64(m_out.constInt64(numArgs), addressFor(m_execStorage, JSStack::ArgumentCount));
-
-                if (dummyThisArgument) 
-                    m_out.storePtr(getUndef(m_out.int64), addressFor(m_execStorage, JSStack::ThisArgument));
-                
-                for (int i = 0; i < numPassedArgs; ++i) {
-                    m_out.storePtr(lowJSValue(m_graph.varArgChild(m_node, 1 + i)),
-                        addressFor(m_execStorage, dummyThisArgument ? JSStack::FirstArgument : JSStack::ThisArgument, i * sizeof(Register)));
-                }
-
-                LType typeCalleeArg;
-                getParamTypes(typeCallee, &typeCalleeArg);
-                LValue calleeCallFrame = m_out.address(m_execState, m_heaps.CallFrame_callerFrame).value();
-                m_out.storePtr(m_out.ptrToInt(calleeCallFrame, m_out.intPtr), m_out.absolute(&vm().topCallFrame));
-                
-                LValue call = vmCall(callee, 
-                    m_out.bitCast(calleeCallFrame, typeCalleeArg));
-
-                if (Options::verboseCompilation())
-                    dataLog("Inlining: ", info.dli_sname, "\n");
-
-                setJSValue(call);
-                return true;
-            }
-        }
-        return false;
-    }
-
     LValue getFunctionBySymbol(const CString symbol)
     {
         if (!m_ftlState.symbolTable.contains(symbol)) 
@@ -4194,6 +4191,8 @@
                 case PutById:
                 case Call:
                 case Construct:
+                case NativeCall:
+                case NativeConstruct:
                     return m_out.below(
                         m_callFrame,
                         m_out.loadPtr(
@@ -4999,7 +4998,7 @@
         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
         
         if (edge->hasConstant()) {
-            JSValue value = m_graph.valueOfJSConstant(edge.node());
+            JSValue value = edge->asJSValue();
             if (!value.isInt32()) {
                 terminate(Uncountable);
                 return m_out.int32Zero;
@@ -5114,7 +5113,7 @@
         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
         
         if (edge->op() == JSConstant) {
-            JSValue value = m_graph.valueOfJSConstant(edge.node());
+            JSValue value = edge->asJSValue();
             if (!value.isCell()) {
                 terminate(Uncountable);
                 return m_out.intPtrZero;
@@ -5177,7 +5176,7 @@
         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
         
         if (edge->hasConstant()) {
-            JSValue value = m_graph.valueOfJSConstant(edge.node());
+            JSValue value = edge->asJSValue();
             if (!value.isBoolean()) {
                 terminate(Uncountable);
                 return m_out.booleanFalse;
@@ -5223,8 +5222,8 @@
         DFG_ASSERT(m_graph, m_node, edge.useKind() != Int52RepUse);
         
         if (edge->hasConstant())
-            return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node())));
-        
+            return m_out.constInt64(JSValue::encode(edge->asJSValue()));
+
         LoweredNodeValue value = m_jsValueValues.get(edge.node());
         if (isValid(value))
             return value.value();
@@ -6202,8 +6201,7 @@
         case JSConstant:
         case Int52Constant:
         case DoubleConstant:
-        case WeakJSConstant:
-            exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
+            exit.m_values[index] = ExitValue::constant(node->asJSValue());
             return true;
         case PhantomArguments:
             exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
diff --git a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
index 62e3b99..4e31a63 100644
--- a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
@@ -87,7 +87,7 @@
         
         Profiler::OSRExit* profilerExit = compilation->addOSRExit(
             exitID, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
-            exit.m_kind, isWatchpoint(exit.m_kind));
+            exit.m_kind, exit.m_kind == UncountableInvalidation);
         jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
     }
 
diff --git a/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp b/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp
index 290e425..41e2179 100644
--- a/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp
+++ b/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp
@@ -33,27 +33,37 @@
 
 namespace JSC {
 
-IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, Structure* head)
+IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, JSValue prototype)
     : m_globalObject(globalObject)
-    , m_head(head)
+    , m_prototype(prototype)
 {
-    JSValue prototype = head->prototypeForLookup(globalObject);
+    ASSERT(m_prototype.isNull() || m_prototype.isObject());
     if (prototype.isNull())
         return;
     for (Structure* current = asObject(prototype)->structure(); current; current = current->storedPrototypeStructure())
         m_vector.append(current);
 }
 
+IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, Structure* head)
+    : m_globalObject(globalObject)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
+{
+    if (m_prototype.isNull())
+        return;
+    for (Structure* current = asObject(m_prototype)->structure(); current; current = current->storedPrototypeStructure())
+        m_vector.append(current);
+}
+
 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, Structure* prototypeStructure)
     : m_globalObject(codeBlock->globalObject())
-    , m_head(head)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
 {
     m_vector.append(prototypeStructure);
 }
 
 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain)
     : m_globalObject(codeBlock->globalObject())
-    , m_head(head)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
 {
     for (unsigned i = 0; chain->head()[i]; ++i)
         m_vector.append(chain->head()[i].get());
@@ -61,7 +71,7 @@
 
 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain, unsigned count)
     : m_globalObject(codeBlock->globalObject())
-    , m_head(head)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
 {
     for (unsigned i = 0; i < count; ++i)
         m_vector.append(chain->head()[i].get());
@@ -73,7 +83,7 @@
 
 bool IntendedStructureChain::isStillValid() const
 {
-    JSValue currentPrototype = m_head->prototypeForLookup(m_globalObject);
+    JSValue currentPrototype = m_prototype;
     for (unsigned i = 0; i < m_vector.size(); ++i) {
         if (asObject(currentPrototype)->structure() != m_vector[i])
             return false;
@@ -93,14 +103,6 @@
     return true;
 }
 
-StructureChain* IntendedStructureChain::chain(VM& vm) const
-{
-    ASSERT(isStillValid());
-    StructureChain* result = StructureChain::create(vm, m_head);
-    ASSERT(matches(result));
-    return result;
-}
-
 bool IntendedStructureChain::mayInterceptStoreTo(VM& vm, StringImpl* uid)
 {
     for (unsigned i = 0; i < m_vector.size(); ++i) {
@@ -118,8 +120,6 @@
 
 bool IntendedStructureChain::isNormalized()
 {
-    if (m_head->isProxy())
-        return false;
     for (unsigned i = 0; i < m_vector.size(); ++i) {
         Structure* structure = m_vector[i];
         if (structure->isProxy())
@@ -134,14 +134,32 @@
 {
     ASSERT(!m_vector.isEmpty());
     if (m_vector.size() == 1)
-        return asObject(m_head->prototypeForLookup(m_globalObject));
+        return asObject(m_prototype);
     return asObject(m_vector[m_vector.size() - 2]->storedPrototype());
 }
 
+bool IntendedStructureChain::operator==(const IntendedStructureChain& other) const
+{
+    return m_globalObject == other.m_globalObject
+        && m_prototype == other.m_prototype
+        && m_vector == other.m_vector;
+}
+
+void IntendedStructureChain::gatherChecks(ConstantStructureCheckVector& vector) const
+{
+    JSValue currentPrototype = m_prototype;
+    for (unsigned i = 0; i < size(); ++i) {
+        JSObject* currentObject = asObject(currentPrototype);
+        Structure* currentStructure = at(i);
+        vector.append(ConstantStructureCheck(currentObject, currentStructure));
+        currentPrototype = currentStructure->prototypeForLookup(m_globalObject);
+    }
+}
+
 void IntendedStructureChain::visitChildren(SlotVisitor& visitor)
 {
     visitor.appendUnbarrieredPointer(&m_globalObject);
-    visitor.appendUnbarrieredPointer(&m_head);
+    visitor.appendUnbarrieredValue(&m_prototype);
     for (unsigned i = m_vector.size(); i--;)
         visitor.appendUnbarrieredPointer(&m_vector[i]);
 }
@@ -155,7 +173,7 @@
 {
     out.print(
         "(global = ", RawPointer(m_globalObject), ", head = ",
-        pointerDumpInContext(m_head, context), ", vector = [");
+        inContext(m_prototype, context), ", vector = [");
     CommaPrinter comma;
     for (unsigned i = 0; i < m_vector.size(); ++i)
         out.print(comma, pointerDumpInContext(m_vector[i], context));
diff --git a/Source/JavaScriptCore/runtime/IntendedStructureChain.h b/Source/JavaScriptCore/runtime/IntendedStructureChain.h
index a78188b..43c9087 100644
--- a/Source/JavaScriptCore/runtime/IntendedStructureChain.h
+++ b/Source/JavaScriptCore/runtime/IntendedStructureChain.h
@@ -26,6 +26,7 @@
 #ifndef IntendedStructureChain_h
 #define IntendedStructureChain_h
 
+#include "ConstantStructureCheck.h"
 #include "Structure.h"
 #include <wtf/RefCounted.h>
 
@@ -39,7 +40,8 @@
 
 class IntendedStructureChain : public RefCounted<IntendedStructureChain> {
 public:
-    IntendedStructureChain(JSGlobalObject* globalObject, Structure* head);
+    IntendedStructureChain(JSGlobalObject* globalObject, JSValue prototype);
+    IntendedStructureChain(JSGlobalObject* globalObject, Structure*);
     IntendedStructureChain(CodeBlock* codeBlock, Structure* head, Structure* prototypeStructure);
     IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain);
     IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain, unsigned count);
@@ -47,27 +49,34 @@
     
     bool isStillValid() const;
     bool matches(StructureChain*) const;
-    StructureChain* chain(VM&) const;
     bool mayInterceptStoreTo(VM&, StringImpl* uid);
     bool isNormalized();
     
-    Structure* head() const { return m_head; }
+    JSValue prototype() const { return m_prototype; }
     
     size_t size() const { return m_vector.size(); }
-    Structure* at(size_t index) { return m_vector[index]; }
-    Structure* operator[](size_t index) { return at(index); }
+    Structure* at(size_t index) const { return m_vector[index]; }
+    Structure* operator[](size_t index) const { return at(index); }
     
     JSObject* terminalPrototype() const;
     
     Structure* last() const { return m_vector.last(); }
     
+    bool operator==(const IntendedStructureChain&) const;
+    bool operator!=(const IntendedStructureChain& other) const
+    {
+        return !(*this == other);
+    }
+    
+    void gatherChecks(ConstantStructureCheckVector&) const;
+    
     void visitChildren(SlotVisitor&);
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     
 private:
     JSGlobalObject* m_globalObject;
-    Structure* m_head;
+    JSValue m_prototype;
     Vector<Structure*> m_vector;
 };
 
diff --git a/Source/JavaScriptCore/runtime/JSCJSValue.cpp b/Source/JavaScriptCore/runtime/JSCJSValue.cpp
index 0ca8103..6df9d6a 100644
--- a/Source/JavaScriptCore/runtime/JSCJSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSCJSValue.cpp
@@ -198,6 +198,13 @@
 
 void JSValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
+    dumpInContextAssumingStructure(
+        out, context, (!!*this && isCell()) ? asCell()->structure() : nullptr);
+}
+
+void JSValue::dumpInContextAssumingStructure(
+    PrintStream& out, DumpContext* context, Structure* structure) const
+{
     if (!*this)
         out.print("<JSValue()>");
     else if (isInt32())
@@ -214,7 +221,7 @@
         out.printf("Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
 #endif
     } else if (isCell()) {
-        if (asCell()->inherits(JSString::info())) {
+        if (structure->classInfo()->isSubClassOf(JSString::info())) {
             JSString* string = jsCast<JSString*>(asCell());
             out.print("String");
             if (string->isRope())
@@ -230,11 +237,11 @@
             } else
                 out.print(" (unresolved)");
             out.print(": ", impl);
-        } else if (asCell()->inherits(Structure::info()))
+        } else if (structure->classInfo()->isSubClassOf(Structure::info()))
             out.print("Structure: ", inContext(*jsCast<Structure*>(asCell()), context));
         else {
             out.print("Cell: ", RawPointer(asCell()));
-            out.print(" (", inContext(*asCell()->structure(), context), ")");
+            out.print(" (", inContext(*structure, context), ")");
         }
 #if USE(JSVALUE64)
         out.print(", ID: ", asCell()->structureID());
diff --git a/Source/JavaScriptCore/runtime/JSCJSValue.h b/Source/JavaScriptCore/runtime/JSCJSValue.h
index 492c1e6..620418a 100644
--- a/Source/JavaScriptCore/runtime/JSCJSValue.h
+++ b/Source/JavaScriptCore/runtime/JSCJSValue.h
@@ -48,6 +48,7 @@
 class PropertyName;
 class PropertySlot;
 class PutPropertySlot;
+class Structure;
 #if ENABLE(DFG_JIT)
 namespace DFG {
 class JITCompiler;
@@ -246,7 +247,7 @@
     JSObject* toObject(ExecState*, JSGlobalObject*) const;
 
     // Integer conversions.
-    double toInteger(ExecState*) const;
+    JS_EXPORT_PRIVATE double toInteger(ExecState*) const;
     JS_EXPORT_PRIVATE double toIntegerPreserveNaN(ExecState*) const;
     int32_t toInt32(ExecState*) const;
     uint32_t toUInt32(ExecState*) const;
@@ -283,6 +284,7 @@
 
     JS_EXPORT_PRIVATE void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
+    void dumpInContextAssumingStructure(PrintStream&, DumpContext*, Structure*) const;
     void dumpForBacktrace(PrintStream&) const;
 
     JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;