Ignore:
Timestamp:
Oct 21, 2011, 6:22:46 PM (14 years ago)
Author:
[email protected]
Message:

DFG should have inlining
https://bugs.webkit.org/show_bug.cgi?id=69996

Reviewed by Oliver Hunt.

Implements inlining that's hooked into the bytecode parser. Only
works for calls, for now, though nothing fundamentally prevents us
from inlining constructor calls. 2% overall speed-up on all
benchmarks. 7% speed-up on V8 (around 34% and 27% on deltablue and
richards respectively), neutral on Kraken and SunSpider.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::visitAggregate):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::baselineVersion):
(JSC::CodeBlock::setInstructionCount):
(JSC::CodeBlock::likelyToTakeSlowCase):
(JSC::CodeBlock::couldTakeSlowCase):
(JSC::CodeBlock::likelyToTakeSpecialFastCase):
(JSC::CodeBlock::likelyToTakeDeepestSlowCase):
(JSC::CodeBlock::likelyToTakeAnySlowCase):

  • bytecode/CodeOrigin.h:

(JSC::CodeOrigin::inlineDepthForCallFrame):
(JSC::CodeOrigin::inlineDepth):
(JSC::CodeOrigin::operator==):
(JSC::CodeOrigin::inlineStack):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::generate):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::beginBasicBlock):
(JSC::DFG::AbstractState::execute):
(JSC::DFG::AbstractState::mergeStateAtTail):

  • dfg/DFGBasicBlock.h:

(JSC::DFG::BasicBlock::BasicBlock):
(JSC::DFG::BasicBlock::ensureLocals):
(JSC::DFG::UnlinkedBlock::UnlinkedBlock):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::ByteCodeParser):
(JSC::DFG::ByteCodeParser::getDirect):
(JSC::DFG::ByteCodeParser::get):
(JSC::DFG::ByteCodeParser::setDirect):
(JSC::DFG::ByteCodeParser::set):
(JSC::DFG::ByteCodeParser::getLocal):
(JSC::DFG::ByteCodeParser::getArgument):
(JSC::DFG::ByteCodeParser::flush):
(JSC::DFG::ByteCodeParser::InlineStackEntry::~InlineStackEntry):
(JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::processPhiStack):
(JSC::DFG::ByteCodeParser::linkBlock):
(JSC::DFG::ByteCodeParser::linkBlocks):
(JSC::DFG::ByteCodeParser::handleSuccessor):
(JSC::DFG::ByteCodeParser::determineReachability):
(JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
(JSC::DFG::ByteCodeParser::parse):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::canHandleOpcodes):
(JSC::DFG::canCompileOpcodes):
(JSC::DFG::canInlineOpcodes):

  • dfg/DFGCapabilities.h:

(JSC::DFG::mightCompileEval):
(JSC::DFG::mightCompileProgram):
(JSC::DFG::mightCompileFunctionForCall):
(JSC::DFG::mightCompileFunctionForConstruct):
(JSC::DFG::mightInlineFunctionForCall):
(JSC::DFG::mightInlineFunctionForConstruct):
(JSC::DFG::canInlineOpcode):
(JSC::DFG::canInlineOpcodes):
(JSC::DFG::canInlineFunctionForCall):
(JSC::DFG::canInlineFunctionForConstruct):

  • dfg/DFGGraph.cpp:

(JSC::DFG::printWhiteSpace):
(JSC::DFG::Graph::dumpCodeOrigin):
(JSC::DFG::Graph::dump):

  • dfg/DFGGraph.h:

(JSC::DFG::GetBytecodeBeginForBlock::operator()):
(JSC::DFG::Graph::blockIndexForBytecodeOffset):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::decodedCodeMapFor):
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::debugCall):
(JSC::DFG::JITCompiler::baselineCodeBlockFor):

  • dfg/DFGJITCompiler32_64.cpp:

(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasVariableAccessData):
(JSC::DFG::Node::shouldGenerate):

  • dfg/DFGOperands.h:

(JSC::DFG::Operands::ensureLocals):
(JSC::DFG::Operands::setLocal):
(JSC::DFG::Operands::getLocal):

  • dfg/DFGPropagator.cpp:

(JSC::DFG::Propagator::propagateNodePredictions):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::OSRExit::OSRExit):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::SpeculativeJIT):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • interpreter/CallFrame.cpp:

(JSC::CallFrame::trueCallerFrameSlow):

  • jit/JITCall.cpp:

(JSC::JIT::compileOpCallSlowCase):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/Executable.cpp:

(JSC::FunctionExecutable::baselineCodeBlockFor):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):

  • runtime/Executable.h:

(JSC::FunctionExecutable::profiledCodeBlockFor):
(JSC::FunctionExecutable::parameterCount):

  • runtime/Heuristics.cpp:

(JSC::Heuristics::initializeHeuristics):

  • runtime/Heuristics.h:
  • runtime/JSFunction.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h

    r97675 r98179  
    2727#define CodeOrigin_h
    2828
     29#include "WriteBarrier.h"
    2930#include <wtf/StdLibExtras.h>
     31#include <wtf/Vector.h>
    3032
    3133namespace JSC {
     
    5759   
    5860    bool isSet() const { return bytecodeIndex != std::numeric_limits<uint32_t>::max(); }
     61   
     62    // The inline depth is the depth of the inline stack, so 1 = not inlined,
     63    // 2 = inlined one deep, etc.
     64    unsigned inlineDepth() const;
     65   
     66    static unsigned inlineDepthForCallFrame(InlineCallFrame*);
     67   
     68    bool operator==(const CodeOrigin& other) const;
     69   
     70#ifndef NDEBUG
     71    // Get the inline stack. This is slow, and is intended for debugging only.
     72    Vector<CodeOrigin> inlineStack() const;
     73#endif
    5974};
    6075
    6176struct InlineCallFrame {
    62     ExecutableBase* executable;
     77    WriteBarrier<ExecutableBase> executable;
    6378    unsigned stackOffset;
    6479    unsigned calleeVR;
    6580    CodeOrigin caller;
    66     unsigned numArgumentsIncludingThis;
     81    unsigned numArgumentsIncludingThis : 31;
     82    bool isCall : 1;
    6783};
    6884
     
    7187    unsigned callReturnOffset;
    7288};
     89
     90inline unsigned CodeOrigin::inlineDepthForCallFrame(InlineCallFrame* inlineCallFrame)
     91{
     92    unsigned result = 1;
     93    for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame)
     94        result++;
     95    return result;
     96}
     97
     98inline unsigned CodeOrigin::inlineDepth() const
     99{
     100    return inlineDepthForCallFrame(inlineCallFrame);
     101}
     102   
     103inline bool CodeOrigin::operator==(const CodeOrigin& other) const
     104{
     105    return bytecodeIndex == other.bytecodeIndex
     106        && inlineCallFrame == other.inlineCallFrame;
     107}
     108   
     109#ifndef NDEBUG
     110// Get the inline stack. This is slow, and is intended for debugging only.
     111inline Vector<CodeOrigin> CodeOrigin::inlineStack() const
     112{
     113    Vector<CodeOrigin> result(inlineDepth());
     114    result.last() = *this;
     115    unsigned index = result.size() - 2;
     116    for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame)
     117        result[index--] = current->caller;
     118    return result;
     119}
     120#endif
    73121
    74122inline unsigned getCallReturnOffsetForCodeOrigin(CodeOriginAtCallReturnOffset* data)
Note: See TracChangeset for help on using the changeset viewer.