WebKit-https.git
7 years agofourthTier: We should have a reduced FTL LLVM pipeline tool in the repository
oliver@apple.com [Thu, 25 Jul 2013 04:04:47 +0000 (04:04 +0000)]
fourthTier: We should have a reduced FTL LLVM pipeline tool in the repository
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: https://svn.webkit.org/repository/webkit/trunk@153275 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should have an SSA form for use by FTL
oliver@apple.com [Thu, 25 Jul 2013 04:04:45 +0000 (04:04 +0000)]
fourthTier: DFG should have an SSA form for use by FTL
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: https://svn.webkit.org/repository/webkit/trunk@153274 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Resurrect the CLoop LLINT on the FTL branch.
oliver@apple.com [Thu, 25 Jul 2013 04:04:39 +0000 (04:04 +0000)]
fourthTier: Resurrect the CLoop LLINT on the FTL branch.
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: https://svn.webkit.org/repository/webkit/trunk@153273 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: NaturalLoops + Profiler = Crash
oliver@apple.com [Thu, 25 Jul 2013 04:04:37 +0000 (04:04 +0000)]
fourthTier: NaturalLoops + Profiler = Crash
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: https://svn.webkit.org/repository/webkit/trunk@153272 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG::AbstractState::beginBasicBlock() should set m_haveStructures if...
oliver@apple.com [Thu, 25 Jul 2013 04:04:35 +0000 (04:04 +0000)]
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: https://svn.webkit.org/repository/webkit/trunk@153271 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: CheckArray should call the right version of filterArrayModes
oliver@apple.com [Thu, 25 Jul 2013 04:04:33 +0000 (04:04 +0000)]
fourthTier: CheckArray should call the right version of filterArrayModes
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: https://svn.webkit.org/repository/webkit/trunk@153270 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Graph::clearAndDerefChild() makes no sense anymore, and neither does Nop
oliver@apple.com [Thu, 25 Jul 2013 04:04:32 +0000 (04:04 +0000)]
fourthTier: Graph::clearAndDerefChild() makes no sense anymore, and neither does Nop
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: https://svn.webkit.org/repository/webkit/trunk@153269 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should better report its compile-times and it should be able to run...
oliver@apple.com [Thu, 25 Jul 2013 04:04:29 +0000 (04:04 +0000)]
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: https://svn.webkit.org/repository/webkit/trunk@153268 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should refer to BasicBlocks by BasicBlock* and not BlockIndex
oliver@apple.com [Thu, 25 Jul 2013 04:04:27 +0000 (04:04 +0000)]
fourthTier: DFG should refer to BasicBlocks by BasicBlock* and not BlockIndex
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: https://svn.webkit.org/repository/webkit/trunk@153267 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Unreviewed, add a helpful comment for why DCE is needed in the FTL.
oliver@apple.com [Thu, 25 Jul 2013 04:04:23 +0000 (04:04 +0000)]
fourthTier: Unreviewed, add a helpful comment for why DCE is needed in the FTL.

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: https://svn.webkit.org/repository/webkit/trunk@153266 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG::Node::m_opInfo2 should also be a uintptr_t
oliver@apple.com [Thu, 25 Jul 2013 04:04:21 +0000 (04:04 +0000)]
fourthTier: DFG::Node::m_opInfo2 should also be a uintptr_t
https://bugs.webkit.org/show_bug.cgi?id=118340

Reviewed by Sam Weinig.

* dfg/DFGNode.h:
(JSC::DFG::Node::Node):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153265 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Have fewer Arrayify's
oliver@apple.com [Thu, 25 Jul 2013 04:04:20 +0000 (04:04 +0000)]
fourthTier: Have fewer Arrayify's
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: https://svn.webkit.org/repository/webkit/trunk@153264 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: add option to disable OSR entry in loops
oliver@apple.com [Thu, 25 Jul 2013 04:04:18 +0000 (04:04 +0000)]
fourthTier: add option to disable OSR entry in loops
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: https://svn.webkit.org/repository/webkit/trunk@153263 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: since the FTL disassembly hacks cannot distinguish between code and data...
oliver@apple.com [Thu, 25 Jul 2013 04:04:16 +0000 (04:04 +0000)]
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: https://svn.webkit.org/repository/webkit/trunk@153262 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should use the equivalent of llvm opt -O2 by default
oliver@apple.com [Thu, 25 Jul 2013 04:04:14 +0000 (04:04 +0000)]
fourthTier: FTL should use the equivalent of llvm opt -O2 by default
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: https://svn.webkit.org/repository/webkit/trunk@153261 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should run LICM after AA setup
oliver@apple.com [Thu, 25 Jul 2013 04:04:12 +0000 (04:04 +0000)]
fourthTier: FTL should run LICM after AA setup
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: https://svn.webkit.org/repository/webkit/trunk@153260 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should run AA passes before GVN
oliver@apple.com [Thu, 25 Jul 2013 04:04:11 +0000 (04:04 +0000)]
fourthTier: FTL should run AA passes before GVN
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: https://svn.webkit.org/repository/webkit/trunk@153259 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Make Graph::substituteGetLocal() out-of-line
oliver@apple.com [Thu, 25 Jul 2013 04:04:09 +0000 (04:04 +0000)]
fourthTier: Make Graph::substituteGetLocal() out-of-line

Rubber stamped by Geoffrey Garen.

* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::substituteGetLocal):
(DFG):
* dfg/DFGGraph.h:
(Graph):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153258 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should know how to find natural loops
oliver@apple.com [Thu, 25 Jul 2013 04:04:08 +0000 (04:04 +0000)]
fourthTier: DFG should know how to find natural loops
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: https://svn.webkit.org/repository/webkit/trunk@153257 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: JSC's disassembly infrastructure should be able to disassemble the code...
oliver@apple.com [Thu, 25 Jul 2013 04:04:05 +0000 (04:04 +0000)]
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: https://svn.webkit.org/repository/webkit/trunk@153256 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should be able to dump disassembly
oliver@apple.com [Thu, 25 Jul 2013 04:04:02 +0000 (04:04 +0000)]
fourthTier: FTL should be able to dump disassembly
https://bugs.webkit.org/show_bug.cgi?id=118141

Reviewed by Geoffrey Garen.

* ftl/FTLCompile.cpp:
(JSC::FTL::compile):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153255 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support hole/OOB PutByVal's
oliver@apple.com [Thu, 25 Jul 2013 04:04:01 +0000 (04:04 +0000)]
fourthTier: FTL should support hole/OOB PutByVal's
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: https://svn.webkit.org/repository/webkit/trunk@153254 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL::canCompile(Graph&) should not consider nodes that won't be compiled
oliver@apple.com [Thu, 25 Jul 2013 04:03:59 +0000 (04:03 +0000)]
fourthTier: FTL::canCompile(Graph&) should not consider nodes that won't be compiled
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: https://svn.webkit.org/repository/webkit/trunk@153253 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support ArrayifyToStructure
oliver@apple.com [Thu, 25 Jul 2013 04:03:57 +0000 (04:03 +0000)]
fourthTier: FTL should support ArrayifyToStructure
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: https://svn.webkit.org/repository/webkit/trunk@153252 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support ForwardCheckStructure/ForwardStructureTransitionWatchp...
oliver@apple.com [Thu, 25 Jul 2013 04:03:56 +0000 (04:03 +0000)]
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: https://svn.webkit.org/repository/webkit/trunk@153251 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support PutByVal
oliver@apple.com [Thu, 25 Jul 2013 04:03:54 +0000 (04:03 +0000)]
fourthTier: FTL should support PutByVal
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: https://svn.webkit.org/repository/webkit/trunk@153250 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Convert versus AsIs should have no bearing on whether we can do the SaneC...
oliver@apple.com [Thu, 25 Jul 2013 04:03:52 +0000 (04:03 +0000)]
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: https://svn.webkit.org/repository/webkit/trunk@153249 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should support switch_string
oliver@apple.com [Thu, 25 Jul 2013 04:03:51 +0000 (04:03 +0000)]
fourthTier: DFG should support switch_string
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: https://svn.webkit.org/repository/webkit/trunk@153248 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Count external memory usage towards heap footprint
oliver@apple.com [Thu, 25 Jul 2013 04:03:46 +0000 (04:03 +0000)]
fourthTier: Count external memory usage towards heap footprint
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: https://svn.webkit.org/repository/webkit/trunk@153247 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should optimize identifier string equality
oliver@apple.com [Thu, 25 Jul 2013 04:03:44 +0000 (04:03 +0000)]
fourthTier: DFG should optimize identifier string equality
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: https://svn.webkit.org/repository/webkit/trunk@153246 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should optimize identifier string equality
oliver@apple.com [Thu, 25 Jul 2013 04:03:42 +0000 (04:03 +0000)]
fourthTier: DFG should optimize identifier string equality
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: https://svn.webkit.org/repository/webkit/trunk@153245 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG shouldn't exit just because a String GetByVal went out-of-bounds
oliver@apple.com [Thu, 25 Jul 2013 04:03:39 +0000 (04:03 +0000)]
fourthTier: DFG shouldn't exit just because a String GetByVal went out-of-bounds
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: https://svn.webkit.org/repository/webkit/trunk@153244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: GC's put_by_id transition fixpoint should converge more quickly
oliver@apple.com [Thu, 25 Jul 2013 04:03:36 +0000 (04:03 +0000)]
fourthTier: GC's put_by_id transition fixpoint should converge more quickly
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: https://svn.webkit.org/repository/webkit/trunk@153243 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should CSE MakeRope
oliver@apple.com [Thu, 25 Jul 2013 04:03:35 +0000 (04:03 +0000)]
fourthTier: DFG should CSE MakeRope
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: https://svn.webkit.org/repository/webkit/trunk@153242 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should't exit just because it GetByVal'd a big character
oliver@apple.com [Thu, 25 Jul 2013 04:03:33 +0000 (04:03 +0000)]
fourthTier: DFG should't exit just because it GetByVal'd a big character
https://bugs.webkit.org/show_bug.cgi?id=117899

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

Add a slow path. Also clarify handling of GetByVal in PutStructure elimination.
Previously it would fail due to canExit() but now we can also fail because
GetByVal(String) can allocate. Just make it so GetByVal is totally poisoned, in
a very explicit way.

* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::putStructureStoreElimination):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
(SpeculativeJIT):

LayoutTests:

Reviewed by Mark Hahnenberg.

This benchmark speeds up by 3x.

* fast/js/regress/script-tests/string-get-by-val-big-char.js: Added.
(foo):
* fast/js/regress/string-get-by-val-big-char-expected.txt: Added.
* fast/js/regress/string-get-by-val-big-char.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153241 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Small strings shouldn't get GC'd
oliver@apple.com [Thu, 25 Jul 2013 04:03:30 +0000 (04:03 +0000)]
fourthTier: Small strings shouldn't get GC'd
https://bugs.webkit.org/show_bug.cgi?id=117897

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

Kill off the code needed to allocate them lazily and finalize them.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
* heap/Heap.cpp:
(JSC::Heap::collect):
* runtime/JSString.h:
(JSC::jsSingleCharacterString):
(JSC::jsSingleCharacterSubstring):
(JSC::jsString):
(JSC::jsSubstring8):
(JSC::jsSubstring):
(JSC::jsOwnedString):
* runtime/NumberPrototype.cpp:
(JSC::integerValueToString):
* runtime/SmallStrings.cpp:
(JSC):
(JSC::SmallStrings::initializeCommonStrings):
(JSC::SmallStrings::visitStrongReferences):
* runtime/SmallStrings.h:
(JSC::SmallStrings::singleCharacterString):
(SmallStrings):

LayoutTests:

Reviewed by Mark Hahnenberg.

This test speeds up by 5%.

* fast/js/regress/script-tests/string-get-by-val.js: Added.
(foo):
* fast/js/regress/string-get-by-val-expected.txt: Added.
* fast/js/regress/string-get-by-val.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153240 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Re-indent JSString.h to aid mhe merging of the FTL branch
oliver@apple.com [Thu, 25 Jul 2013 04:03:27 +0000 (04:03 +0000)]
fourthTier: Re-indent JSString.h to aid mhe merging of the FTL branch

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153239 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Structure should have a dump()
oliver@apple.com [Thu, 25 Jul 2013 04:03:25 +0000 (04:03 +0000)]
fourthTier: Structure should have a dump()
https://bugs.webkit.org/show_bug.cgi?id=117859

Reviewed by Geoffrey Garen.

This is pretty cool. Anywhere we previously printed Structure pointers in dumps,
we now print a bunch of other info as well. For example, for an object literal
like "{f:42, g:64, h:24}", when we print the structure we'll now get:

    0x107a0af80:[Object, {f:0, g:1, h:2}, NonArray, Proto:0x107a8fff0]

This also changes a bunch of places to use the dump method.

* bytecode/StructureSet.h:
(JSC::StructureSet::dump):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::dump):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dump):
* runtime/Structure.cpp:
(JSC::Structure::dump):
(JSC):
* runtime/Structure.h:
(Structure):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153238 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: There should only be one table of SimpleJumpTables
oliver@apple.com [Thu, 25 Jul 2013 04:03:23 +0000 (04:03 +0000)]
fourthTier: There should only be one table of SimpleJumpTables
https://bugs.webkit.org/show_bug.cgi?id=117856

Reviewed by Geoffrey Garen.

Having multiple tables of SimpleJumpTables just means we have to duplicate a
ton of code. This patch deduplicates all of it.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::numberOfSwitchJumpTables):
(JSC::CodeBlock::addSwitchJumpTable):
(JSC::CodeBlock::switchJumpTable):
(JSC::CodeBlock::clearSwitchJumpTables):
(RareData):
* bytecode/PreciseJumpTargets.cpp:
(JSC):
(JSC::computePreciseJumpTargets):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::shrinkToFit):
(JSC::UnlinkedCodeBlock::numberOfSwitchJumpTables):
(JSC::UnlinkedCodeBlock::addSwitchJumpTable):
(JSC::UnlinkedCodeBlock::switchJumpTable):
(RareData):
* bytecompiler/BytecodeGenerator.cpp:
(JSC):
(JSC::prepareJumpTableForSwitch):
(JSC::BytecodeGenerator::endSwitch):
* dfg/DFGByteCodeParser.cpp:
(InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JITCompiler):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(DFG):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
* dfg/DFGSpeculativeJIT.h:
(SpeculativeJIT):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153237 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should clear character switch jump tables
oliver@apple.com [Thu, 25 Jul 2013 04:03:20 +0000 (04:03 +0000)]
fourthTier: FTL should clear character switch jump tables
https://bugs.webkit.org/show_bug.cgi?id=117852

Reviewed by Sam Weinig.

The FTL just uses LLVM's switch, which results in LLVM allocating its own switch
jump tables as needed.

* bytecode/CodeBlock.h:
(JSC::CodeBlock::clearCharacterSwitchJumpTables):
* ftl/FTLLink.cpp:
(JSC::FTL::link):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153236 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support SwitchChar
oliver@apple.com [Thu, 25 Jul 2013 04:03:18 +0000 (04:03 +0000)]
fourthTier: FTL should support SwitchChar
https://bugs.webkit.org/show_bug.cgi?id=117849

Reviewed by Geoffrey Garen.

This adds Switch(SwitchChar) to the FTL and also implicitly does some other things.
SwitchChar requires calling a slow path to resolve ropes. Previously the FTL had no
support for calling slow paths, and we avoided adding coverage that would require
that. Well, this patch adds the ability to call slow paths and just uses that for
resolving ropes for SwitchChar. Also SwitchChar required adding awareness of strings,
so I did that, too.

* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::addCodeOrigin):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.cpp:
(WTF):
(WTF::printInternal):
* dfg/DFGNode.h:
(WTF):
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* ftl/FTLAbbreviations.h:
(JSC::FTL::int16Type):
(JSC::FTL::constInt):
* ftl/FTLAbstractHeapRepository.h:
(FTL):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLCommonValues.cpp:
(JSC::FTL::CommonValues::CommonValues):
* ftl/FTLCommonValues.h:
(CommonValues):
* ftl/FTLIntrinsicRepository.cpp:
(JSC::FTL::IntrinsicRepository::IntrinsicRepository):
(FTL):
* ftl/FTLIntrinsicRepository.h:
(FTL):
(IntrinsicRepository):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::lower):
(JSC::FTL::LowerDFGToLLVM::transferAndCheckArguments):
(JSC::FTL::LowerDFGToLLVM::compileJump):
(JSC::FTL::LowerDFGToLLVM::compileBranch):
(JSC::FTL::LowerDFGToLLVM::compileSwitch):
(JSC::FTL::LowerDFGToLLVM::buildSwitch):
(LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::lowString):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::isObject):
(JSC::FTL::LowerDFGToLLVM::isNotString):
(JSC::FTL::LowerDFGToLLVM::isString):
(JSC::FTL::LowerDFGToLLVM::isNotObject):
(JSC::FTL::LowerDFGToLLVM::speculateObject):
(JSC::FTL::LowerDFGToLLVM::speculateString):
(JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
(JSC::FTL::LowerDFGToLLVM::vmCall):
(JSC::FTL::LowerDFGToLLVM::callPreflight):
(JSC::FTL::LowerDFGToLLVM::callCheck):
(JSC::FTL::LowerDFGToLLVM::lowBlock):
* ftl/FTLOutput.h:
(JSC::FTL::Output::constBool):
(JSC::FTL::Output::constInt8):
(JSC::FTL::Output::constInt32):
(JSC::FTL::Output::constIntPtr):
(JSC::FTL::Output::constInt64):
(JSC::FTL::Output::load16):
(JSC::FTL::Output::isNull):
(JSC::FTL::Output::notNull):
(JSC::FTL::Output::testIsZero32):
(JSC::FTL::Output::testNonZero32):
(Output):
(JSC::FTL::Output::operation):
(JSC::FTL::Output::crash):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153235 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should have switch_char
oliver@apple.com [Thu, 25 Jul 2013 04:03:16 +0000 (04:03 +0000)]
fourthTier: DFG should have switch_char
https://bugs.webkit.org/show_bug.cgi?id=117710

Source/JavaScriptCore:

Reviewed by Michael Saboff.

Add op_switch_char. Most of this is fairly simple, except for the whole
LazyJSValue thing.

It's long been the case that anytime you wanted the DFG to speak of a string
that didn't appear in the constant pool, you would have a hard time since
the DFG isn't allowed to allocate in the GC heap. For example, if you know
that you want to speak of a single character string, you might find that
the one you wanted to speak of had been GC'd. Another example is if you
wanted to add constant folding for string concatenation - something we don't
have yet but will want eventually.

I solve this by finally adding the notion of LazyJSValue. In the future I
anticipate using this for a variety of string-related things. The idea here
is that the DFG can either say that it already knows what the value is, or
it can describe the value. For example, in this patch I needed to be able to
describe single-character strings.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
* bytecode/JumpTable.h:
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGByteCodeParser.cpp:
(InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGPRInfo.h:
(JSC::DFG::JSValueRegs::payloadGPR):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::jumpTable):
(DFG):
(JSC::DFG::JITCompiler::numberOfJumpTables):
(JSC::DFG::JITCompiler::linkSwitches):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JITCompiler):
* dfg/DFGLazyJSValue.cpp: Added.
(DFG):
(JSC::DFG::LazyJSValue::getValue):
(JSC::DFG::equalToSingleCharacter):
(JSC::DFG::LazyJSValue::strictEqual):
(JSC::DFG::LazyJSValue::dump):
* dfg/DFGLazyJSValue.h: Added.
(DFG):
(LazyJSValue):
(JSC::DFG::LazyJSValue::LazyJSValue):
(JSC::DFG::LazyJSValue::singleCharacterString):
(JSC::DFG::LazyJSValue::tryGetValue):
(JSC::DFG::LazyJSValue::value):
(JSC::DFG::LazyJSValue::character):
(JSC::DFG::LazyJSValue::switchLookupValue):
* dfg/DFGNode.h:
(JSC::DFG::SwitchCase::SwitchCase):
(SwitchCase):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(JSC::DFG::SpeculativeJIT::emitSwitchImmIntJump):
(DFG):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::emitSwitch):
* dfg/DFGSpeculativeJIT.h:
(SpeculativeJIT):

Source/WTF:

Reviewed by Michael Saboff.

I wanted to be able to say stringImpl->at(index), and now I can!

Also made it possible to convert a UChar to a utf8 CString without
allocating a StringImpl.

* wtf/text/StringImpl.cpp:
(WTF::StringImpl::utf8Impl):
(WTF):
(WTF::StringImpl::utf8ForCharacters):
(WTF::StringImpl::utf8ForRange):
* wtf/text/StringImpl.h:
(StringImpl):
(WTF::StringImpl::at):
(WTF::StringImpl::operator[]):

LayoutTests:

Rubber stamped by Mark Hahnenberg.

* fast/js/regress/script-tests/switch-char-constant.js: Added.
(foo):
(bar):
* fast/js/regress/script-tests/switch-char.js: Added.
(foo):
(bar):
* fast/js/regress/switch-char-constant-expected.txt: Added.
* fast/js/regress/switch-char-constant.html: Added.
* fast/js/regress/switch-char-expected.txt: Added.
* fast/js/regress/switch-char.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153234 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Refactor ObjCCallbackFunction to inherit directly from InternalFunction
oliver@apple.com [Thu, 25 Jul 2013 04:03:12 +0000 (04:03 +0000)]
fourthTier: Refactor ObjCCallbackFunction to inherit directly from InternalFunction
https://bugs.webkit.org/show_bug.cgi?id=117595

Reviewed by Geoffrey Garen.

* API/APICallbackFunction.h: Added. New struct that allows JSCallbackFunction and
ObjCCallbackFunction to share their host call() implementation through the magic of
templates.
(JSC::APICallbackFunction::call):
* API/JSCallbackFunction.cpp:
(JSC::JSCallbackFunction::getCallData): Changed to get the template-ized version of
the host function.
* API/JSCallbackFunction.h:
* API/ObjCCallbackFunction.h: Now inherits directly from InternalFunction.
* API/ObjCCallbackFunction.mm:
(JSC::ObjCCallbackFunction::ObjCCallbackFunction):
(JSC::ObjCCallbackFunction::getCallData): Ditto.
* GNUmakefile.list.am: Build files!
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153233 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Arity fixup should be done while on same stack
oliver@apple.com [Thu, 25 Jul 2013 04:03:10 +0000 (04:03 +0000)]
fourthTier: Arity fixup should be done while on same stack
https://bugs.webkit.org/show_bug.cgi?id=117102

Reviewed by Oliver Hunt.

Removed the fixup part of op_call_arityCheck() and op_construct_arityCheck() and moved it to
a thunk for the JITs and as assembly for the llint.  This patch provides the plumbing needed to
move to the C stack for JS execution.  The fixup thunk and llint code would need to be change to
work with a stack that grows down when we do move to the C stack.

Due to an issue with the offline assembler, I moved the const at the top of LowLevelInterpreter64.asm
and LowLevelInterpreter32_64.asm to LowLevelInterpreter.asm.  The problem is that a const defined in
one file that are used in a macro doesn't resolve the const if the macro is used in another file.  This
seemed like the quickest path.

* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileFunction):
(JSC::DFG::JITCompiler::linkFunction):
* dfg/DFGJITCompiler.h:
(JITCompiler):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h:
* jit/ThunkGenerators.cpp:
(JSC::arityFixup):
* jit/ThunkGenerators.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::arityCheckFor):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153232 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Add another temp register regT4 to JSInterfaceJIT
oliver@apple.com [Thu, 25 Jul 2013 04:03:07 +0000 (04:03 +0000)]
fourthTier: Add another temp register regT4 to JSInterfaceJIT
https://bugs.webkit.org/show_bug.cgi?id=117719

Reviewed by Geoffrey Garen.

Made the dedicated bucketCounterRegister to be regT4 and then used regT4 wherever
bucketCounterRegister had been used.  Since it is masked whenever it is used and
we are looking for some randomness in the register anyway, we can use it without
any issues.

* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JSC::JIT::emitValueProfilingSite):
* jit/JITCall.cpp:
(JSC::JIT::emitPutCallResult):
* jit/JITCall32_64.cpp:
(JSC::JIT::emitPutCallResult):
* jit/JITInlines.h:
(JSC::JIT::emitValueProfilingSite):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emit_op_get_callee):
(JSC::JIT::emit_op_get_argument_by_val):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_get_callee):
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emit_op_get_argument_by_val):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emitSlow_op_get_by_id):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emitSlow_op_get_by_id):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
* jit/JITStubCall.h:
(JSC::JITStubCall::callWithValueProfiling):
* jit/JSInterfaceJIT.h:
(JSInterfaceJIT):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153231 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support Switch
oliver@apple.com [Thu, 25 Jul 2013 04:03:05 +0000 (04:03 +0000)]
fourthTier: FTL should support Switch
https://bugs.webkit.org/show_bug.cgi?id=117704

Reviewed by Oliver Hunt.

* bytecode/CodeBlock.h:
(JSC::CodeBlock::clearImmediateSwitchJumpTables):
* ftl/FTLAbbreviations.h:
(JSC::FTL::buildFPToSI):
(JSC::FTL::buildSwitch):
(JSC::FTL::addCase):
(FTL):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileSwitch):
(LowerDFGToLLVM):
* ftl/FTLOutput.h:
(JSC::FTL::Output::fpToInt):
(JSC::FTL::Output::fpToInt32):
(Output):
(JSC::FTL::Output::switchInstruction):
* ftl/FTLSwitchCase.h: Added.
(FTL):
(SwitchCase):
(JSC::FTL::SwitchCase::SwitchCase):
(JSC::FTL::SwitchCase::value):
(JSC::FTL::SwitchCase::target):

Conflicts:
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153230 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Add CFG simplification for Switch
oliver@apple.com [Thu, 25 Jul 2013 04:03:03 +0000 (04:03 +0000)]
fourthTier: Add CFG simplification for Switch
https://bugs.webkit.org/show_bug.cgi?id=117677

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

This is for completeness. It only speeds up a microbenchmark at this point.
Broadly, we want all control constructs to be known to the CFG simplifier.

* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
(JSC::DFG::CFGSimplificationPhase::convertToJump):
(CFGSimplificationPhase):
(JSC::DFG::CFGSimplificationPhase::noBlocks):
(JSC::DFG::CFGSimplificationPhase::oneBlock):
(JSC::DFG::CFGSimplificationPhase::mergeBlocks):
* runtime/JSCJSValue.h:
(JSValue):
* runtime/JSCJSValueInlines.h:
(JSC::JSValue::pureStrictEqual):
(JSC):

Source/WTF:

Reviewed by Mark Hahnenberg.

* wtf/TriState.h:
* wtf/text/StringImpl.h:

LayoutTests:

Reviewed by Mark Hahnenberg.

* fast/js/regress/script-tests/switch-constant.js: Added.
(foo):
(bar):
* fast/js/regress/script-tests/switch.js: Added.
(foo):
(bar):
* fast/js/regress/switch-constant-expected.txt: Added.
* fast/js/regress/switch-constant.html: Added.
* fast/js/regress/switch-expected.txt: Added.
* fast/js/regress/switch.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153229 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should support op_switch_imm
oliver@apple.com [Thu, 25 Jul 2013 04:03:00 +0000 (04:03 +0000)]
fourthTier: DFG should support op_switch_imm
https://bugs.webkit.org/show_bug.cgi?id=117559

Reviewed by Oliver Hunt.

Implement integer (i.e. immediate) switches in the DFG. Reduce the minimum
threshold for using op_switch.

Also get rid of edge code support, since we haven't used it in the year since
I introduced it. It was supposed to allow us to break critical edges late in
the backend, thus enabling global register allocation from an SSA-form graph.
But we aren't doing that so I figure we should just kill the code for now. It
would have made implementing switch harder.

* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::timesPtr):
* assembler/MacroAssemblerCodeRef.h:
(JSC::MacroAssemblerCodePtr::dumpWithName):
(MacroAssemblerCodePtr):
(JSC::MacroAssemblerCodePtr::dump):
(MacroAssemblerCodeRef):
(JSC::MacroAssemblerCodeRef::dump):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shrinkToFit):
* bytecode/JumpTable.h:
(SimpleJumpTable):
(JSC::SimpleJumpTable::clear):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::executeEffects):
(JSC::DFG::AbstractState::mergeToSuccessors):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGByteCodeParser.cpp:
(InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::linkBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGCommon.h:
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::determineReachability):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::JITCompiler):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JITCompiler):
(JSC::DFG::JITCompiler::blockHeads):
* dfg/DFGNode.h:
(DFG):
(JSC::DFG::SwitchCase::SwitchCase):
(SwitchCase):
(SwitchData):
(JSC::DFG::SwitchData::SwitchData):
(Node):
(JSC::DFG::Node::isSwitch):
(JSC::DFG::Node::isTerminal):
(JSC::DFG::Node::switchData):
(JSC::DFG::Node::numSuccessors):
(JSC::DFG::Node::successor):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::createOSREntries):
(JSC::DFG::SpeculativeJIT::emitSwitchImmIntJump):
(DFG):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitch):
(JSC::DFG::SpeculativeJIT::linkBranches):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::branchDouble):
(JSC::DFG::SpeculativeJIT::branchDoubleNonZero):
(JSC::DFG::SpeculativeJIT::branch32):
(JSC::DFG::SpeculativeJIT::branchTest32):
(JSC::DFG::SpeculativeJIT::branch64):
(JSC::DFG::SpeculativeJIT::branchPtr):
(JSC::DFG::SpeculativeJIT::branchTestPtr):
(JSC::DFG::SpeculativeJIT::branchTest8):
(JSC::DFG::SpeculativeJIT::jump):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* parser/Nodes.h:
(CaseBlockNode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153228 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Concurrent JIT shouldn't try to recompute the CodeBlockHash as part of...
oliver@apple.com [Thu, 25 Jul 2013 04:02:57 +0000 (04:02 +0000)]
fourthTier: Concurrent JIT shouldn't try to recompute the CodeBlockHash as part of debug dumps, since doing so may fail if dealing with a CachedScript that doesn't have its script string handy
https://bugs.webkit.org/show_bug.cgi?id=117676

Reviewed by Sam Weinig.

Source/JavaScriptCore:

CodeBlock now caches m_hash, and the DFG Driver will force its computation if we're doing debug dumps of any kind.

Also made sure that CodeBlock::CodeBlock initializes all of its fields; it was previously missing the
initialization of m_capabilityLevelState.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::hash):
(JSC::CodeBlock::CodeBlock):
* bytecode/CodeBlock.h:
(CodeBlock):
* bytecode/CodeBlockHash.cpp:
(JSC::CodeBlockHash::CodeBlockHash):
* bytecode/CodeBlockHash.h:
(CodeBlockHash):
(JSC::CodeBlockHash::isSet):
(JSC::CodeBlockHash::operator!):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):

Source/WebCore:

Remove the broken hack for the concurrent JIT, since now the concurrent JIT won't use this code anymore.

No new tests because no new behavior.

* loader/cache/CachedScript.cpp:
(WebCore::CachedScript::script):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153227 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Printing a StringImpl* should really guard against NULL
oliver@apple.com [Thu, 25 Jul 2013 04:02:55 +0000 (04:02 +0000)]
fourthTier: Printing a StringImpl* should really guard against NULL
https://bugs.webkit.org/show_bug.cgi?id=117675

