Title: [130574] trunk/Source/WebCore
Revision
130574
Author
[email protected]
Date
2012-10-05 19:08:50 -0700 (Fri, 05 Oct 2012)

Log Message

[V8] toV8(Node*, ...) does more work than needed (6% faster on dom-traverse)
https://bugs.webkit.org/show_bug.cgi?id=98567

Reviewed by Kentaro Hara.

This patch introduces toV8Fast for Node*. This function works a
differently from the existing toV8 function in two ways:

1) It uses the inline wrapper cache in Node to determine if we're
   executing in the main world. This is faster both in the case when
   isolated worlds exist because we don't need to retrieve any state
   for the current context.

2) It doesn't attempt to inline the hash table lookup used to find the
   wrapper in the isolated world. There isn't a big need to inline this
   code since performance in the isolated world case is dominated by
   the hash table lookup.

Because of these two changes, toV8Fast is small enough to inline into
each attribute getter profitably. Over time, I would like to convert
all the performance critical uses of toV8(Node*) to toV8Fast. At that
point, we can delete toV8 and rename toV8Slow to toV8.

* bindings/scripts/CodeGeneratorV8.pm:
(GenerateHeader):
(GenerateNormalAttrGetter):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (130573 => 130574)


--- trunk/Source/WebCore/ChangeLog	2012-10-06 01:28:05 UTC (rev 130573)
+++ trunk/Source/WebCore/ChangeLog	2012-10-06 02:08:50 UTC (rev 130574)
@@ -1,3 +1,32 @@
+2012-10-05  Adam Barth  <[email protected]>
+
+        [V8] toV8(Node*, ...) does more work than needed (6% faster on dom-traverse)
+        https://bugs.webkit.org/show_bug.cgi?id=98567
+
+        Reviewed by Kentaro Hara.
+
+        This patch introduces toV8Fast for Node*. This function works a
+        differently from the existing toV8 function in two ways:
+
+        1) It uses the inline wrapper cache in Node to determine if we're
+           executing in the main world. This is faster both in the case when
+           isolated worlds exist because we don't need to retrieve any state
+           for the current context.
+
+        2) It doesn't attempt to inline the hash table lookup used to find the
+           wrapper in the isolated world. There isn't a big need to inline this
+           code since performance in the isolated world case is dominated by
+           the hash table lookup.
+
+        Because of these two changes, toV8Fast is small enough to inline into
+        each attribute getter profitably. Over time, I would like to convert
+        all the performance critical uses of toV8(Node*) to toV8Fast. At that
+        point, we can delete toV8 and rename toV8Slow to toV8.
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (GenerateHeader):
+        (GenerateNormalAttrGetter):
+
 2012-10-05  Huang Dongsung  <[email protected]>
 
         [mac] REGRESSION (r122215): Animated GIF outside the viewport doesn't play when scrolled into view.

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm (130573 => 130574)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm	2012-10-06 01:28:05 UTC (rev 130573)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm	2012-10-06 02:08:50 UTC (rev 130574)
@@ -525,6 +525,20 @@
         return wrapper;
     return toV8Slow(impl, creationContext, isolate);
 }
+
+inline v8::Handle<v8::Value> toV8Fast(Node* node, const v8::AccessorInfo& info, Node* holder)
+{
+    if (UNLIKELY(!node))
+        return v8::Null(info.GetIsolate());
+    // What we'd really like to check here is whether we're in the main world or
+    // in an isolated world. The fastest way we know how to do that is to check
+    // whether the holder's inline wrapper is the same wrapper we see in the
+    // v8::AccessorInfo.
+    v8::Handle<v8::Object> holderWrapper = info.Holder();
+    if (holder->wrapper() && *holder->wrapper() == holderWrapper && node->wrapper())
+        return *node->wrapper();
+    return toV8Slow(node, holderWrapper, info.GetIsolate());
+}
 END
     }
 
@@ -1062,18 +1076,19 @@
         portArray->Set(v8Integer(i, info.GetIsolate()), toV8(portsCopy[i].get(), info.Holder(), info.GetIsolate()));
     return portArray;
 END
-    } else {
-        if ($attribute->signature->type eq "SerializedScriptValue" && $attrExt->{"CachedAttribute"}) {
-            my $getterFunc = $codeGenerator->WK_lcfirst($attribute->signature->name);
-            push(@implContentDecls, <<END);
+    } elsif ($attribute->signature->type eq "SerializedScriptValue" && $attrExt->{"CachedAttribute"}) {
+        my $getterFunc = $codeGenerator->WK_lcfirst($attribute->signature->name);
+        push(@implContentDecls, <<END);
     SerializedScriptValue* serialized = imp->${getterFunc}();
     value = serialized ? serialized->deserialize() : v8::Handle<v8::Value>(v8::Null(info.GetIsolate()));
     info.Holder()->SetHiddenValue(propertyName, value);
     return value;
 END
-        } else {
-            push(@implContentDecls, "    " . ReturnNativeToJSValue($attribute->signature, $result, "info.Holder()", "info.GetIsolate()").";\n");
-        }
+    } elsif (IsDOMNodeType(GetTypeFromSignature($attribute->signature)) && $implClassName eq "Node") {
+        # FIXME: We would like to use toV8Fast in more situations.
+        push(@implContentDecls, "    return toV8Fast($result, info, imp);\n");
+    } else {
+        push(@implContentDecls, "    " . ReturnNativeToJSValue($attribute->signature, $result, "info.Holder()", "info.GetIsolate()").";\n");
     }
 
     push(@implContentDecls, "}\n\n");  # end of getter
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to