Title: [262362] trunk/Source/_javascript_Core
Revision
262362
Author
msab...@apple.com
Date
2020-05-31 07:56:06 -0700 (Sun, 31 May 2020)

Log 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:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (262361 => 262362)


--- trunk/Source/_javascript_Core/ChangeLog	2020-05-31 11:57:18 UTC (rev 262361)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-05-31 14:56:06 UTC (rev 262362)
@@ -1,3 +1,49 @@
+2020-05-31  Michael Saboff  <msab...@apple.com>
+
+        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:
+
 2020-05-31  Mark Lam  <mark....@apple.com>
 
         Change JSC::Config to use storage in WTF::Config instead of its own.

Modified: trunk/Source/_javascript_Core/assembler/AssemblerBuffer.cpp (262361 => 262362)


--- trunk/Source/_javascript_Core/assembler/AssemblerBuffer.cpp	2020-05-31 11:57:18 UTC (rev 262361)
+++ trunk/Source/_javascript_Core/assembler/AssemblerBuffer.cpp	2020-05-31 14:56:06 UTC (rev 262362)
@@ -30,4 +30,28 @@
 
 DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AssemblerData);
 
+#if ENABLE(ASSEMBLER)
+
+static ThreadSpecificAssemblerData* threadSpecificAssemblerDataPtr;
+
+ThreadSpecificAssemblerData& threadSpecificAssemblerData()
+{
+    static std::once_flag flag;
+    std::call_once(
+        flag,
+        [] () {
+            threadSpecificAssemblerDataPtr = new ThreadSpecificAssemblerData();
+        });
+    return *threadSpecificAssemblerDataPtr;
+}
+
+void clearAssembleDataThreadSpecificCache()
+{
+    auto& threadSpecific = threadSpecificAssemblerData();
+    if (threadSpecific.isSet())
+        threadSpecific->clear();
+}
+
+#endif // ENABLE(ASSEMBLER)
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/assembler/AssemblerBuffer.h (262361 => 262362)


--- trunk/Source/_javascript_Core/assembler/AssemblerBuffer.h	2020-05-31 11:57:18 UTC (rev 262361)
+++ trunk/Source/_javascript_Core/assembler/AssemblerBuffer.h	2020-05-31 14:56:06 UTC (rev 262362)
@@ -37,10 +37,17 @@
 #include <wtf/PtrTag.h>
 #endif
 #include <wtf/StdLibExtras.h>
+#include <wtf/ThreadSpecific.h>
 #include <wtf/UnalignedAccess.h>
 
 namespace JSC {
+    class AssemblerData;
 
+    typedef ThreadSpecific<AssemblerData, WTF::CanBeGCThread::True> ThreadSpecificAssemblerData;
+
+    JS_EXPORT_PRIVATE ThreadSpecificAssemblerData& threadSpecificAssemblerData();
+    void clearAssembleDataThreadSpecificCache();
+
     class LinkBuffer;
 
     DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AssemblerData);
@@ -99,8 +106,8 @@
                 m_buffer = other.m_buffer;
             m_capacity = other.m_capacity;
 
-            other.m_buffer = nullptr;
-            other.m_capacity = 0;
+            other.m_buffer = other.m_inlineBuffer;
+            other.m_capacity = InlineCapacity;
         }
 
         AssemblerData& operator=(AssemblerData&& other)
@@ -116,17 +123,43 @@
                 m_buffer = other.m_buffer;
             m_capacity = other.m_capacity;
 
-            other.m_buffer = nullptr;
-            other.m_capacity = 0;
+            other.m_buffer = other.m_inlineBuffer;
+            other.m_capacity = InlineCapacity;
             return *this;
         }
 
-        ~AssemblerData()
+        void takeBufferIfLarger(AssemblerData&& other)
         {
+            if (other.isInlineBuffer())
+                return;
+
+            if (m_capacity >= other.m_capacity)
+                return;
+
             if (m_buffer && !isInlineBuffer())
                 AssemblerDataMalloc::free(m_buffer);
+
+            m_buffer = other.m_buffer;
+            m_capacity = other.m_capacity;
+
+            other.m_buffer = other.m_inlineBuffer;
+            other.m_capacity = InlineCapacity;
         }
 
+        ~AssemblerData()
+        {
+            clear();
+        }
+
+        void clear()
+        {
+            if (m_buffer && !isInlineBuffer()) {
+                AssemblerDataMalloc::free(m_buffer);
+                m_capacity = InlineCapacity;
+                m_buffer = m_inlineBuffer;
+            }
+        }
+
         char* buffer() const { return m_buffer; }
 
         unsigned capacity() const { return m_capacity; }
@@ -177,8 +210,16 @@
             : m_storage()
             , m_index(0)
         {
+            auto& threadSpecific = getThreadSpecificAssemblerData();
+            m_storage.takeBufferIfLarger(WTFMove(*threadSpecific));
         }
 
+        ~AssemblerBuffer()
+        {
+            auto& threadSpecific = getThreadSpecificAssemblerData();
+            threadSpecific->takeBufferIfLarger(WTFMove(m_storage));
+        }
+
         bool isAvailable(unsigned space)
         {
             return m_index + space <= m_storage.capacity();
@@ -293,6 +334,18 @@
 
 
     protected:
+        ThreadSpecificAssemblerData& getThreadSpecificAssemblerData()
+        {
+            auto& threadSpecific = threadSpecificAssemblerData();
+
+            if (!threadSpecific.isSet()) {
+                void* ptr = static_cast<AssemblerData*>(threadSpecific);
+                new (ptr) AssemblerData();
+            }
+
+            return threadSpecific;
+        }
+        
         template<typename IntegralType>
         void putIntegral(IntegralType value)
         {

Modified: trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp (262361 => 262362)


--- trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp	2020-05-31 11:57:18 UTC (rev 262361)
+++ trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp	2020-05-31 14:56:06 UTC (rev 262362)
@@ -158,6 +158,7 @@
         
         ASSERT(!m_plan);
         
+        clearAssembleDataThreadSpecificCache();
         m_compilationScope = nullptr;
         m_plan = nullptr;
     }

Modified: trunk/Source/_javascript_Core/jit/JITWorklist.cpp (262361 => 262362)


--- trunk/Source/_javascript_Core/jit/JITWorklist.cpp	2020-05-31 11:57:18 UTC (rev 262361)
+++ trunk/Source/_javascript_Core/jit/JITWorklist.cpp	2020-05-31 14:56:06 UTC (rev 262362)
@@ -146,6 +146,11 @@
         return WorkResult::Continue;
     }
 
+    void threadIsStopping(const AbstractLocker&) final
+    {
+        clearAssembleDataThreadSpecificCache();
+    }
+
     JITWorklist& m_worklist;
     Plans m_myPlans;
 };

Modified: trunk/Source/_javascript_Core/wasm/WasmWorklist.cpp (262361 => 262362)


--- trunk/Source/_javascript_Core/wasm/WasmWorklist.cpp	2020-05-31 11:57:18 UTC (rev 262361)
+++ trunk/Source/_javascript_Core/wasm/WasmWorklist.cpp	2020-05-31 14:56:06 UTC (rev 262362)
@@ -120,6 +120,7 @@
     void threadIsStopping(const AbstractLocker&) final
     {
         clearLLIntThreadSpecificCache();
+        clearAssembleDataThreadSpecificCache();
     }
 
     const char* name() const final
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to