| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. | 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 #include "wtf/Noncopyable.h" | 38 #include "wtf/Noncopyable.h" |
| 39 #if USE(LEAK_SANITIZER) | 39 #if USE(LEAK_SANITIZER) |
| 40 #include "wtf/AddressSanitizer.h" | 40 #include "wtf/AddressSanitizer.h" |
| 41 #include "wtf/TypeTraits.h" | 41 #include "wtf/TypeTraits.h" |
| 42 #endif | 42 #endif |
| 43 | 43 |
| 44 namespace WTF { | 44 namespace WTF { |
| 45 | 45 |
| 46 #if USE(LEAK_SANITIZER) | 46 #if USE(LEAK_SANITIZER) |
| 47 class LeakSanitizerDisabler { | 47 class LeakSanitizerDisabler { |
| 48 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); | 48 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); |
| 49 public: | |
| 50 LeakSanitizerDisabler() | |
| 51 { | |
| 52 __lsan_disable(); | |
| 53 } | |
| 54 | 49 |
| 55 ~LeakSanitizerDisabler() | 50 public: |
| 56 { | 51 LeakSanitizerDisabler() { __lsan_disable(); } |
| 57 __lsan_enable(); | 52 |
| 58 } | 53 ~LeakSanitizerDisabler() { __lsan_enable(); } |
| 59 }; | 54 }; |
| 60 | 55 |
| 61 // WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the | 56 // WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the |
| 62 // current scope will be exempted from LSan consideration. Only to be | 57 // current scope will be exempted from LSan consideration. Only to be |
| 63 // used internal to wtf/, Blink should use LEAK_SANITIZER_DISABLED_SCOPE | 58 // used internal to wtf/, Blink should use LEAK_SANITIZER_DISABLED_SCOPE |
| 64 // elsewhere. | 59 // elsewhere. |
| 65 // | 60 // |
| 66 // TODO(sof): once layering rules allow wtf/ to make use of the Oilpan | 61 // TODO(sof): once layering rules allow wtf/ to make use of the Oilpan |
| 67 // infrastructure, remove this macro. | 62 // infrastructure, remove this macro. |
| 68 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE \ | 63 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE \ |
| 69 WTF::LeakSanitizerDisabler leakSanitizerDisabler; static_cast<void>(0) | 64 WTF::LeakSanitizerDisabler leakSanitizerDisabler; \ |
| 65 static_cast<void>(0) |
| 70 | 66 |
| 71 // LEAK_SANITIZER_IGNORE_OBJECT(X): the heap object referenced by pointer X | 67 // LEAK_SANITIZER_IGNORE_OBJECT(X): the heap object referenced by pointer X |
| 72 // will be ignored by LSan. | 68 // will be ignored by LSan. |
| 73 // | 69 // |
| 74 // "Ignorance" means that LSan's reachability traversal is stopped short | 70 // "Ignorance" means that LSan's reachability traversal is stopped short |
| 75 // upon encountering an ignored memory chunk. Consequently, LSan will not | 71 // upon encountering an ignored memory chunk. Consequently, LSan will not |
| 76 // scan an ignored memory chunk for live, reachable pointers. However, should | 72 // scan an ignored memory chunk for live, reachable pointers. However, should |
| 77 // those embedded pointers be reachable by some other path, they will be | 73 // those embedded pointers be reachable by some other path, they will be |
| 78 // reported as leaking. | 74 // reported as leaking. |
| 79 #define LEAK_SANITIZER_IGNORE_OBJECT(X) __lsan_ignore_object(X) | 75 #define LEAK_SANITIZER_IGNORE_OBJECT(X) __lsan_ignore_object(X) |
| 80 | 76 |
| 81 // If the object pointed to by the static local is on the Oilpan heap, a strong | 77 // If the object pointed to by the static local is on the Oilpan heap, a strong |
| 82 // Persistent<> is created to keep the pointed-to heap object alive. This makes | 78 // Persistent<> is created to keep the pointed-to heap object alive. This makes |
| 83 // both the Persistent<> and the heap object _reachable_ by LeakSanitizer's leak | 79 // both the Persistent<> and the heap object _reachable_ by LeakSanitizer's leak |
| 84 // detection pass. We do not want these intentional leaks to be reported by LSan
, | 80 // detection pass. We do not want these intentional leaks to be reported by LSan
, |
| 85 // hence the static local is registered with Oilpan | 81 // hence the static local is registered with Oilpan |
| 86 // (see RegisterStaticLocalReference<> below.) | 82 // (see RegisterStaticLocalReference<> below.) |
| 87 // | 83 // |
| 88 // Upon Blink shutdown, all the registered statics are released and a final roun
d | 84 // Upon Blink shutdown, all the registered statics are released and a final roun
d |
| 89 // of GCs are performed to sweep out their now-unreachable object graphs. The en
d | 85 // of GCs are performed to sweep out their now-unreachable object graphs. The en
d |
| 90 // result being a tidied heap that the LeakSanitizer can then scan to report rea
l leaks. | 86 // result being a tidied heap that the LeakSanitizer can then scan to report rea
l leaks. |
| 91 // | 87 // |
| 92 // The CanRegisterStaticLocalReference<> and RegisterStaticLocalReference<> temp
lates | 88 // The CanRegisterStaticLocalReference<> and RegisterStaticLocalReference<> temp
lates |
| 93 // arrange for this -- for a class type T, a registerStatic() implementation is | 89 // arrange for this -- for a class type T, a registerStatic() implementation is |
| 94 // provided if "T* T::registerAsStaticReference(T*)" is a method on T | 90 // provided if "T* T::registerAsStaticReference(T*)" is a method on T |
| 95 // (inherited or otherwise.) | 91 // (inherited or otherwise.) |
| 96 // | 92 // |
| 97 // An empty, trivial registerStatic() method is provided for all other class typ
es T. | 93 // An empty, trivial registerStatic() method is provided for all other class typ
es T. |
| 98 template<typename T> | 94 template <typename T> |
| 99 class CanRegisterStaticLocalReference { | 95 class CanRegisterStaticLocalReference { |
| 100 typedef char YesType; | 96 typedef char YesType; |
| 101 typedef struct NoType { | 97 typedef struct NoType { char padding[8]; } NoType; |
| 102 char padding[8]; | |
| 103 } NoType; | |
| 104 | 98 |
| 105 // Check if class T has public method "T* registerAsStaticReference()". | 99 // Check if class T has public method "T* registerAsStaticReference()". |
| 106 template<typename V> static YesType checkHasRegisterAsStaticReferenceMethod(
V* p, typename std::enable_if<IsSubclass<V, typename std::remove_pointer<decltyp
e(p->registerAsStaticReference())>::type>::value>::type* = 0); | 100 template <typename V> |
| 107 template<typename V> static NoType checkHasRegisterAsStaticReferenceMethod(.
..); | 101 static YesType checkHasRegisterAsStaticReferenceMethod( |
| 102 V* p, |
| 103 typename std::enable_if<IsSubclass< |
| 104 V, |
| 105 typename std::remove_pointer<decltype( |
| 106 p->registerAsStaticReference())>::type>::value>::type* = 0); |
| 107 template <typename V> |
| 108 static NoType checkHasRegisterAsStaticReferenceMethod(...); |
| 108 | 109 |
| 109 public: | 110 public: |
| 110 static const bool value = sizeof(YesType) + sizeof(T) == sizeof(checkHasRegi
sterAsStaticReferenceMethod<T>(nullptr)) + sizeof(T); | 111 static const bool value = |
| 112 sizeof(YesType) + sizeof(T) == |
| 113 sizeof(checkHasRegisterAsStaticReferenceMethod<T>(nullptr)) + sizeof(T); |
| 111 }; | 114 }; |
| 112 | 115 |
| 113 template<typename T, bool = CanRegisterStaticLocalReference<T>::value> | 116 template <typename T, bool = CanRegisterStaticLocalReference<T>::value> |
| 114 class RegisterStaticLocalReference { | 117 class RegisterStaticLocalReference { |
| 115 public: | 118 public: |
| 116 static T* registerStatic(T* ptr) | 119 static T* registerStatic(T* ptr) { return ptr; } |
| 117 { | |
| 118 return ptr; | |
| 119 } | |
| 120 }; | 120 }; |
| 121 | 121 |
| 122 template<typename T> | 122 template <typename T> |
| 123 class RegisterStaticLocalReference<T, true> { | 123 class RegisterStaticLocalReference<T, true> { |
| 124 public: | 124 public: |
| 125 static T* registerStatic(T* ptr) | 125 static T* registerStatic(T* ptr) { |
| 126 { | 126 return static_cast<T*>(ptr->registerAsStaticReference()); |
| 127 return static_cast<T*>(ptr->registerAsStaticReference()); | 127 } |
| 128 } | |
| 129 }; | 128 }; |
| 130 | 129 |
| 131 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) WTF::RegisterStaticLo
calReference<Type>::registerStatic(Object) | 130 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) \ |
| 131 WTF::RegisterStaticLocalReference<Type>::registerStatic(Object) |
| 132 #else | 132 #else |
| 133 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE | 133 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE |
| 134 #define LEAK_SANITIZER_IGNORE_OBJECT | 134 #define LEAK_SANITIZER_IGNORE_OBJECT |
| 135 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) Object | 135 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) Object |
| 136 #endif // USE(LEAK_SANITIZER) | 136 #endif // USE(LEAK_SANITIZER) |
| 137 | 137 |
| 138 } // namespace WTF | 138 } // namespace WTF |
| 139 | 139 |
| 140 #endif // WTF_LeakAnnotations_h | 140 #endif // WTF_LeakAnnotations_h |
| OLD | NEW |