Changeset 146669 in webkit


Ignore:
Timestamp:
Mar 22, 2013 4:00:57 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

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.

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/DFGOSRExit.cpp:

(JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):

  • dfg/DFGOSRExit.h:

(JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
(OSRExit):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/Options.h:

(JSC):

Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r146653 r146669  
     12013-03-21  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Fix some minor issues in the DFG's profiling of heap accesses
     4        https://bugs.webkit.org/show_bug.cgi?id=113010
     5
     6        Reviewed by Goeffrey Garen.
     7       
     8        1) If a CodeBlock gets jettisoned by GC, we should count the exit sites.
     9
     10        2) If a CodeBlock clears a structure stub during GC, it should record this, and
     11        the DFG should prefer to not inline that access (i.e. treat it as if it had an
     12        exit site).
     13
     14        3) If a PutById was seen by the baseline JIT, and the JIT attempted to cache it,
     15        but it chose not to, then assume that it will take slow path.
     16
     17        4) If we frequently exited because of a structure check on a weak constant,
     18        don't try to inline that access in the future.
     19
     20        5) Treat all exits that were counted as being frequent.
     21       
     22        81% speed-up on Octane/gbemu. Small speed-ups elsewhere, and no regressions.
     23
     24        * bytecode/CodeBlock.cpp:
     25        (JSC::CodeBlock::finalizeUnconditionally):
     26        (JSC):
     27        (JSC::CodeBlock::resetStubDuringGCInternal):
     28        (JSC::CodeBlock::reoptimize):
     29        (JSC::CodeBlock::jettison):
     30        (JSC::ProgramCodeBlock::jettisonImpl):
     31        (JSC::EvalCodeBlock::jettisonImpl):
     32        (JSC::FunctionCodeBlock::jettisonImpl):
     33        (JSC::CodeBlock::tallyFrequentExitSites):
     34        * bytecode/CodeBlock.h:
     35        (CodeBlock):
     36        (JSC::CodeBlock::tallyFrequentExitSites):
     37        (ProgramCodeBlock):
     38        (EvalCodeBlock):
     39        (FunctionCodeBlock):
     40        * bytecode/GetByIdStatus.cpp:
     41        (JSC::GetByIdStatus::computeFor):
     42        * bytecode/PutByIdStatus.cpp:
     43        (JSC::PutByIdStatus::computeFor):
     44        * bytecode/StructureStubInfo.h:
     45        (JSC::StructureStubInfo::StructureStubInfo):
     46        (StructureStubInfo):
     47        * dfg/DFGByteCodeParser.cpp:
     48        (JSC::DFG::ByteCodeParser::handleGetById):
     49        (JSC::DFG::ByteCodeParser::parseBlock):
     50        * dfg/DFGOSRExit.cpp:
     51        (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
     52        * dfg/DFGOSRExit.h:
     53        (JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
     54        (OSRExit):
     55        * jit/JITStubs.cpp:
     56        (JSC::DEFINE_STUB_FUNCTION):
     57        * runtime/Options.h:
     58        (JSC):
     59
    1602013-03-22  Filip Pizlo  <fpizlo@apple.com>
    261
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r146552 r146669  
    23392339            dataLog(*this, " has dead weak references, jettisoning during GC.\n");
    23402340
    2341         // Make sure that the baseline JIT knows that it should re-warm-up before
    2342         // optimizing.
    2343         alternative()->optimizeAfterWarmUp();
    2344        
    23452341        if (DFG::shouldShowDisassembly()) {
    23462342            dataLog(*this, " will be jettisoned because of the following dead references:\n");
     
    24282424                continue;
    24292425           
    2430             resetStubInternal(repatchBuffer, stubInfo);
     2426            resetStubDuringGCInternal(repatchBuffer, stubInfo);
    24312427        }
    24322428    }
     
    24652461   
    24662462    stubInfo.reset();
     2463}
     2464
     2465void CodeBlock::resetStubDuringGCInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
     2466{
     2467    resetStubInternal(repatchBuffer, stubInfo);
     2468    stubInfo.resetByGC = true;
    24672469}
    24682470#endif
     
    28432845    ASSERT(replacement() != this);
    28442846    ASSERT(replacement()->alternative() == this);
    2845     replacement()->tallyFrequentExitSites();
    28462847    if (DFG::shouldShowDisassembly())
    28472848        dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
    28482849    replacement()->jettison();
    28492850    countReoptimization();
    2850     optimizeAfterWarmUp();
    28512851}
    28522852
     
    29072907}
    29082908
    2909 void ProgramCodeBlock::jettison()
     2909void CodeBlock::jettison()
    29102910{
    29112911    ASSERT(JITCode::isOptimizingJIT(getJITType()));
    29122912    ASSERT(this == replacement());
     2913    alternative()->optimizeAfterWarmUp();
     2914    tallyFrequentExitSites();
    29132915    if (DFG::shouldShowDisassembly())
    29142916        dataLog("Jettisoning ", *this, ".\n");
     2917    jettisonImpl();
     2918}
     2919
     2920void ProgramCodeBlock::jettisonImpl()
     2921{
    29152922    static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
    29162923}
    29172924
    2918 void EvalCodeBlock::jettison()
    2919 {
    2920     ASSERT(JITCode::isOptimizingJIT(getJITType()));
    2921     ASSERT(this == replacement());
    2922     if (DFG::shouldShowDisassembly())
    2923         dataLog("Jettisoning ", *this, ".\n");
     2925void EvalCodeBlock::jettisonImpl()
     2926{
    29242927    static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
    29252928}
    29262929
    2927 void FunctionCodeBlock::jettison()
    2928 {
    2929     ASSERT(JITCode::isOptimizingJIT(getJITType()));
    2930     ASSERT(this == replacement());
    2931     if (DFG::shouldShowDisassembly())
    2932         dataLog("Jettisoning ", *this, ".\n");
     2930void FunctionCodeBlock::jettisonImpl()
     2931{
    29332932    static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
    29342933}
     
    32733272        DFG::OSRExit& exit = m_dfgData->osrExit[i];
    32743273       
    3275         if (!exit.considerAddingAsFrequentExitSite(this, profiledBlock))
     3274        if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
    32763275            continue;
    32773276       
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r146089 r146669  
    438438        ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
    439439        virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex) = 0;
    440         virtual void jettison() = 0;
     440        void jettison();
    441441        enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully };
    442442        JITCompilationResult jitCompile(ExecState* exec)
     
    10521052#if ENABLE(JIT)
    10531053        virtual bool jitCompileImpl(ExecState*) = 0;
     1054        virtual void jettisonImpl() = 0;
    10541055#endif
    10551056        virtual void visitWeakReferences(SlotVisitor&);
    10561057        virtual void finalizeUnconditionally();
    10571058
    1058     private:
    1059         friend class DFGCodeBlocks;
    1060        
    1061         double optimizationThresholdScalingFactor();
    1062 
    1063 #if ENABLE(JIT)
    1064         ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
    1065 #endif
    1066        
    10671059#if ENABLE(DFG_JIT)
    10681060        void tallyFrequentExitSites();
     
    10701062        void tallyFrequentExitSites() { }
    10711063#endif
     1064
     1065    private:
     1066        friend class DFGCodeBlocks;
     1067       
     1068        double optimizationThresholdScalingFactor();
     1069
     1070#if ENABLE(JIT)
     1071        ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
     1072#endif
     1073       
    10721074#if ENABLE(VALUE_PROFILER)
    10731075        void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
     
    11461148#if ENABLE(JIT)
    11471149        void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
     1150        void resetStubDuringGCInternal(RepatchBuffer&, StructureStubInfo&);
    11481151#endif
    11491152        WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
     
    13211324    protected:
    13221325        virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
    1323         virtual void jettison();
     1326        virtual void jettisonImpl();
    13241327        virtual bool jitCompileImpl(ExecState*);
    13251328        virtual CodeBlock* replacement();
     
    13461349    protected:
    13471350        virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
    1348         virtual void jettison();
     1351        virtual void jettisonImpl();
    13491352        virtual bool jitCompileImpl(ExecState*);
    13501353        virtual CodeBlock* replacement();
     
    13711374    protected:
    13721375        virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
    1373         virtual void jettison();
     1376        virtual void jettisonImpl();
    13741377        virtual bool jitCompileImpl(ExecState*);
    13751378        virtual CodeBlock* replacement();
  • trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp

    r139541 r146669  
    126126        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
    127127   
     128    if (stubInfo.resetByGC)
     129        return GetByIdStatus(TakesSlowPath, true);
     130
    128131    PolymorphicAccessStructureList* list;
    129132    int listSize;
  • trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp

    r146653 r146669  
    9595        return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
    9696   
     97    if (stubInfo.resetByGC)
     98        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
     99
    97100    switch (stubInfo.accessType) {
    98101    case access_unset:
    99         return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
     102        // If the JIT saw it but didn't optimize it, then assume that this takes slow path.
     103        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
    100104       
    101105    case access_put_by_id_replace: {
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h

    r143392 r146669  
    9898        : accessType(access_unset)
    9999        , seen(false)
     100        , resetByGC(false)
    100101    {
    101102    }
     
    201202
    202203    int8_t accessType;
    203     int8_t seen;
     204    bool seen : 1;
     205    bool resetByGC : 1;
    204206
    205207#if ENABLE(DFG_JIT)
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r146548 r146669  
    17091709{
    17101710    if (!getByIdStatus.isSimple()
    1711         || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
     1711        || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
     1712        || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache)) {
    17121713        set(destinationOperand,
    17131714            addToGraph(
     
    26092610            }
    26102611           
    2611             bool hasExitSite = m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache);
     2612            bool hasExitSite =
     2613                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
     2614                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache);
    26122615           
    26132616            if (!hasExitSite && putByIdStatus.isSimpleReplace()) {
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp

    r141069 r146669  
    7373}
    7474
    75 bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
     75bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock)
    7676{
    77     if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
    78         return false;
    79    
    8077    FrequentExitSite exitSite;
    8178   
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExit.h

    r141069 r146669  
    101101    uint32_t m_count;
    102102   
    103     bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
     103    bool considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
    104104    {
    105105        if (!m_count || !exitKindIsCountable(m_kind))
    106106            return false;
    107         return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
     107        return considerAddingAsFrequentExitSiteSlow(profiledCodeBlock);
    108108    }
    109109
     
    119119
    120120private:
    121     bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
     121    bool considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock);
    122122};
    123123
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r146552 r146669  
    14571457   
    14581458    if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
    1459         if (!stubInfo->seenOnce())
    1460             stubInfo->setSeen();
    1461         else
    1462             tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
     1459        stubInfo->setSeen();
     1460        tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
    14631461    }
    14641462   
     
    14831481   
    14841482    if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
    1485         if (!stubInfo->seenOnce())
    1486             stubInfo->setSeen();
    1487         else
    1488             tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
     1483        stubInfo->setSeen();
     1484        tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
    14891485    }
    14901486   
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r142377 r146669  
    112112    v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
    113113    \
    114     v(double, osrExitProminenceForFrequentExitSite, 0.3) \
    115114    v(unsigned, osrExitCountForReoptimization, 100) \
    116115    v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
Note: See TracChangeset for help on using the changeset viewer.