| 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 TraceWrapperBase; | |
| 18 | 17 |
| 19 // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or | 18 // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or |
| 20 // field when checking for proper usage. When using GC_PLUGIN_IGNORE | 19 // field when checking for proper usage. When using GC_PLUGIN_IGNORE |
| 21 // a bug-number should be provided as an argument where the bug describes | 20 // a bug-number should be provided as an argument where the bug describes |
| 22 // what needs to happen to remove the GC_PLUGIN_IGNORE again. | 21 // what needs to happen to remove the GC_PLUGIN_IGNORE again. |
| 23 #if COMPILER(CLANG) | 22 #if COMPILER(CLANG) |
| 24 #define GC_PLUGIN_IGNORE(bug) \ | 23 #define GC_PLUGIN_IGNORE(bug) \ |
| 25 __attribute__((annotate("blink_gc_plugin_ignore"))) | 24 __attribute__((annotate("blink_gc_plugin_ignore"))) |
| 26 #else | 25 #else |
| 27 #define GC_PLUGIN_IGNORE(bug) | 26 #define GC_PLUGIN_IGNORE(bug) |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 // }; | 141 // }; |
| 143 // | 142 // |
| 144 // The "operator new" for B will enter the forbidden GC scope, but | 143 // The "operator new" for B will enter the forbidden GC scope, but |
| 145 // upon construction, two GarbageCollectedMixinConstructorMarker constructors | 144 // upon construction, two GarbageCollectedMixinConstructorMarker constructors |
| 146 // will run -- one for A (first) and another for B (secondly). Only | 145 // will run -- one for A (first) and another for B (secondly). Only |
| 147 // the second one should leave the forbidden GC scope. This is realized by | 146 // the second one should leave the forbidden GC scope. This is realized by |
| 148 // recording the address of B's GarbageCollectedMixinConstructorMarker | 147 // recording the address of B's GarbageCollectedMixinConstructorMarker |
| 149 // when the "operator new" for B runs, and leaving the forbidden GC scope | 148 // when the "operator new" for B runs, and leaving the forbidden GC scope |
| 150 // when the constructor of the recorded GarbageCollectedMixinConstructorMarker | 149 // when the constructor of the recorded GarbageCollectedMixinConstructorMarker |
| 151 // runs. | 150 // runs. |
| 152 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ | 151 #define USING_GARBAGE_COLLECTED_MIXIN(TYPE) \ |
| 153 IS_GARBAGE_COLLECTED_TYPE(); \ | 152 IS_GARBAGE_COLLECTED_TYPE(); \ |
| 154 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ | 153 DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(blink::Visitor*, TYPE) \ |
| 155 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \ | 154 DEFINE_GARBAGE_COLLECTED_MIXIN_CONSTRUCTOR_MARKER(TYPE) \ |
| 156 public: \ | 155 public: \ |
| 157 bool isHeapObjectAlive() const override { \ | 156 bool isHeapObjectAlive() const override { \ |
| 158 return ThreadHeap::isHeapObjectAlive(this); \ | 157 return ThreadHeap::isHeapObjectAlive(this); \ |
| 159 } \ | 158 } \ |
| 160 \ | 159 \ |
| 161 private: | 160 private: |
| 162 | 161 |
| 163 // An empty class with a constructor that's arranged invoked when all derived | 162 // An empty class with a constructor that's arranged invoked when all derived |
| 164 // constructors of a mixin instance have completed and it is safe to allow GCs | 163 // constructors of a mixin instance have completed and it is safe to allow GCs |
| 165 // again. See AllocateObjectTrait<> comment for more. | 164 // again. See AllocateObjectTrait<> comment for more. |
| 166 // | 165 // |
| 167 // USING_GARBAGE_COLLECTED_MIXIN() declares a | 166 // USING_GARBAGE_COLLECTED_MIXIN() declares a |
| 168 // GarbageCollectedMixinConstructorMarker<> private field. By following Blink | 167 // GarbageCollectedMixinConstructorMarker<> private field. By following Blink |
| 169 // convention of using the macro at the top of a class declaration, its | 168 // convention of using the macro at the top of a class declaration, its |
| 170 // constructor will run first. | 169 // constructor will run first. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 239 |
| 241 template <typename T> | 240 template <typename T> |
| 242 class NeedsAdjustAndMark<T, false> { | 241 class NeedsAdjustAndMark<T, false> { |
| 243 static_assert(sizeof(T), "T must be fully defined"); | 242 static_assert(sizeof(T), "T must be fully defined"); |
| 244 | 243 |
| 245 public: | 244 public: |
| 246 static const bool value = | 245 static const bool value = |
| 247 IsGarbageCollectedMixin<typename std::remove_const<T>::type>::value; | 246 IsGarbageCollectedMixin<typename std::remove_const<T>::type>::value; |
| 248 }; | 247 }; |
| 249 | 248 |
| 250 template <typename T, | 249 class WrapperVisitor; |
| 251 bool = std::is_base_of<TraceWrapperBase, | 250 template <typename T, typename = void> |
| 252 typename std::remove_const<T>::type>::value> | 251 struct CanTraceWrappers : std::false_type {}; |
| 253 class CanTraceWrappers; | |
| 254 | 252 |
| 255 template <typename T> | 253 template <typename T> |
| 256 class CanTraceWrappers<T, true> { | 254 struct CanTraceWrappers<T, |
| 257 static_assert(sizeof(T), "T must be fully defined"); | 255 decltype( |
| 258 | 256 std::declval<T&>().markAndDispatchTraceWrappers( |
| 259 public: | 257 std::declval<WrapperVisitor*>()))> |
| 260 static const bool value = true; | 258 : std::true_type {}; |
| 261 }; | |
| 262 | |
| 263 template <typename T> | |
| 264 class CanTraceWrappers<T, false> { | |
| 265 static_assert(sizeof(T), "T must be fully defined"); | |
| 266 | |
| 267 public: | |
| 268 static const bool value = false; | |
| 269 }; | |
| 270 | 259 |
| 271 // TODO(sof): migrate to wtf/TypeTraits.h | 260 // TODO(sof): migrate to wtf/TypeTraits.h |
| 272 template <typename T> | 261 template <typename T> |
| 273 class IsFullyDefined { | 262 class IsFullyDefined { |
| 274 using TrueType = char; | 263 using TrueType = char; |
| 275 struct FalseType { | 264 struct FalseType { |
| 276 char dummy[2]; | 265 char dummy[2]; |
| 277 }; | 266 }; |
| 278 | 267 |
| 279 template <typename U, size_t sz = sizeof(U)> | 268 template <typename U, size_t sz = sizeof(U)> |
| 280 static TrueType isSizeofKnown(U*); | 269 static TrueType isSizeofKnown(U*); |
| 281 static FalseType isSizeofKnown(...); | 270 static FalseType isSizeofKnown(...); |
| 282 static T& t; | 271 static T& t; |
| 283 | 272 |
| 284 public: | 273 public: |
| 285 static const bool value = sizeof(TrueType) == sizeof(isSizeofKnown(&t)); | 274 static const bool value = sizeof(TrueType) == sizeof(isSizeofKnown(&t)); |
| 286 }; | 275 }; |
| 287 | 276 |
| 288 } // namespace blink | 277 } // namespace blink |
| 289 | 278 |
| 290 #endif | 279 #endif |
| OLD | NEW |