Title: [133044] trunk
Revision
133044
Author
[email protected]
Date
2012-10-31 10:33:32 -0700 (Wed, 31 Oct 2012)

Log Message

[V8] Garbage collection should use opaque roots rather than implicit references
https://bugs.webkit.org/show_bug.cgi?id=100707

Reviewed by Kentaro Hara.

Source/WebCore:

This patch replaces visitDOMWrapper with opaqueRootForGC. The
former used to inform V8 of implicit relationships between wrapper
objects on a per-wrapper basis. That meant that we needed to know which
DOMDataStore a given wrapper was in during garbage collection.

After this patch, we now use object groups rather than implicit
references to inform V8 of these relationships. That has two benefits:

1) We no longer need to know which DOMDataStore a wrapper belongs
   because we don't need to find the exact source wrapper for the
   implicit connection.

2) We can now handle more complicated implicit relationships, for
   example when some of the intervening objects haven't had their
   _javascript_ wrappers created yet.

This patch also unlocks to paths of future development:
A) Fixing the remaining failures in fast/dom/gc-9.html
B) Enumerating DOM wrappers entirely from V8 rather than from the
   DOMWrapperMaps (so that we can move more object towards using
   IntrusiveDOMWrapperMaps, which aren't enumerable from WebCore).

* bindings/scripts/CodeGeneratorV8.pm:
(NeedsCustomOpaqueRootForGC):
(GenerateOpaqueRootForGC):
(GenerateHeader):
(GenerateImplementation):
* bindings/v8/V8GCController.cpp:
(ImplicitConnection):
(WebCore::ImplicitConnection::ImplicitConnection):
(WebCore::ImplicitConnection::root):
(WebCore::ImplicitConnection::wrapper):
(WebCore):
(WebCore::operator<):
(WrapperGrouper):
(WebCore::WrapperGrouper::WrapperGrouper):
(WebCore::WrapperGrouper::addToGroup):
(WebCore::WrapperGrouper::keepAlive):
(WebCore::WrapperGrouper::apply):
(WebCore::ObjectVisitor::ObjectVisitor):
(WebCore::ObjectVisitor::visitDOMWrapper):
(ObjectVisitor):
(WebCore::V8GCController::opaqueRootForGC):
(WebCore::NodeVisitor::NodeVisitor):
(WebCore::NodeVisitor::visitNodeWrapper):
(NodeVisitor):
(WebCore::V8GCController::majorGCPrologue):
* bindings/v8/V8GCController.h:
(WebCore):
(V8GCController):
* bindings/v8/WrapperTypeInfo.h:
(WebCore):
(WebCore::WrapperTypeInfo::opaqueRootForGC):
(WrapperTypeInfo):
* bindings/v8/custom/V8NodeListCustom.cpp:
(WebCore::V8NodeList::opaqueRootForGC):
* bindings/v8/custom/V8SpeechRecognitionResultCustom.cpp:
(WebCore::V8SpeechRecognitionResult::opaqueRootForGC):

LayoutTests:

Test progression.

* platform/chromium/fast/dom/gc-9-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (133043 => 133044)


--- trunk/LayoutTests/ChangeLog	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/LayoutTests/ChangeLog	2012-10-31 17:33:32 UTC (rev 133044)
@@ -1,3 +1,14 @@
+2012-10-31  Adam Barth  <[email protected]>
+
+        [V8] Garbage collection should use opaque roots rather than implicit references
+        https://bugs.webkit.org/show_bug.cgi?id=100707
+
+        Reviewed by Kentaro Hara.
+
+        Test progression.
+
+        * platform/chromium/fast/dom/gc-9-expected.txt:
+
 2012-10-31  Stephen White  <[email protected]>
 
         [chromium] Added skipped expectations for new test

Modified: trunk/LayoutTests/platform/chromium/fast/dom/gc-9-expected.txt (133043 => 133044)


--- trunk/LayoutTests/platform/chromium/fast/dom/gc-9-expected.txt	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/LayoutTests/platform/chromium/fast/dom/gc-9-expected.txt	2012-10-31 17:33:32 UTC (rev 133044)
@@ -69,8 +69,8 @@
 FAIL: document.body.style.myCustomProperty should be 1 but instead is undefined.
 FAIL: document.body.style.getPropertyCSSValue('color').myCustomProperty should be 1 but instead is undefined.
 PASS: document.styleSheets.myCustomProperty should be 1 and is.
-FAIL: document.styleSheets[0].myCustomProperty should be 1 but instead is undefined.
-FAIL: document.styleSheets[0].cssRules.myCustomProperty should be 1 but instead is undefined.
+PASS: document.styleSheets[0].myCustomProperty should be 1 and is.
+PASS: document.styleSheets[0].cssRules.myCustomProperty should be 1 and is.
 FAIL: document.styleSheets[0].cssRules[0].myCustomProperty should be 1 but instead is undefined.
 PASS: new XPathEvaluator().myCustomProperty should be undefined and is.
 PASS: new XPathEvaluator().evaluate('/', document, null, 0, null).myCustomProperty should be undefined and is.

Modified: trunk/Source/WebCore/ChangeLog (133043 => 133044)


--- trunk/Source/WebCore/ChangeLog	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/ChangeLog	2012-10-31 17:33:32 UTC (rev 133044)
@@ -1,3 +1,69 @@
+2012-10-31  Adam Barth  <[email protected]>
+
+        [V8] Garbage collection should use opaque roots rather than implicit references
+        https://bugs.webkit.org/show_bug.cgi?id=100707
+
+        Reviewed by Kentaro Hara.
+
+        This patch replaces visitDOMWrapper with opaqueRootForGC. The
+        former used to inform V8 of implicit relationships between wrapper
+        objects on a per-wrapper basis. That meant that we needed to know which
+        DOMDataStore a given wrapper was in during garbage collection.
+
+        After this patch, we now use object groups rather than implicit
+        references to inform V8 of these relationships. That has two benefits:
+
+        1) We no longer need to know which DOMDataStore a wrapper belongs
+           because we don't need to find the exact source wrapper for the
+           implicit connection.
+
+        2) We can now handle more complicated implicit relationships, for
+           example when some of the intervening objects haven't had their
+           _javascript_ wrappers created yet.
+
+        This patch also unlocks to paths of future development:
+        A) Fixing the remaining failures in fast/dom/gc-9.html
+        B) Enumerating DOM wrappers entirely from V8 rather than from the
+           DOMWrapperMaps (so that we can move more object towards using
+           IntrusiveDOMWrapperMaps, which aren't enumerable from WebCore).
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (NeedsCustomOpaqueRootForGC):
+        (GenerateOpaqueRootForGC):
+        (GenerateHeader):
+        (GenerateImplementation):
+        * bindings/v8/V8GCController.cpp:
+        (ImplicitConnection):
+        (WebCore::ImplicitConnection::ImplicitConnection):
+        (WebCore::ImplicitConnection::root):
+        (WebCore::ImplicitConnection::wrapper):
+        (WebCore):
+        (WebCore::operator<):
+        (WrapperGrouper):
+        (WebCore::WrapperGrouper::WrapperGrouper):
+        (WebCore::WrapperGrouper::addToGroup):
+        (WebCore::WrapperGrouper::keepAlive):
+        (WebCore::WrapperGrouper::apply):
+        (WebCore::ObjectVisitor::ObjectVisitor):
+        (WebCore::ObjectVisitor::visitDOMWrapper):
+        (ObjectVisitor):
+        (WebCore::V8GCController::opaqueRootForGC):
+        (WebCore::NodeVisitor::NodeVisitor):
+        (WebCore::NodeVisitor::visitNodeWrapper):
+        (NodeVisitor):
+        (WebCore::V8GCController::majorGCPrologue):
+        * bindings/v8/V8GCController.h:
+        (WebCore):
+        (V8GCController):
+        * bindings/v8/WrapperTypeInfo.h:
+        (WebCore):
+        (WebCore::WrapperTypeInfo::opaqueRootForGC):
+        (WrapperTypeInfo):
+        * bindings/v8/custom/V8NodeListCustom.cpp:
+        (WebCore::V8NodeList::opaqueRootForGC):
+        * bindings/v8/custom/V8SpeechRecognitionResultCustom.cpp:
+        (WebCore::V8SpeechRecognitionResult::opaqueRootForGC):
+
 2012-10-31  Alexei Filippov  <[email protected]>
 
         Web Inspector: Add total node to native memory snapshot tree

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm (133043 => 133044)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm	2012-10-31 17:33:32 UTC (rev 133044)
@@ -181,7 +181,7 @@
     }
 }
 
