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/bytecode/ValueProfile.h

    r94477 r94559  
    7878        return counts * certainty / numberOfSamples;
    7979    }
    80        
     80   
    8181    unsigned numberOfInt32s() const
    8282    {
     
    142142    {
    143143        return computeProbability(numberOfArrays(), numberOfSamples());
     144    }
     145
     146#ifndef NDEBUG
     147    void dump(FILE* out)
     148    {
     149        fprintf(out,
     150                "samples = %u, int32 = %u, double = %u, cell = %u, array = %u",
     151                numberOfSamples(),
     152                numberOfInt32s(),
     153                numberOfDoubles(),
     154                numberOfCells(),
     155                numberOfArrays());
     156        bool first = true;
     157        for (unsigned i = 0; i < numberOfBuckets; ++i) {
     158            if (!!buckets[i] || !!weakBuckets[i]) {
     159                if (first) {
     160                    fprintf(out, ": ");
     161                    first = false;
     162                } else
     163                    fprintf(out, ", ");
     164            }
     165           
     166            if (!!buckets[i])
     167                fprintf(out, "%s", JSValue::decode(buckets[i]).description());
     168           
     169            if (!!weakBuckets[i])
     170                fprintf(out, "DeadCell");
     171        }
     172    }
     173#endif
     174   
     175    struct Statistics {
     176        unsigned samples;
     177        unsigned int32s;
     178        unsigned doubles;
     179        unsigned cells;
     180        unsigned arrays;
     181    };
     182
     183    // Optimized method for getting all counts at once.
     184    void computeStatistics(JSGlobalData& globalData, Statistics& statistics) const
     185    {
     186        unsigned samples = 0;
     187        unsigned int32s  = 0;
     188        unsigned doubles = 0;
     189        unsigned cells   = 0;
     190        unsigned arrays  = 0;
     191       
     192        for (unsigned i = 0; i < numberOfBuckets; ++i) {
     193            if (!buckets[i]) {
     194                WeakBucket weakBucket = weakBuckets[i];
     195                if (!!weakBucket) {
     196                    samples++;
     197                    cells++;
     198                    if (weakBucket.getClassInfo() == &JSArray::s_info)
     199                        arrays++;
     200                }
     201               
     202                continue;
     203            }
     204           
     205            samples++;
     206           
     207            JSValue value = JSValue::decode(buckets[i]);
     208            if (value.isInt32())
     209                int32s++;
     210            else if (value.isDouble())
     211                doubles++;
     212            else if (value.isCell()) {
     213                cells++;
     214                if (isJSArray(&globalData, value.asCell()))
     215                    arrays++;
     216            }
     217        }
     218       
     219        statistics.samples = samples;
     220        statistics.int32s  = int32s;
     221        statistics.doubles = doubles;
     222        statistics.cells   = cells;
     223        statistics.arrays  = arrays;
    144224    }
    145225   
Note: See TracChangeset for help on using the changeset viewer.