Changeset 263070 in webkit


Ignore:
Timestamp:
Jun 15, 2020, 6:23:44 PM (5 years ago)
Author:
Alexey Shvayka
Message:

Expand JSObject::defineOwnIndexedProperty() fast path for existing properties
https://bugs.webkit.org/show_bug.cgi?id=213133

Reviewed by Yusuke Suzuki.

JSTests:

  • microbenchmarks/array-redefine-index-and-reverse.js: Added.
  • microbenchmarks/array-redefine-index.js: Added.
  • stress/define-own-indexed-property-fast-path.js: Added.

Source/JavaScriptCore:

This patch expands fast path of JSObject::defineOwnIndexedProperty() to cover existing properties
if given data descriptor has no falsy attributes, preventing the object from entering SparseMode.
The optimization is possible due to this invariant: indexed properties of non-SparseMode objects
have attributes of PropertyAttribute::None (except for typed arrays; added assert covers it).

PropertyDescriptor::attributesOverridingCurrent() with PropertyAttribute::None descriptor
is used to support partial descriptors like {value: 1, writable: true}.

This change advances Object.defineProperty microbenchmark by 35%; array read/write benchmark
following property redefinition is progressed by a factor of 16 due to avoiding SparseMode.

  • runtime/JSObject.cpp:

(JSC::JSObject::defineOwnIndexedProperty):

Location:
trunk
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r263056 r263070  
     12020-06-15  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Expand JSObject::defineOwnIndexedProperty() fast path for existing properties
     4        https://bugs.webkit.org/show_bug.cgi?id=213133
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * microbenchmarks/array-redefine-index-and-reverse.js: Added.
     9        * microbenchmarks/array-redefine-index.js: Added.
     10        * stress/define-own-indexed-property-fast-path.js: Added.
     11
    1122020-06-15  Caio Lima  <ticaiolima@gmail.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r263068 r263070  
     12020-06-15  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Expand JSObject::defineOwnIndexedProperty() fast path for existing properties
     4        https://bugs.webkit.org/show_bug.cgi?id=213133
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        This patch expands fast path of JSObject::defineOwnIndexedProperty() to cover existing properties
     9        if given data descriptor has no falsy attributes, preventing the object from entering SparseMode.
     10        The optimization is possible due to this invariant: indexed properties of non-SparseMode objects
     11        have attributes of PropertyAttribute::None (except for typed arrays; added assert covers it).
     12
     13        PropertyDescriptor::attributesOverridingCurrent() with PropertyAttribute::None descriptor
     14        is used to support partial descriptors like {value: 1, writable: true}.
     15
     16        This change advances Object.defineProperty microbenchmark by 35%; array read/write benchmark
     17        following property redefinition is progressed by a factor of 16 due to avoiding SparseMode.
     18
     19        * runtime/JSObject.cpp:
     20        (JSC::JSObject::defineOwnIndexedProperty):
     21
    1222020-06-15  Robin Morisset  <rmorisset@apple.com>
    223
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r263035 r263070  
    26122612}
    26132613
    2614 // Defined in ES5.1 8.12.9
     2614// https://tc39.es/ecma262/#sec-ordinarydefineownproperty
    26152615bool JSObject::defineOwnIndexedProperty(JSGlobalObject* globalObject, unsigned index, const PropertyDescriptor& descriptor, bool throwException)
    26162616{
     
    26232623
    26242624    if (!inSparseIndexingMode()) {
     2625        const PropertyDescriptor emptyAttributesDescriptor(jsUndefined(), static_cast<unsigned>(PropertyAttribute::None));
     2626        ASSERT(emptyAttributesDescriptor.attributes() == static_cast<unsigned>(PropertyAttribute::None));
     2627
     2628#if ASSERT_ENABLED
     2629        if (canGetIndexQuickly(index) && canDoFastPutDirectIndex(vm, this)) {
     2630            PropertyDescriptor currentDescriptor;
     2631            ASSERT(getOwnPropertyDescriptor(globalObject, Identifier::from(vm, index), currentDescriptor));
     2632            scope.assertNoException();
     2633            ASSERT(currentDescriptor.attributes() == emptyAttributesDescriptor.attributes());
     2634        }
     2635#endif
    26252636        // Fast case: we're putting a regular property to a regular array
    2626         // FIXME: this will pessimistically assume that if attributes are missing then they'll default to false
    2627         // however if the property currently exists missing attributes will override from their current 'true'
    2628         // state (i.e. defineOwnProperty could be used to set a value without needing to entering 'SparseMode').
    2629         if (!descriptor.attributes() && descriptor.value() && canDoFastPutDirectIndex(vm, this)) {
     2637        if (descriptor.value()
     2638            && (!descriptor.attributes() || (canGetIndexQuickly(index) && !descriptor.attributesOverridingCurrent(emptyAttributesDescriptor)))
     2639            && canDoFastPutDirectIndex(vm, this)) {
    26302640            ASSERT(!descriptor.isAccessorDescriptor());
    26312641            RELEASE_AND_RETURN(scope, putDirectIndex(globalObject, index, descriptor.value(), 0, throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow));
Note: See TracChangeset for help on using the changeset viewer.