Reviewed by Mark Hahnenberg.

* wtf/PrintStream.cpp:
(WTF::printInternal):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153226 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG should support op_in and it should use patching to make it fast
oliver@apple.com [Thu, 25 Jul 2013 04:02:53 +0000 (04:02 +0000)]
fourthTier: DFG should support op_in and it should use patching to make it fast
https://bugs.webkit.org/show_bug.cgi?id=117385

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

Implement op_in in the DFG and give it patching. The code we generate is just
a jump on the hot path, and the slow paths generate stubs and link the jump to
them. I didn't want to bother with patching structures and load offsets and
the like, although I probably could have.

This is a ginormous speed-up on microbenchmarks for "in", obviously.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpAssumingJITType):
(JSC::CodeBlock::resetStubInternal):
(JSC::structureStubInfoLessThan):
(JSC):
(JSC::CodeBlock::sortStructureStubInfos):
* bytecode/CodeBlock.h:
(CodeBlock):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::visitWeakReferences):
* bytecode/StructureStubInfo.h:
(JSC::isInAccess):
(JSC):
(StructureStubInfo):
(JSC::StructureStubInfo::initInList):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCCallHelpers.h:
(JSC::DFG::CCallHelpers::setupResults):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGPRInfo.h:
(JSC::DFG::JSValueRegs::payloadOnly):
(JSValueRegs):
(JSC::DFG::JSValueRegs::JSValueRegs):
(JSC::DFG::JSValueRegs::operator!):
(JSC::DFG::JSValueSource::operator!):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::InRecord::InRecord):
(InRecord):
(DFG):
(JITCompiler):
(JSC::DFG::JITCompiler::addIn):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryRepatchIn):
(DFG):
(JSC::DFG::dfgRepatchIn):
(JSC::DFG::dfgResetIn):
* dfg/DFGRepatch.h:
(DFG):
(JSC::DFG::dfgResetIn):
* dfg/DFGSlowPathGenerator.h:
(JSC::DFG::CallSlowPathGenerator::CallSlowPathGenerator):
(JSC::DFG::CallSlowPathGenerator::tearDown):
(JSC::DFG::CallResultAndNoArgumentsSlowPathGenerator::generateInternal):
(JSC::DFG::CallResultAndOneArgumentSlowPathGenerator::generateInternal):
(JSC::DFG::CallResultAndTwoArgumentsSlowPathGenerator::generateInternal):
(JSC::DFG::CallResultAndThreeArgumentsSlowPathGenerator::generateInternal):
(JSC::DFG::CallResultAndFourArgumentsSlowPathGenerator::generateInternal):
(JSC::DFG::CallResultAndFiveArgumentsSlowPathGenerator::generateInternal):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileIn):
(DFG):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::extractResult):
(DFG):
(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::callOperation):
(JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult):
(JSC::DFG::SpeculativeJIT::appendCallSetResult):
(JSC::DFG::JSValueOperand::tagGPR):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dump):
* runtime/JSString.h:
(JSString):
(JSC::JSString::tryGetValueImpl):
(JSC):
* runtime/Operations.h:
(JSC::normalizePrototypeChainForChainAccess):

Source/WTF:

Reviewed by Geoffrey Garen.

Now if you pass a null StringImpl* then something will still get printed instead
of crashing. I figure that this is broadly useful for debug code, and I make use
of it in the JSC portion of this patch.

* wtf/PrintStream.cpp:
(WTF::printInternal):

LayoutTests:

Reviewed by Geoffrey Garen.

Test coverage for op_in performance.

* fast/js/regress/in-four-cases-expected.txt: Added.
* fast/js/regress/in-four-cases.html: Added.
* fast/js/regress/in-one-case-false-expected.txt: Added.
* fast/js/regress/in-one-case-false.html: Added.
* fast/js/regress/in-one-case-true-expected.txt: Added.
* fast/js/regress/in-one-case-true.html: Added.
* fast/js/regress/in-two-cases-expected.txt: Added.
* fast/js/regress/in-two-cases.html: Added.
* fast/js/regress/script-tests/in-four-cases.js: Added.
(foo):
(bar):
* fast/js/regress/script-tests/in-one-case-false.js: Added.
(foo):
(bar):
* fast/js/regress/script-tests/in-one-case-true.js: Added.
(foo):
(bar):
* fast/js/regress/script-tests/in-two-cases.js: Added.
(foo):
(bar):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153225 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: A few fixups to standalone-pre.js
oliver@apple.com [Thu, 25 Jul 2013 04:02:48 +0000 (04:02 +0000)]
fourthTier: A few fixups to standalone-pre.js

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153224 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: The Math object should not be polymorphic
oliver@apple.com [Thu, 25 Jul 2013 04:02:47 +0000 (04:02 +0000)]
fourthTier: The Math object should not be polymorphic
https://bugs.webkit.org/show_bug.cgi?id=117576

Reviewed by Oliver Hunt.

Fill in the Math object eagerly, to avoid its structure changing during
execution. There are lots of ways to skin this cat; this one seemed
easiest, and justified given the relative hotness of math operations.

20% speedup on DSP-filtrr tests, small speedups on a few Kraken tests.

* DerivedSources.make:
* JavaScriptCore.order:
* create_hash_table:
* interpreter/CallFrame.h:
(JSC::ExecState::jsonTable): Removed the Math object's static table.

* runtime/JSObject.cpp:
(JSC::JSObject::putDirectNativeFunctionWithoutTransition):
* runtime/JSObject.h:
* runtime/MathObject.cpp:
(JSC::MathObject::finishCreation):
* runtime/MathObject.h:
(JSC::MathObject::create): Set up the Math object at construction time.

* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
* runtime/VM.h: Removed the Math object's static table.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153223 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: The baseline jit and LLint should use common slow paths
oliver@apple.com [Thu, 25 Jul 2013 04:02:44 +0000 (04:02 +0000)]
fourthTier: The baseline jit and LLint should use common slow paths
https://bugs.webkit.org/show_bug.cgi?id=116889

Reviewed by Filip Pizlo.

Moved the llint_slow_paths that return JSValue along with several others to CommonSlowPaths.cpp.
Eliminated the related JIT stubs.  Changes the baseline JIT to call these new common stubs.
Added a simple slow path call class that uses argument registers or the stack instead of
JITStackFrame.  Changes the exception mechanism for to check for an exception after making
a slowpath call instead of returning to the handler directly form the slowpath function.

* JavaScriptCore.xcodeproj/project.pbxproj:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
(JIT):
* jit/JITArithmetic.cpp:
(JSC::JIT::emitSlow_op_negate):
(JSC::JIT::emitSlow_op_lshift):
(JSC::JIT::emitSlow_op_rshift):
(JSC::JIT::emitSlow_op_urshift):
(JSC::JIT::emitSlow_op_bitand):
(JSC::JIT::emitSlow_op_inc):
(JSC::JIT::emitSlow_op_dec):
(JSC::JIT::emitSlow_op_mod):
(JSC::JIT::emit_op_mod):
(JSC::JIT::compileBinaryArithOpSlowCase):
(JSC::JIT::emit_op_add):
(JSC::JIT::emitSlow_op_add):
(JSC::JIT::emitSlow_op_mul):
(JSC::JIT::emitSlow_op_div):
(JSC::JIT::emitSlow_op_sub):
* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emitSlow_op_negate):
(JSC::JIT::emitSlow_op_lshift):
(JSC::JIT::emitRightShiftSlowCase):
(JSC::JIT::emitSlow_op_bitand):
(JSC::JIT::emitSlow_op_bitor):
(JSC::JIT::emitSlow_op_bitxor):
(JSC::JIT::emitSlow_op_inc):
(JSC::JIT::emitSlow_op_dec):
(JSC::JIT::emit_op_add):
(JSC::JIT::emitSlow_op_add):
(JSC::JIT::emitSlow_op_sub):
(JSC::JIT::emitSlow_op_mul):
(JSC::JIT::emitSlow_op_div):
(JSC::JIT::emit_op_mod):
(JSC::JIT::emitSlow_op_mod):
* jit/JITExceptions.cpp:
(JSC::getExceptionLocation):
(JSC::genericThrow):
(JSC::jitThrowNew):
* jit/JITExceptions.h:
(ExceptionHandler):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_strcat):
(JSC::JIT::emitSlow_op_create_this):
(JSC::JIT::emitSlow_op_to_this):
(JSC::JIT::emitSlow_op_to_primitive):
(JSC::JIT::emitSlow_op_not):
(JSC::JIT::emitSlow_op_bitxor):
(JSC::JIT::emitSlow_op_bitor):
(JSC::JIT::emitSlow_op_stricteq):
(JSC::JIT::emitSlow_op_nstricteq):
(JSC::JIT::emitSlow_op_to_number):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall):
(JSC::JIT::emitSlow_op_to_primitive):
(JSC::JIT::emit_op_strcat):
(JSC::JIT::emitSlow_op_not):
(JSC::JIT::emitSlow_op_stricteq):
(JSC::JIT::emitSlow_op_nstricteq):
(JSC::JIT::emitSlow_op_to_number):
(JSC::JIT::emit_op_create_arguments):
(JSC::JIT::emitSlow_op_create_this):
(JSC::JIT::emitSlow_op_to_this):
(JSC::JIT::emitSlow_op_get_argument_by_val):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
(JSC::cti_vm_throw_slowpath):
* jit/JITStubs.h:
* jit/JITStubsARM.h:
* jit/JITStubsARMv7.h:
* jit/JITStubsMIPS.h:
* jit/JITStubsSH4.h:
* jit/JITStubsX86.h:
* jit/JITStubsX86_64.h:
* jit/JSInterfaceJIT.h:
(JSInterfaceJIT):
* jit/SlowPathCall.h: Added.
(JITSlowPathCall):
(JSC::JITSlowPathCall::JITSlowPathCall):
(JSC::JITSlowPathCall::call):
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):
* llint/LLIntSlowPaths.cpp:
(LLInt):
* llint/LLIntSlowPaths.h:
(LLInt):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter.cpp:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp: Added.
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(SlowPathReturnType):
(JSC::encodeResult):
(JSC::decodeResult):
* runtime/JSCJSValue.h:
(JSValue):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153222 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Re-worked non-local variable resolution
oliver@apple.com [Thu, 25 Jul 2013 04:02:40 +0000 (04:02 +0000)]
fourthTier: Re-worked non-local variable resolution
https://bugs.webkit.org/show_bug.cgi?id=117375

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch has two goals:

(1) Simplicity.

    * Net removes 15 opcodes.
    * Net removes 2,000 lines of code.
    * Removes setPair() from the DFG: All DFG nodes have 1 result register now.

(2) Performance.

    * 2%-3% speedup on SunSpider (20% in LLInt and Baseline JIT)
    * 2% speedup on v8-spider
    * 10% speedup on js-regress-hashmap*
    * Amusing 2X speedup on js-regress-poly-stricteq

The bytecode now separates the scope chain resolution opcode from the
scope access opcode.

    OLD:
        get_scoped_var  r0, 1, 0
        inc             r0
        put_scoped_var  1, 0, r0

    NEW:
        resolve_scope   r0, x(@id0)
        get_from_scope  r1, r0, x(@id0)
        inc             r1
        put_to_scope    r0, x(@id0), r1

Also, we link non-local variable resolution opcodes at CodeBlock link
time instead of time of first opcode execution.

This means that we can represent all possible non-local variable
resolutions using just three opcodes, and any optimizations in these
opcodes naturally apply across-the-board.

* API/JSCTestRunnerUtils.cpp:
(JSC::numberOfDFGCompiles):
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.order:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri: Build!

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode): Updated for removed things.

(JSC::CodeBlock::CodeBlock): Always provide the full scope chain when
creating a CodeBlock, so we can perform non-local variable resolution.

Added code to perform linking for these opcodes. This is where we figure
out which non-local variable resolutions are optimizable, and how.

(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::noticeIncomingCall):
(JSC::CodeBlock::optimizeAfterWarmUp):
(JSC::CodeBlock::optimizeAfterLongWarmUp):
(JSC::CodeBlock::optimizeSoon): Updated for removed things.

* bytecode/CodeBlock.h:
(JSC::CodeBlock::needsActivation):
(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::ProgramCodeBlock::ProgramCodeBlock):
(JSC::EvalCodeBlock::EvalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):
* bytecode/EvalCodeCache.h:
(JSC::EvalCodeCache::getSlow): Updated for interface changes.

* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeFor): Treat global object access as
optimizable even though the global object has a custom property access
callback. This is what we've always done since, otherwise, we can't
optimize globals. (In future, we probably want to figure out a more
targeted policy than "any property access callback means no
optimization".)

* bytecode/GlobalResolveInfo.h: Removed.
* bytecode/Instruction.h:
* bytecode/Opcode.h:
(JSC::padOpcodeName):

* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFor): Like GetByIdStatus.

* bytecode/ResolveGlobalStatus.cpp: Removed.
* bytecode/ResolveGlobalStatus.h: Removed.
* bytecode/ResolveOperation.h: Removed.

* bytecode/UnlinkedCodeBlock.cpp:
(JSC::generateFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::codeBlockFor):
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h: Don't provide a scope chain to unlinked
code blocks. Giving a scope to an unscoped compilation unit invites
programming errors.

* bytecode/Watchpoint.h:
(JSC::WatchpointSet::addressOfIsInvalidated):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::resolveCallee):
(JSC::BytecodeGenerator::local):
(JSC::BytecodeGenerator::constLocal):
(JSC::BytecodeGenerator::resolveType):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::emitInstanceOf):
(JSC::BytecodeGenerator::emitPushWithScope):
(JSC::BytecodeGenerator::emitPopScope):
(JSC::BytecodeGenerator::pushFinallyContext):
(JSC::BytecodeGenerator::emitComplexPopScopes):
(JSC::BytecodeGenerator::popTryAndEmitCatch):
(JSC::BytecodeGenerator::emitPushNameScope):
(JSC::BytecodeGenerator::isArgumentNumber):
* bytecompiler/BytecodeGenerator.h:
(JSC::Local::Local):
(JSC::Local::operator bool):
(JSC::Local::get):
(JSC::Local::isReadOnly):
(JSC::BytecodeGenerator::scopeDepth):
(JSC::BytecodeGenerator::shouldOptimizeLocals):
(JSC::BytecodeGenerator::canOptimizeNonLocals): Refactored the bytecode
generator to resolve all variables within local scope, as if there
were no non-local scope. This helps provide a separation of concerns:
unlinked bytecode is always scope-free, and the linking stage links
in the provided scope.

* bytecompiler/NodesCodegen.cpp:
(JSC::ResolveNode::isPure):
(JSC::ResolveNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::DeleteResolveNode::emitBytecode):
(JSC::TypeOfResolveNode::emitBytecode):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::ConstDeclNode::emitCodeSingle):
(JSC::ForInNode::emitBytecode): A bunch of this codegen is no longer
necessary, since it's redundant with the linking stage.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::ByteCodeParser):
(JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck):
(JSC::DFG::ByteCodeParser::handlePutByOffset):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseBlock): Updated for interface changes.
Notably, we can reuse existing DFG nodes -- but the mapping between
bytecode and DFG nodes has changed, and some nodes and corner cases have
been removed.

* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::scopedVarLoadElimination):
(JSC::DFG::CSEPhase::varInjectionWatchpointElimination):
(JSC::DFG::CSEPhase::globalVarStoreElimination):
(JSC::DFG::CSEPhase::scopedVarStoreElimination):
(JSC::DFG::CSEPhase::getLocalLoadElimination):
(JSC::DFG::CSEPhase::setLocalStoreElimination):
(JSC::DFG::CSEPhase::performNodeCSE): Added CSE for var injection
watchpoints. Even though watchpoints are "free", they're quite common
inside code that's subject to var injection, so I figured we'd save a
little memory.

* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGCapabilities.h: Removed detection for old forms.

* dfg/DFGDriver.h:
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
* dfg/DFGJITCode.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToStructureTransitionWatchpoint):
(JSC::DFG::Node::hasVarNumber):
(JSC::DFG::Node::hasIdentifierNumberForCheck):
(JSC::DFG::Node::hasRegisterPointer):
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGRepatch.h:
(JSC::DFG::dfgResetGetByID):
(JSC::DFG::dfgResetPutByID):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation): Removed some unneeded things,
and updated for renames.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile): The two primary changes here are:

(1) Use a watchpoint for var injection instead of looping over the scope
chain and checking. This is more efficient and much easier to model in
code generation.

(2) I've eliminated the notion of an optimized global assignment that
needs to check for whether it should fire a watchpiont. Instead, we
fire pre-emptively at the point of optimization. This removes a bunch
of edge cases, and it seems like a more honest representation of
the fact that our new optimization contradicts our old one.

* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
* heap/DFGCodeBlocks.cpp:
(JSC::DFGCodeBlocks::jettison):
* interpreter/CallFrame.h:
(JSC::ExecState::trueCallFrame): Removed stuff that's unused now, and
fixed the build.

* interpreter/Interpreter.cpp:
(JSC::eval):
(JSC::getBytecodeOffsetForCallFrame):
(JSC::getCallerInfo):
(JSC::Interpreter::throwException): Updated exception scope tracking
to match the rest of our linking strategy: The unlinked bytecode compiles
exception scope as if non-local scope did not exist, and we add in
non-local scope at link time. This means that we can restore the right
scope depth based on a simple number, without checking the contents of
the scope chain.

(JSC::Interpreter::execute): Make sure to establish the full scope chain
before linking eval code. We now require the full scope chain at link
time, in order to link non-local variable resolution opcodes.

* jit/JIT.cpp:
(JSC::JIT::JIT):
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_add):
* jit/JITCode.cpp:
* jit/JITOpcodes.cpp:
(JSC::JIT::emitSlow_op_bitxor):
(JSC::JIT::emitSlow_op_bitor):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emitSlow_op_to_primitive):
(JSC::JIT::emit_op_strcat):
(JSC::JIT::emitSlow_op_create_this):
(JSC::JIT::emitSlow_op_to_this):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitVarInjectionCheck):
(JSC::JIT::emitResolveClosure):
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emitSlow_op_resolve_scope):
(JSC::JIT::emitLoadWithStructureCheck):
(JSC::JIT::emitGetGlobalProperty):
(JSC::JIT::emitGetGlobalVar):
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
(JSC::JIT::emitPutGlobalProperty):
(JSC::JIT::emitPutGlobalVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
(JSC::JIT::emit_op_init_global_const):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitVarInjectionCheck):
(JSC::JIT::emitResolveClosure):
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emitSlow_op_resolve_scope):
(JSC::JIT::emitLoadWithStructureCheck):
(JSC::JIT::emitGetGlobalProperty):
(JSC::JIT::emitGetGlobalVar):
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
(JSC::JIT::emitPutGlobalProperty):
(JSC::JIT::emitPutGlobalVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
(JSC::JIT::emit_op_init_global_const):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h: Re-wrote baseline JIT codegen for our new variable
resolution model.

* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm: Ditto for LLInt.

* offlineasm/x86.rb: Fixed a pre-existing encoding bug for a syntactic
form that we never used before.

* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
(JSC::arrayProtoFuncJoin):
(JSC::arrayProtoFuncConcat):
(JSC::arrayProtoFuncPop):
(JSC::arrayProtoFuncPush):
(JSC::arrayProtoFuncReverse):
(JSC::arrayProtoFuncShift):
(JSC::arrayProtoFuncSlice):
(JSC::arrayProtoFuncSort):
(JSC::arrayProtoFuncSplice):
(JSC::arrayProtoFuncUnShift):
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncMap):
(JSC::arrayProtoFuncEvery):
(JSC::arrayProtoFuncForEach):
(JSC::arrayProtoFuncSome):
(JSC::arrayProtoFuncReduce):
(JSC::arrayProtoFuncReduceRight):
(JSC::arrayProtoFuncIndexOf):
(JSC::arrayProtoFuncLastIndexOf): Fixed some pre-existing bugs in
'this' value conversion, which I made much more common by removing
special cases in bytecode generation.

These functions need to invoke toThis() because they observe the 'this'
value. Also, toLocaleString() is specified to accept non-array 'this'
values.

(Most other host functions don't need this fix because they perform
strict 'this' checking, which never coerces unexpected types.)

* runtime/CodeCache.cpp:
(JSC::CodeCache::getCodeBlock):
(JSC::CodeCache::getProgramCodeBlock):
(JSC::CodeCache::getEvalCodeBlock):
* runtime/CodeCache.h: Don't supply a scope to the unlinked code cache.
Unlinked code is supposed to be scope-free, so let's have the compiler
help verify that.

* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/Executable.cpp:
(JSC::EvalExecutable::create):
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
* runtime/Executable.h:
(JSC::EvalExecutable::numVariables):
(JSC::EvalExecutable::numberOfFunctionDecls):
* runtime/ExecutionHarness.h:
(JSC::prepareForExecutionImpl):
(JSC::prepareFunctionForExecutionImpl):
(JSC::installOptimizedCode): Fiddled with executable initialization so
that we can always generate a full scope chain before we go to link a
code block. We need this because code block linking now depends on the
scope chain to link non-local variable resolution opcodes.

* runtime/JSActivation.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::createEvalCodeBlock):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::varInjectionWatchpoint):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncEval):
* runtime/JSNameScope.h:
* runtime/JSScope.cpp:
(JSC::abstractAccess):
(JSC::JSScope::objectAtScope):
(JSC::JSScope::depth):
(JSC::JSScope::resolve):
(JSC::JSScope::abstractResolve): Updated to match changes explained above.

* runtime/JSScope.h:
(JSC::makeType):
(JSC::needsVarInjectionChecks):
(JSC::ResolveOp::ResolveOp):
(JSC::ResolveModeAndType::ResolveModeAndType):
(JSC::ResolveModeAndType::mode):
(JSC::ResolveModeAndType::type):
(JSC::ResolveModeAndType::operand): Removed the old variable resolution
state machine, since it's unused now. Added logic for performing abstract
variable resolution at link time. This is used by codeblock linking.

* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncValueOf):
(JSC::objectProtoFuncHasOwnProperty):
(JSC::objectProtoFuncIsPrototypeOf):
(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):
(JSC::objectProtoFuncLookupGetter):
(JSC::objectProtoFuncLookupSetter):
(JSC::objectProtoFuncPropertyIsEnumerable):
(JSC::objectProtoFuncToLocaleString):
(JSC::objectProtoFuncToString): Fixed some pre-existing bugs in
'this' value conversion, which I made much more common by removing
special cases in bytecode generation.

These functions need to invoke toThis() because they observe the 'this'
value.

* runtime/StringPrototype.cpp:
(JSC::checkObjectCoercible):
(JSC::stringProtoFuncReplace):
(JSC::stringProtoFuncCharAt):
(JSC::stringProtoFuncCharCodeAt):
(JSC::stringProtoFuncConcat):
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncLastIndexOf):
(JSC::stringProtoFuncMatch):
(JSC::stringProtoFuncSearch):
(JSC::stringProtoFuncSlice):
(JSC::stringProtoFuncSplit):
(JSC::stringProtoFuncSubstr):
(JSC::stringProtoFuncSubstring):
(JSC::stringProtoFuncToLowerCase):
(JSC::stringProtoFuncToUpperCase):
(JSC::stringProtoFuncLocaleCompare):
(JSC::stringProtoFuncBig):
(JSC::stringProtoFuncSmall):
(JSC::stringProtoFuncBlink):
(JSC::stringProtoFuncBold):
(JSC::stringProtoFuncFixed):
(JSC::stringProtoFuncItalics):
(JSC::stringProtoFuncStrike):
(JSC::stringProtoFuncSub):
(JSC::stringProtoFuncSup):
(JSC::stringProtoFuncFontcolor):
(JSC::stringProtoFuncFontsize):
(JSC::stringProtoFuncAnchor):
(JSC::stringProtoFuncLink):
(JSC::trimString): Fixed some pre-existing bugs in
'this' value conversion, which I made much more common by removing
special cases in bytecode generation.

These functions need to invoke toThis() because they observe the 'this'
value.

* runtime/StructureRareData.cpp:
* runtime/VM.cpp:
(JSC::VM::~VM):

* runtime/WriteBarrier.h:
(JSC::WriteBarrierBase::slot): Modified to reduce casting in client code.

LayoutTests:

This patch removed special-case 'this' resolution from bytecode, making
some pre-existing edge cases in 'this' value treatment much more common.

I updated the test results below, and added some tests, to match bug
fixes for these cases.

* fast/js/script-tests/array-functions-non-arrays.js:
* fast/js/array-functions-non-arrays-expected.txt: As specified, it's
not an error to pass a non-array to toLocaleString. Our new result
matches Firefox and Chrome.

* fast/js/array-prototype-properties-expected.txt: Updated for slightly
clearer error message.

* fast/js/basic-strict-mode-expected.txt: Updated for slightly more
standard error message.

* fast/js/object-prototype-toString-expected.txt: Added.
* fast/js/object-prototype-toString.html: Added. This test demonstrates
why we now fail a Sputnik test below, while Firefox and Chrome pass it.
(The test doesn't test what it thinks it tests, and this test verifies
that we get right what it does think it tests.)

* fast/js/string-prototype-function-this-expected.txt: Added.
* fast/js/string-prototype-function-this.html: Added. This test shows
that we CheckObjectCoercible in string prototype functions. (We used
to get this wrong, but Sputnik tests made it seem like we got it right
because they didn't test the dynamic scope case.)

* sputnik/Conformance/11_Expressions/11.1_Primary_Expressions/11.1.1_The_this_Keyword/S11.1.1_A2-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.3_Array_prototype_toLocaleString/S15.4.4.3_A2_T1-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.11_String.prototype.replace/S15.5.4.11_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.6_String.prototype.concat/S15.5.4.6_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A1_T3-expected.txt:

Updated to show failing results. Firefox and Chrome also fail these
tests, and the ES5 spec seems to mandate failure. Because these tests
resolve a String.prototype function at global scope, the 'this' value
for the call is an environment record. Logically, an environment record
converts to 'undefined' at the call site, and should then fail the
CheckObjectCoercible test.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153221 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: isContravenedByStructure is backwards
oliver@apple.com [Thu, 25 Jul 2013 04:02:32 +0000 (04:02 +0000)]
fourthTier: isContravenedByStructure is backwards
https://bugs.webkit.org/show_bug.cgi?id=117366

We should be checking if arrayModeForStructure(structure) is a
subset of arrayModesThatPassFiltering(), not the other way around.
Also renamed isContravenedByStructure to better reflect what the
function is trying to determine.

Rubber stamped by Filip Pizlo.

* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::structureWouldPassArrayModeFiltering):
* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheckAccountingForArrayMode):
(JSC::DFG::ArrayTypeCheck::isContravenedByValue):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153220 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Type check hoisting phase has a dead if statement
oliver@apple.com [Thu, 25 Jul 2013 04:02:30 +0000 (04:02 +0000)]
fourthTier: Type check hoisting phase has a dead if statement
https://bugs.webkit.org/show_bug.cgi?id=117510

Reviewed by Geoffrey Garen.

* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153219 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Introducing the StackIterator class.
oliver@apple.com [Thu, 25 Jul 2013 04:02:28 +0000 (04:02 +0000)]
fourthTier: Introducing the StackIterator class.

This was a non trivial merge as trunk has changed computation of line and column information

Introducing the StackIterator class.
https://bugs.webkit.org/show_bug.cgi?id=117390.

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

The StackIterator class is meant to unify the way we iterate the JS
stack. It also makes it so that we don't have to copy the frame data
into the intermediate StackFrame struct before processing it.
Unfortunately we still can't get rid of StackFrame because it is used
to record frame information for the Exception stack that is expected
to persist beyond when the frames have been popped off the JS stack.

The StackIterator will iterate over all "logical" frames (i.e. including
inlined frames). As it iterates the JS stack, if it encounters a DFG
frame that has inlined frames, the iterator will canonicalize the
inlined frames before returning. Once canonicalized, the frame can be
read like any other frame.

The StackIterator implements a Frame class that inherits from CallFrame.
The StackIterator::Frame serves as reader of the CallFrame that makes
it easier to access information about the frame. The StackIterator::Frame
only adds functions, and no additional data fields.

* API/JSContextRef.cpp:
(JSContextCreateBacktrace):
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* interpreter/CallFrame.cpp:
(JSC::CallFrame::begin):
(JSC::CallFrame::beginAt):
* interpreter/CallFrame.h:
(JSC::ExecState::setInlineCallFrame):
(ExecState):
(JSC::ExecState::end):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::dumpRegisters):
(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::throwException):
(JSC::Interpreter::debug):
* interpreter/Interpreter.h:
(Interpreter):
* interpreter/StackIterator.cpp: Added.
(JSC::StackIterator::StackIterator):
(JSC::StackIterator::beginAt):
(JSC::StackIterator::gotoNextFrame):
- Based on the deleted Interpreter::findFunctionCallFrameFromVMCode().
(JSC::StackIterator::findFrameForFunction):
- Based on the deleted Interpreter::retrieveCallerFromVMCode().
(JSC::StackIterator::Frame::codeType):
- Based on the deleted getStackFrameCodeType().
(JSC::StackIterator::Frame::functionName):
- Based on StackFrame::friendlyFunctionName().
(JSC::StackIterator::Frame::sourceURL):
- Based on StackFrame::friendlySourceURL().
(JSC::StackIterator::Frame::toString):
- Based on StackFrame::toString().
(JSC::StackIterator::Frame::bytecodeOffset):
(JSC::StackIterator::Frame::line):
- Based on StackFrame::line().
(JSC::StackIterator::Frame::column):
- Based on StackFrame::column().
(JSC::StackIterator::Frame::arguments):
- Based on the deleted Interpreter::retrieveArgumentsFromVMCode().
(JSC::StackIterator::Frame::retrieveExpressionInfo):
- Based on StackFrame::expressionInfo().
(JSC::StackIterator::Frame::logicalFrame):
- Based on the now deleted CallFrame::trueCallFrame().
(JSC::StackIterator::Frame::logicalCallerFrame):
- Based on the now deleted CallFrame::trueCallerFrame().
(JSC::jitTypeName):
(JSC::printIndents):
(JSC::printif):
(JSC::StackIterator::Frame::print):
(debugPrintCallFrame):
- Prints the contents of the frame for debugging purposes.
  There are 2 versions that can be used as follows:

  1. When you have a valid StackIterator, you can print
     the current frame's content using the print instance
     method:
         iter->print(indentLevel);

  2. When you have a CallFrame* that you want to dump from a debugger
     console, you can print its content as follows:
         (gdb) call debugPrintCallFrame(callFrame)

  A sample of the output looks like this:

      frame 0x1510c70b0 {
         name 'shouldBe'
         sourceURL 'testapi.js'
         hostFlag 0
         isInlinedFrame 0
         callee 0x15154efb0
         returnPC 0x10ed0786d
         callerFrame 0x1510c7058
         logicalCallerFrame 0x1510c7058
         rawLocationBits 27 0x1b
         codeBlock 0x7fe79b037200
            bytecodeOffset 27 0x1b / 210
            line 46
            column 20
            jitType 3 <BaselineJIT> isOptimizingJIT 0
            hasCodeOrigins 0
      }

