Changeset 229516 in webkit
- Timestamp:
- Mar 11, 2018 10:45:49 AM (6 years ago)
- Location:
- trunk/Source/bmalloc
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/bmalloc/CMakeLists.txt
r228108 r229516 26 26 bmalloc/Logging.cpp 27 27 bmalloc/ObjectType.cpp 28 bmalloc/PerProcess.cpp 28 29 bmalloc/Scavenger.cpp 29 30 bmalloc/StaticMutex.cpp -
trunk/Source/bmalloc/ChangeLog
r229504 r229516 1 2018-03-10 Filip Pizlo <fpizlo@apple.com> 2 3 PerProcess<> should be safe by default 4 https://bugs.webkit.org/show_bug.cgi?id=183545 5 6 Reviewed by Yusuke Suzuki. 7 8 This makes PerProcess<> safe by default, so we don't need SafePerProcess<>. 9 10 The new PerProcess<> design relies on a hash-consing mechanism for PerProcess<> storage based 11 on the __PRETTY_FUNCTION__ from inside PerProcess<>, which captures the instantiated type in 12 the string. Therefore, this can be used to runtime-coalesce PerProcess<> instances based on 13 type. 14 15 I expect this to be perf-neutral. It's an important prerequisite to more bmalloc work, since I 16 don't want to have more PerProcess<> vs SafePerProcess<> bugs, and SafePerProcess<> can't be 17 used for everything (I don't see how to use it for isoheaps). 18 19 * CMakeLists.txt: 20 * bmalloc.xcodeproj/project.pbxproj: 21 * bmalloc/Heap.cpp: 22 (bmalloc::Heap::Heap): 23 * bmalloc/IsoDirectoryInlines.h: 24 (bmalloc::passedNumPages>::takeFirstEligible): 25 (bmalloc::passedNumPages>::didBecome): 26 * bmalloc/PerProcess.cpp: Added. 27 (bmalloc::stringHash): 28 (bmalloc::allocate): 29 (bmalloc::getPerProcessData): 30 * bmalloc/PerProcess.h: 31 (bmalloc::PerProcess::mutex): 32 (bmalloc::PerProcess::coalesce): 33 (bmalloc::PerProcess::getSlowCase): 34 (): Deleted. 35 * bmalloc/Scavenger.cpp: 36 * bmalloc/Scavenger.h: 37 * bmalloc/bmalloc.cpp: 38 (bmalloc::api::scavenge): 39 (bmalloc::api::setScavengerThreadQOSClass): 40 1 41 2018-03-10 Commit Queue <commit-queue@webkit.org> 2 42 -
trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj
r228108 r229516 22 22 23 23 /* Begin PBXBuildFile section */ 24 0F26A7A5205483130090A141 /* PerProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F26A7A42054830D0090A141 /* PerProcess.cpp */; }; 24 25 0F5167741FAD685C008236A8 /* bmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5167731FAD6852008236A8 /* bmalloc.cpp */; }; 25 26 0F5549EF1FB54704007FF75A /* IsoPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5549EE1FB54701007FF75A /* IsoPage.cpp */; }; … … 175 176 176 177 /* Begin PBXFileReference section */ 178 0F26A7A42054830D0090A141 /* PerProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PerProcess.cpp; path = bmalloc/PerProcess.cpp; sourceTree = "<group>"; }; 177 179 0F5167731FAD6852008236A8 /* bmalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bmalloc.cpp; path = bmalloc/bmalloc.cpp; sourceTree = "<group>"; }; 178 180 0F5549EE1FB54701007FF75A /* IsoPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IsoPage.cpp; path = bmalloc/IsoPage.cpp; sourceTree = "<group>"; }; … … 522 524 14C8992A1CC485E70027A057 /* Map.h */, 523 525 144DCED617A649D90093B2F2 /* Mutex.h */, 526 0F26A7A42054830D0090A141 /* PerProcess.cpp */, 524 527 0F5BF1481F22A8D80029D91D /* PerHeapKind.h */, 525 528 14446A0717A61FA400F9EA1D /* PerProcess.h */, … … 769 772 6599C5CC1EC3F15900A2F7BB /* AvailableMemory.cpp in Sources */, 770 773 14F271C418EA397B008C152F /* Cache.cpp in Sources */, 774 0F26A7A5205483130090A141 /* PerProcess.cpp in Sources */, 771 775 14F271C518EA397E008C152F /* Deallocator.cpp in Sources */, 772 776 142B44361E2839E7001DA6E9 /* DebugHeap.cpp in Sources */, -
trunk/Source/bmalloc/bmalloc/CryptoRandom.cpp
r224537 r229516 54 54 55 55 namespace bmalloc { 56 57 namespace {58 56 59 57 class ARC4Stream { … … 181 179 } 182 180 183 }184 185 181 void cryptoRandom(void* buffer, size_t length) 186 182 { -
trunk/Source/bmalloc/bmalloc/Heap.cpp
r228107 r229516 65 65 } 66 66 67 m_scavenger = SafePerProcess<Scavenger>::get();67 m_scavenger = PerProcess<Scavenger>::get(); 68 68 } 69 69 -
trunk/Source/bmalloc/bmalloc/IsoDirectoryInlines.h
r228107 r229516 52 52 return EligibilityKind::Full; 53 53 54 Scavenger& scavenger = * SafePerProcess<Scavenger>::get();54 Scavenger& scavenger = *PerProcess<Scavenger>::get(); 55 55 scavenger.didStartGrowing(); 56 56 … … 101 101 fprintf(stderr, "%p: %p did become empty.\n", this, page); 102 102 m_empty[pageIndex] = true; 103 SafePerProcess<Scavenger>::get()->schedule(IsoPageBase::pageSize);103 PerProcess<Scavenger>::get()->schedule(IsoPageBase::pageSize); 104 104 return; 105 105 } -
trunk/Source/bmalloc/bmalloc/PerProcess.h
r228107 r229516 39 39 // Object will be instantiated only once, even in the face of concurrency. 40 40 // 41 // WARNING: PerProcess<T> does not export its storage. So in actuality when42 // used in multiple libraries / images it ends up being per-image. To truly43 // declare a per-process singleton use SafePerProcess<T>.44 //45 41 // NOTE: If you observe global side-effects of the Object constructor, be 46 42 // sure to lock the Object mutex. For example: … … 55 51 // Object* object = PerProcess<Object>::get(lock); 56 52 // if (globalFlag) { ... } // OK. 53 54 struct PerProcessData { 55 const char* disambiguator; 56 void* memory; 57 size_t size; 58 size_t alignment; 59 StaticMutex mutex; 60 bool isInitialized; 61 PerProcessData* next; 62 }; 63 64 constexpr unsigned stringHash(const char* string) 65 { 66 unsigned result = 5381; 67 while (char c = *string++) 68 result = result * 33 + c; 69 return result; 70 } 71 72 BEXPORT PerProcessData* getPerProcessData(unsigned disambiguatorHash, const char* disambiguator, size_t size, size_t alignment); 57 73 58 74 template<typename T> … … 72 88 } 73 89 74 static StaticMutex& mutex() { return s_mutex; } 90 static StaticMutex& mutex() 91 { 92 if (!s_data) 93 coalesce(); 94 return s_data->mutex; 95 } 75 96 76 97 private: 98 static void coalesce() 99 { 100 if (s_data) 101 return; 102 103 const char* disambiguator = __PRETTY_FUNCTION__; 104 s_data = getPerProcessData(stringHash(disambiguator), disambiguator, sizeof(T), std::alignment_of<T>::value); 105 } 106 77 107 BNO_INLINE static T* getSlowCase() 78 108 { 79 std::lock_guard<StaticMutex> lock(s_mutex); 80 if (!s_object.load(std::memory_order_consume)) { 81 T* t = new (&s_memory) T(lock); 82 s_object.store(t, std::memory_order_release); 109 std::lock_guard<StaticMutex> lock(mutex()); 110 if (!s_object.load()) { 111 if (s_data->isInitialized) 112 s_object.store(static_cast<T*>(s_data->memory)); 113 else { 114 T* t = new (s_data->memory) T(lock); 115 s_object.store(t); 116 s_data->isInitialized = true; 117 } 83 118 } 84 return s_object.load( std::memory_order_consume);119 return s_object.load(); 85 120 } 86 121 87 122 static std::atomic<T*> s_object; 88 static StaticMutex s_mutex; 89 90 typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type Memory; 91 static Memory s_memory; 123 static PerProcessData* s_data; 92 124 }; 93 125 … … 96 128 97 129 template<typename T> 98 StaticMutex PerProcess<T>::s_mutex; 99 100 template<typename T> 101 typename PerProcess<T>::Memory PerProcess<T>::s_memory; 102 103 104 // SafePerProcess<T> behaves like PerProcess<T>, but its usage 105 // requires DECLARE/DEFINE macros that export symbols that allow for 106 // a single shared instance is across images in the process. 107 108 template<typename T> struct SafePerProcessStorageTraits; 109 110 template<typename T> 111 class BEXPORT SafePerProcess { 112 public: 113 using Storage = typename SafePerProcessStorageTraits<T>::Storage; 114 115 static T* get() 116 { 117 T* object = getFastCase(); 118 if (!object) 119 return getSlowCase(); 120 return object; 121 } 122 123 static T* getFastCase() 124 { 125 return (Storage::s_object).load(std::memory_order_relaxed); 126 } 127 128 static StaticMutex& mutex() { return Storage::s_mutex; } 129 130 using Memory = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type; 131 132 private: 133 BNO_INLINE static T* getSlowCase() 134 { 135 std::lock_guard<StaticMutex> lock(Storage::s_mutex); 136 if (!Storage::s_object.load(std::memory_order_consume)) { 137 T* t = new (&Storage::s_memory) T(lock); 138 Storage::s_object.store(t, std::memory_order_release); 139 } 140 return Storage::s_object.load(std::memory_order_consume); 141 } 142 }; 143 144 #define DECLARE_SAFE_PER_PROCESS_STORAGE(Type) \ 145 template<> struct SafePerProcessStorageTraits<Type> { \ 146 struct BEXPORT Storage { \ 147 BEXPORT static std::atomic<Type*> s_object; \ 148 BEXPORT static StaticMutex s_mutex; \ 149 BEXPORT static SafePerProcess<Type>::Memory s_memory; \ 150 }; \ 151 }; 152 153 #define DEFINE_SAFE_PER_PROCESS_STORAGE(Type) \ 154 std::atomic<Type*> SafePerProcessStorageTraits<Type>::Storage::s_object; \ 155 StaticMutex SafePerProcessStorageTraits<Type>::Storage::s_mutex; \ 156 SafePerProcess<Type>::Memory SafePerProcessStorageTraits<Type>::Storage::s_memory; 130 PerProcessData* PerProcess<T>::s_data; 157 131 158 132 } // namespace bmalloc -
trunk/Source/bmalloc/bmalloc/Scavenger.cpp
r228107 r229516 32 32 33 33 namespace bmalloc { 34 35 DEFINE_SAFE_PER_PROCESS_STORAGE(Scavenger);36 34 37 35 Scavenger::Scavenger(std::lock_guard<StaticMutex>&) -
trunk/Source/bmalloc/bmalloc/Scavenger.h
r228107 r229516 94 94 }; 95 95 96 DECLARE_SAFE_PER_PROCESS_STORAGE(Scavenger);97 98 96 } // namespace bmalloc 99 97 -
trunk/Source/bmalloc/bmalloc/bmalloc.cpp
r228107 r229516 74 74 scavengeThisThread(); 75 75 76 SafePerProcess<Scavenger>::get()->scavenge();76 PerProcess<Scavenger>::get()->scavenge(); 77 77 } 78 78 … … 88 88 { 89 89 std::unique_lock<StaticMutex> lock(Heap::mutex()); 90 SafePerProcess<Scavenger>::get()->setScavengerThreadQOSClass(overrideClass);90 PerProcess<Scavenger>::get()->setScavengerThreadQOSClass(overrideClass); 91 91 } 92 92 #endif
Note: See TracChangeset
for help on using the changeset viewer.