Changeset 147391 in webkit
- Timestamp:
- Apr 1, 2013 11:23:54 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r147389 r147391 1 2013-04-01 Elliott Sprehn <esprehn@chromium.org> 2 3 Make all v8 weak callbacks type safe 4 https://bugs.webkit.org/show_bug.cgi?id=111802 5 6 Reviewed by Adam Barth. 7 8 Make all v8 handle weak callbacks typesafe by adding a new class WeakHandleListner 9 that uses templates to generate the callback proxies that have the correct type 10 arguments. Now getting the arguments wrong will fail compilation. 11 12 No new tests, no change in behavior. 13 14 * bindings/v8/DOMDataStore.h: 15 (WebCore::::callback): 16 * bindings/v8/DOMWrapperMap.h: 17 (WebCore::DOMWrapperMap::DOMWrapperMap): 18 (WebCore::DOMWrapperMap::set): 19 (WebCore::DOMWrapperMap::reportMemoryUsage): 20 (DOMWrapperMap): 21 * bindings/v8/DOMWrapperWorld.cpp: 22 (WebCore::::callback): 23 (WebCore::DOMWrapperWorld::makeContextWeak): 24 * bindings/v8/ScriptState.cpp: 25 (WebCore::::callback): 26 (WebCore::ScriptState::ScriptState): 27 * bindings/v8/ScriptState.h: 28 (ScriptState): 29 * bindings/v8/ScriptWrappable.h: 30 (ScriptWrappable): 31 (WebCore::ScriptWrappable::setWrapper): 32 (WebCore::::callback): 33 * bindings/v8/V8AbstractEventListener.cpp: 34 (WebCore::::callback): 35 (WebCore::V8AbstractEventListener::setListenerObject): 36 * bindings/v8/V8AbstractEventListener.h: 37 (V8AbstractEventListener): 38 * bindings/v8/V8MutationCallback.cpp: 39 (WebCore::::callback): 40 (WebCore::V8MutationCallback::V8MutationCallback): 41 * bindings/v8/V8MutationCallback.h: 42 (V8MutationCallback): 43 * bindings/v8/V8NPObject.cpp: 44 (V8NPTemplateMap): 45 (WebCore::V8NPTemplateMap::set): 46 (WebCore::::callback): 47 (WebCore::staticNPObjectMap): 48 * bindings/v8/V8Utilities.h: 49 (WeakHandleListener): 50 (WebCore::WeakHandleListener::makeWeak): 51 (WebCore::WeakHandleListener::WeakHandleListener): 52 (WebCore::WeakHandleListener::invokeWeakCallback): 53 * bindings/v8/V8ValueCache.cpp: 54 (WebCore::::callback): 55 (WebCore::StringCache::v8ExternalStringSlow): 56 * bindings/v8/custom/V8InjectedScriptManager.cpp: 57 (WebCore::::callback): 58 (WebCore::createInjectedScriptHostV8Wrapper): 59 1 60 2013-04-01 Tien-Ren Chen <trchen@chromium.org> 2 61 -
trunk/Source/WebCore/bindings/v8/DOMDataStore.h
r146357 r147391 171 171 }; 172 172 173 template<> 174 inline void WeakHandleListener<DOMWrapperMap<void> >::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> value, DOMWrapperMap<void>* map) 175 { 176 ASSERT(value->IsObject()); 177 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(value); 178 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); 179 ASSERT(type->derefObjectFunction); 180 void* key = static_cast<void*>(toNative(wrapper)); 181 map->removeAndDispose(key, wrapper, isolate); 182 type->derefObject(key); 183 } 184 173 185 } // namespace WebCore 174 186 -
trunk/Source/WebCore/bindings/v8/DOMWrapperMap.h
r142250 r147391 32 32 #define DOMWrapperMap_h 33 33 34 #include "V8Utilities.h" 34 35 #include "WebCoreMemoryInstrumentation.h" 35 36 #include "WrapperTypeInfo.h" … … 45 46 typedef HashMap<KeyType*, v8::Persistent<v8::Object> > MapType; 46 47 47 explicit DOMWrapperMap(v8::Isolate* isolate, v8::NearDeathCallback callback = &defaultWeakCallback) 48 : m_callback(callback) 49 , m_isolate(isolate) 48 explicit DOMWrapperMap(v8::Isolate* isolate) 49 : m_isolate(isolate) 50 50 { 51 51 } … … 62 62 v8::Persistent<v8::Object> persistent = v8::Persistent<v8::Object>::New(m_isolate, wrapper); 63 63 configuration.configureWrapper(persistent, m_isolate); 64 persistent.MakeWeak(m_isolate, this, m_callback);64 WeakHandleListener<DOMWrapperMap<KeyType> >::makeWeak(m_isolate, persistent, this); 65 65 m_map.set(key, persistent); 66 66 } … … 81 81 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding); 82 82 info.addMember(m_map, "map"); 83 info.ignoreMember(m_callback);84 83 } 85 84 … … 96 95 97 96 private: 98 static void defaultWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> value, void* context)99 {100 DOMWrapperMap<KeyType>* map = static_cast<DOMWrapperMap<KeyType>*>(context);101 ASSERT(value->IsObject());102 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(value);103 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);104 ASSERT(type->derefObjectFunction);105 KeyType* key = static_cast<KeyType*>(toNative(wrapper));106 map->removeAndDispose(key, wrapper, isolate);107 type->derefObject(key);108 }109 110 v8::NearDeathCallback m_callback;111 97 v8::Isolate* m_isolate; 112 98 MapType m_map; -
trunk/Source/WebCore/bindings/v8/DOMWrapperWorld.cpp
r144617 r147391 85 85 } 86 86 87 static void isolatedWorldWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, void* parameter) 87 template<> 88 void WeakHandleListener<DOMWrapperWorld>::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, DOMWrapperWorld* world) 88 89 { 89 90 object.Dispose(isolate); 90 91 object.Clear(); 91 static_cast<DOMWrapperWorld*>(parameter)->deref();92 world->deref(); 92 93 } 93 94 … … 97 98 ASSERT(isolatedWorld(context) == this); 98 99 v8::Isolate* isolate = context->GetIsolate(); 99 v8::Persistent<v8::Context>::New(isolate, context).MakeWeak(isolate, this, isolatedWorldWeakCallback); 100 v8::Persistent<v8::Context> persistent = v8::Persistent<v8::Context>::New(isolate, context); 101 WeakHandleListener<DOMWrapperWorld>::makeWeak(isolate, persistent, this); 100 102 // Matching deref is in weak callback. 101 103 this->ref(); -
trunk/Source/WebCore/bindings/v8/ScriptState.cpp
r141771 r147391 46 46 namespace WebCore { 47 47 48 template<> 49 void WeakHandleListener<ScriptState>::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, ScriptState* scriptState) 50 { 51 delete scriptState; 52 } 53 48 54 ScriptState::ScriptState(v8::Handle<v8::Context> context) 49 55 : m_context(context) 50 56 { 51 m_context.get().MakeWeak(context->GetIsolate(), this, &ScriptState::weakReferenceCallback);57 WeakHandleListener<ScriptState>::makeWeak(context->GetIsolate(), m_context.get(), this); 52 58 } 53 59 … … 89 95 ASSERT(!context.IsEmpty()); 90 96 return ScriptState::forContext(context); 91 }92 93 void ScriptState::weakReferenceCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, void* parameter)94 {95 ScriptState* scriptState = static_cast<ScriptState*>(parameter);96 delete scriptState;97 97 } 98 98 -
trunk/Source/WebCore/bindings/v8/ScriptState.h
r141771 r147391 34 34 #include "DOMWrapperWorld.h" 35 35 #include "ScopedPersistent.h" 36 #include "V8Utilities.h" 36 37 #include <v8.h> 37 38 #include <wtf/Noncopyable.h> … … 81 82 private: 82 83 friend ScriptState* mainWorldScriptState(Frame*); 84 friend class WeakHandleListener<ScriptState>; 83 85 explicit ScriptState(v8::Handle<v8::Context>); 84 86 -
trunk/Source/WebCore/bindings/v8/ScriptWrappable.h
r143737 r147391 32 32 #define ScriptWrappable_h 33 33 34 #include "V8Utilities.h" 34 35 #include "WebCoreMemoryInstrumentation.h" 35 36 #include "WrapperTypeInfo.h" … … 39 40 40 41 class ScriptWrappable { 42 friend class WeakHandleListener<ScriptWrappable>; 41 43 public: 42 44 ScriptWrappable() { } … … 52 54 v8::Persistent<v8::Object> persistent = v8::Persistent<v8::Object>::New(isolate, wrapper); 53 55 configuration.configureWrapper(persistent, isolate); 54 persistent.MakeWeak(isolate, this, weakCallback);56 WeakHandleListener<ScriptWrappable>::makeWeak(isolate, persistent, this); 55 57 m_maskedWrapper = maskOrUnmaskPointer(*persistent); 56 58 } … … 81 83 return reinterpret_cast<v8::Object*>((objectPointer ^ randomMask) & (!objectPointer - 1)); // Preserve null without branching. 82 84 } 85 }; 83 86 84 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> value, void* context) 85 { 86 ScriptWrappable* key = static_cast<ScriptWrappable*>(context); 87 88 89 87 template<> 88 inline void WeakHandleListener<ScriptWrappable>::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> value, ScriptWrappable* key) 89 { 90 ASSERT(value->IsObject()); 91 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(value); 92 ASSERT(key->wrapper() == wrapper); 90 93 91 92 93 94 94 // Note: |object| might not be equal to |key|, e.g., if ScriptWrappable isn't a left-most base class. 95 void* object = toNative(wrapper); 96 WrapperTypeInfo* info = toWrapperTypeInfo(wrapper); 97 ASSERT(info->derefObjectFunction); 95 98 96 key->disposeWrapper(value, isolate); 97 // FIXME: I noticed that 50%~ of minor GC cycle times can be consumed 98 // inside key->deref(), which causes Node destructions. We should 99 // make Node destructions incremental. 100 info->derefObject(object); 101 } 102 }; 99 key->disposeWrapper(value, isolate); 100 // FIXME: I noticed that 50%~ of minor GC cycle times can be consumed 101 // inside key->deref(), which causes Node destructions. We should 102 // make Node destructions incremental. 103 info->derefObject(object); 104 } 103 105 104 106 } // namespace WebCore -
trunk/Source/WebCore/bindings/v8/V8AbstractEventListener.cpp
r142940 r147391 43 43 #include "V8EventTarget.h" 44 44 #include "V8HiddenPropertyName.h" 45 #include "V8Utilities.h"46 45 #include "WorkerContext.h" 47 46 48 47 namespace WebCore { 49 48 50 void V8AbstractEventListener::weakEventListenerCallback(v8::Isolate* isolate, v8::Persistent<v8::Value>, void* parameter) 49 template<> 50 void WeakHandleListener<V8AbstractEventListener>::callback(v8::Isolate*, v8::Persistent<v8::Value>, V8AbstractEventListener* listener) 51 51 { 52 V8AbstractEventListener* listener = static_cast<V8AbstractEventListener*>(parameter);53 52 listener->m_listener.clear(); 54 53 } … … 107 106 { 108 107 m_listener.set(listener); 109 m_listener.get().MakeWeak(m_isolate, this, &V8AbstractEventListener::weakEventListenerCallback);108 WeakHandleListener<V8AbstractEventListener>::makeWeak(m_isolate, m_listener.get(), this); 110 109 } 111 110 -
trunk/Source/WebCore/bindings/v8/V8AbstractEventListener.h
r141771 r147391 34 34 #include "EventListener.h" 35 35 #include "ScopedPersistent.h" 36 #include "V8Utilities.h" 36 37 #include "WorldContextHandle.h" 37 38 #include <v8.h> … … 52 53 // but ALLOWs duplicated non-HTML event handlers. 53 54 class V8AbstractEventListener : public EventListener { 55 friend class WeakHandleListener<V8AbstractEventListener>; 54 56 public: 55 57 virtual ~V8AbstractEventListener(); -
trunk/Source/WebCore/bindings/v8/V8MutationCallback.cpp
r145379 r147391 36 36 namespace WebCore { 37 37 38 template<> 39 void WeakHandleListener<V8MutationCallback>::callback(v8::Isolate*, v8::Persistent<v8::Value>, V8MutationCallback* callback) 40 { 41 callback->m_callback.clear(); 42 } 43 38 44 V8MutationCallback::V8MutationCallback(v8::Handle<v8::Function> callback, ScriptExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate) 39 45 : ActiveDOMCallback(context) … … 42 48 { 43 49 owner->SetHiddenValue(V8HiddenPropertyName::callback(), callback); 44 m_callback.get().MakeWeak(isolate, this, &V8MutationCallback::weakCallback);50 WeakHandleListener<V8MutationCallback>::makeWeak(isolate, m_callback.get(), this); 45 51 } 46 52 -
trunk/Source/WebCore/bindings/v8/V8MutationCallback.h
r145379 r147391 31 31 #include "MutationCallback.h" 32 32 #include "ScopedPersistent.h" 33 #include "V8Utilities.h" 33 34 #include <v8.h> 34 35 #include <wtf/RefPtr.h> … … 39 40 40 41 class V8MutationCallback : public MutationCallback, public ActiveDOMCallback { 42 friend class WeakHandleListener<V8MutationCallback>; 41 43 public: 42 44 static PassRefPtr<V8MutationCallback> create(v8::Handle<v8::Function> callback, ScriptExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate) … … 52 54 V8MutationCallback(v8::Handle<v8::Function>, ScriptExecutionContext*, v8::Handle<v8::Object>, v8::Isolate*); 53 55 54 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> wrapper, void* parameter)55 {56 V8MutationCallback* object = static_cast<V8MutationCallback*>(parameter);57 object->m_callback.clear();58 }59 60 56 ScopedPersistent<v8::Function> m_callback; 61 57 RefPtr<DOMWrapperWorld> m_world; -
trunk/Source/WebCore/bindings/v8/V8NPObject.cpp
r145906 r147391 161 161 } 162 162 163 164 class V8NPTemplateMap 165 { 163 class V8NPTemplateMap { 164 friend class WeakHandleListener<V8NPTemplateMap, PrivateIdentifier>; 166 165 public: 167 166 // NPIdentifier is PrivateIdentifier*. … … 177 176 ASSERT(!m_map.contains(key)); 178 177 m_map.set(key, wrapper); 179 wrapper.MakeWeak(m_isolate, key, weakCallback);178 WeakHandleListener<V8NPTemplateMap, PrivateIdentifier>::makeWeak(m_isolate, wrapper, key); 180 179 } 181 180 … … 191 190 : m_isolate(isolate) 192 191 { 193 }194 195 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, void* context)196 {197 sharedInstance(isolate).dispose(static_cast<PrivateIdentifier*>(context));198 192 } 199 193 … … 210 204 v8::Isolate* m_isolate; 211 205 }; 206 207 template<> 208 void WeakHandleListener<V8NPTemplateMap, PrivateIdentifier>::callback(v8::Isolate* isolate, v8::Persistent<v8::Value>, PrivateIdentifier* key) 209 { 210 V8NPTemplateMap::sharedInstance(isolate).dispose(key); 211 } 212 212 213 213 static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> key, v8::Isolate* isolate) … … 385 385 } 386 386 387 static void weakNPObjectCallback(v8::Isolate*, v8::Persistent<v8::Value>, void*);388 389 387 static DOMWrapperMap<NPObject>& staticNPObjectMap() 390 388 { 391 DEFINE_STATIC_LOCAL(DOMWrapperMap<NPObject>, npObjectMap, (v8::Isolate::GetCurrent() , &weakNPObjectCallback));389 DEFINE_STATIC_LOCAL(DOMWrapperMap<NPObject>, npObjectMap, (v8::Isolate::GetCurrent())); 392 390 return npObjectMap; 393 391 } 394 392 395 static void weakNPObjectCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> value, void*) 393 template<> 394 inline void WeakHandleListener<DOMWrapperMap<NPObject> >::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> value, DOMWrapperMap<NPObject>*) 396 395 { 397 396 ASSERT(value->IsObject()); -
trunk/Source/WebCore/bindings/v8/V8Utilities.h
r141946 r147391 64 64 bool getMessagePortArray(v8::Local<v8::Value>, MessagePortArray&, v8::Isolate*); 65 65 66 // FIXME: We might move this to its own file. 67 template<class OwnerType, class ArgumentType = OwnerType> 68 class WeakHandleListener { 69 public: 70 template <class HandleType> 71 static void makeWeak(v8::Isolate* isolate, HandleType handle, ArgumentType* parameter) 72 { 73 handle.MakeWeak(isolate, parameter, &invokeWeakCallback); 74 } 75 76 static void callback(v8::Isolate*, v8::Persistent<v8::Value>, ArgumentType*); 77 78 private: 79 static void invokeWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> handle, void* parameter) 80 { 81 WeakHandleListener<OwnerType, ArgumentType>::callback(isolate, handle, static_cast<ArgumentType*>(parameter)); 82 } 83 }; 84 66 85 } // namespace WebCore 67 86 -
trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp
r145049 r147391 58 58 } 59 59 60 static void cachedStringCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> wrapper, void* parameter) 60 template<> 61 void WeakHandleListener<StringCache, StringImpl>::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> wrapper, StringImpl* stringImpl) 61 62 { 62 StringImpl* stringImpl = static_cast<StringImpl*>(parameter);63 63 V8PerIsolateData::current()->stringCache()->remove(stringImpl); 64 64 wrapper.Dispose(isolate); … … 100 100 stringImpl->ref(); 101 101 wrapper.MarkIndependent(isolate); 102 wrapper.MakeWeak(isolate, stringImpl, cachedStringCallback);102 WeakHandleListener<StringCache, StringImpl>::makeWeak(isolate, wrapper, stringImpl); 103 103 m_stringCache.set(stringImpl, wrapper); 104 104 -
trunk/Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp
r145353 r147391 46 46 namespace WebCore { 47 47 48 static void WeakReferenceCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, void* parameter) 48 template<> 49 void WeakHandleListener<InjectedScriptManager, InjectedScriptHost>::callback(v8::Isolate* isolate, v8::Persistent<v8::Value> object, InjectedScriptHost* host) 49 50 { 50 InjectedScriptHost* nativeObject = static_cast<InjectedScriptHost*>(parameter); 51 nativeObject->deref(); 51 host->deref(); 52 52 object.Dispose(isolate); 53 53 object.Clear(); … … 71 71 host->ref(); 72 72 v8::Persistent<v8::Object> weakHandle = v8::Persistent<v8::Object>::New(isolate, instance); 73 weakHandle.MakeWeak(isolate, host, &WeakReferenceCallback);73 WeakHandleListener<InjectedScriptManager, InjectedScriptHost>::makeWeak(isolate, weakHandle, host); 74 74 return instance; 75 75 }
Note: See TracChangeset
for help on using the changeset viewer.