* interpreter/StackIterator.h: Added.
(StackIterator::Frame):
(JSC::StackIterator::Frame::create):
(JSC::StackIterator::Frame::isJSFrame):
(JSC::StackIterator::Frame::callFrame):
* interpreter/StackIteratorPrivate.h: Added.
(StackIterator):
(JSC::StackIterator::operator*):
(JSC::StackIterator::operator->):
(JSC::StackIterator::operator==):
(JSC::StackIterator::operator!=):
(JSC::StackIterator::operator++):
(JSC::StackIterator::end):
(JSC::StackIterator::empty):
* jsc.cpp:
(functionJSCStack):
* profiler/ProfileGenerator.cpp:
(JSC::ProfileGenerator::addParentForConsoleStart):
* profiler/ProfileNode.h:
(ProfileNode):
* runtime/JSFunction.cpp:
(JSC::retrieveArguments):
(JSC::JSFunction::argumentsGetter):
(JSC::skipOverBoundFunctions):
(JSC::retrieveCallerFunction):
(JSC::JSFunction::callerGetter):
(JSC::JSFunction::getOwnPropertyDescriptor):
(JSC::JSFunction::defineOwnProperty):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncProtoGetter):
(JSC::globalFuncProtoSetter):
* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorGetPrototypeOf):
* runtime/Operations.h:

Source/WebCore:

No new tests.

* ForwardingHeaders/interpreter/StackIterator.h: Added.
* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::send):
* bindings/js/ScriptCallStackFactory.cpp:
(WebCore::createScriptCallStack):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153218 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG GetById patching shouldn't distinguish between self lists and proto...
oliver@apple.com [Thu, 25 Jul 2013 04:02:24 +0000 (04:02 +0000)]
fourthTier: DFG GetById patching shouldn't distinguish between self lists and proto lists
https://bugs.webkit.org/show_bug.cgi?id=117377

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

Previously if you did self accesses and then wanted to do a prototype access, you'd
have a bad time: the prototype accesses would be forced to take slow path because
the self list wouldn't allow prototype accesses. Likewise if you did prototype (or
chain) accesses and then wanted to do a self access, similar stupidity would ensue.

This fixes the stupidity.

I believe that this was introduced way back in the days of the old interpreter,
where distinguishing between self lists, proto lists, and chain lists was meaningful
for interpreter performance: it meant fewer branches to evaluate those lists. Then
it got mostly carried over to the old JIT since the old JIT was just initially an
optimized version of the old interpreter, and then later it got carried over to the
DFG because I didn't know any better at the time. Now I do know better and I'm
fixing it.

* bytecode/PolymorphicAccessStructureList.h:
(JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
* bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::initGetByIdSelfList):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::getPolymorphicStructureList):
(DFG):
(JSC::DFG::patchJumpToGetByIdStub):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::dfgBuildGetByIDList):

LayoutTests:

Reviewed by Geoffrey Garen.

Add tests that show why this is important. These tests speed up by more than 3x.

* fast/js/regress/get-by-id-proto-or-self-expected.txt: Added.
* fast/js/regress/get-by-id-proto-or-self.html: Added.
* fast/js/regress/get-by-id-self-or-proto-expected.txt: Added.
* fast/js/regress/get-by-id-self-or-proto.html: Added.
* fast/js/regress/script-tests/get-by-id-proto-or-self.js: Added.
(foo):
(bar):
(Foo):
* fast/js/regress/script-tests/get-by-id-self-or-proto.js: Added.
(foo):
(bar):
(Foo):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153217 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Recursive deadlock in DFG::ByteCodeParser
oliver@apple.com [Thu, 25 Jul 2013 04:02:20 +0000 (04:02 +0000)]
fourthTier: Recursive deadlock in DFG::ByteCodeParser
https://bugs.webkit.org/show_bug.cgi?id=117376

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

Leave the lock early to prevent a deadlock beneath get().

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):

Source/WTF:

Reviewed by Mark Hahnenberg.

I've often wanted to leave a lock early. Now I have that power!

* wtf/Locker.h:
(WTF::Locker::Locker):
(WTF::Locker::~Locker):
(Locker):
(WTF::Locker::unlockEarly):
(WTF::Locker::lock):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153216 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: don't insert ForceOSRExits except for inadequate coverage
oliver@apple.com [Thu, 25 Jul 2013 04:02:17 +0000 (04:02 +0000)]
fourthTier: don't insert ForceOSRExits except for inadequate coverage
https://bugs.webkit.org/show_bug.cgi?id=117363

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

Previously (in http://trac.webkit.org/changeset/151303) I made it so that we
inserted ForceOSRExits more eagerly.  I now think it's better to have
contradictions execute normally and exit with full OSR exit profiling.  It's
better at catching the few cases where the DFG will end up with different
types than the baseline engines.

This simplifies a bunch of code. For example it gets rid of
ConstantFoldingPhase::paintUnreachableCode().

You can think of this as a partial roll-out of r151303, except that it uses
the facilities introduced by that patch to give us run-time assertions that
check the CFA's correctness: if the CFA thought that something was a
contradiction but the code didn't exit, we'll now trap.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::AbstractState):
(JSC::DFG::AbstractState::startExecuting):
(JSC::DFG::AbstractState::executeEffects):
(JSC::DFG::AbstractState::execute):
(JSC::DFG::AbstractState::filter):
(JSC::DFG::AbstractState::filterArrayModes):
(JSC::DFG::AbstractState::filterByValue):
(DFG):
* dfg/DFGAbstractState.h:
(AbstractState):
(JSC::DFG::AbstractState::filter):
(JSC::DFG::AbstractState::filterArrayModes):
(JSC::DFG::AbstractState::filterByValue):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::performBlockCFA):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::run):
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(ConstantFoldingPhase):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):

LayoutTests:

Reviewed by Mark Hahnenberg.

Convert this test, since this was the test originally added for
ConstantFoldingPhase::paintUnreachableCode(). I wanted to make sure that I had good coverage
for this since I am removing that method.

* fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt:
* fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153215 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Reenable the DFG optimization fixpoint now that it's profitable to do...
oliver@apple.com [Thu, 25 Jul 2013 04:02:15 +0000 (04:02 +0000)]
fourthTier: Reenable the DFG optimization fixpoint now that it's profitable to do so with concurrent compilation
https://bugs.webkit.org/show_bug.cgi?id=117331

Rubber stamped by Sam Weinig.

* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153214 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG CFA should know when it hits a contradiction
oliver@apple.com [Thu, 25 Jul 2013 04:02:13 +0000 (04:02 +0000)]
fourthTier: DFG CFA should know when it hits a contradiction
https://bugs.webkit.org/show_bug.cgi?id=117272

Reviewed by Oliver Hunt.

This makes the DFG CFA immediately detect when it hit a contradiction. Previously
we might not know this: for example if we did an int32 type check on a known string;
the code would definitely always exit but the CFA would think that we wouldn't have
even though it would have computed a BOTTOM (i.e. contradictory) value for that
variable.

This requires two other changes:

- CFA must report contradictions as if they are frequent exit sites, since
  contradictory speculations will subsequently get replaced with ForceOSRExit.
  ForceOSRExit cannot itself report profiling data back to the DFG::ExitProfile. So,
  we do this on behalf of the speculation, eagerly, within the CFA. This also has
  the effect of speeding convergence somewhat. We may want to revisit this later;
  for example we might want to instead have the notion of a ForceOSRExit that knows
  the set of speculations that got folded into it.

- This revealed a bug where the CFA was modeling CheckStructure on a node that had
  a known singleton m_futurePossibleStructure set somewhat differently than the
  constant folder. If the CheckStructure was checking a structure set with two or
  more structures in it, it would not filter the abstract value. But the constant
  folder would turn this into a watchpoint on the singleton structure, thereby
  filtering the value. This discrepancy meant that we wouldn't realize the
  contradiction until the backend, and the AbstractState::bail() method asserts that
  we always realize contradictions in the constant folder.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.h:
(JSC::CodeBlock::addFrequentExitSite):
(JSC::CodeBlock::hasExitSite):
(CodeBlock):
* bytecode/DFGExitProfile.cpp:
(JSC::DFG::ExitProfile::add):
(JSC::DFG::ExitProfile::hasExitSite):
(JSC::DFG::QueryableExitProfile::QueryableExitProfile):
(JSC::DFG::QueryableExitProfile::~QueryableExitProfile):
(DFG):
(JSC::DFG::QueryableExitProfile::initialize):
* bytecode/DFGExitProfile.h:
(JSC::DFG::FrequentExitSite::FrequentExitSite):
(ExitProfile):
(JSC::DFG::ExitProfile::hasExitSite):
(QueryableExitProfile):
* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::AbstractState):
(JSC::DFG::AbstractState::beginBasicBlock):
(JSC::DFG::AbstractState::reset):
(JSC::DFG::AbstractState::startExecuting):
(JSC::DFG::AbstractState::executeEffects):
(JSC::DFG::AbstractState::execute):
(JSC::DFG::AbstractState::filter):
(DFG):
(JSC::DFG::AbstractState::filterArrayModes):
(JSC::DFG::AbstractState::filterByValue):
(JSC::DFG::AbstractState::bail):
* dfg/DFGAbstractState.h:
(AbstractState):
(JSC::DFG::AbstractState::filter):
(JSC::DFG::AbstractState::filterArrayModes):
(JSC::DFG::AbstractState::filterByValue):
(JSC::DFG::AbstractState::filterByType):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filter):
(JSC::DFG::AbstractValue::filterArrayModes):
(DFG):
(JSC::DFG::AbstractValue::filterByValue):
(JSC::DFG::AbstractValue::normalizeClarity):
* dfg/DFGAbstractValue.h:
(AbstractValue):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::performBlockCFA):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::debugFail):
(JSC::DFG::capabilityLevel):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(ConstantFoldingPhase):
(JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
* dfg/DFGFiltrationResult.h: Added.
(DFG):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGOSRExitBase.cpp:
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
* dfg/DFGOSRExitBase.h:
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::backwardTypeCheck):
(JSC::DFG::SpeculativeJIT::bail):
(DFG):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileToStringOnCell):
(JSC::DFG::SpeculativeJIT::speculateStringObject):
(JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
* dfg/DFGSpeculativeJIT.h:
(SpeculativeJIT):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::appendTypeCheck):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153213 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: 32-bit CallFrame::Location should use Instruction* for BytecodeLocation...
oliver@apple.com [Thu, 25 Jul 2013 04:02:09 +0000 (04:02 +0000)]
fourthTier: 32-bit CallFrame::Location should use Instruction* for BytecodeLocation, not bytecodeOffset.
https://bugs.webkit.org/show_bug.cgi?id=117327.

Reviewed by Michael Saboff.

- Renamed CallFrame::Location's Type to TypeTag.
- Made the CallFrame::Location::TypeTag private, and provided type
  specific encoder functions. This reduces verbosity in client code.
- Fixed the DFG's reifyInlinedCallFrames() on 32-bit ports to store a
  bytecode Instruction* in the CallFrame location instead of a bytecode
  offset.
- Fixed places in JIT and FTL code which populate the CallFrame location
  (i.e. ArgumentCount tag) to use a Location encoder instead of storing
  the bytecodeOffset directly. This doesn't make any semantic difference,
  but it does assert that the stored value does not have bits where we
  would expect Location TypeTags to be.

* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::beginCall):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::setLocationAsBytecodeOffset):
* interpreter/CallFrame.h:
(Location):
* interpreter/CallFrameInlines.h:
(JSC::CallFrame::Location::encodeAsBytecodeOffset):
(JSC::CallFrame::Location::encodeAsBytecodeInstruction):
(JSC::CallFrame::Location::encodeAsCodeOriginIndex):
(JSC::CallFrame::Location::encodeAsInlinedCode):
(JSC::CallFrame::Location::isBytecodeLocation):
(JSC::CallFrame::setIsInlinedFrame):
(JSC::CallFrame::hasLocationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileOpCall):
* jit/JITInlines.h:
(JSC::JIT::updateTopCallFrame):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153212 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: CallFrame::trueCallFrame() should populate the bytecodeOffset field
oliver@apple.com [Thu, 25 Jul 2013 04:02:07 +0000 (04:02 +0000)]
fourthTier: CallFrame::trueCallFrame() should populate the bytecodeOffset field
when reifying inlined frames..
https://bugs.webkit.org/show_bug.cgi?id=117209.

Reviewed by Geoffrey Garen.

When reifying an inlined frame, we fill in its CodeBlock, and
bytecodeOffset. We also set the InlinedFrame bit in the location field.
This is needed in order to iterate the stack correctly. Here's why:

    Let's say we have the following stack trace:
      X calls A inlines B inlines C calls D

    Based on the above scenario,
    1. D's callerFrame points to A (not C).
    2. A has a codeOriginIndex that points to C.

When iterating the stack (from D back towards X), we will encounter A
twice:

    t1. when trying to find C as D's caller.
        This is the time when we reify B and C using the
        codeOriginIndex in A, and return C as the caller frame of D.

    t2. when getting's the reified B's caller.
        This time, we don't run the reification process, and
        just take A as the caller frame of B.

To discern which treatment of the DFG frame (i.e. A) we need to apply,
we check if the callee is an inlined frame:

    If callee is NOT an inlined frame (e.g. frame D), apply treatment t1.
    If callee is an inlined frame (e.g. frame B), apply treatment t2.

Why not just reify A by replacing its codeOriginIndex with A's
bytecodeOffset?

We can't do this because D's callerFrame pointer still points to A, and
needs to remain that way because we did not deopt A. It remains a DFG
frame which inlined B and C.

If we replace the codeOriginIndex in A with A's bytecodeOffset, we will
only get to iterate the stack correctly once. If we try to iterate the
stack a second time, we will not have the information from the
codeOriginIndex to tell us that D's caller is actually the inlined C,
and not A.

To recap, when reifying frames for stack iteration purposes, the DFG
frame needs to hold on to its codeOriginIndex. This in turn means the
DFG frame will need to be treated in 2 possible ways, and we need to
know if a callee frame is an inlined frame in order to choose the
correct treatment for the DFG frame.

Other changes:
- Simplified Interpreter::getCallerInfo().
- Removed CodeBlock::codeOriginForReturn() and supporting code
  which is now unneeded.
- Moved CallFrame location bit encoding from the CodeOrigin to the
  new CallFrame::Location class.
- Explicitly tagged inlined frames. This is necessary in order to
  iterate the stack correctly as explained above.

* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
(JSC::CodeBlock::codeOrigins):
(CodeBlock):
(JSC::CodeBlock::codeOrigin):
(RareData):
* bytecode/CodeOrigin.h:
(CodeOrigin):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::beginCall):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::trueCallFrame):
(JSC::CallFrame::trueCallerFrame):
(JSC::CallFrame::bytecodeOffsetFromCodeOriginIndex):
* interpreter/CallFrame.h:
(Location):
(ExecState):
(JSC::ExecState::trueCallerFrame):
(JSC::ExecState::callerFrameNoFlags):
* interpreter/CallFrameInlines.h:
(JSC::CallFrame::Location::encode):
(JSC::CallFrame::Location::decode):
(JSC::CallFrame::Location::isBytecodeOffset):
(JSC::CallFrame::Location::isCodeOriginIndex):
(JSC::CallFrame::Location::isInlinedFrame):
(JSC::CallFrame::isInlinedFrame):
(JSC::CallFrame::setIsInlinedFrame):
(JSC::CallFrame::hasLocationAsBytecodeOffset):
(JSC::CallFrame::hasLocationAsCodeOriginIndex):
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::locationAsCodeOriginIndex):
* interpreter/Interpreter.cpp:
(JSC::getCallerInfo):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::findFunctionCallFrameFromVMCode):
* runtime/Arguments.cpp:
(JSC::Arguments::tearOff):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153211 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG CFA shouldn't filter ArrayModes with ALL_NON_ARRAY_ARRAY_MODES if...
oliver@apple.com [Thu, 25 Jul 2013 04:02:04 +0000 (04:02 +0000)]
fourthTier: DFG CFA shouldn't filter ArrayModes with ALL_NON_ARRAY_ARRAY_MODES if the speculated type is not SpecArray
https://bugs.webkit.org/show_bug.cgi?id=117279

