Ignore:
Timestamp:
Oct 11, 2012, 12:36:04 PM (13 years ago)
Author:
[email protected]
Message:

DFG should inline code blocks that use new_array_buffer
https://bugs.webkit.org/show_bug.cgi?id=98996

Reviewed by Geoffrey Garen.

This adds plumbing to drop in constant buffers from the inlinees to the inliner.
It's smart about not duplicating buffers needlessly but doesn't try to completely
hash-cons them, either.

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::numberOfConstantBuffers):
(JSC::CodeBlock::addConstantBuffer):
(JSC::CodeBlock::constantBufferAsVector):
(JSC::CodeBlock::constantBuffer):

  • dfg/DFGAbstractState.cpp:

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

  • dfg/DFGByteCodeParser.cpp:

(ConstantBufferKey):
(JSC::DFG::ConstantBufferKey::ConstantBufferKey):
(JSC::DFG::ConstantBufferKey::operator==):
(JSC::DFG::ConstantBufferKey::hash):
(JSC::DFG::ConstantBufferKey::isHashTableDeletedValue):
(JSC::DFG::ConstantBufferKey::codeBlock):
(JSC::DFG::ConstantBufferKey::index):
(DFG):
(JSC::DFG::ConstantBufferKeyHash::hash):
(JSC::DFG::ConstantBufferKeyHash::equal):
(ConstantBufferKeyHash):
(WTF):
(ByteCodeParser):
(InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):

  • dfg/DFGCapabilities.h:

(JSC::DFG::canInlineOpcode):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.h:

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

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r130826 r131087  
    4141#include <wtf/HashMap.h>
    4242#include <wtf/MathExtras.h>
     43
     44namespace JSC { namespace DFG {
     45
     46class ConstantBufferKey {
     47public:
     48    ConstantBufferKey()
     49        : m_codeBlock(0)
     50        , m_index(0)
     51    {
     52    }
     53   
     54    ConstantBufferKey(WTF::HashTableDeletedValueType)
     55        : m_codeBlock(0)
     56        , m_index(1)
     57    {
     58    }
     59   
     60    ConstantBufferKey(CodeBlock* codeBlock, unsigned index)
     61        : m_codeBlock(codeBlock)
     62        , m_index(index)
     63    {
     64    }
     65   
     66    bool operator==(const ConstantBufferKey& other) const
     67    {
     68        return m_codeBlock == other.m_codeBlock
     69            && m_index == other.m_index;
     70    }
     71   
     72    unsigned hash() const
     73    {
     74        return WTF::PtrHash<CodeBlock*>::hash(m_codeBlock) ^ m_index;
     75    }
     76   
     77    bool isHashTableDeletedValue() const
     78    {
     79        return !m_codeBlock && m_index;
     80    }
     81   
     82    CodeBlock* codeBlock() const { return m_codeBlock; }
     83    unsigned index() const { return m_index; }
     84   
     85private:
     86    CodeBlock* m_codeBlock;
     87    unsigned m_index;
     88};
     89
     90struct ConstantBufferKeyHash {
     91    static unsigned hash(const ConstantBufferKey& key) { return key.hash(); }
     92    static bool equal(const ConstantBufferKey& a, const ConstantBufferKey& b)
     93    {
     94        return a == b;
     95    }
     96   
     97    static const bool safeToCompareToEmptyOrDeleted = true;
     98};
     99
     100} } // namespace JSC::DFG
     101
     102namespace WTF {
     103
     104template<typename T> struct DefaultHash;
     105template<> struct DefaultHash<JSC::DFG::ConstantBufferKey> {
     106    typedef JSC::DFG::ConstantBufferKeyHash Hash;
     107};
     108
     109template<typename T> struct HashTraits;
     110template<> struct HashTraits<JSC::DFG::ConstantBufferKey> : SimpleClassHashTraits<JSC::DFG::ConstantBufferKey> { };
     111
     112} // namespace WTF
    43113
    44114namespace JSC { namespace DFG {
     
    10531123    Vector<PhiStackEntry, 16> m_localPhiStack;
    10541124   
     1125    HashMap<ConstantBufferKey, unsigned> m_constantBufferCache;
     1126   
    10551127    struct InlineStackEntry {
    10561128        ByteCodeParser* m_byteCodeParser;
     
    10711143        Vector<unsigned> m_identifierRemap;
    10721144        Vector<unsigned> m_constantRemap;
     1145        Vector<unsigned> m_constantBufferRemap;
    10731146       
    10741147        // Blocks introduced by this code block, which need successor linking.
     
    18971970            int startConstant = currentInstruction[2].u.operand;
    18981971            int numConstants = currentInstruction[3].u.operand;
    1899             set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(startConstant), OpInfo(numConstants)));
     1972            set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(m_inlineStackTop->m_constantBufferRemap[startConstant]), OpInfo(numConstants)));
    19001973            NEXT_OPCODE(op_new_array_buffer);
    19011974        }
     
    32523325        m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
    32533326        m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
     3327        m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
    32543328
    32553329        for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i) {
     
    32803354        for (unsigned i = 0; i < codeBlock->numberOfGlobalResolveInfos(); ++i)
    32813355            byteCodeParser->m_codeBlock->addGlobalResolveInfo(std::numeric_limits<unsigned>::max());
     3356        for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) {
     3357            // If we inline the same code block multiple times, we don't want to needlessly
     3358            // duplicate its constant buffers.
     3359            HashMap<ConstantBufferKey, unsigned>::iterator iter =
     3360                byteCodeParser->m_constantBufferCache.find(ConstantBufferKey(codeBlock, i));
     3361            if (iter != byteCodeParser->m_constantBufferCache.end()) {
     3362                m_constantBufferRemap[i] = iter->value;
     3363                continue;
     3364            }
     3365            Vector<JSValue>& buffer = codeBlock->constantBufferAsVector(i);
     3366            unsigned newIndex = byteCodeParser->m_codeBlock->addConstantBuffer(buffer);
     3367            m_constantBufferRemap[i] = newIndex;
     3368            byteCodeParser->m_constantBufferCache.add(ConstantBufferKey(codeBlock, i), newIndex);
     3369        }
    32823370       
    32833371        m_callsiteBlockHeadNeedsLinking = true;
     
    32953383        m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
    32963384        m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
     3385        m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
    32973386
    32983387        for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i)
     
    33003389        for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i)
    33013390            m_constantRemap[i] = i + FirstConstantRegisterIndex;
     3391        for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i)
     3392            m_constantBufferRemap[i] = i;
    33023393
    33033394        m_callsiteBlockHeadNeedsLinking = false;
Note: See TracChangeset for help on using the changeset viewer.