Ignore:
Timestamp:
Oct 31, 2011, 4:50:57 PM (14 years ago)
Author:
[email protected]
Message:

DFG OSR exits should add to value profiles
https://bugs.webkit.org/show_bug.cgi?id=71202

Reviewed by Oliver Hunt.

Value profiles now have an extra special slot not used by the old JIT's
profiling, which is reserved for OSR exits.

The DFG's OSR exit code now knows which register, node index, and value
profiling site was responsible for the (possibly flawed) information that
led to the OSR failure. This is somewhat opportunistic and imperfect;
if there's a lot of control flow between the value profiling site and the
OSR failure point, then this mechanism simply gives up. It also gives up
if the OSR failure is caused by either known deficiencies in the DFG
(like that we always assume that the index in a strict charCodeAt access
is within bounds) or where the OSR failure would be catalogues and
profiled through other means (like slow case counters).

This patch also adds the notion of a JSValueRegs, which is either a
single register in JSVALUE64 or a pair in JSVALUE32_64. We should
probably move the 32_64 DFG towards using this, since it often makes it
easier to share code between 64 and 32_64.

Also fixed a number of pathologies that this uncovered. op_method_check
didn't have a value profiling site on the slow path. GetById should not
always force OSR exit if it never executed in the old JIT; we may be
able to infer its type if it's a array or string length get. Finally,
these changes benefit from a slight tweak to optimization delay
heuristics (profile fullness is now 0.35 instead of 0.25).

3.8% speed-up on Kraken, mostly due to ~35% on both stanford-crypto-aes
and imaging-darkroom.

  • bytecode/ValueProfile.cpp:

(JSC::ValueProfile::computeStatistics):
(JSC::ValueProfile::computeUpdatedPrediction):

  • bytecode/ValueProfile.h:

(JSC::ValueProfile::ValueProfile):
(JSC::ValueProfile::specFailBucket):
(JSC::ValueProfile::numberOfSamples):
(JSC::ValueProfile::isLive):
(JSC::ValueProfile::numberOfInt32s):
(JSC::ValueProfile::numberOfDoubles):
(JSC::ValueProfile::numberOfCells):
(JSC::ValueProfile::numberOfObjects):
(JSC::ValueProfile::numberOfFinalObjects):
(JSC::ValueProfile::numberOfStrings):
(JSC::ValueProfile::numberOfArrays):
(JSC::ValueProfile::numberOfBooleans):
(JSC::ValueProfile::dump):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
(JSC::DFG::ByteCodeParser::getPrediction):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGGPRInfo.h:

(JSC::DFG::JSValueRegs::JSValueRegs):
(JSC::DFG::JSValueRegs::operator!):
(JSC::DFG::JSValueRegs::gpr):
(JSC::DFG::JSValueSource::JSValueSource):
(JSC::DFG::JSValueSource::unboxedCell):
(JSC::DFG::JSValueSource::operator!):
(JSC::DFG::JSValueSource::isAddress):
(JSC::DFG::JSValueSource::offset):
(JSC::DFG::JSValueSource::base):
(JSC::DFG::JSValueSource::gpr):
(JSC::DFG::JSValueSource::asAddress):
(JSC::DFG::JSValueSource::notAddress):
(JSC::DFG::JSValueRegs::tagGPR):
(JSC::DFG::JSValueRegs::payloadGPR):
(JSC::DFG::JSValueSource::tagGPR):
(JSC::DFG::JSValueSource::payloadGPR):
(JSC::DFG::JSValueSource::hasKnownTag):
(JSC::DFG::JSValueSource::tag):

  • dfg/DFGGenerationInfo.h:

(JSC::DFG::GenerationInfo::jsValueRegs):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::valueProfileFor):

  • dfg/DFGJITCodeGenerator.h:

(JSC::JSValueOperand::jsValueRegs):

  • dfg/DFGJITCompiler.cpp:

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

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::valueProfileFor):

  • dfg/DFGJITCompiler32_64.cpp:

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

  • dfg/DFGPropagator.cpp:

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

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::OSRExit::OSRExit):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
(JSC::DFG::SpeculativeJIT::compilePutByValForByteArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnByteArray):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::speculationCheck):
(JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(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::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emitSlow_op_method_check):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emitSlow_op_method_check):

  • runtime/Heuristics.cpp:

