1. 24 Jul, 2013 40 commits
    • oliver@apple.com's avatar
      fourthTier: DFG shouldn't create CheckStructures for array accesses except if... · 58cdc336
      oliver@apple.com authored
      fourthTier: DFG shouldn't create CheckStructures for array accesses except if the ArrayMode implies an original array access
      https://bugs.webkit.org/show_bug.cgi?id=118867
      
      Reviewed by Mark Hahnenberg.
      
      This allows us to kill off a bunch of code in the parser, in fixup, and to simplify
      ArrayProfile.
      
      It also makes it easier to ask any array-using node how to create its type check.
      
      Doing this required fixing a bug in LowLevelInterpreter64, where it was storing into
      an array profile, thinking that it was storing into a value profile. Reshuffling the
      fields in ArrayProfile revealed this.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescriptionWithoutUpdating):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (ArrayProfile):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::updateAllArrayPredictions):
      (JSC::CodeBlock::updateAllPredictions):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::updateAllArrayPredictions):
      * dfg/DFGArrayMode.h:
      (ArrayMode):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getArrayModeConsideringSlowPath):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (FixupPhase):
      (JSC::DFG::FixupPhase::checkArray):
      (JSC::DFG::FixupPhase::blessArrayOperation):
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153281 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      58cdc336
    • oliver@apple.com's avatar
      fourthTier: CFA should consider live-at-head for clobbering and dumping · 96feafa0
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118857
      
      Reviewed by Mark Hahnenberg.
      
      - clobberStructures() was not considering nodes live-at-head when in SSA
        form. This means it would fail to clobber some structures.
      
      - dump() was not considering nodes live-at-head when in SSA form. This
        means it wouldn't dump everything that you might be interested in.
      
      - AbstractState::m_currentNode is a useless variable and we should get
        rid of it.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::AbstractState):
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::AbstractState::reset):
      (JSC::DFG::AbstractState::startExecuting):
      (JSC::DFG::AbstractState::clobberStructures):
      (JSC::DFG::AbstractState::dump):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153280 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      96feafa0
    • oliver@apple.com's avatar
      fourthTier: Add a phase to create loop pre-headers · 5663e31c
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118778
      
      Reviewed by Oliver Hunt.
      
      Add a loop pre-header creation phase. Any loop that doesn't already have
      just one predecessor that isn't part of the loop has a pre-header
      prepended. All non-loop predecessors then jump to that pre-header.
      
      Also fix a handful of bugs:
      
      - DFG::Analysis should set m_valid before running the analysis, since that
        makes it easier to use ASSERT(m_valid) in the analysis' methods, which
        may be called by the analysis before the analysis completes. NaturalLoops
        does this with loopsOf().
      
      - NaturalLoops::headerOf() was missing a check for innerMostLoopOf()
        returning 0, since that'll happen if the block isn't in any loop.
      
      - Change BlockInsertionSet to dethread the graph, since anyone using it
        will want to do so.
      
      - Change dethreading to ignore SSA form graphs.
      
      This also adds NaturalLoops::belongsTo(), which I always used in the
      pre-header creation phase. I didn't end up using it but I'll probably use
      it in the near future.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAnalysis.h:
      (JSC::DFG::Analysis::computeIfNecessary):
      * dfg/DFGBlockInsertionSet.cpp:
      (JSC::DFG::BlockInsertionSet::execute):
      * dfg/DFGCriticalEdgeBreakingPhase.cpp:
      (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dethread):
      * dfg/DFGLoopPreHeaderCreationPhase.cpp: Added.
      (DFG):
      (LoopPreHeaderCreationPhase):
      (JSC::DFG::LoopPreHeaderCreationPhase::LoopPreHeaderCreationPhase):
      (JSC::DFG::LoopPreHeaderCreationPhase::run):
      (JSC::DFG::performLoopPreHeaderCreation):
      * dfg/DFGLoopPreHeaderCreationPhase.h: Added.
      (DFG):
      * dfg/DFGNaturalLoops.h:
      (NaturalLoop):
      (JSC::DFG::NaturalLoops::headerOf):
      (JSC::DFG::NaturalLoops::innerMostLoopOf):
      (JSC::DFG::NaturalLoops::innerMostOuterLoop):
      (JSC::DFG::NaturalLoops::belongsTo):
      (NaturalLoops):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153279 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5663e31c
    • oliver@apple.com's avatar
      fourthTier: Rationalize Node::replacement · 6c816f4b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118774
      
      Reviewed by Oliver Hunt.
      
      - Clearing of replacements is now done in Graph::clearReplacements().
      
      - New nodes now have replacement set to 0.
      
      - Node::replacement is now part of a 'misc' union. I'll be putting at least
        one other field into that union as part of LICM work (see
        https://bugs.webkit.org/show_bug.cgi?id=118749).
      
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::run):
      (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::run):
      (JSC::DFG::CSEPhase::setReplacement):
      (JSC::DFG::CSEPhase::performBlockCSE):
      * dfg/DFGGraph.cpp:
      (DFG):
      (JSC::DFG::Graph::clearReplacements):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::performSubstitutionForEdge):
      (Graph):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::Node):
      * dfg/DFGSSAConversionPhase.cpp:
      (JSC::DFG::SSAConversionPhase::run):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153278 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6c816f4b
    • oliver@apple.com's avatar
      fourthTier: NaturalLoops should be able to quickly answer questions like "what... · 4fe26dec
      oliver@apple.com authored
      fourthTier: NaturalLoops should be able to quickly answer questions like "what loops own this basic block"
      https://bugs.webkit.org/show_bug.cgi?id=118750
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      * dfg/DFGBasicBlock.h:
      (BasicBlock):
      * dfg/DFGNaturalLoops.cpp:
      (JSC::DFG::NaturalLoops::compute):
      (JSC::DFG::NaturalLoops::loopsOf):
      * dfg/DFGNaturalLoops.h:
      (DFG):
      (JSC::DFG::NaturalLoop::NaturalLoop):
      (NaturalLoop):
      (JSC::DFG::NaturalLoop::index):
      (JSC::DFG::NaturalLoop::isOuterMostLoop):
      (JSC::DFG::NaturalLoop::addBlock):
      (JSC::DFG::NaturalLoops::headerOf):
      (JSC::DFG::NaturalLoops::innerMostLoopOf):
      (NaturalLoops):
      (JSC::DFG::NaturalLoops::innerMostOuterLoop):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      Add a utility function for inserting an element into a vector that has bounded size,
      and where the insertion causes things to drop off the end.
      
      * wtf/StdLibExtras.h:
      (WTF):
      (WTF::insertIntoBoundedVector):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153277 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4fe26dec
    • oliver@apple.com's avatar
      fourthTier: don't GC when shutting down the VM · 0f220549
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118751
      
      Reviewed by Mark Hahnenberg.
      
      * heap/Heap.h:
      (Heap):
      * runtime/VM.cpp:
      (JSC::VM::~VM):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153276 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0f220549
    • oliver@apple.com's avatar
      fourthTier: We should have a reduced FTL LLVM pipeline tool in the repository · f13fc1d0
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118647
      
      Rubber stamped by Geoffrey Garen and Mark Hahnenberg.
      
      Add a tool that takes in an LLVM bitcode file and JITs it in exactly the same
      way that the FTL would.
      
      Also add a tool that combines multiple LLVM modules generated by FTL into a
      single module.
      
      * ReducedFTL: Added.
      * ReducedFTL/ReducedFTL.c: Added.
      (usage):
      (currentTime):
      (MemorySection):
      (mmAllocateCodeSection):
      (mmAllocateDataSection):
      (mmApplyPermissions):
      (mmDestroy):
      (symbolLookupCallback):
      (main):
      * ReducedFTL/build.sh: Added.
      * ReducedFTL/combineModules.rb: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153275 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f13fc1d0
    • oliver@apple.com's avatar
      fourthTier: DFG should have an SSA form for use by FTL · 827d2cf7
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118338
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Adds an SSA form to the DFG. We can convert ThreadedCPS form into SSA form
      after breaking critical edges. The conversion algorithm follows Aycock and
      Horspool, and the SSA form itself follows something I've done before, where
      instead of having Phi functions specify input nodes corresponding to block
      predecessors, we instead have Upsilon functions in the predecessors that
      specify which value in that block goes into which subsequent Phi. Upsilons
      don't have to dominate Phis (usually they don't) and they correspond to a
      non-SSA "mov" into the Phi's "variable". This gives all of the good
      properties of SSA, while ensuring that a bunch of CFG transformations don't
      have to be SSA-aware.
      
      So far the only DFG phases that are SSA-aware are DCE and CFA. CFG
      simplification is probably SSA-aware by default, though I haven't tried it.
      Constant folding probably needs a few tweaks, but is likely ready. Ditto
      for CSE, though it's not clear that we'd want to use block-local CSE when
      we could be doing GVN.
      
      Currently only the FTL can generate code from the SSA form, and there is no
      way to convert from SSA to ThreadedCPS or LoadStore. There probably will
      never be such a capability.
      
      In order to handle OSR exit state in the SSA, we place MovHints at Phi
      points. Other than that, you can reconstruct state-at-exit by forward
      propagating MovHints. Note that MovHint is the new SetLocal in SSA.
      SetLocal and GetLocal only survive into SSA if they are on captured
      variables, or in the case of flushes. A "live SetLocal" will be
      NodeMustGenerate and will always correspond to a flush. Computing the
      state-at-exit requires running SSA liveness analysis, OSR availability
      analysis, and flush liveness analysis. The FTL runs all of these prior to
      generating code. While OSR exit continues to be tricky, much of the logic
      is now factored into separate phases and the backend has to do less work
      to reason about what happened outside of the basic block that is being
      lowered.
      
      Conversion from DFG SSA to LLVM SSA is done by ensuring that we generate
      code in depth-first order, thus guaranteeing that a node will always be
      lowered (and hence have a LValue) before any of the blocks dominated by
      that node's block have code generated. For Upsilon/Phi, we just use
      alloca's. We could do something more clever there, but it's probably not
      worth it, at least not now.
      
      Finally, while the SSA form is currently only being converted to LLVM IR,
      there is nothing that prevents us from considering other backends in the
      future - with the caveat that this form is designed to be first lowered to
      a lower-level SSA before actual machine code generation commences. So we
      ought to either use LLVM (the intended path) or we will have to write our
      own SSA low-level backend.
      
      This runs all of the code that the FTL was known to run previously. No
      change in performance for now. But it does open some exciting
      possibilities!
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/Operands.h:
      (JSC::OperandValueTraits::dump):
      (JSC::Operands::fill):
      (Operands):
      (JSC::Operands::clear):
      (JSC::Operands::operator==):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::setLiveValues):
      (DFG):
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      (JSC::DFG::AbstractState::merge):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      * dfg/DFGAdjacencyList.h:
      (JSC::DFG::AdjacencyList::justOneChild):
      (AdjacencyList):
      * dfg/DFGBasicBlock.cpp: Added.
      (DFG):
      (JSC::DFG::BasicBlock::BasicBlock):
      (JSC::DFG::BasicBlock::~BasicBlock):
      (JSC::DFG::BasicBlock::ensureLocals):
      (JSC::DFG::BasicBlock::isInPhis):
      (JSC::DFG::BasicBlock::isInBlock):
      (JSC::DFG::BasicBlock::removePredecessor):
      (JSC::DFG::BasicBlock::replacePredecessor):
      (JSC::DFG::BasicBlock::dump):
      (JSC::DFG::BasicBlock::SSAData::SSAData):
      (JSC::DFG::BasicBlock::SSAData::~SSAData):
      * dfg/DFGBasicBlock.h:
      (BasicBlock):
      (JSC::DFG::BasicBlock::operator[]):
      (JSC::DFG::BasicBlock::successor):
      (JSC::DFG::BasicBlock::successorForCondition):
      (SSAData):
      * dfg/DFGBasicBlockInlines.h:
      (DFG):
      * dfg/DFGBlockInsertionSet.cpp: Added.
      (DFG):
      (JSC::DFG::BlockInsertionSet::BlockInsertionSet):
      (JSC::DFG::BlockInsertionSet::~BlockInsertionSet):
      (JSC::DFG::BlockInsertionSet::insert):
      (JSC::DFG::BlockInsertionSet::insertBefore):
      (JSC::DFG::BlockInsertionSet::execute):
      * dfg/DFGBlockInsertionSet.h: Added.
      (DFG):
      (BlockInsertionSet):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::run):
      * dfg/DFGCFGSimplificationPhase.cpp:
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
      * dfg/DFGCommon.cpp:
      (WTF::printInternal):
      * dfg/DFGCommon.h:
      (JSC::DFG::doesKill):
      (DFG):
      (JSC::DFG::killStatusForDoesKill):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (JSC::DFG::ConstantFoldingPhase::isCapturedAtOrAfter):
      * dfg/DFGCriticalEdgeBreakingPhase.cpp: Added.
      (DFG):
      (CriticalEdgeBreakingPhase):
      (JSC::DFG::CriticalEdgeBreakingPhase::CriticalEdgeBreakingPhase):
      (JSC::DFG::CriticalEdgeBreakingPhase::run):
      (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
      (JSC::DFG::performCriticalEdgeBreaking):
      * dfg/DFGCriticalEdgeBreakingPhase.h: Added.
      (DFG):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::findTypeCheckRoot):
      (JSC::DFG::DCEPhase::countNode):
      (DCEPhase):
      (JSC::DFG::DCEPhase::countEdge):
      (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGEdge.cpp:
      (JSC::DFG::Edge::dump):
      * dfg/DFGEdge.h:
      (JSC::DFG::Edge::Edge):
      (JSC::DFG::Edge::setNode):
      (JSC::DFG::Edge::useKindUnchecked):
      (JSC::DFG::Edge::setUseKind):
      (JSC::DFG::Edge::setProofStatus):
      (JSC::DFG::Edge::willNotHaveCheck):
      (JSC::DFG::Edge::willHaveCheck):
      (Edge):
      (JSC::DFG::Edge::killStatusUnchecked):
      (JSC::DFG::Edge::killStatus):
      (JSC::DFG::Edge::setKillStatus):
      (JSC::DFG::Edge::doesKill):
      (JSC::DFG::Edge::doesNotKill):
      (JSC::DFG::Edge::shift):
      (JSC::DFG::Edge::makeWord):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGFlushFormat.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h: Added.
      (DFG):
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      (WTF):
      * dfg/DFGFlushLivenessAnalysisPhase.cpp: Added.
      (DFG):
      (FlushLivenessAnalysisPhase):
      (JSC::DFG::FlushLivenessAnalysisPhase::FlushLivenessAnalysisPhase):
      (JSC::DFG::FlushLivenessAnalysisPhase::run):
      (JSC::DFG::FlushLivenessAnalysisPhase::process):
      (JSC::DFG::FlushLivenessAnalysisPhase::setForNode):
      (JSC::DFG::FlushLivenessAnalysisPhase::flushFormat):
      (JSC::DFG::performFlushLivenessAnalysis):
      * dfg/DFGFlushLivenessAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::dumpBlockHeader):
      (DFG):
      (JSC::DFG::Graph::addForDepthFirstSort):
      (JSC::DFG::Graph::getBlocksInDepthFirstOrder):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::convertToConstant):
      (JSC::DFG::Graph::valueProfileFor):
      (Graph):
      * dfg/DFGInsertionSet.h:
      (DFG):
      (JSC::DFG::InsertionSet::execute):
      * dfg/DFGLivenessAnalysisPhase.cpp: Added.
      (DFG):
      (LivenessAnalysisPhase):
      (JSC::DFG::LivenessAnalysisPhase::LivenessAnalysisPhase):
      (JSC::DFG::LivenessAnalysisPhase::run):
      (JSC::DFG::LivenessAnalysisPhase::process):
      (JSC::DFG::LivenessAnalysisPhase::addChildUse):
      (JSC::DFG::performLivenessAnalysis):
      * dfg/DFGLivenessAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGNode.cpp:
      (JSC::DFG::Node::hasVariableAccessData):
      (DFG):
      * dfg/DFGNode.h:
      (DFG):
      (Node):
      (JSC::DFG::Node::hasLocal):
      (JSC::DFG::Node::variableAccessData):
      (JSC::DFG::Node::hasPhi):
      (JSC::DFG::Node::phi):
      (JSC::DFG::Node::takenBlock):
      (JSC::DFG::Node::notTakenBlock):
      (JSC::DFG::Node::successor):
      (JSC::DFG::Node::successorForCondition):
      (JSC::DFG::nodeComparator):
      (JSC::DFG::nodeListDump):
      (JSC::DFG::nodeMapDump):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSRAvailabilityAnalysisPhase.cpp: Added.
      (DFG):
      (OSRAvailabilityAnalysisPhase):
      (JSC::DFG::OSRAvailabilityAnalysisPhase::OSRAvailabilityAnalysisPhase):
      (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
      (JSC::DFG::performOSRAvailabilityAnalysis):
      * dfg/DFGOSRAvailabilityAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSSAConversionPhase.cpp: Added.
      (DFG):
      (SSAConversionPhase):
      (JSC::DFG::SSAConversionPhase::SSAConversionPhase):
      (JSC::DFG::SSAConversionPhase::run):
      (JSC::DFG::SSAConversionPhase::forwardPhiChildren):
      (JSC::DFG::SSAConversionPhase::forwardPhi):
      (JSC::DFG::SSAConversionPhase::forwardPhiEdge):
      (JSC::DFG::SSAConversionPhase::deduplicateChildren):
      (JSC::DFG::SSAConversionPhase::addFlushedLocalOp):
      (JSC::DFG::SSAConversionPhase::addFlushedLocalEdge):
      (JSC::DFG::performSSAConversion):
      * dfg/DFGSSAConversionPhase.h: Added.
      (DFG):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      (Validate):
      (JSC::DFG::Validate::validateCPS):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::flushFormat):
      (VariableAccessData):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileJSConstant):
      (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
      (JSC::FTL::LowerDFGToLLVM::compileArithMod):
      (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
      (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compileBitAnd):
      (JSC::FTL::LowerDFGToLLVM::compileBitOr):
      (JSC::FTL::LowerDFGToLLVM::compileBitXor):
      (JSC::FTL::LowerDFGToLLVM::compileBitRShift):
      (JSC::FTL::LowerDFGToLLVM::compileBitLShift):
      (JSC::FTL::LowerDFGToLLVM::compileBitURShift):
      (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
      (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
      (JSC::FTL::LowerDFGToLLVM::compileGetButterfly):
      (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (JSC::FTL::LowerDFGToLLVM::compileGetByOffset):
      (JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::compileLogicalNot):
      (JSC::FTL::LowerDFGToLLVM::speculateBackward):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::lowStorage):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::speculateBoolean):
      (JSC::FTL::LowerDFGToLLVM::isLive):
      (JSC::FTL::LowerDFGToLLVM::use):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):
      (JSC::FTL::LowerDFGToLLVM::setInt32):
      (JSC::FTL::LowerDFGToLLVM::setJSValue):
      (JSC::FTL::LowerDFGToLLVM::setBoolean):
      (JSC::FTL::LowerDFGToLLVM::setStorage):
      (JSC::FTL::LowerDFGToLLVM::setDouble):
      (JSC::FTL::LowerDFGToLLVM::isValid):
      * ftl/FTLLoweredNodeValue.h: Added.
      (FTL):
      (LoweredNodeValue):
      (JSC::FTL::LoweredNodeValue::LoweredNodeValue):
      (JSC::FTL::LoweredNodeValue::isSet):
      (JSC::FTL::LoweredNodeValue::operator!):
      (JSC::FTL::LoweredNodeValue::value):
      (JSC::FTL::LoweredNodeValue::block):
      * ftl/FTLValueFromBlock.h:
      (JSC::FTL::ValueFromBlock::ValueFromBlock):
      (ValueFromBlock):
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      - Extend variadicity of PrintStream and dataLog.
      
      - Give HashSet the ability to add a span of things.
      
      - Give HashSet the ability to == another HashSet.
      
      - Note FIXME's in HashTable concerning copying performance, that affects
        the way that the DFG now uses HashSets and HashMaps.
      
      - Factor out the bulk-insertion logic of JSC::DFG::InsertionSet into
        WTF::Insertion, so that it can be used in more places.
      
      - Create a dumper for lists and maps.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/DataLog.h:
      (WTF):
      (WTF::dataLog):
      * wtf/HashSet.h:
      (HashSet):
      (WTF):
      (WTF::::add):
      (WTF::=):
      * wtf/HashTable.h:
      (WTF::::HashTable):
      (WTF::=):
      * wtf/Insertion.h: Added.
      (WTF):
      (Insertion):
      (WTF::Insertion::Insertion):
      (WTF::Insertion::index):
      (WTF::Insertion::element):
      (WTF::Insertion::operator<):
      (WTF::executeInsertions):
      * wtf/ListDump.h: Added.
      (WTF):
      (ListDump):
      (WTF::ListDump::ListDump):
      (WTF::ListDump::dump):
      (MapDump):
      (WTF::MapDump::MapDump):
      (WTF::MapDump::dump):
      (WTF::listDump):
      (WTF::sortedListDump):
      (WTF::lessThan):
      (WTF::mapDump):
      (WTF::sortedMapDump):
      * wtf/PrintStream.h:
      (PrintStream):
      (WTF::PrintStream::print):
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153274 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      827d2cf7
    • oliver@apple.com's avatar
      fourthTier: Resurrect the CLoop LLINT on the FTL branch. · 0d587919
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118144.
      
      Reviewed by Mark Hahnenberg.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::jitType):
        - Fix the CodeBlock jitType to be InterpreterThunk when !ENABLE_JIT.
      * bytecode/JumpTable.h:
      (JSC::SimpleJumpTable::clear):
      * interpreter/StackIterator.cpp:
      (JSC::StackIterator::Frame::bytecodeOffset):
      (JSC::StackIterator::Frame::print):
      * jit/JITCode.cpp:
      (JSC):
      * jit/JITExceptions.cpp:
      (JSC::getExceptionLocation):
      * llint/LowLevelInterpreter.cpp:
      * offlineasm/cloop.rb:
      * runtime/Structure.cpp:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153273 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0d587919
    • oliver@apple.com's avatar
      fourthTier: NaturalLoops + Profiler = Crash · 1d325fa7
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118486
      
      Reviewed by Geoffrey Garen.
      
      I borked dominators in:
      http://trac.webkit.org/changeset/152431/branches/dfgFourthTier/Source/JavaScriptCore/dfg/DFGDominators.h
      
      This patch also adds some debug support, and fixes the loop that adds a block to
      an already-existing natural loop. Note that we currently don't take that path in
      most programs, but it will arise, for example if you use 'continue' - though you'd
      have to use it rather cleverly since the bytecode will not jump to the loop header
      in most uses of 'continue'.
      
      * dfg/DFGDominators.cpp:
      (JSC::DFG::Dominators::dump):
      (DFG):
      * dfg/DFGDominators.h:
      (JSC::DFG::Dominators::dominates):
      (Dominators):
      * dfg/DFGNaturalLoops.cpp:
      (JSC::DFG::NaturalLoops::compute):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153272 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1d325fa7
    • oliver@apple.com's avatar
      fourthTier: DFG::AbstractState::beginBasicBlock() should set m_haveStructures... · 06cf1a8b
      oliver@apple.com authored
      fourthTier: DFG::AbstractState::beginBasicBlock() should set m_haveStructures if any of the valuesAtHead have either a current known structure or a non-top/non-bottom array modes
      https://bugs.webkit.org/show_bug.cgi?id=118489
      
      Reviewed by Mark Hahnenberg.
      
      * bytecode/ArrayProfile.h:
      (JSC::arrayModesAreClearOrTop):
      (JSC):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::beginBasicBlock):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::hasClobberableState):
      (AbstractValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153271 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      06cf1a8b
    • oliver@apple.com's avatar
      fourthTier: CheckArray should call the right version of filterArrayModes · 52be8f8c
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118488
      
      Reviewed by Filip Pizlo.
      
      Currently in the CFA CheckArray doesn't call the right filterArrayMode which can cause
      the CFA to ignore when it sees a contradiction.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153270 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      52be8f8c
    • oliver@apple.com's avatar
      fourthTier: Graph::clearAndDerefChild() makes no sense anymore, and neither does Nop · afbdabe0
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118452
      
      Reviewed by Sam Weinig.
      
      Noticed that ArgumentsSimplificationPhase was converting something to a Nop and then
      resetting its children using clearAndDerefChild(). Using Nop instead of Phantom is a
      holdover from back when we needed a no-MustGenerate no-op. We don't anymore. Using
      clearAndDerefChild() was necessary back when we did eager reference counting. We
      don't need to do that anymore, and in fact clearAndDerefChild() appeared to not do
      any reference counting, so it was badly named to begin with.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::willHaveCodeGenOrOSR):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153269 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      afbdabe0
    • oliver@apple.com's avatar
      fourthTier: FTL should better report its compile-times and it should be able... · 62242ce4
      oliver@apple.com authored
      fourthTier: FTL should better report its compile-times and it should be able to run in a mode where it doesn't spend time generating OSR exits
      https://bugs.webkit.org/show_bug.cgi?id=118401
      
      Reviewed by Sam Weinig.
      
      Add two new OSR exit modes, which are useful only for playing with compile times:
      
      - All OSR exits are llvm.trap().
      
      - OSR exits don't take arguments and have no exit value marshaling.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPlan.h:
      (Plan):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::trap):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153268 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      62242ce4
    • oliver@apple.com's avatar
      fourthTier: DFG should refer to BasicBlocks by BasicBlock* and not BlockIndex · 426f5b02
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118339
      
      Reviewed by Michael Saboff.
      
      This accomplishes two goals:
      
      1) Simplifies a bunch of code. You can now much more directly get to a successor
         or predecessor, since you just get the pointer directly. The backend(s) always
         hold onto a pointer to the block they're on, so you don't have to do work to
         get the block from the index.
      
      2) It allows for the possibility of inserting blocks into the program.
         Previously, if you did that, you'd have to edit all references to blocks since
         those references would have outdated indexing after an insertion. Now, if you
         change the indexing, you just have to invalidate some analyses and make sure
         that you change each block's BasicBlock::index accordingly.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::mergeToSuccessors):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::run):
      * dfg/DFGBasicBlock.h:
      (DFG):
      (JSC::DFG::BasicBlock::BasicBlock):
      (JSC::DFG::BasicBlock::size):
      (JSC::DFG::BasicBlock::isEmpty):
      (JSC::DFG::BasicBlock::at):
      (JSC::DFG::BasicBlock::operator[]):
      (JSC::DFG::BasicBlock::last):
      (JSC::DFG::BasicBlock::resize):
      (JSC::DFG::BasicBlock::grow):
      (BasicBlock):
      (JSC::DFG::BasicBlock::append):
      (JSC::DFG::BasicBlock::numSuccessors):
      (JSC::DFG::BasicBlock::successor):
      (JSC::DFG::BasicBlock::successorForCondition):
      (JSC::DFG::BasicBlock::dump):
      (UnlinkedBlock):
      (JSC::DFG::UnlinkedBlock::UnlinkedBlock):
      (JSC::DFG::getBytecodeBeginForBlock):
      (JSC::DFG::blockForBytecodeOffset):
      * dfg/DFGByteCodeParser.cpp:
      (ByteCodeParser):
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::linkBlock):
      (JSC::DFG::ByteCodeParser::linkBlocks):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseCodeBlock):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::performBlockCFA):
      (JSC::DFG::CFAPhase::performForwardCFA):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      (JSC::DFG::CFGSimplificationPhase::convertToJump):
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
      (JSC::DFG::CPSRethreadingPhase::propagatePhis):
      (CPSRethreadingPhase):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::run):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::run):
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      * dfg/DFGDisassembler.cpp:
      (JSC::DFG::Disassembler::Disassembler):
      (JSC::DFG::Disassembler::createDumpList):
      * dfg/DFGDisassembler.h:
      (JSC::DFG::Disassembler::setForBlockIndex):
      * dfg/DFGDominators.cpp:
      (JSC::DFG::Dominators::compute):
      (JSC::DFG::Dominators::iterateForBlock):
      * dfg/DFGDominators.h:
      (JSC::DFG::Dominators::dominates):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::dumpBlockHeader):
      (JSC::DFG::Graph::handleSuccessor):
      (JSC::DFG::Graph::determineReachability):
      (JSC::DFG::Graph::resetReachability):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::numBlocks):
      (JSC::DFG::Graph::block):
      (JSC::DFG::Graph::lastBlock):
      (Graph):
      (JSC::DFG::Graph::appendBlock):
      (JSC::DFG::Graph::killBlock):
      (DFG):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::JITCompiler):
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::setForBlockIndex):
      * dfg/DFGNaturalLoops.cpp:
      (JSC::DFG::NaturalLoop::dump):
      (JSC::DFG::NaturalLoops::compute):
      (JSC::DFG::NaturalLoops::loopsOf):
      * dfg/DFGNaturalLoops.h:
      (JSC::DFG::NaturalLoop::NaturalLoop):
      (JSC::DFG::NaturalLoop::addBlock):
      (JSC::DFG::NaturalLoop::header):
      (JSC::DFG::NaturalLoop::at):
      (JSC::DFG::NaturalLoop::operator[]):
      (JSC::DFG::NaturalLoop::contains):
      (NaturalLoop):
      (JSC::DFG::NaturalLoops::headerOf):
      (NaturalLoops):
      * dfg/DFGNode.h:
      (DFG):
      (JSC::DFG::SwitchCase::SwitchCase):
      (JSC::DFG::SwitchCase::withBytecodeIndex):
      (SwitchCase):
      (JSC::DFG::SwitchCase::targetBytecodeIndex):
      (JSC::DFG::SwitchData::SwitchData):
      (JSC::DFG::SwitchData::setFallThroughBytecodeIndex):
      (JSC::DFG::SwitchData::fallThroughBytecodeIndex):
      (SwitchData):
      (JSC::DFG::Node::setTakenBlock):
      (JSC::DFG::Node::setNotTakenBlock):
      (JSC::DFG::Node::takenBlock):
      (JSC::DFG::Node::notTakenBlock):
      (JSC::DFG::Node::successor):
      (JSC::DFG::Node::successorForCondition):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagateForward):
      (JSC::DFG::PredictionPropagationPhase::propagateBackward):
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeCompare):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::createOSREntries):
      (JSC::DFG::SpeculativeJIT::linkOSREntries):
      (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::compileRegExpExec):
      (JSC::DFG::SpeculativeJIT::addBranch):
      (JSC::DFG::SpeculativeJIT::linkBranches):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::nextBlock):
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::branchDouble):
      (JSC::DFG::SpeculativeJIT::branchDoubleNonZero):
      (JSC::DFG::SpeculativeJIT::branch32):
      (JSC::DFG::SpeculativeJIT::branchTest32):
      (JSC::DFG::SpeculativeJIT::branch64):
      (JSC::DFG::SpeculativeJIT::branch8):
      (JSC::DFG::SpeculativeJIT::branchPtr):
      (JSC::DFG::SpeculativeJIT::branchTestPtr):
      (JSC::DFG::SpeculativeJIT::branchTest8):
      (JSC::DFG::SpeculativeJIT::jump):
      (JSC::DFG::SpeculativeJIT::addBranch):
      (JSC::DFG::SpeculativeJIT::StringSwitchCase::StringSwitchCase):
      (StringSwitchCase):
      (JSC::DFG::SpeculativeJIT::BranchRecord::BranchRecord):
      (BranchRecord):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::run):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      (JSC::DFG::TypeCheckHoistingPhase::disableHoistingAcrossOSREntries):
      * dfg/DFGUnificationPhase.cpp:
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      (JSC::DFG::Validate::checkOperand):
      (JSC::DFG::Validate::reportValidationContext):
      * dfg/DFGVirtualRegisterAllocationPhase.cpp:
      (JSC::DFG::VirtualRegisterAllocationPhase::run):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileJump):
      (JSC::FTL::LowerDFGToLLVM::compileBranch):
      (JSC::FTL::LowerDFGToLLVM::lowBlock):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      426f5b02
    • oliver@apple.com's avatar
      fourthTier: Unreviewed, add a helpful comment for why DCE is needed in the FTL. · 5a554043
      oliver@apple.com authored
      I believe I've now twice down the experiment of disabling DCE in the FTL,
      only to realize that this can't work, and that DCE is needed. I'd kind of
      like to not make that mistake again.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153266 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5a554043
    • oliver@apple.com's avatar
      fourthTier: DFG::Node::m_opInfo2 should also be a uintptr_t · d83bc44d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118340
      
      Reviewed by Sam Weinig.
      
      * dfg/DFGNode.h:
      (JSC::DFG::Node::Node):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153265 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d83bc44d
    • oliver@apple.com's avatar
      fourthTier: Have fewer Arrayify's · 4cd40f2e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118335
      
      Reviewed by Mark Hahnenberg.
      
      A lot of Arrayify's arise because some program saw Int32 arrays early on in
      execution, but then they all got converted to Double arrays and the program
      will never see Int32 arrays ever again. Prior to this change you would always
      have an Arrayify in this case. But with this change, the first time that an
      ArrayProfile is about to go polymorphic in computeUpdatedPrediction(), it
      instead forcibly monomorphises itself to the latest-seen structure.
      Thereafter it will never again perform this monomorphisation. This is
      controlled by ArrayProfile::m_didPerformFirstRunPruning. This is a 5%
      speed-up on Kraken/imaging-gaussian-blur with the FTL enabled, and it
      unblocks a bunch of stuff we want to do in the future because it makes a
      bunch of loops effect-free.
      
      We will still want to implement Arrayify hoisting in the future, but this is
      great anyway because it's better to not have Arrayifications than it is to
      have hoisted Arrayifications.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescription):
      (JSC):
      (JSC::ArrayProfile::briefDescriptionWithoutUpdating):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (ArrayProfile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153264 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4cd40f2e
    • oliver@apple.com's avatar
      fourthTier: add option to disable OSR entry in loops · d2a1638b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118329
      
      Reviewed by Mark Hahnenberg.
      
      This adds that option, and also makes the OSR exit reoptimization trigger rely less on
      OSR entry failing. Now even if we never attempt OSR entry but our execution counter gets
      high after a small number of OSR exits, we will recompile.
      
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::handleExitCounts):
      * dfg/DFGOperations.cpp:
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_loop_hint):
      (JSC::JIT::emitSlow_op_loop_hint):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153263 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d2a1638b
    • oliver@apple.com's avatar
      fourthTier: since the FTL disassembly hacks cannot distinguish between code... · e6dfe683
      oliver@apple.com authored
      fourthTier: since the FTL disassembly hacks cannot distinguish between code and data, the LLVM disassembler symbol table callback should be able to deal gracefully with arbitrary garbage
      https://bugs.webkit.org/show_bug.cgi?id=118313
      
      Reviewed by Mark Hahnenberg.
      
      Give it a mode where we can still crash on unrecognized reference types, so that we might
      implement them in the future, but by default just print some stuff and keep going.
      
      * disassembler/LLVMDisassembler.cpp:
      (JSC):
      (JSC::symbolLookupCallback):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153262 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e6dfe683
    • oliver@apple.com's avatar
      fourthTier: FTL should use the equivalent of llvm opt -O2 by default · 0fc04331
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118311
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Use a PassManagerBuilder instead of rolling our own.
      
      This boosts our speed-up by another 5% or so.
      
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * runtime/Options.h:
      (JSC):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      * wtf/LLVMHeaders.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153261 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0fc04331
    • oliver@apple.com's avatar
      fourthTier: FTL should run LICM after AA setup · 64fde79a
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118277
      
      Reviewed by Maciej Stachowiak.
      
      LICM queries alias analysis. Hence, just like GVN, it should run after
      we have set up the alias analysis.
      
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153260 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      64fde79a
    • oliver@apple.com's avatar
      fourthTier: FTL should run AA passes before GVN · 52b453f1
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118276
      
      Rubber stamped by Geoffrey Garen.
      
      These enable load elimination in GVN.
      
      Immediately gives us a speed-up on a bunch of benchmarks I hacked to run
      properly in the FTL. One example is 20% on imaging-gaussian-blur. (Fair
      warning: the stock version of that benchmark won't see speed-ups -
      probably slow-downs instead - because the FTL can't do OSR entry yet.)
      Another example is the findGraphNode function, which now sees a 7%
      speed-up, and that's without even doing LICM or other good things.
      
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153259 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      52b453f1
    • oliver@apple.com's avatar
      fourthTier: Make Graph::substituteGetLocal() out-of-line · b595abac
      oliver@apple.com authored
      Rubber stamped by Geoffrey Garen.
      
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::substituteGetLocal):
      (DFG):
      * dfg/DFGGraph.h:
      (Graph):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153258 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      b595abac
    • oliver@apple.com's avatar
      fourthTier: DFG should know how to find natural loops · fc3f1177
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118152
      
      Reviewed by Mark Hahnenberg.
      
      There are a bunch of things we can do when we know where the loops are.
      Previously we didn't. With this patch, we do.
      
      This patch adds the classic dominator based natural loop finder.
      
      The only client of this right now is the DFG::Disassembler. It prints out
      a summary of the analysis for each block.
      
      This will become more important when I do
      https://bugs.webkit.org/show_bug.cgi?id=118151, which definitely requires
      this kind of analysis, at least if we want to do the optimization over
      DFG IR (and I'm pretty sure we do).
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAnalysis.h: Added.
      (DFG):
      (Analysis):
      (JSC::DFG::Analysis::Analysis):
      (JSC::DFG::Analysis::invalidate):
      (JSC::DFG::Analysis::computeIfNecessary):
      (JSC::DFG::Analysis::isValid):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      * dfg/DFGDisassembler.cpp:
      (JSC::DFG::Disassembler::createDumpList):
      * dfg/DFGDominators.cpp:
      (JSC::DFG::Dominators::Dominators):
      (JSC::DFG::Dominators::compute):
      * dfg/DFGDominators.h:
      (Dominators):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dumpBlockHeader):
      (JSC::DFG::Graph::invalidateCFG):
      (DFG):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGNaturalLoops.cpp: Added.
      (DFG):
      (JSC::DFG::NaturalLoop::dump):
      (JSC::DFG::NaturalLoops::NaturalLoops):
      (JSC::DFG::NaturalLoops::~NaturalLoops):
      (JSC::DFG::NaturalLoops::compute):
      (JSC::DFG::NaturalLoops::loopsOf):
      (JSC::DFG::NaturalLoops::dump):
      * dfg/DFGNaturalLoops.h: Added.
      (DFG):
      (NaturalLoop):
      (JSC::DFG::NaturalLoop::NaturalLoop):
      (JSC::DFG::NaturalLoop::addBlock):
      (JSC::DFG::NaturalLoop::header):
      (JSC::DFG::NaturalLoop::size):
      (JSC::DFG::NaturalLoop::at):
      (JSC::DFG::NaturalLoop::operator[]):
      (JSC::DFG::NaturalLoop::contains):
      (NaturalLoops):
      (JSC::DFG::NaturalLoops::numLoops):
      (JSC::DFG::NaturalLoops::loop):
      (JSC::DFG::NaturalLoops::headerOf):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153257 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      fc3f1177
    • oliver@apple.com's avatar
      fourthTier: JSC's disassembly infrastructure should be able to disassemble the... · 49a2bafa
      oliver@apple.com authored
      fourthTier: JSC's disassembly infrastructure should be able to disassemble the code that LLVM generates
      https://bugs.webkit.org/show_bug.cgi?id=118148
      
      Source/JavaScriptCore:
      
      Reviewed by Anders Carlsson.
      
      Oh boy. UDis86 cannot disassemble the AVX (or whatever it's called) stuff
      that LLVM generates for floating point. So the right decision is to
      switch to the LLVM disassembler, right? Wrong!! LLVM's disassembler
      cannot disassemble the load-from-absolute-address-into-%rax instructions
      that our JIT generates quite a lot of.
      
      So, this keeps the UDis86 disassembler, but adds the LLVM disassembler,
      and requires the caller of disassemble() to hint which one is likely to
      be less wrong for the given code.
      
      Maybe in the future LLVM will catch up to UDis86, but it's definitely not
      there right now.
      
      This now allows us to disassemble all of the code that LLVM generates.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * disassembler/Disassembler.cpp:
      (JSC::disassemble):
      * disassembler/Disassembler.h:
      (JSC::tryToDisassemble):
      (JSC):
      * disassembler/LLVMDisassembler.cpp: Added.
      (JSC):
      (JSC::symbolLookupCallback):
      (JSC::tryToDisassembleWithLLVM):
      * disassembler/LLVMDisassembler.h: Added.
      (JSC):
      (JSC::tryToDisassembleWithLLVM):
      * disassembler/UDis86Disassembler.cpp:
      (JSC::tryToDisassembleWithUDis86):
      * disassembler/UDis86Disassembler.h: Added.
      (JSC):
      (JSC::tryToDisassembleWithUDis86):
      * disassembler/X86Disassembler.cpp: Added.
      (JSC):
      (JSC::tryToDisassemble):
      * ftl/FTLAbbreviatedTypes.h:
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLJITCode.h:
      * ftl/FTLJITFinalizer.h:
      * ftl/FTLLLVMHeaders.h: Removed.
      * ftl/FTLLink.cpp:
      * runtime/InitializeThreading.cpp:
      (JSC::initializeThreadingOnce):
      * runtime/Options.h:
      (JSC):
      
      Source/WTF:
      
      Reviewed by Anders Carlsson.
      
      We now use LLVM for two things: disassembler and FTL. Separate out the question
      of whether we have LLVM (HAVE(LLVM)) from whether we want to use the LLVM
      disassembler (USE(LLVM_DISASSEMBLER)) and whether we enable the FTL
      (ENABLE(FTL_JIT)).
      
      Also move the cruft for including LLVM headers into WTF since now we use it in
      a bunch of places, not all related to FTL. There's no obvious place to put that
      file in JSC so I put it in WTF.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/LLVMHeaders.h: Copied from Source/JavaScriptCore/ftl/FTLLLVMHeaders.h.
      * wtf/Platform.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153256 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      49a2bafa
    • oliver@apple.com's avatar
      fourthTier: FTL should be able to dump disassembly · 789501da
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118141
      
      Reviewed by Geoffrey Garen.
      
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      789501da
    • oliver@apple.com's avatar
      fourthTier: FTL should support hole/OOB PutByVal's · 8c55ed0b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118112
      
      Reviewed by Geoffrey Garen.
      
      Added a common code generator for the out-of-bounds case that is reused by
      all contiguous-like arrays (Int32, Double, Contiguous).
      
      This is relatively straight-forward, except that it's the first time that
      the FTL has to call DFG operations that take more than two arguments.
      
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::functionType):
      (JSC::FTL::buildCall):
      * ftl/FTLAbstractHeapRepository.h:
      (FTL):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::contiguousPutByValOutOfBounds):
      (JSC::FTL::LowerDFGToLLVM::vmCall):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::call):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153254 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      8c55ed0b
    • oliver@apple.com's avatar
      fourthTier: FTL::canCompile(Graph&) should not consider nodes that won't be compiled · 5ef61346
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118097
      
      Reviewed by Mark Hahnenberg.
      
      This increases coverage to include programs that have unprofiled paths. Those paths will
      often have nodes that appear to do untyped speculations, and the FTL sometimes doesn't
      support those; except that it doesn't matter since the reason why they were untyped is
      that they were unprofiled and anyway we won't run them because we'll exit before them.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5ef61346
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArrayifyToStructure · b0cdcb4a
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118095
      
      Reviewed by Mark Hahnenberg.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
      (LowerDFGToLLVM):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153252 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      b0cdcb4a
    • oliver@apple.com's avatar
      fourthTier: FTL should support... · 6a2aafdc
      oliver@apple.com authored
      fourthTier: FTL should support ForwardCheckStructure/ForwardStructureTransitionWatchpoint and doing so shouldn't break V8/crypto
      https://bugs.webkit.org/show_bug.cgi?id=118091
      
      Reviewed by Mark Hahnenberg.
      
      I was going to just add ForwardCheckStructure/ForwardStructureTransitionWatchpoint support,
      which is trivial. But doing so increases coverage a lot, and revealed long-standing bugs in
      the FTL. I then fixed those bugs, also:
      
      - The FTL should not attempt to compile a block that is not reachable according to the CFA.
        This is analogous to terminating basic block compilation if the CFA becomes !isValid().
        Attempting to compile such a block means that you're running on broken CFA state, and the
        CFA will become inconsistent with the code you're generating, leading to some
        strangeness. For example, the FTL relies on the CFA to tell it that we gave up compiling
        a node and hence don't have LValue's for that node (by virtue of us giving up due to
        !isValid()). But the CFA's isValid() bit will not be set correctly for blocks that
        weren't visited by the CFA at all, and the CFA expects you to know this because it
        expects that you already checked BasicBlock::cfaHasVisited.
      
      - SetLocal needs to change the ValueSource of the operand to indicate that its value has
        been stashed in the local (i.e. the "reference" corresponding to the operand in FTL
        speak). This is because although OSR exit already knows that the value of the operand is
        stored in the Node, and it already knows what LValue corresponds to the node, OSR exit
        will also assume that if the Node dies then the value-at-exit for that operand should be
        Dead (i.e. jsUndefined). But the Node dying, and the local dying, are two distinct
        things; in particular the local always outlives the Node in the case of a SetLocal. So,
        we just need to have SetLocal have the ValueSource be BlahInLocal rather than HaveNode,
        to ensure that OSR exit knows that the darn thing is really live until the end of the
        basic block, as opposed to until whenever the Node dies (which could be at any time).
      
      - PutByOffset was erroneously storing to an offset from the base object, rather than an
        offset from the storage. Note that the storage will be the base object (exactly - i.e.
        same node, same value) for inline stores, but will be a distinct thing for out-of-line
        stores.
      
      - At-head set-up of OSR exit state was using ValueInLocals for variables forced double,
        when it should have been using DoubleInLocals.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compilePutByOffset):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153251 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6a2aafdc
    • oliver@apple.com's avatar
      fourthTier: FTL should support PutByVal · 5b4f1429
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118075
      
      Reviewed by Mark Hahnenberg.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153250 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5b4f1429
    • oliver@apple.com's avatar
      fourthTier: Convert versus AsIs should have no bearing on whether we can do... · 1e177c35
      oliver@apple.com authored
      fourthTier: Convert versus AsIs should have no bearing on whether we can do the SaneChain optimization for double array GetByVals
      https://bugs.webkit.org/show_bug.cgi?id=118028
      
      Reviewed by Sam Weinig.
      
      The SaneChain optimization allows us to get rid of the NaN check on loading from
      a double array, if the result is used in an arithmetic op that wouldn't
      distinguish between NaN and undefined. Normally the NaN check would be needed
      because NaN is the hole marker.
      
      The SaneChain optimization definitely requires that you're an Original array,
      since we need to watchpoint the array prototype chain. And so it also needs to
      be a JSArray, and not an object that has indexed double properties. We also
      require an in-bounds access, since the backend is only capable of the
      optimization in the in-bounds case (though we could extend it to OOB in the
      future). But whether the array is being converted or is as-is isn't relevant.
      Either way, if it's a double original array in-bounds access by the time that
      the array check (or conversion!) completes, we can do the optimization.
      
      Ever-so-slight speed-up on Kraken/imaging-gaussian-blur.
      
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153249 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1e177c35
    • oliver@apple.com's avatar
      fourthTier: DFG should support switch_string · 5c826c0d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117967
      
      Source/JavaScriptCore:
      
      Reviewed by Sam Weinig.
      
      Add a reusable binary switch creator.
      
      Implement switch on string using three modes:
      
      - Binary switch on StringImpl* in the case of identifiers.
      
      - Trie of binary switches on characters in the case of a not-too-big
        switch over not-too-big 8-bit strings.
      
      - Hash lookup if all else fails.
      
      Anywhere from a 2x to 3x speed-up on microbenchmarks that stress
      string switches. 25-35% speed-up on HashMap tests. 4% speed-up on
      pdfjs.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/JumpTable.h:
      (StringJumpTable):
      (JSC::StringJumpTable::clear):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGBinarySwitch.cpp: Added.
      (DFG):
      (JSC::DFG::BinarySwitch::BinarySwitch):
      (JSC::DFG::BinarySwitch::advance):
      (JSC::DFG::BinarySwitch::build):
      * dfg/DFGBinarySwitch.h: Added.
      (DFG):
      (BinarySwitch):
      (JSC::DFG::BinarySwitch::caseIndex):
      (JSC::DFG::BinarySwitch::caseValue):
      (JSC::DFG::BinarySwitch::fallThrough):
      (JSC::DFG::BinarySwitch::Case::Case):
      (Case):
      (JSC::DFG::BinarySwitch::Case::operator<):
      (JSC::DFG::BinarySwitch::BranchCode::BranchCode):
      (BranchCode):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGLazyJSValue.cpp:
      (JSC::DFG::LazyJSValue::getValue):
      (JSC::DFG::equalToStringImpl):
      (DFG):
      (JSC::DFG::LazyJSValue::strictEqual):
      (JSC::DFG::LazyJSValue::dump):
      * dfg/DFGLazyJSValue.h:
      (JSC::DFG::LazyJSValue::knownStringImpl):
      (LazyJSValue):
      (JSC::DFG::LazyJSValue::stringImpl):
      (JSC::DFG::LazyJSValue::switchLookupValue):
      * dfg/DFGNode.cpp:
      (WTF::printInternal):
      * dfg/DFGNode.h:
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::emitSwitchChar):
      (JSC::DFG::SpeculativeJIT::StringSwitchCase::operator<):
      (DFG):
      (JSC::DFG::SpeculativeJIT::emitBinarySwitchStringRecurse):
      (JSC::DFG::SpeculativeJIT::emitSwitchStringOnString):
      (JSC::DFG::SpeculativeJIT::emitSwitchString):
      (JSC::DFG::SpeculativeJIT::emitSwitch):
      (JSC::DFG::SpeculativeJIT::addBranch):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      (JSC::DFG::SpeculativeJIT::branch8):
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::StringSwitchCase::StringSwitchCase):
      (StringSwitchCase):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileSwitch):
      * runtime/Options.h:
      (JSC):
      
      Source/WTF:
      
      Reviewed by Sam Weinig.
      
      Make it possible to compare a RefPtr<StringImpl> and a StringImpl* without
      having to ref the StringImpl.
      
      * wtf/text/StringHash.h:
      (WTF::StringHash::equal):
      
      LayoutTests:
      
      Reviewed by Sam Weinig.
      
      * fast/js/regress/script-tests/switch-string-basic-big-var.js: Added.
      (foo):
      (make):
      * fast/js/regress/script-tests/switch-string-basic-big.js: Added.
      (foo):
      (make):
      * fast/js/regress/script-tests/switch-string-basic-var.js: Added.
      (foo):
      (make):
      * fast/js/regress/script-tests/switch-string-basic.js: Added.
      (foo):
      * fast/js/regress/script-tests/switch-string-big-length-tower-var.js: Added.
      (foo):
      * fast/js/regress/script-tests/switch-string-length-tower-var.js: Added.
      (foo):
      * fast/js/regress/script-tests/switch-string-length-tower.js: Added.
      (foo):
      * fast/js/regress/script-tests/switch-string-short.js: Added.
      (foo):
      * fast/js/regress/switch-string-basic-big-expected.txt: Added.
      * fast/js/regress/switch-string-basic-big-var-expected.txt: Added.
      * fast/js/regress/switch-string-basic-big-var.html: Added.
      * fast/js/regress/switch-string-basic-big.html: Added.
      * fast/js/regress/switch-string-basic-expected.txt: Added.
      * fast/js/regress/switch-string-basic-var-expected.txt: Added.
      * fast/js/regress/switch-string-basic-var.html: Added.
      * fast/js/regress/switch-string-basic.html: Added.
      * fast/js/regress/switch-string-big-length-tower-var-expected.txt: Added.
      * fast/js/regress/switch-string-big-length-tower-var.html: Added.
      * fast/js/regress/switch-string-length-tower-expected.txt: Added.
      * fast/js/regress/switch-string-length-tower-var-expected.txt: Added.
      * fast/js/regress/switch-string-length-tower-var.html: Added.
      * fast/js/regress/switch-string-length-tower.html: Added.
      * fast/js/regress/switch-string-short-expected.txt: Added.
      * fast/js/regress/switch-string-short.html: Added.
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153248 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5c826c0d
    • oliver@apple.com's avatar
      fourthTier: Count external memory usage towards heap footprint · 8cebf376
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117948
      
      Reviewed by Geoffrey Garen.
      
      Source/JavaScriptCore:
      
      Currently just count strings. Strings get counted in such a way that we won't re-count strings
      that are aliased, by dividing by the reference count. This then ups the GC footprint and allows
      the collector to appropriately amortize itself.
      
      * heap/Heap.cpp:
      (JSC::Heap::Heap):
      (JSC::Heap::size):
      (JSC::Heap::collect):
      * heap/Heap.h:
      (Heap):
      * heap/SlotVisitor.h:
      * heap/SlotVisitorInlines.h:
      (JSC::SlotVisitor::reportExtraMemoryUsage):
      (JSC):
      * runtime/JSString.cpp:
      (JSC::JSString::visitChildren):
      
      Source/WTF:
      
      Expose some functionality needed for properly measuring StringImpl footprint.
      
      * wtf/Atomics.h:
      (WTF::weakCompareAndSwapSize):
      (WTF):
      * wtf/MathExtras.h:
      (divideRoundedUp):
      * wtf/text/StringImpl.h:
      (WTF::StringImpl::cost):
      (StringImpl):
      (WTF::StringImpl::costDuringGC):
      (WTF::StringImpl::refCount):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153247 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      8cebf376
    • oliver@apple.com's avatar
      fourthTier: DFG should optimize identifier string equality · dc3a19ab
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117920
      
      Reviewed by Sam Weinig.
      
      Note that this ChangeLog was supposed to be committed in r151890.
      
      Expose the IsIdentifier bit to the JIT.
      
      * wtf/text/StringImpl.h:
      (WTF::StringImpl::flagIsIdentifier):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153246 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      dc3a19ab
    • oliver@apple.com's avatar
      fourthTier: DFG should optimize identifier string equality · bd15be8f
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117920
      
      Source/JavaScriptCore:
      
      Reviewed by Sam Weinig.
      
      This is a 20% speed-up for string equality comparisons when both strings are
      identifiers.
      
      This is important for two reasons:
      
      1) Using strings as enumerations is an idiom. A great example is typeof. It
         would be great if this performed better.
      
      2) When I implement switch_string in the DFG, it would be great to optimize
         the case where the switched-on value is an identifier. That would involve
         a simple binary switch rather than a more complicated trie-switch over
         characters.
      
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      (JSC::speculationToAbbreviatedString):
      (JSC::speculationFromCell):
      * bytecode/SpeculatedType.h:
      (JSC):
      (JSC::isStringIdentSpeculation):
      (JSC::isStringSpeculation):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::shouldSpeculateStringIdent):
      (Node):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::compileStringEquality):
      (JSC::DFG::SpeculativeJIT::compileStringIdentEquality):
      (DFG):
      (JSC::DFG::SpeculativeJIT::speculateString):
      (JSC::DFG::SpeculativeJIT::speculateStringIdentAndLoadStorage):
      (JSC::DFG::SpeculativeJIT::speculateStringIdent):
      (JSC::DFG::SpeculativeJIT::speculate):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGUseKind.cpp:
      (WTF::printInternal):
      * dfg/DFGUseKind.h:
      (JSC::DFG::typeFilterFor):
      (JSC::DFG::isCell):
      
      LayoutTests:
      
      Reviewed by Sam Weinig.
      
      Add a benchmark for string equality where there is a long identifier, and
      also add a benchmark for non-identifier string equality (since the previous
      test for string equality was really identifier equality).
      
      * fast/js/regress/script-tests/string-long-ident-equality.js: Added.
      (foo):
      * fast/js/regress/script-tests/string-var-equality.js: Added.
      (addFoo):
      (foo):
      * fast/js/regress/string-long-ident-equality-expected.txt: Added.
      * fast/js/regress/string-long-ident-equality.html: Added.
      * fast/js/regress/string-var-equality-expected.txt: Added.
      * fast/js/regress/string-var-equality.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153245 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bd15be8f
    • oliver@apple.com's avatar
      fourthTier: DFG shouldn't exit just because a String GetByVal went out-of-bounds · 211b3bec
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117906
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      This does the obvious thing, but also makes sure that out-of-bounds accesses
      don't fall off into a C call, but try to do the fast thing if the prototype
      chain is sane. We ought to probably do this for other array accesses in the
      future, as well, since it's so darn easy.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::objectPrototypeIsSane):
      (JSC):
      (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
      (JSC::JSGlobalObject::stringPrototypeChainIsSane):
      * runtime/JSGlobalObject.h:
      (JSGlobalObject):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      The out-of-bounds benchmark that isn't insane speeds up by 22x in this
      patch.
      
      * fast/js/regress/script-tests/string-get-by-val-out-of-bounds-insane.js: Added.
      (foo):
      * fast/js/regress/script-tests/string-get-by-val-out-of-bounds.js: Added.
      (foo):
      * fast/js/regress/string-get-by-val-out-of-bounds-expected.txt: Added.
      * fast/js/regress/string-get-by-val-out-of-bounds-insane-expected.txt: Added.
      * fast/js/regress/string-get-by-val-out-of-bounds-insane.html: Added.
      * fast/js/regress/string-get-by-val-out-of-bounds.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153244 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      211b3bec
    • oliver@apple.com's avatar
      fourthTier: GC's put_by_id transition fixpoint should converge more quickly · c0a31d7e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117912
      
      Reviewed by Mark Hahnenberg.
      
      This was a rookie mistake. The GC does a classic forward data flow fixpoint. These work well so long as you
      iterate the program in program order, or at least something close to program order. Because I enjoy reverse
      loops ("while (n--) blah"), I ended up iterating in *reverse* of program order which ensured worst-case
      pathologies every single time. And unsurprisingly, this slowed down a program, namely pdfjs.
      
      Flipping the loops to iterate forward fixes a 90% regression in Octane/pdfjs and is otherwise neutral.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::propagateTransitions):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153243 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c0a31d7e
    • oliver@apple.com's avatar
      fourthTier: DFG should CSE MakeRope · c2eda9aa
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117905
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Adds MakeRope to the CSE phase and removes the comment that says that
      we could do it but aren't doing it.
      
      Also fixed SpeculatedType dumping so that if you have a Cell type then
      it just prints "Cell" and if you just have Object then it just prints
      "Object", instead of printing the long list of types.
      
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::performNodeCSE):
      
      LayoutTests:
      
      Reviewed by Geoffrey Garen.
      
      This benchmark speeds up by 50%.
      
      * fast/js/regress/make-rope-cse-expected.txt: Added.
      * fast/js/regress/make-rope-cse.html: Added.
      * fast/js/regress/script-tests/make-rope-cse.js: Added.
      (foo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153242 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c2eda9aa