Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Side by Side Diff: third_party/WebKit/Source/platform/heap/Heap.h

Issue 1892713003: Prepare for multiple ThreadHeaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 { 100 {
101 static_assert(sizeof(T), "T must be fully defined"); 101 static_assert(sizeof(T), "T must be fully defined");
102 return object->isHeapObjectAlive(); 102 return object->isHeapObjectAlive();
103 } 103 }
104 }; 104 };
105 105
106 class PLATFORM_EXPORT ProcessHeap { 106 class PLATFORM_EXPORT ProcessHeap {
107 STATIC_ONLY(ProcessHeap); 107 STATIC_ONLY(ProcessHeap);
108 public: 108 public:
109 static void init(); 109 static void init();
110 static void shutdown();
110 111
111 static CrossThreadPersistentRegion& crossThreadPersistentRegion(); 112 static CrossThreadPersistentRegion& crossThreadPersistentRegion();
112 113
113 static bool isLowEndDevice() { return s_isLowEndDevice; } 114 static bool isLowEndDevice() { return s_isLowEndDevice; }
114 static void increaseTotalAllocatedObjectSize(size_t delta) { atomicAdd(&s_to talAllocatedObjectSize, static_cast<long>(delta)); } 115 static void increaseTotalAllocatedObjectSize(size_t delta) { atomicAdd(&s_to talAllocatedObjectSize, static_cast<long>(delta)); }
115 static void decreaseTotalAllocatedObjectSize(size_t delta) { atomicSubtract( &s_totalAllocatedObjectSize, static_cast<long>(delta)); } 116 static void decreaseTotalAllocatedObjectSize(size_t delta) { atomicSubtract( &s_totalAllocatedObjectSize, static_cast<long>(delta)); }
116 static size_t totalAllocatedObjectSize() { return acquireLoad(&s_totalAlloca tedObjectSize); } 117 static size_t totalAllocatedObjectSize() { return acquireLoad(&s_totalAlloca tedObjectSize); }
117 static void increaseTotalMarkedObjectSize(size_t delta) { atomicAdd(&s_total MarkedObjectSize, static_cast<long>(delta)); } 118 static void increaseTotalMarkedObjectSize(size_t delta) { atomicAdd(&s_total MarkedObjectSize, static_cast<long>(delta)); }
119 static void decreaseTotalMarkedObjectSize(size_t delta) { atomicSubtract(&s_ totalMarkedObjectSize, static_cast<long>(delta)); }
118 static size_t totalMarkedObjectSize() { return acquireLoad(&s_totalMarkedObj ectSize); } 120 static size_t totalMarkedObjectSize() { return acquireLoad(&s_totalMarkedObj ectSize); }
119 static void increaseTotalAllocatedSpace(size_t delta) { atomicAdd(&s_totalAl locatedSpace, static_cast<long>(delta)); } 121 static void increaseTotalAllocatedSpace(size_t delta) { atomicAdd(&s_totalAl locatedSpace, static_cast<long>(delta)); }
120 static void decreaseTotalAllocatedSpace(size_t delta) { atomicSubtract(&s_to talAllocatedSpace, static_cast<long>(delta)); } 122 static void decreaseTotalAllocatedSpace(size_t delta) { atomicSubtract(&s_to talAllocatedSpace, static_cast<long>(delta)); }
121 static size_t totalAllocatedSpace() { return acquireLoad(&s_totalAllocatedSp ace); } 123 static size_t totalAllocatedSpace() { return acquireLoad(&s_totalAllocatedSp ace); }
122 static void resetHeapCounters(); 124 static void resetHeapCounters();
123 125
124 private: 126 private:
127 static bool s_shutdownComplete;
125 static bool s_isLowEndDevice; 128 static bool s_isLowEndDevice;
126 static size_t s_totalAllocatedSpace; 129 static size_t s_totalAllocatedSpace;
127 static size_t s_totalAllocatedObjectSize; 130 static size_t s_totalAllocatedObjectSize;
128 static size_t s_totalMarkedObjectSize; 131 static size_t s_totalMarkedObjectSize;
129 132
130 friend class ThreadState; 133 friend class ThreadState;
131 }; 134 };
132 135
133 // Stats for the heap. 136 // Stats for the heap.
134 class ThreadHeapStats { 137 class ThreadHeapStats {
(...skipping 29 matching lines...) Expand all
164 size_t m_objectSizeAtLastGC; 167 size_t m_objectSizeAtLastGC;
165 size_t m_markedObjectSize; 168 size_t m_markedObjectSize;
166 size_t m_markedObjectSizeAtLastCompleteSweep; 169 size_t m_markedObjectSizeAtLastCompleteSweep;
167 size_t m_wrapperCount; 170 size_t m_wrapperCount;
168 size_t m_wrapperCountAtLastGC; 171 size_t m_wrapperCountAtLastGC;
169 size_t m_collectedWrapperCount; 172 size_t m_collectedWrapperCount;
170 size_t m_partitionAllocSizeAtLastGC; 173 size_t m_partitionAllocSizeAtLastGC;
171 double m_estimatedMarkingTimePerByte; 174 double m_estimatedMarkingTimePerByte;
172 }; 175 };
173 176
177 using ThreadStateSet = HashSet<ThreadState*>;
178
174 class PLATFORM_EXPORT ThreadHeap { 179 class PLATFORM_EXPORT ThreadHeap {
175 STATIC_ONLY(ThreadHeap);
176 public: 180 public:
177 static void init(); 181 ThreadHeap();
178 static void shutdown(); 182 ~ThreadHeap();
183
184 // Returns true for main thread's heap.
185 // TODO(keishi): Per-thread-heap will return false.
186 bool isMainThreadHeap() { return this == ThreadHeap::mainThreadHeap(); }
187 static ThreadHeap* mainThreadHeap() { return s_mainThreadHeap; }
179 188
180 #if ENABLE(ASSERT) 189 #if ENABLE(ASSERT)
181 static BasePage* findPageFromAddress(Address); 190 bool isAtSafePoint();
182 static BasePage* findPageFromAddress(const void* pointer) { return findPageF romAddress(reinterpret_cast<Address>(const_cast<void*>(pointer))); } 191 BasePage* findPageFromAddress(Address);
183 #endif 192 #endif
184 193
185 template<typename T> 194 template<typename T>
186 static inline bool isHeapObjectAlive(T* object) 195 static inline bool isHeapObjectAlive(T* object)
187 { 196 {
188 static_assert(sizeof(T), "T must be fully defined"); 197 static_assert(sizeof(T), "T must be fully defined");
189 // The strongification of collections relies on the fact that once a 198 // The strongification of collections relies on the fact that once a
190 // collection has been strongified, there is no way that it can contain 199 // collection has been strongified, there is no way that it can contain
191 // non-live entries, so no entries will be removed. Since you can't set 200 // non-live entries, so no entries will be removed. Since you can't set
192 // the mark bit on a null pointer, that means that null pointers are 201 // the mark bit on a null pointer, that means that null pointers are
(...skipping 16 matching lines...) Expand all
209 static inline bool isHeapObjectAlive(const UntracedMember<T>& member) 218 static inline bool isHeapObjectAlive(const UntracedMember<T>& member)
210 { 219 {
211 return isHeapObjectAlive(member.get()); 220 return isHeapObjectAlive(member.get());
212 } 221 }
213 template<typename T> 222 template<typename T>
214 static inline bool isHeapObjectAlive(const T*& ptr) 223 static inline bool isHeapObjectAlive(const T*& ptr)
215 { 224 {
216 return isHeapObjectAlive(ptr); 225 return isHeapObjectAlive(ptr);
217 } 226 }
218 227
228 RecursiveMutex& threadAttachMutex() { return m_threadAttachMutex; }
229 const ThreadStateSet& threads() const { return m_threads; }
230 ThreadHeapStats& heapStats() { return m_stats; }
231 SafePointBarrier* safePointBarrier() { return m_safePointBarrier.get(); }
232 CallbackStack* markingStack() const { return m_markingStack.get(); }
233 CallbackStack* postMarkingCallbackStack() const { return m_postMarkingCallba ckStack.get(); }
234 CallbackStack* globalWeakCallbackStack() const { return m_globalWeakCallback Stack.get(); }
235 CallbackStack* ephemeronStack() const { return m_ephemeronStack.get(); }
236
237 void attach(ThreadState*);
238 void detach(ThreadState*);
239 void lockThreadAttachMutex();
240 void unlockThreadAttachMutex();
241 bool park();
242 void resume();
243
244 void visitPersistentRoots(Visitor*);
245 void visitStackRoots(Visitor*);
246 void checkAndPark(ThreadState*, SafePointAwareMutexLocker*);
247 void enterSafePoint(ThreadState*);
248 void leaveSafePoint(ThreadState*, SafePointAwareMutexLocker*);
249
250 // Add a weak pointer callback to the weak callback work list. General
251 // object pointer callbacks are added to a thread local weak callback work
252 // list and the callback is called on the thread that owns the object, with
253 // the closure pointer as an argument. Most of the time, the closure and
254 // the containerObject can be the same thing, but the containerObject is
255 // constrained to be on the heap, since the heap is used to identify the
256 // correct thread.
257 void pushThreadLocalWeakCallback(void* closure, void* containerObject, WeakC allback);
258
259 static RecursiveMutex& allHeapsMutex();
260 static HashSet<ThreadHeap*>& allHeaps();
261
219 // Is the finalizable GC object still alive, but slated for lazy sweeping? 262 // Is the finalizable GC object still alive, but slated for lazy sweeping?
220 // If a lazy sweep is in progress, returns true if the object was found 263 // If a lazy sweep is in progress, returns true if the object was found
221 // to be not reachable during the marking phase, but it has yet to be swept 264 // to be not reachable during the marking phase, but it has yet to be swept
222 // and finalized. The predicate returns false in all other cases. 265 // and finalized. The predicate returns false in all other cases.
223 // 266 //
224 // Holding a reference to an already-dead object is not a valid state 267 // Holding a reference to an already-dead object is not a valid state
225 // to be in; willObjectBeLazilySwept() has undefined behavior if passed 268 // to be in; willObjectBeLazilySwept() has undefined behavior if passed
226 // such a reference. 269 // such a reference.
227 template<typename T> 270 template<typename T>
228 NO_LAZY_SWEEP_SANITIZE_ADDRESS 271 NO_LAZY_SWEEP_SANITIZE_ADDRESS
229 static bool willObjectBeLazilySwept(const T* objectPointer) 272 static bool willObjectBeLazilySwept(const T* objectPointer)
230 { 273 {
231 static_assert(IsGarbageCollectedType<T>::value, "only objects deriving f rom GarbageCollected can be used."); 274 static_assert(IsGarbageCollectedType<T>::value, "only objects deriving f rom GarbageCollected can be used.");
232 BasePage* page = pageFromObject(objectPointer); 275 BasePage* page = pageFromObject(objectPointer);
233 if (page->hasBeenSwept()) 276 if (page->hasBeenSwept())
234 return false; 277 return false;
235 ASSERT(page->arena()->getThreadState()->isSweepingInProgress()); 278 ASSERT(page->arena()->getThreadState()->isSweepingInProgress());
236 279
237 return !ThreadHeap::isHeapObjectAlive(const_cast<T*>(objectPointer)); 280 return !ThreadHeap::isHeapObjectAlive(const_cast<T*>(objectPointer));
238 } 281 }
239 282
240 // Push a trace callback on the marking stack. 283 // Push a trace callback on the marking stack.
241 static void pushTraceCallback(void* containerObject, TraceCallback); 284 void pushTraceCallback(void* containerObject, TraceCallback);
242 285
243 // Push a trace callback on the post-marking callback stack. These 286 // Push a trace callback on the post-marking callback stack. These
244 // callbacks are called after normal marking (including ephemeron 287 // callbacks are called after normal marking (including ephemeron
245 // iteration). 288 // iteration).
246 static void pushPostMarkingCallback(void*, TraceCallback); 289 void pushPostMarkingCallback(void*, TraceCallback);
247
248 // Add a weak pointer callback to the weak callback work list. General
249 // object pointer callbacks are added to a thread local weak callback work
250 // list and the callback is called on the thread that owns the object, with
251 // the closure pointer as an argument. Most of the time, the closure and
252 // the containerObject can be the same thing, but the containerObject is
253 // constrained to be on the heap, since the heap is used to identify the
254 // correct thread.
255 static void pushThreadLocalWeakCallback(void* closure, void* containerObject , WeakCallback);
256 290
257 // Similar to the more general pushThreadLocalWeakCallback, but cell 291 // Similar to the more general pushThreadLocalWeakCallback, but cell
258 // pointer callbacks are added to a static callback work list and the weak 292 // pointer callbacks are added to a static callback work list and the weak
259 // callback is performed on the thread performing garbage collection. This 293 // callback is performed on the thread performing garbage collection. This
260 // is OK because cells are just cleared and no deallocation can happen. 294 // is OK because cells are just cleared and no deallocation can happen.
261 static void pushGlobalWeakCallback(void** cell, WeakCallback); 295 void pushGlobalWeakCallback(void** cell, WeakCallback);
262 296
263 // Pop the top of a marking stack and call the callback with the visitor 297 // Pop the top of a marking stack and call the callback with the visitor
264 // and the object. Returns false when there is nothing more to do. 298 // and the object. Returns false when there is nothing more to do.
265 static bool popAndInvokeTraceCallback(Visitor*); 299 bool popAndInvokeTraceCallback(Visitor*);
266 300
267 // Remove an item from the post-marking callback stack and call 301 // Remove an item from the post-marking callback stack and call
268 // the callback with the visitor and the object pointer. Returns 302 // the callback with the visitor and the object pointer. Returns
269 // false when there is nothing more to do. 303 // false when there is nothing more to do.
270 static bool popAndInvokePostMarkingCallback(Visitor*); 304 bool popAndInvokePostMarkingCallback(Visitor*);
271 305
272 // Remove an item from the weak callback work list and call the callback 306 // Remove an item from the weak callback work list and call the callback
273 // with the visitor and the closure pointer. Returns false when there is 307 // with the visitor and the closure pointer. Returns false when there is
274 // nothing more to do. 308 // nothing more to do.
275 static bool popAndInvokeGlobalWeakCallback(Visitor*); 309 bool popAndInvokeGlobalWeakCallback(Visitor*);
276 310
277 // Register an ephemeron table for fixed-point iteration. 311 // Register an ephemeron table for fixed-point iteration.
278 static void registerWeakTable(void* containerObject, EphemeronCallback, Ephe meronCallback); 312 void registerWeakTable(void* containerObject, EphemeronCallback, EphemeronCa llback);
279 #if ENABLE(ASSERT) 313 #if ENABLE(ASSERT)
280 static bool weakTableRegistered(const void*); 314 bool weakTableRegistered(const void*);
281 #endif 315 #endif
282 316
317 BlinkGC::GCReason lastGCReason() { return m_lastGCReason; }
318 RegionTree* getRegionTree() { return m_regionTree.get(); }
319
283 static inline size_t allocationSizeFromSize(size_t size) 320 static inline size_t allocationSizeFromSize(size_t size)
284 { 321 {
285 // Check the size before computing the actual allocation size. The 322 // Check the size before computing the actual allocation size. The
286 // allocation size calculation can overflow for large sizes and the chec k 323 // allocation size calculation can overflow for large sizes and the chec k
287 // therefore has to happen before any calculation on the size. 324 // therefore has to happen before any calculation on the size.
288 RELEASE_ASSERT(size < maxHeapObjectSize); 325 RELEASE_ASSERT(size < maxHeapObjectSize);
289 326
290 // Add space for header. 327 // Add space for header.
291 size_t allocationSize = size + sizeof(HeapObjectHeader); 328 size_t allocationSize = size + sizeof(HeapObjectHeader);
292 // Align size with allocation granularity. 329 // Align size with allocation granularity.
293 allocationSize = (allocationSize + allocationMask) & ~allocationMask; 330 allocationSize = (allocationSize + allocationMask) & ~allocationMask;
294 return allocationSize; 331 return allocationSize;
295 } 332 }
296 static Address allocateOnArenaIndex(ThreadState*, size_t, int arenaIndex, si ze_t gcInfoIndex, const char* typeName); 333 static Address allocateOnArenaIndex(ThreadState*, size_t, int arenaIndex, si ze_t gcInfoIndex, const char* typeName);
297 template<typename T> static Address allocate(size_t, bool eagerlySweep = fal se); 334 template<typename T> static Address allocate(size_t, bool eagerlySweep = fal se);
298 template<typename T> static Address reallocate(void* previous, size_t); 335 template<typename T> static Address reallocate(void* previous, size_t);
299 336
300 static const char* gcReasonString(BlinkGC::GCReason); 337 static const char* gcReasonString(BlinkGC::GCReason);
301 static void collectGarbage(BlinkGC::StackState, BlinkGC::GCType, BlinkGC::GC Reason); 338 static void collectGarbage(BlinkGC::StackState, BlinkGC::GCType, BlinkGC::GC Reason);
302 static void collectGarbageForTerminatingThread(ThreadState*); 339 static void collectGarbageForTerminatingThread(ThreadState*);
303 static void collectAllGarbage(); 340 static void collectAllGarbage();
304 341
305 static void processMarkingStack(Visitor*); 342 void processMarkingStack(Visitor*);
306 static void postMarkingProcessing(Visitor*); 343 void postMarkingProcessing(Visitor*);
307 static void globalWeakProcessing(Visitor*); 344 void globalWeakProcessing(Visitor*);
308 static void setForcePreciseGCForTesting();
309 345
310 static void preGC(); 346 void preGC();
311 static void postGC(BlinkGC::GCType); 347 void postGC(BlinkGC::GCType);
312 348
313 // Conservatively checks whether an address is a pointer in any of the 349 // Conservatively checks whether an address is a pointer in any of the
314 // thread heaps. If so marks the object pointed to as live. 350 // thread heaps. If so marks the object pointed to as live.
315 static Address checkAndMarkPointer(Visitor*, Address); 351 Address checkAndMarkPointer(Visitor*, Address);
316 352
317 static size_t objectPayloadSizeForTesting(); 353 size_t objectPayloadSizeForTesting();
318 354
319 static void flushHeapDoesNotContainCache(); 355 void flushHeapDoesNotContainCache();
320 356
321 static FreePagePool* getFreePagePool() { return s_freePagePool; } 357 FreePagePool* getFreePagePool() { return m_freePagePool.get(); }
322 static OrphanedPagePool* getOrphanedPagePool() { return s_orphanedPagePool; } 358 OrphanedPagePool* getOrphanedPagePool() { return m_orphanedPagePool.get(); }
323 359
324 // This look-up uses the region search tree and a negative contains cache to 360 // This look-up uses the region search tree and a negative contains cache to
325 // provide an efficient mapping from arbitrary addresses to the containing 361 // provide an efficient mapping from arbitrary addresses to the containing
326 // heap-page if one exists. 362 // heap-page if one exists.
327 static BasePage* lookup(Address); 363 BasePage* lookupPageForAddress(Address);
328 static RegionTree* getRegionTree();
329 364
330 static const GCInfo* gcInfo(size_t gcInfoIndex) 365 static const GCInfo* gcInfo(size_t gcInfoIndex)
331 { 366 {
332 ASSERT(gcInfoIndex >= 1); 367 ASSERT(gcInfoIndex >= 1);
333 ASSERT(gcInfoIndex < GCInfoTable::maxIndex); 368 ASSERT(gcInfoIndex < GCInfoTable::maxIndex);
334 ASSERT(s_gcInfoTable); 369 ASSERT(s_gcInfoTable);
335 const GCInfo* info = s_gcInfoTable[gcInfoIndex]; 370 const GCInfo* info = s_gcInfoTable[gcInfoIndex];
336 ASSERT(info); 371 ASSERT(info);
337 return info; 372 return info;
338 } 373 }
339 374
340 static ThreadHeapStats& heapStats();
341
342 static double estimatedMarkingTime();
343 static void reportMemoryUsageHistogram(); 375 static void reportMemoryUsageHistogram();
344 static void reportMemoryUsageForTracing(); 376 static void reportMemoryUsageForTracing();
345 static BlinkGC::GCReason lastGCReason() { return s_lastGCReason; }
346 377
347 private: 378 private:
348 // Reset counters that track live and allocated-since-last-GC sizes. 379 // Reset counters that track live and allocated-since-last-GC sizes.
349 static void resetHeapCounters(); 380 void resetHeapCounters();
350 381
351 static int arenaIndexForObjectSize(size_t); 382 static int arenaIndexForObjectSize(size_t);
352 static bool isNormalArenaIndex(int); 383 static bool isNormalArenaIndex(int);
353 384
354 static void decommitCallbackStacks(); 385 void decommitCallbackStacks();
355 386
356 static CallbackStack* s_markingStack; 387 RecursiveMutex m_threadAttachMutex;
357 static CallbackStack* s_postMarkingCallbackStack; 388 ThreadStateSet m_threads;
358 static CallbackStack* s_globalWeakCallbackStack; 389 ThreadHeapStats m_stats;
359 static CallbackStack* s_ephemeronStack; 390 OwnPtr<RegionTree> m_regionTree;
360 static HeapDoesNotContainCache* s_heapDoesNotContainCache; 391 OwnPtr<HeapDoesNotContainCache> m_heapDoesNotContainCache;
361 static FreePagePool* s_freePagePool; 392 OwnPtr<SafePointBarrier> m_safePointBarrier;
362 static OrphanedPagePool* s_orphanedPagePool; 393 OwnPtr<FreePagePool> m_freePagePool;
363 static BlinkGC::GCReason s_lastGCReason; 394 OwnPtr<OrphanedPagePool> m_orphanedPagePool;
395 OwnPtr<CallbackStack> m_markingStack;
396 OwnPtr<CallbackStack> m_postMarkingCallbackStack;
397 OwnPtr<CallbackStack> m_globalWeakCallbackStack;
398 OwnPtr<CallbackStack> m_ephemeronStack;
399 BlinkGC::GCReason m_lastGCReason;
400
401 static ThreadHeap* s_mainThreadHeap;
364 402
365 friend class ThreadState; 403 friend class ThreadState;
366 }; 404 };
367 405
368 template<typename T> 406 template<typename T>
369 struct IsEagerlyFinalizedType { 407 struct IsEagerlyFinalizedType {
370 STATIC_ONLY(IsEagerlyFinalizedType); 408 STATIC_ONLY(IsEagerlyFinalizedType);
371 private: 409 private:
372 typedef char YesType; 410 typedef char YesType;
373 struct NoType { 411 struct NoType {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) 592 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object)
555 { 593 {
556 T** cell = reinterpret_cast<T**>(object); 594 T** cell = reinterpret_cast<T**>(object);
557 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) 595 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell))
558 *cell = nullptr; 596 *cell = nullptr;
559 } 597 }
560 598
561 } // namespace blink 599 } // namespace blink
562 600
563 #endif // Heap_h 601 #endif // Heap_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/exported/Platform.cpp ('k') | third_party/WebKit/Source/platform/heap/Heap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698