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