(JSC::Heuristics::initializeHeuristics):

  • runtime/JSValue.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGGPRInfo.h

    r95902 r98912  
    3737#define InvalidGPRReg ((GPRReg)-1)
    3838
     39#if USE(JSVALUE64)
     40class JSValueRegs {
     41public:
     42    JSValueRegs()
     43        : m_gpr(InvalidGPRReg)
     44    {
     45    }
     46   
     47    explicit JSValueRegs(GPRReg gpr)
     48        : m_gpr(gpr)
     49    {
     50    }
     51   
     52    bool operator!() const { return m_gpr == InvalidGPRReg; }
     53   
     54    GPRReg gpr() const { return m_gpr; }
     55   
     56private:
     57    GPRReg m_gpr;
     58};
     59
     60class JSValueSource {
     61public:
     62    JSValueSource()
     63        : m_offset(notAddress())
     64        , m_base(InvalidGPRReg)
     65    {
     66    }
     67   
     68    JSValueSource(JSValueRegs regs)
     69        : m_offset(notAddress())
     70        , m_base(regs.gpr())
     71    {
     72    }
     73   
     74    explicit JSValueSource(GPRReg gpr)
     75        : m_offset(notAddress())
     76        , m_base(gpr)
     77    {
     78    }
     79   
     80    JSValueSource(MacroAssembler::Address address)
     81        : m_offset(address.offset)
     82        , m_base(address.base)
     83    {
     84        ASSERT(m_offset != notAddress());
     85        ASSERT(m_base != InvalidGPRReg);
     86    }
     87   
     88    static JSValueSource unboxedCell(GPRReg payloadGPR)
     89    {
     90        return JSValueSource(payloadGPR);
     91    }
     92   
     93    bool operator!() const { return m_base == InvalidGPRReg; }
     94   
     95    bool isAddress() const { return m_offset != notAddress(); }
     96   
     97    int32_t offset() const
     98    {
     99        ASSERT(isAddress());
     100        return m_offset;
     101    }
     102   
     103    GPRReg base() const
     104    {
     105        ASSERT(isAddress());
     106        return m_base;
     107    }
     108   
     109    GPRReg gpr() const
     110    {
     111        ASSERT(!isAddress());
     112        return m_base;
     113    }
     114   
     115    MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); }
     116   
     117private:
     118    static inline int32_t notAddress() { return 0x80000000; }     
     119         
     120    int32_t m_offset;
     121    GPRReg m_base;
     122};
     123#endif
     124
     125#if USE(JSVALUE32_64)
     126class JSValueRegs {
     127public:
     128    JSValueRegs()
     129        : m_tagGPR(static_cast<int8_t>(InvalidGPRReg))
     130        , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg))
     131    {
     132    }
     133   
     134    JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR)
     135        : m_tagGPR(tagGPR)
     136        , m_payloadGPR(payloadGPR)
     137    {
     138        ASSERT((static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg) == (static_cast<GPRReg>(payloadGPR) == InvalidGPRReg));
     139    }
     140   
     141    bool operator!() const { return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg; }
     142   
     143    GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); }
     144    GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); }
     145
     146private:
     147    int8_t m_tagGPR;
     148    int8_t m_payloadGPR;
     149};
     150
     151class JSValueSource {
     152public:
     153    JSValueSource()
     154        : m_offset(notAddress())
     155        , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg))
     156        , m_payload(static_cast<int8_t>(InvalidGPRReg))
     157        , m_tagType(0)
     158    {
     159    }
     160   
     161    JSValueSource(JSValueRegs regs)
     162        : m_offset(notAddress())
     163        , m_baseOrTag(regs.tagGPR())
     164        , m_payload(regs.payloadGPR())
     165        , m_tagType(0)
     166    {
     167    }
     168   
     169    JSValueSource(GPRReg tagGPR, GPRReg payloadGPR)
     170        : m_offset(notAddress())
     171        , m_baseOrTag(static_cast<int8_t>(tagGPR))
     172        , m_payload(static_cast<int8_t>(payloadGPR))
     173        , m_tagType(0)
     174    {
     175    }
     176   
     177    JSValueSource(MacroAssembler::Address address)
     178        : m_offset(address.offset)
     179        , m_baseOrTag(static_cast<int8_t>(address.base))
     180        , m_payload(static_cast<int8_t>(InvalidGPRReg))
     181        , m_tagType(0)
     182    {
     183        ASSERT(m_offset != notAddress());
     184        ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
     185    }
     186   
     187    static JSValueSource unboxedCell(GPRReg payloadGPR)
     188    {
     189        JSValueSource result;
     190        result.m_offset = notAddress();
     191        result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg);
     192        result.m_payload = static_cast<int8_t>(payloadGPR);
     193        result.m_tagType = static_cast<int8_t>(JSValue::CellTag);
     194        return result;
     195    }
     196   
     197    bool operator!() const { return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg && static_cast<GPRReg>(m_payload) == InvalidGPRReg; }
     198   
     199    bool isAddress() const
     200    {
     201        ASSERT(!!*this);
     202        return m_offset != notAddress();
     203    }
     204   
     205    int32_t offset() const
     206    {
     207        ASSERT(isAddress());
     208        return m_offset;
     209    }
     210   
     211    GPRReg base() const
     212    {
     213        ASSERT(isAddress());
     214        return static_cast<GPRReg>(m_baseOrTag);
     215    }
     216   
     217    GPRReg tagGPR() const
     218    {
     219        ASSERT(!isAddress() && m_baseOrTag != InvalidGPRReg);
     220        return static_cast<GPRReg>(m_baseOrTag);
     221    }
     222   
     223    GPRReg payloadGPR() const
     224    {
     225        ASSERT(!isAddress());
     226        return static_cast<GPRReg>(m_payload);
     227    }
     228   
     229    bool hasKnownTag() const
     230    {
     231        ASSERT(!!*this);
     232        ASSERT(!isAddress());
     233        return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg;
     234    }
     235   
     236    uint32_t tag() const
     237    {
     238        return static_cast<int32_t>(m_tagType);
     239    }
     240   
     241    MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); }
     242   
     243private:
     244    static inline int32_t notAddress() { return 0x80000000; }     
     245         
     246    int32_t m_offset;
     247    int8_t m_baseOrTag;
     248    int8_t m_payload;
     249    int8_t m_tagType; // Contains the low bits of the tag.
     250};
     251#endif
     252
    39253#if CPU(X86)
    40254
Note: See TracChangeset for help on using the changeset viewer.