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 |