Changeset 66840 in webkit


Ignore:
Timestamp:
Sep 6, 2010 10:46:44 AM (14 years ago)
Author:
antonm@chromium.org
Message:

2010-09-06 Anton Muhin <antonm@chromium.org>

Reviewed by Adam Barth.

[v8] Inline hot methods for V8 to WebCore and back conversions
https://bugs.webkit.org/show_bug.cgi?id=45270

Inline fast paths of hot functions performing conversions from V8 wrappers
to WebCore native objects and back.
That slightly increases the size of binary (within 0.1% for both Ubuntu
and Windows, but those builds are slightly different from official ones),
but gives performance boost (3--5% on Windows, up to 8% on Ubuntu).

  • bindings/scripts/CodeGeneratorV8.pm:
  • bindings/v8/V8DOMWindowShell.cpp: (WebCore::V8DOMWindowShell::initContextIfNeeded):
  • bindings/v8/V8DOMWindowShell.h:
  • bindings/v8/V8DOMWrapper.cpp: (WebCore::V8DOMWrapper::getWrapperSlow):
  • bindings/v8/V8DOMWrapper.h: (WebCore::V8DOMWrapper::getWrapper):
  • bindings/v8/custom/V8NodeCustom.cpp: (WebCore::toV8Slow):
Location:
trunk/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r66836 r66840  
     12010-09-06  Anton Muhin  <antonm@chromium.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        [v8] Inline hot methods for V8 to WebCore and back conversions
     6        https://bugs.webkit.org/show_bug.cgi?id=45270
     7
     8        Inline fast paths of hot functions performing conversions from V8 wrappers
     9        to WebCore native objects and back.
     10        That slightly increases the size of binary (within 0.1% for both Ubuntu
     11        and Windows, but those builds are slightly different from official ones),
     12        but gives performance boost (3--5% on Windows, up to 8% on Ubuntu).
     13
     14        * bindings/scripts/CodeGeneratorV8.pm:
     15        * bindings/v8/V8DOMWindowShell.cpp:
     16        (WebCore::V8DOMWindowShell::initContextIfNeeded):
     17        * bindings/v8/V8DOMWindowShell.h:
     18        * bindings/v8/V8DOMWrapper.cpp:
     19        (WebCore::V8DOMWrapper::getWrapperSlow):
     20        * bindings/v8/V8DOMWrapper.h:
     21        (WebCore::V8DOMWrapper::getWrapper):
     22        * bindings/v8/custom/V8NodeCustom.cpp:
     23        (WebCore::toV8Slow):
     24
    1252010-09-06  Shane Stephens  <shanestephens@google.com>
    226
  • trunk/WebCore/bindings/scripts/CodeGeneratorV8.pm

    r66802 r66840  
    234234    $headerIncludes{"wtf/text/StringHash.h"} = 1;
    235235    $headerIncludes{"WrapperTypeInfo.h"} = 1;
     236    $headerIncludes{"V8DOMWrapper.h"} = 1;
    236237    my $headerClassInclude = GetHeaderClassInclude($implClassName);
    237238    $headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
     
    254255        $nativeType = "V8SVGPODTypeWrapper<${nativeType} >";
    255256    }
     257
     258    my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
    256259    my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
     260    my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
     261    my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
     262
    257263    push(@headerContent, <<END);
    258264
     
    261267    static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
    262268    static v8::Persistent<v8::FunctionTemplate> GetTemplate();
    263     static ${nativeType}* toNative(v8::Handle<v8::Object>);
    264     static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
     269    static ${nativeType}* toNative(v8::Handle<v8::Object> object)
     270    {
     271        return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
     272    }
     273    inline static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
    265274    static void derefObject(void*);
    266275    static WrapperTypeInfo info;
     
    337346
    338347    push(@headerContent, <<END);
     348private:
     349    static v8::Handle<v8::Object> wrapSlow(${nativeType}*);
    339350};
    340351
     352END
     353
     354    push(@headerContent, <<END);
     355
     356v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
     357{
     358END
     359    if ($domMapFunction) {
     360        push(@headerContent, "    if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
     361        my $getWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getWrapper(impl)" : "${domMapFunction}.get(impl)";
     362        push(@headerContent, <<END);
     363        v8::Handle<v8::Object> wrapper = ${getWrapper};
     364        if (!wrapper.IsEmpty())
     365            return wrapper;
     366END
     367        push(@headerContent, "    }\n") if IsDOMNodeType($interfaceName);
     368    }
     369    push(@headerContent, <<END);
     370    return ${className}::wrapSlow(impl);
     371}
     372END
     373
     374    if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
     375        push(@headerContent, <<END);
     376
     377inline v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectParameter})
     378{
     379    if (!impl)
     380        return v8::Null();
     381    return ${className}::wrap(impl${forceNewObjectCall});
     382}
     383END
     384    } elsif ($interfaceName ne 'Node') {
     385        push(@headerContent, <<END);
     386
    341387v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
    342388END
     389    } else {
     390        push(@headerContent, <<END);
     391
     392v8::Handle<v8::Value> toV8Slow(Node*, bool);
     393
     394inline v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject = false)
     395{
     396    if (!impl)
     397        return v8::Null();
     398    if (!forceNewObject) {
     399        v8::Handle<v8::Value> wrapper = V8DOMWrapper::getWrapper(impl);
     400        if (!wrapper.IsEmpty())
     401            return wrapper;
     402    }
     403    return toV8Slow(impl, forceNewObject);
     404}
     405END
     406    }
     407
    343408    if (IsRefPtrType($implClassName)) {
    344409        push(@headerContent, <<END);
    345 v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
     410inline v8::Handle<v8::Value> toV8(PassRefPtr< ${nativeType} > impl${forceNewObjectParameter})
     411{
     412    return toV8(impl.get()${forceNewObjectCall});
     413}
    346414END
    347415    }
     
    20872155}
    20882156
    2089 ${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
    2090 {
    2091     return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
    2092 }
    2093 
    20942157bool ${className}::HasInstance(v8::Handle<v8::Value> value)
    20952158{
     
    23602423    push(@implContent, <<END);
    23612424
    2362 v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
     2425v8::Handle<v8::Object> ${className}::wrapSlow(${nativeType}* impl)
    23632426{
    23642427    v8::Handle<v8::Object> wrapper;
     
    23702433    if (impl->document()) {
    23712434        proxy = V8Proxy::retrieve(impl->document()->frame());
    2372         if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
    2373             proxy->windowShell()->initContextIfNeeded();
    2374     }
    2375 
    2376 END
    2377     }
    2378 
    2379     if ($domMapFunction) {
    2380         push(@implContent, "    if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
    2381         if (IsNodeSubType($dataNode)) {
    2382             push(@implContent, "        wrapper = V8DOMWrapper::getWrapper(impl);\n");
    2383         } else {
    2384             push(@implContent, "        wrapper = ${domMapFunction}.get(impl);\n");
    2385         }
    2386         push(@implContent, <<END);
    2387         if (!wrapper.IsEmpty())
    2388             return wrapper;
    2389 END
    2390         push(@implContent, "    }\n") if IsDOMNodeType($interfaceName);
    2391     }
     2435        if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) {
     2436            if (proxy->windowShell()->initContextIfNeeded()) {
     2437                // initContextIfNeeded may have created a wrapper for the object, retry from the start.
     2438                return ${className}::wrap(impl);
     2439            }
     2440        }
     2441    }
     2442
     2443END
     2444    }
     2445
    23922446    if (IsNodeSubType($dataNode)) {
    23932447        push(@implContent, <<END);
     
    24462500}
    24472501END
    2448 
    2449     if (IsRefPtrType($interfaceName)) {
    2450         push(@implContent, <<END);
    2451 
    2452 v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
    2453 {
    2454     return toV8(impl.get()${forceNewObjectCall});
    2455 }
    2456 END
    2457     }
    2458 
    2459     if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
    2460         push(@implContent, <<END);
    2461 
    2462 v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
    2463 {
    2464     if (!impl)
    2465         return v8::Null();
    2466     return ${className}::wrap(impl${forceNewObjectCall});
    2467 }
    2468 END
    2469     }
    24702502}
    24712503
  • trunk/WebCore/bindings/v8/V8DOMWindowShell.cpp

    r65316 r66840  
    243243// If there are JS code holds a closure to the old inner window,
    244244// it won't be able to reach the outer window via its global object.
    245 void V8DOMWindowShell::initContextIfNeeded()
     245bool V8DOMWindowShell::initContextIfNeeded()
    246246{
    247247    // Bail out if the context has already been initialized.
    248248    if (!m_context.IsEmpty())
    249         return;
     249        return false;
    250250
    251251    // Create a handle scope for all local handles.
     
    274274    m_context = createNewContext(m_global, 0);
    275275    if (m_context.IsEmpty())
    276         return;
     276        return false;
    277277
    278278    v8::Local<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context);
     
    285285        if (m_global.IsEmpty()) {
    286286            disposeContextHandles();
    287             return;
     287            return false;
    288288        }
    289289#ifndef NDEBUG
     
    294294    if (!installHiddenObjectPrototype(v8Context)) {
    295295        disposeContextHandles();
    296         return;
     296        return false;
    297297    }
    298298
    299299    if (!installDOMWindow(v8Context, m_frame->domWindow())) {
    300300        disposeContextHandles();
    301         return;
     301        return false;
    302302    }
    303303
     
    311311    // we do isolated worlds the WebCore way.
    312312    m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
     313
     314    return true;
    313315}
    314316
  • trunk/WebCore/bindings/v8/V8DOMWindowShell.h

    r65316 r66840  
    7070    static bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow*);
    7171
    72     void initContextIfNeeded();
     72    bool initContextIfNeeded();
    7373    void updateDocumentWrapper(v8::Handle<v8::Object> wrapper);
    7474
  • trunk/WebCore/bindings/v8/V8DOMWrapper.cpp

    r65937 r66840  
    330330}
    331331
    332 v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
    333 {
    334     ASSERT(WTF::isMainThread());
     332v8::Handle<v8::Object> V8DOMWrapper::getWrapperSlow(Node* node)
     333{
    335334    V8IsolatedContext* context = V8IsolatedContext::getEntered();
    336335    if (LIKELY(!context)) {
     
    340339        return *wrapper;
    341340    }
    342 
    343341    DOMNodeMapping& domNodeMap = context->world()->domDataStore()->domNodeMap();
    344342    return domNodeMap.get(node);
  • trunk/WebCore/bindings/v8/V8DOMWrapper.h

    r65021 r66840  
    3434#include "Document.h"
    3535#include "Event.h"
     36#include "IsolatedWorld.h"
    3637#include "Node.h"
    3738#include "NodeFilter.h"
     
    131132        static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo*, void* impl);
    132133
    133         static v8::Handle<v8::Object> getWrapper(Node*);
     134        static v8::Handle<v8::Object> getWrapper(Node* node)
     135        {
     136            ASSERT(WTF::isMainThread());
     137            if (LIKELY(!IsolatedWorld::count())) {
     138                v8::Persistent<v8::Object>* wrapper = node->wrapper();
     139                if (wrapper)
     140                    return *wrapper;
     141            }
     142            return getWrapperSlow(node);
     143        }
     144
     145    private:
     146        static v8::Handle<v8::Object> getWrapperSlow(Node*);
    134147    };
    135148
  • trunk/WebCore/bindings/v8/custom/V8NodeCustom.cpp

    r60023 r66840  
    131131}
    132132
    133 v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject)
     133v8::Handle<v8::Value> toV8Slow(Node* impl, bool forceNewObject)
    134134{
    135135    if (!impl)
Note: See TracChangeset for help on using the changeset viewer.