[V8] More efficient wrapper dispatch
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2012 19:06:30 +0000 (19:06 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2012 19:06:30 +0000 (19:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102082

Patch by Dan Carney <dcarney@google.com> on 2012-11-13
Reviewed by Adam Barth.

Source/WebCore:

Dispatching a call to V8Whatever::wrap involved a chain
of calls, each of which checked its wrapper cache.
This refactor gives calls only 2 choices of functions to call:
toV8 and toV8Object instead of wrap. wrap has been renamed to
dispatchWrap and no longer contains cache checks.
Additionally, classes which require a custom toV8 function
have had all wrapping and caching calls removed, as they could
not have been accessed.

No new tests. Sufficiently covered.

* Modules/indexeddb/IDBAny.idl:
* Modules/indexeddb/IDBKey.idl:
* WebCore.gypi:
* bindings/scripts/CodeGeneratorV8.pm:
(GenerateHeader):
(GenerateNormalAttrGetter):
(GenerateImplementation):
(GenerateToV8Converters):
* bindings/scripts/IDLAttributes.txt:
* bindings/v8/SerializedScriptValue.cpp:
* bindings/v8/custom/V8BlobCustom.cpp:
(WebCore::V8Blob::dispatchWrapCustom):
* bindings/v8/custom/V8CSSRuleCustom.cpp:
(WebCore::V8CSSRule::dispatchWrapCustom):
* bindings/v8/custom/V8CSSValueCustom.cpp:
(WebCore::V8CSSValue::dispatchWrapCustom):
* bindings/v8/custom/V8CanvasRenderingContextCustom.cpp:
(WebCore::V8CanvasRenderingContext::dispatchWrapCustom):
* bindings/v8/custom/V8DataViewCustom.cpp:
(WebCore):
(WebCore::V8DataView::dispatchWrapCustom):
* bindings/v8/custom/V8DocumentCustom.cpp:
(WebCore::V8Document::dispatchWrapCustom):
* bindings/v8/custom/V8ElementCustom.cpp: Copied from Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp.
(WebCore):
(WebCore::V8Element::dispatchWrapCustom):
* bindings/v8/custom/V8EntryCustom.cpp:
(WebCore::V8Entry::dispatchWrapCustom):
* bindings/v8/custom/V8EntrySyncCustom.cpp:
(WebCore::V8EntrySync::dispatchWrapCustom):
* bindings/v8/custom/V8EventCustom.cpp:
(WebCore):
(WebCore::V8Event::dispatchWrapCustom):
* bindings/v8/custom/V8HTMLCollectionCustom.cpp:
(WebCore::V8HTMLCollection::dispatchWrapCustom):
* bindings/v8/custom/V8HTMLDocumentCustom.cpp:
(WebCore::V8HTMLDocument::dispatchWrapCustom):
* bindings/v8/custom/V8HTMLElementCustom.cpp:
(WebCore::V8HTMLElement::dispatchWrapCustom):
* bindings/v8/custom/V8ImageDataCustom.cpp:
(WebCore::V8ImageData::dispatchWrapCustom):
* bindings/v8/custom/V8NodeCustom.cpp:
(WebCore::V8Node::dispatchWrapCustom):
* bindings/v8/custom/V8PerformanceEntryCustom.cpp:
(WebCore::V8PerformanceEntry::dispatchWrapCustom):
* bindings/v8/custom/V8SVGDocumentCustom.cpp:
(WebCore::V8SVGDocument::dispatchWrapCustom):
* bindings/v8/custom/V8SVGElementCustom.cpp:
(WebCore::V8SVGElement::dispatchWrapCustom):
* bindings/v8/custom/V8SVGPathSegCustom.cpp:
(WebCore::V8SVGPathSeg::dispatchWrapCustom):
* bindings/v8/custom/V8StyleSheetCustom.cpp:
(WebCore::V8StyleSheet::dispatchWrapCustom):
* dom/Element.idl:
* dom/make_names.pl:
(printWrapperFunctions):
(printWrapperFactoryCppFile):
(printWrapperFactoryHeaderFile):
* html/MicroDataItemValue.idl:
* inspector/ScriptProfile.idl:
* inspector/ScriptProfileNode.idl:
* page/DOMWindow.idl:
* workers/WorkerContext.idl:

Source/WebKit/chromium:

* src/WebArrayBuffer.cpp:
(WebKit::WebArrayBuffer::toV8Value):
* src/WebBlob.cpp:
(WebKit::WebBlob::toV8Value):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@134447 268f45cc-cd09-0410-ab3c-d52691b4dbfc

37 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBAny.idl
Source/WebCore/Modules/indexeddb/IDBKey.idl
Source/WebCore/WebCore.gypi
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/v8/SerializedScriptValue.cpp
Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp
Source/WebCore/bindings/v8/custom/V8CSSRuleCustom.cpp
Source/WebCore/bindings/v8/custom/V8CSSValueCustom.cpp
Source/WebCore/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp
Source/WebCore/bindings/v8/custom/V8DataViewCustom.cpp
Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
Source/WebCore/bindings/v8/custom/V8ElementCustom.cpp [new file with mode: 0644]
Source/WebCore/bindings/v8/custom/V8EntryCustom.cpp
Source/WebCore/bindings/v8/custom/V8EntrySyncCustom.cpp
Source/WebCore/bindings/v8/custom/V8EventCustom.cpp
Source/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
Source/WebCore/bindings/v8/custom/V8HTMLElementCustom.cpp
Source/WebCore/bindings/v8/custom/V8ImageDataCustom.cpp
Source/WebCore/bindings/v8/custom/V8NodeCustom.cpp
Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp
Source/WebCore/bindings/v8/custom/V8SVGDocumentCustom.cpp
Source/WebCore/bindings/v8/custom/V8SVGElementCustom.cpp
Source/WebCore/bindings/v8/custom/V8SVGPathSegCustom.cpp
Source/WebCore/bindings/v8/custom/V8StyleSheetCustom.cpp
Source/WebCore/dom/Element.idl
Source/WebCore/dom/make_names.pl
Source/WebCore/html/MicroDataItemValue.idl
Source/WebCore/inspector/ScriptProfile.idl
Source/WebCore/inspector/ScriptProfileNode.idl
Source/WebCore/page/DOMWindow.idl
Source/WebCore/workers/WorkerContext.idl
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebArrayBuffer.cpp
Source/WebKit/chromium/src/WebBlob.cpp

index 835eb19..a44b375 100644 (file)
@@ -1,3 +1,85 @@
+2012-11-13  Dan Carney  <dcarney@google.com>
+
+        [V8] More efficient wrapper dispatch
+        https://bugs.webkit.org/show_bug.cgi?id=102082
+
+        Reviewed by Adam Barth.
+
+        Dispatching a call to V8Whatever::wrap involved a chain
+        of calls, each of which checked its wrapper cache.
+        This refactor gives calls only 2 choices of functions to call:
+        toV8 and toV8Object instead of wrap. wrap has been renamed to
+        dispatchWrap and no longer contains cache checks.
+        Additionally, classes which require a custom toV8 function
+        have had all wrapping and caching calls removed, as they could
+        not have been accessed.
+
+        No new tests. Sufficiently covered.
+
+        * Modules/indexeddb/IDBAny.idl:
+        * Modules/indexeddb/IDBKey.idl:
+        * WebCore.gypi:
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (GenerateHeader):
+        (GenerateNormalAttrGetter):
+        (GenerateImplementation):
+        (GenerateToV8Converters):
+        * bindings/scripts/IDLAttributes.txt:
+        * bindings/v8/SerializedScriptValue.cpp:
+        * bindings/v8/custom/V8BlobCustom.cpp:
+        (WebCore::V8Blob::dispatchWrapCustom):
+        * bindings/v8/custom/V8CSSRuleCustom.cpp:
+        (WebCore::V8CSSRule::dispatchWrapCustom):
+        * bindings/v8/custom/V8CSSValueCustom.cpp:
+        (WebCore::V8CSSValue::dispatchWrapCustom):
+        * bindings/v8/custom/V8CanvasRenderingContextCustom.cpp:
+        (WebCore::V8CanvasRenderingContext::dispatchWrapCustom):
+        * bindings/v8/custom/V8DataViewCustom.cpp:
+        (WebCore):
+        (WebCore::V8DataView::dispatchWrapCustom):
+        * bindings/v8/custom/V8DocumentCustom.cpp:
+        (WebCore::V8Document::dispatchWrapCustom):
+        * bindings/v8/custom/V8ElementCustom.cpp: Copied from Source/WebCore/bindings/v8/custom/V8PerformanceEntryCustom.cpp.
+        (WebCore):
+        (WebCore::V8Element::dispatchWrapCustom):
+        * bindings/v8/custom/V8EntryCustom.cpp:
+        (WebCore::V8Entry::dispatchWrapCustom):
+        * bindings/v8/custom/V8EntrySyncCustom.cpp:
+        (WebCore::V8EntrySync::dispatchWrapCustom):
+        * bindings/v8/custom/V8EventCustom.cpp:
+        (WebCore):
+        (WebCore::V8Event::dispatchWrapCustom):
+        * bindings/v8/custom/V8HTMLCollectionCustom.cpp:
+        (WebCore::V8HTMLCollection::dispatchWrapCustom):
+        * bindings/v8/custom/V8HTMLDocumentCustom.cpp:
+        (WebCore::V8HTMLDocument::dispatchWrapCustom):
+        * bindings/v8/custom/V8HTMLElementCustom.cpp:
+        (WebCore::V8HTMLElement::dispatchWrapCustom):
+        * bindings/v8/custom/V8ImageDataCustom.cpp:
+        (WebCore::V8ImageData::dispatchWrapCustom):
+        * bindings/v8/custom/V8NodeCustom.cpp:
+        (WebCore::V8Node::dispatchWrapCustom):
+        * bindings/v8/custom/V8PerformanceEntryCustom.cpp:
+        (WebCore::V8PerformanceEntry::dispatchWrapCustom):
+        * bindings/v8/custom/V8SVGDocumentCustom.cpp:
+        (WebCore::V8SVGDocument::dispatchWrapCustom):
+        * bindings/v8/custom/V8SVGElementCustom.cpp:
+        (WebCore::V8SVGElement::dispatchWrapCustom):
+        * bindings/v8/custom/V8SVGPathSegCustom.cpp:
+        (WebCore::V8SVGPathSeg::dispatchWrapCustom):
+        * bindings/v8/custom/V8StyleSheetCustom.cpp:
+        (WebCore::V8StyleSheet::dispatchWrapCustom):
+        * dom/Element.idl:
+        * dom/make_names.pl:
+        (printWrapperFunctions):
+        (printWrapperFactoryCppFile):
+        (printWrapperFactoryHeaderFile):
+        * html/MicroDataItemValue.idl:
+        * inspector/ScriptProfile.idl:
+        * inspector/ScriptProfileNode.idl:
+        * page/DOMWindow.idl:
+        * workers/WorkerContext.idl:
+
 2012-11-13  Dimitri Glazkov  <dglazkov@chromium.org>
 
         Unreviewed, rolling out r134367.
index 59618ad..b6c4042 100644 (file)
@@ -25,7 +25,8 @@
 
 [
     Conditional=INDEXED_DATABASE,
-    CustomToJSObject
+    CustomToJSObject,
+    V8NoWrapperCache
 ] interface IDBAny {
     // This space is intentionally left blank.
 };
index 3b96fc1..074b2ab 100644 (file)
@@ -25,7 +25,8 @@
 
 [
     Conditional=INDEXED_DATABASE,
-    CustomToJSObject
+    CustomToJSObject,
+    V8NoWrapperCache
 ] interface IDBKey {
     // This space is intentionally left blank.
 };
index ae906b0..0efc150 100644 (file)
             'bindings/v8/custom/V8DeviceOrientationEventCustom.cpp',
             'bindings/v8/custom/V8DocumentCustom.cpp',
             'bindings/v8/custom/V8DocumentLocationCustom.cpp',
+            'bindings/v8/custom/V8ElementCustom.cpp',
             'bindings/v8/custom/V8EntryCustom.cpp',
             'bindings/v8/custom/V8EntrySyncCustom.cpp',
             'bindings/v8/custom/V8EventCustom.cpp',
index 5041641..b814c1d 100644 (file)
@@ -381,7 +381,6 @@ END
     {
         return reinterpret_cast<${nativeType}*>(object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
     }
-    inline static v8::Handle<v8::Object> wrap(${nativeType}*, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* = 0);
     static void derefObject(void*);
     static WrapperTypeInfo info;
 END
@@ -402,8 +401,8 @@ END
 
     if ($implClassName eq "HTMLDocument") {
       push(@headerContent, <<END);
-  static v8::Local<v8::Object> wrapInShadowObject(v8::Local<v8::Object> wrapper, Node* impl);
-  static v8::Handle<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const AtomicString& key, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+    static v8::Local<v8::Object> wrapInShadowObject(v8::Local<v8::Object> wrapper, Node* impl);
+    static v8::Handle<v8::Value> getNamedProperty(HTMLDocument* htmlDocument, const AtomicString& key, v8::Handle<v8::Object> creationContext, v8::Isolate*);
 END
     }
 
@@ -490,10 +489,23 @@ END
 END
     }
 
-    my $wrapSlowArgumentType = GetPassRefPtrType($nativeType);
-    push(@headerContent, <<END);
+    if ($interfaceName eq "HTMLElement") {
+        push(@headerContent, <<END);
+    friend v8::Handle<v8::Object> createV8HTMLWrapper(HTMLElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+END
+    } elsif ($interfaceName eq "SVGElement") {
+        push(@headerContent, <<END);
+    friend v8::Handle<v8::Object> createV8SVGWrapper(SVGElement*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+END
+    } elsif ($interfaceName eq "Element") {
+        push(@headerContent, <<END);
+    // This is a performance optimization hack. See V8Element::dispatchWrapCustom.
+    friend class V8Node;
+END
+    }
+
+        push(@headerContent, <<END);
 private:
-    static v8::Handle<v8::Object> wrapSlow(${wrapSlowArgumentType}, v8::Handle<v8::Object> creationContext, v8::Isolate*);
 END
 
     if (IsConstructable($dataNode) && @{$dataNode->constructors} > 1) {
@@ -504,61 +516,72 @@ END
         }
     }
 
-    push(@headerContent, <<END);
+    my $wrapSlowArgumentType = GetPassRefPtrType($nativeType);
+    my $noWrap = $dataNode->extendedAttributes->{"V8NoWrapperCache"};
+    if ($noWrap) {
+        push(@headerContent, <<END);
 };
 
 END
-
-    push(@headerContent, <<END);
-v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
-{
-END
-    my $getCachedWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getCachedWrapper(impl)" : "DOMDataStore::current(isolate)->get(impl)";
-    push(@headerContent, <<END);
-        v8::Handle<v8::Object> wrapper = $getCachedWrapper;
-        if (!wrapper.IsEmpty())
-            return wrapper;
-END
-    push(@headerContent, <<END);
-    return ${className}::wrapSlow(impl, creationContext, isolate);
-}
-END
-
-    if ($interfaceName eq 'Element' or $dataNode->extendedAttributes->{"SuppressToJSObject"}) {
-        # Do not generate toV8() for performance optimization.
-    } elsif (!($dataNode->extendedAttributes->{"CustomToJSObject"} or $dataNode->extendedAttributes->{"V8CustomToJSObject"})) {
+    } else {
+        my $wrapSlowArgumentType = GetPassRefPtrType($nativeType);
         push(@headerContent, <<END);
+    friend v8::Handle<v8::Object> dispatchWrap(${nativeType}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+    static v8::Handle<v8::Object> dispatchWrapCustom(${nativeType}*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+    static v8::Handle<v8::Object> wrapSlow(${wrapSlowArgumentType}, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+};
 
-inline v8::Handle<v8::Value> toV8(${nativeType}* impl, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* isolate = 0)
-{
-    if (!impl)
-        return v8NullWithCheck(isolate);
-    return ${className}::wrap(impl, creationContext, isolate);
-}
 END
-    } elsif ($interfaceName ne 'Node') {
-        push(@headerContent, <<END);
+    }
 
+    my $customWrap = !!($dataNode->extendedAttributes->{"CustomToJSObject"} or $dataNode->extendedAttributes->{"V8CustomToJSObject"});
+    if ($dataNode->extendedAttributes->{"SuppressToJSObject"}) {
+        die "Can't suppress toV8 for subclass\n" if @allParents;
+    } elsif ($noWrap) {
+        die "Must have custom toV8\n" if !$customWrap;
+        push(@headerContent, <<END);
+class ${nativeType};
 v8::Handle<v8::Value> toV8(${nativeType}*, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* = 0);
 END
     } else {
+
+        my $getCachedWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getCachedWrapper(impl)" : "DOMDataStore::current(isolate)->get(impl)";
+        my $wrapSlowCall = $customWrap ? "${className}::dispatchWrapCustom" : "${className}::wrapSlow";
         push(@headerContent, <<END);
 
-v8::Handle<v8::Value> toV8Slow(Node*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+inline v8::Handle<v8::Object> dispatchWrap(${nativeType}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate = 0)
+{
+    ASSERT(impl);
+    ASSERT($getCachedWrapper.IsEmpty());
+    return $wrapSlowCall(impl, creationContext, isolate);
+}
+
+inline v8::Handle<v8::Object> toV8Object(${nativeType}* impl, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* isolate = 0)
+{
+    if (UNLIKELY(!impl))
+        return v8::Handle<v8::Object>();
+    v8::Handle<v8::Object> wrapper = $getCachedWrapper;
+    if (!wrapper.IsEmpty())
+        return wrapper;
+    return dispatchWrap(impl, creationContext, isolate);
+}
 
-inline v8::Handle<v8::Value> toV8(Node* impl, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* isolate = 0)
+inline v8::Handle<v8::Value> toV8(${nativeType}* impl, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* isolate = 0)
 {
     if (UNLIKELY(!impl))
         return v8NullWithCheck(isolate);
-    v8::Handle<v8::Value> wrapper = V8DOMWrapper::getCachedWrapper(impl);
+    v8::Handle<v8::Value> wrapper = $getCachedWrapper;
     if (!wrapper.IsEmpty())
         return wrapper;
-    return toV8Slow(impl, creationContext, isolate);
+    return dispatchWrap(impl, creationContext, isolate);
 }
+END
+        if (IsNodeSubType($dataNode)) {
+            push(@headerContent, <<END);
 
-inline v8::Handle<v8::Value> toV8Fast(Node* node, const v8::AccessorInfo& info, Node* holder)
+inline v8::Handle<v8::Value> toV8Fast(${nativeType}* impl, const v8::AccessorInfo& info, Node* holder)
 {
-    if (UNLIKELY(!node))
+    if (UNLIKELY(!impl))
         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
@@ -566,16 +589,18 @@ inline v8::Handle<v8::Value> toV8Fast(Node* node, const v8::AccessorInfo& info,
     // v8::AccessorInfo.
     v8::Handle<v8::Object> holderWrapper = info.Holder();
     if (holder->wrapper() == holderWrapper) {
-        v8::Handle<v8::Object> wrapper = node->wrapper();
+        v8::Handle<v8::Object> wrapper = impl->wrapper();
         if (!wrapper.IsEmpty())
             return wrapper;
     }
-    return toV8Slow(node, holderWrapper, info.GetIsolate());
+    return dispatchWrap(impl, holderWrapper, info.GetIsolate());
 }
 END
+        }
     }
 
     push(@headerContent, <<END);
+
 inline v8::Handle<v8::Value> toV8(PassRefPtr< ${nativeType} > impl, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* isolate = 0)
 {
     return toV8(impl.get(), creationContext, isolate);
@@ -1046,7 +1071,7 @@ END
         push(@implContentDecls, "    RefPtr<$returnType> result = ${getterString};\n");
         push(@implContentDecls, "    v8::Handle<v8::Value> wrapper = result.get() ? v8::Handle<v8::Value>(DOMDataStore::current(info.GetIsolate())->get(result.get())) : v8Undefined();\n");
         push(@implContentDecls, "    if (wrapper.IsEmpty()) {\n");
-        push(@implContentDecls, "        wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());\n");
+        push(@implContentDecls, "        wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());\n"); # FIXME: Could use dispatchWrap here since the wrapper is empty.
         push(@implContentDecls, "        if (!wrapper.IsEmpty())\n");
         push(@implContentDecls, "            V8DOMWrapper::setNamedHiddenReference(info.Holder(), \"${attrName}\", wrapper);\n");
         push(@implContentDecls, "    }\n");
@@ -2729,11 +2754,10 @@ sub GenerateImplementation
     if ($dataNode->extendedAttributes->{"TypedArray"}) {
         my $viewType = GetTypeNameOfExternalTypedArray($dataNode);
         push(@implContent, <<END);
-v8::Handle<v8::Value> toV8($implClassName* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8${implClassName}::dispatchWrapCustom($implClassName* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-    v8::Handle<v8::Object> wrapper = V8${implClassName}::wrap(impl, creationContext, isolate);
+    ASSERT(impl);
+    v8::Handle<v8::Object> wrapper = V8${implClassName}::wrapSlow(impl, creationContext, isolate);
     if (!wrapper.IsEmpty())
         wrapper->SetIndexedPropertiesToExternalArrayData(impl->baseAddress(), $viewType, impl->length());
     return wrapper;
@@ -3453,13 +3477,20 @@ sub GenerateToV8Converters
     my $className = shift;
     my $nativeType = shift;
 
+    if ($dataNode->extendedAttributes->{"V8NoWrapperCache"}) {
+        return;
+    }
+
     my $wrapSlowArgumentType = GetPassRefPtrType($nativeType);
     my $baseType = BaseInterfaceName($dataNode);
+    my $getCachedWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getCachedWrapper(impl.get())" : "DOMDataStore::current(isolate)->get(impl.get())";
 
     push(@implContent, <<END);
 
 v8::Handle<v8::Object> ${className}::wrapSlow(${wrapSlowArgumentType} impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
+    ASSERT(impl.get());
+    ASSERT($getCachedWrapper.IsEmpty());
     v8::Handle<v8::Object> wrapper;
 END
     if ($baseType ne $interfaceName) {
@@ -3475,7 +3506,9 @@ END
     if (Frame* frame = impl->frame()) {
         if (frame->script()->initializeMainWorld()) {
             // initializeMainWorld may have created a wrapper for the object, retry from the start.
-            return ${className}::wrap(impl.get(), creationContext, isolate);
+            v8::Handle<v8::Object> wrapper = V8DOMWrapper::getCachedWrapper(impl.get());
+            if (!wrapper.IsEmpty())
+                return wrapper;
         }
     }
 END
index db5884c..66dd5c6 100644 (file)
@@ -119,6 +119,7 @@ V8DoNotCheckSignature
 V8EnabledAtRuntime=*
 V8EnabledPerContext=*
 V8GenerateIsReachable=ImplDocument|ImplElementRoot|ImplOwnerRoot|ImplOwnerNodeRoot|ImplBaseRoot
+V8NoWrapperCache=*
 V8MeasureAs=*
 V8ReadOnly
 V8Unforgeable
index d12d085..4c310d8 100644 (file)
@@ -638,11 +638,11 @@ public:
         ASSERT(!tryCatch.HasCaught());
         if (messagePorts) {
             for (size_t i = 0; i < messagePorts->size(); i++)
-                m_transferredMessagePorts.set(V8MessagePort::wrap(messagePorts->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate()), i);
+                m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate()), i);
         }
         if (arrayBuffers) {
             for (size_t i = 0; i < arrayBuffers->size(); i++)  {
-                v8::Handle<v8::Object> v8ArrayBuffer = V8ArrayBuffer::wrap(arrayBuffers->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate());
+                v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i).get(), v8::Handle<v8::Object>(), m_writer.getIsolate());
                 // Coalesce multiple occurences of the same buffer to the first index.
                 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer))
                     m_transferredArrayBuffers.set(v8ArrayBuffer, i);
@@ -2022,7 +2022,7 @@ public:
             return false;
         if (index >= m_transferredMessagePorts->size())
             return false;
-        *object = V8MessagePort::wrap(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
+        *object = toV8(m_transferredMessagePorts->at(index).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
         return true;
     }
 
@@ -2034,7 +2034,7 @@ public:
             return false;
         v8::Handle<v8::Object> result = m_arrayBuffers.at(index);
         if (result.IsEmpty()) {
-            result = V8ArrayBuffer::wrap(ArrayBuffer::create(m_arrayBufferContents->at(index)).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
+            result = toV8Object(ArrayBuffer::create(m_arrayBufferContents->at(index)).get(), v8::Handle<v8::Object>(), m_reader.getIsolate());
             m_arrayBuffers[index] = result;
         }
         *object = result;
index 0ecc59e..71f162a 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(Blob* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8Blob::dispatchWrapCustom(Blob* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-
+    ASSERT(impl);
     if (impl->isFile())
-        return toV8(toFile(impl), creationContext, isolate);
-
-    return V8Blob::wrap(impl, creationContext, isolate);
+        return dispatchWrap(toFile(impl), creationContext, isolate);
+    return V8Blob::wrapSlow(impl, creationContext, isolate);
 }
 
 v8::Handle<v8::Value> V8Blob::constructorCallback(const v8::Arguments& args)
index 8b10ad5..cd7636a 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(CSSRule* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8CSSRule::dispatchWrapCustom(CSSRule* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     switch (impl->type()) {
     case CSSRule::UNKNOWN_RULE:
         // CSSUnknownRule.idl is explicitly excluded as it doesn't add anything
         // over CSSRule.idl (see WebCore.gyp/WebCore.gyp: 'bindings_idl_files').
         // -> Use the base class wrapper here.
-        return V8CSSRule::wrap(impl, creationContext, isolate);
+        return V8CSSRule::wrapSlow(impl, creationContext, isolate);
     case CSSRule::STYLE_RULE:
-        return toV8(static_cast<CSSStyleRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSStyleRule*>(impl), creationContext, isolate);
     case CSSRule::CHARSET_RULE:
-        return toV8(static_cast<CSSCharsetRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSCharsetRule*>(impl), creationContext, isolate);
     case CSSRule::IMPORT_RULE:
-        return toV8(static_cast<CSSImportRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSImportRule*>(impl), creationContext, isolate);
     case CSSRule::MEDIA_RULE:
-        return toV8(static_cast<CSSMediaRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSMediaRule*>(impl), creationContext, isolate);
     case CSSRule::FONT_FACE_RULE:
-        return toV8(static_cast<CSSFontFaceRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSFontFaceRule*>(impl), creationContext, isolate);
     case CSSRule::PAGE_RULE:
-        return toV8(static_cast<CSSPageRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSPageRule*>(impl), creationContext, isolate);
     case CSSRule::WEBKIT_KEYFRAME_RULE:
-        return toV8(static_cast<WebKitCSSKeyframeRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<WebKitCSSKeyframeRule*>(impl), creationContext, isolate);
     case CSSRule::WEBKIT_KEYFRAMES_RULE:
-        return toV8(static_cast<WebKitCSSKeyframesRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<WebKitCSSKeyframesRule*>(impl), creationContext, isolate);
     case CSSRule::WEBKIT_REGION_RULE:
-        return toV8(static_cast<WebKitCSSRegionRule*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<WebKitCSSRegionRule*>(impl), creationContext, isolate);
     }
-    return V8CSSRule::wrap(impl, creationContext, isolate);
+    return V8CSSRule::wrapSlow(impl, creationContext, isolate);
 }
 
 } // namespace WebCore
index 262d8e1..094dac5 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(CSSValue* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8CSSValue::dispatchWrapCustom(CSSValue* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     if (impl->isWebKitCSSTransformValue())
-        return toV8(static_cast<WebKitCSSTransformValue*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<WebKitCSSTransformValue*>(impl), creationContext, isolate);
 #if ENABLE(CSS_FILTERS)
     if (impl->isWebKitCSSFilterValue())
-        return toV8(static_cast<WebKitCSSFilterValue*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<WebKitCSSFilterValue*>(impl), creationContext, isolate);
 #endif
     if (impl->isValueList())
-        return toV8(static_cast<CSSValueList*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSValueList*>(impl), creationContext, isolate);
     if (impl->isPrimitiveValue())
-        return toV8(static_cast<CSSPrimitiveValue*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CSSPrimitiveValue*>(impl), creationContext, isolate);
 #if ENABLE(SVG)
     if (impl->isSVGPaint())
-        return toV8(static_cast<SVGPaint*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPaint*>(impl), creationContext, isolate);
     if (impl->isSVGColor())
-        return toV8(static_cast<SVGColor*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGColor*>(impl), creationContext, isolate);
 #endif
-    return V8CSSValue::wrap(impl, creationContext, isolate);
+    return V8CSSValue::wrapSlow(impl, creationContext, isolate);
 }
 
 } // namespace WebCore
index 37a652f..10682d3 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(CanvasRenderingContext* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8CanvasRenderingContext::dispatchWrapCustom(CanvasRenderingContext* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     if (impl->is2d())
-        return toV8(static_cast<CanvasRenderingContext2D*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CanvasRenderingContext2D*>(impl), creationContext, isolate);
 #if ENABLE(WEBGL)
     if (impl->is3d())
-        return toV8(static_cast<WebGLRenderingContext*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<WebGLRenderingContext*>(impl), creationContext, isolate);
 #endif
     ASSERT_NOT_REACHED();
-    return v8NullWithCheck(isolate);
+    return v8::Handle<v8::Object>();
 }
 
 } // namespace WebCore
index 6de9ce8..c702119 100644 (file)
@@ -56,11 +56,11 @@ v8::Handle<v8::Value> V8DataView::constructorCallback(const v8::Arguments& args)
     return constructWebGLArrayWithArrayBufferArgument<DataView, char>(args, &info, v8::kExternalByteArray, false);
 }
 
-v8::Handle<v8::Value> toV8(DataView* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+// FIXME: Don't need this override.
+v8::Handle<v8::Object> V8DataView::dispatchWrapCustom(DataView* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-    return V8DataView::wrap(impl, creationContext, isolate);
+    ASSERT(impl);
+    return V8DataView::wrapSlow(impl, creationContext, isolate);
 }
 
 v8::Handle<v8::Value> V8DataView::getInt8Callback(const v8::Arguments& args)
index 597908c..723ff29 100644 (file)
@@ -95,17 +95,16 @@ v8::Handle<v8::Value> V8Document::evaluateCallback(const v8::Arguments& args)
     return toV8(result.release(), args.Holder(), args.GetIsolate());
 }
 
-v8::Handle<v8::Value> toV8(Document* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8Document::dispatchWrapCustom(Document* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     if (impl->isHTMLDocument())
-        return toV8(static_cast<HTMLDocument*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<HTMLDocument*>(impl), creationContext, isolate);
 #if ENABLE(SVG)
     if (impl->isSVGDocument())
-        return toV8(static_cast<SVGDocument*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGDocument*>(impl), creationContext, isolate);
 #endif
-    v8::Handle<v8::Object> wrapper = V8Document::wrap(impl, creationContext, isolate);
+    v8::Handle<v8::Object> wrapper = V8Document::wrapSlow(impl, creationContext, isolate);
     if (wrapper.IsEmpty())
         return wrapper;
     if (!V8DOMWindowShell::getEntered()) {
diff --git a/Source/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/Source/WebCore/bindings/v8/custom/V8ElementCustom.cpp
new file mode 100644 (file)
index 0000000..ab2e27c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ *     * 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
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Element.h"
+
+#include "V8Element.h"
+#include "V8HTMLElement.h"
+#include "V8SVGElement.h"
+
+namespace WebCore {
+
+// This code is duplicated in V8Node::dispatchWrapCustom for performance. It must be kept in sync.
+v8::Handle<v8::Object> V8Element::dispatchWrapCustom(Element* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+{
+    ASSERT(impl);
+    if (impl->isHTMLElement())
+        return dispatchWrap(toHTMLElement(impl), creationContext, isolate);
+#if ENABLE(SVG)
+    if (impl->isSVGElement())
+        return dispatchWrap(static_cast<SVGElement*>(impl), creationContext, isolate);
+#endif
+    return V8Element::wrapSlow(static_cast<Element*>(impl), creationContext, isolate);
+}
+
+}
index b35e133..ae901eb 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(Entry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8Entry::dispatchWrapCustom(Entry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-
+    ASSERT(impl);
     if (impl->isFile())
-        return toV8(static_cast<FileEntry*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<FileEntry*>(impl), creationContext, isolate);
 
     ASSERT(impl->isDirectory());
-    return toV8(static_cast<DirectoryEntry*>(impl), creationContext, isolate);
+    return dispatchWrap(static_cast<DirectoryEntry*>(impl), creationContext, isolate);
 }
 
 } // namespace WebCore
index 545dd1f..6d8895c 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(EntrySync* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8EntrySync::dispatchWrapCustom(EntrySync* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-
+    ASSERT(impl);
     if (impl->isFile())
-        return toV8(static_cast<FileEntrySync*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<FileEntrySync*>(impl), creationContext, isolate);
 
     ASSERT(impl->isDirectory());
-    return toV8(static_cast<DirectoryEntrySync*>(impl), creationContext, isolate);
+    return dispatchWrap(static_cast<DirectoryEntrySync*>(impl), creationContext, isolate);
 }
 
 } // namespace WebCore
index 381e82b..43eab69 100644 (file)
@@ -64,22 +64,21 @@ v8::Handle<v8::Value> V8Event::clipboardDataAccessorGetter(v8::Local<v8::String>
 
 #define TRY_TO_WRAP_WITH_INTERFACE(interfaceName) \
     if (eventNames().interfaceFor##interfaceName == desiredInterface) \
-        return toV8(static_cast<interfaceName*>(event), creationContext, isolate);
+        return dispatchWrap(static_cast<interfaceName*>(event), creationContext, isolate);
 
-v8::Handle<v8::Value> toV8(Event* event, v8::Handle<v8::Object> creationContext, v8::Isolate *isolate)
+v8::Handle<v8::Object> V8Event::dispatchWrapCustom(Event* event, v8::Handle<v8::Object> creationContext, v8::Isolate *isolate)
 {
-    if (!event)
-        return v8NullWithCheck(isolate);
+    ASSERT(event);
 
     String desiredInterface = event->interfaceName();
 
     // We need to check Event first to avoid infinite recursion.
     if (eventNames().interfaceForEvent == desiredInterface)
-        return V8Event::wrap(event, creationContext, isolate);
+        return V8Event::wrapSlow(event, creationContext, isolate);
 
     DOM_EVENT_INTERFACES_FOR_EACH(TRY_TO_WRAP_WITH_INTERFACE)
 
-    return V8Event::wrap(event, creationContext, isolate);
+    return V8Event::wrapSlow(event, creationContext, isolate);
 }
 
 } // namespace WebCore
index 04915d7..0e09881 100644 (file)
@@ -84,14 +84,12 @@ v8::Handle<v8::Value> V8HTMLCollection::namedItemCallback(const v8::Arguments& a
     return result;
 }
 
-v8::Handle<v8::Value> toV8(HTMLCollection* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8HTMLCollection::dispatchWrapCustom(HTMLCollection* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-
+    ASSERT(impl);
     if (impl->type() == DocAll)
-        return toV8(static_cast<HTMLAllCollection*>(impl), creationContext, isolate);
-    return V8HTMLCollection::wrap(impl, creationContext, isolate);
+        return dispatchWrap(static_cast<HTMLAllCollection*>(impl), creationContext, isolate);
+    return V8HTMLCollection::wrapSlow(impl, creationContext, isolate);
 }
 
 } // namespace WebCore
index 8f4fcf4..203abb5 100644 (file)
@@ -168,11 +168,10 @@ void V8HTMLDocument::allAccessorSetter(v8::Local<v8::String> name, v8::Local<v8:
     info.This()->ForceSet(name, value);
 }
 
-v8::Handle<v8::Value> toV8(HTMLDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8HTMLDocument::dispatchWrapCustom(HTMLDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-    v8::Handle<v8::Object> wrapper = V8HTMLDocument::wrap(impl, creationContext, isolate);
+    ASSERT(impl);
+    v8::Handle<v8::Object> wrapper = V8HTMLDocument::wrapSlow(impl, creationContext, isolate);
     if (wrapper.IsEmpty())
         return wrapper;
     if (!V8DOMWindowShell::getEntered()) {
index 63c0f65..fb57160 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(HTMLElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8HTMLElement::dispatchWrapCustom(HTMLElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     return createV8HTMLWrapper(impl, creationContext, isolate);
 }
 
index 890e412..dd23f6b 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(ImageData* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8ImageData::dispatchWrapCustom(ImageData* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-    v8::Handle<v8::Object> wrapper = V8ImageData::wrap(impl, creationContext, isolate);
+    ASSERT(impl);
+    v8::Handle<v8::Object> wrapper = V8ImageData::wrapSlow(impl, creationContext, isolate);
     if (!wrapper.IsEmpty()) {
         // Create a V8 Uint8ClampedArray object.
         v8::Handle<v8::Value> pixelArray = toV8(impl->data(), creationContext, isolate);
index 8a98a76..de1d3f9 100644 (file)
@@ -125,49 +125,44 @@ v8::Handle<v8::Value> V8Node::appendChildCallback(const v8::Arguments& args)
     return v8::Null(args.GetIsolate());
 }
 
-v8::Handle<v8::Value> toV8Slow(Node* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8Node::dispatchWrapCustom(Node* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-
-    v8::Handle<v8::Value> wrapper = V8DOMWrapper::getCachedWrapper(impl);
-    if (!wrapper.IsEmpty())
-        return wrapper;
-
+    ASSERT(impl);
     switch (impl->nodeType()) {
     case Node::ELEMENT_NODE:
+        // For performance reasons, this is inlined from V8Element::dispatchWrapCustom and must remain in sync.
         if (impl->isHTMLElement())
-            return toV8(toHTMLElement(impl), creationContext, isolate);
+            return dispatchWrap(toHTMLElement(impl), creationContext, isolate);
 #if ENABLE(SVG)
         if (impl->isSVGElement())
-            return toV8(static_cast<SVGElement*>(impl), creationContext, isolate);
+            return dispatchWrap(static_cast<SVGElement*>(impl), creationContext, isolate);
 #endif
-        return V8Element::wrap(static_cast<Element*>(impl), creationContext, isolate);
+        return V8Element::wrapSlow(static_cast<Element*>(impl), creationContext, isolate);
     case Node::ATTRIBUTE_NODE:
-        return toV8(static_cast<Attr*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<Attr*>(impl), creationContext, isolate);
     case Node::TEXT_NODE:
-        return toV8(toText(impl), creationContext, isolate);
+        return dispatchWrap(toText(impl), creationContext, isolate);
     case Node::CDATA_SECTION_NODE:
-        return toV8(static_cast<CDATASection*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<CDATASection*>(impl), creationContext, isolate);
     case Node::ENTITY_REFERENCE_NODE:
-        return toV8(static_cast<EntityReference*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<EntityReference*>(impl), creationContext, isolate);
     case Node::ENTITY_NODE:
-        return toV8(static_cast<Entity*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<Entity*>(impl), creationContext, isolate);
     case Node::PROCESSING_INSTRUCTION_NODE:
-        return toV8(static_cast<ProcessingInstruction*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<ProcessingInstruction*>(impl), creationContext, isolate);
     case Node::COMMENT_NODE:
-        return toV8(static_cast<Comment*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<Comment*>(impl), creationContext, isolate);
     case Node::DOCUMENT_NODE:
-        return toV8(static_cast<Document*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<Document*>(impl), creationContext, isolate);
     case Node::DOCUMENT_TYPE_NODE:
-        return toV8(static_cast<DocumentType*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<DocumentType*>(impl), creationContext, isolate);
     case Node::DOCUMENT_FRAGMENT_NODE:
-        return toV8(static_cast<DocumentFragment*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<DocumentFragment*>(impl), creationContext, isolate);
     case Node::NOTATION_NODE:
-        return toV8(static_cast<Notation*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<Notation*>(impl), creationContext, isolate);
     default:
         break; // XPATH_NAMESPACE_NODE
     }
-    return V8Node::wrap(impl, creationContext, isolate);
+    return V8Node::wrapSlow(impl, creationContext, isolate);
 }
 } // namespace WebCore
index 397e3f9..20e17e5 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(PerformanceEntry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8PerformanceEntry::dispatchWrapCustom(PerformanceEntry* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8::Null();
-
+    ASSERT(impl);
 #if ENABLE(RESOURCE_TIMING)
     if (impl->isResource())
-        return toV8(static_cast<PerformanceResourceTiming*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<PerformanceResourceTiming*>(impl), creationContext, isolate);
 #endif
-
-    return V8PerformanceEntry::wrap(impl, creationContext, isolate);
+    return V8PerformanceEntry::wrapSlow(impl, creationContext, isolate);
 }
 
 } // namespace WebCore
index 60738d7..c28c365 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(SVGDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8SVGDocument::dispatchWrapCustom(SVGDocument* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
-    v8::Handle<v8::Object> wrapper = V8SVGDocument::wrap(impl, creationContext, isolate);
+    ASSERT(impl);
+    v8::Handle<v8::Object> wrapper = V8SVGDocument::wrapSlow(impl, creationContext, isolate);
     if (wrapper.IsEmpty())
         return wrapper;
     if (!V8DOMWindowShell::getEntered()) {
index 72ac1d6..6b22e95 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(SVGElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8SVGElement::dispatchWrapCustom(SVGElement* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     return createV8SVGWrapper(impl, creationContext, isolate);
 }
 
index d45cbe2..6e88a9f 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(SVGPathSeg* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8SVGPathSeg::dispatchWrapCustom(SVGPathSeg* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     switch (impl->pathSegType()) {
     case SVGPathSeg::PATHSEG_CLOSEPATH:
-        return toV8(static_cast<SVGPathSegClosePath*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegClosePath*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_MOVETO_ABS:
-        return toV8(static_cast<SVGPathSegMovetoAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegMovetoAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_MOVETO_REL:
-        return toV8(static_cast<SVGPathSegMovetoRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegMovetoRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_LINETO_ABS:
-        return toV8(static_cast<SVGPathSegLinetoAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegLinetoAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_LINETO_REL:
-        return toV8(static_cast<SVGPathSegLinetoRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegLinetoRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
-        return toV8(static_cast<SVGPathSegCurvetoCubicAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoCubicAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL:
-        return toV8(static_cast<SVGPathSegCurvetoCubicRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoCubicRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS:
-        return toV8(static_cast<SVGPathSegCurvetoQuadraticAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoQuadraticAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL:
-        return toV8(static_cast<SVGPathSegCurvetoQuadraticRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoQuadraticRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_ARC_ABS:
-        return toV8(static_cast<SVGPathSegArcAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegArcAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_ARC_REL:
-        return toV8(static_cast<SVGPathSegArcRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegArcRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS:
-        return toV8(static_cast<SVGPathSegLinetoHorizontalAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegLinetoHorizontalAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL:
-        return toV8(static_cast<SVGPathSegLinetoHorizontalRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegLinetoHorizontalRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS:
-        return toV8(static_cast<SVGPathSegLinetoVerticalAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegLinetoVerticalAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL:
-        return toV8(static_cast<SVGPathSegLinetoVerticalRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegLinetoVerticalRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
-        return toV8(static_cast<SVGPathSegCurvetoCubicSmoothAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoCubicSmoothAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
-        return toV8(static_cast<SVGPathSegCurvetoCubicSmoothRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoCubicSmoothRel*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
-        return toV8(static_cast<SVGPathSegCurvetoQuadraticSmoothAbs*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoQuadraticSmoothAbs*>(impl), creationContext, isolate);
     case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
-        return toV8(static_cast<SVGPathSegCurvetoQuadraticSmoothRel*>(impl), creationContext, isolate);
+        return dispatchWrap(static_cast<SVGPathSegCurvetoQuadraticSmoothRel*>(impl), creationContext, isolate);
     }
     ASSERT_NOT_REACHED();
-    return V8SVGPathSeg::wrap(impl, creationContext, isolate);
+    return V8SVGPathSeg::wrapSlow(impl, creationContext, isolate);
 }
 
 } // namespace WebCore
index ed05fa2..3b8f54b 100644 (file)
 
 namespace WebCore {
 
-v8::Handle<v8::Value> toV8(StyleSheet* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> V8StyleSheet::dispatchWrapCustom(StyleSheet* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    if (!impl)
-        return v8NullWithCheck(isolate);
+    ASSERT(impl);
     if (impl->isCSSStyleSheet())
-        return toV8(static_cast<CSSStyleSheet*>(impl), creationContext, isolate);
-    return V8StyleSheet::wrap(impl, creationContext, isolate);
+        return dispatchWrap(static_cast<CSSStyleSheet*>(impl), creationContext, isolate);
+    return V8StyleSheet::wrapSlow(impl, creationContext, isolate);
 }
 
 } // namespace WebCore
index d51e804..ff741f6 100644 (file)
@@ -20,7 +20,8 @@
 
 [
     JSGenerateToNativeObject,
-    JSInlineGetOwnPropertySlot
+    JSInlineGetOwnPropertySlot,
+    V8CustomToJSObject
 ] interface Element : Node {
 
     // DOM Level 1 Core
index 38d8595..3b9b5ad 100755 (executable)
@@ -1066,12 +1066,12 @@ END
         } elsif ($wrapperFactoryType eq "V8") {
             if ($enabledTags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
                 print F <<END
-static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
     Settings* settings = element->document()->settings();
     if (!MediaPlayer::isAvailable() || (settings && !settings->isMediaEnabled()))
-        return V8$parameters{namespace}Element::wrap(element, creationContext, isolate);
-    return toV8(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
+        return dispatchWrap(element, creationContext, isolate);
+    return dispatchWrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
 }
 
 END
@@ -1079,39 +1079,40 @@ END
             } elsif ($enabledTags{$tagName}{contextConditional}) {
                 my $contextConditional = $enabledTags{$tagName}{contextConditional};
                 print F <<END
-static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
     if (!ContextFeatures::${contextConditional}Enabled(element->document()))
-        return V8$parameters{fallbackInterfaceName}::wrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
-    return toV8(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
+        return dispatchWrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
+    return dispatchWrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
 }
 END
 ;
             } elsif ($enabledTags{$tagName}{runtimeConditional}) {
                 my $runtimeConditional = $enabledTags{$tagName}{runtimeConditional};
                 print F <<END
-static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
     if (!RuntimeEnabledFeatures::${runtimeConditional}Enabled())
-        return V8$parameters{fallbackInterfaceName}::wrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
-    return toV8(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
+        return dispatchWrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
+    return dispatchWrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
 }
 END
 ;
             } elsif (${JSInterfaceName} eq "HTMLElement") {
                 print F <<END
-static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    return V8$parameters{namespace}Element::wrap(element, creationContext, isolate);
+    ASSERT_NOT_REACHED();
+    return v8::Handle<v8::Object>();
 }
 
 END
 ;
              } else {
             print F <<END
-static v8::Handle<v8::Value> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
-    return toV8(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
+    return dispatchWrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
 }
 
 
@@ -1194,7 +1195,7 @@ END
 ;
     } elsif ($wrapperFactoryType eq "V8") {
         print F <<END
-typedef v8::Handle<v8::Value> (*Create$parameters{namespace}ElementWrapperFunction)($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+typedef v8::Handle<v8::Object> (*Create$parameters{namespace}ElementWrapperFunction)($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
 
 END
 ;
@@ -1213,7 +1214,7 @@ END
 ;
     } elsif ($wrapperFactoryType eq "V8") {
         print F <<END
-v8::Handle<v8::Value> createV8$parameters{namespace}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
+v8::Handle<v8::Object> createV8$parameters{namespace}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
 {
     typedef HashMap<WTF::AtomicStringImpl*, Create$parameters{namespace}ElementWrapperFunction> FunctionMap;
     DEFINE_STATIC_LOCAL(FunctionMap, map, ());
@@ -1243,7 +1244,7 @@ END
     print F <<END
     }
     Create$parameters{namespace}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
-    if (createWrapperFunction)
+    if (createWrapperFunction) {
 END
 ;
     if ($wrapperFactoryType eq "JS") {
@@ -1253,11 +1254,28 @@ END
 END
 ;
     } elsif ($wrapperFactoryType eq "V8") {
+        if ($parameters{namespace} eq "HTML") {
+            print F <<END
+        if (createWrapperFunction == createHTMLElementWrapper)
+           return V8HTMLElement::wrapSlow(element, creationContext, isolate);
+END
+        }
         print F <<END
         return createWrapperFunction(element, creationContext, isolate);
-    return V8$parameters{fallbackInterfaceName}::wrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
+    }
+END
+;
+        if ($parameters{namespace} eq "SVG") {
+            print F <<END
+    return V8SVGElement::wrapSlow(element, creationContext, isolate);
+END
+;
+        } else {
+            print F <<END
+    return dispatchWrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
 END
 ;
+        }
     }
     print F <<END
 }
@@ -1315,7 +1333,7 @@ namespace WebCore {
 
     class $parameters{namespace}Element;
 
-    v8::Handle<v8::Value> createV8$parameters{namespace}Wrapper($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
+    v8::Handle<v8::Object> createV8$parameters{namespace}Wrapper($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
 }
 END
 ;
index 5b29ed5..fc1a3ac 100644 (file)
@@ -31,6 +31,7 @@
 [
     Conditional=MICRODATA,
     CustomToJSObject,
-    OmitConstructor
+    OmitConstructor,
+    V8NoWrapperCache
 ] interface MicroDataItemValue {
 };
index 46c0e99..6a7a82d 100644 (file)
@@ -27,7 +27,8 @@
 [
     Conditional=JAVASCRIPT_DEBUGGER,
     OmitConstructor,
-    V8CustomToJSObject
+    V8CustomToJSObject,
+    V8NoWrapperCache
 ] interface ScriptProfile {
     readonly attribute DOMString title;
     readonly attribute unsigned long uid;
index 0b8b125..e6be287 100644 (file)
@@ -27,7 +27,8 @@
 [
     Conditional=JAVASCRIPT_DEBUGGER,
     OmitConstructor,
-    V8CustomToJSObject
+    V8CustomToJSObject,
+    V8NoWrapperCache
 ] interface ScriptProfileNode {
     readonly attribute DOMString functionName;
     readonly attribute DOMString url;
index de5eb7e..dc2a2dc 100644 (file)
@@ -39,6 +39,7 @@
     ReplaceableConstructor,
     JSLegacyParent=JSDOMWindowBase,
     V8CustomToJSObject,
+    V8NoWrapperCache,
     InterfaceName=Window
 ] interface DOMWindow {
     // DOM Level 0
index 69b11f1..2d523eb 100644 (file)
@@ -34,7 +34,8 @@
     JSLegacyParent=JSWorkerContextBase,
     JSNoStaticTables,
     OmitConstructor,
-    V8CustomToJSObject
+    V8CustomToJSObject,
+    V8NoWrapperCache
 ] interface WorkerContext {
 
     // WorkerGlobalScope
index 7211100..c666cc1 100644 (file)
@@ -1,3 +1,15 @@
+2012-11-13  Dan Carney  <dcarney@google.com>
+
+        [V8] More efficient wrapper dispatch
+        https://bugs.webkit.org/show_bug.cgi?id=102082
+
+        Reviewed by Adam Barth.
+
+        * src/WebArrayBuffer.cpp:
+        (WebKit::WebArrayBuffer::toV8Value):
+        * src/WebBlob.cpp:
+        (WebKit::WebBlob::toV8Value):
+
 2012-11-12  Dana Jansens  <danakj@chromium.org>
 
         [chromium] Remove the WebCompositorSupport methods for changing settings, plumb everything through WebLayerTreeSettings
index d43874b..2d192bd 100644 (file)
@@ -72,7 +72,7 @@ unsigned WebArrayBuffer::byteLength() const
 #if WEBKIT_USING_V8
 v8::Handle<v8::Value> WebArrayBuffer::toV8Value()
 {
-    return V8ArrayBuffer::wrap(m_private.get());
+    return toV8Object(m_private.get());
 }
 
 WebArrayBuffer* WebArrayBuffer::createFromV8Value(v8::Handle<v8::Value> value)
index f8228e9..b2f299f 100644 (file)
@@ -61,7 +61,7 @@ void WebBlob::assign(const WebBlob& other)
 #if WEBKIT_USING_V8
 v8::Handle<v8::Value>  WebBlob::toV8Value()
 {
-    return V8Blob::wrap(m_private.get());
+    return toV8Object(m_private.get());
 }
 #endif