Ignore:
Timestamp:
Sep 6, 2011, 2:23:55 AM (14 years ago)
Author:
[email protected]
Message:

JavaScriptCore does not have tiered compilation
https://bugs.webkit.org/show_bug.cgi?id=67176

Reviewed by Gavin Barraclough.

This adds the ability to have multiple CodeBlocks associated with
a particular role in an Executable. These are stored in
descending order of compiler tier. CodeBlocks are optimized when
a counter (m_executeCounter) that is incremented in loops and
epilogues becomes positive. Optimizing means that all calls to
the old CodeBlock are unlinked.

The DFG can now pull in predictions from ValueProfiles, and
propagate them along the graph. To support the new phase while
maintaing some level of abstraction, a DFGDriver was introduced
that encapsulates how to run the DFG compiler.

This is turned off by default because it's not yet a performance
win on all benchmarks. It speeds up crypto and richards by
10% and 6% respectively, but still does not do as good of a job
as it could. Notably, the DFG backend has not changed, and
is largely oblivious to the new information being made available
to it.

When turned off (the default), this patch is performance neutral.

  • CMakeLists.txt:
  • GNUmakefile.am:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
  • JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssemblerX86.h:

(JSC::MacroAssemblerX86::branchAdd32):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::branchAdd32):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::~CodeBlock):
(JSC::CodeBlock::visitAggregate):
(JSC::CallLinkInfo::unlink):
(JSC::CodeBlock::unlinkCalls):
(JSC::CodeBlock::unlinkIncomingCalls):
(JSC::CodeBlock::clearEvalCache):
(JSC::replaceExistingEntries):
(JSC::CodeBlock::copyDataFromAlternative):
(JSC::ProgramCodeBlock::replacement):
(JSC::EvalCodeBlock::replacement):
(JSC::FunctionCodeBlock::replacement):
(JSC::ProgramCodeBlock::compileOptimized):
(JSC::EvalCodeBlock::compileOptimized):
(JSC::FunctionCodeBlock::compileOptimized):

  • bytecode/CodeBlock.h:

(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::ProgramCodeBlock::ProgramCodeBlock):
(JSC::EvalCodeBlock::EvalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):

  • bytecode/ValueProfile.h:

(JSC::ValueProfile::dump):
(JSC::ValueProfile::computeStatistics):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):

  • bytecompiler/BytecodeGenerator.h:
  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::ByteCodeParser):
(JSC::DFG::ByteCodeParser::addCall):
(JSC::DFG::ByteCodeParser::dynamicallyPredict):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::parse):

  • dfg/DFGDriver.cpp: Added.

(JSC::DFG::compile):
(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):

  • dfg/DFGDriver.h: Added.

(JSC::DFG::tryCompile):
(JSC::DFG::tryCompileFunction):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::predictArgumentTypes):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::predict):
(JSC::DFG::Graph::predictGlobalVar):
(JSC::DFG::Graph::isConstant):
(JSC::DFG::Graph::isJSConstant):
(JSC::DFG::Graph::isInt32Constant):
(JSC::DFG::Graph::isDoubleConstant):
(JSC::DFG::Graph::valueOfJSConstant):
(JSC::DFG::Graph::valueOfInt32Constant):
(JSC::DFG::Graph::valueOfDoubleConstant):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::isConstant):
(JSC::DFG::JITCompiler::isJSConstant):
(JSC::DFG::JITCompiler::isInt32Constant):
(JSC::DFG::JITCompiler::isDoubleConstant):
(JSC::DFG::JITCompiler::valueOfJSConstant):
(JSC::DFG::JITCompiler::valueOfInt32Constant):
(JSC::DFG::JITCompiler::valueOfDoubleConstant):

  • dfg/DFGNode.h:

(JSC::DFG::isCellPrediction):
(JSC::DFG::isNumberPrediction):
(JSC::DFG::predictionToString):
(JSC::DFG::mergePrediction):
(JSC::DFG::makePrediction):
(JSC::DFG::Node::valueOfJSConstant):
(JSC::DFG::Node::isInt32Constant):
(JSC::DFG::Node::isDoubleConstant):
(JSC::DFG::Node::valueOfInt32Constant):
(JSC::DFG::Node::valueOfDoubleConstant):
(JSC::DFG::Node::predict):

  • dfg/DFGPropagation.cpp: Added.

(JSC::DFG::Propagator::Propagator):
(JSC::DFG::Propagator::fixpoint):
(JSC::DFG::Propagator::setPrediction):
(JSC::DFG::Propagator::mergePrediction):
(JSC::DFG::Propagator::propagateNode):
(JSC::DFG::Propagator::propagateForward):
(JSC::DFG::Propagator::propagateBackward):
(JSC::DFG::propagate):

  • dfg/DFGPropagation.h: Added.

(JSC::DFG::propagate):

  • dfg/DFGRepatch.cpp:

(JSC::DFG::dfgLinkFor):

  • heap/HandleHeap.h:

(JSC::HandleHeap::Node::Node):

  • jit/JIT.cpp:

(JSC::JIT::emitOptimizationCheck):
(JSC::JIT::emitTimeoutCheck):
(JSC::JIT::privateCompile):
(JSC::JIT::linkFor):

  • jit/JIT.h:

