WebKit Bugzilla
Attachment 340986 Details for
Bug 185846
: Get rid of TLCs
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
the patch
blah.patch (text/plain), 62.67 KB, created by
Filip Pizlo
on 2018-05-22 09:32:54 PDT
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2018-05-22 09:32:54 PDT
Size:
62.67 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 232031) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,112 @@ >+2018-05-21 Filip Pizlo <fpizlo@apple.com> >+ >+ Get rid of TLCs >+ https://bugs.webkit.org/show_bug.cgi?id=185846 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This removes support for thread-local caches from the GC in order to speed up allocation a >+ bit. >+ >+ We added TLCs as part of Spectre mitigations, which we have since removed. >+ >+ We will want some kind of TLCs eventually, since they allow us to: >+ >+ - have a global GC, which may be a perf optimization at some point. >+ - allocate objects from JIT threads, which we've been wanting to do for a while. >+ >+ This change keeps the most interesting aspect of TLCs, which is the >+ LocalAllocator/BlockDirectory separation. This means that it ought to be easy to implement >+ TLCs again in the future if we wanted this feature. >+ >+ This change removes the part of TLCs that causes a perf regression, namely that Allocator is >+ an offset that requires a bounds check and lookup that makes the rest of the allocation fast >+ path dependent on the load of the TLC. Now, Allocator is really just a LocalAllocator*, so >+ you can directly use it to allocate. This removes two loads and a check from the allocation >+ fast path. In hindsight, I probably could have made that whole thing more efficient, had I >+ allowed us to have a statically known set of LocalAllocators. This would have removed the >+ bounds check (one load and one branch) and it would have made it possible to CSE the load of >+ the TLC data structure, since that would no longer resize. But that's a harder change that >+ this patch, and we don't need it right now. >+ >+ While reviewing the allocation hot paths, I found that CreateThis had an unnecessary branch >+ to check if the allocator is null. I removed that check. AssemblyHelpers::emitAllocate() does >+ that check already. Previously, the TLC bounds check doubled as this check. >+ >+ This is a 1% speed-up on Octane and a 2.3% speed-up on TailBench. However, the Octane >+ speed-up on my machine includes an 8% regexp speed-up. I've found that sometimes regexp >+ speeds up or slows down by 8% depending on which path I build JSC from. Without that 8%, this >+ is still an Octane speed-up due to 2-4% speed-ups in earley, boyer, raytrace, and splay. >+ >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * bytecode/ObjectAllocationProfileInlines.h: >+ (JSC::ObjectAllocationProfile::initializeProfile): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::compileCreateThis): >+ * ftl/FTLLowerDFGToB3.cpp: >+ (JSC::FTL::DFG::LowerDFGToB3::compileMakeRope): >+ (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): >+ (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl): >+ (JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell): >+ (JSC::FTL::DFG::LowerDFGToB3::allocateObject): >+ (JSC::FTL::DFG::LowerDFGToB3::allocatorForSize): >+ * heap/Allocator.cpp: >+ (JSC::Allocator::cellSize const): >+ * heap/Allocator.h: >+ (JSC::Allocator::Allocator): >+ (JSC::Allocator::localAllocator const): >+ (JSC::Allocator::operator== const): >+ (JSC::Allocator::offset const): Deleted. >+ * heap/AllocatorInlines.h: >+ (JSC::Allocator::allocate const): >+ (JSC::Allocator::tryAllocate const): Deleted. >+ * heap/BlockDirectory.cpp: >+ (JSC::BlockDirectory::BlockDirectory): >+ (JSC::BlockDirectory::~BlockDirectory): >+ * heap/BlockDirectory.h: >+ (JSC::BlockDirectory::allocator const): Deleted. >+ * heap/CompleteSubspace.cpp: >+ (JSC::CompleteSubspace::allocateNonVirtual): >+ (JSC::CompleteSubspace::allocatorForSlow): >+ (JSC::CompleteSubspace::tryAllocateSlow): >+ * heap/CompleteSubspace.h: >+ * heap/Heap.cpp: >+ (JSC::Heap::Heap): >+ * heap/Heap.h: >+ (JSC::Heap::threadLocalCacheLayout): Deleted. >+ * heap/IsoSubspace.cpp: >+ (JSC::IsoSubspace::IsoSubspace): >+ (JSC::IsoSubspace::allocateNonVirtual): >+ * heap/IsoSubspace.h: >+ (JSC::IsoSubspace::allocatorForNonVirtual): >+ * heap/LocalAllocator.cpp: >+ (JSC::LocalAllocator::LocalAllocator): >+ (JSC::LocalAllocator::~LocalAllocator): >+ * heap/LocalAllocator.h: >+ (JSC::LocalAllocator::cellSize const): >+ (JSC::LocalAllocator::tlc const): Deleted. >+ * heap/ThreadLocalCache.cpp: Removed. >+ * heap/ThreadLocalCache.h: Removed. >+ * heap/ThreadLocalCacheInlines.h: Removed. >+ * heap/ThreadLocalCacheLayout.cpp: Removed. >+ * heap/ThreadLocalCacheLayout.h: Removed. >+ * jit/AssemblyHelpers.cpp: >+ (JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator): >+ (JSC::AssemblyHelpers::emitAllocate): >+ (JSC::AssemblyHelpers::emitAllocateVariableSized): >+ * jit/JITOpcodes.cpp: >+ (JSC::JIT::emit_op_create_this): >+ * runtime/JSLock.cpp: >+ (JSC::JSLock::didAcquireLock): >+ * runtime/VM.cpp: >+ (JSC::VM::VM): >+ (JSC::VM::~VM): >+ * runtime/VM.h: >+ * runtime/VMEntryScope.cpp: >+ (JSC::VMEntryScope::~VMEntryScope): >+ * runtime/VMEntryScope.h: >+ > 2018-05-21 Commit Queue <commit-queue@webkit.org> > > Unreviewed, rolling out r231998 and r232017. >Index: Source/JavaScriptCore/Sources.txt >=================================================================== >--- Source/JavaScriptCore/Sources.txt (revision 232021) >+++ Source/JavaScriptCore/Sources.txt (working copy) >@@ -524,8 +524,6 @@ heap/StopIfNecessaryTimer.cpp > heap/Subspace.cpp > heap/SynchronousStopTheWorldMutatorScheduler.cpp > heap/Synchronousness.cpp >-heap/ThreadLocalCache.cpp >-heap/ThreadLocalCacheLayout.cpp > heap/VisitRaceKey.cpp > heap/Weak.cpp > heap/WeakBlock.cpp >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 232021) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -395,12 +395,10 @@ > 0F725CAA1C503DED00AD943A /* B3PureCSE.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F725CA61C503DED00AD943A /* B3PureCSE.h */; }; > 0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */; }; > 0F74B93B1F89614800B935D3 /* PrototypeKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F74B93A1F89614500B935D3 /* PrototypeKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 0F75A05E200D25F60038E2CF /* ThreadLocalCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A055200D25EF0038E2CF /* ThreadLocalCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F75A060200D260B0038E2CF /* LocalAllocatorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A05A200D25F00038E2CF /* LocalAllocatorInlines.h */; }; > 0F75A061200D26180038E2CF /* LocalAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A057200D25F00038E2CF /* LocalAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F75A062200D261D0038E2CF /* AllocatorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A05D200D25F10038E2CF /* AllocatorInlines.h */; }; > 0F75A063200D261F0038E2CF /* Allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A054200D25EF0038E2CF /* Allocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 0F75A064200D26280038E2CF /* ThreadLocalCacheLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A05C200D25F10038E2CF /* ThreadLocalCacheLayout.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F75A0662013E4F10038E2CF /* JITAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F75A0652013E4EF0038E2CF /* JITAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -2449,14 +2447,9 @@ > 0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3FoldPathConstants.h; path = b3/B3FoldPathConstants.h; sourceTree = "<group>"; }; > 0F74B93A1F89614500B935D3 /* PrototypeKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeKey.h; sourceTree = "<group>"; }; > 0F75A054200D25EF0038E2CF /* Allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Allocator.h; sourceTree = "<group>"; }; >- 0F75A055200D25EF0038E2CF /* ThreadLocalCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocalCache.h; sourceTree = "<group>"; }; >- 0F75A056200D25EF0038E2CF /* ThreadLocalCacheInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocalCacheInlines.h; sourceTree = "<group>"; }; > 0F75A057200D25F00038E2CF /* LocalAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalAllocator.h; sourceTree = "<group>"; }; >- 0F75A058200D25F00038E2CF /* ThreadLocalCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadLocalCache.cpp; sourceTree = "<group>"; }; > 0F75A059200D25F00038E2CF /* LocalAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LocalAllocator.cpp; sourceTree = "<group>"; }; > 0F75A05A200D25F00038E2CF /* LocalAllocatorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalAllocatorInlines.h; sourceTree = "<group>"; }; >- 0F75A05B200D25F10038E2CF /* ThreadLocalCacheLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadLocalCacheLayout.cpp; sourceTree = "<group>"; }; >- 0F75A05C200D25F10038E2CF /* ThreadLocalCacheLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocalCacheLayout.h; sourceTree = "<group>"; }; > 0F75A05D200D25F10038E2CF /* AllocatorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllocatorInlines.h; sourceTree = "<group>"; }; > 0F75A0652013E4EF0038E2CF /* JITAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITAllocator.h; sourceTree = "<group>"; }; > 0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = "<group>"; }; >@@ -5775,11 +5768,6 @@ > 0FD79A2C1EBBBDB200DA88D3 /* Synchronousness.h */, > 0F1FB38A1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp */, > 0F1FB38B1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h */, >- 0F75A058200D25F00038E2CF /* ThreadLocalCache.cpp */, >- 0F75A055200D25EF0038E2CF /* ThreadLocalCache.h */, >- 0F75A056200D25EF0038E2CF /* ThreadLocalCacheInlines.h */, >- 0F75A05B200D25F10038E2CF /* ThreadLocalCacheLayout.cpp */, >- 0F75A05C200D25F10038E2CF /* ThreadLocalCacheLayout.h */, > 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */, > 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */, > 0F4D8C721FC7A973001D32AC /* VisitCounter.h */, >@@ -9463,8 +9451,6 @@ > 70ECA6091AFDBEA200449739 /* TemplateObjectDescriptor.h in Headers */, > 0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */, > 0FA2C17C17D7CF84009D015F /* TestRunnerUtils.h in Headers */, >- 0F75A05E200D25F60038E2CF /* ThreadLocalCache.h in Headers */, >- 0F75A064200D26280038E2CF /* ThreadLocalCacheLayout.h in Headers */, > FE3422121D6B81C30032BE88 /* ThrowScope.h in Headers */, > 0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */, > A7386556118697B400540279 /* ThunkGenerators.h in Headers */, >Index: Source/JavaScriptCore/bytecode/ObjectAllocationProfileInlines.h >=================================================================== >--- Source/JavaScriptCore/bytecode/ObjectAllocationProfileInlines.h (revision 232021) >+++ Source/JavaScriptCore/bytecode/ObjectAllocationProfileInlines.h (working copy) >@@ -105,7 +105,7 @@ ALWAYS_INLINE void ObjectAllocationProfi > > // Take advantage of extra inline capacity available in the size class. > if (allocator) { >- size_t slop = (allocator.cellSize(vm.heap) - allocationSize) / sizeof(WriteBarrier<Unknown>); >+ size_t slop = (allocator.cellSize() - allocationSize) / sizeof(WriteBarrier<Unknown>); > inlineCapacity += slop; > if (inlineCapacity > JSFinalObject::maxInlineCapacity()) > inlineCapacity = JSFinalObject::maxInlineCapacity(); >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (revision 232021) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (working copy) >@@ -12207,11 +12207,9 @@ void SpeculativeJIT::compileCreateThis(N > m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfRareData()), rareDataGPR); > slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR)); > m_jit.xorPtr(JITCompiler::TrustedImmPtr(JSFunctionPoison::key()), rareDataGPR); >- m_jit.load32(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR); >+ m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR); > m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR); > >- slowPath.append(m_jit.branch32(MacroAssembler::Equal, allocatorGPR, TrustedImm32(Allocator().offset()))); >- > auto butterfly = TrustedImmPtr(nullptr); > emitAllocateJSObject(resultGPR, JITAllocator::variable(), allocatorGPR, structureGPR, butterfly, scratchGPR, slowPath); > >Index: Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (revision 232021) >+++ Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (working copy) >@@ -6170,7 +6170,7 @@ private: > Allocator allocator = subspaceFor<JSRopeString>(vm())->allocatorForNonVirtual(sizeof(JSRopeString), AllocatorForMode::AllocatorIfExists); > > LValue result = allocateCell( >- m_out.constInt32(allocator.offset()), vm().stringStructure.get(), slowPath); >+ m_out.constIntPtr(allocator.localAllocator()), vm().stringStructure.get(), slowPath); > > m_out.storePtr(m_out.intPtrZero, result, m_heaps.JSString_value); > for (unsigned i = 0; i < numKids; ++i) >@@ -10472,7 +10472,8 @@ private: > m_out.store32(vectorLength, fastButterflyValue, m_heaps.Butterfly_vectorLength); > > LValue fastObjectValue = allocateObject( >- m_out.constInt32(cellAllocator.offset()), structure, fastButterflyValue, slowPath); >+ m_out.constIntPtr(cellAllocator.localAllocator()), structure, fastButterflyValue, >+ slowPath); > > ValueFromBlock fastObject = m_out.anchor(fastObjectValue); > ValueFromBlock fastButterfly = m_out.anchor(fastButterflyValue); >@@ -11474,7 +11475,8 @@ private: > > size_t sizeInBytes = sizeInValues * sizeof(JSValue); > Allocator allocator = vm().jsValueGigacageAuxiliarySpace.allocatorForNonVirtual(sizeInBytes, AllocatorForMode::AllocatorIfExists); >- LValue startOfStorage = allocateHeapCell(m_out.constInt32(allocator.offset()), slowPath); >+ LValue startOfStorage = allocateHeapCell( >+ m_out.constIntPtr(allocator.localAllocator()), slowPath); > ValueFromBlock fastButterfly = m_out.anchor( > m_out.add(m_out.constIntPtr(sizeInBytes + sizeof(IndexingHeader)), startOfStorage)); > m_out.jump(continuation); >@@ -12518,7 +12520,7 @@ private: > { > JITAllocator actualAllocator; > if (allocator->hasInt32()) >- actualAllocator = JITAllocator::constant(Allocator(allocator->asInt32())); >+ actualAllocator = JITAllocator::constant(Allocator(bitwise_cast<LocalAllocator*>(allocator->asIntPtr()))); > else > actualAllocator = JITAllocator::variable(); > >@@ -12536,7 +12538,7 @@ private: > LBasicBlock haveAllocator = m_out.newBlock(); > LBasicBlock lastNext = m_out.insertNewBlocksBefore(haveAllocator); > m_out.branch( >- m_out.notEqual(allocator, m_out.constInt32(Allocator().offset())), >+ m_out.notEqual(allocator, m_out.intPtrZero), > usually(haveAllocator), rarely(slowPath)); > m_out.appendTo(haveAllocator, lastNext); > } >@@ -12666,7 +12668,8 @@ private: > size_t size, StructureType structure, LValue butterfly, LBasicBlock slowPath) > { > Allocator allocator = subspaceFor<ClassType>(vm())->allocatorForNonVirtual(size, AllocatorForMode::AllocatorIfExists); >- return allocateObject(m_out.constInt32(allocator.offset()), structure, butterfly, slowPath); >+ return allocateObject( >+ m_out.constIntPtr(allocator.localAllocator()), structure, butterfly, slowPath); > } > > template<typename ClassType, typename StructureType> >@@ -12691,10 +12694,10 @@ private: > LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation); > m_out.jump(slowPath); > m_out.appendTo(continuation, lastNext); >- return m_out.int32Zero; >+ return m_out.intPtrZero; > } > >- return m_out.constInt32(actualAllocator.offset()); >+ return m_out.constIntPtr(actualAllocator.localAllocator()); > } > > unsigned stepShift = getLSBSet(MarkedSpace::sizeStep); >@@ -12713,7 +12716,7 @@ private: > > m_out.appendTo(continuation, lastNext); > >- return m_out.load32( >+ return m_out.loadPtr( > m_out.baseIndex( > m_heaps.CompleteSubspace_allocatorForSizeStep, > subspace, m_out.sub(sizeClassIndex, m_out.intPtrOne))); >@@ -12755,7 +12758,7 @@ private: > LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath); > > ValueFromBlock fastResult = m_out.anchor(allocateObject( >- m_out.constInt32(allocator.offset()), structure, m_out.intPtrZero, slowPath)); >+ m_out.constIntPtr(allocator.localAllocator()), structure, m_out.intPtrZero, slowPath)); > > m_out.jump(continuation); > >Index: Source/JavaScriptCore/heap/Allocator.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Allocator.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/Allocator.cpp (working copy) >@@ -27,13 +27,13 @@ > #include "Allocator.h" > > #include "Heap.h" >-#include "ThreadLocalCacheLayout.h" >+#include "LocalAllocator.h" > > namespace JSC { > >-unsigned Allocator::cellSize(Heap& heap) const >+unsigned Allocator::cellSize() const > { >- return heap.threadLocalCacheLayout().directory(m_offset)->cellSize(); >+ return m_localAllocator->cellSize(); > } > > } // namespace JSC >Index: Source/JavaScriptCore/heap/Allocator.h >=================================================================== >--- Source/JavaScriptCore/heap/Allocator.h (revision 232021) >+++ Source/JavaScriptCore/heap/Allocator.h (working copy) >@@ -31,35 +31,32 @@ > namespace JSC { > > class GCDeferralContext; >-class Heap; >-class VM; >+class LocalAllocator; >+ >+// This abstracts how we refer to LocalAllocator so that we could eventually support thread-local >+// caches. > > class Allocator { > public: > Allocator() { } > >- explicit Allocator(unsigned offset) >- : m_offset(offset) >+ explicit Allocator(LocalAllocator* localAllocator) >+ : m_localAllocator(localAllocator) > { > } > >- void* allocate(VM&, GCDeferralContext*, AllocationFailureMode) const; >- >- // This version calls FailureFunc if we have a null allocator or if the TLC hasn't been resized >- // to include this allocator. >- template<typename FailureFunc> >- void* tryAllocate(VM&, GCDeferralContext*, AllocationFailureMode, const FailureFunc&) const; >+ void* allocate(GCDeferralContext*, AllocationFailureMode) const; > >- unsigned cellSize(Heap&) const; >+ unsigned cellSize() const; > >- unsigned offset() const { return m_offset; } >+ LocalAllocator* localAllocator() const { return m_localAllocator; } > >- bool operator==(const Allocator& other) const { return m_offset == other.offset(); } >+ bool operator==(const Allocator& other) const { return m_localAllocator == other.localAllocator(); } > bool operator!=(const Allocator& other) const { return !(*this == other); } > explicit operator bool() const { return *this != Allocator(); } > > private: >- unsigned m_offset { UINT_MAX }; >+ LocalAllocator* m_localAllocator { nullptr }; > }; > > } // namespace JSC >Index: Source/JavaScriptCore/heap/AllocatorInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/AllocatorInlines.h (revision 232021) >+++ Source/JavaScriptCore/heap/AllocatorInlines.h (working copy) >@@ -26,28 +26,13 @@ > #pragma once > > #include "Allocator.h" >-#include "ThreadLocalCache.h" >+#include "LocalAllocator.h" > > namespace JSC { > >-inline void* Allocator::allocate(VM& vm, GCDeferralContext* context, AllocationFailureMode mode) const >+inline void* Allocator::allocate(GCDeferralContext* context, AllocationFailureMode mode) const > { >- return ThreadLocalCache::allocator(vm, m_offset).allocate(context, mode); >-} >- >-template<typename FailureFunc> >-void* Allocator::tryAllocate(VM& vm, GCDeferralContext* context, AllocationFailureMode mode, const FailureFunc& failureFunc) const >-{ >- void* result; >- ThreadLocalCache::tryGetAllocator( >- vm, m_offset, >- [&] (LocalAllocator& allocator) { >- result = allocator.allocate(context, mode); >- }, >- [&] () { >- result = failureFunc(); >- }); >- return result; >+ return m_localAllocator->allocate(context, mode); > } > > } // namespace JSC >Index: Source/JavaScriptCore/heap/BlockDirectory.cpp >=================================================================== >--- Source/JavaScriptCore/heap/BlockDirectory.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/BlockDirectory.cpp (working copy) >@@ -33,7 +33,6 @@ > #include "JSCInlines.h" > #include "MarkedBlockInlines.h" > #include "SuperSampler.h" >-#include "ThreadLocalCacheInlines.h" > #include "VM.h" > > namespace JSC { >@@ -42,11 +41,13 @@ BlockDirectory::BlockDirectory(Heap* hea > : m_cellSize(static_cast<unsigned>(cellSize)) > , m_heap(heap) > { >- heap->threadLocalCacheLayout().allocateOffset(this); > } > > BlockDirectory::~BlockDirectory() > { >+ auto locker = holdLock(m_localAllocatorsLock); >+ while (!m_localAllocators.isEmpty()) >+ m_localAllocators.begin()->remove(); > } > > void BlockDirectory::setSubspace(Subspace* subspace) >Index: Source/JavaScriptCore/heap/BlockDirectory.h >=================================================================== >--- Source/JavaScriptCore/heap/BlockDirectory.h (revision 232021) >+++ Source/JavaScriptCore/heap/BlockDirectory.h (working copy) >@@ -26,7 +26,6 @@ > #pragma once > > #include "AllocationFailureMode.h" >-#include "Allocator.h" > #include "CellAttributes.h" > #include "FreeList.h" > #include "LocalAllocator.h" >@@ -44,8 +43,6 @@ class Heap; > class IsoCellSet; > class MarkedSpace; > class LLIntOffsetsExtractor; >-class ThreadLocalCache; >-class ThreadLocalCacheLayout; > > #define FOR_EACH_BLOCK_DIRECTORY_BIT(macro) \ > macro(live, Live) /* The set of block indices that have actual blocks. */\ >@@ -158,8 +155,6 @@ public: > Subspace* subspace() const { return m_subspace; } > MarkedSpace& markedSpace() const; > >- Allocator allocator() const { return Allocator(m_tlcOffset); } >- > void dump(PrintStream&) const; > void dumpBits(PrintStream& = WTF::dataFile()); > >@@ -168,7 +163,6 @@ private: > friend class LocalAllocator; > friend class LocalSideAllocator; > friend class MarkedBlock; >- friend class ThreadLocalCacheLayout; > > MarkedBlock::Handle* findBlockForAllocation(LocalAllocator&); > >@@ -201,7 +195,6 @@ private: > BlockDirectory* m_nextDirectoryInAlignedMemoryAllocator { nullptr }; > > Lock m_localAllocatorsLock; >- size_t m_tlcOffset; > SentinelLinkedList<LocalAllocator, BasicRawSentinelNode<LocalAllocator>> m_localAllocators; > }; > >Index: Source/JavaScriptCore/heap/CompleteSubspace.cpp >=================================================================== >--- Source/JavaScriptCore/heap/CompleteSubspace.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/CompleteSubspace.cpp (working copy) >@@ -34,7 +34,6 @@ > #include "MarkedBlockInlines.h" > #include "PreventCollectionScope.h" > #include "SubspaceInlines.h" >-#include "ThreadLocalCacheInlines.h" > > namespace JSC { > >@@ -60,12 +59,9 @@ void* CompleteSubspace::allocate(VM& vm, > > void* CompleteSubspace::allocateNonVirtual(VM& vm, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode) > { >- Allocator allocator = allocatorForNonVirtual(size, AllocatorForMode::AllocatorIfExists); >- return allocator.tryAllocate( >- vm, deferralContext, failureMode, >- [&] () { >- return allocateSlow(vm, size, deferralContext, failureMode); >- }); >+ if (Allocator allocator = allocatorForNonVirtual(size, AllocatorForMode::AllocatorIfExists)) >+ return allocator.allocate(deferralContext, failureMode); >+ return allocateSlow(vm, size, deferralContext, failureMode); > } > > Allocator CompleteSubspace::allocatorForSlow(size_t size) >@@ -88,28 +84,39 @@ Allocator CompleteSubspace::allocatorFor > return allocator; > > if (false) >- dataLog("Creating marked allocator for ", m_name, ", ", m_attributes, ", ", sizeClass, ".\n"); >+ dataLog("Creating BlockDirectory/LocalAllocator for ", m_name, ", ", m_attributes, ", ", sizeClass, ".\n"); >+ > std::unique_ptr<BlockDirectory> uniqueDirectory = > std::make_unique<BlockDirectory>(m_space.heap(), sizeClass); > BlockDirectory* directory = uniqueDirectory.get(); > m_directories.append(WTFMove(uniqueDirectory)); >+ > directory->setSubspace(this); > m_space.addBlockDirectory(locker, directory); >+ >+ std::unique_ptr<LocalAllocator> uniqueLocalAllocator = >+ std::make_unique<LocalAllocator>(directory); >+ LocalAllocator* localAllocator = uniqueLocalAllocator.get(); >+ m_localAllocators.append(WTFMove(uniqueLocalAllocator)); >+ >+ Allocator allocator(localAllocator); >+ > index = MarkedSpace::sizeClassToIndex(sizeClass); > for (;;) { > if (MarkedSpace::s_sizeClassForSizeStep[index] != sizeClass) > break; > >- m_allocatorForSizeStep[index] = directory->allocator(); >+ m_allocatorForSizeStep[index] = allocator; > > if (!index--) > break; > } >+ > directory->setNextDirectoryInSubspace(m_firstDirectory); > m_alignedMemoryAllocator->registerDirectory(directory); > WTF::storeStoreFence(); > m_firstDirectory = directory; >- return directory->allocator(); >+ return allocator; > } > > void* CompleteSubspace::allocateSlow(VM& vm, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode) >@@ -125,7 +132,7 @@ void* CompleteSubspace::tryAllocateSlow( > sanitizeStackForVM(&vm); > > if (Allocator allocator = allocatorFor(size, AllocatorForMode::EnsureAllocator)) >- return allocator.allocate(vm, deferralContext, AllocationFailureMode::ReturnNull); >+ return allocator.allocate(deferralContext, AllocationFailureMode::ReturnNull); > > if (size <= Options::largeAllocationCutoff() > && size <= MarkedSpace::largeCutoff) { >Index: Source/JavaScriptCore/heap/CompleteSubspace.h >=================================================================== >--- Source/JavaScriptCore/heap/CompleteSubspace.h (revision 232021) >+++ Source/JavaScriptCore/heap/CompleteSubspace.h (working copy) >@@ -58,6 +58,7 @@ private: > > std::array<Allocator, MarkedSpace::numSizeClasses> m_allocatorForSizeStep; > Vector<std::unique_ptr<BlockDirectory>> m_directories; >+ Vector<std::unique_ptr<LocalAllocator>> m_localAllocators; > }; > > ALWAYS_INLINE Allocator CompleteSubspace::allocatorForNonVirtual(size_t size, AllocatorForMode mode) >Index: Source/JavaScriptCore/heap/Heap.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Heap.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/Heap.cpp (working copy) >@@ -68,7 +68,6 @@ > #include "StopIfNecessaryTimer.h" > #include "SweepingScope.h" > #include "SynchronousStopTheWorldMutatorScheduler.h" >-#include "ThreadLocalCacheLayout.h" > #include "TypeProfiler.h" > #include "TypeProfilerLog.h" > #include "UnlinkedCodeBlock.h" >@@ -314,7 +313,6 @@ Heap::Heap(VM* vm, HeapType heapType) > , m_helperClient(&heapHelperPool()) > , m_threadLock(Box<Lock>::create()) > , m_threadCondition(AutomaticThreadCondition::create()) >- , m_threadLocalCacheLayout(std::make_unique<ThreadLocalCacheLayout>()) > { > m_worldState.store(0); > >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 232021) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -84,7 +84,6 @@ class SlotVisitor; > class SpaceTimeMutatorScheduler; > class StopIfNecessaryTimer; > class SweepingScope; >-class ThreadLocalCacheLayout; > class VM; > class WeakGCMapBase; > struct CurrentThreadState; >@@ -381,8 +380,6 @@ public: > template<typename Func> > void forEachSlotVisitor(const Func&); > >- ThreadLocalCacheLayout& threadLocalCacheLayout() { return *m_threadLocalCacheLayout; } >- > Seconds totalGCTime() const { return m_totalGCTime; } > > private: >@@ -731,8 +728,6 @@ private: > > CurrentThreadState* m_currentThreadState { nullptr }; > WTF::Thread* m_currentThread { nullptr }; // It's OK if this becomes a dangling pointer. >- >- std::unique_ptr<ThreadLocalCacheLayout> m_threadLocalCacheLayout; > }; > > } // namespace JSC >Index: Source/JavaScriptCore/heap/IsoSubspace.cpp >=================================================================== >--- Source/JavaScriptCore/heap/IsoSubspace.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/IsoSubspace.cpp (working copy) >@@ -30,7 +30,6 @@ > #include "BlockDirectoryInlines.h" > #include "IsoAlignedMemoryAllocator.h" > #include "LocalAllocatorInlines.h" >-#include "ThreadLocalCacheInlines.h" > > namespace JSC { > >@@ -38,7 +37,7 @@ IsoSubspace::IsoSubspace(CString name, H > : Subspace(name, heap) > , m_size(size) > , m_directory(&heap, WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size)) >- , m_allocator(m_directory.allocator()) >+ , m_localAllocator(&m_directory) > , m_isoAlignedMemoryAllocator(std::make_unique<IsoAlignedMemoryAllocator>()) > { > initialize(heapCellType, m_isoAlignedMemoryAllocator.get()); >@@ -64,10 +63,11 @@ void* IsoSubspace::allocate(VM& vm, size > return allocateNonVirtual(vm, size, deferralContext, failureMode); > } > >-void* IsoSubspace::allocateNonVirtual(VM& vm, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode) >+void* IsoSubspace::allocateNonVirtual(VM&, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode) > { > RELEASE_ASSERT(size == this->size()); >- void* result = m_allocator.allocate(vm, deferralContext, failureMode); >+ Allocator allocator = allocatorForNonVirtual(size, AllocatorForMode::MustAlreadyHaveAllocator); >+ void* result = allocator.allocate(deferralContext, failureMode); > return result; > } > >Index: Source/JavaScriptCore/heap/IsoSubspace.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoSubspace.h (revision 232021) >+++ Source/JavaScriptCore/heap/IsoSubspace.h (working copy) >@@ -56,7 +56,7 @@ private: > > size_t m_size; > BlockDirectory m_directory; >- Allocator m_allocator; >+ LocalAllocator m_localAllocator; > std::unique_ptr<IsoAlignedMemoryAllocator> m_isoAlignedMemoryAllocator; > SentinelLinkedList<IsoCellSet, BasicRawSentinelNode<IsoCellSet>> m_cellSets; > }; >@@ -64,7 +64,7 @@ private: > inline Allocator IsoSubspace::allocatorForNonVirtual(size_t size, AllocatorForMode) > { > RELEASE_ASSERT(size == this->size()); >- return m_allocator; >+ return Allocator(&m_localAllocator); > } > > #define ISO_SUBSPACE_INIT(heap, heapCellType, type) ("Isolated " #type " Space", (heap), (heapCellType), sizeof(type)) >Index: Source/JavaScriptCore/heap/LocalAllocator.cpp >=================================================================== >--- Source/JavaScriptCore/heap/LocalAllocator.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/LocalAllocator.cpp (working copy) >@@ -32,9 +32,8 @@ > > namespace JSC { > >-LocalAllocator::LocalAllocator(ThreadLocalCache* tlc, BlockDirectory* directory) >- : m_tlc(tlc) >- , m_directory(directory) >+LocalAllocator::LocalAllocator(BlockDirectory* directory) >+ : m_directory(directory) > , m_cellSize(directory->m_cellSize) > , m_freeList(m_cellSize) > { >@@ -42,23 +41,6 @@ LocalAllocator::LocalAllocator(ThreadLoc > directory->m_localAllocators.append(this); > } > >-LocalAllocator::LocalAllocator(LocalAllocator&& other) >- : m_tlc(other.m_tlc) >- , m_directory(other.m_directory) >- , m_cellSize(other.m_cellSize) >- , m_freeList(WTFMove(other.m_freeList)) >- , m_currentBlock(other.m_currentBlock) >- , m_lastActiveBlock(other.m_lastActiveBlock) >- , m_allocationCursor(other.m_allocationCursor) >-{ >- other.reset(); >- if (other.isOnList()) { >- auto locker = holdLock(m_directory->m_localAllocatorsLock); >- other.remove(); >- m_directory->m_localAllocators.append(this); >- } >-} >- > void LocalAllocator::reset() > { > m_freeList.clear(); >@@ -74,25 +56,6 @@ LocalAllocator::~LocalAllocator() > remove(); > } > >- // Assert that this allocator isn't holding onto any memory. This is a valid assertion for the >- // following two use cases: >- // >- // - Immortal TLC. Those destruct after the heap is done destructing, so they should not have >- // any state left in them. >- // >- // - TLC owned by an object. Such a TLC gets destroyed after a GC flip during which we proved >- // that it is not reachable. Therefore, the TLC should still be in a fully reset state at the >- // time of destruction because for it to get into any other state, someone must have allocated >- // in it (which is impossible because it's supposedly unreachable). >- // >- // My biggest worry with these assertions is that there will be some TLC that gets set as the >- // current one but then never reset, and in the meantime the global object that owns it gets >- // destroyed. >- // >- // Note that if we did hold onto some memory and we wanted to return it then this could be weird. >- // We would potentially have to stopAllocating(). That would mean having to return a block to the >- // BlockDirectory. It's not clear that the BlockDirectory is prepared to handle that during >- // sweeping another block, for example. > bool ok = true; > if (!m_freeList.allocationWillFail()) { > dataLog("FATAL: ", RawPointer(this), "->~LocalAllocator has non-empty free-list.\n"); >Index: Source/JavaScriptCore/heap/LocalAllocator.h >=================================================================== >--- Source/JavaScriptCore/heap/LocalAllocator.h (revision 232021) >+++ Source/JavaScriptCore/heap/LocalAllocator.h (working copy) >@@ -33,17 +33,17 @@ namespace JSC { > > class BlockDirectory; > class GCDeferralContext; >-class ThreadLocalCache; > > class LocalAllocator : public BasicRawSentinelNode<LocalAllocator> { > WTF_MAKE_NONCOPYABLE(LocalAllocator); > > public: >- LocalAllocator(ThreadLocalCache*, BlockDirectory*); >- LocalAllocator(LocalAllocator&&); >+ LocalAllocator(BlockDirectory*); > ~LocalAllocator(); > > void* allocate(GCDeferralContext*, AllocationFailureMode); >+ >+ unsigned cellSize() const { return m_cellSize; } > > void stopAllocating(); > void prepareForAllocation(); >@@ -55,8 +55,6 @@ public: > > bool isFreeListedCell(const void*) const; > >- ThreadLocalCache* tlc() const { return m_tlc; } >- > private: > friend class BlockDirectory; > >@@ -68,7 +66,6 @@ private: > void* allocateIn(MarkedBlock::Handle*); > ALWAYS_INLINE void doTestCollectionsIfNeeded(GCDeferralContext*); > >- ThreadLocalCache* m_tlc; > BlockDirectory* m_directory; > unsigned m_cellSize; > FreeList m_freeList; >Index: Source/JavaScriptCore/heap/ThreadLocalCache.cpp >=================================================================== >--- Source/JavaScriptCore/heap/ThreadLocalCache.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/ThreadLocalCache.cpp (nonexistent) >@@ -1,126 +0,0 @@ >-/* >- * Copyright (C) 2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ThreadLocalCache.h" >- >-#include "ThreadLocalCacheInlines.h" >-#include "ThreadLocalCacheLayout.h" >-#include <wtf/StdLibExtras.h> >- >-namespace JSC { >- >-RefPtr<ThreadLocalCache> ThreadLocalCache::create(Heap& heap) >-{ >- return adoptRef(new ThreadLocalCache(heap)); >-} >- >-ThreadLocalCache::ThreadLocalCache(Heap& heap) >- : m_heap(heap) >-{ >- m_data = allocateData(); >-} >- >-ThreadLocalCache::~ThreadLocalCache() >-{ >- destroyData(m_data); >-} >- >-ThreadLocalCache::Data* ThreadLocalCache::allocateData() >-{ >- size_t oldSize = m_data ? m_data->size : 0; >- ThreadLocalCacheLayout::Snapshot layout = m_heap.threadLocalCacheLayout().snapshot(); >- >- Data* result = static_cast<Data*>(fastMalloc(OBJECT_OFFSETOF(Data, allocator) + layout.size)); >- result->size = layout.size; >- result->cache = this; >- for (size_t offset = 0; offset < oldSize; offset += sizeof(LocalAllocator)) >- new (&allocator(*result, offset)) LocalAllocator(WTFMove(allocator(*m_data, offset))); >- for (size_t offset = oldSize; offset < layout.size; offset += sizeof(LocalAllocator)) >- new (&allocator(*result, offset)) LocalAllocator(this, layout.directories[offset / sizeof(LocalAllocator)]); >- return result; >-} >- >-void ThreadLocalCache::destroyData(Data* data) >-{ >- for (size_t offset = 0; offset < data->size; offset += sizeof(LocalAllocator)) >- allocator(*data, offset).~LocalAllocator(); >- fastFree(data); >-} >- >-void ThreadLocalCache::installSlow(VM& vm, RefPtr<ThreadLocalCache>* previous) >-{ >-#if USE(FAST_TLS_FOR_TLC) >- static std::once_flag onceFlag; >- std::call_once( >- onceFlag, >- [] () { >- pthread_key_init_np(tlsKey, destructor); >- }); >-#endif >- >- ref(); >- >- if (ThreadLocalCache::Data* oldCacheData = getImpl(vm)) { >- ThreadLocalCache* oldCache = oldCacheData->cache; >- if (previous) >- *previous = adoptRef(oldCache); >- else >- oldCache->deref(); >- } >- >- installData(vm, m_data); >-} >- >-void ThreadLocalCache::installData(VM& vm, Data* data) >-{ >-#if USE(FAST_TLS_FOR_TLC) >- UNUSED_PARAM(vm); >- _pthread_setspecific_direct(tlsKey, data); >-#else >- vm.threadLocalCacheData = data; >-#endif >-} >- >-LocalAllocator& ThreadLocalCache::allocatorSlow(VM& vm, size_t offset) >-{ >- Data* oldData = m_data; >- m_data = allocateData(); >- destroyData(oldData); >- installData(vm, m_data); >- RELEASE_ASSERT(offset < m_data->size); >- return allocator(*m_data, offset); >-} >- >-void ThreadLocalCache::destructor(void* arg) >-{ >- if (!arg) >- return; >- Data* data = static_cast<Data*>(arg); >- data->cache->deref(); >-} >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/ThreadLocalCache.h >=================================================================== >--- Source/JavaScriptCore/heap/ThreadLocalCache.h (revision 232021) >+++ Source/JavaScriptCore/heap/ThreadLocalCache.h (nonexistent) >@@ -1,105 +0,0 @@ >-/* >- * Copyright (C) 2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "AllocationFailureMode.h" >-#include "LocalAllocator.h" >-#include <wtf/FastMalloc.h> >-#include <wtf/FastTLS.h> >-#include <wtf/ThreadSafeRefCounted.h> >-#include <wtf/Vector.h> >- >-namespace JSC { >- >-class Heap; >-class VM; >- >-class ThreadLocalCache : public ThreadSafeRefCounted<ThreadLocalCache> { >- WTF_MAKE_NONCOPYABLE(ThreadLocalCache); >- WTF_MAKE_FAST_ALLOCATED; >- >-public: >- JS_EXPORT_PRIVATE static RefPtr<ThreadLocalCache> create(Heap&); >- >- JS_EXPORT_PRIVATE virtual ~ThreadLocalCache(); >- >- static RefPtr<ThreadLocalCache> get(VM&); >- >- // This is designed to be fast enough that you could even call it before every allocation, by >- // optimizing for the case that you're just installing the cache that is already installed. This >- // assumes a relatively small number of caches or low chance of actual context switch combined >- // with possibly high rate of "I may have context switched" sites that call this out of paranoia. >- void install(VM&, RefPtr<ThreadLocalCache>* = nullptr); >- >- static LocalAllocator& allocator(VM&, size_t offset); >- >- template<typename SuccessFunc, typename FailureFunc> >- static void tryGetAllocator(VM&, size_t offset, const SuccessFunc&, const FailureFunc&); >- >- static ptrdiff_t offsetOfSizeInData() { return OBJECT_OFFSETOF(Data, size); } >- static ptrdiff_t offsetOfFirstAllocatorInData() { return OBJECT_OFFSETOF(Data, allocator); } >- >-protected: >- JS_EXPORT_PRIVATE ThreadLocalCache(Heap&); >- >-private: >- friend class VM; >- >- struct Data { >- size_t size; >- ThreadLocalCache* cache; >- LocalAllocator allocator[1]; >- }; >- >- static Data* getImpl(VM&); >- >- Data* allocateData(); >- void destroyData(Data*); >- static LocalAllocator& allocator(Data& data, size_t offset); >- >- void installSlow(VM&, RefPtr<ThreadLocalCache>*); >- static void installData(VM&, Data*); >- >- LocalAllocator& allocatorSlow(VM&, size_t offset); >- >- static void destructor(void*); >- >- // When installed, we ref() the cache. Uninstalling deref()s the cache. TLS destruction deref()s >- // the cache. When the cache is destructed, it needs to return all of its state to the GC. I >- // think that just means stopAllocating(), but with some seriously heavy caveats having to do >- // with when it's valid to make that call. Alternatively, we could RELEASE_ASSERT that the cache >- // is empty when we destruct it. This is correct for caches that are kept live by GC objects and >- // it's correct for immortal caches. >- Heap& m_heap; >- Data* m_data { nullptr }; >- >-#if USE(FAST_TLS_FOR_TLC) >- static const pthread_key_t tlsKey = WTF_GC_TLC_KEY; >-#endif >-}; >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/ThreadLocalCacheInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/ThreadLocalCacheInlines.h (revision 232021) >+++ Source/JavaScriptCore/heap/ThreadLocalCacheInlines.h (nonexistent) >@@ -1,85 +0,0 @@ >-/* >- * Copyright (C) 2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "ThreadLocalCache.h" >-#include "VM.h" >- >-namespace JSC { >- >-inline ThreadLocalCache::Data* ThreadLocalCache::getImpl(VM& vm) >-{ >-#if USE(FAST_TLS_FOR_TLC) >- UNUSED_PARAM(vm); >- return static_cast<Data*>(_pthread_getspecific_direct(tlsKey)); >-#else >- return vm.threadLocalCacheData; >-#endif >-} >- >-inline RefPtr<ThreadLocalCache> ThreadLocalCache::get(VM& vm) >-{ >- ThreadLocalCache::Data* data = getImpl(vm); >- if (LIKELY(data)) >- return data->cache; >- return nullptr; >-} >- >-inline void ThreadLocalCache::install(VM& vm, RefPtr<ThreadLocalCache>* previous) >-{ >- if (getImpl(vm) == m_data) { >- if (previous) >- *previous = nullptr; >- return; >- } >- installSlow(vm, previous); >-} >- >-inline LocalAllocator& ThreadLocalCache::allocator(VM& vm, size_t offset) >-{ >- ThreadLocalCache::Data* data = getImpl(vm); >- if (LIKELY(offset < data->size)) >- return allocator(*data, offset); >- return data->cache->allocatorSlow(vm, offset); >-} >- >-template<typename SuccessFunc, typename FailureFunc> >-void ThreadLocalCache::tryGetAllocator(VM& vm, size_t offset, const SuccessFunc& successFunc, const FailureFunc& failureFunc) >-{ >- ThreadLocalCache::Data* data = getImpl(vm); >- if (LIKELY(offset < data->size)) >- successFunc(allocator(*data, offset)); >- else >- failureFunc(); >-} >- >-inline LocalAllocator& ThreadLocalCache::allocator(Data& data, size_t offset) >-{ >- return *bitwise_cast<LocalAllocator*>(bitwise_cast<char*>(&data.allocator[0]) + offset); >-} >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/ThreadLocalCacheLayout.cpp >=================================================================== >--- Source/JavaScriptCore/heap/ThreadLocalCacheLayout.cpp (revision 232021) >+++ Source/JavaScriptCore/heap/ThreadLocalCacheLayout.cpp (nonexistent) >@@ -1,65 +0,0 @@ >-/* >- * Copyright (C) 2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ThreadLocalCacheLayout.h" >- >-#include "BlockDirectory.h" >- >-namespace JSC { >- >-ThreadLocalCacheLayout::ThreadLocalCacheLayout() >-{ >-} >- >-ThreadLocalCacheLayout::~ThreadLocalCacheLayout() >-{ >-} >- >-void ThreadLocalCacheLayout::allocateOffset(BlockDirectory* directory) >-{ >- auto locker = holdLock(m_lock); >- directory->m_tlcOffset = m_size; >- m_size += sizeof(LocalAllocator); >- m_directories.append(directory); >-} >- >-ThreadLocalCacheLayout::Snapshot ThreadLocalCacheLayout::snapshot() >-{ >- auto locker = holdLock(m_lock); >- Snapshot result; >- result.size = m_size; >- result.directories = m_directories; >- return result; >-} >- >-BlockDirectory* ThreadLocalCacheLayout::directory(unsigned offset) >-{ >- auto locker = holdLock(m_lock); >- return m_directories[offset / sizeof(LocalAllocator)]; >-} >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/ThreadLocalCacheLayout.h >=================================================================== >--- Source/JavaScriptCore/heap/ThreadLocalCacheLayout.h (revision 232021) >+++ Source/JavaScriptCore/heap/ThreadLocalCacheLayout.h (nonexistent) >@@ -1,67 +0,0 @@ >-/* >- * Copyright (C) 2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include <wtf/FastMalloc.h> >-#include <wtf/Lock.h> >-#include <wtf/Noncopyable.h> >-#include <wtf/Vector.h> >- >-namespace JSC { >- >-class BlockDirectory; >- >-// Each Heap has a ThreadLocalCacheLayout that helps us figure out how to allocate a ThreadLocalCache >-// for that Heap. >- >-class ThreadLocalCacheLayout { >- WTF_MAKE_NONCOPYABLE(ThreadLocalCacheLayout); >- WTF_MAKE_FAST_ALLOCATED; >- >-public: >- ThreadLocalCacheLayout(); >- ~ThreadLocalCacheLayout(); >- >- // BlockDirectory calls this during creation and this fills in BlockDirectory::offset. >- void allocateOffset(BlockDirectory*); >- >- struct Snapshot { >- size_t size; >- Vector<BlockDirectory*> directories; >- }; >- >- Snapshot snapshot(); >- >- BlockDirectory* directory(unsigned offset); >- >-private: >- Lock m_lock; >- size_t m_size { 0 }; >- Vector<BlockDirectory*> m_directories; >-}; >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/jit/AssemblyHelpers.cpp >=================================================================== >--- Source/JavaScriptCore/jit/AssemblyHelpers.cpp (revision 232021) >+++ Source/JavaScriptCore/jit/AssemblyHelpers.cpp (working copy) >@@ -588,24 +588,13 @@ void AssemblyHelpers::emitAllocateWithNo > Jump popPath; > Jump done; > >-#if USE(FAST_TLS_FOR_TLC) >- loadFromTLSPtr(fastTLSOffsetForKey(WTF_GC_TLC_KEY), scratchGPR); >-#else >- loadPtr(&vm().threadLocalCacheData, scratchGPR); >-#endif >- if (allocator.isConstant()) { >- slowPath.append(branch32(BelowOrEqual, Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), TrustedImm32(allocator.allocator().offset()))); >- addPtr(TrustedImm32(ThreadLocalCache::offsetOfFirstAllocatorInData() + allocator.allocator().offset()), scratchGPR, allocatorGPR); >- } else { >- slowPath.append(branch32(BelowOrEqual, Address(scratchGPR, ThreadLocalCache::offsetOfSizeInData()), allocatorGPR)); >- addPtr(TrustedImm32(ThreadLocalCache::offsetOfFirstAllocatorInData()), allocatorGPR); >- addPtr(scratchGPR, allocatorGPR); >- } >+ if (allocator.isConstant()) >+ move(TrustedImmPtr(allocator.allocator().localAllocator()), allocatorGPR); > > load32(Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfRemaining()), resultGPR); > popPath = branchTest32(Zero, resultGPR); > if (allocator.isConstant()) >- add32(TrustedImm32(-allocator.allocator().cellSize(vm().heap)), resultGPR, scratchGPR); >+ add32(TrustedImm32(-allocator.allocator().cellSize()), resultGPR, scratchGPR); > else { > move(resultGPR, scratchGPR); > sub32(Address(allocatorGPR, LocalAllocator::offsetOfCellSize()), scratchGPR); >@@ -638,7 +627,8 @@ void AssemblyHelpers::emitAllocate(GPRRe > slowPath.append(jump()); > return; > } >- } >+ } else >+ slowPath.append(branchTestPtr(Zero, allocatorGPR)); > emitAllocateWithNonNullAllocator(resultGPR, allocator, allocatorGPR, scratchGPR, slowPath); > } > >@@ -652,7 +642,7 @@ void AssemblyHelpers::emitAllocateVariab > urshift32(TrustedImm32(stepShift), scratchGPR1); > slowPath.append(branch32(Above, scratchGPR1, TrustedImm32(MarkedSpace::largeCutoff >> stepShift))); > move(TrustedImmPtr(subspace.allocatorForSizeStep() - 1), scratchGPR2); >- load32(BaseIndex(scratchGPR2, scratchGPR1, TimesFour), scratchGPR1); >+ loadPtr(BaseIndex(scratchGPR2, scratchGPR1, timesPtr()), scratchGPR1); > > emitAllocate(resultGPR, JITAllocator::variable(), scratchGPR1, scratchGPR2, slowPath); > } >Index: Source/JavaScriptCore/jit/JITOpcodes32_64.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (revision 232021) >+++ Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (working copy) >@@ -957,7 +957,6 @@ void JIT::emit_op_create_this(Instructio > addSlowCase(branchTestPtr(Zero, rareDataReg)); > load32(Address(rareDataReg, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg); > loadPtr(Address(rareDataReg, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg); >- addSlowCase(branch32(Equal, allocatorReg, TrustedImm32(Allocator().offset()))); > > loadPtr(cachedFunction, cachedFunctionReg); > Jump hasSeenMultipleCallees = branchPtr(Equal, cachedFunctionReg, TrustedImmPtr(JSCell::seenMultipleCalleeObjects())); >Index: Source/JavaScriptCore/jit/JITOpcodes.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITOpcodes.cpp (revision 232021) >+++ Source/JavaScriptCore/jit/JITOpcodes.cpp (working copy) >@@ -834,9 +834,8 @@ void JIT::emit_op_create_this(Instructio > loadPtr(Address(calleeReg, JSFunction::offsetOfRareData()), rareDataReg); > addSlowCase(branchTestPtr(Zero, rareDataReg)); > xorPtr(TrustedImmPtr(JSFunctionPoison::key()), rareDataReg); >- load32(Address(rareDataReg, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg); >+ loadPtr(Address(rareDataReg, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg); > loadPtr(Address(rareDataReg, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg); >- addSlowCase(branch32(Equal, allocatorReg, TrustedImm32(Allocator().offset()))); > > loadPtr(cachedFunction, cachedFunctionReg); > Jump hasSeenMultipleCallees = branchPtr(Equal, cachedFunctionReg, TrustedImmPtr(JSCell::seenMultipleCalleeObjects())); >Index: Source/JavaScriptCore/runtime/JSLock.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSLock.cpp (revision 232021) >+++ Source/JavaScriptCore/runtime/JSLock.cpp (working copy) >@@ -28,7 +28,6 @@ > #include "JSCInlines.h" > #include "MachineStackMarker.h" > #include "SamplingProfiler.h" >-#include "ThreadLocalCacheInlines.h" > #include "WasmMachineThreads.h" > #include <thread> > #include <wtf/Threading.h> >@@ -149,8 +148,6 @@ void JSLock::didAcquireLock() > m_vm->setLastStackTop(thread.savedLastStackTop()); > ASSERT(thread.stack().contains(m_vm->lastStackTop())); > >- m_vm->defaultThreadLocalCache->install(*m_vm); >- > m_vm->heap.machineThreads().addCurrentThread(); > #if ENABLE(WEBASSEMBLY) > Wasm::startTrackingCurrentThread(); >Index: Source/JavaScriptCore/runtime/VM.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/VM.cpp (revision 232021) >+++ Source/JavaScriptCore/runtime/VM.cpp (working copy) >@@ -137,7 +137,6 @@ > #include "StrongInlines.h" > #include "StructureInlines.h" > #include "TestRunnerUtils.h" >-#include "ThreadLocalCacheInlines.h" > #include "ThunkGenerators.h" > #include "TypeProfiler.h" > #include "TypeProfilerLog.h" >@@ -354,9 +353,6 @@ VM::VM(VMType vmType, HeapType heapType) > updateSoftReservedZoneSize(Options::softReservedZoneSize()); > setLastStackTop(stack.origin()); > >- defaultThreadLocalCache = ThreadLocalCache::create(heap); >- defaultThreadLocalCache->install(*this); >- > // Need to be careful to keep everything consistent here > JSLockHolder lock(this); > AtomicStringTable* existingEntryAtomicStringTable = Thread::current().setCurrentAtomicStringTable(m_atomicStringTable); >@@ -553,10 +549,6 @@ VM::~VM() > m_apiLock->willDestroyVM(this); > heap.lastChanceToFinalize(); > >-#if !USE(FAST_TLS_FOR_TLC) >- ThreadLocalCache::destructor(threadLocalCacheData); >-#endif >- > delete interpreter; > #ifndef NDEBUG > interpreter = reinterpret_cast<Interpreter*>(0xbbadbeef); >Index: Source/JavaScriptCore/runtime/VM.h >=================================================================== >--- Source/JavaScriptCore/runtime/VM.h (revision 232021) >+++ Source/JavaScriptCore/runtime/VM.h (working copy) >@@ -53,7 +53,6 @@ > #include "StructureCache.h" > #include "VMEntryRecord.h" > #include "VMTraps.h" >-#include "ThreadLocalCache.h" > #include "WasmContext.h" > #include "Watchpoint.h" > #include <wtf/BumpPointerAllocator.h> >@@ -687,11 +686,6 @@ public: > JSObject* stringRecursionCheckFirstObject { nullptr }; > HashSet<JSObject*> stringRecursionCheckVisitedObjects; > >-#if !USE(FAST_TLS_FOR_TLC) >- ThreadLocalCache::Data* threadLocalCacheData { nullptr }; >-#endif >- RefPtr<ThreadLocalCache> defaultThreadLocalCache; >- > LocalTimeOffsetCache localTimeOffsetCache; > > String cachedDateString; >Index: Source/JavaScriptCore/runtime/VMEntryScope.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/VMEntryScope.cpp (revision 232021) >+++ Source/JavaScriptCore/runtime/VMEntryScope.cpp (working copy) >@@ -30,7 +30,6 @@ > #include "JSGlobalObject.h" > #include "Options.h" > #include "SamplingProfiler.h" >-#include "ThreadLocalCacheInlines.h" > #include "VM.h" > #include "Watchdog.h" > #include <wtf/StackBounds.h> >@@ -71,9 +70,6 @@ void VMEntryScope::addDidPopListener(std > > VMEntryScope::~VMEntryScope() > { >- if (m_previousTLC) >- m_previousTLC->install(m_vm); >- > if (m_vm.entryScope != this) > return; > >Index: Source/JavaScriptCore/runtime/VMEntryScope.h >=================================================================== >--- Source/JavaScriptCore/runtime/VMEntryScope.h (revision 232021) >+++ Source/JavaScriptCore/runtime/VMEntryScope.h (working copy) >@@ -31,7 +31,6 @@ > namespace JSC { > > class JSGlobalObject; >-class ThreadLocalCache; > class VM; > > class VMEntryScope { >@@ -48,7 +47,6 @@ private: > VM& m_vm; > JSGlobalObject* m_globalObject; > Vector<std::function<void ()>> m_didPopListeners; >- RefPtr<ThreadLocalCache> m_previousTLC; > }; > > } // namespace JSC
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ggaren
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185846
:
340910
|
340945
|
340986
|
340987
|
341001