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

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

Issue 1200333006: Oilpan: Support nested pre-finalizers (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/platform/heap/HeapTest.cpp ('k') | Source/platform/heap/ThreadState.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 class ThreadState; 64 class ThreadState;
65 class Visitor; 65 class Visitor;
66 66
67 using Address = uint8_t*; 67 using Address = uint8_t*;
68 68
69 using FinalizationCallback = void (*)(void*); 69 using FinalizationCallback = void (*)(void*);
70 using VisitorCallback = void (*)(Visitor*, void* self); 70 using VisitorCallback = void (*)(Visitor*, void* self);
71 using TraceCallback = VisitorCallback; 71 using TraceCallback = VisitorCallback;
72 using WeakCallback = VisitorCallback; 72 using WeakCallback = VisitorCallback;
73 using EphemeronCallback = VisitorCallback; 73 using EphemeronCallback = VisitorCallback;
74 using PreFinalizerCallback = bool(*)(void*);
74 75
75 // Declare that a class has a pre-finalizer function. The function is called in 76 // Declare that a class has a pre-finalizer. The pre-finalizer is called
76 // the object's owner thread. The pre-finalizer is called before any object gets 77 // before any object gets swept, so it is safe to touch on-heap objects
77 // swept, so it is allowed to touch on-heap objects that may be collected in the 78 // that may be collected in the same GC cycle. If you cannot avoid touching
78 // GC cycle. If you cannot avoid touching on-heap objects in a destructor (which 79 // on-heap objects in a destructor (which is not allowed), you can consider
79 // is not allowed), you can consider using the pre-finalizer or 80 // using the pre-finalizer. The only restriction is that the pre-finalizer
80 // EARGERY_FINALIZED. The only restriction is that the pre-finalizer must not 81 // must not resurrect dead objects (e.g., store unmarked objects into
81 // resurrect dead objects (e.g., store unmarked objects into Members etc). 82 // Members etc). The pre-finalizer is called on the thread that registered
83 // the pre-finalizer.
82 // 84 //
83 // This feature is similar to the HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>> 85 // Since a pre-finalizer adds pressure on GC performance, you should use it
86 // only if necessary.
87 //
88 // A pre-finalizer is similar to the HeapHashMap<WeakMember<Foo>, OwnPtr<Dispose r>>
84 // idiom. The difference between this and the idiom is that pre-finalizer 89 // idiom. The difference between this and the idiom is that pre-finalizer
85 // function is called whenever an object is destructed with this feature. The 90 // function is called whenever an object is destructed with this feature. The
86 // HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>> idiom requires an assumption 91 // HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>> idiom requires an assumption
87 // that the HeapHashMap outlives objects pointed by WeakMembers. 92 // that the HeapHashMap outlives objects pointed by WeakMembers.
88 // FIXME: Replace all of the HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>> 93 // FIXME: Replace all of the HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>>
89 // idiom usages with the pre-finalizer if the replacement won't cause 94 // idiom usages with the pre-finalizer if the replacement won't cause
90 // performance regressions. 95 // performance regressions.
91 // 96 //
92 // See ThreadState::registerPreFinalizer.
93 //
94 // Usage: 97 // Usage:
95 // 98 //
96 // class Foo : GarbageCollected<Foo> { 99 // class Foo : GarbageCollected<Foo> {
97 // USING_PRE_FINALIZER(Foo, dispose); 100 // USING_PRE_FINALIZER(Foo, dispose);
98 // public: 101 // public:
99 // Foo() 102 // Foo()
100 // { 103 // {
101 // ThreadState::current()->registerPreFinalizer(*this); 104 // ThreadState::current()->registerPreFinalizer(this, dispose);
102 // } 105 // }
103 // private: 106 // private:
104 // void dispose(); 107 // void dispose()
108 // {
109 // m_bar->...; // It is safe to touch other on-heap objects.
110 // }
105 // Member<Bar> m_bar; 111 // Member<Bar> m_bar;
106 // }; 112 // };
107 // 113 #define USING_PRE_FINALIZER(Class, preFinalizer) \
108 // void Foo::dispose() 114 public: \
109 // { 115 static bool invokePreFinalizer(void* object) \
110 // m_bar->... 116 { \
111 // } 117 Class* self = reinterpret_cast<Class*>(object); \
112 #define USING_PRE_FINALIZER(Class, method) \ 118 if (Heap::isHeapObjectAlive(self)) \
113 public: \ 119 return false; \
114 static bool invokePreFinalizer(void* object) \ 120 self->Class::preFinalizer(); \
115 { \ 121 return true; \
116 Class* self = reinterpret_cast<Class*>(object); \ 122 } \
117 if (Heap::isHeapObjectAlive(self)) \ 123 using UsingPreFinazlizerMacroNeedsTrailingSemiColon = char
118 return false; \
119 self->method(); \
120 return true; \
121 } \
122 using UsingPreFinazlizerMacroNeedsTrailingSemiColon = char
123 124
124 #if ENABLE(OILPAN) 125 #if ENABLE(OILPAN)
125 #define WILL_BE_USING_PRE_FINALIZER(Class, method) USING_PRE_FINALIZER(Class, me thod) 126 #define WILL_BE_USING_PRE_FINALIZER(Class, method) USING_PRE_FINALIZER(Class, me thod)
126 #else 127 #else
127 #define WILL_BE_USING_PRE_FINALIZER(Class, method) 128 #define WILL_BE_USING_PRE_FINALIZER(Class, method)
128 #endif 129 #endif
129 130
130 // List of typed heaps. The list is used to generate the implementation 131 // List of typed heaps. The list is used to generate the implementation
131 // of typed heap related methods. 132 // of typed heap related methods.
132 // 133 //
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 void reportMarkSweepStats(const char* statsName, const ClassAgeCountsMap&) c onst; 530 void reportMarkSweepStats(const char* statsName, const ClassAgeCountsMap&) c onst;
530 #endif 531 #endif
531 532
532 void pushThreadLocalWeakCallback(void*, WeakCallback); 533 void pushThreadLocalWeakCallback(void*, WeakCallback);
533 bool popAndInvokeThreadLocalWeakCallback(Visitor*); 534 bool popAndInvokeThreadLocalWeakCallback(Visitor*);
534 void threadLocalWeakProcessing(); 535 void threadLocalWeakProcessing();
535 536
536 size_t objectPayloadSizeForTesting(); 537 size_t objectPayloadSizeForTesting();
537 void prepareHeapForTermination(); 538 void prepareHeapForTermination();
538 539
539 // Request to call a pref-finalizer of the target object before the object 540 // Register the pre-finalizer for the |self| object. This method is normally
540 // is destructed. The class T must have USING_PRE_FINALIZER(). The 541 // called in the constructor of the |self| object. The class T must have
541 // argument should be |*this|. Registering a lot of objects affects GC 542 // USING_PRE_FINALIZER().
542 // performance. We should register an object only if the object really
543 // requires pre-finalizer, and we should unregister the object if
544 // pre-finalizer is unnecessary.
545 template<typename T> 543 template<typename T>
546 void registerPreFinalizer(T& target) 544 void registerPreFinalizer(T* self)
547 { 545 {
546 static_assert(sizeof(&T::invokePreFinalizer) > 0, "USING_PRE_FINALIZER(T ) must be defined.");
548 checkThread(); 547 checkThread();
549 ASSERT(!m_preFinalizers.contains(&target));
550 ASSERT(!sweepForbidden()); 548 ASSERT(!sweepForbidden());
551 m_preFinalizers.add(&target, &T::invokePreFinalizer); 549 auto it = m_preFinalizers.find(self);
550 Vector<PreFinalizerCallback>* callbackVector;
551 if (it == m_preFinalizers.end()) {
552 callbackVector = m_preFinalizers.add(self, adoptPtr(new Vector<PreFi nalizerCallback>)).storedValue->value.get();
553 } else {
554 callbackVector = it->value.get();
555 }
556 ASSERT(!callbackVector->contains(&T::invokePreFinalizer));
557 callbackVector->append(&T::invokePreFinalizer);
552 } 558 }
553 559
554 // Cancel above requests. The argument should be |*this|. This function is 560 // Unregister the pre-finalizer for the |self| object.
555 // ignored if it is called in pre-finalizer functions.
556 template<typename T> 561 template<typename T>
557 void unregisterPreFinalizer(T& target) 562 void unregisterPreFinalizer(T* self)
558 { 563 {
559 static_assert(sizeof(&T::invokePreFinalizer) > 0, "Declaration of USING_ PRE_FINALIZER()'s prefinalizer trampoline not in scope."); 564 static_assert(sizeof(&T::invokePreFinalizer) > 0, "USING_PRE_FINALIZER(T ) must be defined.");
560 checkThread(); 565 checkThread();
561 unregisterPreFinalizerInternal(&target); 566 // Ignore pre-finalizers called during pre-finalizers or destructors.
567 if (sweepForbidden())
568 return;
569 auto it = m_preFinalizers.find(self);
570 ASSERT(it != m_preFinalizers.end());
571 Vector<PreFinalizerCallback>* callbackVector = it->value.get();
572 ASSERT(it->value->contains(&T::invokePreFinalizer));
573 callbackVector->remove(callbackVector->find(&T::invokePreFinalizer));
574 if (callbackVector->isEmpty())
575 m_preFinalizers.remove(it);
562 } 576 }
563 577
564 Vector<PageMemoryRegion*>& allocatedRegionsSinceLastGC() { return m_allocate dRegionsSinceLastGC; } 578 Vector<PageMemoryRegion*>& allocatedRegionsSinceLastGC() { return m_allocate dRegionsSinceLastGC; }
565 579
566 void shouldFlushHeapDoesNotContainCache() { m_shouldFlushHeapDoesNotContainC ache = true; } 580 void shouldFlushHeapDoesNotContainCache() { m_shouldFlushHeapDoesNotContainC ache = true; }
567 581
568 void registerTraceDOMWrappers(v8::Isolate* isolate, void (*traceDOMWrappers) (v8::Isolate*, Visitor*)) 582 void registerTraceDOMWrappers(v8::Isolate* isolate, void (*traceDOMWrappers) (v8::Isolate*, Visitor*))
569 { 583 {
570 m_isolate = isolate; 584 m_isolate = isolate;
571 m_traceDOMWrappers = traceDOMWrappers; 585 m_traceDOMWrappers = traceDOMWrappers;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 // When ThreadState is detaching from non-main thread its 698 // When ThreadState is detaching from non-main thread its
685 // heap is expected to be empty (because it is going away). 699 // heap is expected to be empty (because it is going away).
686 // Perform registered cleanup tasks and garbage collection 700 // Perform registered cleanup tasks and garbage collection
687 // to sweep away any objects that are left on this heap. 701 // to sweep away any objects that are left on this heap.
688 // We assert that nothing must remain after this cleanup. 702 // We assert that nothing must remain after this cleanup.
689 // If assertion does not hold we crash as we are potentially 703 // If assertion does not hold we crash as we are potentially
690 // in the dangling pointer situation. 704 // in the dangling pointer situation.
691 void cleanup(); 705 void cleanup();
692 void cleanupPages(); 706 void cleanupPages();
693 707
694 void unregisterPreFinalizerInternal(void*);
695 void invokePreFinalizers(); 708 void invokePreFinalizers();
696 709
697 void takeSnapshot(SnapshotType); 710 void takeSnapshot(SnapshotType);
698 #if ENABLE(GC_PROFILING) 711 #if ENABLE(GC_PROFILING)
699 void snapshotFreeList(); 712 void snapshotFreeList();
700 #endif 713 #endif
701 void clearHeapAges(); 714 void clearHeapAges();
702 int heapIndexOfVectorHeapLeastRecentlyExpanded(int beginHeapIndex, int endHe apIndex); 715 int heapIndexOfVectorHeapLeastRecentlyExpanded(int beginHeapIndex, int endHe apIndex);
703 716
704 friend class SafePointAwareMutexLocker; 717 friend class SafePointAwareMutexLocker;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 size_t m_heapAges[NumberOfHeaps]; 750 size_t m_heapAges[NumberOfHeaps];
738 size_t m_currentHeapAges; 751 size_t m_currentHeapAges;
739 752
740 bool m_isTerminating; 753 bool m_isTerminating;
741 GarbageCollectedMixinConstructorMarker* m_gcMixinMarker; 754 GarbageCollectedMixinConstructorMarker* m_gcMixinMarker;
742 755
743 bool m_shouldFlushHeapDoesNotContainCache; 756 bool m_shouldFlushHeapDoesNotContainCache;
744 GCState m_gcState; 757 GCState m_gcState;
745 758
746 CallbackStack* m_threadLocalWeakCallbackStack; 759 CallbackStack* m_threadLocalWeakCallbackStack;
747 HashMap<void*, bool (*)(void*)> m_preFinalizers; 760 HashMap<void*, OwnPtr<Vector<PreFinalizerCallback>>> m_preFinalizers;
748 761
749 v8::Isolate* m_isolate; 762 v8::Isolate* m_isolate;
750 void (*m_traceDOMWrappers)(v8::Isolate*, Visitor*); 763 void (*m_traceDOMWrappers)(v8::Isolate*, Visitor*);
751 764
752 #if defined(ADDRESS_SANITIZER) 765 #if defined(ADDRESS_SANITIZER)
753 void* m_asanFakeStack; 766 void* m_asanFakeStack;
754 #endif 767 #endif
755 768
756 Vector<PageMemoryRegion*> m_allocatedRegionsSinceLastGC; 769 Vector<PageMemoryRegion*> m_allocatedRegionsSinceLastGC;
757 770
(...skipping 22 matching lines...) Expand all
780 }; 793 };
781 794
782 template<> class ThreadStateFor<AnyThread> { 795 template<> class ThreadStateFor<AnyThread> {
783 public: 796 public:
784 static ThreadState* state() { return ThreadState::current(); } 797 static ThreadState* state() { return ThreadState::current(); }
785 }; 798 };
786 799
787 } // namespace blink 800 } // namespace blink
788 801
789 #endif // ThreadState_h 802 #endif // ThreadState_h
OLDNEW
« no previous file with comments | « Source/platform/heap/HeapTest.cpp ('k') | Source/platform/heap/ThreadState.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698