Changeset 112218 in webkit


Ignore:
Timestamp:
Mar 27, 2012 12:48:09 AM (12 years ago)
Author:
haraken@chromium.org
Message:

[V8][Performance] Optimize createTextNode(), createElement(), cloneNode(), etc
https://bugs.webkit.org/show_bug.cgi?id=82201

Reviewed by Adam Barth.

This patch improves performance of createTextNode() by 13%, createElement() by 14%,
and cloneNode() by 16%. Similar performance improvement will be observed in
DOM methods that create a new object every time.

Performance test: https://bugs.webkit.org/attachment.cgi?id=133799

The performance test results are as follows. Since the performance of V8's GC is
really unstable, the average of measured times makes no sense in Chromium.
Instead, let us focus on the median. I believe that this performance
improvement has impact on Dromaeo, but we cannot observe the improvement
due to the unsteadiness of V8's GC, as shown below.

Chromium/V8/Linux (without the patch):
createTextNode : median=277ms (mean=460.88ms, min=270ms, max=3381ms)
createElement : median=379ms (mean=637.52ms, min=372ms, max=3022ms)
cloneNode : median=369ms (mean=581.72ms, min=363ms, max=3050ms)
Dromaeo/dom-modify/createElement: 439.17runs/s +-31.60% (<--- pretty noisy)
Dromaeo/dom-modify/createTextNode: 287.71runs/s +-28.39% (<--- pretty noisy)
Dromaeo/dom-modify/cloneNode: 174.62runs/s +-25.68% (<--- pretty noisy)

Chromium/V8/Linux (with the patch):
createTextNode : median=240ms (mean=411.12ms, min=237ms, max=2965ms)
createElement : median=325ms (mean=585.30ms, min=317ms, max=2984ms)
cloneNode : median=310ms (mean=522.48ms, min=302ms, max=2988ms)
Dromaeo/dom-modify/createElement: 507.15runs/s +-36.00% (<--- pretty noisy)
Dromaeo/dom-modify/createTextNode: 251.01runs/s +-6.57%
Dromaeo/dom-modify/cloneNode: 177.85runs/s +-28.74% (<--- pretty noisy)

Chromium/V8/Mac (without the patch):
createTextNode : median=317ms (mean=439.08ms, min=303ms, max=3126ms)
createElement : median=403ms (mean=695.70ms, min=398ms, max=5615ms)
cloneNode : median=384ms (mean=577.96ms, min=372ms, max=5313ms)
Dromaeo/dom-modify/createElement: 493.89runs/s +-28.32% (<--- pretty noisy)
Dromaeo/dom-modify/createTextNode: 279.66runs/s +-1.91%
Dromaeo/dom-modify/cloneNode: 173.06runs/s +-24.41% (<--- pretty noisy)

Chromium/V8/Mac (with the patch):
createTextNode : median=277ms (mean=460.88ms, min=270ms, max=3381ms)
createElement : median=379ms (mean=637.52ms, min=372ms, max=3022ms)
cloneNode : median=369ms (mean=581.72ms, min=363ms, max=3050ms)
Dromaeo/dom-modify/createElement: 510.47runs/s +-28.13% (<--- pretty noisy)
Dromaeo/dom-modify/createTextNode: 215.80runs/s +-20.99% (<--- pretty noisy)
Dromaeo/dom-modify/cloneNode: 174.41runs/s +-24.85% (<--- pretty noisy)

Safari/JavaScriptCore/Mac:
createTextNode : median=142ms (mean=141.04ms, min=110ms, max=168ms)
createElement : median=234ms (mean=245.74ms, min=219ms, max=305ms)
cloneNode : median=210ms (mean=213.36ms, min=204ms, max=284ms)
Dromaeo/dom-modify/createElement: 822.49runs/s +-1.69%
Dromaeo/dom-modify/createTextNode: 735.57runs/s +-0.91%
Dromaeo/dom-modify/cloneNode: 135.20runs/s +-4.13%

This patch makes the following two optimizations:

