Ignore:
Timestamp:
May 31, 2020, 7:56:06 AM (5 years ago)
Author:
[email protected]
Message:

Consider a Thread Specific Cache for AssemblerBuffers
https://bugs.webkit.org/show_bug.cgi?id=212562

Reviewed by Filip Pizlo.

This patch creates a thread local cache of AssemblerData in the hopes that it will reduce
memory allocation churn. The cache is cleared when a thread is destroyed.
If an AssemblerData is destroyed in another thread, its storage is cached by the
destroying thread.

Made a few changes described below to facilite the swap as well as returning a
clear()'ed AssemblerData back to its original state.

Reviewed by Filip Pizlo.

  • assembler/AssemblerBuffer.cpp:

(JSC::threadSpecificAssemblerData):
(JSC::clearAssembleDataThreadSpecificCache):

  • assembler/AssemblerBuffer.h:

(JSC::AssemblerData::AssemblerData):
(JSC::AssemblerData::operator=):
The copy constructor and assignment operator now perform complete AssemblerBuffer swaps.

(JSC::AssemblerData::takeBufferIfLarger):
A new method that will conditionally copy the enclosed buffer of the argument to "this"
if the argument's buffer is larger than the current buffer of "this".

(JSC::AssemblerData::~AssemblerData):
(JSC::AssemblerData::clear):
The destructor now calls clear which has been changed to reset the buffer to one with
inline capacity.

(JSC::AssemblerBuffer::AssemblerBuffer):
Take the cached out of line buffer if there is one.

(JSC::AssemblerBuffer::~AssemblerBuffer):
Cache the enclosed out of line buffer if it is larger than the currently cached one.

(JSC::AssemblerBuffer::getThreadSpecificAssemblerData):

  • dfg/DFGWorklist.cpp:
  • jit/JITWorklist.cpp:
  • wasm/WasmWorklist.cpp:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/AssemblerBuffer.h

    r254087 r262362  
    3838#endif
    3939#include <wtf/StdLibExtras.h>
     40#include <wtf/ThreadSpecific.h>
    4041#include <wtf/UnalignedAccess.h>
    4142
    4243namespace JSC {
     44    class AssemblerData;
     45
     46    typedef ThreadSpecific<AssemblerData, WTF::CanBeGCThread::True> ThreadSpecificAssemblerData;
     47
     48    JS_EXPORT_PRIVATE ThreadSpecificAssemblerData& threadSpecificAssemblerData();
     49    void clearAssembleDataThreadSpecificCache();
    4350
    4451    class LinkBuffer;
     
    100107            m_capacity = other.m_capacity;
    101108
    102             other.m_buffer = nullptr;
    103             other.m_capacity = 0;
     109            other.m_buffer = other.m_inlineBuffer;
     110            other.m_capacity = InlineCapacity;
    104111        }
    105112
     
    117124            m_capacity = other.m_capacity;
    118125
    119             other.m_buffer = nullptr;
    120             other.m_capacity = 0;
     126            other.m_buffer = other.m_inlineBuffer;
     127            other.m_capacity = InlineCapacity;
    121128            return *this;
    122129        }
    123130
    124         ~AssemblerData()
    125         {
     131        void takeBufferIfLarger(AssemblerData&& other)
     132        {
     133            if (other.isInlineBuffer())
     134                return;
     135
     136            if (m_capacity >= other.m_capacity)
     137                return;
     138
    126139            if (m_buffer && !isInlineBuffer())
    127140                AssemblerDataMalloc::free(m_buffer);
     141
     142            m_buffer = other.m_buffer;
     143            m_capacity = other.m_capacity;
     144
     145            other.m_buffer = other.m_inlineBuffer;
     146            other.m_capacity = InlineCapacity;
     147        }
     148
     149        ~AssemblerData()
     150        {
     151            clear();
     152        }
     153
     154        void clear()
     155        {
     156            if (m_buffer && !isInlineBuffer()) {
     157                AssemblerDataMalloc::free(m_buffer);
     158                m_capacity = InlineCapacity;
     159                m_buffer = m_inlineBuffer;
     160            }
    128161        }
    129162
     
    178211            , m_index(0)
    179212        {
     213            auto& threadSpecific = getThreadSpecificAssemblerData();
     214            m_storage.takeBufferIfLarger(WTFMove(*threadSpecific));
     215        }
     216
     217        ~AssemblerBuffer()
     218        {
     219            auto& threadSpecific = getThreadSpecificAssemblerData();
     220            threadSpecific->takeBufferIfLarger(WTFMove(m_storage));
    180221        }
    181222
     
    294335
    295336    protected:
     337        ThreadSpecificAssemblerData& getThreadSpecificAssemblerData()
     338        {
     339            auto& threadSpecific = threadSpecificAssemblerData();
     340
     341            if (!threadSpecific.isSet()) {
     342                void* ptr = static_cast<AssemblerData*>(threadSpecific);
     343                new (ptr) AssemblerData();
     344            }
     345
     346            return threadSpecific;
     347        }
     348       
    296349        template<typename IntegralType>
    297350        void putIntegral(IntegralType value)
Note: See TracChangeset for help on using the changeset viewer.