-sub NeedsToVisitDOMWrapper
+sub NeedsCustomOpaqueRootForGC
 {
     my $dataNode = shift;
     return GetGenerateIsReachable($dataNode) || GetCustomIsReachable($dataNode);
@@ -199,7 +199,7 @@
     return $dataNode->extendedAttributes->{"CustomIsReachable"} || $dataNode->extendedAttributes->{"V8CustomIsReachable"};
 }
 
-sub GenerateVisitDOMWrapper
+sub GenerateOpaqueRootForGC
 {
     my ($dataNode, $implClassName) = @_;
 
@@ -208,7 +208,7 @@
     }
 
     push(@implContent, <<END);
-void V8${implClassName}::visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper)
+void* V8${implClassName}::opaqueRootForGC(void* object, v8::Persistent<v8::Object> wrapper)
 {
     ${implClassName}* impl = static_cast<${implClassName}*>(object);
 END
@@ -218,6 +218,8 @@
         GetGenerateIsReachable($dataNode) eq  "ImplOwnerNodeRoot" ||
         GetGenerateIsReachable($dataNode) eq  "ImplBaseRoot") {
 
+        $implIncludes{"V8GCController.h"} = 1;
+
         my $methodName;
         $methodName = "document" if (GetGenerateIsReachable($dataNode) eq "ImplDocument");
         $methodName = "element" if (GetGenerateIsReachable($dataNode) eq "ImplElementRoot");
@@ -226,17 +228,13 @@
         $methodName = "base" if (GetGenerateIsReachable($dataNode) eq "ImplBaseRoot");
 
         push(@implContent, <<END);
-    if (Node* owner = impl->${methodName}()) {
-        v8::Persistent<v8::Object> ownerWrapper = store->domNodeMap().get(owner);
-        if (!ownerWrapper.IsEmpty()) {
-            v8::Persistent<v8::Value> value = wrapper;
-            v8::V8::AddImplicitReferences(ownerWrapper, &value, 1);
-        }
-    }
+    if (Node* owner = impl->${methodName}())
+        return V8GCController::opaqueRootForGC(owner);
 END
     }
 
     push(@implContent, <<END);
