Changeset 109969 in webkit


Ignore:
Timestamp:
Mar 6, 2012 3:54:46 PM (12 years ago)
Author:
haraken@chromium.org
Message:

[V8][Performance] Optimize V8 bindings for HTMLElement.classList,
Element.dataset and Node.attributes
https://bugs.webkit.org/show_bug.cgi?id=80376

Reviewed by Adam Barth.

This patch improves the performance of HTMLElement.classList, Element.dataset
and Node.attributes by 6.4 times, 7.1 times and 10.9 times, respectively.

Previously, a 'hiddenReferenceName' string was allocated on v8::Handle and
created every time the DOM attribute is accessed, in spite of the fact that
the 'hiddenReferenceName' string is static.

This patch moves the 'hiddenReferenceName' string to v8::Persistent and makes it static.
Also, this patch removes 'if (!elementValue.IsEmpty() && elementValue->IsObject())',
since if 'element' exists, it is guaranteed that 'elementValue' is not empty
and is an Object.

Performance tests: https://bugs.webkit.org/attachment.cgi?id=130283

AppleWebKit/JavaScriptCore:
div.classList : 382ms
div.classList.foo = 123 : 335ms
div.dataset : 403ms
div.dataset.foo = 123 : 5250ms
div.attributes : 183ms

Chromium/V8 (without this patch):
div.classList : 9140ms
div.classList.foo = 123 : 9086ms
div.dataset : 9930ms
div.dataset.foo = 123 : 49698ms
div.attributes : 13489ms

Chromium/V8 (with this patch):
div.classList : 1435ms
div.classList.foo = 123 : 1470ms
div.dataset : 1400ms
div.dataset.foo = 123 : 30396ms
div.attributes : 1242ms

No tests. No change in behavior.

  • bindings/v8/custom/V8DOMStringMapCustom.cpp: Modified as described above.

(WebCore::toV8):

  • bindings/v8/custom/V8DOMTokenListCustom.cpp: Ditto.

(WebCore::toV8):

  • bindings/v8/custom/V8NamedNodeMapCustom.cpp: Ditto.

(WebCore::toV8):

  • bindings/v8/V8HiddenPropertyName.cpp: Defined a hidden property name string statically

to optimize the macro.
(WebCore):
(WebCore::V8HiddenPropertyName::hiddenReferenceName):

  • bindings/v8/V8HiddenPropertyName.h: Modified to switch two prefixes "WebCore::HiddenProperty::"

