Changeset 261667 in webkit
- Timestamp:
- May 13, 2020, 6:09:19 PM (6 years ago)
- Location:
- trunk/Source/bmalloc
- Files:
-
- 2 added
- 9 edited
-
CMakeLists.txt (modified) (2 diffs)
-
ChangeLog (modified) (1 diff)
-
bmalloc.xcodeproj/project.pbxproj (modified) (5 diffs)
-
bmalloc/Algorithm.h (modified) (1 diff)
-
bmalloc/Deallocator.cpp (modified) (1 diff)
-
bmalloc/Heap.cpp (modified) (11 diffs)
-
bmalloc/Heap.h (modified) (6 diffs)
-
bmalloc/ObjectType.cpp (modified) (1 diff)
-
bmalloc/ObjectTypeTable.cpp (added)
-
bmalloc/ObjectTypeTable.h (added)
-
bmalloc/Scavenger.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/bmalloc/CMakeLists.txt
r261444 r261667 30 30 bmalloc/Mutex.cpp 31 31 bmalloc/ObjectType.cpp 32 bmalloc/ObjectTypeTable.cpp 32 33 bmalloc/PerProcess.cpp 33 34 bmalloc/Scavenger.cpp … … 111 112 bmalloc/Object.h 112 113 bmalloc/ObjectType.h 114 bmalloc/ObjectTypeTable.h 113 115 bmalloc/Packed.h 114 116 bmalloc/PerHeapKind.h -
trunk/Source/bmalloc/ChangeLog
r261543 r261667 1 2020-05-13 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [bmalloc] Introduce lock-less ObjectType query 4 https://bugs.webkit.org/show_bug.cgi?id=211809 5 6 Reviewed by Mark Lam. 7 8 This patch introduces ObjectTypeTable, which allows lock-less ObjectType query for Chunk*. 9 It has bit-vector to store ObjectType per address. And each bit represents 1MB of VA region since 10 Chunk*'s size is at least 1MB and ObjectType is 1bit data. Every time we extend this bit-vector 11 to support larger VA region, we do not free the old bit-vector. Since we always allocate power-of-2 12 sized bit-vector, # of extension is limited and it does not waste much memory because Chunk's size 13 is enough large (1MB). Since each 4KB page on macOS can represent a bit-vector for 32GB VA region, 14 in practice, this extension almost never happens. I verified that 4KB page can handle memory 15 allocations in JetStream2 and Gmail. 16 17 * CMakeLists.txt: 18 * bmalloc.xcodeproj/project.pbxproj: 19 * bmalloc/Algorithm.h: 20 (bmalloc::roundUpToPowerOfTwo): 21 * bmalloc/Deallocator.cpp: 22 (bmalloc::Deallocator::deallocateSlowCase): 23 * bmalloc/Heap.cpp: 24 (bmalloc::Heap::freeableMemory): 25 (bmalloc::Heap::decommitLargeRange): 26 (bmalloc::Heap::scavenge): 27 (bmalloc::Heap::scavengeToHighWatermark): 28 (bmalloc::Heap::allocateSmallChunk): 29 (bmalloc::Heap::deallocateSmallChunk): 30 (bmalloc::Heap::deallocateSmallLine): 31 (bmalloc::Heap::splitAndAllocate): 32 (bmalloc::Heap::isLarge): Deleted. 33 * bmalloc/Heap.h: 34 (bmalloc::Heap::isLarge): 35 * bmalloc/ObjectType.cpp: 36 (bmalloc::objectType): 37 * bmalloc/ObjectTypeTable.cpp: Added. 38 (bmalloc::ObjectTypeTable::set): 39 * bmalloc/ObjectTypeTable.h: Added. 40 (bmalloc::ObjectTypeTable::convertToIndex): 41 (bmalloc::ObjectTypeTable::Bits::Bits): 42 (bmalloc::ObjectTypeTable::Bits::previous const): 43 (bmalloc::ObjectTypeTable::Bits::begin const): 44 (bmalloc::ObjectTypeTable::Bits::end const): 45 (bmalloc::ObjectTypeTable::Bits::count const): 46 (bmalloc::ObjectTypeTable::Bits::sizeInBytes const): 47 (bmalloc::ObjectTypeTable::Bits::words const): 48 (bmalloc::ObjectTypeTable::Bits::words): 49 (bmalloc::ObjectTypeTable::ObjectTypeTable): 50 (bmalloc::ObjectTypeTable::get): 51 (bmalloc::ObjectTypeTable::Bits::get): 52 (bmalloc::ObjectTypeTable::Bits::set): 53 (bmalloc::ObjectTypeTable::Bits::wordForIndex): 54 * bmalloc/Scavenger.cpp: 55 (bmalloc::Scavenger::scavenge): 56 (bmalloc::Scavenger::partialScavenge): 57 (bmalloc::Scavenger::freeableMemory): 58 1 59 2020-05-11 Basuke Suzuki <basuke.suzuki@sony.com> 2 60 -
trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj
r260712 r261667 140 140 E31E74802238CA5C005D084A /* StaticPerProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = E31E747F2238CA5B005D084A /* StaticPerProcess.h */; settings = {ATTRIBUTES = (Private, ); }; }; 141 141 E328D84D23CEB38900545B18 /* Packed.h in Headers */ = {isa = PBXBuildFile; fileRef = E328D84C23CEB38900545B18 /* Packed.h */; settings = {ATTRIBUTES = (Private, ); }; }; 142 E378A9DF246B68720029C2BB /* ObjectTypeTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E378A9DE246B686A0029C2BB /* ObjectTypeTable.cpp */; }; 143 E378A9E0246B68750029C2BB /* ObjectTypeTable.h in Headers */ = {isa = PBXBuildFile; fileRef = E378A9DD246B686A0029C2BB /* ObjectTypeTable.h */; settings = {ATTRIBUTES = (Private, ); }; }; 142 144 E3A413C9226061140037F470 /* IsoSharedPageInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A413C8226061140037F470 /* IsoSharedPageInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 143 145 E3F24402225D2C0100A0E0C3 /* IsoSharedPage.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F24401225D2C0100A0E0C3 /* IsoSharedPage.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 294 296 E31E747F2238CA5B005D084A /* StaticPerProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StaticPerProcess.h; path = bmalloc/StaticPerProcess.h; sourceTree = "<group>"; }; 295 297 E328D84C23CEB38900545B18 /* Packed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Packed.h; path = bmalloc/Packed.h; sourceTree = "<group>"; }; 298 E378A9DD246B686A0029C2BB /* ObjectTypeTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ObjectTypeTable.h; path = bmalloc/ObjectTypeTable.h; sourceTree = "<group>"; }; 299 E378A9DE246B686A0029C2BB /* ObjectTypeTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectTypeTable.cpp; path = bmalloc/ObjectTypeTable.cpp; sourceTree = "<group>"; }; 296 300 E3A413C8226061140037F470 /* IsoSharedPageInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedPageInlines.h; path = bmalloc/IsoSharedPageInlines.h; sourceTree = "<group>"; }; 297 301 E3F24401225D2C0100A0E0C3 /* IsoSharedPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoSharedPage.h; path = bmalloc/IsoSharedPage.h; sourceTree = "<group>"; }; … … 491 495 14105E8318E14374003A106E /* ObjectType.cpp */, 492 496 1485656018A43DBA00ED6942 /* ObjectType.h */, 497 E378A9DE246B686A0029C2BB /* ObjectTypeTable.cpp */, 498 E378A9DD246B686A0029C2BB /* ObjectTypeTable.h */, 493 499 795AB3C6206E0D250074FE76 /* PhysicalPageMap.h */, 494 500 AD14AD27202529A600890E3B /* ProcessCheck.h */, … … 646 652 144BE11F1CA346520099C8C0 /* Object.h in Headers */, 647 653 14DD789318F48D0F00950702 /* ObjectType.h in Headers */, 654 E378A9E0246B68750029C2BB /* ObjectTypeTable.h in Headers */, 648 655 E328D84D23CEB38900545B18 /* Packed.h in Headers */, 649 656 0F5BF1491F22A8D80029D91D /* PerHeapKind.h in Headers */, … … 778 785 143CB81C19022BC900B16A45 /* Mutex.cpp in Sources */, 779 786 14F271C818EA3990008C152F /* ObjectType.cpp in Sources */, 787 E378A9DF246B68720029C2BB /* ObjectTypeTable.cpp in Sources */, 780 788 0F26A7A5205483130090A141 /* PerProcess.cpp in Sources */, 781 789 AD14AD2A202529C700890E3B /* ProcessCheck.mm in Sources */, -
trunk/Source/bmalloc/bmalloc/Algorithm.h
r254708 r261667 220 220 } 221 221 222 // From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 223 constexpr uint32_t roundUpToPowerOfTwo(uint32_t v) 224 { 225 v--; 226 v |= v >> 1; 227 v |= v >> 2; 228 v |= v >> 4; 229 v |= v >> 8; 230 v |= v >> 16; 231 v++; 232 return v; 233 } 234 222 235 } // namespace bmalloc 223 236 -
trunk/Source/bmalloc/bmalloc/Deallocator.cpp
r254781 r261667 69 69 return; 70 70 71 UniqueLockHolder lock(Heap::mutex());72 if (m_heap.isLarge(lock, object)) {71 if (m_heap.isLarge(object)) { 72 UniqueLockHolder lock(Heap::mutex()); 73 73 m_heap.deallocateLarge(lock, object); 74 74 return; 75 75 } 76 76 77 if (m_objectLog.size() == m_objectLog.capacity()) 77 if (m_objectLog.size() == m_objectLog.capacity()) { 78 UniqueLockHolder lock(Heap::mutex()); 78 79 processObjectLog(lock); 80 } 79 81 80 82 m_objectLog.push(object); -
trunk/Source/bmalloc/bmalloc/Heap.cpp
r256088 r261667 85 85 } 86 86 87 size_t Heap::freeableMemory( constLockHolder&)87 size_t Heap::freeableMemory(UniqueLockHolder&) 88 88 { 89 89 return m_freeableMemory; … … 102 102 } 103 103 104 void Heap::decommitLargeRange( constLockHolder&, LargeRange& range, BulkDecommit& decommitter)104 void Heap::decommitLargeRange(UniqueLockHolder&, LargeRange& range, BulkDecommit& decommitter) 105 105 { 106 106 m_footprint -= range.totalPhysicalSize(); … … 118 118 119 119 #if BUSE(PARTIAL_SCAVENGE) 120 void Heap::scavenge( constLockHolder& lock, BulkDecommit& decommitter)120 void Heap::scavenge(UniqueLockHolder& lock, BulkDecommit& decommitter) 121 121 #else 122 void Heap::scavenge( constLockHolder& lock, BulkDecommit& decommitter, size_t& deferredDecommits)122 void Heap::scavenge(UniqueLockHolder& lock, BulkDecommit& decommitter, size_t& deferredDecommits) 123 123 #endif 124 124 { … … 151 151 for (auto& list : m_chunkCache) { 152 152 while (!list.isEmpty()) 153 deallocateSmallChunk(l ist.pop(), &list - &m_chunkCache[0]);153 deallocateSmallChunk(lock, list.pop(), &list - &m_chunkCache[0]); 154 154 } 155 155 … … 173 173 174 174 #if BUSE(PARTIAL_SCAVENGE) 175 void Heap::scavengeToHighWatermark( constLockHolder& lock, BulkDecommit& decommitter)175 void Heap::scavengeToHighWatermark(UniqueLockHolder& lock, BulkDecommit& decommitter) 176 176 { 177 177 void* newHighWaterMark = nullptr; … … 214 214 Chunk* chunk = new (memory) Chunk(pageSize); 215 215 216 m_objectTypes.set( chunk, ObjectType::Small);216 m_objectTypes.set(lock, chunk, ObjectType::Small); 217 217 218 218 size_t accountedInFreeable = 0; … … 245 245 } 246 246 247 void Heap::deallocateSmallChunk( Chunk* chunk, size_t pageClass)248 { 249 m_objectTypes.set( chunk, ObjectType::Large);247 void Heap::deallocateSmallChunk(UniqueLockHolder& lock, Chunk* chunk, size_t pageClass) 248 { 249 m_objectTypes.set(lock, chunk, ObjectType::Large); 250 250 251 251 size_t size = m_largeAllocated.remove(chunk); … … 358 358 359 359 if (!m_chunkCache[pageClass].isEmpty()) 360 deallocateSmallChunk( m_chunkCache[pageClass].pop(), pageClass);360 deallocateSmallChunk(lock, m_chunkCache[pageClass].pop(), pageClass); 361 361 362 362 m_chunkCache[pageClass].push(chunk); … … 496 496 } 497 497 498 LargeRange Heap::splitAndAllocate(UniqueLockHolder& , LargeRange& range, size_t alignment, size_t size)498 LargeRange Heap::splitAndAllocate(UniqueLockHolder& lock, LargeRange& range, size_t alignment, size_t size) 499 499 { 500 500 RELEASE_BASSERT(isActiveHeapKind(m_kind)); … … 538 538 } 539 539 540 m_objectTypes.set( Chunk::get(range.begin()), ObjectType::Large);540 m_objectTypes.set(lock, Chunk::get(range.begin()), ObjectType::Large); 541 541 542 542 m_largeAllocated.set(range.begin(), range.size()); … … 622 622 } 623 623 624 bool Heap::isLarge(UniqueLockHolder&, void* object)625 {626 return m_objectTypes.get(Object(object).chunk()) == ObjectType::Large;627 }628 629 624 size_t Heap::largeSize(UniqueLockHolder&, void* object) 630 625 { -
trunk/Source/bmalloc/bmalloc/Heap.h
r256088 r261667 36 36 #include "Mutex.h" 37 37 #include "Object.h" 38 #include "ObjectTypeTable.h" 38 39 #include "PerHeapKind.h" 39 40 #include "PerProcess.h" … … 70 71 void deallocateLarge(UniqueLockHolder&, void*); 71 72 72 bool isLarge( UniqueLockHolder&,void*);73 bool isLarge(void*); 73 74 size_t largeSize(UniqueLockHolder&, void*); 74 75 void shrinkLarge(UniqueLockHolder&, const Range&, size_t); 75 76 76 77 #if BUSE(PARTIAL_SCAVENGE) 77 void scavengeToHighWatermark( constLockHolder&, BulkDecommit&);78 void scavenge( constLockHolder&, BulkDecommit&);78 void scavengeToHighWatermark(UniqueLockHolder&, BulkDecommit&); 79 void scavenge(UniqueLockHolder&, BulkDecommit&); 79 80 #else 80 void scavenge( constLockHolder&, BulkDecommit&, size_t& deferredDecommits);81 void scavenge(UniqueLockHolder&, BulkDecommit&, size_t& deferredDecommits); 81 82 #endif 82 void scavenge( constLockHolder&, BulkDecommit&, size_t& freed, size_t goal);83 void scavenge(UniqueLockHolder&, BulkDecommit&, size_t& freed, size_t goal); 83 84 84 size_t freeableMemory( constLockHolder&);85 size_t freeableMemory(UniqueLockHolder&); 85 86 size_t footprint(); 86 87 … … 93 94 94 95 private: 95 void decommitLargeRange( constLockHolder&, LargeRange&, BulkDecommit&);96 void decommitLargeRange(UniqueLockHolder&, LargeRange&, BulkDecommit&); 96 97 97 98 struct LargeObjectHash { … … 118 119 119 120 void allocateSmallChunk(UniqueLockHolder&, size_t pageClass, FailureAction); 120 void deallocateSmallChunk( Chunk*, size_t pageClass);121 void deallocateSmallChunk(UniqueLockHolder&, Chunk*, size_t pageClass); 121 122 122 123 LargeRange tryAllocateLargeChunk(size_t alignment, size_t); … … 136 137 LargeMap m_largeFree; 137 138 138 Map<Chunk*, ObjectType, ChunkHash>m_objectTypes;139 ObjectTypeTable m_objectTypes; 139 140 140 141 Scavenger* m_scavenger { nullptr }; … … 169 170 } 170 171 172 inline bool Heap::isLarge(void* object) 173 { 174 return m_objectTypes.get(Object(object).chunk()) == ObjectType::Large; 175 } 176 171 177 } // namespace bmalloc 172 178 -
trunk/Source/bmalloc/bmalloc/ObjectType.cpp
r254781 r261667 39 39 return ObjectType::Small; 40 40 41 UniqueLockHolder lock(Heap::mutex()); 42 if (heap.isLarge(lock, object)) 41 if (heap.isLarge(object)) 43 42 return ObjectType::Large; 44 43 } -
trunk/Source/bmalloc/bmalloc/Scavenger.cpp
r259652 r261667 224 224 size_t deferredDecommits = 0; 225 225 #endif 226 LockHolder lock(Heap::mutex());226 UniqueLockHolder lock(Heap::mutex()); 227 227 for (unsigned i = numHeaps; i--;) { 228 228 if (!isActiveHeapKind(static_cast<HeapKind>(i))) … … 298 298 { 299 299 PrintTime printTime("\npartialScavenge under lock time"); 300 LockHolder lock(Heap::mutex());300 UniqueLockHolder lock(Heap::mutex()); 301 301 for (unsigned i = numHeaps; i--;) { 302 302 if (!isActiveHeapKind(static_cast<HeapKind>(i))) … … 356 356 size_t result = 0; 357 357 { 358 LockHolder lock(Heap::mutex());358 UniqueLockHolder lock(Heap::mutex()); 359 359 for (unsigned i = numHeaps; i--;) { 360 360 if (!isActiveHeapKind(static_cast<HeapKind>(i)))
Note:
See TracChangeset
for help on using the changeset viewer.