+    return object;
 }
 
 END
@@ -387,8 +385,8 @@
     static WrapperTypeInfo info;
 END
 
-    if (NeedsToVisitDOMWrapper($dataNode)) {
-        push(@headerContent, "    static void visitDOMWrapper(DOMDataStore*, void*, v8::Persistent<v8::Object>);\n");
+    if (NeedsCustomOpaqueRootForGC($dataNode)) {
+        push(@headerContent, "    static void* opaqueRootForGC(void*, v8::Persistent<v8::Object>);\n");
     }
 
     if ($dataNode->extendedAttributes->{"ActiveDOMObject"}) {
@@ -2594,7 +2592,7 @@
     AddIncludesForType($interfaceName);
 
     my $toActive = $dataNode->extendedAttributes->{"ActiveDOMObject"} ? "${className}::toActiveDOMObject" : "0";
-    my $domVisitor = NeedsToVisitDOMWrapper($dataNode) ? "${className}::visitDOMWrapper" : "0";
+    my $rootForGC = NeedsCustomOpaqueRootForGC($dataNode) ? "${className}::opaqueRootForGC" : "0";
 
     # Find the super descriptor.
     my $parentClass = "";
@@ -2611,7 +2609,7 @@
 
     my $WrapperTypePrototype = $dataNode->isException ? "WrapperTypeErrorPrototype" : "WrapperTypeObjectPrototype";
 
-    push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, $toActive, $domVisitor, ${className}::installPerContextPrototypeProperties, $parentClassInfo, $WrapperTypePrototype };\n\n");
+    push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, $toActive, $rootForGC, ${className}::installPerContextPrototypeProperties, $parentClassInfo, $WrapperTypePrototype };\n\n");
     push(@implContentDecls, "namespace ${interfaceName}V8Internal {\n\n");
 
     push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
@@ -2672,8 +2670,8 @@
         GenerateReplaceableAttrSetter($dataNode, $implClassName);
     }
 
-    if (NeedsToVisitDOMWrapper($dataNode)) {
-        GenerateVisitDOMWrapper($dataNode, $implClassName);
+    if (NeedsCustomOpaqueRootForGC($dataNode)) {
+        GenerateOpaqueRootForGC($dataNode, $implClassName);
     }
 
     if ($dataNode->extendedAttributes->{"TypedArray"}) {

Modified: trunk/Source/WebCore/bindings/v8/V8GCController.cpp (133043 => 133044)


--- trunk/Source/WebCore/bindings/v8/V8GCController.cpp	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/bindings/v8/V8GCController.cpp	2012-10-31 17:33:32 UTC (rev 133044)
@@ -67,14 +67,79 @@
 
 namespace WebCore {
 
+class ImplicitConnection {
+public:
+    ImplicitConnection(void* root, v8::Persistent<v8::Value> wrapper)
+        : m_root(root)
+        , m_wrapper(wrapper)
+    {
+    }
+
+    void* root() const { return m_root; }
+    v8::Persistent<v8::Value> wrapper() const { return m_wrapper; }
+
+private:
+    void* m_root;
+    v8::Persistent<v8::Value> m_wrapper;
+};
+
+bool operator<(const ImplicitConnection& left, const ImplicitConnection& right)
+{
+    return left.root() < right.root();
+}
+
+class WrapperGrouper {
+public:
+    WrapperGrouper()
+    {
+        m_liveObjects.append(V8PerIsolateData::current()->ensureLiveRoot());
+    }
+
+    void addToGroup(void* root, v8::Persistent<v8::Value> wrapper)
+    {
+        m_connections.append(ImplicitConnection(root, wrapper));
+    }
+
+    void keepAlive(v8::Persistent<v8::Value> wrapper)
+    {
+        m_liveObjects.append(wrapper);
+    }
+
+    void apply()
+    {
+        if (m_liveObjects.size() > 1)
+            v8::V8::AddObjectGroup(m_liveObjects.data(), m_liveObjects.size());
+
+        std::sort(m_connections.begin(), m_connections.end());
+        Vector<v8::Persistent<v8::Value> > group;
+        size_t i = 0;
+        while (i < m_connections.size()) {
+            void* root = m_connections[i].root();
+
+            do {
+                group.append(m_connections[i++].wrapper());
+            } while (i < m_connections.size() && root == m_connections[i].root());
+
+            if (group.size() > 1)
+                v8::V8::AddObjectGroup(group.data(), group.size(), 0);
+
+            group.shrink(0);
+        }
+    }
+
+private:
+    Vector<v8::Persistent<v8::Value> > m_liveObjects;
+    Vector<ImplicitConnection> m_connections;
+};
+
 class ObjectVisitor : public DOMWrapperVisitor<void> {
 public:
-    explicit ObjectVisitor(Vector<v8::Persistent<v8::Value> >* liveObjects)
-        : m_liveObjects(liveObjects)
+    explicit ObjectVisitor(WrapperGrouper* grouper)
+        : m_grouper(grouper)
     {
     }
 
-    void visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper)
+    void visitDOMWrapper(DOMDataStore*, void* object, v8::Persistent<v8::Object> wrapper)
     {
         WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
 
@@ -84,20 +149,21 @@
             // implementation can't tell the difference.
             MessagePort* port = static_cast<MessagePort*>(object);
             if (port->isEntangled() || port->hasPendingActivity())
-                m_liveObjects->append(wrapper);
+                m_grouper->keepAlive(wrapper);
         } else {
             ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
             if (activeDOMObject && activeDOMObject->hasPendingActivity())
-                m_liveObjects->append(wrapper);
+                m_grouper->keepAlive(wrapper);
         }
 
-        type->visitDOMWrapper(store, object, wrapper);
+        m_grouper->addToGroup(type->opaqueRootForGC(object, wrapper), wrapper);
     }
 
 private:
-    Vector<v8::Persistent<v8::Value> >* m_liveObjects;
+    WrapperGrouper* m_grouper;
 };
 
+// FIXME: This should use opaque GC roots.
 static void addImplicitReferencesForNodeWithEventListeners(Node* node, v8::Persistent<v8::Object> wrapper)
 {
     ASSERT(node->hasEventListeners());
@@ -120,15 +186,16 @@
     v8::V8::AddImplicitReferences(wrapper, listeners.data(), listeners.size());
 }
 
-static Node* rootForGC(Node* node)
+void* V8GCController::opaqueRootForGC(Node* node)
 {
     if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static_cast<HTMLImageElement*>(node)->hasPendingActivity()))
         return node->document();
 
     if (node->isAttributeNode()) {
-        node = static_cast<Attr*>(node)->ownerElement();
-        if (!node)
-            return 0;
+        Node* ownerElement = static_cast<Attr*>(node)->ownerElement();
+        if (!ownerElement)
+            return node;
+        node = ownerElement;
     }
 
     while (Node* parent = node->parentOrHostNode())
