Changeset 244481 in webkit
- Timestamp:
- Apr 19, 2019 8:29:40 PM (5 years ago)
- Location:
- trunk/Source/bmalloc
- Files:
-
- 2 added
- 19 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/bmalloc/CMakeLists.txt
r233773 r244481 20 20 bmalloc/IsoHeapImpl.cpp 21 21 bmalloc/IsoPage.cpp 22 bmalloc/IsoSharedHeap.cpp 23 bmalloc/IsoSharedPage.cpp 22 24 bmalloc/IsoTLS.cpp 23 25 bmalloc/IsoTLSEntry.cpp -
trunk/Source/bmalloc/ChangeLog
r244422 r244481 1 2019-04-19 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [bmalloc] IsoHeap should have lower tier using shared IsoPage 4 https://bugs.webkit.org/show_bug.cgi?id=196837 5 6 Reviewed by Filip Pizlo. 7 8 IsoHeap had a scalability problem. Once one instance is allocated from IsoHeap, it immediately allocates 16KB page for this type. 9 But some types allocate only a few instances. It leads to memory wastage, and it also limits the scalability of IsoHeap since 10 we need to carefully select classes which will be confined in IsoHeap due to this characteristics. If we can remove this wastage, 11 we can apply IsoHeap more aggressively without causing memory regression, this is the goal of this patch. 12 13 In this patch, we introduce a slow tier to IsoHeap allocation. Initially, the allocator for a certain type allocates instances from 14 a shared page with the other allocators, and eventually, the allocator tiers up and gets dedicated pages if instances of the type 15 are allocated a lot. This "shared" tier is slow, but it is totally OK because we will tier up to the normal fast tier if allocation 16 frequently happens. Even the instance is allocated from pages shared with the other allocators, we still make the allocated memory 17 region dedicated to the specific type: once a memory region is allocated for a certain type from a shared page, this region continues 18 being used only for this type even after this memory is freed. To summarize the changes: 19 20 1. We introduce "shared" tier to IsoHeap allocation. Up to N (N = 8 for now, but we can pick any power-of-two numbers up to 32) allocations, 21 we continue using this tier. We allocate memory from shared pages so that we do not waste 16KB pages for types which only allocates a few instances. 22 23 2. We eventually tier up to the "fast" tier, and eventually tier down to the "shared" tier too. We measure the period between slow paths, 24 and switch the appropriate tier for the type. Currently, we use 1 seconds as heuristics. We also count # of allocations per cycle to 25 avoid pathological slow downs. 26 27 3. Shared page mechanism must keep the characteristics of IsoHeap. Once a memory region is allocated for a certain type, this memory region 28 must be dedicated to this type. We keep track the allocated memory regions from shared pages in IsoHeapImpl, and ensure that we never 29 reuse a memory region for a different type. 30 31 This patch improves PLUM2 by 1.4% (128.4MB v.s. 126.62MB), and early Speedometer2 results are performance-neutral. 32 33 * CMakeLists.txt: 34 * bmalloc.xcodeproj/project.pbxproj: 35 * bmalloc/Algorithm.h: 36 (bmalloc::roundUpToMultipleOfImpl): 37 (bmalloc::roundUpToMultipleOf): 38 * bmalloc/BCompiler.h: 39 * bmalloc/BExport.h: 40 * bmalloc/FreeList.h: 41 * bmalloc/IsoAllocator.h: 42 * bmalloc/IsoAllocatorInlines.h: 43 (bmalloc::IsoAllocator<Config>::allocateSlow): 44 * bmalloc/IsoDeallocator.h: 45 * bmalloc/IsoDeallocatorInlines.h: 46 (bmalloc::IsoDeallocator<Config>::deallocate): 47 * bmalloc/IsoHeapImpl.h: 48 * bmalloc/IsoHeapImplInlines.h: 49 (bmalloc::IsoHeapImpl<Config>::scavenge): 50 (bmalloc::IsoHeapImpl<Config>::forEachLiveObject): 51 (bmalloc::IsoHeapImpl<Config>::updateAllocationMode): 52 (bmalloc::IsoHeapImpl<Config>::allocateFromShared): 53 * bmalloc/IsoPage.h: 54 (bmalloc::IsoPageBase::IsoPageBase): 55 (bmalloc::IsoPageBase::isShared const): 56 * bmalloc/IsoPageInlines.h: 57 (bmalloc::IsoPage<Config>::IsoPage): 58 (bmalloc::IsoPageBase::pageFor): 59 (bmalloc::IsoPage<Config>::pageFor): 60 (bmalloc::IsoPage<Config>::free): 61 * bmalloc/IsoSharedConfig.h: Copied from Source/bmalloc/bmalloc/BExport.h. 62 * bmalloc/IsoSharedHeap.cpp: Copied from Source/bmalloc/bmalloc/BExport.h. 63 * bmalloc/IsoSharedHeap.h: Copied from Source/bmalloc/bmalloc/IsoAllocator.h. 64 (bmalloc::VariadicBumpAllocator::VariadicBumpAllocator): 65 (bmalloc::IsoSharedHeap::IsoSharedHeap): 66 * bmalloc/IsoSharedHeapInlines.h: Added. 67 (bmalloc::VariadicBumpAllocator::allocate): 68 (bmalloc::IsoSharedHeap::allocateNew): 69 (bmalloc::IsoSharedHeap::allocateSlow): 70 * bmalloc/IsoSharedPage.cpp: Copied from Source/bmalloc/bmalloc/BExport.h. 71 (bmalloc::IsoSharedPage::tryCreate): 72 * bmalloc/IsoSharedPage.h: Copied from Source/bmalloc/bmalloc/IsoDeallocator.h. 73 (bmalloc::IsoSharedPage::IsoSharedPage): 74 (bmalloc::indexSlotFor): 75 * bmalloc/IsoSharedPageInlines.h: Added. 76 (bmalloc::IsoSharedPage::free): 77 (bmalloc::IsoSharedPage::startAllocating): 78 (bmalloc::IsoSharedPage::stopAllocating): 79 * bmalloc/IsoTLS.h: 80 * bmalloc/IsoTLSInlines.h: 81 (bmalloc::IsoTLS::deallocateImpl): 82 (bmalloc::IsoTLS::deallocateFast): 83 (bmalloc::IsoTLS::deallocateSlow): 84 * bmalloc/StdLibExtras.h: 85 (bmalloc::bitwise_cast): 86 * test/testbmalloc.cpp: 87 (testIsoMallocAndFreeFast): 88 (run): 89 1 90 2019-04-18 Yusuke Suzuki <ysuzuki@apple.com> 2 91 -
trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj
r243357 r244481 145 145 DE8B13B321CC5D9F00A63FCD /* BVMTags.h in Headers */ = {isa = PBXBuildFile; fileRef = DE8B13B221CC5D9F00A63FCD /* BVMTags.h */; settings = {ATTRIBUTES = (Private, ); }; }; 146 146 E31E74802238CA5C005D084A /* StaticPerProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = E31E747F2238CA5B005D084A /* StaticPerProcess.h */; settings = {ATTRIBUTES = (Private, ); }; }; 147 E3A413C9226061140037F470 /* IsoSharedPageInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A413C8226061140037F470 /* IsoSharedPageInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 148 E3F24402225D2C0100A0E0C3 /* IsoSharedPage.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F24401225D2C0100A0E0C3 /* IsoSharedPage.h */; settings = {ATTRIBUTES = (Private, ); }; }; 149 E3F24404225D2C7600A0E0C3 /* IsoSharedPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3F24403225D2C7600A0E0C3 /* IsoSharedPage.cpp */; }; 150 E3FBB5A0225EADB000DB6FBD /* IsoSharedConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FBB59D225EADB000DB6FBD /* IsoSharedConfig.h */; settings = {ATTRIBUTES = (Private, ); }; }; 151 E3FBB5A1225EADB000DB6FBD /* IsoSharedHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3FBB59E225EADB000DB6FBD /* IsoSharedHeap.cpp */; }; 152 E3FBB5A2225EADB000DB6FBD /* IsoSharedHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FBB59F225EADB000DB6FBD /* IsoSharedHeap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 153 E3FBB5A4225ECAD200DB6FBD /* IsoSharedHeapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FBB5A3225ECAD200DB6FBD /* IsoSharedHeapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 147 154 /* End PBXBuildFile section */ 148 155 … … 312 319 DE8B13B221CC5D9F00A63FCD /* BVMTags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BVMTags.h; path = bmalloc/BVMTags.h; sourceTree = "<group>"; }; 313 320 E31E747F2238CA5B005D084A /* StaticPerProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StaticPerProcess.h; path = bmalloc/StaticPerProcess.h; sourceTree = "<group>"; }; 321 E3A413C8226061140037F470 /* IsoSharedPageInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedPageInlines.h; path = bmalloc/IsoSharedPageInlines.h; sourceTree = "<group>"; }; 322 E3F24401225D2C0100A0E0C3 /* IsoSharedPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedPage.h; path = bmalloc/IsoSharedPage.h; sourceTree = "<group>"; }; 323 E3F24403225D2C7600A0E0C3 /* IsoSharedPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IsoSharedPage.cpp; path = bmalloc/IsoSharedPage.cpp; sourceTree = "<group>"; }; 324 E3FBB59D225EADB000DB6FBD /* IsoSharedConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedConfig.h; path = bmalloc/IsoSharedConfig.h; sourceTree = "<group>"; }; 325 E3FBB59E225EADB000DB6FBD /* IsoSharedHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IsoSharedHeap.cpp; path = bmalloc/IsoSharedHeap.cpp; sourceTree = "<group>"; }; 326 E3FBB59F225EADB000DB6FBD /* IsoSharedHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedHeap.h; path = bmalloc/IsoSharedHeap.h; sourceTree = "<group>"; }; 327 E3FBB5A3225ECAD200DB6FBD /* IsoSharedHeapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedHeapInlines.h; path = bmalloc/IsoSharedHeapInlines.h; sourceTree = "<group>"; }; 314 328 /* End PBXFileReference section */ 315 329 … … 392 406 0F7EB80A1F9541AE00F1ABCB /* IsoPageInlines.h */, 393 407 0F7EB8041F9541AD00F1ABCB /* IsoPageTrigger.h */, 408 E3FBB59D225EADB000DB6FBD /* IsoSharedConfig.h */, 409 E3FBB59E225EADB000DB6FBD /* IsoSharedHeap.cpp */, 410 E3FBB59F225EADB000DB6FBD /* IsoSharedHeap.h */, 411 E3FBB5A3225ECAD200DB6FBD /* IsoSharedHeapInlines.h */, 412 E3F24403225D2C7600A0E0C3 /* IsoSharedPage.cpp */, 413 E3F24401225D2C0100A0E0C3 /* IsoSharedPage.h */, 414 E3A413C8226061140037F470 /* IsoSharedPageInlines.h */, 394 415 0F7EB80F1F9541AE00F1ABCB /* IsoTLS.cpp */, 395 416 0F7EB81B1F9541AF00F1ABCB /* IsoTLS.h */, … … 639 660 0F7EB8311F9541B000F1ABCB /* IsoPageInlines.h in Headers */, 640 661 0F7EB82B1F9541B000F1ABCB /* IsoPageTrigger.h in Headers */, 662 E3FBB5A0225EADB000DB6FBD /* IsoSharedConfig.h in Headers */, 663 E3FBB5A2225EADB000DB6FBD /* IsoSharedHeap.h in Headers */, 664 E3FBB5A4225ECAD200DB6FBD /* IsoSharedHeapInlines.h in Headers */, 665 E3F24402225D2C0100A0E0C3 /* IsoSharedPage.h in Headers */, 666 E3A413C9226061140037F470 /* IsoSharedPageInlines.h in Headers */, 641 667 0F7EB8421F9541B000F1ABCB /* IsoTLS.h in Headers */, 642 668 0F7EB8431F9541B000F1ABCB /* IsoTLSAllocatorEntry.h in Headers */, … … 810 836 0F7EB83B1F9541B000F1ABCB /* IsoHeapImpl.cpp in Sources */, 811 837 0F5549EF1FB54704007FF75A /* IsoPage.cpp in Sources */, 838 E3FBB5A1225EADB000DB6FBD /* IsoSharedHeap.cpp in Sources */, 839 E3F24404225D2C7600A0E0C3 /* IsoSharedPage.cpp in Sources */, 812 840 0F7EB8361F9541B000F1ABCB /* IsoTLS.cpp in Sources */, 813 841 0F7EB8321F9541B000F1ABCB /* IsoTLSEntry.cpp in Sources */, -
trunk/Source/bmalloc/bmalloc/Algorithm.h
r240193 r244481 72 72 } 73 73 74 template<typename T> inline T roundUpToMultipleOf(size_t divisor, T x)74 template<typename T> constexpr T roundUpToMultipleOfImpl(size_t divisor, T x) 75 75 { 76 BASSERT(isPowerOfTwo(divisor));77 76 static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); 78 77 return static_cast<T>((static_cast<uintptr_t>(x) + (divisor - 1)) & ~(divisor - 1)); 79 78 } 80 79 81 template<size_t divisor, typename T> inline T roundUpToMultipleOf(T x) 80 template<typename T> inline T roundUpToMultipleOf(size_t divisor, T x) 81 { 82 BASSERT(isPowerOfTwo(divisor)); 83 return roundUpToMultipleOfImpl(divisor, x); 84 } 85 86 template<size_t divisor, typename T> constexpr T roundUpToMultipleOf(T x) 82 87 { 83 88 static_assert(isPowerOfTwo(divisor), "'divisor' must be a power of two."); 84 return roundUpToMultipleOf (divisor, x);89 return roundUpToMultipleOfImpl(divisor, x); 85 90 } 86 91 -
trunk/Source/bmalloc/bmalloc/BCompiler.h
r236450 r244481 55 55 #endif 56 56 57 /* BFALLTHROUGH */ 58 59 #if !defined(BFALLTHROUGH) && defined(__cplusplus) && defined(__has_cpp_attribute) 60 61 #if __has_cpp_attribute(fallthrough) 62 #define BFALLTHROUGH [[fallthrough]] 63 #elif __has_cpp_attribute(clang::fallthrough) 64 #define BFALLTHROUGH [[clang::fallthrough]] 65 #elif __has_cpp_attribute(gnu::fallthrough) 66 #define BFALLTHROUGH [[gnu::fallthrough]] 67 #endif 68 69 #endif // !defined(BFALLTHROUGH) && defined(__cplusplus) && defined(__has_cpp_attribute) 70 71 #if !defined(BFALLTHROUGH) 72 #define BFALLTHROUGH 73 #endif -
trunk/Source/bmalloc/bmalloc/BExport.h
r226958 r244481 33 33 #define BEXPORT 34 34 #endif 35 36 #define BNOEXPORT -
trunk/Source/bmalloc/bmalloc/FreeList.h
r224537 r244481 32 32 namespace bmalloc { 33 33 34 class VariadicBumpAllocator; 35 34 36 struct FreeCell { 35 37 static uintptr_t scramble(FreeCell* cell, uintptr_t secret) … … 58 60 class FreeList { 59 61 public: 62 friend class VariadicBumpAllocator; 63 60 64 BEXPORT FreeList(); 61 65 BEXPORT ~FreeList(); -
trunk/Source/bmalloc/bmalloc/IsoAllocator.h
r224537 r244481 33 33 template<typename Config> class IsoHeapImpl; 34 34 35 enum class AllocationMode : uint8_t { Init, Fast, Shared }; 36 35 37 template<typename Config> 36 38 class IsoAllocator { … … 39 41 ~IsoAllocator(); 40 42 43 AllocationMode considerUsingSharedAllocation(); 44 41 45 void* allocate(bool abortOnFailure); 42 46 void scavenge(); -
trunk/Source/bmalloc/bmalloc/IsoAllocatorInlines.h
r224537 r244481 29 29 #include "EligibilityResult.h" 30 30 #include "IsoAllocator.h" 31 #include "IsoHeapImpl .h"31 #include "IsoHeapImplInlines.h" 32 32 #include "IsoPage.h" 33 33 … … 62 62 { 63 63 std::lock_guard<Mutex> locker(m_heap->lock); 64 65 AllocationMode allocationMode = m_heap->updateAllocationMode(); 66 if (allocationMode == AllocationMode::Shared) { 67 if (m_currentPage) { 68 m_currentPage->stopAllocating(m_freeList); 69 m_currentPage = nullptr; 70 m_freeList.clear(); 71 } 72 return m_heap->allocateFromShared(abortOnFailure); 73 } 74 75 BASSERT(allocationMode == AllocationMode::Fast); 64 76 65 77 EligibilityResult<Config> result = m_heap->takeFirstEligible(); -
trunk/Source/bmalloc/bmalloc/IsoDeallocator.h
r230308 r244481 42 42 ~IsoDeallocator(); 43 43 44 void deallocate(void* p); 44 template<typename Type> 45 void deallocate(api::IsoHeap<Type>&, void* p); 45 46 void scavenge(); 46 47 -
trunk/Source/bmalloc/bmalloc/IsoDeallocatorInlines.h
r224537 r244481 29 29 #include "IsoDeallocator.h" 30 30 #include "IsoPage.h" 31 #include "IsoSharedPage.h" 31 32 #include "Mutex.h" 32 33 #include <mutex> … … 46 47 47 48 template<typename Config> 48 void IsoDeallocator<Config>::deallocate(void* ptr) 49 template<typename Type> 50 void IsoDeallocator<Config>::deallocate(api::IsoHeap<Type>& handle, void* ptr) 49 51 { 50 52 static constexpr bool verbose = false; 51 53 if (verbose) 52 54 fprintf(stderr, "%p: deallocating %p of size %u\n", &IsoPage<Config>::pageFor(ptr)->heap(), ptr, Config::objectSize); 55 56 // For allocation from shared pages, we deallocate immediately rather than batching deallocations with object log. 57 // The batching delays the reclamation of the shared cells, which can make allocator mistakenly think that "we exhaust shared 58 // cells because this is allocated a lot". Since the number of shared cells are limited, this immediate deallocation path 59 // should be rarely taken. If we see frequent malloc-and-free pattern, we tier up the allocator from shared mode to fast mode. 60 IsoPageBase* page = IsoPageBase::pageFor(ptr); 61 if (page->isShared()) { 62 std::lock_guard<Mutex> locker(*m_lock); 63 static_cast<IsoSharedPage*>(page)->free<Config>(handle, ptr); 64 return; 65 } 53 66 54 67 if (m_objectLog.size() == m_objectLog.capacity()) -
trunk/Source/bmalloc/bmalloc/IsoHeapImpl.h
r243144 r244481 27 27 28 28 #include "BMalloced.h" 29 #include "IsoAllocator.h" 29 30 #include "IsoDirectoryPage.h" 30 31 #include "IsoTLSAllocatorEntry.h" … … 38 39 MAKE_BMALLOCED; 39 40 public: 41 static constexpr unsigned maxAllocationFromShared = 8; 42 static constexpr unsigned maxAllocationFromSharedMask = maxAllocationFromShared - 1; 43 static_assert(maxAllocationFromShared <= bmalloc::alignment, ""); 44 static_assert(isPowerOfTwo(maxAllocationFromShared), ""); 45 40 46 virtual ~IsoHeapImplBase(); 41 47 … … 46 52 void scavengeNow(); 47 53 static void finishScavenging(Vector<DeferredDecommit>&); 48 54 49 55 protected: 50 56 IsoHeapImplBase(); 51 57 void addToAllIsoHeaps(); 52 58 53 private: 59 friend class IsoSharedPage; 54 60 friend class AllIsoHeaps; 55 61 56 62 IsoHeapImplBase* m_next { nullptr }; 63 std::chrono::steady_clock::time_point m_slowPathTimePoint; 64 std::array<void*, maxAllocationFromShared> m_sharedCells { }; 65 unsigned m_numberOfAllocationsFromSharedInOneCycle { 0 }; 66 unsigned m_usableBits { maxAllocationFromSharedMask }; 67 AllocationMode m_allocationMode { AllocationMode::Init }; 57 68 }; 58 69 … … 99 110 void isNowFreeable(void* ptr, size_t bytes); 100 111 void isNoLongerFreeable(void* ptr, size_t bytes); 112 113 AllocationMode updateAllocationMode(); 114 void* allocateFromShared(bool abortOnFailure); 101 115 102 116 // It's almost always the caller's responsibility to grab the lock. This lock comes from the -
trunk/Source/bmalloc/bmalloc/IsoHeapImplInlines.h
r243144 r244481 28 28 #include "IsoHeapImpl.h" 29 29 #include "IsoTLSDeallocatorEntry.h" 30 #include "IsoSharedHeapInlines.h" 31 #include "IsoSharedPageInlines.h" 30 32 31 33 namespace bmalloc { … … 108 110 }); 109 111 m_directoryHighWatermark = 0; 112 m_numberOfAllocationsFromSharedInOneCycle = 0; 113 m_allocationMode = AllocationMode::Init; 110 114 } 111 115 … … 177 181 page.forEachLiveObject(func); 178 182 }); 183 for (unsigned index = 0; index < maxAllocationFromShared; ++index) { 184 void* pointer = m_sharedCells[index]; 185 if (pointer && !(m_usableBits & (1U << index))) 186 func(pointer); 187 } 179 188 } 180 189 … … 222 231 } 223 232 233 template<typename Config> 234 AllocationMode IsoHeapImpl<Config>::updateAllocationMode() 235 { 236 // Exhaust shared free cells, which means we should start activating the fast allocation mode for this type. 237 if (!m_usableBits) { 238 m_slowPathTimePoint = std::chrono::steady_clock::now(); 239 return AllocationMode::Fast; 240 } 241 242 switch (m_allocationMode) { 243 case AllocationMode::Shared: 244 // Currently in the shared allocation mode. Until we exhaust shared free cells, continue using the shared allocation mode. 245 // But if we allocate so many shared cells within very short period, we should use the fast allocation mode instead. 246 // This avoids the following pathological case. 247 // 248 // for (int i = 0; i < 1e6; ++i) { 249 // auto* ptr = allocate(); 250 // ... 251 // free(ptr); 252 // } 253 if (m_numberOfAllocationsFromSharedInOneCycle <= IsoPage<Config>::numObjects) 254 return AllocationMode::Shared; 255 BFALLTHROUGH; 256 257 case AllocationMode::Fast: { 258 // The allocation pattern may change. We should check the allocation rate and decide which mode is more appropriate. 259 // If we don't go to the allocation slow path during 1~ seconds, we think the allocation becomes quiescent state. 260 auto now = std::chrono::steady_clock::now(); 261 if ((now - m_slowPathTimePoint) < std::chrono::seconds(1)) { 262 m_slowPathTimePoint = now; 263 return AllocationMode::Fast; 264 } 265 266 m_numberOfAllocationsFromSharedInOneCycle = 0; 267 m_slowPathTimePoint = now; 268 return AllocationMode::Shared; 269 } 270 271 case AllocationMode::Init: 272 m_slowPathTimePoint = std::chrono::steady_clock::now(); 273 return AllocationMode::Shared; 274 } 275 276 return AllocationMode::Shared; 277 } 278 279 template<typename Config> 280 void* IsoHeapImpl<Config>::allocateFromShared(bool abortOnFailure) 281 { 282 static constexpr bool verbose = false; 283 284 unsigned indexPlusOne = __builtin_ffs(m_usableBits); 285 BASSERT(indexPlusOne); 286 unsigned index = indexPlusOne - 1; 287 void* result = result = m_sharedCells[index]; 288 if (result) { 289 if (verbose) 290 fprintf(stderr, "%p: allocated %p from shared again of size %u\n", this, result, Config::objectSize); 291 } else { 292 constexpr unsigned objectSizeWithHeapImplPointer = Config::objectSize + sizeof(uint8_t); 293 result = IsoSharedHeap::get()->allocateNew<objectSizeWithHeapImplPointer>(abortOnFailure); 294 if (!result) 295 return nullptr; 296 if (verbose) 297 fprintf(stderr, "%p: allocated %p from shared of size %u\n", this, result, Config::objectSize); 298 BASSERT(index < IsoHeapImplBase::maxAllocationFromShared); 299 *indexSlotFor<Config>(result) = index; 300 m_sharedCells[index] = result; 301 } 302 BASSERT(result); 303 m_usableBits &= (~(1U << index)); 304 ++m_numberOfAllocationsFromSharedInOneCycle; 305 return result; 306 } 307 224 308 } // namespace bmalloc 225 309 -
trunk/Source/bmalloc/bmalloc/IsoPage.h
r225125 r244481 33 33 namespace bmalloc { 34 34 35 class IsoHeapImplBase; 35 36 template<typename Config> class IsoDirectoryBase; 36 37 template<typename Config> class IsoHeapImpl; … … 39 40 public: 40 41 static constexpr size_t pageSize = 16384; 42 43 explicit IsoPageBase(bool isShared) 44 : m_isShared(isShared) 45 { 46 } 47 48 static IsoPageBase* pageFor(void*); 49 50 bool isShared() const { return m_isShared; } 41 51 42 52 protected: 43 53 BEXPORT static void* allocatePageMemory(); 54 55 bool m_isShared { false }; 44 56 }; 45 57 … … 82 94 } 83 95 84 IsoDirectoryBase<Config>& m_directory;85 unsigned m_index { UINT_MAX };86 87 96 // The possible states of a page are as follows. We mark these states by their corresponding 88 97 // eligible, empty, and committed bits (respectively). … … 102 111 103 112 // This must have a trivial destructor. 104 105 unsigned m_allocBits[bitsArrayLength(numObjects)]; 106 unsigned m_numNonEmptyWords { 0 }; 113 107 114 bool m_eligibilityHasBeenNoted { true }; 108 115 bool m_isInUseForAllocation { false }; 109 116 DeferredTrigger<IsoPageTrigger::Eligible> m_eligibilityTrigger; 110 117 DeferredTrigger<IsoPageTrigger::Empty> m_emptyTrigger; 118 119 IsoDirectoryBase<Config>& m_directory; 120 unsigned m_index { UINT_MAX }; 121 122 unsigned m_allocBits[bitsArrayLength(numObjects)]; 123 unsigned m_numNonEmptyWords { 0 }; 111 124 }; 112 125 -
trunk/Source/bmalloc/bmalloc/IsoPageInlines.h
r242892 r244481 28 28 #include "CryptoRandom.h" 29 29 #include "IsoDirectory.h" 30 #include "IsoHeapImpl.h" 30 31 #include "IsoPage.h" 31 32 #include "StdLibExtras.h" … … 46 47 template<typename Config> 47 48 IsoPage<Config>::IsoPage(IsoDirectoryBase<Config>& directory, unsigned index) 48 : m_directory(directory) 49 : IsoPageBase(false) 50 , m_directory(directory) 49 51 , m_index(index) 50 52 { … … 52 54 } 53 55 56 inline IsoPageBase* IsoPageBase::pageFor(void* ptr) 57 { 58 return reinterpret_cast<IsoPageBase*>(reinterpret_cast<uintptr_t>(ptr) & ~(pageSize - 1)); 59 } 60 54 61 template<typename Config> 55 62 IsoPage<Config>* IsoPage<Config>::pageFor(void* ptr) 56 63 { 57 return reinterpret_cast<IsoPage<Config>*>( reinterpret_cast<uintptr_t>(ptr) & ~(pageSize - 1));64 return reinterpret_cast<IsoPage<Config>*>(IsoPageBase::pageFor(ptr)); 58 65 } 59 66 … … 61 68 void IsoPage<Config>::free(void* passedPtr) 62 69 { 70 BASSERT(!m_isShared); 63 71 unsigned offset = static_cast<char*>(passedPtr) - reinterpret_cast<char*>(this); 64 72 unsigned index = offset / Config::objectSize; -
trunk/Source/bmalloc/bmalloc/IsoSharedConfig.h
r244480 r244481 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 26 #pragma once 27 27 28 #include " BPlatform.h"28 #include "IsoConfig.h" 29 29 30 #if BUSE(EXPORT_MACROS) 31 #define BEXPORT __attribute__((visibility("default"))) 32 #else 33 #define BEXPORT 34 #endif 30 namespace bmalloc { 31 32 static constexpr unsigned alignmentForIsoSharedAllocation = 16; 33 34 } // namespace bmalloc 35 -
trunk/Source/bmalloc/bmalloc/IsoSharedHeap.cpp
r244480 r244481 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 # pragma once26 #include "IsoSharedHeap.h" 27 27 28 #include "BPlatform.h" 28 namespace bmalloc { 29 29 30 #if BUSE(EXPORT_MACROS) 31 #define BEXPORT __attribute__((visibility("default"))) 32 #else 33 #define BEXPORT 34 #endif 30 DEFINE_STATIC_PER_PROCESS_STORAGE(IsoSharedHeap); 31 32 } // namespace bmalloc -
trunk/Source/bmalloc/bmalloc/IsoSharedHeap.h
r244480 r244481 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 26 #pragma once 27 27 28 #include "FreeList.h" 28 #include "IsoSharedConfig.h" 29 #include "IsoSharedPage.h" 30 #include "StaticPerProcess.h" 29 31 30 32 namespace bmalloc { 31 33 32 template<typename Config> class IsoPage; 33 template<typename Config> class IsoHeapImpl; 34 class AllIsoHeaps; 34 35 35 template<typename Config> 36 class IsoAllocator { 36 class VariadicBumpAllocator { 37 37 public: 38 IsoAllocator(IsoHeapImpl<Config>&); 39 ~IsoAllocator(); 40 41 void* allocate(bool abortOnFailure); 42 void scavenge(); 43 38 VariadicBumpAllocator() = default; 39 40 VariadicBumpAllocator(char* payloadEnd, unsigned remaining) 41 : m_payloadEnd(payloadEnd) 42 , m_remaining(remaining) 43 { 44 } 45 46 template<unsigned, typename Func> 47 void* allocate(const Func& slowPath); 48 44 49 private: 50 char* m_payloadEnd { nullptr }; 51 unsigned m_remaining { 0 }; 52 }; 53 54 class IsoSharedHeap : public StaticPerProcess<IsoSharedHeap> { 55 public: 56 IsoSharedHeap(std::lock_guard<Mutex>&) 57 { 58 } 59 60 template<unsigned> 61 void* allocateNew(bool abortOnFailure); 62 63 private: 64 template<unsigned> 45 65 void* allocateSlow(bool abortOnFailure); 46 47 IsoHeapImpl<Config>* m_heap { nullptr }; 48 FreeList m_freeList; 49 IsoPage<Config>* m_currentPage { nullptr }; 66 67 IsoSharedPage* m_currentPage { nullptr }; 68 VariadicBumpAllocator m_allocator; 50 69 }; 70 DECLARE_STATIC_PER_PROCESS_STORAGE(IsoSharedHeap); 51 71 52 72 } // namespace bmalloc 53 73 74 -
trunk/Source/bmalloc/bmalloc/IsoSharedPage.cpp
r244480 r244481 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 # pragma once26 #include "IsoSharedPage.h" 27 27 28 #include "BPlatform.h" 28 #include "StdLibExtras.h" 29 #include "VMAllocate.h" 29 30 30 #if BUSE(EXPORT_MACROS) 31 #define BEXPORT __attribute__((visibility("default"))) 32 #else 33 #define BEXPORT 34 #endif 31 namespace bmalloc { 32 33 IsoSharedPage* IsoSharedPage::tryCreate() 34 { 35 void* memory = allocatePageMemory(); 36 if (!memory) 37 return nullptr; 38 39 return new (memory) IsoSharedPage(); 40 } 41 42 43 } // namespace bmalloc -
trunk/Source/bmalloc/bmalloc/IsoSharedPage.h
r244480 r244481 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 26 #pragma once 27 27 28 #include " FixedVector.h"28 #include "IsoHeap.h" 29 29 #include "IsoPage.h" 30 #include " Mutex.h"30 #include "IsoSharedConfig.h" 31 31 32 32 namespace bmalloc { 33 33 34 class IsoHeapImplBase; 35 36 class IsoSharedPage : public IsoPageBase { 37 public: 38 BEXPORT static IsoSharedPage* tryCreate(); 39 40 template<typename Config, typename Type> 41 void free(api::IsoHeap<Type>&, void*); 42 VariadicBumpAllocator startAllocating(); 43 void stopAllocating(); 44 45 private: 46 IsoSharedPage() 47 : IsoPageBase(true) 48 { 49 } 50 }; 51 34 52 template<typename Config> 35 class IsoDeallocator { 36 public: 37 static constexpr unsigned logsPerPage = 2; 38 static constexpr unsigned logCapacity = 39 (IsoPageBase::pageSize / Config::objectSize + logsPerPage - 1) / logsPerPage; 40 41 IsoDeallocator(Mutex& lock); 42 ~IsoDeallocator(); 43 44 void deallocate(void* p); 45 void scavenge(); 46 47 private: 48 Mutex* m_lock; 49 FixedVector<void*, logCapacity> m_objectLog; 50 }; 53 uint8_t* indexSlotFor(void* ptr) 54 { 55 BASSERT(IsoPageBase::pageFor(ptr)->isShared()); 56 return static_cast<uint8_t*>(ptr) + Config::objectSize; 57 } 51 58 52 59 } // namespace bmalloc -
trunk/Source/bmalloc/bmalloc/IsoTLS.h
r241847 r244481 70 70 static void deallocateImpl(api::IsoHeap<Type>&, void* p); 71 71 72 template<typename Config >73 void deallocateFast( unsigned offset, void* p);72 template<typename Config, typename Type> 73 void deallocateFast(api::IsoHeap<Type>&, unsigned offset, void* p); 74 74 75 75 template<typename Config, typename Type> -
trunk/Source/bmalloc/bmalloc/IsoTLSInlines.h
r242938 r244481 114 114 deallocateSlow<Config>(handle, p); 115 115 else 116 tls->deallocateFast<Config>( offset, p);116 tls->deallocateFast<Config>(handle, offset, p); 117 117 } 118 118 119 template<typename Config >120 void IsoTLS::deallocateFast( unsigned offset, void* p)119 template<typename Config, typename Type> 120 void IsoTLS::deallocateFast(api::IsoHeap<Type>& handle, unsigned offset, void* p) 121 121 { 122 reinterpret_cast<IsoDeallocator<Config>*>(m_data + offset)->deallocate( p);122 reinterpret_cast<IsoDeallocator<Config>*>(m_data + offset)->deallocate(handle, p); 123 123 } 124 124 … … 146 146 IsoTLS* tls = ensureEntries(std::max(handle.allocatorOffset(), handle.deallocatorOffset())); 147 147 148 tls->deallocateFast<Config>(handle .deallocatorOffset(), p);148 tls->deallocateFast<Config>(handle, handle.deallocatorOffset(), p); 149 149 } 150 150 -
trunk/Source/bmalloc/bmalloc/StdLibExtras.h
r242892 r244481 43 43 #endif 44 44 typename std::remove_const<ToType>::type to { }; 45 std::memcpy(static_cast<void*>(&to), static_cast<void*>(&from), sizeof(to));45 memcpy(static_cast<void*>(&to), static_cast<void*>(&from), sizeof(to)); 46 46 return to; 47 47 } -
trunk/Source/bmalloc/test/testbmalloc.cpp
r242938 r244481 256 256 } 257 257 258 static void testIsoMallocAndFreeFast() 259 { 260 static IsoHeap<char[256]> heap; 261 void* ptr = nullptr; 262 for (int i = 0; i < 1e6; ++i) { 263 ptr = heap.allocate(); 264 heap.deallocate(ptr); 265 } 266 CHECK(!IsoPageBase::pageFor(ptr)->isShared()); 267 } 268 258 269 class BisoMalloced { 259 MAKE_BISO_MALLOCED(BisoMalloced );270 MAKE_BISO_MALLOCED(BisoMalloced, BNOEXPORT); 260 271 public: 261 272 BisoMalloced(int x, float y) … … 311 322 RUN(testIsoFlipFlopFragmentedPagesScavengeInMiddle()); 312 323 RUN(testIsoFlipFlopFragmentedPagesScavengeInMiddle288()); 324 RUN(testIsoMallocAndFreeFast()); 313 325 RUN(testBisoMalloced()); 314 326 RUN(testBisoMallocedInline());
Note: See TracChangeset
for help on using the changeset viewer.