Changeset 262362 in webkit
- Timestamp:
- May 31, 2020 7:56:06 AM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r262356 r262362 1 2020-05-31 Michael Saboff <msaboff@apple.com> 2 3 Consider a Thread Specific Cache for AssemblerBuffers 4 https://bugs.webkit.org/show_bug.cgi?id=212562 5 6 Reviewed by Filip Pizlo. 7 8 This patch creates a thread local cache of AssemblerData in the hopes that it will reduce 9 memory allocation churn. The cache is cleared when a thread is destroyed. 10 If an AssemblerData is destroyed in another thread, its storage is cached by the 11 destroying thread. 12 13 Made a few changes described below to facilite the swap as well as returning a 14 clear()'ed AssemblerData back to its original state. 15 16 Reviewed by Filip Pizlo. 17 18 * assembler/AssemblerBuffer.cpp: 19 (JSC::threadSpecificAssemblerData): 20 (JSC::clearAssembleDataThreadSpecificCache): 21 * assembler/AssemblerBuffer.h: 22 23 (JSC::AssemblerData::AssemblerData): 24 (JSC::AssemblerData::operator=): 25 The copy constructor and assignment operator now perform complete AssemblerBuffer swaps. 26 27 (JSC::AssemblerData::takeBufferIfLarger): 28 A new method that will conditionally copy the enclosed buffer of the argument to "this" 29 if the argument's buffer is larger than the current buffer of "this". 30 31 (JSC::AssemblerData::~AssemblerData): 32 (JSC::AssemblerData::clear): 33 The destructor now calls clear which has been changed to reset the buffer to one with 34 inline capacity. 35 36 (JSC::AssemblerBuffer::AssemblerBuffer): 37 Take the cached out of line buffer if there is one. 38 39 (JSC::AssemblerBuffer::~AssemblerBuffer): 40 Cache the enclosed out of line buffer if it is larger than the currently cached one. 41 42 (JSC::AssemblerBuffer::getThreadSpecificAssemblerData): 43 * dfg/DFGWorklist.cpp: 44 * jit/JITWorklist.cpp: 45 * wasm/WasmWorklist.cpp: 46 1 47 2020-05-31 Mark Lam <mark.lam@apple.com> 2 48 -
trunk/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp
r261755 r262362 31 31 DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AssemblerData); 32 32 33 #if ENABLE(ASSEMBLER) 34 35 static ThreadSpecificAssemblerData* threadSpecificAssemblerDataPtr; 36 37 ThreadSpecificAssemblerData& threadSpecificAssemblerData() 38 { 39 static std::once_flag flag; 40 std::call_once( 41 flag, 42 [] () { 43 threadSpecificAssemblerDataPtr = new ThreadSpecificAssemblerData(); 44 }); 45 return *threadSpecificAssemblerDataPtr; 46 } 47 48 void clearAssembleDataThreadSpecificCache() 49 { 50 auto& threadSpecific = threadSpecificAssemblerData(); 51 if (threadSpecific.isSet()) 52 threadSpecific->clear(); 53 } 54 55 #endif // ENABLE(ASSEMBLER) 56 33 57 } // namespace JSC -
trunk/Source/JavaScriptCore/assembler/AssemblerBuffer.h
r254087 r262362 38 38 #endif 39 39 #include <wtf/StdLibExtras.h> 40 #include <wtf/ThreadSpecific.h> 40 41 #include <wtf/UnalignedAccess.h> 41 42 42 43 namespace JSC { 44 class AssemblerData; 45 46 typedef ThreadSpecific<AssemblerData, WTF::CanBeGCThread::True> ThreadSpecificAssemblerData; 47 48 JS_EXPORT_PRIVATE ThreadSpecificAssemblerData& threadSpecificAssemblerData(); 49 void clearAssembleDataThreadSpecificCache(); 43 50 44 51 class LinkBuffer; … … 100 107 m_capacity = other.m_capacity; 101 108 102 other.m_buffer = nullptr;103 other.m_capacity = 0;109 other.m_buffer = other.m_inlineBuffer; 110 other.m_capacity = InlineCapacity; 104 111 } 105 112 … … 117 124 m_capacity = other.m_capacity; 118 125 119 other.m_buffer = nullptr;120 other.m_capacity = 0;126 other.m_buffer = other.m_inlineBuffer; 127 other.m_capacity = InlineCapacity; 121 128 return *this; 122 129 } 123 130 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 126 139 if (m_buffer && !isInlineBuffer()) 127 140 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 } 128 161 } 129 162 … … 178 211 , m_index(0) 179 212 { 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)); 180 221 } 181 222 … … 294 335 295 336 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 296 349 template<typename IntegralType> 297 350 void putIntegral(IntegralType value) -
trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp
r261895 r262362 159 159 ASSERT(!m_plan); 160 160 161 clearAssembleDataThreadSpecificCache(); 161 162 m_compilationScope = nullptr; 162 163 m_plan = nullptr; -
trunk/Source/JavaScriptCore/jit/JITWorklist.cpp
r261755 r262362 145 145 m_worklist.m_numAvailableThreads++; 146 146 return WorkResult::Continue; 147 } 148 149 void threadIsStopping(const AbstractLocker&) final 150 { 151 clearAssembleDataThreadSpecificCache(); 147 152 } 148 153 -
trunk/Source/JavaScriptCore/wasm/WasmWorklist.cpp
r261569 r262362 121 121 { 122 122 clearLLIntThreadSpecificCache(); 123 clearAssembleDataThreadSpecificCache(); 123 124 } 124 125
Note: See TracChangeset
for help on using the changeset viewer.