Commit 7d56968b authored by ggaren@apple.com's avatar ggaren@apple.com

2009-04-15 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Sam Weinig.
        
        More fix for https://bugs.webkit.org/show_bug.cgi?id=21260
        Unbounded memory growth when churning elements with anonymous event handler functions

        Also fixed <rdar://problem/6792909> WebInspector crashes when reloading
        a page with breakpoints set
        
        * bindings/js/JSEventListener.cpp:
        (WebCore::JSEventListener::clearJSFunctionInline):
        (WebCore::JSEventListener::markJSFunction):
        * bindings/js/JSEventListener.h: Actually clear our function and global
        object pointers when our client instructs us to. (Oops!) Also, mark
        our global object while we still intend to use it.

        * bindings/js/JSSVGElementInstanceCustom.cpp:
        (WebCore::JSSVGElementInstance::mark):
        (WebCore::toJS):
        * bindings/scripts/CodeGeneratorJS.pm:
        * svg/SVGElementInstance.idl: For every SVGElementInstance wrapper, ensure
        that the corresponding element also has a wrapper, to keep its event
        listeners alive.



git-svn-id: svn://svn.chromium.org/blink/trunk@42569 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 2fcbd0eb
2009-04-15 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
More fix for https://bugs.webkit.org/show_bug.cgi?id=21260
Unbounded memory growth when churning elements with anonymous event handler functions
Also fixed <rdar://problem/6792909> WebInspector crashes when reloading
a page with breakpoints set
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::clearJSFunctionInline):
(WebCore::JSEventListener::markJSFunction):
* bindings/js/JSEventListener.h: Actually clear our function and global
object pointers when our client instructs us to. (Oops!) Also, mark
our global object while we still intend to use it.
* bindings/js/JSSVGElementInstanceCustom.cpp:
(WebCore::JSSVGElementInstance::mark):
(WebCore::toJS):
* bindings/scripts/CodeGeneratorJS.pm:
* svg/SVGElementInstance.idl: For every SVGElementInstance wrapper, ensure
that the corresponding element also has a wrapper, to keep its event
listeners alive.
2009-04-15 Dimitri Glazkov <dglazkov@chromium.org> 2009-04-15 Dimitri Glazkov <dglazkov@chromium.org>
Reviewed by Darin Fisher. Reviewed by Darin Fisher.
...@@ -144,6 +144,18 @@ JSEventListener::JSEventListener(JSObject* function, JSDOMGlobalObject* globalOb ...@@ -144,6 +144,18 @@ JSEventListener::JSEventListener(JSObject* function, JSDOMGlobalObject* globalOb
} }
} }
inline void JSEventListener::clearJSFunctionInline()
{
if (m_jsFunction && m_globalObject) {
JSDOMWindow::JSListenersMap& listeners = isInline()
? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners();
listeners.remove(m_jsFunction);
}
m_jsFunction = 0;
m_globalObject = 0;
}
JSEventListener::~JSEventListener() JSEventListener::~JSEventListener()
{ {
clearJSFunctionInline(); clearJSFunctionInline();
...@@ -173,6 +185,8 @@ void JSEventListener::markJSFunction() ...@@ -173,6 +185,8 @@ void JSEventListener::markJSFunction()
{ {
if (m_jsFunction && !m_jsFunction->marked()) if (m_jsFunction && !m_jsFunction->marked())
m_jsFunction->mark(); m_jsFunction->mark();
if (m_globalObject && !m_globalObject->marked())
m_globalObject->mark();
} }
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -65,14 +65,7 @@ namespace WebCore { ...@@ -65,14 +65,7 @@ namespace WebCore {
virtual JSDOMGlobalObject* globalObject() const; virtual JSDOMGlobalObject* globalObject() const;
void clearJSFunctionInline() void clearJSFunctionInline();
{
if (m_jsFunction && m_globalObject) {
JSDOMWindow::JSListenersMap& listeners = isInline()
? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners();
listeners.remove(m_jsFunction);
}
}
JSC::JSObject* m_jsFunction; JSC::JSObject* m_jsFunction;
JSDOMGlobalObject* m_globalObject; JSDOMGlobalObject* m_globalObject;
......
...@@ -26,11 +26,12 @@ ...@@ -26,11 +26,12 @@
#include "config.h" #include "config.h"
#if ENABLE(SVG) #if ENABLE(SVG)
#include "SVGElementInstance.h"
#include "JSSVGElementInstance.h" #include "JSSVGElementInstance.h"
#include "JSEventListener.h"
#include "JSDOMWindow.h" #include "JSDOMWindow.h"
#include "JSEventListener.h"
#include "JSSVGElement.h"
#include "SVGElementInstance.h"
using namespace JSC; using namespace JSC;
...@@ -38,9 +39,13 @@ namespace WebCore { ...@@ -38,9 +39,13 @@ namespace WebCore {
void JSSVGElementInstance::mark() void JSSVGElementInstance::mark()
{ {
Base::mark(); DOMObject::mark();
markEventListeners(impl()->eventListeners()); // Mark the wrapper for our corresponding element, so it can mark its event handlers.
JSNode* correspondingWrapper = getCachedDOMNodeWrapper(impl()->correspondingElement()->document(), impl()->correspondingElement());
ASSERT(correspondingWrapper);
if (!correspondingWrapper->marked())
correspondingWrapper->mark();
} }
JSValuePtr JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args) JSValuePtr JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args)
...@@ -71,6 +76,17 @@ void JSSVGElementInstance::pushEventHandlerScope(ExecState*, ScopeChain&) const ...@@ -71,6 +76,17 @@ void JSSVGElementInstance::pushEventHandlerScope(ExecState*, ScopeChain&) const
{ {
} }
JSC::JSValuePtr toJS(JSC::ExecState* exec, SVGElementInstance* object)
{
JSValuePtr result = getDOMObjectWrapper<JSSVGElementInstance>(exec, object);
// Ensure that our corresponding element has a JavaScript wrapper to keep its event handlers alive.
if (object)
toJS(exec, object->correspondingElement());
return result;
} }
#endif } // namespace WebCore
#endif // ENABLE(SVG)
...@@ -145,7 +145,7 @@ sub UsesManualToJSImplementation ...@@ -145,7 +145,7 @@ sub UsesManualToJSImplementation
{ {
my $type = shift; my $type = shift;
return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event" or $type eq "ImageData" or $type eq "Element" or $type eq "Text"; return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event" or $type eq "ImageData" or $type eq "Element" or $type eq "Text" or $type eq "SVGElementInstance";
return 0; return 0;
} }
...@@ -1018,10 +1018,6 @@ sub GenerateImplementation ...@@ -1018,10 +1018,6 @@ sub GenerateImplementation
} elsif ($interfaceName eq "DOMWindow") { } elsif ($interfaceName eq "DOMWindow") {
$implIncludes{"RegisteredEventListener.h"} = 1; $implIncludes{"RegisteredEventListener.h"} = 1;
push(@implContent, " invalidateEventListeners(impl()->eventListeners());\n"); push(@implContent, " invalidateEventListeners(impl()->eventListeners());\n");
} elsif ($interfaceName eq "SVGElementInstance") {
$implIncludes{"RegisteredEventListener.h"} = 1;
push(@implContent, " invalidateEventListeners(m_impl->eventListeners());\n");
push(@implContent, " forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get());\n");
} else { } else {
if ($podType) { if ($podType) {
my $animatedType = $implClassName; my $animatedType = $implClassName;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment