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

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

Issue 1477023003: Refactor the Heap into ThreadHeap to prepare for per thread heaps Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 48
49 namespace v8 { 49 namespace v8 {
50 class Isolate; 50 class Isolate;
51 }; 51 };
52 52
53 namespace blink { 53 namespace blink {
54 54
55 class BasePage; 55 class BasePage;
56 class CallbackStack; 56 class CallbackStack;
57 class CrossThreadPersistentRegion; 57 class CrossThreadPersistentRegion;
58 class FreePagePool;
58 struct GCInfo; 59 struct GCInfo;
59 class GarbageCollectedMixinConstructorMarker; 60 class GarbageCollectedMixinConstructorMarker;
61 class HeapDoesNotContainCache;
60 class HeapObjectHeader; 62 class HeapObjectHeader;
63 class OrphanedPagePool;
61 class PersistentRegion; 64 class PersistentRegion;
65 class XThreadPersistentRegion;
62 class BaseHeap; 66 class BaseHeap;
63 class SafePointAwareMutexLocker; 67 class SafePointAwareMutexLocker;
64 class SafePointBarrier; 68 class SafePointBarrier;
65 class ThreadState; 69 class ThreadState;
66 class Visitor; 70 class Visitor;
71 class PageMemoryRegion;
67 72
68 // Declare that a class has a pre-finalizer. The pre-finalizer is called 73 // Declare that a class has a pre-finalizer. The pre-finalizer is called
69 // before any object gets swept, so it is safe to touch on-heap objects 74 // before any object gets swept, so it is safe to touch on-heap objects
70 // that may be collected in the same GC cycle. If you cannot avoid touching 75 // that may be collected in the same GC cycle. If you cannot avoid touching
71 // on-heap objects in a destructor (which is not allowed), you can consider 76 // on-heap objects in a destructor (which is not allowed), you can consider
72 // using the pre-finalizer. The only restriction is that the pre-finalizer 77 // using the pre-finalizer. The only restriction is that the pre-finalizer
73 // must not resurrect dead objects (e.g., store unmarked objects into 78 // must not resurrect dead objects (e.g., store unmarked objects into
74 // Members etc). The pre-finalizer is called on the thread that registered 79 // Members etc). The pre-finalizer is called on the thread that registered
75 // the pre-finalizer. 80 // the pre-finalizer.
76 // 81 //
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 #define WILL_BE_USING_PRE_FINALIZER(Class, method) USING_PRE_FINALIZER(Class, me thod) 123 #define WILL_BE_USING_PRE_FINALIZER(Class, method) USING_PRE_FINALIZER(Class, me thod)
119 #else 124 #else
120 #define WILL_BE_USING_PRE_FINALIZER(Class, method) 125 #define WILL_BE_USING_PRE_FINALIZER(Class, method)
121 #endif 126 #endif
122 127
123 class PLATFORM_EXPORT ThreadState { 128 class PLATFORM_EXPORT ThreadState {
124 WTF_MAKE_NONCOPYABLE(ThreadState); 129 WTF_MAKE_NONCOPYABLE(ThreadState);
125 public: 130 public:
126 typedef std::pair<void*, PreFinalizerCallback> PreFinalizer; 131 typedef std::pair<void*, PreFinalizerCallback> PreFinalizer;
127 132
133 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted
134 // by base addresses.
135 class RegionTree {
136 public:
137 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (nullptr), m_right(nullptr) { }
138 ~RegionTree()
139 {
140 delete m_left;
141 delete m_right;
142 }
143 PageMemoryRegion* lookup(Address);
144 static void add(RegionTree*, RegionTree**);
145 static void remove(PageMemoryRegion*, RegionTree**);
146 private:
147 PageMemoryRegion* m_region;
148 RegionTree* m_left;
149 RegionTree* m_right;
150 };
151
128 // See setGCState() for possible state transitions. 152 // See setGCState() for possible state transitions.
129 enum GCState { 153 enum GCState {
130 NoGCScheduled, 154 NoGCScheduled,
131 IdleGCScheduled, 155 IdleGCScheduled,
132 PreciseGCScheduled, 156 PreciseGCScheduled,
133 FullGCScheduled, 157 FullGCScheduled,
134 PageNavigationGCScheduled, 158 PageNavigationGCScheduled,
135 GCRunning, 159 GCRunning,
136 EagerSweepScheduled, 160 EagerSweepScheduled,
137 LazySweepScheduled, 161 LazySweepScheduled,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 // the stack start of the main thread, we judge that we are in 242 // the stack start of the main thread, we judge that we are in
219 // the main thread. 243 // the main thread.
220 if (LIKELY(addressDiff < s_mainThreadUnderestimatedStackSize)) { 244 if (LIKELY(addressDiff < s_mainThreadUnderestimatedStackSize)) {
221 ASSERT(**s_threadSpecific == mainThreadState()); 245 ASSERT(**s_threadSpecific == mainThreadState());
222 return mainThreadState(); 246 return mainThreadState();
223 } 247 }
224 // TLS lookup is slow. 248 // TLS lookup is slow.
225 return **s_threadSpecific; 249 return **s_threadSpecific;
226 #endif 250 #endif
227 } 251 }
252 static ThreadState* terminating()
253 {
254 // TLS lookup is fast in these platforms.
255 return **s_threadSpecificTerminating;
256 }
228 257
229 static ThreadState* mainThreadState() 258 static ThreadState* mainThreadState()
230 { 259 {
231 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage); 260 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage);
232 } 261 }
233 262
263 CallbackStack* markingStack() const { return m_markingStack.get(); }
264 CallbackStack* postMarkingCallbackStack() const { return m_postMarkingCallba ckStack.get(); }
265 CallbackStack* globalWeakCallbackStack() const { return m_globalWeakCallback Stack.get(); }
266 CallbackStack* ephemeronStack() const { return m_ephemeronStack.get(); }
267 FreePagePool* freePagePool() const { return m_freePagePool.get(); }
268 void setMarkedObjectSizeAtLastCompleteSweep(size_t size) { releaseStore(&m_m arkedObjectSizeAtLastCompleteSweep, size); }
269 size_t markedObjectSizeAtLastCompleteSweep() { return acquireLoad(&m_markedO bjectSizeAtLastCompleteSweep); }
270 void increaseAllocatedObjectSize(size_t delta) { atomicAdd(&m_allocatedObjec tSize, static_cast<long>(delta)); }
271 void decreaseAllocatedObjectSize(size_t delta) { atomicSubtract(&m_allocated ObjectSize, static_cast<long>(delta)); }
272 size_t allocatedObjectSize() { return acquireLoad(&m_allocatedObjectSize); }
273 void increaseMarkedObjectSize(size_t delta) { atomicAdd(&m_markedObjectSize, static_cast<long>(delta)); }
274 size_t markedObjectSize() { return acquireLoad(&m_markedObjectSize); }
275 void increaseAllocatedSpace(size_t delta) { atomicAdd(&m_allocatedSpace, sta tic_cast<long>(delta)); }
276 void decreaseAllocatedSpace(size_t delta) { atomicSubtract(&m_allocatedSpace , static_cast<long>(delta)); }
277 size_t allocatedSpace() { return acquireLoad(&m_allocatedSpace); }
278 size_t objectSizeAtLastGC() { return acquireLoad(&m_objectSizeAtLastGC); }
279 void increaseWrapperCount(size_t delta) { atomicAdd(&m_wrapperCount, static_ cast<long>(delta)); }
280 void decreaseWrapperCount(size_t delta) { atomicSubtract(&m_wrapperCount, st atic_cast<long>(delta)); }
281 size_t wrapperCount() { return acquireLoad(&m_wrapperCount); }
282 size_t wrapperCountAtLastGC() { return acquireLoad(&m_wrapperCountAtLastGC); }
283 void increaseCollectedWrapperCount(size_t delta) { atomicAdd(&m_collectedWra pperCount, static_cast<long>(delta)); }
284 size_t collectedWrapperCount() { return acquireLoad(&m_collectedWrapperCount ); }
285 size_t partitionAllocSizeAtLastGC() { return acquireLoad(&m_partitionAllocSi zeAtLastGC); }
286
287 void setEstimatedMarkingTimePerByte(double estimatedMarkingTimePerByte) { m_ estimatedMarkingTimePerByte = estimatedMarkingTimePerByte; }
288 double estimatedMarkingTimePerByte() const { return m_estimatedMarkingTimePe rByte; }
289 void setShutdownCalled(bool shutdownCalled) { m_shutdownCalled = shutdownCal led; }
290 bool shutdownCalled() const { return m_shutdownCalled; }
291 HeapDoesNotContainCache* heapDoesNotContainCache() const { return m_heapDoes NotContainCache.get(); }
292 RegionTree* regionTree() const { return m_regionTree; }
293 void setRegionTree(RegionTree* tree) { m_regionTree = tree; }
294
295 double estimatedMarkingTime();
296 void reportMemoryUsageHistogram();
297 void reportMemoryUsageForTracing();
298
299 #if ENABLE(ASSERT)
300 void incrementGcGeneration() {
301 if (++m_gcGeneration == 0)
302 m_gcGeneration = 1;
303 }
304 uint16_t gcGeneration() { return m_gcGeneration; }
305 #endif
306
307 void flushHeapDoesNotContainCache();
308 OrphanedPagePool* orphanedPagePool() { return m_orphanedPagePool.get(); }
309
310 // Reset counters that track live and allocated-since-last-GC sizes.
311 void resetHeapCounters();
312
234 bool isMainThread() const { return this == mainThreadState(); } 313 bool isMainThread() const { return this == mainThreadState(); }
235 #if ENABLE(ASSERT) 314 #if ENABLE(ASSERT)
236 bool checkThread() const { return m_thread == currentThread(); } 315 bool checkThread() const { return m_thread == currentThread(); }
237 #endif 316 #endif
238 317
239 void performIdleGC(double deadlineSeconds); 318 void performIdleGC(double deadlineSeconds);
240 void performIdleLazySweep(double deadlineSeconds); 319 void performIdleLazySweep(double deadlineSeconds);
241 320
242 void scheduleIdleGC(); 321 void scheduleIdleGC();
243 void scheduleIdleLazySweep(); 322 void scheduleIdleLazySweep();
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 #if ENABLE(ASSERT) 440 #if ENABLE(ASSERT)
362 // Infrastructure to determine if an address is within one of the 441 // Infrastructure to determine if an address is within one of the
363 // address ranges for the Blink heap. If the address is in the Blink 442 // address ranges for the Blink heap. If the address is in the Blink
364 // heap the containing heap page is returned. 443 // heap the containing heap page is returned.
365 BasePage* findPageFromAddress(Address); 444 BasePage* findPageFromAddress(Address);
366 BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddr ess(reinterpret_cast<Address>(const_cast<void*>(pointer))); } 445 BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddr ess(reinterpret_cast<Address>(const_cast<void*>(pointer))); }
367 #endif 446 #endif
368 447
369 // A region of PersistentNodes allocated on the given thread. 448 // A region of PersistentNodes allocated on the given thread.
370 PersistentRegion* persistentRegion() const { return m_persistentRegion.get() ; } 449 PersistentRegion* persistentRegion() const { return m_persistentRegion.get() ; }
450 XThreadPersistentRegion* xThreadPersistentRegion() const { return m_xThreadP ersistentRegion.get(); }
371 // A region of PersistentNodes not owned by any particular thread. 451 // A region of PersistentNodes not owned by any particular thread.
372 static CrossThreadPersistentRegion& crossThreadPersistentRegion(); 452 static CrossThreadPersistentRegion& crossThreadPersistentRegion();
373 453
374 // Visit local thread stack and trace all pointers conservatively. 454 // Visit local thread stack and trace all pointers conservatively.
375 void visitStack(Visitor*); 455 void visitStack(Visitor*);
376 456
377 // Visit the asan fake stack frame corresponding to a slot on the 457 // Visit the asan fake stack frame corresponding to a slot on the
378 // real machine stack if there is one. 458 // real machine stack if there is one.
379 void visitAsanFakeStackForPointer(Visitor*, Address); 459 void visitAsanFakeStackForPointer(Visitor*, Address);
380 460
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 } 583 }
504 void allocationPointAdjusted(int heapIndex); 584 void allocationPointAdjusted(int heapIndex);
505 void promptlyFreed(size_t gcInfoIndex); 585 void promptlyFreed(size_t gcInfoIndex);
506 586
507 void accumulateSweepingTime(double time) { m_accumulatedSweepingTime += time ; } 587 void accumulateSweepingTime(double time) { m_accumulatedSweepingTime += time ; }
508 588
509 #if OS(WIN) && COMPILER(MSVC) 589 #if OS(WIN) && COMPILER(MSVC)
510 size_t threadStackSize(); 590 size_t threadStackSize();
511 #endif 591 #endif
512 592
593 void setIsolated(bool isolated) { m_isolated = isolated; }
594 bool isolated() { return m_isolated; }
595
513 private: 596 private:
514 enum SnapshotType { 597 enum SnapshotType {
515 HeapSnapshot, 598 HeapSnapshot,
516 FreelistSnapshot 599 FreelistSnapshot
517 }; 600 };
518 601
519 ThreadState(); 602 ThreadState();
520 ~ThreadState(); 603 ~ThreadState();
521 604
522 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); 605 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 int heapIndexOfVectorHeapLeastRecentlyExpanded(int beginHeapIndex, int endHe apIndex); 672 int heapIndexOfVectorHeapLeastRecentlyExpanded(int beginHeapIndex, int endHe apIndex);
590 673
591 // Should only be called under protection of threadAttachMutex(). 674 // Should only be called under protection of threadAttachMutex().
592 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in terruptors; } 675 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in terruptors; }
593 676
594 friend class SafePointAwareMutexLocker; 677 friend class SafePointAwareMutexLocker;
595 friend class SafePointBarrier; 678 friend class SafePointBarrier;
596 friend class SafePointScope; 679 friend class SafePointScope;
597 680
598 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific; 681 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific;
682 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecificTerminating;
599 static uintptr_t s_mainThreadStackStart; 683 static uintptr_t s_mainThreadStackStart;
600 static uintptr_t s_mainThreadUnderestimatedStackSize; 684 static uintptr_t s_mainThreadUnderestimatedStackSize;
601 static SafePointBarrier* s_safePointBarrier; 685 static SafePointBarrier* s_safePointBarrier;
602 686
603 // We can't create a static member of type ThreadState here 687 // We can't create a static member of type ThreadState here
604 // because it will introduce global constructor and destructor. 688 // because it will introduce global constructor and destructor.
605 // We would like to manage lifetime of the ThreadState attached 689 // We would like to manage lifetime of the ThreadState attached
606 // to the main thread explicitly instead and still use normal 690 // to the main thread explicitly instead and still use normal
607 // constructor and destructor for the ThreadState class. 691 // constructor and destructor for the ThreadState class.
608 // For this we reserve static storage for the main ThreadState 692 // For this we reserve static storage for the main ThreadState
609 // and lazily construct ThreadState in it using placement new. 693 // and lazily construct ThreadState in it using placement new.
610 static uint8_t s_mainThreadStateStorage[]; 694 static uint8_t s_mainThreadStateStorage[];
611 695
612 ThreadIdentifier m_thread; 696 ThreadIdentifier m_thread;
697 bool m_isolated;
613 OwnPtr<PersistentRegion> m_persistentRegion; 698 OwnPtr<PersistentRegion> m_persistentRegion;
699 OwnPtr<XThreadPersistentRegion> m_xThreadPersistentRegion;
614 BlinkGC::StackState m_stackState; 700 BlinkGC::StackState m_stackState;
615 #if OS(WIN) && COMPILER(MSVC) 701 #if OS(WIN) && COMPILER(MSVC)
616 size_t m_threadStackSize; 702 size_t m_threadStackSize;
617 #endif 703 #endif
618 intptr_t* m_startOfStack; 704 intptr_t* m_startOfStack;
619 intptr_t* m_endOfStack; 705 intptr_t* m_endOfStack;
620 706
621 void* m_safePointScopeMarker; 707 void* m_safePointScopeMarker;
622 Vector<Address> m_safePointStackCopy; 708 Vector<Address> m_safePointStackCopy;
623 bool m_atSafePoint; 709 bool m_atSafePoint;
(...skipping 28 matching lines...) Expand all
652 void* m_asanFakeStack; 738 void* m_asanFakeStack;
653 #endif 739 #endif
654 740
655 // Ideally we want to allocate an array of size |gcInfoTableMax| but it will 741 // Ideally we want to allocate an array of size |gcInfoTableMax| but it will
656 // waste memory. Thus we limit the array size to 2^8 and share one entry 742 // waste memory. Thus we limit the array size to 2^8 and share one entry
657 // with multiple types of vectors. This won't be an issue in practice, 743 // with multiple types of vectors. This won't be an issue in practice,
658 // since there will be less than 2^8 types of objects in common cases. 744 // since there will be less than 2^8 types of objects in common cases.
659 static const int likelyToBePromptlyFreedArraySize = (1 << 8); 745 static const int likelyToBePromptlyFreedArraySize = (1 << 8);
660 static const int likelyToBePromptlyFreedArrayMask = likelyToBePromptlyFreedA rraySize - 1; 746 static const int likelyToBePromptlyFreedArrayMask = likelyToBePromptlyFreedA rraySize - 1;
661 OwnPtr<int[]> m_likelyToBePromptlyFreed; 747 OwnPtr<int[]> m_likelyToBePromptlyFreed;
748
749 OwnPtr<CallbackStack> m_markingStack;
750 OwnPtr<CallbackStack> m_postMarkingCallbackStack;
751 OwnPtr<CallbackStack> m_globalWeakCallbackStack;
752 OwnPtr<CallbackStack> m_ephemeronStack;
753 OwnPtr<FreePagePool> m_freePagePool;
754 size_t m_allocatedSpace;
755 size_t m_allocatedObjectSize;
756 size_t m_objectSizeAtLastGC;
757 size_t m_markedObjectSize;
758 size_t m_markedObjectSizeAtLastCompleteSweep;
759 size_t m_wrapperCount;
760 size_t m_wrapperCountAtLastGC;
761 size_t m_collectedWrapperCount;
762 size_t m_partitionAllocSizeAtLastGC;
763 double m_estimatedMarkingTimePerByte;
764 #if ENABLE(ASSERT)
765 uint16_t m_gcGeneration;
766 #endif
767 OwnPtr<HeapDoesNotContainCache> m_heapDoesNotContainCache;
768 bool m_shutdownCalled;
769 OwnPtr<OrphanedPagePool> m_orphanedPagePool;
770 RegionTree* m_regionTree;
662 }; 771 };
663 772
664 template<ThreadAffinity affinity> class ThreadStateFor; 773 template<ThreadAffinity affinity> class ThreadStateFor;
665 774
666 template<> class ThreadStateFor<MainThreadOnly> { 775 template<> class ThreadStateFor<MainThreadOnly> {
667 public: 776 public:
668 static ThreadState* state() 777 static ThreadState* state()
669 { 778 {
670 // This specialization must only be used from the main thread. 779 // This specialization must only be used from the main thread.
671 ASSERT(ThreadState::current()->isMainThread()); 780 ASSERT(ThreadState::current()->isMainThread());
672 return ThreadState::mainThreadState(); 781 return ThreadState::mainThreadState();
673 } 782 }
674 }; 783 };
675 784
676 template<> class ThreadStateFor<AnyThread> { 785 template<> class ThreadStateFor<AnyThread> {
677 public: 786 public:
678 static ThreadState* state() { return ThreadState::current(); } 787 static ThreadState* state() { return ThreadState::current(); }
679 }; 788 };
680 789
681 } // namespace blink 790 } // namespace blink
682 791
683 #endif // ThreadState_h 792 #endif // ThreadState_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698