Title: [113393] branches/chromium/1084
Revision
113393
Author
[email protected]
Date
2012-04-05 16:28:21 -0700 (Thu, 05 Apr 2012)

Log Message

Merge 113086 - [v8] Fix memory leak in V8LazyEventListener
https://bugs.webkit.org/show_bug.cgi?id=83057

Reviewed by Ojan Vafai.

Source/WebCore:

This also brings the V8 and JSC implementation closer. The timing when we first lookup
the form element is now same in JSC and V8 (but different from Mozilla).

This also clears the strings once the code has been parsed and the function created.

Tests: fast/dom/inline-event-attributes-moved.html
       fast/dom/inline-event-attributes-release.html

* bindings/v8/V8LazyEventListener.cpp:
(WebCore::V8LazyEventListener::V8LazyEventListener):
(WebCore::V8LazyEventListener::prepareListenerObject):
* bindings/v8/V8LazyEventListener.h:
(WebCore::V8LazyEventListener::create):
(V8LazyEventListener):

LayoutTests:

* fast/dom/inline-event-attributes-moved-expected.txt: Added.
* fast/dom/inline-event-attributes-moved.html: Added.
* fast/dom/inline-event-attributes-release-expected.txt: Added.
* fast/dom/inline-event-attributes-release.html: Added.

[email protected]
Review URL: https://chromiumcodereview.appspot.com/10007027

Modified Paths

Added Paths

Diff

Modified: branches/chromium/1084/LayoutTests/ChangeLog (113392 => 113393)


--- branches/chromium/1084/LayoutTests/ChangeLog	2012-04-05 23:20:31 UTC (rev 113392)
+++ branches/chromium/1084/LayoutTests/ChangeLog	2012-04-05 23:28:21 UTC (rev 113393)
@@ -12,6 +12,18 @@
         * webintents/web-intents-api.html:
         * webintents/web-intents-invoke.html:
 
+2012-04-03  Erik Arvidsson  <[email protected]>
+
+        [v8] Fix memory leak in V8LazyEventListener
+        https://bugs.webkit.org/show_bug.cgi?id=83057
+
+        Reviewed by Ojan Vafai.
+
+        * fast/dom/inline-event-attributes-moved-expected.txt: Added.
+        * fast/dom/inline-event-attributes-moved.html: Added.
+        * fast/dom/inline-event-attributes-release-expected.txt: Added.
+        * fast/dom/inline-event-attributes-release.html: Added.
+
 2012-03-27  Dirk Pranke  <[email protected]>
 
         Remove a bunch of lines that are no longer failing.

Copied: branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-moved-expected.txt (from rev 113086, trunk/LayoutTests/fast/dom/inline-event-attributes-moved-expected.txt) (0 => 113393)


--- branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-moved-expected.txt	                        (rev 0)
+++ branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-moved-expected.txt	2012-04-05 23:28:21 UTC (rev 113393)
@@ -0,0 +1,10 @@
+Tests that we have the expected form in scope
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS expected is "undefined"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-moved.html (from rev 113086, trunk/LayoutTests/fast/dom/inline-event-attributes-moved.html) (0 => 113393)


--- branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-moved.html	                        (rev 0)
+++ branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-moved.html	2012-04-05 23:28:21 UTC (rev 113393)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<script src=""
+<script>
+
+description('Tests that we have the expected form in scope');
+
+function dispatchClick(element)
+{
+    var clickEvent = document.createEvent('MouseEvent');
+    clickEvent.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+    element.dispatchEvent(clickEvent);
+}
+
+var expected;
+var f = document.createElement('form');
+var i = f.appendChild(document.createElement('input'));
+i.setAttribute('onclick', 'expected = typeof action');
+f.removeChild(i);
+f = null;
+gc();
+dispatchClick(i);
+shouldBeEqualToString('expected', 'undefined');
+
+</script>
+<script src=""
\ No newline at end of file

Copied: branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-release-expected.txt (from rev 113086, trunk/LayoutTests/fast/dom/inline-event-attributes-release-expected.txt) (0 => 113393)


--- branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-release-expected.txt	                        (rev 0)
+++ branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-release-expected.txt	2012-04-05 23:28:21 UTC (rev 113393)
@@ -0,0 +1,10 @@
+Tests that we do not hold on to any nodes
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS afterCount - beforeCount is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-release.html (from rev 113086, trunk/LayoutTests/fast/dom/inline-event-attributes-release.html) (0 => 113393)


--- branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-release.html	                        (rev 0)
+++ branches/chromium/1084/LayoutTests/fast/dom/inline-event-attributes-release.html	2012-04-05 23:28:21 UTC (rev 113393)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<script src=""
+<script>
+
+description('Tests that we do not hold on to any nodes');
+
+gc();
+
+function numberOfLiveNodes() {
+    return window.internals && window.internals.numberOfLiveNodes && window.internals.numberOfLiveNodes();
+}
+
+var beforeCount = numberOfLiveNodes();
+
+var f = document.createElement('form');
+var i = f.appendChild(document.createElement('input'));
+i.setAttribute('onclick', '');
+f.removeChild(i);
+f = null;
+i = null;
+gc();
+
+var afterCount = numberOfLiveNodes();
+
+shouldBe('afterCount - beforeCount', '0');
+
+</script>
+<script src=""
\ No newline at end of file

