Changeset 110347 in webkit


Ignore:
Timestamp:
Mar 9, 2012 4:13:13 PM (12 years ago)
Author:
haraken@chromium.org
Message:

[V8][Performance] Inline hot methods in V8Bindings.h
https://bugs.webkit.org/show_bug.cgi?id=80685

Reviewed by Adam Barth.

This patch slightly improves DOM binding performance by inlining hot
methods in V8Binding.cpp, e.g. isUndefinedOrNull(), v8StringOrNull(), v8Boolean().
For example, this patch improves div.nodeName by 5.0%, and div.nodeValue by 4.1%.

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

The performance test results in my Mac environment are as follows:

Chromium/V8 without this patch:
div.nodeName : 3417.4 ms
div.nodeValue : 2069.6 ms

Chromium/V8 with this patch:
div.nodeName : 3245.6 ms
div.nodeValue : 1983.1 ms

No tests. No change in behavior.

  • bindings/v8/V8Binding.cpp:
  • bindings/v8/V8Binding.h:

(WebCore::toWebCoreString):
(WebCore::isUndefinedOrNull):
(WebCore::isHostObject):
(WebCore::v8Boolean):
(WebCore::toWebCoreStringWithNullCheck):
(WebCore::toAtomicWebCoreStringWithNullCheck):
(WebCore::toWebCoreStringWithNullOrUndefinedCheck):
(WebCore::v8UndetectableString):
(WebCore::v8StringOrNull):
(WebCore::v8StringOrUndefined):
(WebCore::v8StringOrFalse):
(WebCore::toWebCoreDate):
(WebCore::v8DateOrNull):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r110344 r110347  
     12012-03-09  Kentaro Hara  <haraken@chromium.org>
     2
     3        [V8][Performance] Inline hot methods in V8Bindings.h
     4        https://bugs.webkit.org/show_bug.cgi?id=80685
     5
     6        Reviewed by Adam Barth.
     7
     8        This patch slightly improves DOM binding performance by inlining hot
     9        methods in V8Binding.cpp, e.g. isUndefinedOrNull(), v8StringOrNull(), v8Boolean().
     10        For example, this patch improves div.nodeName by 5.0%, and div.nodeValue by 4.1%.
     11
     12        Performance tests: https://bugs.webkit.org/attachment.cgi?id=131006
     13
     14        The performance test results in my Mac environment are as follows:
     15
     16        Chromium/V8 without this patch:
     17        div.nodeName : 3417.4 ms
     18        div.nodeValue : 2069.6 ms
     19
     20        Chromium/V8 with this patch:
     21        div.nodeName : 3245.6 ms
     22        div.nodeValue : 1983.1 ms
     23
     24        No tests. No change in behavior.
     25
     26        * bindings/v8/V8Binding.cpp:
     27        * bindings/v8/V8Binding.h:
     28        (WebCore::toWebCoreString):
     29        (WebCore::isUndefinedOrNull):
     30        (WebCore::isHostObject):
     31        (WebCore::v8Boolean):
     32        (WebCore::toWebCoreStringWithNullCheck):
     33        (WebCore::toAtomicWebCoreStringWithNullCheck):
     34        (WebCore::toWebCoreStringWithNullOrUndefinedCheck):
     35        (WebCore::v8UndetectableString):
     36        (WebCore::v8StringOrNull):
     37        (WebCore::v8StringOrUndefined):
     38        (WebCore::v8StringOrFalse):
     39        (WebCore::toWebCoreDate):
     40        (WebCore::v8DateOrNull):
     41
    1422012-03-09  W. James MacLean  <wjmaclean@chromium.org>
    243
  • trunk/Source/WebCore/bindings/v8/V8Binding.cpp

    r105157 r110347  
    287287}
    288288
    289 String toWebCoreString(const v8::Arguments& args, int index) {
    290     return v8ValueToWebCoreString(args[index]);
    291 }
    292 
    293    
    294 String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
    295 {
    296     if (value->IsNull())
    297         return String();
    298     return v8ValueToWebCoreString(value);
    299 }
    300 
    301 AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
    302 {
    303     if (value->IsNull())
    304         return AtomicString();
    305     return v8ValueToAtomicWebCoreString(value);
    306 }
    307 
    308 String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value)
    309 {
    310     if (value->IsNull() || value->IsUndefined())
    311         return String();
    312     return toWebCoreString(value);
    313 }
    314 
    315 bool isUndefinedOrNull(v8::Handle<v8::Value> value)
    316 {
    317     return value->IsNull() || value->IsUndefined();
    318 }
    319 
    320 bool isHostObject(v8::Handle<v8::Object> object)
    321 {
    322     // If the object has any internal fields, then we won't be able to serialize or deserialize
    323     // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
    324     // the mechanism for these relies on data stored in these fields. We should
    325     // catch external array data and external pixel data as a special case (noting that CanvasPixelArrays
    326     // can't be serialized without being wrapped by ImageData according to the standard).
    327     return object->InternalFieldCount() || object->HasIndexedPropertiesInPixelData() || object->HasIndexedPropertiesInExternalArrayData();
    328 }
    329 
    330 v8::Handle<v8::Boolean> v8Boolean(bool value)
    331 {
    332     return value ? v8::True() : v8::False();
    333 }
    334 
    335 v8::Handle<v8::String> v8UndetectableString(const String& str)
    336 {
    337     return v8::String::NewUndetectable(fromWebCoreString(str), str.length());
    338 }
    339 
    340 v8::Handle<v8::Value> v8StringOrNull(const String& str)
    341 {
    342     return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str));
    343 }
    344 
    345 v8::Handle<v8::Value> v8StringOrUndefined(const String& str)
    346 {
    347     return str.isNull() ? v8::Handle<v8::Value>(v8::Undefined()) : v8::Handle<v8::Value>(v8String(str));
    348 }
    349 
    350 v8::Handle<v8::Value> v8StringOrFalse(const String& str)
    351 {
    352     return str.isNull() ? v8::Handle<v8::Value>(v8::False()) : v8::Handle<v8::Value>(v8String(str));
    353 }
    354 
    355 double toWebCoreDate(v8::Handle<v8::Value> object)
    356 {
    357     return (object->IsDate() || object->IsNumber()) ? object->NumberValue() : std::numeric_limits<double>::quiet_NaN();
    358 }
    359 
    360 v8::Handle<v8::Value> v8DateOrNull(double value)
    361 {
    362     if (isfinite(value))
    363         return v8::Date::New(value);
    364     return v8::Null();
    365 }
    366 
    367289template <class S> struct StringTraits
    368290{
  • trunk/Source/WebCore/bindings/v8/V8Binding.h

    r110104 r110347  
    330330    }
    331331
    332     String toWebCoreString(const v8::Arguments&, int index);
     332    inline String toWebCoreString(const v8::Arguments& args, int index)
     333    {
     334        return v8ValueToWebCoreString(args[index]);
     335    }
    333336
    334337    // The string returned by this function is still owned by the argument
     
    339342    }
    340343
    341     bool isUndefinedOrNull(v8::Handle<v8::Value> value);
     344    inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
     345    {
     346        return value->IsNull() || value->IsUndefined();
     347    }
    342348
    343349    // Returns true if the provided object is to be considered a 'host object', as used in the
    344350    // HTML5 structured clone algorithm.
    345     bool isHostObject(v8::Handle<v8::Object>);
    346 
    347     v8::Handle<v8::Boolean> v8Boolean(bool value);
    348 
    349     String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
    350 
    351     AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
    352 
    353     String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value);
    354 
    355     v8::Handle<v8::String> v8UndetectableString(const String& str);
    356 
    357     v8::Handle<v8::Value> v8StringOrNull(const String& str);
    358 
    359     v8::Handle<v8::Value> v8StringOrUndefined(const String& str);
    360 
    361     v8::Handle<v8::Value> v8StringOrFalse(const String& str);
     351    inline bool isHostObject(v8::Handle<v8::Object> object)
     352    {
     353        // If the object has any internal fields, then we won't be able to serialize or deserialize
     354        // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
     355        // the mechanism for these relies on data stored in these fields. We should
     356        // catch external array data and external pixel data as a special case (noting that CanvasPixelArrays
     357        // can't be serialized without being wrapped by ImageData according to the standard).
     358        return object->InternalFieldCount() || object->HasIndexedPropertiesInPixelData() || object->HasIndexedPropertiesInExternalArrayData();
     359    }
     360
     361    inline v8::Handle<v8::Boolean> v8Boolean(bool value)
     362    {
     363        return value ? v8::True() : v8::False();
     364    }
     365
     366    inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
     367    {
     368        return value->IsNull() ? String() : v8ValueToWebCoreString(value);
     369    }
     370
     371    inline AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
     372    {
     373        return value->IsNull() ? AtomicString() : v8ValueToAtomicWebCoreString(value);
     374    }
     375
     376    inline String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value)
     377    {
     378        return (value->IsNull() || value->IsUndefined()) ? String() : toWebCoreString(value);
     379    }
     380
     381    inline v8::Handle<v8::String> v8UndetectableString(const String& str)
     382    {
     383        return v8::String::NewUndetectable(fromWebCoreString(str), str.length());
     384    }
     385
     386    inline v8::Handle<v8::Value> v8StringOrNull(const String& str)
     387    {
     388        return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str));
     389    }
     390
     391    inline v8::Handle<v8::Value> v8StringOrUndefined(const String& str)
     392    {
     393        return str.isNull() ? v8::Handle<v8::Value>(v8::Undefined()) : v8::Handle<v8::Value>(v8String(str));
     394    }
     395
     396    inline v8::Handle<v8::Value> v8StringOrFalse(const String& str)
     397    {
     398        return str.isNull() ? v8::Handle<v8::Value>(v8::False()) : v8::Handle<v8::Value>(v8String(str));
     399    }
    362400
    363401    template <class T> v8::Handle<v8::Value> v8NumberArray(const Vector<T>& values)
     
    370408    }
    371409
    372     double toWebCoreDate(v8::Handle<v8::Value> object);
    373 
    374     v8::Handle<v8::Value> v8DateOrNull(double value);
     410    inline double toWebCoreDate(v8::Handle<v8::Value> object)
     411    {
     412        return (object->IsDate() || object->IsNumber()) ? object->NumberValue() : std::numeric_limits<double>::quiet_NaN();
     413    }
     414
     415    inline v8::Handle<v8::Value> v8DateOrNull(double value)
     416    {
     417        return isfinite(value) ? v8::Date::New(value) : v8::Handle<v8::Value>(v8::Null());
     418    }
    375419
    376420    v8::Persistent<v8::FunctionTemplate> createRawTemplate();
Note: See TracChangeset for help on using the changeset viewer.