OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef GarbageCollected_h | 5 #ifndef GarbageCollected_h |
6 #define GarbageCollected_h | 6 #define GarbageCollected_h |
7 | 7 |
8 #include "platform/heap/ThreadState.h" | 8 #include "platform/heap/ThreadState.h" |
9 #include "wtf/Allocator.h" | 9 #include "wtf/Allocator.h" |
10 #include "wtf/Assertions.h" | 10 #include "wtf/Assertions.h" |
11 #include "wtf/TypeTraits.h" | 11 #include "wtf/TypeTraits.h" |
12 | 12 |
13 namespace blink { | 13 namespace blink { |
14 | 14 |
15 template <typename T> | 15 template <typename T> |
16 class GarbageCollected; | 16 class GarbageCollected; |
17 class HeapObjectHeader; | |
18 class InlinedGlobalMarkingVisitor; | 17 class InlinedGlobalMarkingVisitor; |
19 class TraceWrapperBase; | 18 class TraceWrapperBase; |
20 class WrapperVisitor; | |
21 | 19 |
22 // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or | 20 // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or |
23 // field when checking for proper usage. When using GC_PLUGIN_IGNORE | 21 // field when checking for proper usage. When using GC_PLUGIN_IGNORE |
24 // a bug-number should be provided as an argument where the bug describes | 22 // a bug-number should be provided as an argument where the bug describes |
25 // what needs to happen to remove the GC_PLUGIN_IGNORE again. | 23 // what needs to happen to remove the GC_PLUGIN_IGNORE again. |
26 #if COMPILER(CLANG) | 24 #if COMPILER(CLANG) |
27 #define GC_PLUGIN_IGNORE(bug) \ | 25 #define GC_PLUGIN_IGNORE(bug) \ |
28 __attribute__((annotate("blink_gc_plugin_ignore"))) | 26 __attribute__((annotate("blink_gc_plugin_ignore"))) |
29 #else | 27 #else |
30 #define GC_PLUGIN_IGNORE(bug) | 28 #define GC_PLUGIN_IGNORE(bug) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 // Note that this is only enabled for Member<B>. For Member<A> which we can | 68 // Note that this is only enabled for Member<B>. For Member<A> which we can |
71 // compute the object header addr statically, this dynamic dispatch is not used. | 69 // compute the object header addr statically, this dynamic dispatch is not used. |
72 // | 70 // |
73 class PLATFORM_EXPORT GarbageCollectedMixin { | 71 class PLATFORM_EXPORT GarbageCollectedMixin { |
74 public: | 72 public: |
75 typedef int IsGarbageCollectedMixinMarker; | 73 typedef int IsGarbageCollectedMixinMarker; |
76 virtual void adjustAndMark(Visitor*) const = 0; | 74 virtual void adjustAndMark(Visitor*) const = 0; |
77 virtual void trace(Visitor*) {} | 75 virtual void trace(Visitor*) {} |
78 virtual void adjustAndMark(InlinedGlobalMarkingVisitor) const = 0; | 76 virtual void adjustAndMark(InlinedGlobalMarkingVisitor) const = 0; |
79 virtual void trace(InlinedGlobalMarkingVisitor); | 77 virtual void trace(InlinedGlobalMarkingVisitor); |
80 virtual void adjustAndMarkAndTraceWrapper(const WrapperVisitor*) const = 0; | |
81 virtual void adjustAndMarkWrapperNoTracing(const WrapperVisitor*) const = 0; | |
82 virtual void adjustAndTraceMarkedWrapper(const WrapperVisitor*) const = 0; | |
83 virtual bool isHeapObjectAlive() const = 0; | 78 virtual bool isHeapObjectAlive() const = 0; |
84 virtual HeapObjectHeader* adjustAndGetHeapObjectHeader() const = 0; | |
85 }; | 79 }; |
86 | 80 |
87 #define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(VISITOR, TYPE) \ | 81 #define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(VISITOR, TYPE) \ |
88 public: \ | 82 public: \ |
89 void adjustAndMark(VISITOR visitor) const override { \ | 83 void adjustAndMark(VISITOR visitor) const override { \ |
90 typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \ | 84 typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \ |
91 blink::GarbageCollected> \ | 85 blink::GarbageCollected> \ |
92 IsSubclassOfGarbageCollected; \ | 86 IsSubclassOfGarbageCollected; \ |
93 static_assert( \ | 87 static_assert( \ |
94 IsSubclassOfGarbageCollected::value, \ | 88 IsSubclassOfGarbageCollected::value, \ |
95 "only garbage collected objects can have garbage collected mixins"); \ | 89 "only garbage collected objects can have garbage collected mixins"); \ |
96 if (TraceEagerlyTrait<TYPE>::value) { \ | 90 if (TraceEagerlyTrait<TYPE>::value) { \ |
97 if (visitor->ensureMarked(static_cast<const TYPE*>(this))) \ | 91 if (visitor->ensureMarked(static_cast<const TYPE*>(this))) \ |
98 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \ | 92 TraceTrait<TYPE>::trace(visitor, const_cast<TYPE*>(this)); \ |
99 return; \ | 93 return; \ |
100 } \ | 94 } \ |
101 visitor->mark(static_cast<const TYPE*>(this), \ | 95 visitor->mark(static_cast<const TYPE*>(this), \ |
102 &blink::TraceTrait<TYPE>::trace); \ | 96 &blink::TraceTrait<TYPE>::trace); \ |
103 } \ | 97 } \ |
104 \ | 98 \ |
105 private: | 99 private: |
106 | 100 |
107 #define DEFINE_GARBAGE_COLLECTED_MIXIN_WRAPPER_METHODS(TYPE) \ | |
108 private: \ | |
109 typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \ | |
110 blink::GarbageCollected> \ | |
111 IsSubclassOfGarbageCollected; \ | |
112 \ | |
113 public: \ | |
114 void adjustAndMarkAndTraceWrapper(const WrapperVisitor* visitor) \ | |
115 const override { \ | |
116 static_assert( \ | |
117 IsSubclassOfGarbageCollected::value, \ | |
118 "only garbage collected objects can have garbage collected mixins"); \ | |
119 return AdjustAndMarkTrait<TYPE>::markAndTraceWrapper( \ | |
120 visitor, static_cast<const TYPE*>(this)); \ | |
121 } \ | |
122 void adjustAndMarkWrapperNoTracing(const WrapperVisitor* visitor) \ | |
123 const override { \ | |
124 static_assert( \ | |
125 IsSubclassOfGarbageCollected::value, \ | |
126 "only garbage collected objects can have garbage collected mixins"); \ | |
127 return AdjustAndMarkTrait<TYPE>::markWrapperNoTracing( \ | |
128 visitor, static_cast<const TYPE*>(this)); \ | |
129 } \ | |
130 void adjustAndTraceMarkedWrapper(const WrapperVisitor* visitor) \ | |
131 const override { \ | |
132 static_assert( \ | |
133 IsSubclassOfGarbageCollected::value, \ | |
134 "only garbage collected objects can have garbage collected mixins"); \ | |
135 AdjustAndMarkTrait<TYPE>::traceMarkedWrapper( \ | |
136 visitor, static_cast<const TYPE*>(this)); \ | |
137 } \ | |
138 HeapObjectHeader* adjustAndGetHeapObjectHeader() const override { \ | |
139 static_assert( \ | |
140 IsSubclassOfGarbageCollected::value, \ | |
141 "only garbage collected objects can have garbage collected mixins"); \ | |
142 return AdjustAndMarkTrait<TYPE>::heapObjectHeader( \ | |
143 static_cast<const TYPE*>(this)); \ | |
144 } \ | |
145 \ | |
146 private: | |
147 | |
148 // A C++ object's vptr will be initialized to its leftmost base's vtable after | 101 // A C++ object's vptr will be initialized to its leftmost base's vtable after |
149 // the constructors of all its subclasses have run, so if a subclass constructor | 102 // the constructors of all its subclasses have run, so if a subclass constructor |
150 // tries to access any of the vtbl entries of its leftmost base prematurely, | 103 // tries to access any of the vtbl entries of its leftmost base prematurely, |
151 // it'll find an as-yet incorrect vptr and fail. Which is exactly what a | 104 // it'll find an as-yet incorrect vptr and fail. Which is exactly what a |
152 // garbage collector will try to do if it tries to access the leftmost base | 105 // garbage collector will try to do if it tries to access the leftmost base |
153 // while one of the subclass constructors of a GC mixin object triggers a GC. | 106 // while one of the subclass constructors of a GC mixin object triggers a GC. |
154 // It is consequently not safe to allow any GCs while these objects are under | 107 // It is consequently not safe to allow any GCs while these objects are under |
155 // (sub constructor) construction. | 108 // (sub constructor) construction. |
156 // | 109 // |
157 // To prevent GCs in that restricted window of a mixin object's construction: | 110 // To prevent GCs in that restricted window of a mixin object's construction: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // the second one should leave the forbidden GC scope. This is realized by | 150 // the second one should leave the forbidden GC scope. This is realized by |
198 // recording the address of B's GarbageCollectedMixinConstructorMarker | 151 // recording the address of B's GarbageCollectedMixinConstructorMarker |
199 // when the "operator new" for B runs, and leaving the forbidden GC scope | 152 // when the "operator new" for B runs, and leaving the forbidden GC scope |
200 // when the constructor of the recorded GarbageCollectedMixinConstructorMarker | 153 // when the constructor of the recorded GarbageCollectedMixinConstructorMarker |
201 // runs. | 154 // runs. |
202 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 155 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
203 IS_GARBAGE_COLLECTED_TYPE(); \ | 156 IS_GARBAGE_COLLECTED_TYPE(); \ |
204 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ | 157 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ |
205 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::InlinedGlobalMarkingVisitor, \ | 158 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::InlinedGlobalMarkingVisitor, \ |
206 TYPE) \ | 159 TYPE) \ |
207 DEFINE_GARBAGE_COLLECTED_MIXIN_WRAPPER_METHODS(TYPE) \ | |
208 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \ | 160 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \ |
209 public: \ | 161 public: \ |
210 bool isHeapObjectAlive() const override { \ | 162 bool isHeapObjectAlive() const override { \ |
211 return ThreadHeap::isHeapObjectAlive(this); \ | 163 return ThreadHeap::isHeapObjectAlive(this); \ |
212 } \ | 164 } \ |
213 \ | 165 \ |
214 private: | 166 private: |
215 | 167 |
216 // An empty class with a constructor that's arranged invoked when all derived | 168 // An empty class with a constructor that's arranged invoked when all derived |
217 // constructors of a mixin instance have completed and it is safe to allow GCs | 169 // constructors of a mixin instance have completed and it is safe to allow GCs |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 static FalseType isSizeofKnown(...); | 294 static FalseType isSizeofKnown(...); |
343 static T& t; | 295 static T& t; |
344 | 296 |
345 public: | 297 public: |
346 static const bool value = sizeof(TrueType) == sizeof(isSizeofKnown(&t)); | 298 static const bool value = sizeof(TrueType) == sizeof(isSizeofKnown(&t)); |
347 }; | 299 }; |
348 | 300 |
349 } // namespace blink | 301 } // namespace blink |
350 | 302 |
351 #endif | 303 #endif |
OLD | NEW |