Modified: branches/chromium/1084/Source/WebCore/bindings/v8/V8LazyEventListener.cpp (113392 => 113393)


--- branches/chromium/1084/Source/WebCore/bindings/v8/V8LazyEventListener.cpp	2012-04-05 23:20:31 UTC (rev 113392)
+++ branches/chromium/1084/Source/WebCore/bindings/v8/V8LazyEventListener.cpp	2012-04-05 23:28:21 UTC (rev 113393)
@@ -50,18 +50,15 @@
 
 namespace WebCore {
 
-V8LazyEventListener::V8LazyEventListener(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String sourceURL, const TextPosition& position, PassRefPtr<Node> node, const WorldContextHandle& worldContext)
+V8LazyEventListener::V8LazyEventListener(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String sourceURL, const TextPosition& position, Node* node, const WorldContextHandle& worldContext)
     : V8AbstractEventListener(true, worldContext)
     , m_functionName(functionName)
     , m_eventParameterName(eventParameterName)
     , m_code(code)
     , m_sourceURL(sourceURL)
     , m_node(node)
-    , m_formElement(0)
     , m_position(position)
 {
-    if (m_node && m_node->isHTMLElement())
-        m_formElement = static_cast<HTMLElement*>(m_node.get())->form();
 }
 
 template<typename T>
@@ -165,13 +162,14 @@
     ASSERT(value->IsFunction());
     v8::Local<v8::Function> intermediateFunction = value.As<v8::Function>();
 
-    v8::Handle<v8::Object> nodeWrapper = toObjectWrapper<Node>(m_node.get());
-    v8::Handle<v8::Object> formWrapper = toObjectWrapper<HTMLFormElement>(m_formElement.get());
+    HTMLFormElement* formElement = 0;
+    if (m_node && m_node->isHTMLElement())
+        formElement = static_cast<HTMLElement*>(m_node)->form();
+
+    v8::Handle<v8::Object> nodeWrapper = toObjectWrapper<Node>(m_node);
+    v8::Handle<v8::Object> formWrapper = toObjectWrapper<HTMLFormElement>(formElement);
     v8::Handle<v8::Object> documentWrapper = toObjectWrapper<Document>(m_node ? m_node->ownerDocument() : 0);
 
-    m_node.clear();
-    m_formElement.clear();
-
     v8::Handle<v8::Value> parameters[3] = { nodeWrapper, formWrapper, documentWrapper };
 
     // Use Call directly to avoid an erroneous call to V8RecursionScope::didLeaveScriptContext().
@@ -212,6 +210,12 @@
 
     wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
 
+    // Since we only parse once, there's no need to keep data used for parsing around anymore.
+    m_functionName = String();
+    m_code = String();
+    m_eventParameterName = String();
+    m_sourceURL = String();
+
     setListenerObject(wrappedFunction);
 }
 

Modified: branches/chromium/1084/Source/WebCore/bindings/v8/V8LazyEventListener.h (113392 => 113393)


--- branches/chromium/1084/Source/WebCore/bindings/v8/V8LazyEventListener.h	2012-04-05 23:20:31 UTC (rev 113392)
+++ branches/chromium/1084/Source/WebCore/bindings/v8/V8LazyEventListener.h	2012-04-05 23:28:21 UTC (rev 113393)
@@ -48,7 +48,7 @@
     // A V8LazyEventListener is either a HTML or SVG event handler.
     class V8LazyEventListener : public V8AbstractEventListener {
     public:
-        static PassRefPtr<V8LazyEventListener> create(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String& sourceURL, const TextPosition& position, PassRefPtr<Node> node, const WorldContextHandle& worldContext)
+        static PassRefPtr<V8LazyEventListener> create(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String& sourceURL, const TextPosition& position, Node* node, const WorldContextHandle& worldContext)
         {
             return adoptRef(new V8LazyEventListener(functionName, eventParameterName, code, sourceURL, position, node, worldContext));
         }
@@ -59,7 +59,7 @@
         virtual void prepareListenerObject(ScriptExecutionContext*);
 
     private:
-        V8LazyEventListener(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String sourceURL, const TextPosition&, PassRefPtr<Node>, const WorldContextHandle&);
+        V8LazyEventListener(const AtomicString& functionName, const AtomicString& eventParameterName, const String& code, const String sourceURL, const TextPosition&, Node*, const WorldContextHandle&);
 
         virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
 
@@ -73,8 +73,7 @@
         AtomicString m_eventParameterName;
         String m_code;
         String m_sourceURL;
-        RefPtr<Node> m_node;
-        RefPtr<HTMLFormElement> m_formElement;
+        Node* m_node;
         TextPosition m_position;
     };
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to