@@ -137,31 +204,10 @@
     return node;
 }
 
-class ImplicitConnection {
-public:
-    ImplicitConnection(Node* root, v8::Persistent<v8::Value> wrapper)
-        : m_root(root)
-        , m_wrapper(wrapper)
-    {
-    }
-
-    Node* root() const { return m_root; }
-    v8::Persistent<v8::Value> wrapper() const { return m_wrapper; }
-
-public:
-    Node* m_root;
-    v8::Persistent<v8::Value> m_wrapper;
-};
-
-bool operator<(const ImplicitConnection& left, const ImplicitConnection& right)
-{
-    return left.root() < right.root();
-}
-
 class NodeVisitor : public NodeWrapperVisitor {
 public:
-    explicit NodeVisitor(Vector<v8::Persistent<v8::Value> >* liveObjects)
-        : m_liveObjects(liveObjects)
+    explicit NodeVisitor(WrapperGrouper* grouper)
+        : m_grouper(grouper)
     {
     }
 
@@ -174,36 +220,13 @@
 
         ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
         if (activeDOMObject && activeDOMObject->hasPendingActivity())
-            m_liveObjects->append(wrapper);
+            m_grouper->keepAlive(wrapper);
 
-        Node* root = rootForGC(node);
-        if (!root)
-            return;
-        m_connections.append(ImplicitConnection(root, wrapper));
+        m_grouper->addToGroup(V8GCController::opaqueRootForGC(node), wrapper);
     }
 
-    void applyGrouping()
-    {
-        std::sort(m_connections.begin(), m_connections.end());
-        Vector<v8::Persistent<v8::Value> > group;
-        size_t i = 0;
-        while (i < m_connections.size()) {
-            Node* root = m_connections[i].root();
-
-            do {
-                group.append(m_connections[i++].wrapper());
-            } while (i < m_connections.size() && root == m_connections[i].root());
-
-            if (group.size() > 1)
-                v8::V8::AddObjectGroup(group.data(), group.size(), new RetainedDOMInfo(root));
-
-            group.shrink(0);
-        }
-    }
-
 private:
-    Vector<v8::Persistent<v8::Value> >* m_liveObjects;
-    Vector<ImplicitConnection> m_connections;
+    WrapperGrouper* m_grouper;
 };
 
 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
@@ -224,17 +247,14 @@
 
     v8::HandleScope scope;
 
-    Vector<v8::Persistent<v8::Value> > liveObjects;
-    liveObjects.append(V8PerIsolateData::current()->ensureLiveRoot());
+    WrapperGrouper grouper;
 
-    NodeVisitor nodeVisitor(&liveObjects);
+    NodeVisitor nodeVisitor(&grouper);
+    ObjectVisitor objectVisitor(&grouper);
     visitAllDOMNodes(&nodeVisitor);
-    nodeVisitor.applyGrouping();
-
-    ObjectVisitor objectVisitor(&liveObjects);
     visitDOMObjects(&objectVisitor);
 
-    v8::V8::AddObjectGroup(liveObjects.data(), liveObjects.size());
+    grouper.apply();
 
     V8PerIsolateData* data = ""
     data->stringCache()->clearOnGC();

Modified: trunk/Source/WebCore/bindings/v8/V8GCController.h (133043 => 133044)


--- trunk/Source/WebCore/bindings/v8/V8GCController.h	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/bindings/v8/V8GCController.h	2012-10-31 17:33:32 UTC (rev 133044)
@@ -35,6 +35,8 @@
 
 namespace WebCore {
 
+class Node;
+
 class V8GCController {
 public:
     static void gcPrologue(v8::GCType, v8::GCCallbackFlags);
@@ -47,6 +49,8 @@
     static void checkMemoryUsage();
     static void hintForCollectGarbage();
     static void collectGarbage();
+
+    static void* opaqueRootForGC(Node*);
 };
 
 }

Modified: trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h (133043 => 133044)


--- trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h	2012-10-31 17:33:32 UTC (rev 133044)
@@ -47,7 +47,7 @@
     typedef v8::Persistent<v8::FunctionTemplate> (*GetTemplateFunction)();
     typedef void (*DerefObjectFunction)(void*);
     typedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>);