Reviewed by Mark Hahnenberg.

The normalization of abstract value clarity introduced in r151229 revealed a
long-standing bug where we filtered ArrayModes incorrectly and sometimes ended
up with BOTTOM incorrectly.

This patch fixes that bug, and cleans up a bunch of debugging infrastructure
that I needed to resurrect to track this down.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::resetStubInternal):
(JSC::CodeBlock::noticeIncomingCall):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filterArrayModesByType):
* dfg/DFGCFAPhase.cpp:
(CFAPhase):
(JSC::DFG::CFAPhase::run):
(JSC::DFG::CFAPhase::performBlockCFA):
(JSC::DFG::CFAPhase::performForwardCFA):
* runtime/Options.h:
(JSC):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153210 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Disambiguate between CallFrame bytecodeOffset and codeOriginIndex.
oliver@apple.com [Thu, 25 Jul 2013 04:02:03 +0000 (04:02 +0000)]
fourthTier: Disambiguate between CallFrame bytecodeOffset and codeOriginIndex.
https://bugs.webkit.org/show_bug.cgi?id=117262.

Reviewed by Geoffrey Garen.

When writing to the ArgumentCount tag in CallFrame, we will set the high
bit if the written value is a codeOriginIndex.

* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeOrigin.h:
(CodeOrigin):
(JSC::CodeOrigin::isHandle):
(JSC::CodeOrigin::encodeHandle):
(JSC::CodeOrigin::decodeHandle):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::beginCall):
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryBuildGetByIDList):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::currentVPC):
(JSC::CallFrame::setCurrentVPC):
(JSC::CallFrame::trueCallFrame):
* interpreter/CallFrame.h:
(ExecState):
(JSC::ExecState::inlineCallFrame):
* interpreter/CallFrameInlines.h: Added.
(JSC::CallFrame::hasLocationAsBytecodeOffset):
(JSC::CallFrame::hasLocationAsCodeOriginIndex):
(JSC::CallFrame::locationAsRawBits):
(JSC::CallFrame::setLocationAsRawBits):
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::locationAsCodeOriginIndex):
* interpreter/Interpreter.cpp:
(JSC::getBytecodeOffsetForCallFrame):
(JSC::getCallerInfo):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153209 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Clean up AbstractValue
oliver@apple.com [Thu, 25 Jul 2013 04:02:00 +0000 (04:02 +0000)]
fourthTier: Clean up AbstractValue
https://bugs.webkit.org/show_bug.cgi?id=117217

Reviewed by Oliver Hunt.

This started as an attempt to make it so that when AbstractValue becomes empty,
its m_type always becomes SpecNone. I wanted this to happen naturally. That turns
out to be basically impossible, since AbstractValue is a set that is dynamically
computed from the intersection of several internal sets: so the value becomes
empty when any of the sets go empty. It's OK if we're imprecise here because it's
always safe for the AbstractValue to seem to overapproximate the set of values
that we see. So I mostly gave up on cleaning up that aspect of AbstractValue. But
while trying to make this happen, I encountered two bugs:

- filterValueByType() ignores the case when m_type contravenes m_value. Namely,
  we might filter the AbstractValue against a SpeculatedType leading to m_value
  becoming inconsistent with the new m_type. This change fixes that case. This
  wasn't a symptomatic bug but it was a silly oversight.

- filterFuturePossibleStructure() was never right. The one call to this method,
  in filter(Graph&, const StructureSet&), assumed that the previous notions of
  what structures the value could have in the future were still relevant. This
  could lead to a bug where we:

  1) CheckStructure(@foo, S1)

     Where S1 has a valid watchpoint. Now @foo's abstract value will have current
     and future structure = S1.

  2) Clobber the world.

     Now @foo's abstract value will have current structure = TOP, and future
     possible structure = S1.

  3) CheckStructure(@foo, S2)

     Now @foo's abstract value will have current structure = S2 and future
     possible structure = S1 intersect S2 = BOTTOM.

  Now we will think that any subsequent watchpoint on @foo is valid because the
  value is effectively BOTTOM. That would only be correct if we had actually set
  a watchpoint on S1. If we had done so, then (3) would only pass (i.e. @foo
  would only have structure S2) if S1's watchpoint fired, in which case (3)
  wouldn't have been reachable. But we didn't actually set a watchpoint on S1:
  we just observed that we *could* have set the watchpoint. Hence future possible
  structure should only be set to either the known structure at compile-time, or
  it should be the structure we just checked; in both cases it should only be set
  if the structure is watchable.

Then, in addition to all of this, I changed AbstractValue's filtering methods to
call clear() if the AbstractValue is effectively clear. This is just meant to
simplify the recognition of truly empty AbstractValues, but doesn't actually have
any other implications.

* bytecode/StructureSet.h:
(JSC::StructureSet::dump):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filter):
(DFG):
(JSC::DFG::AbstractValue::filterArrayModes):
(JSC::DFG::AbstractValue::filterValueByType):
(JSC::DFG::AbstractValue::filterArrayModesByType):
(JSC::DFG::AbstractValue::shouldBeClear):
(JSC::DFG::AbstractValue::normalizeClarity):
(JSC::DFG::AbstractValue::checkConsistency):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::isClear):
(AbstractValue):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153208 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: The DFG JIT should populate frame bytecodeOffsets on OSR exit.
oliver@apple.com [Thu, 25 Jul 2013 04:01:59 +0000 (04:01 +0000)]
fourthTier: The DFG JIT should populate frame bytecodeOffsets on OSR exit.
https://bugs.webkit.org/show_bug.cgi?id=117103.

Reviewed by Geoffrey Garen.

* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153207 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: all cached put_by_id transitions, even ones that weren't inlined by the...
oliver@apple.com [Thu, 25 Jul 2013 04:01:56 +0000 (04:01 +0000)]
fourthTier: all cached put_by_id transitions, even ones that weren't inlined by the DFG, should be propagated by the GC
https://bugs.webkit.org/show_bug.cgi?id=117170

Reviewed by Mark Hahnenberg.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::visitAggregate):
(JSC::CodeBlock::propagateTransitions):
(JSC):
(JSC::CodeBlock::determineLiveness):
(JSC::CodeBlock::visitWeakReferences):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecode/CodeBlock.h:
(CodeBlock):
* bytecode/PolymorphicPutByIdList.h:
(JSC):
(PutByIdAccess):
(PolymorphicPutByIdList):
* bytecode/StructureStubInfo.h:
(StructureStubInfo):
* jit/JITCode.h:
(JSC::JITCode::couldBeInterpreted):
(JITCode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153206 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Get rid of StructureStubInfo::bytecodeIndex
oliver@apple.com [Thu, 25 Jul 2013 04:01:54 +0000 (04:01 +0000)]
fourthTier: Get rid of StructureStubInfo::bytecodeIndex
https://bugs.webkit.org/show_bug.cgi?id=117127

Reviewed by Mark Hahnenberg.

StructureStubInfo already has a CodeOrigin field, which also has a bytecodeIndex.
It makes sense to just always use the CodeOrigin.

* bytecode/StructureStubInfo.h:
(StructureStubInfo):
(JSC::getStructureStubInfoBytecodeIndex):
* jit/JIT.cpp:
(JSC::PropertyStubCompilationInfo::copyToStubInfo):
* jit/JIT.h:
(JSC::JIT::compileGetByIdProto):
(JSC::JIT::compileGetByIdSelfList):
(JSC::JIT::compileGetByIdProtoList):
(JSC::JIT::compileGetByIdChainList):
(JSC::JIT::compileGetByIdChain):
(JSC::JIT::compilePutByIdTransition):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::privateCompilePutByIdTransition):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153205 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Fix some minor issues in the DFG's profiling of heap accesses
oliver@apple.com [Thu, 25 Jul 2013 04:01:52 +0000 (04:01 +0000)]
fourthTier: Fix some minor issues in the DFG's profiling of heap accesses
https://bugs.webkit.org/show_bug.cgi?id=113010

Reviewed by Goeffrey Garen.

Carefully merge r146669 from trunk. This required some fiddling since it
wasn't a clean apply.

Original changelog:

    1) If a CodeBlock gets jettisoned by GC, we should count the exit sites.

    2) If a CodeBlock clears a structure stub during GC, it should record this, and
    the DFG should prefer to not inline that access (i.e. treat it as if it had an
    exit site).

    3) If a PutById was seen by the baseline JIT, and the JIT attempted to cache it,
    but it chose not to, then assume that it will take slow path.

    4) If we frequently exited because of a structure check on a weak constant,
    don't try to inline that access in the future.

    5) Treat all exits that were counted as being frequent.

    81% speed-up on Octane/gbemu. Small speed-ups elsewhere, and no regressions.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finalizeUnconditionally):
(JSC):
(JSC::CodeBlock::resetStubDuringGCInternal):
(JSC::CodeBlock::reoptimize):
(JSC::CodeBlock::jettison):
(JSC::ProgramCodeBlock::jettisonImpl):
(JSC::EvalCodeBlock::jettisonImpl):
(JSC::FunctionCodeBlock::jettisonImpl):
(JSC::CodeBlock::tallyFrequentExitSites):
* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::tallyFrequentExitSites):
(ProgramCodeBlock):
(EvalCodeBlock):
(FunctionCodeBlock):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeFor):
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFor):
* bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::StructureStubInfo):
(StructureStubInfo):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGOSRExitBase.cpp:
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
* dfg/DFGOSRExitBase.h:
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
(OSRExitBase):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Options.h:
(JSC):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153204 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT
oliver@apple.com [Thu, 25 Jul 2013 04:01:50 +0000 (04:01 +0000)]
fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT

Rubber stamped by Mark Hahnenberg.

* fast/js/dfg-arguments-alias-one-block-overwrite-expected.txt:
* fast/js/dfg-arguments-out-of-bounds-expected.txt:
* fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt:
* fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt:
* fast/js/dfg-array-length-dead-expected.txt:
* fast/js/dfg-array-pop-side-effects-expected.txt:
* fast/js/resources/js-test-pre.js:
(testFailed):
(dfgIncrement):
(isSuccessfullyParsed):
* fast/js/script-tests/dfg-arguments-alias-one-block-overwrite.js:
* fast/js/script-tests/dfg-arguments-out-of-bounds.js:
* fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js:
* fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js:
* fast/js/script-tests/dfg-array-length-dead.js:
* fast/js/script-tests/dfg-array-pop-side-effects.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153203 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Remove CodeOrigin::valueProfileOffset since it was only needed for op_cal...
oliver@apple.com [Thu, 25 Jul 2013 04:01:48 +0000 (04:01 +0000)]
fourthTier: Remove CodeOrigin::valueProfileOffset since it was only needed for op_call_put_result.

Rubber stamped by Mark Hahnenberg.

* bytecode/CodeOrigin.h:
(CodeOrigin):
(JSC::CodeOrigin::CodeOrigin):
(JSC::CodeOrigin::isSet):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::currentCodeOrigin):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::valueProfileFor):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153202 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Remove finalDestinationOrIgnored since it isn't called anymore.
oliver@apple.com [Thu, 25 Jul 2013 04:01:46 +0000 (04:01 +0000)]
fourthTier: Remove finalDestinationOrIgnored since it isn't called anymore.

Rubber stamped by Mark Hahnenberg.

* bytecompiler/BytecodeGenerator.h:
(BytecodeGenerator):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153201 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: get rid of op_call_put_result
oliver@apple.com [Thu, 25 Jul 2013 04:01:45 +0000 (04:01 +0000)]
fourthTier: get rid of op_call_put_result
https://bugs.webkit.org/show_bug.cgi?id=117047

Reviewed by Gavin Barraclough.

Work in progress. This still makes like 20 tests crash.

op_call_put_result is an oddball. Its semantics are that it takes the return
value of a call instruction, which is set aside in regT0/regT1, and places them
into some stack slot. This is weird since there is an implicit contract with the
preceding bytecode instruction, and it's even weirder since it means that it
doesn't make sense to jump to it; for example OSR exit from the preceding call
instruction must make sure to jump over the op_call_put_result.

So this patch gets rid of op_call_put_result:

- In bytecode, all calls return a value and we always allocate a temporary for
  that value even if it isn't used.

- The LLInt does the return value saving as part of dispatchAfterCall().

- The JIT and DFG do the return value saving as part of normal code generation.
  The DFG already did the right thing.

- DFG->JIT OSR exit in the case of inlining will make the return PC's point at
  the CallLinkInfo::callReturnLocation, rather than the machine PC associated
  with the op_call_put_result instruction.

- Tons of code gets removed. The DFG had to track whether or not a call had a
  return value in a bunch of places. It had to track the fact that we would
  exit to after the op_call_put_result. It was a mess. That mess is now gone.

* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::computeFromLLInt):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printCallOp):
(JSC::CodeBlock::dumpArrayProfiling):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
* bytecode/CodeBlock.h:
* bytecode/Opcode.h:
(JSC):
(JSC::padOpcodeName):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitCall):
(JSC::BytecodeGenerator::emitCallVarargs):
(JSC::BytecodeGenerator::emitConstruct):
* bytecompiler/NodesCodegen.cpp:
(JSC::NewExprNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::ByteCodeParser):
(ByteCodeParser):
(JSC::DFG::ByteCodeParser::currentCodeOrigin):
(JSC::DFG::ByteCodeParser::addCall):
(JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
(JSC::DFG::ByteCodeParser::getPrediction):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::handleMinMax):
(JSC::DFG::ByteCodeParser::handleIntrinsic):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
(JIT):
* jit/JITCall.cpp:
(JSC::JIT::emitPutCallResult):
(JSC::JIT::compileLoadVarargs):
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::emit_op_call):
(JSC):
(JSC::JIT::emit_op_call_eval):
(JSC::JIT::emit_op_call_varargs):
(JSC::JIT::emit_op_construct):
(JSC::JIT::emitSlow_op_call):
(JSC::JIT::emitSlow_op_call_eval):
(JSC::JIT::emitSlow_op_call_varargs):
(JSC::JIT::emitSlow_op_construct):
* jit/JITCall32_64.cpp:
(JSC::JIT::emitPutCallResult):
(JSC::JIT::compileLoadVarargs):
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITOpcodes.cpp:
(JSC):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::genericCall):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153200 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: LLInt shouldn't store an offset call PC during op_call-like calls
oliver@apple.com [Thu, 25 Jul 2013 04:01:42 +0000 (04:01 +0000)]
fourthTier: LLInt shouldn't store an offset call PC during op_call-like calls
https://bugs.webkit.org/show_bug.cgi?id=117048

Reviewed by Mark Hahnenberg.

This just makes everything consistent in the LLInt: anytime any op calls out,
it stores its PC and never the next op's PC.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::linkIncomingCall):
(JSC::CodeBlock::bytecodeOffset):
* bytecode/CodeBlock.h:
* bytecode/Opcode.h:
(JSC::padOpcodeName):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitCallVarargs):
* llint/LLIntExceptions.cpp:
(JSC::LLInt::interpreterThrowInCaller):
(JSC::LLInt::returnToThrow):
(JSC::LLInt::callToThrow):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153199 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support ArithAbs
oliver@apple.com [Thu, 25 Jul 2013 04:01:40 +0000 (04:01 +0000)]
fourthTier: FTL should support ArithAbs
https://bugs.webkit.org/show_bug.cgi?id=116890

