Title: [128249] trunk/Source/WebCore
Revision
128249
Author
[email protected]
Date
2012-09-11 17:41:06 -0700 (Tue, 11 Sep 2012)

Log Message

Add new JSDependentRetained that allows keeping a JSObject alive as long as another is alive
https://bugs.webkit.org/show_bug.cgi?id=96034

Patch by Elliott Sprehn <[email protected]> on 2012-09-11
Reviewed by Geoffrey Garen.

Add new JSDependentRetained (with the same API as V8DependentRetained) that allows keeping
a JSObject alive as long as another is alive. This is useful for keeping callbacks on
wrappers without keeping strong references into the JS heap in C++ which can result in
cycles that create memory leaks.

No new tests needed, this will be used to fix MutationObservers and UndoManager which will have tests.

* GNUmakefile.list.am:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDependentRetained.h: Added.
(WebCore):
(JSDependentRetained):
(WebCore::JSDependentRetained::JSDependentRetained):
(WebCore::JSDependentRetained::~JSDependentRetained):
(WebCore::JSDependentRetained::get): Get the JSObject value.
(WebCore::JSDependentRetained::isEmpty): Check if the value is still alive.
(WebCore::JSDependentRetained::retain): Sets the owner of the object, should only be used once.
(WebCore::JSDependentRetained::release):
* bindings/v8/V8DependentRetained.h:
(WebCore::V8DependentRetained::V8DependentRetained):
(WebCore::V8DependentRetained::retain): Added this method so the API for JSC and V8 are identical.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (128248 => 128249)


--- trunk/Source/WebCore/ChangeLog	2012-09-12 00:35:07 UTC (rev 128248)
+++ trunk/Source/WebCore/ChangeLog	2012-09-12 00:41:06 UTC (rev 128249)
@@ -1,3 +1,33 @@
+2012-09-11  Elliott Sprehn  <[email protected]>
+
+        Add new JSDependentRetained that allows keeping a JSObject alive as long as another is alive
+        https://bugs.webkit.org/show_bug.cgi?id=96034
+
+        Reviewed by Geoffrey Garen.
+
+        Add new JSDependentRetained (with the same API as V8DependentRetained) that allows keeping
+        a JSObject alive as long as another is alive. This is useful for keeping callbacks on
+        wrappers without keeping strong references into the JS heap in C++ which can result in
+        cycles that create memory leaks.
+
+        No new tests needed, this will be used to fix MutationObservers and UndoManager which will have tests.
+
+        * GNUmakefile.list.am:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSDependentRetained.h: Added.
+        (WebCore):
+        (JSDependentRetained):
+        (WebCore::JSDependentRetained::JSDependentRetained):
+        (WebCore::JSDependentRetained::~JSDependentRetained):
+        (WebCore::JSDependentRetained::get): Get the JSObject value.
+        (WebCore::JSDependentRetained::isEmpty): Check if the value is still alive.
+        (WebCore::JSDependentRetained::retain): Sets the owner of the object, should only be used once.
+        (WebCore::JSDependentRetained::release):
+        * bindings/v8/V8DependentRetained.h:
+        (WebCore::V8DependentRetained::V8DependentRetained):
+        (WebCore::V8DependentRetained::retain): Added this method so the API for JSC and V8 are identical.
+
 2012-09-11  Alec Flett  <[email protected]>
 
         Add 'any' type to V8 bindings as a synonym for DOMObject                

Modified: trunk/Source/WebCore/GNUmakefile.list.am (128248 => 128249)


--- trunk/Source/WebCore/GNUmakefile.list.am	2012-09-12 00:35:07 UTC (rev 128248)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2012-09-12 00:41:06 UTC (rev 128249)
@@ -2238,6 +2238,7 @@
 	Source/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp \
 	Source/WebCore/bindings/js/JSCustomXPathNSResolver.cpp \
 	Source/WebCore/bindings/js/JSCustomXPathNSResolver.h \
+	Source/WebCore/bindings/js/JSDependentRetained.h \
 	Source/WebCore/bindings/js/JSDictionary.cpp \
 	Source/WebCore/bindings/js/JSDictionary.h \
 	Source/WebCore/bindings/js/JSDOMBinding.cpp \

Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (128248 => 128249)


--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2012-09-12 00:35:07 UTC (rev 128248)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2012-09-12 00:41:06 UTC (rev 128249)
@@ -65926,6 +65926,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\bindings\js\JSDependentRetained.h"
+					>
+				</File>
+				<File
 					RelativePath="..\bindings\js\JSDedicatedWorkerContextCustom.cpp"
 					>
 					<FileConfiguration

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (128248 => 128249)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-09-12 00:35:07 UTC (rev 128248)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-09-12 00:41:06 UTC (rev 128249)
@@ -6548,6 +6548,7 @@
 		FE6FD48D0F676E9300092873 /* JSCoordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */; };
 		FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD48C0F676E9300092873 /* JSCoordinates.h */; };
 		FE700DD10F92D81A008E2BFE /* JSCoordinatesCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE700DD00F92D81A008E2BFE /* JSCoordinatesCustom.cpp */; };
+		FFD86E7815F9583600047233 /* JSDependentRetained.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD86E7715F9583600047233 /* JSDependentRetained.h */; };
 		FE80D7AB0E9C1ED2000D6F75 /* JSGeolocationCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */; };
 		FE80DA630E9C4703000D6F75 /* JSGeolocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */; };
 		FE80DA640E9C4703000D6F75 /* JSGeolocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA600E9C4703000D6F75 /* JSGeolocation.h */; };
