Chromium Code Reviews| Index: third_party/WebKit/Source/wtf/StdLibExtras.h |
| diff --git a/third_party/WebKit/Source/wtf/StdLibExtras.h b/third_party/WebKit/Source/wtf/StdLibExtras.h |
| index 5475d3feb7e47a9e4b1ee0552abfadca7f508e13..6f3709a9fa455842edba6dd8f2ca49147607e1fb 100644 |
| --- a/third_party/WebKit/Source/wtf/StdLibExtras.h |
| +++ b/third_party/WebKit/Source/wtf/StdLibExtras.h |
| @@ -59,34 +59,57 @@ private: |
| }; |
| #endif |
| -// A direct static local to a Blink garbage collected objects isn't allowed; |
| -// must be wrapped up with a persistent reference. |
| -#define STATIC_ASSERT_FOR_LOCAL_WITH_GARBAGE_COLLECTED_TYPE(Name, Type) \ |
| - using Name##NoConstType = std::remove_const<Type>::type; \ |
| - using Name##NoPointerType = std::remove_pointer<Name##NoConstType>::type; \ |
| - using Name##NoReferenceType = std::remove_reference<Name##NoPointerType>::type; \ |
| - static_assert(!WTF::IsGarbageCollectedType<Name##NoReferenceType>::value || WTF::IsPersistentReferenceType<Name##NoReferenceType>::value, "Garbage collected static local needs to be wrapped up with a persistent reference") |
| - |
| -// Use DEFINE_STATIC_LOCAL() to declare and define a static local variable (static T;) |
| -// so that it is leaked and its destructors are not called at exit. |
| -// |
| -// To cooperate with leak detection, the objects held onto by these local statics |
| -// will in some cases have to be finalized prior to leak checking. This only applies |
| -// to static references to Oilpan heap objects and what they transitively hold on to. |
| -// LEAK_SANITIZER_REGISTER_STATIC_LOCAL() takes care of the details. |
| -// |
| +namespace blink { |
| +template<typename T>class Persistent; |
| +}; |
| + |
| +template<typename T, bool = WTF::IsGarbageCollectedType<T>::value && !WTF::IsPersistentReferenceType<T>::value> |
| +class StaticLocalWrapper { |
| +public: |
| + using WrapType = T; |
| + |
| + static T& unwrap(T* singleton) |
| + { |
| + return *singleton; |
| + } |
| +}; |
| + |
| +template<typename T> |
| +class StaticLocalWrapper<T, true> { |
| +public: |
| + using WrapType = blink::Persistent<T>; |
| + |
| + static T& unwrap(blink::Persistent<T>* singleton) |
| + { |
| + return **singleton; |
| + } |
| +}; |
| + |
| #if ENABLE(ASSERT) |
| -#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \ |
| - STATIC_ASSERT_FOR_LOCAL_WITH_GARBAGE_COLLECTED_TYPE(Name, Type); \ |
| +#define DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name) \ |
| static StaticLocalVerifier Name##StaticLocalVerifier; \ |
| - ASSERT(Name##StaticLocalVerifier.isNotRacy()); \ |
| - static Type& Name = *LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, new Type Arguments) |
| + ASSERT(Name##StaticLocalVerifier.isNotRacy()) |
| #else |
| -#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \ |
| - STATIC_ASSERT_FOR_LOCAL_WITH_GARBAGE_COLLECTED_TYPE(Name, Type); \ |
| - static Type& Name = *LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, new Type Arguments) |
| +#define DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name) |
| #endif |
| +// Use DEFINE_STATIC_LOCAL() to declare and define a static local variable |
| +// (static T;) so that it is leaked and its destructors are not called at exit. |
| +// T may also be a Blink garbage collected object, in which case it is |
| +// wrapped up by a strong off-heap Persistent<T> reference. |
|
haraken
2016/04/03 23:46:52
Nit: "strong off-heap" might be misleading. "a str
sof
2016/04/04 07:09:00
Reworded.
|
| +// |
| +// To cooperate with leak detection(LSan) for Blink garbage collected objects, |
| +// the objects owned by persistent local statics will in some cases have to be |
| +// finalized prior to leak checking. This only applies to static references to |
| +// Blink heap objects and what they transitively hold on to. Hence the |
| +// LEAK_SANITIZER_REGISTER_STATIC_LOCAL() use, it taking care of the grungy |
| +// details. |
| +// |
| +#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \ |
| + DEFINE_STATIC_LOCAL_CHECK_THREADSAFE_ACCESS(Name); \ |
| + using WrappedTypeFor##Name = StaticLocalWrapper<Type>::WrapType; \ |
| + static Type& Name = StaticLocalWrapper<Type>::unwrap(LEAK_SANITIZER_REGISTER_STATIC_LOCAL(WrappedTypeFor##Name, new WrappedTypeFor##Name Arguments)) |
| + |
| // Use this to declare and define a static local pointer to a ref-counted object so that |
| // it is leaked so that the object's destructors are not called at exit. |
| // This macro should be used with ref-counted objects rather than DEFINE_STATIC_LOCAL macro, |