Reviewed by Oliver Hunt.

Implements ArithAbs in the FTL, and cleans up the DFG implementation. The
DFG implementation was previously doing zero extensions manually when it
is probably better to just use StrictInt32Operand instead.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLIntrinsicRepository.h:
(FTL):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileArithAbs):
(LowerDFGToLLVM):
* ftl/FTLOutput.h:
(JSC::FTL::Output::doubleAbs):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153198 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Misc JIT probe enhacements.
oliver@apple.com [Thu, 25 Jul 2013 04:01:38 +0000 (04:01 +0000)]
fourthTier: Misc JIT probe enhacements.
https://bugs.webkit.org/show_bug.cgi?id=116586.

Reviewed by Michael Saboff.

1. Added JIT probe support for ARMv7 and traditional ARM.
   Built and tested on ARMv7. ARM version not tested nor built.
2. Fix the following bugs in the X86 and X86_64 probes:
   a. Cannot assume that the stack pointer is already aligned when
      we push args for the probe. Instead, we ensure the stack
      alignment at runtime when we set up the probe call.
      This is now done in the ctiMasmProbeTrampoline.
   b. On return, the user probe function may have altered the stack
      pointer value to be restored. Previously, if the sp restore value
      points to some of the other register restore values in the
      ProbeContext record, we will fail to return from the probe having
      those user specified value as we're expected to do.
      This is now fixed.
3. Rearranged the X86/X86_64 registers order to organize them like gdb
   expects on X86_64.
4. We also now preserve the condition code registers.

* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/ARMAssembler.h:
* assembler/ARMv7Assembler.h:
(ARMRegisters):
* assembler/MacroAssemblerARM.cpp:
(JSC::isVFPPresent):
(JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters):
(JSC::MacroAssemblerARM::ProbeContext::dump):
(JSC::MacroAssemblerARM::probe):
* assembler/MacroAssemblerARM.h:
(MacroAssemblerARM):
(CPUState):
(ProbeContext):
(JSC::MacroAssemblerARM::trustedImm32FromPtr):
* assembler/MacroAssemblerARMv7.h:
(MacroAssemblerARMv7):
(CPUState):
(ProbeContext):
(JSC::MacroAssemblerARMv7::trustedImm32FromPtr):
* assembler/MacroAssemblerX86.h:
(MacroAssemblerX86):
(JSC::MacroAssemblerX86::probe):
* assembler/MacroAssemblerX86Common.cpp:
(JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::probe):
* assembler/X86Assembler.h:
* config.h:
* jit/JITStubsARM.h:
* jit/JITStubsARMv7.h:
* jit/JITStubsX86.h:
* jit/JITStubsX86Common.h:
* jit/JITStubsX86_64.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153197 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should call masqueradesAsUndefinedWatchpointIfIsStillValid() in all...
oliver@apple.com [Thu, 25 Jul 2013 04:01:35 +0000 (04:01 +0000)]
fourthTier: FTL should call masqueradesAsUndefinedWatchpointIfIsStillValid() in all of the places where it currently calls masqueradesAsUndefinedWatchpointIsStillValid()
https://bugs.webkit.org/show_bug.cgi?id=116892

Reviewed by Oliver Hunt.

All of those places mean to plant the watchpoint if it's still valid.

* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
(JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153196 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT
oliver@apple.com [Thu, 25 Jul 2013 04:01:32 +0000 (04:01 +0000)]
fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT

Rubber stamped by Oliver Hunt.

* fast/js/dfg-arguments-alias-activation-expected.txt:
* fast/js/dfg-arguments-alias-activation.html:
* fast/js/dfg-arguments-alias-expected.txt:
* fast/js/script-tests/dfg-arguments-alias.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153195 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support ArithMin/ArithMax
oliver@apple.com [Thu, 25 Jul 2013 04:01:30 +0000 (04:01 +0000)]
fourthTier: FTL should support ArithMin/ArithMax
https://bugs.webkit.org/show_bug.cgi?id=116885

Reviewed by Oliver Hunt.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153194 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT
oliver@apple.com [Thu, 25 Jul 2013 04:01:28 +0000 (04:01 +0000)]
fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT

Rubber stamped by Oliver Hunt.

* fast/js/dfg-abs-backwards-propagation-expected.txt:
* fast/js/dfg-add-not-number-expected.txt:
* fast/js/dfg-arguments-alias-escape-expected.txt:
* fast/js/resources/js-test-pre.js:
(dfgCompiled):
(dfgIncrement):
* fast/js/script-tests/dfg-abs-backwards-propagation.js:
* fast/js/script-tests/dfg-add-not-number.js:
* fast/js/script-tests/dfg-arguments-alias-escape.js:
* fast/js/script-tests/dfg-arguments-alias-one-block-osr-exit.js:
* fast/js/script-tests/dfg-arguments-alias-one-block-overwrite-arguments.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153193 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: fast/js should have a way of running tests long enough to wait for the...
oliver@apple.com [Thu, 25 Jul 2013 04:01:26 +0000 (04:01 +0000)]
fourthTier: fast/js should have a way of running tests long enough to wait for the concurrent JIT to tier up
https://bugs.webkit.org/show_bug.cgi?id=116878

Reviewed by Oliver Hunt.

This adds three things to js-test-pre and uses them in one representative test:

silentTestPass: If you set this to true, then testPassed() won't print anything, and will instead just have
    isSuccessfullyParsed() print a message saying that some tests passed silently. This allows tests to call
    shouldBe() and friends in a loop whose running time is dependent on concurrent JIT behavior, and still
    be sure that the resulting test will be deterministic.

noInline(): If testRunner is present, disable inlining of the relevant function.

dfgIncrement({f:function, i:index, n:limit}): Returns index either if index < limit, or if the function is
    DFG compiled. Otherwise, if index >= limit and the function isn't DFG compiled, return 0. This means
    that the 'i++' in the fast/js/dfg-* warm-up loops can be replaced with:

    i = dfgIncrement({f:<function you're interested in>, i:i + 1, n:<some number smaller than the loop condition>)

    This has the effect of having the loop repeat the first 'n' iterations until the function is DFG
    compiled. See the modified test, where we do n:100 and the loop condition is i < 200. So the loop will
    repeat the first 100 iterations until the function is DFG compiled and will only do the last 100
    iterations once DFG compilation kicks in.

* fast/js/dfg-arguments-osr-exit-multiple-blocks-expected.txt:
* fast/js/resources/js-test-pre.js:
(testPassed):
(dfgIncrement):
(noInline):
(isSuccessfullyParsed):
* fast/js/script-tests/dfg-arguments-osr-exit-multiple-blocks.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153192 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: testRunner should have a way of disabling inlining of functions
oliver@apple.com [Thu, 25 Jul 2013 04:01:24 +0000 (04:01 +0000)]
fourthTier: testRunner should have a way of disabling inlining of functions
https://bugs.webkit.org/show_bug.cgi?id=116875

Reviewed by Mark Hahnenberg.

Source/JavaScriptCore:

* API/JSCTestRunnerUtils.cpp:
(JSC::getExecutable):
(JSC):
(JSC::numberOfDFGCompiles):
(JSC::setNeverInline):
* API/JSCTestRunnerUtils.h:
(JSC):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpAssumingJITType):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::mightInlineFunctionForCall):
(JSC::DFG::mightInlineFunctionForClosureCall):
(JSC::DFG::mightInlineFunctionForConstruct):
* runtime/Executable.h:
(JSC::ScriptExecutable::ScriptExecutable):
(ScriptExecutable):
(JSC::ScriptExecutable::setNeverInline):
(JSC::ScriptExecutable::neverInline):
(JSC::ScriptExecutable::isInliningCandidate):

Tools:

* DumpRenderTree/TestRunner.cpp:
(neverInlineFunction):
(TestRunner::staticFunctions):

LayoutTests:

* fast/js/script-tests/dfg-min-max.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153191 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support ArithMod
oliver@apple.com [Thu, 25 Jul 2013 04:01:22 +0000 (04:01 +0000)]
fourthTier: FTL should support ArithMod
https://bugs.webkit.org/show_bug.cgi?id=116792

Reviewed by Oliver Hunt.

* ftl/FTLAbbreviations.h:
(JSC::FTL::buildFRem):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileArithMod):
(LowerDFGToLLVM):
* ftl/FTLOutput.h:
(JSC::FTL::Output::doubleRem):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153190 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: It should be possible to record heap operations (both FastMalloc and...
oliver@apple.com [Thu, 25 Jul 2013 04:01:20 +0000 (04:01 +0000)]
fourthTier: It should be possible to record heap operations (both FastMalloc and JSC GC)
https://bugs.webkit.org/show_bug.cgi?id=116848

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

Record GC heap operations if ENABLE(ALLOCATION_LOGGING).

* API/JSManagedValue.mm:
* dfg/DFGOperations.cpp:
* heap/Heap.cpp:
(JSC::Heap::collect):
* heap/Heap.h:
(Heap):
(JSC::Heap::allocateWithNormalDestructor):
(JSC::Heap::allocateWithImmortalStructureDestructor):
(JSC::Heap::allocateWithoutDestructor):
(JSC::Heap::tryAllocateStorage):
(JSC::Heap::tryReallocateStorage):
(JSC):
(JSC::Heap::ascribeOwner):
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::append):
(JSC::SlotVisitor::internalAppend):
* heap/SlotVisitor.h:
(SlotVisitor):
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::append):
(JSC::SlotVisitor::appendUnbarrieredPointer):
(JSC::SlotVisitor::appendUnbarrieredValue):
(JSC::SlotVisitor::appendUnbarrieredWeak):
(JSC::SlotVisitor::internalAppend):
(JSC):
(JSC::SlotVisitor::appendValues):
* jit/JITWriteBarrier.h:
(JSC::SlotVisitor::append):
* llint/LLIntCommon.h:
* runtime/Butterfly.h:
(Butterfly):
* runtime/ButterflyInlines.h:
(JSC::Butterfly::createUninitialized):
(JSC::Butterfly::create):
(JSC::Butterfly::growPropertyStorage):
(JSC::Butterfly::createOrGrowArrayRight):
(JSC):
(JSC::Butterfly::growArrayRight):
(JSC::Butterfly::resizeArray):
* runtime/JSArray.cpp:
(JSC::createArrayButterflyInDictionaryIndexingMode):
(JSC::JSArray::unshiftCountSlowCase):
* runtime/JSArray.h:
(JSC::createContiguousArrayButterfly):
(JSC::createArrayButterfly):
(JSC):
(JSC::JSArray::create):
(JSC::JSArray::tryCreateUninitialized):
* runtime/JSObject.cpp:
(JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
(JSC::JSObject::createInitialIndexedStorage):
(JSC::JSObject::createArrayStorage):
(JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
(JSC::JSObject::increaseVectorLength):
(JSC::JSObject::ensureLengthSlow):
(JSC::JSObject::growOutOfLineStorage):
* runtime/JSObject.h:
(JSC::JSObject::JSObject):
* runtime/Operations.h:
* runtime/RegExpMatchesArray.cpp:
(JSC::RegExpMatchesArray::create):
* runtime/StructureInlines.h:
(JSC):
* runtime/WriteBarrier.h:
(JSC):

Source/WTF:

Reviewed by Mark Hahnenberg.

* WTF.xcodeproj/project.pbxproj:
* wtf/DataLog.cpp:
(WTF):
(WTF::initializeLogFileOnce):
* wtf/FastMalloc.cpp:
(WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
* wtf/Platform.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153189 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: testRunner should be able to tell you if a function is DFG compiled
oliver@apple.com [Thu, 25 Jul 2013 04:01:17 +0000 (04:01 +0000)]
fourthTier: testRunner should be able to tell you if a function is DFG compiled
https://bugs.webkit.org/show_bug.cgi?id=116847

Reviewed by Mark Hahnenberg.

Source/JavaScriptCore:

* API/JSCTestRunnerUtils.cpp: Added.
(JSC):
(JSC::numberOfDFGCompiles):
* API/JSCTestRunnerUtils.h: Added.
(JSC):
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::numberOfDFGCompiles):
(JSC):
* bytecode/CodeBlock.h:
(CodeBlock):
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::runThread):
* runtime/Executable.h:
(JSC):
* runtime/JSFunctionInlines.h: Added.
(JSC):
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::jsExecutable):
(JSC::JSFunction::isHostFunction):
(JSC::JSFunction::nativeFunction):
(JSC::JSFunction::nativeConstructor):
* runtime/Operations.h:

Source/WebCore:

Bail early if we're in the compilation thread. This is only relevant for
debug dumps.

No new tests becase no new behavior.

* loader/cache/CachedScript.cpp:
(WebCore::CachedScript::script):

Tools:

* DumpRenderTree/TestRunner.cpp:
(numberOfDFGCompiles):
(TestRunner::staticFunctions):

LayoutTests:

* fast/js/script-tests/dfg-min-max.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153188 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: DFG ArithMod should have the !nodeUsedAsNumber optimizations that ArithDi...
oliver@apple.com [Thu, 25 Jul 2013 04:01:14 +0000 (04:01 +0000)]
fourthTier: DFG ArithMod should have the !nodeUsedAsNumber optimizations that ArithDiv has
https://bugs.webkit.org/show_bug.cgi?id=116841

Reviewed by Mark Hahnenberg.

Source/JavaScriptCore:

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithMod):

LayoutTests:

* fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
* fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html: Added.
* fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
* fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html: Added.
* fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt: Added.
* fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html: Added.
* fast/js/jsc-test-list:
* fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js: Added.
(foo):
* fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js: Added.
(foo):
* fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js: Added.
(foo):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153187 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: clean up ArithDiv/ArithMod in the DFG
oliver@apple.com [Thu, 25 Jul 2013 04:01:11 +0000 (04:01 +0000)]
fourthTier: clean up ArithDiv/ArithMod in the DFG
https://bugs.webkit.org/show_bug.cgi?id=116793

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

This makes ArithDiv and ArithMod behave similarly, and moves both of their
implementations entirely into DFGSpeculativeJIT.cpp into methods named like
the ones for ArithSub/ArithMul.

Specifically, ArithMod now uses the wrap-in-conversion-nodes idiom that
ArithDiv used for platforms that don't support integer division. Previously
ArithMod had its own int-to-double and double-to-int conversions for this
purpose.

As well, this gets rid of confusing methods like compileSoftModulo() (which
did no such thing, there wasn't anything "soft" about it) and
compileIntegerArithDivForX86() (which is accurately named but we don't use
the platform-specific method convention anywhere else).

Finally, this takes the optimized power-of-two modulo operation that was
previously only for ARMv7s, and makes it available for all platforms. Well,
sort of: I actually rewrote it to do what latest LLVM appears to do, which
is a crazy straight-line power-of-2 modulo based on a combination of shifts,
ands, additions, and subtractions. I can kind of understand it well enough
to see that it complies with both C and JS power-of-2 modulo semantics. I've
also confirmed that it does by testing (hence the corresponding improvements
to one of the division tests). But, I don't claim to know exactly how this
code works other than to observe that it is super leet.

Overall, this patch has the effect of killing some code (no more hackish
int-to-double conversions in ArithMod), making some optimization work on
more platforms, and making the compiler less confusing by doing more things
with the same idiom.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::executeEffects):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGSpeculativeJIT.cpp:
(DFG):
(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):
* dfg/DFGSpeculativeJIT.h:
(SpeculativeJIT):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):

