| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 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 17 matching lines...) Expand all Loading... |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #ifndef ScriptWrappable_h | 31 #ifndef ScriptWrappable_h |
| 32 #define ScriptWrappable_h | 32 #define ScriptWrappable_h |
| 33 | 33 |
| 34 #include "bindings/core/v8/WrapperTypeInfo.h" | 34 #include "bindings/core/v8/WrapperTypeInfo.h" |
| 35 #include "core/CoreExport.h" | 35 #include "core/CoreExport.h" |
| 36 #include "platform/heap/Handle.h" | 36 #include "platform/heap/Handle.h" |
| 37 #include "wtf/Noncopyable.h" | 37 #include "wtf/Noncopyable.h" |
| 38 #include "wtf/TypeTraits.h" |
| 38 #include <v8.h> | 39 #include <v8.h> |
| 39 | 40 |
| 40 namespace blink { | 41 namespace blink { |
| 41 | 42 |
| 42 /** | 43 /** |
| 43 * ScriptWrappable wraps a V8 object and its WrapperTypeInfo. | 44 * ScriptWrappable wraps a V8 object and its WrapperTypeInfo. |
| 44 * | 45 * |
| 45 * ScriptWrappable acts much like a v8::Persistent<> in that it keeps a | 46 * ScriptWrappable acts much like a v8::Persistent<> in that it keeps a |
| 46 * V8 object alive. | 47 * V8 object alive. |
| 47 * | 48 * |
| 48 * The state transitions are: | 49 * The state transitions are: |
| 49 * - new: an empty ScriptWrappable. | 50 * - new: an empty ScriptWrappable. |
| 50 * - setWrapper: install a v8::Persistent (or empty) | 51 * - setWrapper: install a v8::Persistent (or empty) |
| 51 * - disposeWrapper (via setWeakCallback, triggered by V8 garbage collecter): | 52 * - disposeWrapper (via setWeakCallback, triggered by V8 garbage collecter): |
| 52 * remove v8::Persistent and become empty. | 53 * remove v8::Persistent and become empty. |
| 53 */ | 54 */ |
| 54 class CORE_EXPORT ScriptWrappable { | 55 class CORE_EXPORT ScriptWrappable { |
| 55 WTF_MAKE_NONCOPYABLE(ScriptWrappable); | 56 WTF_MAKE_NONCOPYABLE(ScriptWrappable); |
| 56 public: | 57 public: |
| 57 ScriptWrappable() { } | 58 ScriptWrappable() { } |
| 58 | 59 |
| 59 template<typename T> | 60 template<typename T> |
| 60 T* toImpl() | 61 T* toImpl() |
| 61 { | 62 { |
| 63 // All ScriptWrappables are managed by the Blink GC heap; check that |
| 64 // |T| is a garbage collected type. |
| 65 static_assert(sizeof(T) && WTF::IsGarbageCollectedType<T>::value, "Class
es implementing ScriptWrappable must be garbage collected."); |
| 66 |
| 62 // Check if T* is castable to ScriptWrappable*, which means T doesn't | 67 // Check if T* is castable to ScriptWrappable*, which means T doesn't |
| 63 // have two or more ScriptWrappable as superclasses. If T has two | 68 // have two or more ScriptWrappable as superclasses. If T has two |
| 64 // ScriptWrappable as superclasses, conversions from T* to | 69 // ScriptWrappable as superclasses, conversions from T* to |
| 65 // ScriptWrappable* are ambiguous. | 70 // ScriptWrappable* are ambiguous. |
| 66 #if !COMPILER(MSVC) | 71 #if !COMPILER(MSVC) |
| 67 // MSVC 2013 doesn't support static_assert + constexpr well. | 72 // MSVC 2013 doesn't support static_assert + constexpr well. |
| 68 static_assert(!static_cast<ScriptWrappable*>(static_cast<T*>(nullptr)), | 73 static_assert(!static_cast<ScriptWrappable*>(static_cast<T*>(nullptr)), |
| 69 "Class T must not have two or more ScriptWrappable as its superclass
es."); | 74 "Class T must not have two or more ScriptWrappable as its superclass
es."); |
| 70 #endif | 75 #endif |
| 71 return static_cast<T*>(this); | 76 return static_cast<T*>(this); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 RELEASE_ASSERT(containsWrapper()); | 166 RELEASE_ASSERT(containsWrapper()); |
| 162 m_wrapper.Reset(); | 167 m_wrapper.Reset(); |
| 163 } | 168 } |
| 164 | 169 |
| 165 static void firstWeakCallback(const v8::WeakCallbackInfo<ScriptWrappable>& d
ata) | 170 static void firstWeakCallback(const v8::WeakCallbackInfo<ScriptWrappable>& d
ata) |
| 166 { | 171 { |
| 167 auto scriptWrappable = data.GetParameter(); | 172 auto scriptWrappable = data.GetParameter(); |
| 168 scriptWrappable->disposeWrapper(data); | 173 scriptWrappable->disposeWrapper(data); |
| 169 | 174 |
| 170 auto wrapperTypeInfo = reinterpret_cast<WrapperTypeInfo*>(data.GetIntern
alField(v8DOMWrapperTypeIndex)); | 175 auto wrapperTypeInfo = reinterpret_cast<WrapperTypeInfo*>(data.GetIntern
alField(v8DOMWrapperTypeIndex)); |
| 171 if (wrapperTypeInfo->isGarbageCollected()) { | 176 wrapperTypeInfo->wrapperDestroyed(); |
| 172 // derefObject() for garbage collected objects is very cheap, so | |
| 173 // we don't delay derefObject to the second pass. | |
| 174 // | |
| 175 // More importantly, we've already disposed the wrapper at this | |
| 176 // moment, so the ScriptWrappable may have already been collected | |
| 177 // by GC by the second pass. We shouldn't use a pointer to the | |
| 178 // ScriptWrappable in secondWeakCallback in case of garbage | |
| 179 // collected objects. Thus calls derefObject right now. | |
| 180 wrapperTypeInfo->derefObject(scriptWrappable); | |
| 181 } else { | |
| 182 // For reference counted objects, let's delay the destruction of | |
| 183 // the object to the second pass. | |
| 184 data.SetSecondPassCallback(secondWeakCallback); | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 static void secondWeakCallback(const v8::WeakCallbackInfo<ScriptWrappable>&
data) | |
| 189 { | |
| 190 // FIXME: I noticed that 50%~ of minor GC cycle times can be consumed | |
| 191 // inside data.GetParameter()->deref(), which causes Node destructions.
We should | |
| 192 // make Node destructions incremental. | |
| 193 auto scriptWrappable = reinterpret_cast<ScriptWrappable*>(data.GetIntern
alField(v8DOMWrapperObjectIndex)); | |
| 194 auto wrapperTypeInfo = reinterpret_cast<WrapperTypeInfo*>(data.GetIntern
alField(v8DOMWrapperTypeIndex)); | |
| 195 wrapperTypeInfo->derefObject(scriptWrappable); | |
| 196 } | 177 } |
| 197 | 178 |
| 198 v8::Persistent<v8::Object> m_wrapper; | 179 v8::Persistent<v8::Object> m_wrapper; |
| 199 }; | 180 }; |
| 200 | 181 |
| 201 // Defines 'wrapperTypeInfo' virtual method which returns the WrapperTypeInfo of | 182 // Defines 'wrapperTypeInfo' virtual method which returns the WrapperTypeInfo of |
| 202 // the instance. Also declares a static member of type WrapperTypeInfo, of which | 183 // the instance. Also declares a static member of type WrapperTypeInfo, of which |
| 203 // the definition is given by the IDL code generator. | 184 // the definition is given by the IDL code generator. |
| 204 // | 185 // |
| 205 // All the derived classes of ScriptWrappable, regardless of directly or | 186 // All the derived classes of ScriptWrappable, regardless of directly or |
| (...skipping 20 matching lines...) Expand all Loading... |
| 226 // in X's cpp code, and instantiate X, i.e. "template class X;". | 207 // in X's cpp code, and instantiate X, i.e. "template class X;". |
| 227 #define DECLARE_WRAPPERTYPEINFO() \ | 208 #define DECLARE_WRAPPERTYPEINFO() \ |
| 228 public: \ | 209 public: \ |
| 229 const WrapperTypeInfo* wrapperTypeInfo() const override; \ | 210 const WrapperTypeInfo* wrapperTypeInfo() const override; \ |
| 230 private: \ | 211 private: \ |
| 231 typedef void end_of_define_wrappertypeinfo_not_reached_t | 212 typedef void end_of_define_wrappertypeinfo_not_reached_t |
| 232 | 213 |
| 233 } // namespace blink | 214 } // namespace blink |
| 234 | 215 |
| 235 #endif // ScriptWrappable_h | 216 #endif // ScriptWrappable_h |
| OLD | NEW |