Changeset 42657 in webkit
- Timestamp:
- Apr 19, 2009 12:38:26 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r42655 r42657 1 2009-04-18 Geoffrey Garen <ggaren@apple.com> 2 3 Reviewed by Alexey Proskuryakov. 4 5 More fix for https://bugs.webkit.org/show_bug.cgi?id=21260 6 Unbounded memory growth when churning elements with anonymous event handler functions 7 8 Removed a little more complexity from event handler creation and destruction. 9 10 Removed the jsProtectedEventListeners, jsProtectedInlineEventListeners, 11 and jsInlineEventListeners maps, and all the code for managing them. 12 13 ProtectedEventListeners don't exist anymore, so they're easy to nix. 14 15 Inline EventListeners do still exist, but there's no reason to track 16 them in a map. The map exists to enable 'removeEventListener' to associate 17 a unique JSEventListener with a given JavaScript function. But the 18 'removeEventListener' API only works with non-inline event listeners! 19 20 * bindings/js/JSDOMGlobalObject.cpp: 21 (WebCore::JSDOMGlobalObject::~JSDOMGlobalObject): 22 (WebCore::JSDOMGlobalObject::findJSEventListener): 23 (WebCore::JSDOMGlobalObject::findOrCreateJSEventListener): 24 (WebCore::JSDOMGlobalObject::createJSInlineEventListener): 25 * bindings/js/JSDOMGlobalObject.h: 26 * bindings/js/JSEventListener.cpp: 27 (WebCore::JSEventListener::JSEventListener): 28 (WebCore::JSEventListener::clearJSFunctionInline): 29 * bindings/js/JSLazyEventListener.cpp: 30 (WebCore::JSLazyEventListener::~JSLazyEventListener): 31 (WebCore::JSLazyEventListener::parseCode): 32 * bindings/scripts/CodeGeneratorJS.pm: 33 1 34 2009-04-18 Dan Bernstein <mitz@apple.com> 2 35 -
trunk/WebCore/bindings/js/JSDOMGlobalObject.cpp
r42589 r42657 54 54 JSDOMGlobalObject::~JSDOMGlobalObject() 55 55 { 56 // Clear any backpointers to the window57 ProtectedListenersMap::iterator i1 = d()->jsProtectedEventListeners.begin();58 ProtectedListenersMap::iterator e1 = d()->jsProtectedEventListeners.end();59 for (; i1 != e1; ++i1)60 i1->second->clearGlobalObject();61 62 i1 = d()->jsProtectedInlineEventListeners.begin();63 e1 = d()->jsProtectedInlineEventListeners.end();64 for (; i1 != e1; ++i1)65 i1->second->clearGlobalObject();66 67 56 JSListenersMap::iterator i2 = d()->jsEventListeners.begin(); 68 57 JSListenersMap::iterator e2 = d()->jsEventListeners.end(); 69 for (; i2 != e2; ++i2)70 i2->second->clearGlobalObject();71 72 i2 = d()->jsInlineEventListeners.begin();73 e2 = d()->jsInlineEventListeners.end();74 58 for (; i2 != e2; ++i2) 75 59 i2->second->clearGlobalObject(); … … 91 75 } 92 76 93 JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValuePtr val , bool isInline)77 JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValuePtr val) 94 78 { 95 79 if (!val.isObject()) 96 80 return 0; 97 81 98 JSListenersMap& listeners = isInline ? d()->jsInlineEventListeners : d()->jsEventListeners; 99 return listeners.get(asObject(val)); 82 return d()->jsEventListeners.get(asObject(val)); 100 83 } 101 84 102 PassRefPtr<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(JSValuePtr val , bool isInline)85 PassRefPtr<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(JSValuePtr val) 103 86 { 104 if (JSEventListener* listener = findJSEventListener(val , isInline))87 if (JSEventListener* listener = findJSEventListener(val)) 105 88 return listener; 106 89 … … 109 92 110 93 // The JSEventListener constructor adds it to our jsEventListeners map. 111 return JSEventListener::create(asObject(val), this, isInline).get();94 return JSEventListener::create(asObject(val), this, false).get(); 112 95 } 113 96 114 JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedEventListeners()97 PassRefPtr<JSEventListener> JSDOMGlobalObject::createJSInlineEventListener(JSValuePtr val) 115 98 { 116 return d()->jsProtectedEventListeners;117 } 99 if (!val.isObject()) 100 return 0; 118 101 119 JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedInlineEventListeners() 120 { 121 return d()->jsProtectedInlineEventListeners; 102 return JSEventListener::create(asObject(val), this, true).get(); 122 103 } 123 104 … … 125 106 { 126 107 return d()->jsEventListeners; 127 }128 129 JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsInlineEventListeners()130 {131 return d()->jsInlineEventListeners;132 108 } 133 109 -
trunk/WebCore/bindings/js/JSDOMGlobalObject.h
r42589 r42657 34 34 class Event; 35 35 class JSLazyEventListener; 36 class JSProtectedEventListener;37 36 class JSEventListener; 38 37 class ScriptExecutionContext; … … 56 55 57 56 // Finds a wrapper of a GC-unprotected JS EventListener, returns 0 if no existing one. 58 JSEventListener* findJSEventListener(JSC::JSValuePtr , bool isInline = false);57 JSEventListener* findJSEventListener(JSC::JSValuePtr); 59 58 60 59 // Finds or creates a wrapper of a JS EventListener. JS EventListener object is *NOT* GC-protected. 61 PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::JSValuePtr , bool isInline = false);60 PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::JSValuePtr); 62 61 63 typedef HashMap<JSC::JSObject*, JSLazyEventListener*> ProtectedListenersMap; 62 // Creates a GC-protected JS EventListener for an "onXXX" event attribute. 63 // These listeners cannot be removed through the removeEventListener API. 64 PassRefPtr<JSEventListener> createJSInlineEventListener(JSC::JSValuePtr); 65 64 66 typedef HashMap<JSC::JSObject*, JSEventListener*> JSListenersMap; 65 67 66 ProtectedListenersMap& jsProtectedEventListeners();67 ProtectedListenersMap& jsProtectedInlineEventListeners();68 68 JSListenersMap& jsEventListeners(); 69 JSListenersMap& jsInlineEventListeners();70 69 71 70 void setCurrentEvent(Event*); … … 81 80 JSDOMConstructorMap constructors; 82 81 83 JSDOMGlobalObject::ProtectedListenersMap jsProtectedEventListeners;84 JSDOMGlobalObject::ProtectedListenersMap jsProtectedInlineEventListeners;85 82 JSDOMGlobalObject::JSListenersMap jsEventListeners; 86 JSDOMGlobalObject::JSListenersMap jsInlineEventListeners;87 83 88 84 Event* evt; -
trunk/WebCore/bindings/js/JSEventListener.cpp
r42589 r42657 138 138 , m_globalObject(globalObject) 139 139 { 140 if (m_jsFunction) { 141 JSDOMWindow::JSListenersMap& listeners = isInline 142 ? globalObject->jsInlineEventListeners() : globalObject->jsEventListeners(); 143 listeners.set(m_jsFunction, this); 144 } 140 if (!isInline && m_jsFunction) 141 globalObject->jsEventListeners().set(m_jsFunction, this); 145 142 } 146 143 147 144 inline void JSEventListener::clearJSFunctionInline() 148 145 { 149 if (m_jsFunction && m_globalObject) { 150 JSDOMWindow::JSListenersMap& listeners = isInline() 151 ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners(); 152 listeners.remove(m_jsFunction); 153 } 146 if (!isInline() && m_jsFunction && m_globalObject) 147 m_globalObject->jsEventListeners().remove(m_jsFunction); 154 148 155 149 m_jsFunction = 0; -
trunk/WebCore/bindings/js/JSLazyEventListener.cpp
r42633 r42657 72 72 JSLazyEventListener::~JSLazyEventListener() 73 73 { 74 if (m_jsFunction && m_globalObject) {75 JSDOMWindow::ProtectedListenersMap& listeners = isInline()76 ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners();77 listeners.remove(m_jsFunction);78 }79 74 #ifndef NDEBUG 80 75 eventListenerCounter.decrement(); … … 140 135 m_code = String(); 141 136 m_eventParameterName = String(); 142 143 if (m_jsFunction) {144 ASSERT(isInline());145 JSDOMWindow::ProtectedListenersMap& listeners = m_globalObject->jsProtectedInlineEventListeners();146 listeners.set(m_jsFunction, const_cast<JSLazyEventListener*>(this));147 }148 137 } 149 138 -
trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm
r42569 r42657 1256 1256 push(@implContent, " return;\n"); 1257 1257 } 1258 push(@implContent, " imp->set$implSetterFunctionName(globalObject-> findOrCreateJSEventListener(value, true));\n");1258 push(@implContent, " imp->set$implSetterFunctionName(globalObject->createJSInlineEventListener(value));\n"); 1259 1259 } elsif ($attribute->signature->type =~ /Constructor$/) { 1260 1260 my $constructorType = $attribute->signature->type;
Note: See TracChangeset
for help on using the changeset viewer.