LayoutTests:

Reviewed by Mark Hahnenberg.

* fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js:
(myModBy2):
(myModBy1073741824):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153186 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: cti_optimize shouldn't allow GCs to get in the way of it seeing the state...
oliver@apple.com [Thu, 25 Jul 2013 04:01:09 +0000 (04:01 +0000)]
fourthTier: cti_optimize shouldn't allow GCs to get in the way of it seeing the state of its CodeBlock
https://bugs.webkit.org/show_bug.cgi?id=116748

Reviewed by Geoffrey Garen.

This fixes the following race: an optimized version of our code block could be installed
by the GC just as we return from completeAllReadyPlansForVM(), leading us to believe
that the code block isn't ready yet even though it is. Currently this triggers a
RELEASE_ASSERT. We could remove that assertion, but then this case would lead to the
code in question entering into optimizeAfterWarmUp mode. That seems pretty wasteful.

Fix the bug, and hopefully close the door on these bugs for a while, by wrapping
cti_optimize in a DeferGC. There is little downside to doing so since the only
"allocations" in cti_optimize are the ones where we inform the GC about extra memory
usage.

I had a more comprehensive solution (see the bug, "work in progress" patch) but that
one involved adding *more* raciness to cti_optimize. I decided that was a less good
approach once I came to appreciate the simplicity of just using DeferGC.

* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153185 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support ArithDiv
oliver@apple.com [Thu, 25 Jul 2013 04:01:08 +0000 (04:01 +0000)]
fourthTier: FTL should support ArithDiv
https://bugs.webkit.org/show_bug.cgi?id=116771

Reviewed by Oliver Hunt.

* ftl/FTLAbbreviations.h:
(JSC::FTL::buildDiv):
(JSC::FTL::buildRem):
(JSC::FTL::buildFDiv):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLCommonValues.cpp:
(JSC::FTL::CommonValues::CommonValues):
* ftl/FTLCommonValues.h:
(CommonValues):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileArithMul):
(JSC::FTL::LowerDFGToLLVM::compileArithDiv):
(LowerDFGToLLVM):
* ftl/FTLOutput.h:
(JSC::FTL::Output::div):
(JSC::FTL::Output::rem):
(JSC::FTL::Output::doubleDiv):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153184 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Remove Interpreter::retrieveLastCaller().
oliver@apple.com [Thu, 25 Jul 2013 04:01:06 +0000 (04:01 +0000)]
fourthTier: Remove Interpreter::retrieveLastCaller().

This merge is complicated by the trunk js stack reporting logic.

Remove Interpreter::retrieveLastCaller().
https://bugs.webkit.org/show_bug.cgi?id=116753.

Reviewed by Geoffrey Garen.

This is part of the refactoring effort to get rid of functions walking
the JS stack in their own way.

../JavaScriptCore:

* API/JSContextRef.cpp:
(JSContextCreateBacktrace):
* interpreter/CallFrame.cpp:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::Interpreter):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::addStackTraceIfNecessary):
* interpreter/Interpreter.h:
(StackFrame):
(JSC::StackFrame::StackFrame):
(Interpreter):
* jsc.cpp:
(functionJSCStack):
* profiler/ProfileGenerator.cpp:
(JSC::ProfileGenerator::addParentForConsoleStart):

../WebCore:

No new tests.

* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::send):
* bindings/js/ScriptCallStackFactory.cpp:
(WebCore::createScriptCallStack):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153183 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL boolify should support ObjectOrOtherUse
oliver@apple.com [Thu, 25 Jul 2013 04:01:03 +0000 (04:01 +0000)]
fourthTier: FTL boolify should support ObjectOrOtherUse
https://bugs.webkit.org/show_bug.cgi?id=116741

Reviewed by Geoffrey Garen.

Just reusing what was already there in equalNullOrUndefined(). Note that we will
sometimes generate some redundant IR - like having some spurious bitNot's in
places - but it's safe to assume that LLVM will simplify those, and that it won't
be the longest pole in the tent for compile times.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
(JSC::FTL::LowerDFGToLLVM::boolify):
(JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153182 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: FTL should support LogicalNot and Branch on Int32 and Number
oliver@apple.com [Thu, 25 Jul 2013 04:01:02 +0000 (04:01 +0000)]
fourthTier: FTL should support LogicalNot and Branch on Int32 and Number
https://bugs.webkit.org/show_bug.cgi?id=116739

Reviewed by Gavin Barraclough.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileLogicalNot):
(JSC::FTL::LowerDFGToLLVM::compileBranch):
(JSC::FTL::LowerDFGToLLVM::boolify):
(LowerDFGToLLVM):
* ftl/FTLOutput.h:
(JSC::FTL::Output::isZero32):
(JSC::FTL::Output::notZero32):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153181 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: add heuristics to reduce the likelihood of a trivially inlineable functio...
oliver@apple.com [Thu, 25 Jul 2013 04:01:00 +0000 (04:01 +0000)]
fourthTier: add heuristics to reduce the likelihood of a trivially inlineable function being independently compiled by the concurrent JIT
https://bugs.webkit.org/show_bug.cgi?id=116557

Reviewed by Geoffrey Garen.

This introduces a fairly comprehensive mechanism for preventing trivially inlineable
functions from being compiled independently of all of the things into which they end
up being inlined.

The trick is CodeBlock::m_shouldAlwaysBeInlined, or SABI for short (that's what the
debug logging calls it). A SABI function is one that we currently believe should
never be DFG optimized because it should always be inlined into the functions that
call it. SABI follows "innocent until proven guilty": all functions start out SABI
and have SABI set to false if we see proof that that function may be called in some
possibly non-inlineable way. So long as a function is SABI, it will not tier up to
the DFG: cti_optimize will perpetually postpone its optimization. Because SABI has
such a severe effect, we make the burden of proof of guilt quite low. SABI gets
cleared if any of the following happen:

- You get called from native code (either through CallData or CachedCall).

- You get called from an eval, since eval code takes a long time to get DFG
  optimized.

- You get called from global code, since often global code doesn't tier-up since
  it's run-once.

- You get called recursively, where recursion is detected by a stack walk of depth
  Options::maximumInliningDepth().

- You get called through an unlinked virtual call.

- You get called from DFG code, since if the caller was already DFG optimized and
  didn't inline you then obviously, you might not get inlined.

- You've tiered up to the baseline JIT and you get called from the interpreter.
  The idea here is that this kind of ensures that you stay SABI only if you're
  called no more frequently than any of your callers.

- You get called from a code block that isn't a DFG candidate.

- You aren't an inlining candidate.

Most of the heuristics for SABI are in CodeBlock::noticeIncomingCall().

This is neutral on SunSpider and V8Spider, and appears to be a slight speed-up on
V8v7, which was previously adversely affected by concurrent compilation. I also
confirmed that for example on V8/richards, it dramatically reduces the number of
code blocks that get DFG compiled. It is a speed-up on those V8v7 benchmarks that
saw regressions from concurrent compilation.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpAssumingJITType):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::linkIncomingCall):
(JSC):
(JSC::CodeBlock::noticeIncomingCall):
* bytecode/CodeBlock.h:
(CodeBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::mightInlineFunction):
(DFG):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThread):
* dfg/DFGRepatch.cpp:
(JSC::DFG::dfgLinkFor):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
(JSC::JIT::linkFor):
* jit/JIT.h:
(JIT):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
(JSC::lazyLinkFor):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153180 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: rationalize DFG::CapabilityLevel and DFGCapabilities.[h|cpp]
oliver@apple.com [Thu, 25 Jul 2013 04:00:58 +0000 (04:00 +0000)]
fourthTier: rationalize DFG::CapabilityLevel and DFGCapabilities.[h|cpp]
https://bugs.webkit.org/show_bug.cgi?id=116696

Reviewed by Sam Weinig.

Make it so that all capability calculation is funneled through one function, which tells
you everything you wanted to know: can it be inlined, and can it be compiled.

This work will help with https://bugs.webkit.org/show_bug.cgi?id=116557, since now the
JIT has a fairly authoritative answer to the "can it be inlined" question.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::ProgramCodeBlock::capabilityLevelInternal):
(JSC::EvalCodeBlock::capabilityLevelInternal):
(JSC::FunctionCodeBlock::capabilityLevelInternal):
* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::capabilityLevel):
(JSC::CodeBlock::capabilityLevelState):
(ProgramCodeBlock):
(EvalCodeBlock):
(FunctionCodeBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::debugFail):
(DFG):
(JSC::DFG::canInlineResolveOperations):
(JSC::DFG::capabilityLevel):
* dfg/DFGCapabilities.h:
(DFG):
(JSC::DFG::capabilityLevel):
(JSC::DFG::evalCapabilityLevel):
(JSC::DFG::programCapabilityLevel):
(JSC::DFG::functionForCallCapabilityLevel):
(JSC::DFG::functionForConstructCapabilityLevel):
(JSC::DFG::canInlineFunctionForCall):
(JSC::DFG::canInlineFunctionForClosureCall):
(JSC::DFG::canInlineFunctionForConstruct):
* dfg/DFGCommon.h:
(JSC::DFG::canCompile):
(DFG):
(JSC::DFG::canInline):
(JSC::DFG::leastUpperBound):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
* tools/CodeProfile.cpp:
(JSC::CodeProfile::sample):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153179 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Reindent CodeBlock.h to aid merging
oliver@apple.com [Thu, 25 Jul 2013 04:00:56 +0000 (04:00 +0000)]
fourthTier: Reindent CodeBlock.h to aid merging

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153178 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Rename getJITCode and getJITType to jitCode and jitType.
oliver@apple.com [Thu, 25 Jul 2013 04:00:54 +0000 (04:00 +0000)]
fourthTier: Rename getJITCode and getJITType to jitCode and jitType.

Rubber stampted by Mark Hahnenberg.

* assembler/RepatchBuffer.h:
(JSC::RepatchBuffer::RepatchBuffer):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dump):
(JSC::CodeBlock::visitAggregate):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::resetStubInternal):
(JSC::CodeBlock::stronglyVisitWeakReferences):
(JSC::CodeBlock::baselineVersion):
(JSC::CodeBlock::hasOptimizedReplacement):
(JSC::CodeBlock::bytecodeOffset):
(JSC::CodeBlock::codeOriginForReturn):
(JSC::ProgramCodeBlock::compileOptimized):
(JSC::EvalCodeBlock::compileOptimized):
(JSC::FunctionCodeBlock::compileOptimized):
(JSC::ProgramCodeBlock::jettison):
(JSC::EvalCodeBlock::jettison):
(JSC::FunctionCodeBlock::jettison):
(JSC::ProgramCodeBlock::jitCompileImpl):
(JSC::EvalCodeBlock::jitCompileImpl):
(JSC::FunctionCodeBlock::jitCompileImpl):
(JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult):
(JSC::CodeBlock::adjustedExitCountThreshold):
(JSC::CodeBlock::tallyFrequentExitSites):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::getCallLinkInfo):
(JSC::CodeBlock::jitCode):
(JSC::CodeBlock::jitCodeWithArityCheck):
(JSC::CodeBlock::jitType):
(JSC::CodeBlock::hasBaselineJITProfiling):
(JSC::CodeBlock::jitCompile):
(JSC::CodeBlock::addFrequentExitSite):
(JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
(JSC::ExecState::isInlineCallFrame):
* dfg/DFGAssemblyHelpers.cpp:
(JSC::DFG::AssemblyHelpers::decodedCodeMapFor):
* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::AssemblyHelpers):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::codeLocationForRepatch):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::adjustAndJumpToTarget):
* dfg/DFGOperations.cpp:
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStream::reconstruct):
* ftl/FTLOSRExit.cpp:
(JSC::FTL::OSRExit::codeLocationForRepatch):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileFTLOSRExit):
* heap/DFGCodeBlocks.cpp:
(JSC::DFGCodeBlocks::~DFGCodeBlocks):
(JSC::DFGCodeBlocks::jettison):
(JSC::DFGCodeBlocks::clearMarks):
(JSC::DFGCodeBlocks::deleteUnmarkedJettisonedCodeBlocks):
(JSC::DFGCodeBlocks::traceMarkedCodeBlocks):
* interpreter/Interpreter.cpp:
(JSC::getLineNumberForCallFrame):
(JSC::getCallerInfo):
* jit/JITDriver.h:
(JSC::jitCompileIfAppropriateImpl):
(JSC::jitCompileFunctionIfAppropriateImpl):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::entryOSR):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Executable.cpp:
(JSC::jettisonCodeBlock):
(JSC::EvalExecutable::compileOptimized):
(JSC::EvalExecutable::jettisonOptimizedCode):
(JSC::ProgramExecutable::compileOptimized):
(JSC::ProgramExecutable::jettisonOptimizedCode):
(JSC::FunctionExecutable::baselineCodeBlockFor):
(JSC::FunctionExecutable::compileOptimizedForCall):
(JSC::FunctionExecutable::compileOptimizedForConstruct):
(JSC::FunctionExecutable::jettisonOptimizedCodeForCall):
(JSC::FunctionExecutable::jettisonOptimizedCodeForConstruct):
* tools/CodeProfile.cpp:
(JSC::CodeProfile::sample):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153177 268f45cc-cd09-0410-ab3c-d52691b4dbfc

7 years agofourthTier: Race between LLInt->Baseline tier-up and DFG reading Baseline profiling...
oliver@apple.com [Thu, 25 Jul 2013 04:00:51 +0000 (04:00 +0000)]
fourthTier: Race between LLInt->Baseline tier-up and DFG reading Baseline profiling data
https://bugs.webkit.org/show_bug.cgi?id=116633

Reviewed by Mark Hahnenberg.

Previously we would check if we had Baseline JIT profiling data by seeing if the
appropriate vector was non-empty. This is horrible if we're doing LLInt->Baseline
tier-up at the same time. This will happen for code we are inlining, if we're
deciding to inline it before the LLInt->Baseline tier-up happened for that code.

This changes things to take advantage of the fact that the very last thing that
LLInt->Baseline tier-up will do (in JITDriver.h) is setJITCode(). We now precede
the actual work in setJITCode() with a store-store fence to ensure that all
stores to modify the CodeBlock happen before setting the JITCode, and we modify
CodeBlock::getJITType() to use load-load fences to ensure that if you see
JITCode::BaselineJIT then you will also see all of those vectors. Then this
changes all of the code that scrapes Baseline JIT profiles to check if
getJITType() returns JITCode::BaselineJIT instead of checking vector sizes.

The outcome is that for the non-racy cases we behave as we did before (we fall
back on LLInt profiling if the tier-up hasn't happened) and for racy cases we
use LLInt profiling conservatively.

Note that for some (but not all!) of the cases where we scrape Baseline JIT
profiling, we would have anyway been holding the CodeBlock::m_lock so we can also
fix those cases by just having setJITCode graph that lock. This patch does that
also, mainly because although we only call setJITCode() from the main thread, in
general it's dangerous to have a pointer to a ref-counted object being modified
in a racy way. So, this patch just does the most conservative thing possible that
does we can afford to do.

* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::computeFor):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::setJITCode):
(JSC::CodeBlock::getJITType):
(JSC::CodeBlock::hasBaselineJITProfiling):
(JSC::CodeBlock::likelyToTakeSlowCase):
(JSC::CodeBlock::couldTakeSlowCase):
(JSC::CodeBlock::likelyToTakeSpecialFastCase):
(JSC::CodeBlock::couldTakeSpecialFastCase):
(JSC::CodeBlock::likelyToTakeDeepestSlowCase):
(JSC::CodeBlock::likelyToTakeAnySlowCase):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeFor):
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFor):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153176 268f45cc-cd09-0410-ab3c-d52691b4dbfc