and "WebCore::HiddenReference::", depending on whether a given name represents a hidden property
or a hidden reference.
(WebCore):
(V8HiddenPropertyName):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r109968 r109969  
     12012-03-06  Kentaro Hara  <haraken@chromium.org>
     2
     3        [V8][Performance] Optimize V8 bindings for HTMLElement.classList,
     4        Element.dataset and Node.attributes
     5        https://bugs.webkit.org/show_bug.cgi?id=80376
     6
     7        Reviewed by Adam Barth.
     8
     9        This patch improves the performance of HTMLElement.classList, Element.dataset
     10        and Node.attributes by 6.4 times, 7.1 times and 10.9 times, respectively.
     11
     12        Previously, a 'hiddenReferenceName' string was allocated on v8::Handle and
     13        created every time the DOM attribute is accessed, in spite of the fact that
     14        the 'hiddenReferenceName' string is static.
     15
     16        This patch moves the 'hiddenReferenceName' string to v8::Persistent and makes it static.
     17        Also, this patch removes 'if (!elementValue.IsEmpty() && elementValue->IsObject())',
     18        since if 'element' exists, it is guaranteed that 'elementValue' is not empty
     19        and is an Object.
     20
     21        Performance tests: https://bugs.webkit.org/attachment.cgi?id=130283
     22
     23        AppleWebKit/JavaScriptCore:
     24        div.classList : 382ms
     25        div.classList.foo = 123 : 335ms
     26        div.dataset : 403ms
     27        div.dataset.foo = 123 : 5250ms
     28        div.attributes : 183ms
     29
     30        Chromium/V8 (without this patch):
     31        div.classList : 9140ms
     32        div.classList.foo = 123 : 9086ms
     33        div.dataset : 9930ms
     34        div.dataset.foo = 123 : 49698ms
     35        div.attributes : 13489ms
     36
     37        Chromium/V8 (with this patch):
     38        div.classList : 1435ms
     39        div.classList.foo = 123 : 1470ms
     40        div.dataset : 1400ms
     41        div.dataset.foo = 123 : 30396ms
     42        div.attributes : 1242ms
     43
     44        No tests. No change in behavior.
     45
     46        * bindings/v8/custom/V8DOMStringMapCustom.cpp: Modified as described above.
     47        (WebCore::toV8):
     48        * bindings/v8/custom/V8DOMTokenListCustom.cpp: Ditto.
     49        (WebCore::toV8):
     50        * bindings/v8/custom/V8NamedNodeMapCustom.cpp: Ditto.
     51        (WebCore::toV8):
     52
     53        * bindings/v8/V8HiddenPropertyName.cpp: Defined a hidden property name string statically
     54        to optimize the macro.
     55        (WebCore):
     56        (WebCore::V8HiddenPropertyName::hiddenReferenceName):
     57        * bindings/v8/V8HiddenPropertyName.h: Modified to switch two prefixes "WebCore::HiddenProperty::"
     58        and "WebCore::HiddenReference::", depending on whether a given name represents a hidden property
     59        or a hidden reference.
     60        (WebCore):
     61        (V8HiddenPropertyName):
     62
    1632012-03-06  Alexis Menard  <alexis.menard@openbossa.org>
    264
  • trunk/Source/WebCore/bindings/v8/V8HiddenPropertyName.cpp

    r95901 r109969  
    3434#include "V8Binding.h"
    3535#include <string.h>
     36#include <wtf/StdLibExtras.h>
    3637#include <wtf/Vector.h>
    3738
     
    4142#define V8_AS_STRING_IMPL(x) #x
    4243
    43 #define V8_DEFINE_PROPERTY(name) \
     44#define V8_DEFINE_HIDDEN_PROPERTY(name, prefix) \
    4445v8::Handle<v8::String> V8HiddenPropertyName::name() \
    4546{ \
    46     V8HiddenPropertyName* hiddenPropertyName = V8BindingPerIsolateData::current()->hiddenPropertyName(); \
    47     if (hiddenPropertyName->m_##name.IsEmpty()) { \
    48         hiddenPropertyName->m_##name = createString("WebCore::HiddenProperty::" V8_AS_STRING(name)); \
    49     } \
    50     return hiddenPropertyName->m_##name; \
     47    DEFINE_STATIC_LOCAL(v8::Persistent<v8::String>, hiddenPropertyName, (createString(prefix V8_AS_STRING(name)))); \
     48    return hiddenPropertyName; \
    5149}
    5250
    53 V8_HIDDEN_PROPERTIES(V8_DEFINE_PROPERTY);
    54 
    55 static const char hiddenReferenceNamePrefix[] = "WebCore::HiddenReference::";
     51V8_HIDDEN_PROPERTIES(V8_DEFINE_HIDDEN_PROPERTY);
    5652
    5753v8::Handle<v8::String> V8HiddenPropertyName::hiddenReferenceName(const char* name)
    5854{
    5955    Vector<char, 64> prefixedName;
    60     prefixedName.append(hiddenReferenceNamePrefix, sizeof(hiddenReferenceNamePrefix) - 1);
     56    prefixedName.append(V8_HIDDEN_REFERENCE_PREFIX, sizeof(V8_HIDDEN_REFERENCE_PREFIX) - 1);
    6157    ASSERT(name && strlen(name));
    6258    prefixedName.append(name, strlen(name));
  • trunk/Source/WebCore/bindings/v8/V8HiddenPropertyName.h

    r108596 r109969  
    3636namespace WebCore {
    3737
     38#define V8_HIDDEN_PROPERTY_PREFIX "WebCore::HiddenProperty::"
     39#define V8_HIDDEN_REFERENCE_PREFIX "WebCore::HiddenReference::"
     40
    3841#define V8_HIDDEN_PROPERTIES(V) \
    39     V(objectPrototype) \
    40     V(listener) \
    41     V(attributeListener) \
    42     V(scriptState) \
    43     V(devtoolsInjectedScript) \
    44     V(sleepFunction) \
    45     V(toStringString) \
    46     V(event) \
    47     V(state)
    48 
     42    V(objectPrototype, V8_HIDDEN_PROPERTY_PREFIX) \
     43    V(listener, V8_HIDDEN_PROPERTY_PREFIX) \
     44    V(attributeListener, V8_HIDDEN_PROPERTY_PREFIX) \
     45    V(scriptState, V8_HIDDEN_PROPERTY_PREFIX) \
     46    V(devtoolsInjectedScript, V8_HIDDEN_PROPERTY_PREFIX) \
     47    V(sleepFunction, V8_HIDDEN_PROPERTY_PREFIX) \
     48    V(toStringString, V8_HIDDEN_PROPERTY_PREFIX) \
     49    V(event, V8_HIDDEN_PROPERTY_PREFIX) \
     50    V(state, V8_HIDDEN_PROPERTY_PREFIX) \
     51    V(domStringMap, V8_HIDDEN_REFERENCE_PREFIX) \
     52    V(domTokenList, V8_HIDDEN_REFERENCE_PREFIX) \
     53    V(ownerNode, V8_HIDDEN_REFERENCE_PREFIX)
    4954
    5055    class V8HiddenPropertyName {
    5156    public:
    5257        V8HiddenPropertyName() { }
    53 #define V8_DECLARE_PROPERTY(name) static v8::Handle<v8::String> name();
     58#define V8_DECLARE_PROPERTY(name, prefix) static v8::Handle<v8::String> name();
    5459        V8_HIDDEN_PROPERTIES(V8_DECLARE_PROPERTY);
    5560#undef V8_DECLARE_PROPERTY
     
    5964    private:
    6065        static v8::Persistent<v8::String> createString(const char* key);
    61 #define V8_DECLARE_FIELD(name) v8::Persistent<v8::String> m_##name;
    62         V8_HIDDEN_PROPERTIES(V8_DECLARE_FIELD);
    63 #undef V8_DECLARE_FIELD
    6466    };
    6567
  • trunk/Source/WebCore/bindings/v8/custom/V8DOMStringMapCustom.cpp

    r107266 r109969  
    9292    // Add a hidden reference from the element to the DOMStringMap.
    9393    Element* element = impl->element();
    94     if (!wrapper.IsEmpty() && element) {
    95         v8::Handle<v8::Value> elementValue = toV8(element);
    96         if (!elementValue.IsEmpty() && elementValue->IsObject())
    97             V8DOMWrapper::setNamedHiddenReference(elementValue.As<v8::Object>(), "domStringMap", wrapper);
    98     }
     94    if (!wrapper.IsEmpty() && element)
     95        toV8(element).As<v8::Object>()->SetHiddenValue(V8HiddenPropertyName::domStringMap(), wrapper);
    9996    return wrapper;
    10097}
  • trunk/Source/WebCore/bindings/v8/custom/V8DOMTokenListCustom.cpp

    r107266 r109969  
    4646    // Add a hidden reference from the element to the DOMTokenList.
    4747    Element* element = impl->element();
    48     if (!wrapper.IsEmpty() && element) {
    49         v8::Handle<v8::Value> elementValue = toV8(element);
    50         if (!elementValue.IsEmpty() && elementValue->IsObject())
    51             V8DOMWrapper::setNamedHiddenReference(elementValue.As<v8::Object>(), "domTokenList", wrapper);
    52     }
     48    if (!wrapper.IsEmpty() && element)
     49        toV8(element).As<v8::Object>()->SetHiddenValue(V8HiddenPropertyName::domTokenList(), wrapper);
    5350    return wrapper;
    5451}
  • trunk/Source/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp

    r107266 r109969  
    8080    Element* element = impl->element();
    8181    if (!wrapper.IsEmpty() && element)
    82         V8DOMWrapper::setNamedHiddenReference(wrapper, "ownerNode", toV8(element));
     82        toV8(element).As<v8::Object>()->SetHiddenValue(V8HiddenPropertyName::ownerNode(), wrapper);
    8383    return wrapper;
    8484}
Note: See TracChangeset for help on using the changeset viewer.