Ignore:
Timestamp:
Jul 25, 2014, 1:55:17 PM (11 years ago)
Author:
[email protected]
Message:

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

2014-06-17 Filip Pizlo <[email protected]>


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 <[email protected]>


[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 <[email protected]>


[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 <[email protected]>


[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 <[email protected]>


[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 <[email protected]>


[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 <[email protected]>


[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 <[email protected]>


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 <[email protected]>


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 <[email protected]>


[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 <[email protected]>


[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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r171391 r171613  
    133133        , m_currentBlock(0)
    134134        , m_currentIndex(0)
    135         , m_constantUndefined(UINT_MAX)
    136         , m_constantNull(UINT_MAX)
    137         , m_constantNaN(UINT_MAX)
    138         , m_constant1(UINT_MAX)
    139         , m_constants(m_codeBlock->numberOfConstantRegisters())
     135        , m_constantUndefined(graph.freeze(jsUndefined()))
     136        , m_constantNull(graph.freeze(jsNull()))
     137        , m_constantNaN(graph.freeze(jsNumber(PNaN)))
     138        , m_constantOne(graph.freeze(jsNumber(1)))
    140139        , m_numArguments(m_codeBlock->numParameters())
    141140        , m_numLocals(m_codeBlock->m_numCalleeRegisters)
     
    144143        , m_inlineStackTop(0)
    145144        , m_haveBuiltOperandMaps(false)
    146         , m_emptyJSValueIndex(UINT_MAX)
    147145        , m_currentInstruction(0)
    148146    {
     
    195193        Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus&,
    196194        bool isDirect);
    197     Node* emitPrototypeChecks(Structure*, IntendedStructureChain*);
     195    void emitChecks(const ConstantStructureCheckVector&);
    198196
    199197    Node* getScope(bool skipTop, unsigned skipCount);
     
    218216    Node* getDirect(VirtualRegister operand)
    219217    {
    220         // Is this a constant?
    221         if (operand.isConstant()) {
    222             unsigned constant = operand.toConstantIndex();
    223             ASSERT(constant < m_constants.size());
    224             return getJSConstant(constant);
    225         }
     218        ASSERT(!operand.isConstant());
    226219
    227220        // Is this an argument?
     
    235228    Node* get(VirtualRegister operand)
    236229    {
     230        if (operand.isConstant()) {
     231            unsigned constantIndex = operand.toConstantIndex();
     232            unsigned oldSize = m_constants.size();
     233            if (constantIndex >= oldSize || !m_constants[constantIndex]) {
     234                JSValue value = m_inlineStackTop->m_codeBlock->getConstant(operand.offset());
     235                if (constantIndex >= oldSize) {
     236                    m_constants.grow(constantIndex + 1);
     237                    for (unsigned i = oldSize; i < m_constants.size(); ++i)
     238                        m_constants[i] = nullptr;
     239                }
     240                m_constants[constantIndex] =
     241                    addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(value)));
     242            }
     243            ASSERT(m_constants[constantIndex]);
     244            return m_constants[constantIndex];
     245        }
     246       
    237247        if (inlineCallFrame()) {
    238248            if (!inlineCallFrame()->isClosureCall) {
    239249                JSFunction* callee = inlineCallFrame()->calleeConstant();
    240250                if (operand.offset() == JSStack::Callee)
    241                     return cellConstant(callee);
     251                    return weakJSConstant(callee);
    242252                if (operand.offset() == JSStack::ScopeChain)
    243                     return cellConstant(callee->scope());
     253                    return weakJSConstant(callee->scope());
    244254            }
    245255        } else if (operand.offset() == JSStack::Callee)
     
    310320                    addToGraph(FunctionReentryWatchpoint, OpInfo(m_codeBlock->symbolTable()));
    311321                    addToGraph(VariableWatchpoint, OpInfo(set));
    312                     // Note: this is very special from an OSR exit standpoint. We wouldn't be
    313                     // able to do this for most locals, but it works here because we're dealing
    314                     // with a flushed local. For most locals we would need to issue a GetLocal
    315                     // here and ensure that we have uses in DFG IR wherever there would have
    316                     // been uses in bytecode. Clearly this optimization does not do this. But
    317                     // that's fine, because we don't need to track liveness for captured
    318                     // locals, and this optimization only kicks in for captured locals.
    319                     return inferredConstant(value);
     322                    return weakJSConstant(value);
    320323                }
    321324            }
     
    368371        VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
    369372        variableAccessData->mergeStructureCheckHoistingFailed(
    370             m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
    371             || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
     373            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
    372374        variableAccessData->mergeCheckArrayHoistingFailed(
    373375            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
     
    425427       
    426428        variableAccessData->mergeStructureCheckHoistingFailed(
    427             m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
    428             || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
     429            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
    429430        variableAccessData->mergeCheckArrayHoistingFailed(
    430431            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
     
    467468    }
    468469
    469     void addConstant(JSValue value)
    470     {
    471         unsigned constantIndex = m_codeBlock->addConstantLazily();
    472         initializeLazyWriteBarrierForConstant(
    473             m_graph.m_plan.writeBarriers,
    474             m_codeBlock->constants()[constantIndex],
    475             m_codeBlock,
    476             constantIndex,
    477             m_codeBlock->ownerExecutable(),
    478             value);
    479     }
    480    
    481470    void flush(VirtualRegister operand)
    482471    {
     
    555544    }
    556545
    557     // NOTE: Only use this to construct constants that arise from non-speculative
    558     // constant folding. I.e. creating constants using this if we had constant
    559     // field inference would be a bad idea, since the bytecode parser's folding
    560     // doesn't handle liveness preservation.
    561     Node* getJSConstantForValue(JSValue constantValue)
    562     {
    563         unsigned constantIndex;
    564         if (!m_codeBlock->findConstant(constantValue, constantIndex)) {
    565             addConstant(constantValue);
    566             m_constants.append(ConstantRecord());
    567         }
    568        
    569         ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
    570        
    571         return getJSConstant(constantIndex);
    572     }
    573 
    574     Node* getJSConstant(unsigned constant)
    575     {
    576         Node* node = m_constants[constant].asJSValue;
    577         if (node)
    578             return node;
    579 
    580         Node* result = addToGraph(JSConstant, OpInfo(constant));
    581         m_constants[constant].asJSValue = result;
    582         return result;
     546    // Assumes that the constant should be strongly marked.
     547    Node* jsConstant(JSValue constantValue)
     548    {
     549        return addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(constantValue)));
     550    }
     551
     552    Node* weakJSConstant(JSValue constantValue)
     553    {
     554        return addToGraph(JSConstant, OpInfo(m_graph.freeze(constantValue)));
    583555    }
    584556
     
    594566    }
    595567
    596     // Convenience methods for checking nodes for constants.
    597     bool isJSConstant(Node* node)
    598     {
    599         return node->op() == JSConstant;
    600     }
    601     bool isInt32Constant(Node* node)
    602     {
    603         return isJSConstant(node) && valueOfJSConstant(node).isInt32();
    604     }
    605     // Convenience methods for getting constant values.
    606     JSValue valueOfJSConstant(Node* node)
    607     {
    608         ASSERT(isJSConstant(node));
    609         return m_codeBlock->getConstant(FirstConstantRegisterIndex + node->constantNumber());
    610     }
    611     int32_t valueOfInt32Constant(Node* node)
    612     {
    613         ASSERT(isInt32Constant(node));
    614         return valueOfJSConstant(node).asInt32();
    615     }
    616    
    617     // This method returns a JSConstant with the value 'undefined'.
    618     Node* constantUndefined()
    619     {
    620         // Has m_constantUndefined been set up yet?
    621         if (m_constantUndefined == UINT_MAX) {
    622             // Search the constant pool for undefined, if we find it, we can just reuse this!
    623             unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
    624             for (m_constantUndefined = 0; m_constantUndefined < numberOfConstants; ++m_constantUndefined) {
    625                 JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantUndefined);
    626                 if (testMe.isUndefined())
    627                     return getJSConstant(m_constantUndefined);
    628             }
    629 
    630             // Add undefined to the CodeBlock's constants, and add a corresponding slot in m_constants.
    631             ASSERT(m_constants.size() == numberOfConstants);
    632             addConstant(jsUndefined());
    633             m_constants.append(ConstantRecord());
    634             ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
    635         }
    636 
    637         // m_constantUndefined must refer to an entry in the CodeBlock's constant pool that has the value 'undefined'.
    638         ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantUndefined).isUndefined());
    639         return getJSConstant(m_constantUndefined);
    640     }
    641 
    642     // This method returns a JSConstant with the value 'null'.
    643     Node* constantNull()
    644     {
    645         // Has m_constantNull been set up yet?
    646         if (m_constantNull == UINT_MAX) {
    647             // Search the constant pool for null, if we find it, we can just reuse this!
    648             unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
    649             for (m_constantNull = 0; m_constantNull < numberOfConstants; ++m_constantNull) {
    650                 JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNull);
    651                 if (testMe.isNull())
    652                     return getJSConstant(m_constantNull);
    653             }
    654 
    655             // Add null to the CodeBlock's constants, and add a corresponding slot in m_constants.
    656             ASSERT(m_constants.size() == numberOfConstants);
    657             addConstant(jsNull());
    658             m_constants.append(ConstantRecord());
    659             ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
    660         }
    661 
    662         // m_constantNull must refer to an entry in the CodeBlock's constant pool that has the value 'null'.
    663         ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNull).isNull());
    664         return getJSConstant(m_constantNull);
    665     }
    666 
    667     // This method returns a DoubleConstant with the value 1.
    668     Node* one()
    669     {
    670         // Has m_constant1 been set up yet?
    671         if (m_constant1 == UINT_MAX) {
    672             // Search the constant pool for the value 1, if we find it, we can just reuse this!
    673             unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
    674             for (m_constant1 = 0; m_constant1 < numberOfConstants; ++m_constant1) {
    675                 JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1);
    676                 if (testMe.isInt32() && testMe.asInt32() == 1)
    677                     return getJSConstant(m_constant1);
    678             }
    679 
    680             // Add the value 1 to the CodeBlock's constants, and add a corresponding slot in m_constants.
    681             ASSERT(m_constants.size() == numberOfConstants);
    682             addConstant(jsNumber(1));
    683             m_constants.append(ConstantRecord());
    684             ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
    685         }
    686 
    687         // m_constant1 must refer to an entry in the CodeBlock's constant pool that has the integer value 1.
    688         ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).isInt32());
    689         ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).asInt32() == 1);
    690         return getJSConstant(m_constant1);
    691     }
    692    
    693     // This method returns a DoubleConstant with the value NaN.
    694     Node* constantNaN()
    695     {
    696         JSValue nan = jsNaN();
    697        
    698         // Has m_constantNaN been set up yet?
    699         if (m_constantNaN == UINT_MAX) {
    700             // Search the constant pool for the value NaN, if we find it, we can just reuse this!
    701             unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
    702             for (m_constantNaN = 0; m_constantNaN < numberOfConstants; ++m_constantNaN) {
    703                 JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN);
    704                 if (JSValue::encode(testMe) == JSValue::encode(nan))
    705                     return getJSConstant(m_constantNaN);
    706             }
    707 
    708             // Add the value nan to the CodeBlock's constants, and add a corresponding slot in m_constants.
    709             ASSERT(m_constants.size() == numberOfConstants);
    710             addConstant(nan);
    711             m_constants.append(ConstantRecord());
    712             ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
    713         }
    714 
    715         // m_constantNaN must refer to an entry in the CodeBlock's constant pool that has the value nan.
    716         ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).isDouble());
    717         ASSERT(std::isnan(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).asDouble()));
    718         return getJSConstant(m_constantNaN);
    719     }
    720    
    721     Node* cellConstant(JSCell* cell)
    722     {
    723         HashMap<JSCell*, Node*>::AddResult result = m_cellConstantNodes.add(cell, nullptr);
    724         if (result.isNewEntry) {
    725             ASSERT(!Heap::isZombified(cell));
    726             result.iterator->value = addToGraph(WeakJSConstant, OpInfo(cell));
    727         }
    728        
    729         return result.iterator->value;
    730     }
    731    
    732     Node* inferredConstant(JSValue value)
    733     {
    734         if (value.isCell())
    735             return cellConstant(value.asCell());
    736         return getJSConstantForValue(value);
    737     }
    738    
    739568    InlineCallFrame* inlineCallFrame()
    740569    {
     
    821650            m_parameterSlots = parameterSlots;
    822651
    823         int dummyThisArgument = op == Call ? 0 : 1;
     652        int dummyThisArgument = op == Call || op == NativeCall ? 0 : 1;
    824653        for (int i = 0 + dummyThisArgument; i < argCount; ++i)
    825654            addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
     
    832661    Node* cellConstantWithStructureCheck(JSCell* object, Structure* structure)
    833662    {
    834         Node* objectNode = cellConstant(object);
     663        Node* objectNode = weakJSConstant(object);
    835664        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
    836665        return objectNode;
    837666    }
    838667   
    839     Node* cellConstantWithStructureCheck(JSCell* object)
    840     {
    841         return cellConstantWithStructureCheck(object, object->structure());
    842     }
    843 
    844668    SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
    845669    {
     
    972796    }
    973797   
    974     bool structureChainIsStillValid(bool direct, Structure* previousStructure, StructureChain* chain)
    975     {
    976         if (direct)
    977             return true;
    978        
    979         if (!previousStructure->storedPrototype().isNull() && previousStructure->storedPrototype().asCell()->structure() != chain->head()->get())
    980             return false;
    981        
    982         for (WriteBarrier<Structure>* it = chain->head(); *it; ++it) {
    983             if (!(*it)->storedPrototype().isNull() && (*it)->storedPrototype().asCell()->structure() != it[1].get())
    984                 return false;
    985         }
    986        
    987         return true;
    988     }
    989    
    990798    void buildOperandMapsIfNecessary();
    991799   
     
    1000808    unsigned m_currentIndex;
    1001809
    1002     // We use these values during code generation, and to avoid the need for
    1003     // special handling we make sure they are available as constants in the
    1004     // CodeBlock's constant pool. These variables are initialized to
    1005     // UINT_MAX, and lazily updated to hold an index into the CodeBlock's
    1006     // constant pool, as necessary.
    1007     unsigned m_constantUndefined;
    1008     unsigned m_constantNull;
    1009     unsigned m_constantNaN;
    1010     unsigned m_constant1;
    1011     HashMap<JSCell*, unsigned> m_cellConstants;
    1012     HashMap<JSCell*, Node*> m_cellConstantNodes;
    1013 
    1014     // A constant in the constant pool may be represented by more than one
    1015     // node in the graph, depending on the context in which it is being used.
    1016     struct ConstantRecord {
    1017         ConstantRecord()
    1018             : asInt32(0)
    1019             , asNumeric(0)
    1020             , asJSValue(0)
    1021         {
    1022         }
    1023 
    1024         Node* asInt32;
    1025         Node* asNumeric;
    1026         Node* asJSValue;
    1027     };
    1028 
    1029     // Track the index of the node whose result is the current value for every
    1030     // register value in the bytecode - argument, local, and temporary.
    1031     Vector<ConstantRecord, 16> m_constants;
     810    FrozenValue* m_constantUndefined;
     811    FrozenValue* m_constantNull;
     812    FrozenValue* m_constantNaN;
     813    FrozenValue* m_constantOne;
     814    Vector<Node*, 16> m_constants;
    1032815
    1033816    // The number of arguments passed to the function.
     
    1064847        // direct, caller).
    1065848        Vector<unsigned> m_identifierRemap;
    1066         Vector<unsigned> m_constantRemap;
    1067849        Vector<unsigned> m_constantBufferRemap;
    1068850        Vector<unsigned> m_switchRemap;
     
    1135917                return operand;
    1136918           
    1137             if (operand.isConstant()) {
    1138                 VirtualRegister result = VirtualRegister(m_constantRemap[operand.toConstantIndex()]);
    1139                 ASSERT(result.isConstant());
    1140                 return result;
    1141             }
     919            ASSERT(!operand.isConstant());
    1142920
    1143921            return VirtualRegister(operand.offset() + m_inlineCallFrame->stackOffset);
     
    1173951    // Mapping between identifier names and numbers.
    1174952    BorrowedIdentifierMap m_identifierMap;
    1175     // Mapping between values and constant numbers.
    1176     JSValueMap m_jsValueMap;
    1177     // Index of the empty value, or UINT_MAX if there is no mapping. This is a horrible
    1178     // work-around for the fact that JSValueMap can't handle "empty" values.
    1179     unsigned m_emptyJSValueIndex;
    1180953   
    1181954    CodeBlock* m_dfgCodeBlock;
     
    1225998    CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
    1226999   
    1227     if (m_graph.isConstant(callTarget)) {
    1228         callLinkStatus = CallLinkStatus(
    1229             m_graph.valueOfJSConstant(callTarget)).setIsProved(true);
    1230     }
     1000    if (callTarget->hasConstant())
     1001        callLinkStatus = CallLinkStatus(callTarget->asJSValue()).setIsProved(true);
    12311002   
    12321003    if (!callLinkStatus.canOptimize()) {
     
    12741045            m_graph.compilation()->noticeInlinedCall();
    12751046        return;
    1276     } else if (JSFunction* function = callLinkStatus.function())
    1277         if (function->isHostFunction()) {
     1047    } else if (isFTL(m_graph.m_plan.mode)) {
     1048        JSFunction* function = callLinkStatus.function();
     1049        if (function && function->isHostFunction()) {
    12781050            emitFunctionChecks(callLinkStatus, callTarget, registerOffset, specializationKind);
    12791051            knownFunction = function;
    1280         }
    1281    
    1282     addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset)->giveKnownFunction(knownFunction);
     1052
     1053            if (op == Call)
     1054                op = NativeCall;
     1055            else {
     1056                ASSERT(op == Construct);
     1057                op = NativeConstruct;
     1058            }
     1059        }
     1060    }
     1061    Node* call = addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset);
     1062
     1063    if (knownFunction)
     1064        call->giveKnownFunction(knownFunction);
    12831065}
    12841066
     
    12991081   
    13001082    if (JSFunction* function = callLinkStatus.function())
    1301         addToGraph(CheckFunction, OpInfo(function), callTarget, thisArgument);
     1083        addToGraph(CheckFunction, OpInfo(m_graph.freeze(function)), callTarget, thisArgument);
    13021084    else {
    13031085        ASSERT(callLinkStatus.structure());
     
    14561238   
    14571239    parseCodeBlock();
     1240    prepareToParseBlock(); // Reset our state now that we're back to the outer code.
    14581241   
    14591242    m_currentIndex = oldIndex;
     
    15451328{
    15461329    if (argumentCountIncludingThis == 1) { // Math.min()
    1547         set(VirtualRegister(resultOperand), constantNaN());
     1330        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
    15481331        return true;
    15491332    }
     
    15701353    case AbsIntrinsic: {
    15711354        if (argumentCountIncludingThis == 1) { // Math.abs()
    1572             set(VirtualRegister(resultOperand), constantNaN());
     1355            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
    15731356            return true;
    15741357        }
     
    15941377    case SinIntrinsic: {
    15951378        if (argumentCountIncludingThis == 1) {
    1596             set(VirtualRegister(resultOperand), constantNaN());
     1379            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
    15971380            return true;
    15981381        }
     
    17411524       
    17421525    case DFGTrueIntrinsic: {
    1743         set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true)));
     1526        set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
    17441527        return true;
    17451528    }
     
    17471530    case OSRExitIntrinsic: {
    17481531        addToGraph(ForceOSRExit);
    1749         set(VirtualRegister(resultOperand), constantUndefined());
     1532        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
    17501533        return true;
    17511534    }
     
    17531536    case IsFinalTierIntrinsic: {
    17541537        set(VirtualRegister(resultOperand),
    1755             getJSConstantForValue(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
     1538            jsConstant(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
    17561539        return true;
    17571540    }
     
    17631546                node->setHeapPrediction(SpecInt32);
    17641547        }
    1765         set(VirtualRegister(resultOperand), constantUndefined());
     1548        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
    17661549        return true;
    17671550    }
     
    18691652       
    18701653        if (argumentCountIncludingThis <= 1)
    1871             result = cellConstant(m_vm->smallStrings.emptyString());
     1654            result = jsConstant(m_vm->smallStrings.emptyString());
    18721655        else
    18731656            result = addToGraph(ToString, get(virtualRegisterForArgument(1, registerOffset)));
     
    19251708}
    19261709
    1927 Node* ByteCodeParser::emitPrototypeChecks(
    1928     Structure* structure, IntendedStructureChain* chain)
     1710void ByteCodeParser::emitChecks(const ConstantStructureCheckVector& vector)
    19291711{
    1930     ASSERT(structure);
    1931     Node* base = 0;
    1932     m_graph.chains().addLazily(chain);
    1933     Structure* currentStructure = structure;
    1934     JSObject* currentObject = 0;
    1935     for (unsigned i = 0; i < chain->size(); ++i) {
    1936         currentObject = asObject(currentStructure->prototypeForLookup(m_inlineStackTop->m_codeBlock));
    1937         currentStructure = chain->at(i);
    1938         base = cellConstantWithStructureCheck(currentObject, currentStructure);
    1939     }
    1940     return base;
     1712    for (unsigned i = 0; i < vector.size(); ++i)
     1713        cellConstantWithStructureCheck(vector[i].constant(), vector[i].structure());
    19411714}
    19421715
     
    19671740        //    optimal, if there is some rarely executed case in the chain that requires a lot
    19681741        //    of checks and those checks are not watchpointable.
    1969         for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) {
    1970             if (getByIdStatus[variantIndex].chain()) {
    1971                 emitPrototypeChecks(
    1972                     getByIdStatus[variantIndex].structureSet().onlyStructure(),
    1973                     getByIdStatus[variantIndex].chain());
    1974             }
    1975         }
     1742        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;)
     1743            emitChecks(getByIdStatus[variantIndex].constantChecks());
    19761744       
    19771745        // 2) Emit a MultiGetByOffset
     
    19941762    addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base);
    19951763   
    1996     if (variant.chain()) {
    1997         base = emitPrototypeChecks(
    1998             variant.structureSet().onlyStructure(), variant.chain());
    1999     }
     1764    emitChecks(variant.constantChecks());
     1765
     1766    if (variant.alternateBase())
     1767        base = weakJSConstant(variant.alternateBase());
    20001768   
    20011769    // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
     
    20101778    Node* loadedValue;
    20111779    if (variant.specificValue())
    2012         loadedValue = cellConstant(variant.specificValue().asCell());
     1780        loadedValue = weakJSConstant(variant.specificValue());
    20131781    else {
    20141782        loadedValue = handleGetByOffset(
     
    20941862                if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition)
    20951863                    continue;
    2096                 if (!putByIdStatus[variantIndex].structureChain())
    2097                     continue;
    2098                 emitPrototypeChecks(
    2099                     putByIdStatus[variantIndex].oldStructure(),
    2100                     putByIdStatus[variantIndex].structureChain());
     1864                emitChecks(putByIdStatus[variantIndex].constantChecks());
    21011865            }
    21021866        }
     
    21251889    }
    21261890
    2127     if (variant.structureChain() && !variant.structureChain()->isStillValid()) {
    2128         emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
    2129         return;
    2130     }
    2131    
    2132     m_graph.chains().addLazily(variant.structureChain());
    2133                
    21341891    addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
    2135     if (!isDirect)
    2136         emitPrototypeChecks(variant.oldStructure(), variant.structureChain());
     1892    emitChecks(variant.constantChecks());
    21371893
    21381894    ASSERT(variant.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
     
    21841940void ByteCodeParser::prepareToParseBlock()
    21851941{
    2186     for (unsigned i = 0; i < m_constants.size(); ++i)
    2187         m_constants[i] = ConstantRecord();
    2188     m_cellConstantNodes.clear();
     1942    m_constants.resize(0);
    21891943}
    21901944
     
    22181972                virtualRegisterForArgument(argument), m_codeBlock->isCaptured(virtualRegisterForArgument(argument)));
    22191973            variable->mergeStructureCheckHoistingFailed(
    2220                 m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
    2221                 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
     1974                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
    22221975            variable->mergeCheckArrayHoistingFailed(
    22231976                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
     
    22652018        // === Function entry opcodes ===
    22662019
    2267         case op_enter:
     2020        case op_enter: {
     2021            Node* undefined = addToGraph(JSConstant, OpInfo(m_constantUndefined));
    22682022            // Initialize all locals to undefined.
    22692023            for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
    2270                 set(virtualRegisterForLocal(i), constantUndefined(), ImmediateNakedSet);
     2024                set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet);
    22712025            if (m_inlineStackTop->m_codeBlock->specializationKind() == CodeForConstruct)
    2272                 set(virtualRegisterForArgument(0), constantUndefined(), ImmediateNakedSet);
     2026                set(virtualRegisterForArgument(0), undefined, ImmediateNakedSet);
    22732027            NEXT_OPCODE(op_enter);
     2028        }
    22742029           
    22752030        case op_touch_entry:
     
    22862041                    || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
    22872042                    || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
    2288                     || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)
    22892043                    || (op1->op() == GetLocal && op1->variableAccessData()->structureCheckHoistingFailed())) {
    22902044                    setThis(addToGraph(ToThis, op1));
     
    23032057            Node* callee = get(VirtualRegister(calleeOperand));
    23042058            bool alreadyEmitted = false;
    2305             if (callee->op() == WeakJSConstant) {
    2306                 JSCell* cell = callee->weakConstant();
    2307                 ASSERT(cell->inherits(JSFunction::info()));
    2308                
    2309                 JSFunction* function = jsCast<JSFunction*>(cell);
     2059            if (JSFunction* function = callee->dynamicCastConstant<JSFunction*>()) {
    23102060                if (Structure* structure = function->allocationStructure()) {
    2311                     addToGraph(AllocationProfileWatchpoint, OpInfo(function));
     2061                    addToGraph(AllocationProfileWatchpoint, OpInfo(m_graph.freeze(function)));
    23122062                    // The callee is still live up to this point.
    23132063                    addToGraph(Phantom, callee);
     
    23812131                set(VirtualRegister(currentInstruction[1].u.operand), get(VirtualRegister(JSStack::Callee)));
    23822132            } else {
     2133                FrozenValue* frozen = m_graph.freeze(cachedFunction);
    23832134                ASSERT(cachedFunction->inherits(JSFunction::info()));
    23842135                Node* actualCallee = get(VirtualRegister(JSStack::Callee));
    2385                 addToGraph(CheckFunction, OpInfo(cachedFunction), actualCallee);
    2386                 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(WeakJSConstant, OpInfo(cachedFunction)));
     2136                addToGraph(CheckFunction, OpInfo(frozen), actualCallee);
     2137                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(JSConstant, OpInfo(frozen)));
    23872138            }
    23882139            NEXT_OPCODE(op_get_callee);
     
    24482199            VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
    24492200            Node* op = get(srcDstVirtualRegister);
    2450             set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, one())));
     2201            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
    24512202            NEXT_OPCODE(op_inc);
    24522203        }
     
    24562207            VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
    24572208            Node* op = get(srcDstVirtualRegister);
    2458             set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, one())));
     2209            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
    24592210            NEXT_OPCODE(op_dec);
    24602211        }
     
    26732424        case op_eq_null: {
    26742425            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
    2675             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, constantNull()));
     2426            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull))));
    26762427            NEXT_OPCODE(op_eq_null);
    26772428        }
     
    26932444        case op_neq_null: {
    26942445            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
    2695             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, constantNull())));
     2446            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)))));
    26962447            NEXT_OPCODE(op_neq_null);
    26972448        }
     
    28182569            unsigned relativeOffset = currentInstruction[2].u.operand;
    28192570            Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
    2820             Node* condition = addToGraph(CompareEqConstant, value, constantNull());
     2571            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
    28212572            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jeq_null))), condition);
    28222573            LAST_OPCODE(op_jeq_null);
     
    28262577            unsigned relativeOffset = currentInstruction[2].u.operand;
    28272578            Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
    2828             Node* condition = addToGraph(CompareEqConstant, value, constantNull());
     2579            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
    28292580            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jneq_null), m_currentIndex + relativeOffset)), condition);
    28302581            LAST_OPCODE(op_jneq_null);
     
    29152666                if (target == data.fallThrough.bytecodeIndex())
    29162667                    continue;
    2917                 data.cases.append(SwitchCase::withBytecodeIndex(jsNumber(static_cast<int32_t>(table.min + i)), target));
     2668                data.cases.append(SwitchCase::withBytecodeIndex(m_graph.freeze(jsNumber(static_cast<int32_t>(table.min + i))), target));
    29182669            }
    29192670            flushIfTerminal(data);
     
    30662817            addToGraph(
    30672818                CheckFunction,
    3068                 OpInfo(actualPointerFor(m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)),
     2819                OpInfo(m_graph.freeze(static_cast<JSCell*>(actualPointerFor(
     2820                    m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)))),
    30692821                get(VirtualRegister(currentInstruction[1].u.operand)));
    30702822            addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr)));
     
    30852837            case GlobalPropertyWithVarInjectionChecks:
    30862838            case GlobalVarWithVarInjectionChecks:
    3087                 set(VirtualRegister(dst), cellConstant(m_inlineStackTop->m_codeBlock->globalObject()));
     2839                set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop->m_codeBlock->globalObject()));
    30882840                break;
    30892841            case ClosureVar:
     
    30932845                    && activation->symbolTable()->m_functionEnteredOnce.isStillValid()) {
    30942846                    addToGraph(FunctionReentryWatchpoint, OpInfo(activation->symbolTable()));
    3095                     set(VirtualRegister(dst), cellConstant(activation));
     2847                    set(VirtualRegister(dst), weakJSConstant(activation));
    30962848                    break;
    30972849                }
     
    31422894                addToGraph(Phantom, get(VirtualRegister(scope)));
    31432895                if (JSValue specificValue = status[0].specificValue())
    3144                     set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
     2896                    set(VirtualRegister(dst), weakJSConstant(specificValue.asCell()));
    31452897                else
    31462898                    set(VirtualRegister(dst), handleGetByOffset(prediction, base, identifierNumber, operand));
     
    31612913               
    31622914                addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
    3163                 set(VirtualRegister(dst), inferredConstant(specificValue));
     2915                set(VirtualRegister(dst), weakJSConstant(specificValue));
    31642916                break;
    31652917            }
     
    31772929                            addToGraph(Phantom, scopeNode);
    31782930                            addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
    3179                             set(VirtualRegister(dst), inferredConstant(value));
     2931                            set(VirtualRegister(dst), weakJSConstant(value));
    31802932                            break;
    31812933                        }
     
    32783030           
    32793031        case op_init_lazy_reg: {
    3280             set(VirtualRegister(currentInstruction[1].u.operand), getJSConstantForValue(JSValue()));
     3032            set(VirtualRegister(currentInstruction[1].u.operand), jsConstant(JSValue()));
    32813033            ASSERT(operandIsLocal(currentInstruction[1].u.operand));
    32823034            m_graph.m_lazyVars.set(VirtualRegister(currentInstruction[1].u.operand).toLocal());
     
    34333185    for (size_t i = 0; i < m_codeBlock->numberOfIdentifiers(); ++i)
    34343186        m_identifierMap.add(m_codeBlock->identifier(i).impl(), i);
    3435     for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i) {
    3436         JSValue value = m_codeBlock->getConstant(i + FirstConstantRegisterIndex);
    3437         if (!value)
    3438             m_emptyJSValueIndex = i + FirstConstantRegisterIndex;
    3439         else
    3440             m_jsValueMap.add(JSValue::encode(value), i + FirstConstantRegisterIndex);
    3441     }
    34423187   
    34433188    m_haveBuiltOperandMaps = true;
     
    35373282       
    35383283        m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
    3539         m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
    35403284        m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
    35413285        m_switchRemap.resize(codeBlock->numberOfSwitchJumpTables());
     
    35473291                byteCodeParser->m_graph.identifiers().addLazily(rep);
    35483292            m_identifierRemap[i] = result.iterator->value;
    3549         }
    3550         for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) {
    3551             JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex);
    3552             if (!value) {
    3553                 if (byteCodeParser->m_emptyJSValueIndex == UINT_MAX) {
    3554                     byteCodeParser->m_emptyJSValueIndex = byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex;
    3555                     byteCodeParser->addConstant(JSValue());
    3556                     byteCodeParser->m_constants.append(ConstantRecord());
    3557                 }
    3558                 m_constantRemap[i] = byteCodeParser->m_emptyJSValueIndex;
    3559                 continue;
    3560             }
    3561             JSValueMap::AddResult result = byteCodeParser->m_jsValueMap.add(JSValue::encode(value), byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex);
    3562             if (result.isNewEntry) {
    3563                 byteCodeParser->addConstant(value);
    3564                 byteCodeParser->m_constants.append(ConstantRecord());
    3565             }
    3566             m_constantRemap[i] = result.iterator->value;
    35673293        }
    35683294        for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) {
     
    35963322
    35973323        m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
    3598         m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
    35993324        m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
    36003325        m_switchRemap.resize(codeBlock->numberOfSwitchJumpTables());
    36013326        for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i)
    36023327            m_identifierRemap[i] = i;
    3603         for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i)
    3604             m_constantRemap[i] = i + FirstConstantRegisterIndex;
    36053328        for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i)
    36063329            m_constantBufferRemap[i] = i;
     
    36103333    }
    36113334   
    3612     for (size_t i = 0; i < m_constantRemap.size(); ++i)
    3613         ASSERT(m_constantRemap[i] >= static_cast<unsigned>(FirstConstantRegisterIndex));
    3614    
    36153335    byteCodeParser->m_inlineStackTop = this;
    36163336}
     
    36183338void ByteCodeParser::parseCodeBlock()
    36193339{
     3340    prepareToParseBlock();
     3341   
    36203342    CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
    36213343   
Note: See TracChangeset for help on using the changeset viewer.