@@ -13988,6 +13989,7 @@
 		FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCoordinates.cpp; sourceTree = "<group>"; };
 		FE6FD48C0F676E9300092873 /* JSCoordinates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCoordinates.h; sourceTree = "<group>"; };
 		FE700DD00F92D81A008E2BFE /* JSCoordinatesCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCoordinatesCustom.cpp; sourceTree = "<group>"; };
+		FFD86E7715F9583600047233 /* JSDependentRetained.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDependentRetained.h; sourceTree = "<group>"; };
 		FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeolocationCustom.cpp; sourceTree = "<group>"; };
 		FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeolocation.cpp; sourceTree = "<group>"; };
 		FE80DA600E9C4703000D6F75 /* JSGeolocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGeolocation.h; sourceTree = "<group>"; };
@@ -20195,6 +20197,7 @@
 				C585A66111D4FAC5004C3E4B /* IDBBindingUtilities.h */,
 				1C81BA030E97348300266E07 /* _javascript_CallFrame.cpp */,
 				1C81BA040E97348300266E07 /* _javascript_CallFrame.h */,
+				FFD86E7715F9583600047233 /* JSDependentRetained.h */,
 				BCE438A1140C0DBF005E437E /* JSDictionary.cpp */,
 				BCE4389B140B1BA7005E437E /* JSDictionary.h */,
 				93B70D4709EB0C7C009D8468 /* JSDOMBinding.cpp */,
@@ -23876,6 +23879,7 @@
 				2E97CE701293AD6B00C5C8FF /* JSDataView.h in Headers */,
 				4162A4581011464700DFF3ED /* JSDedicatedWorkerContext.h in Headers */,
 				FDA15ED212B03F94003A583A /* JSDelayNode.h in Headers */,
+				FFD86E7815F9583600047233 /* JSDependentRetained.h in Headers */,
 				31FB1A66120A5D3F00DC02A0 /* JSDeviceMotionEvent.h in Headers */,
 				59A86008119DAFA100DEF1EF /* JSDeviceOrientationEvent.h in Headers */,
 				BCE4389C140B1BA8005E437E /* JSDictionary.h in Headers */,

Added: trunk/Source/WebCore/bindings/js/JSDependentRetained.h (0 => 128249)


--- trunk/Source/WebCore/bindings/js/JSDependentRetained.h	                        (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDependentRetained.h	2012-09-12 00:41:06 UTC (rev 128249)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 Google Inc. All Rights Reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSDependentRetained_h
+#define JSDependentRetained_h
+
+#include <heap/Weak.h>
+#include <runtime/JSObject.h>
+#include <runtime/PrivateName.h>
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class JSDependentRetained {
+public:
+    JSDependentRetained(JSC::JSObject* owner, JSC::JSObject* value)
+        : m_value(value)
+    {
+        ASSERT(value);
+        if (owner)
+            retain(owner);
+    }
+
+    ~JSDependentRetained()
+    {
+        release();
+    }
+
+    JSC::JSObject* get() const
+    {
+        return m_value.get();
+    }
+
+    bool isEmpty() const
+    {
+        return !m_owner || !m_value;
+    }
+
+    void retain(JSC::JSObject* owner)
+    {
+        ASSERT(!m_owner && owner);
+        ASSERT(m_value);
+        m_owner = JSC::PassWeak<JSC::JSObject>(owner);
+        m_owner->putDirect(m_propertyName, get());
+    }
+
+private:
+
+    void release()
+    {
+        if (m_owner)
+            m_owner->removeDirect(m_propertyName);
+        m_value.clear();
+        m_owner.clear();
+    }
+
+    JSC::Weak<JSC::JSObject> m_owner;
+    JSC::Weak<JSC::JSObject> m_value;
+    JSC::PrivateName m_propertyName;
+};
+
+} // namespace WebCore
+
+#endif // JSDependentRetained_h

Modified: trunk/Source/WebCore/bindings/v8/V8DependentRetained.h (128248 => 128249)


--- trunk/Source/WebCore/bindings/v8/V8DependentRetained.h	2012-09-12 00:35:07 UTC (rev 128248)
+++ trunk/Source/WebCore/bindings/v8/V8DependentRetained.h	2012-09-12 00:41:06 UTC (rev 128249)
@@ -1,29 +1,25 @@
 /*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All Rights Reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
@@ -44,15 +40,13 @@
 class V8DependentRetained {
 public:
     V8DependentRetained(v8::Handle<v8::Object> owner, v8::Handle<v8::Object> value)
-        : m_owner(owner)
-        , m_value(value)
+        : m_value(value)
         , m_propertyName(createPropertyName())
     {
-        ASSERT(!m_owner.IsEmpty());
-        ASSERT(!m_value.IsEmpty());
-        owner->SetHiddenValue(m_propertyName.get(), value);
-        m_owner.get().MakeWeak(this, &V8DependentRetained::ownerWeakCallback);
+        ASSERT(!m_value.isEmpty());
         m_value.get().MakeWeak(this, &V8DependentRetained::valueWeakCallback);
+        if (!owner.IsEmpty())
+            retain(owner);
     }
 
     ~V8DependentRetained()
@@ -70,9 +64,14 @@
         return m_owner.isEmpty() || m_value.isEmpty();
     }
 
-    // FIXME: We might add an explicit retain(v8::Handle<v8::Object>) method to allow
-    // creating one of these and choosing the owner later. Such behavior is required
-    // in JSC, but not in v8 right now.
+    void retain(v8::Handle<v8::Object> owner)
+    {
+        ASSERT(m_owner.isEmpty() && !owner.IsEmpty());
+        ASSERT(!m_value.isEmpty());
+        owner->SetHiddenValue(m_propertyName.get(), get());
+        m_owner = owner;
+        m_owner.get().MakeWeak(this, &V8DependentRetained::ownerWeakCallback);
+    }
 
 private:
     static v8::Handle<v8::String> createPropertyName()
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to