[1] If the currently running context is equal to the context that we are about to enter,
we do not call context->Enter().
[2] We do not create a Local handle of the context until we really need to enter the context.

  • bindings/scripts/CodeGeneratorV8.pm:

(GenerateToV8Converters):

  • bindings/v8/V8Proxy.cpp:

(WebCore::V8Proxy::persistentContext):
(WebCore):

  • bindings/v8/V8Proxy.h:

(V8Proxy):

  • WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp: Updated run-bindings-tests results.
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r112217 r112218  
     12012-03-27  Kentaro Hara  <haraken@chromium.org>
     2
     3        [V8][Performance] Optimize createTextNode(), createElement(), cloneNode(), etc
     4        https://bugs.webkit.org/show_bug.cgi?id=82201
     5
     6        Reviewed by Adam Barth.
     7
     8        This patch improves performance of createTextNode() by 13%, createElement() by 14%,
     9        and cloneNode() by 16%. Similar performance improvement will be observed in
     10        DOM methods that create a new object every time.
     11
     12        Performance test: https://bugs.webkit.org/attachment.cgi?id=133799
     13
     14        The performance test results are as follows. Since the performance of V8's GC is
     15        really unstable, the average of measured times makes no sense in Chromium.
     16        Instead, let us focus on the median. I believe that this performance
     17        improvement has impact on Dromaeo, but we cannot observe the improvement
     18        due to the unsteadiness of V8's GC, as shown below.
     19
     20        Chromium/V8/Linux (without the patch):
     21        createTextNode : median=277ms (mean=460.88ms, min=270ms, max=3381ms)
     22        createElement : median=379ms (mean=637.52ms, min=372ms, max=3022ms)
     23        cloneNode : median=369ms (mean=581.72ms, min=363ms, max=3050ms)
     24        Dromaeo/dom-modify/createElement: 439.17runs/s +-31.60% (<--- pretty noisy)
     25        Dromaeo/dom-modify/createTextNode: 287.71runs/s +-28.39% (<--- pretty noisy)
     26        Dromaeo/dom-modify/cloneNode: 174.62runs/s +-25.68% (<--- pretty noisy)
     27
     28        Chromium/V8/Linux (with the patch):
     29        createTextNode : median=240ms (mean=411.12ms, min=237ms, max=2965ms)
     30        createElement : median=325ms (mean=585.30ms, min=317ms, max=2984ms)
     31        cloneNode : median=310ms (mean=522.48ms, min=302ms, max=2988ms)
     32        Dromaeo/dom-modify/createElement: 507.15runs/s +-36.00% (<--- pretty noisy)
     33        Dromaeo/dom-modify/createTextNode: 251.01runs/s +-6.57%
     34        Dromaeo/dom-modify/cloneNode: 177.85runs/s +-28.74% (<--- pretty noisy)
     35
     36        Chromium/V8/Mac (without the patch):
     37        createTextNode : median=317ms (mean=439.08ms, min=303ms, max=3126ms)
     38        createElement : median=403ms (mean=695.70ms, min=398ms, max=5615ms)
     39        cloneNode : median=384ms (mean=577.96ms, min=372ms, max=5313ms)
     40        Dromaeo/dom-modify/createElement: 493.89runs/s +-28.32% (<--- pretty noisy)
     41        Dromaeo/dom-modify/createTextNode: 279.66runs/s +-1.91%
     42        Dromaeo/dom-modify/cloneNode: 173.06runs/s +-24.41% (<--- pretty noisy)
     43
     44        Chromium/V8/Mac (with the patch):
     45        createTextNode : median=277ms (mean=460.88ms, min=270ms, max=3381ms)
     46        createElement : median=379ms (mean=637.52ms, min=372ms, max=3022ms)
     47        cloneNode : median=369ms (mean=581.72ms, min=363ms, max=3050ms)
     48        Dromaeo/dom-modify/createElement: 510.47runs/s +-28.13% (<--- pretty noisy)
     49        Dromaeo/dom-modify/createTextNode: 215.80runs/s +-20.99% (<--- pretty noisy)
     50        Dromaeo/dom-modify/cloneNode: 174.41runs/s +-24.85% (<--- pretty noisy)
     51
     52        Safari/JavaScriptCore/Mac:
     53        createTextNode : median=142ms (mean=141.04ms, min=110ms, max=168ms)
     54        createElement : median=234ms (mean=245.74ms, min=219ms, max=305ms)
     55        cloneNode : median=210ms (mean=213.36ms, min=204ms, max=284ms)
     56        Dromaeo/dom-modify/createElement: 822.49runs/s +-1.69%
     57        Dromaeo/dom-modify/createTextNode: 735.57runs/s +-0.91%
     58        Dromaeo/dom-modify/cloneNode: 135.20runs/s +-4.13%
     59
     60        This patch makes the following two optimizations:
     61
     62        [1] If the currently running context is equal to the context that we are about to enter,
     63        we do not call context->Enter().
     64        [2] We do not create a Local handle of the context until we really need to enter the context.
     65
     66        * bindings/scripts/CodeGeneratorV8.pm:
     67        (GenerateToV8Converters):
     68        * bindings/v8/V8Proxy.cpp:
     69        (WebCore::V8Proxy::persistentContext):
     70        (WebCore):
     71        * bindings/v8/V8Proxy.h:
     72        (V8Proxy):
     73
     74        * WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp: Updated run-bindings-tests results.
     75
    1762012-03-27  Bill Budge  <bbudge@chromium.org>
    277
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm

    r112207 r112218  
    31453145        push(@implContent, <<END);
    31463146
     3147    // Enter the node's context and create the wrapper in that context.
    31473148    v8::Handle<v8::Context> context;
    3148     if (proxy)
     3149    if (proxy && !proxy->matchesCurrentContext()) {
     3150        // For performance, we enter the context only if the currently running context
     3151        // is different from the context that we are about to enter.
    31493152        context = proxy->context();
    3150 
    3151     // Enter the node's context and create the wrapper in that context.
    3152     if (!context.IsEmpty())
    3153         context->Enter();
     3153        if (!context.IsEmpty())
     3154            context->Enter();
     3155    }
    31543156END
    31553157    }
  • trunk/Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp

    r112207 r112218  
    169169    }
    170170
     171    // Enter the node's context and create the wrapper in that context.
    171172    v8::Handle<v8::Context> context;
    172     if (proxy)
     173    if (proxy && !proxy->matchesCurrentContext()) {
     174        // For performance, we enter the context only if the currently running context
     175        // is different from the context that we are about to enter.
    173176        context = proxy->context();
    174 
    175     // Enter the node's context and create the wrapper in that context.
    176     if (!context.IsEmpty())
    177         context->Enter();
     177        if (!context.IsEmpty())
     178            context->Enter();
     179    }
    178180    wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl.get());
    179181    // Exit the node's context if it was entered.
  • trunk/Source/WebCore/bindings/v8/V8Proxy.cpp

    r109540 r112218  
    643643}
    644644
     645bool V8Proxy::matchesCurrentContext()
     646{
     647    v8::Handle<v8::Context> context;
     648    if (V8IsolatedContext* isolatedContext = V8IsolatedContext::getEntered()) {
     649        context = isolatedContext->sharedContext()->get();
     650        if (m_frame != V8Proxy::retrieveFrame(context))
     651            return false;
     652    } else {
     653        windowShell()->initContextIfNeeded();
     654        context = windowShell()->context();
     655    }
     656    return context == context->GetCurrent();
     657}
     658
    645659v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
    646660{
  • trunk/Source/WebCore/bindings/v8/V8Proxy.h

    r112163 r112218  
    244244        v8::Local<v8::Context> context();
    245245        v8::Local<v8::Context> mainWorldContext();
     246        bool matchesCurrentContext();
    246247
    247248        // FIXME: This should eventually take DOMWrapperWorld argument!
Note: See TracChangeset for help on using the changeset viewer.