-    typedef void (*DOMWrapperVisitorFunction)(DOMDataStore*, void*, v8::Persistent<v8::Object>);
+    typedef void* (*OpaqueRootForGC)(void*, v8::Persistent<v8::Object>);
     typedef void (*InstallPerContextPrototypePropertiesFunction)(v8::Handle<v8::Object>);
 
     enum WrapperTypePrototype {
@@ -102,16 +102,17 @@
             return toActiveDOMObjectFunction(object);
         }
 
-        void visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper)
+        void* opaqueRootForGC(void* object, v8::Persistent<v8::Object> wrapper)
         {
-            if (domWrapperVisitorFunction)
-                domWrapperVisitorFunction(store, object, wrapper);
+            if (!opaqueRootForGCFunction)
+                return object;
+            return opaqueRootForGCFunction(object, wrapper);
         }
 
         const GetTemplateFunction getTemplateFunction;
         const DerefObjectFunction derefObjectFunction;
         const ToActiveDOMObjectFunction toActiveDOMObjectFunction;
-        const DOMWrapperVisitorFunction domWrapperVisitorFunction;
+        const OpaqueRootForGC opaqueRootForGCFunction;
         const InstallPerContextPrototypePropertiesFunction installPerContextPrototypePropertiesFunction;
         const WrapperTypeInfo* parentClass;
         const WrapperTypePrototype wrapperTypePrototype;

Modified: trunk/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp (133043 => 133044)


--- trunk/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp	2012-10-31 17:33:32 UTC (rev 133044)
@@ -34,6 +34,7 @@
 #include "DynamicNodeList.h"
 #include "NodeList.h"
 #include "V8Binding.h"
+#include "V8GCController.h"
 #include "V8Node.h"
 
 #include <wtf/RefPtr.h>
@@ -59,19 +60,16 @@
     return toV8(result.release(), info.Holder(), info.GetIsolate());
 }
 
-void V8NodeList::visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper)
+void* V8NodeList::opaqueRootForGC(void* object, v8::Persistent<v8::Object> wrapper)
 {
+    ASSERT(V8NodeList::HasInstance(wrapper));
     NodeList* impl = static_cast<NodeList*>(object);
-    if (impl->isDynamicNodeList()) {
-        Node* owner = static_cast<DynamicNodeList*>(impl)->ownerNode();
-        if (owner) {
-            v8::Persistent<v8::Object> ownerWrapper = store->domNodeMap().get(owner);
-            if (!ownerWrapper.IsEmpty()) {
-                v8::Persistent<v8::Value> value = wrapper;
-                v8::V8::AddImplicitReferences(ownerWrapper, &value, 1);
-            }
-        }
-    }
+    if (!impl->isDynamicNodeList())
+        return object;
+    Node* owner = static_cast<DynamicNodeList*>(impl)->ownerNode();
+    if (!owner)
+        return object;
+    return V8GCController::opaqueRootForGC(owner);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/v8/custom/V8SpeechRecognitionResultCustom.cpp (133043 => 133044)


--- trunk/Source/WebCore/bindings/v8/custom/V8SpeechRecognitionResultCustom.cpp	2012-10-31 17:21:36 UTC (rev 133043)
+++ trunk/Source/WebCore/bindings/v8/custom/V8SpeechRecognitionResultCustom.cpp	2012-10-31 17:33:32 UTC (rev 133044)
@@ -31,16 +31,15 @@
 
 #include "SpeechRecognitionResult.h"
 #include "V8Binding.h"
+#include "V8GCController.h"
 
 namespace WebCore {
 
-void V8SpeechRecognitionResult::visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper)
+void* V8SpeechRecognitionResult::opaqueRootForGC(void* object, v8::Persistent<v8::Object> wrapper)
 {
+    ASSERT(V8SpeechRecognitionResult::HasInstance(wrapper));
     SpeechRecognitionResult* impl = static_cast<SpeechRecognitionResult*>(object);
-    Document* emma = impl->emma();
-    v8::Persistent<v8::Value> emmaWrapper = store->domNodeMap().get(emma);
-    if (!emmaWrapper.IsEmpty())
-        v8::V8::AddImplicitReferences(wrapper, &emmaWrapper, 1);
+    return V8GCController::opaqueRootForGC(impl->emma());
 }
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to