(JSC::JIT::emitOptimizationCheck):

  • jit/JITCall32_64.cpp:

(JSC::JIT::emit_op_ret):
(JSC::JIT::emit_op_ret_object_or_this):

  • jit/JITCode.h:

(JSC::JITCode::JITCode):
(JSC::JITCode::bottomTierJIT):
(JSC::JITCode::topTierJIT):
(JSC::JITCode::nextTierJIT):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_ret):
(JSC::JIT::emit_op_ret_object_or_this):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jit/JITStubs.h:
  • runtime/Executable.cpp:

(JSC::EvalExecutable::compileOptimized):
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileOptimized):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileOptimizedForCall):
(JSC::FunctionExecutable::compileOptimizedForConstruct):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):

  • runtime/Executable.h:

(JSC::EvalExecutable::compile):
(JSC::ProgramExecutable::compile):
(JSC::FunctionExecutable::compileForCall):
(JSC::FunctionExecutable::compileForConstruct):
(JSC::FunctionExecutable::compileOptimizedFor):

  • wtf/Platform.h:
  • wtf/SentinelLinkedList.h:

(WTF::BasicRawSentinelNode::BasicRawSentinelNode):
(WTF::BasicRawSentinelNode::setPrev):
(WTF::BasicRawSentinelNode::setNext):
(WTF::BasicRawSentinelNode::prev):
(WTF::BasicRawSentinelNode::next):
(WTF::BasicRawSentinelNode::isOnList):
(WTF::::remove):
(WTF::::SentinelLinkedList):
(WTF::::begin):
(WTF::::end):
(WTF::::push):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r94364 r94559  
    307307            JSObject* error = 0;
    308308            if (!m_evalCodeBlock)
    309                 error = compileInternal(exec, scopeChainNode);
     309                error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
    310310            ASSERT(!error == !!m_evalCodeBlock);
    311311            return error;
    312312        }
     313       
     314        JSObject* compileOptimized(ExecState*, ScopeChainNode*);
    313315
    314316        EvalCodeBlock& generatedBytecode()
     
    345347        EvalExecutable(ExecState*, const SourceCode&, bool);
    346348
    347         JSObject* compileInternal(ExecState*, ScopeChainNode*);
     349        JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
    348350        virtual void visitChildren(SlotVisitor&);
    349351        void unlinkCalls();
     
    370372            JSObject* error = 0;
    371373            if (!m_programCodeBlock)
    372                 error = compileInternal(exec, scopeChainNode);
     374                error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
    373375            ASSERT(!error == !!m_programCodeBlock);
    374376            return error;
    375377        }
     378
     379        JSObject* compileOptimized(ExecState*, ScopeChainNode*);
    376380
    377381        ProgramCodeBlock& generatedBytecode()
     
    404408        ProgramExecutable(ExecState*, const SourceCode&);
    405409
    406         JSObject* compileInternal(ExecState*, ScopeChainNode*);
     410        JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
    407411        virtual void visitChildren(SlotVisitor&);
    408412        void unlinkCalls();
     
    451455            JSObject* error = 0;
    452456            if (!m_codeBlockForCall)
    453                 error = compileForCallInternal(exec, scopeChainNode, calleeArgsExec);
     457                error = compileForCallInternal(exec, scopeChainNode, calleeArgsExec, JITCode::bottomTierJIT());
    454458            ASSERT(!error == !!m_codeBlockForCall);
    455459            return error;
    456460        }
     461
     462        JSObject* compileOptimizedForCall(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec = 0);
    457463
    458464        bool isGeneratedForCall() const
     
    472478            JSObject* error = 0;
    473479            if (!m_codeBlockForConstruct)
    474                 error = compileForConstructInternal(exec, scopeChainNode);
     480                error = compileForConstructInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
    475481            ASSERT(!error == !!m_codeBlockForConstruct);
    476482            return error;
    477483        }
     484
     485        JSObject* compileOptimizedForConstruct(ExecState*, ScopeChainNode*);
    478486
    479487        bool isGeneratedForConstruct() const
     
    500508            ASSERT(kind == CodeForConstruct);
    501509            return compileForConstruct(exec, scopeChainNode);
     510        }
     511       
     512        JSObject* compileOptimizedFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
     513        {
     514            // compileOptimizedFor should only be called with a callframe set up to call this function,
     515            // since we will make speculative optimizations based on the arguments.
     516            ASSERT(exec->callee());
     517            ASSERT(exec->callee()->inherits(&JSFunction::s_info));
     518            ASSERT(asFunction(exec->callee())->jsExecutable() == this);
     519           
     520            if (kind == CodeForCall)
     521                return compileOptimizedForCall(exec, scopeChainNode, exec);
     522            ASSERT(kind == CodeForConstruct);
     523            return compileOptimizedForConstruct(exec, scopeChainNode);
    502524        }
    503525       
     
    550572        FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
    551573
    552         JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec);
    553         JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
     574        JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec, JITCode::JITType);
     575        JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
    554576       
    555577        static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
Note: See TracChangeset for help on using the changeset viewer.