Changeset 286251 in webkit


Ignore:
Timestamp:
Nov 29, 2021 12:04:08 PM (8 months ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Public Class Field initialization is slow
https://bugs.webkit.org/show_bug.cgi?id=232479

Reviewed by Alexey Shvayka.

JSTests:

  • microbenchmarks/class-fields-classic-constructor-assignments.js: Added.

(Classic_Constructor_Assignments):
(bench):

  • microbenchmarks/class-fields-private-fields.js: Added.

(ES2022_Private_Fields):
(bench):

  • microbenchmarks/class-fields-public-fields.js: Added.

(ES2022_Public_Fields):
(bench):

  • stress/class-fields-getter-override.js: Added.

(shouldThrow):
(defineCGetter.):
(B):
(define0Getter.):
(define0Getter):
(D):

  • stress/custom-get-set-proto-chain-put.js:

(let.object.of.getObjects):

  • stress/freeze-and-seal-should-prevent-extensions.js:
  • stress/object-assign-fast-path.js:
  • stress/ordinary-set-exceptions.js:

(shouldThrow):

  • stress/put-non-reified-static-function-or-custom.js:
  • wasm/js-api/test_basic_api.js:

(const.c.in.constructorProperties.switch):

Source/JavaScriptCore:

Class public field implementation did not have optimization for initializing class fields: using
runtime call to initialize fields instead of IC. This patch leverages put_by_id / put_by_val with
direct flag so that we can enable IC.

Currently, we are not changing original putDirect semantics since it is out of this patch's scope.
We will look into it and probably changing it in a separate patch, but not in this patch.

ToT Patched

class-fields-classic-constructor-assignments

17.1491+-2.6327 15.0906+-0.6795 might be 1.1364x faster

class-fields-public-fields 409.4328+-8.3140 20.2752+-2.0835 definitely 20.1938x faster
class-fields-private-fields 27.2621+-1.3858 25.1810+-3.9873 might be 1.0826x faster

  • bytecompiler/NodesCodegen.cpp:

(JSC::DefineFieldNode::emitBytecode):

  • runtime/CommonSlowPaths.h:

(JSC::CommonSlowPaths::putDirectWithReify):

  • runtime/JSObject.cpp:

(JSC::JSObject::putDirectCustomAccessor):
(JSC::JSObject::putDirectNonIndexAccessor):

  • runtime/JSObject.h:

(JSC::JSObject::putDirect):
(JSC::JSObject::putDirectRespectingExtensibility):

  • runtime/JSObjectInlines.h:

(JSC::JSObject::putInlineFast):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::putOwnDataProperty):
(JSC::JSObject::putOwnDataPropertyMayBeIndex):

Source/WTF:

  • wtf/text/ASCIILiteral.h:
Location:
trunk
Files:
4 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r286249 r286251  
     12021-11-29  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Public Class Field initialization is slow
     4        https://bugs.webkit.org/show_bug.cgi?id=232479
     5
     6        Reviewed by Alexey Shvayka.
     7
     8        * microbenchmarks/class-fields-classic-constructor-assignments.js: Added.
     9        (Classic_Constructor_Assignments):
     10        (bench):
     11        * microbenchmarks/class-fields-private-fields.js: Added.
     12        (ES2022_Private_Fields):
     13        (bench):
     14        * microbenchmarks/class-fields-public-fields.js: Added.
     15        (ES2022_Public_Fields):
     16        (bench):
     17        * stress/class-fields-getter-override.js: Added.
     18        (shouldThrow):
     19        (defineCGetter.):
     20        (B):
     21        (define0Getter.):
     22        (define0Getter):
     23        (D):
     24        * stress/custom-get-set-proto-chain-put.js:
     25        (let.object.of.getObjects):
     26        * stress/freeze-and-seal-should-prevent-extensions.js:
     27        * stress/object-assign-fast-path.js:
     28        * stress/ordinary-set-exceptions.js:
     29        (shouldThrow):
     30        * stress/put-non-reified-static-function-or-custom.js:
     31        * wasm/js-api/test_basic_api.js:
     32        (const.c.in.constructorProperties.switch):
     33
    1342021-11-29  Yusuke Suzuki  <ysuzuki@apple.com>
    235
  • trunk/JSTests/stress/custom-get-set-proto-chain-put.js

    r280256 r286251  
    122122        Object.preventExtensions(object);
    123123        for (let i = 0; i < 100; ++i) {
    124             shouldThrow(() => { object.customValueNoSetter = {}; }, "TypeError: Attempted to assign to readonly property.");
     124            shouldThrow(() => { object.customValueNoSetter = {}; }, "TypeError: Attempting to define property on object that is not extensible.");
    125125            assert(!Reflect.set(object, "customValueNoSetter", {}));
    126126        }
  • trunk/JSTests/stress/freeze-and-seal-should-prevent-extensions.js

    r192858 r286251  
    3232    shouldBe(object.Matcha, 'Matcha');
    3333    shouldBe(Reflect.isExtensible(object), false);
    34     shouldThrow(() => object.Mocha = 'Mocha', `TypeError: Attempted to assign to readonly property.`);
     34    shouldThrow(() => object.Mocha = 'Mocha', `TypeError: Attempting to define property on object that is not extensible.`);
    3535}());
    3636
     
    4848    shouldBe(object.Matcha, 'Matcha');
    4949    shouldBe(Reflect.isExtensible(object), false);
    50     shouldThrow(() => object.Mocha = 'Mocha', `TypeError: Attempted to assign to readonly property.`);
     50    shouldThrow(() => object.Mocha = 'Mocha', `TypeError: Attempting to define property on object that is not extensible.`);
    5151}());
  • trunk/JSTests/stress/object-assign-fast-path.js

    r280460 r286251  
    181181    shouldThrow(() => {
    182182        Object.assign(object, { bar: 2 });
    183     }, `TypeError: Attempted to assign to readonly property.`);
     183    }, `TypeError: Attempting to define property on object that is not extensible.`);
    184184    shouldBe(object.bar, undefined);
    185185}
  • trunk/JSTests/stress/ordinary-set-exceptions.js

    r198270 r286251  
    6464    }), true);
    6565    receiver.cocoa = 'NG';
    66 }, `TypeError: Attempted to assign to readonly property.`);
     66}, `TypeError: Attempting to change value of a readonly property.`);
    6767
    6868// 9.1.9.1 4-d-ii
     
    8686    }), true);
    8787    receiver.cocoa = 'NG';
    88 }, `TypeError: Attempted to assign to readonly property.`);
     88}, `TypeError: Attempting to change value of a readonly property.`);
    8989
    9090// 9.1.9.1 7
  • trunk/JSTests/stress/put-non-reified-static-function-or-custom.js

    r278589 r286251  
    126126    Object.preventExtensions(heir);
    127127
    128     shouldThrow(() => { heir[key] = testValue; }, "TypeError: Attempted to assign to readonly property.", key);
     128    shouldThrow(() => { heir[key] = testValue; }, "TypeError: Attempting to define property on object that is not extensible.", key);
    129129    assert(heir[key] !== testValue, key);
    130130    assert(object[key] !== testValue, key);
  • trunk/JSTests/wasm/js-api/test_basic_api.js

    r274609 r286251  
    8787        assert.eq(Symbol.toStringTag in instance.exports, false);
    8888        assert.eq(Object.getOwnPropertySymbols(instance.exports).length, 0);
    89         assert.throws(() => instance.exports[Symbol.toStringTag] = 42, TypeError, `Attempted to assign to readonly property.`);
     89        assert.throws(() => instance.exports[Symbol.toStringTag] = 42, TypeError, `Attempting to define property on object that is not extensible.`);
    9090        break;
    9191    case "Memory":
  • trunk/Source/JavaScriptCore/ChangeLog

    r286249 r286251  
     12021-11-29  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Public Class Field initialization is slow
     4        https://bugs.webkit.org/show_bug.cgi?id=232479
     5
     6        Reviewed by Alexey Shvayka.
     7
     8        Class public field implementation did not have optimization for initializing class fields: using
     9        runtime call to initialize fields instead of IC. This patch leverages put_by_id / put_by_val with
     10        direct flag so that we can enable IC.
     11
     12        Currently, we are not changing original putDirect semantics since it is out of this patch's scope.
     13        We will look into it and probably changing it in a separate patch, but not in this patch.
     14
     15                                                             ToT                     Patched
     16
     17        class-fields-classic-constructor-assignments
     18                                                       17.1491+-2.6327           15.0906+-0.6795          might be 1.1364x faster
     19        class-fields-public-fields                    409.4328+-8.3140     ^     20.2752+-2.0835        ^ definitely 20.1938x faster
     20        class-fields-private-fields                    27.2621+-1.3858           25.1810+-3.9873          might be 1.0826x faster
     21
     22        * bytecompiler/NodesCodegen.cpp:
     23        (JSC::DefineFieldNode::emitBytecode):
     24        * runtime/CommonSlowPaths.h:
     25        (JSC::CommonSlowPaths::putDirectWithReify):
     26        * runtime/JSObject.cpp:
     27        (JSC::JSObject::putDirectCustomAccessor):
     28        (JSC::JSObject::putDirectNonIndexAccessor):
     29        * runtime/JSObject.h:
     30        (JSC::JSObject::putDirect):
     31        (JSC::JSObject::putDirectRespectingExtensibility):
     32        * runtime/JSObjectInlines.h:
     33        (JSC::JSObject::putInlineFast):
     34        (JSC::JSObject::putDirectInternal):
     35        (JSC::JSObject::putOwnDataProperty):
     36        (JSC::JSObject::putOwnDataPropertyMayBeIndex):
     37
    1382021-11-29  Yusuke Suzuki  <ysuzuki@apple.com>
    239
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r284435 r286251  
    50405040    switch (m_type) {
    50415041    case DefineFieldNode::Type::Name: {
    5042         // FIXME: Improve performance of public class fields
    5043         // https://bugs.webkit.org/show_bug.cgi?id=198330
    5044         RefPtr<RegisterID> propertyName = generator.emitLoad(nullptr, *m_ident);
    5045         generator.emitCallDefineProperty(generator.thisRegister(), propertyName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
     5042        StrictModeScope strictModeScope(generator);
     5043        if (auto index = parseIndex(*m_ident)) {
     5044            RefPtr<RegisterID> propertyName = generator.emitLoad(nullptr, jsNumber(index.value()));
     5045            generator.emitDirectPutByVal(generator.thisRegister(), propertyName.get(), value.get());
     5046        } else
     5047            generator.emitDirectPutById(generator.thisRegister(), *m_ident, value.get());
    50465048        break;
    50475049    }
     
    50585060    }
    50595061    case DefineFieldNode::Type::ComputedName: {
    5060         // FIXME: Improve performance of public class fields
    5061         // https://bugs.webkit.org/show_bug.cgi?id=198330
    5062 
    50635062        // For ComputedNames, the expression has already been evaluated earlier during evaluation of a ClassExprNode.
    50645063        // Here, `m_ident` refers to private symbol ID in a class lexical scope, containing the value already converted to an Expression.
     
    50735072            generator.emitSetFunctionName(value.get(), privateName.get());
    50745073        generator.emitProfileType(privateName.get(), var, m_position, m_position + m_ident->length());
    5075         generator.emitCallDefineProperty(generator.thisRegister(), privateName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
     5074        {
     5075            StrictModeScope strictModeScope(generator);
     5076            generator.emitDirectPutByVal(generator.thisRegister(), privateName.get(), value.get());
     5077        }
    50765078        break;
    50775079    }
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r284700 r286251  
    3636#include "SlowPathFunction.h"
    3737#include "StackAlignment.h"
     38#include "TypeError.h"
    3839#include "VMInlines.h"
    3940#include <wtf/StdLibExtras.h>
     
    187188}
    188189
    189 
    190190static ALWAYS_INLINE void putDirectWithReify(VM& vm, JSGlobalObject* globalObject, JSObject* baseObject, PropertyName propertyName, JSValue value, PutPropertySlot& slot, Structure** result = nullptr)
    191191{
    192192    auto scope = DECLARE_THROW_SCOPE(vm);
    193     if (baseObject->inherits<JSFunction>(vm)) {
     193    bool isJSFunction = baseObject->inherits<JSFunction>(vm);
     194    if (isJSFunction) {
    194195        jsCast<JSFunction*>(baseObject)->reifyLazyPropertyIfNeeded(vm, globalObject, propertyName);
    195196        RETURN_IF_EXCEPTION(scope, void());
     
    197198    if (result)
    198199        *result = originalStructureBeforePut(vm, baseObject);
    199     scope.release();
    200     baseObject->putDirect(vm, propertyName, value, slot);
     200
     201    Structure* structure = baseObject->structure(vm);
     202    if (LIKELY(propertyName != vm.propertyNames->underscoreProto && !structure->hasReadOnlyOrGetterSetterPropertiesExcludingProto() && (isJSFunction || structure->classInfo()->methodTable.defineOwnProperty == &JSObject::defineOwnProperty))) {
     203        auto error = baseObject->putDirectRespectingExtensibility(vm, propertyName, value, 0, slot);
     204        if (!error.isNull())
     205            typeError(globalObject, scope, slot.isStrictMode(), error);
     206    } else {
     207        slot.disableCaching();
     208        scope.release();
     209        PropertyDescriptor descriptor(value, 0);
     210        baseObject->methodTable(vm)->defineOwnProperty(baseObject, globalObject, propertyName, descriptor, slot.isStrictMode());
     211    }
    201212}
    202213
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r285687 r286251  
    20072007
    20082008    PutPropertySlot slot(this);
    2009     bool result = putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot);
     2009    bool result = putDirectInternal<PutModeDefineOwnPropertyIgnoringExtensibility>(vm, propertyName, value, attributes, slot).isNull();
    20102010
    20112011    ASSERT(slot.type() == PutPropertySlot::NewProperty);
     
    20382038    ASSERT(attributes & PropertyAttribute::Accessor);
    20392039    PutPropertySlot slot(this);
    2040     bool result = putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, accessor, attributes, slot);
     2040    bool result = putDirectInternal<PutModeDefineOwnPropertyIgnoringExtensibility>(vm, propertyName, accessor, attributes, slot).isNull();
    20412041
    20422042    Structure* structure = this->structure(vm);
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r285730 r286251  
    101101    JS_EXPORT_PRIVATE friend bool setUpStaticFunctionSlot(VM&, const HashTableValue*, JSObject*, PropertyName, PropertySlot&);
    102102
    103     enum PutMode {
     103    enum PutMode : uint8_t {
    104104        PutModePut,
    105105        PutModeDefineOwnProperty,
     106        PutModeDefineOwnPropertyIgnoringExtensibility,
    106107    };
    107108
     
    686687    bool putDirect(VM&, PropertyName, JSValue, unsigned attributes, PutPropertySlot&);
    687688    bool putDirect(VM&, PropertyName, JSValue, PutPropertySlot&);
     689    ASCIILiteral putDirectRespectingExtensibility(VM&, PropertyName, JSValue, unsigned attributes, PutPropertySlot&);
    688690    void putDirectWithoutTransition(VM&, PropertyName, JSValue, unsigned attributes = 0);
    689691    bool putDirectNonIndexAccessor(VM&, PropertyName, GetterSetter*, unsigned attributes);
     
    11571159       
    11581160    template<PutMode>
    1159     bool putDirectInternal(VM&, PropertyName, JSValue, unsigned attr, PutPropertySlot&);
     1161    ASCIILiteral putDirectInternal(VM&, PropertyName, JSValue, unsigned attr, PutPropertySlot&);
    11601162
    11611163    JS_EXPORT_PRIVATE NEVER_INLINE bool putInlineSlow(JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
     
    15831585    ASSERT(!value.isCustomGetterSetter() && !(attributes & PropertyAttribute::CustomAccessorOrValue));
    15841586    PutPropertySlot slot(this);
    1585     return putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot);
     1587    return putDirectInternal<PutModeDefineOwnPropertyIgnoringExtensibility>(vm, propertyName, value, attributes, slot).isNull();
    15861588}
    15871589
    15881590inline bool JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot)
     1591{
     1592    ASSERT(!value.isGetterSetter());
     1593    ASSERT(!value.isCustomGetterSetter());
     1594    return putDirectInternal<PutModeDefineOwnPropertyIgnoringExtensibility>(vm, propertyName, value, attributes, slot).isNull();
     1595}
     1596
     1597inline bool JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
     1598{
     1599    ASSERT(!value.isGetterSetter());
     1600    ASSERT(!value.isCustomGetterSetter());
     1601    return putDirectInternal<PutModeDefineOwnPropertyIgnoringExtensibility>(vm, propertyName, value, 0, slot).isNull();
     1602}
     1603
     1604inline ASCIILiteral JSObject::putDirectRespectingExtensibility(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot)
    15891605{
    15901606    ASSERT(!value.isGetterSetter());
    15911607    ASSERT(!value.isCustomGetterSetter());
    15921608    return putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot);
    1593 }
    1594 
    1595 inline bool JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
    1596 {
    1597     ASSERT(!value.isGetterSetter());
    1598     ASSERT(!value.isCustomGetterSetter());
    1599     return putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, 0, slot);
    16001609}
    16011610
  • trunk/Source/JavaScriptCore/runtime/JSObjectInlines.h

    r284330 r286251  
    283283    auto scope = DECLARE_THROW_SCOPE(vm);
    284284
    285     // FIXME: For a failure due to non-extensible structure, the error message is misleading
    286     if (!putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot))
    287         return typeError(globalObject, scope, slot.isStrictMode(), ReadonlyPropertyWriteError);
     285    auto error = putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot);
     286    if (!error.isNull())
     287        return typeError(globalObject, scope, slot.isStrictMode(), error);
    288288    return true;
    289289}
     
    320320
    321321template<JSObject::PutMode mode>
    322 ALWAYS_INLINE bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot)
     322ALWAYS_INLINE ASCIILiteral JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot)
    323323{
    324324    ASSERT(value);
     
    336336        PropertyOffset offset = structure->get(vm, propertyName, currentAttributes);
    337337        if (offset != invalidOffset) {
    338             if ((mode == PutModePut) && currentAttributes & PropertyAttribute::ReadOnlyOrAccessorOrCustomAccessor)
    339                 return false;
     338            if ((mode == PutModePut || mode == PutModeDefineOwnProperty) && currentAttributes & PropertyAttribute::ReadOnlyOrAccessorOrCustomAccessor)
     339                return ReadonlyPropertyChangeError;
    340340
    341341            putDirect(vm, offset, value);
     
    344344            // FIXME: Check attributes against PropertyAttribute::CustomAccessorOrValue. Changing GetterSetter should work w/o transition.
    345345            // https://bugs.webkit.org/show_bug.cgi?id=214342
    346             if (mode == PutModeDefineOwnProperty && (attributes != currentAttributes || (attributes & PropertyAttribute::AccessorOrCustomAccessorOrValue)))
     346            if ((mode == PutModeDefineOwnProperty || mode == PutModeDefineOwnPropertyIgnoringExtensibility) && (attributes != currentAttributes || (attributes & PropertyAttribute::AccessorOrCustomAccessorOrValue)))
    347347                setStructure(vm, Structure::attributeChangeTransition(vm, structure, propertyName, attributes));
    348348            else {
     
    351351            }
    352352
    353             return true;
     353            return ASCIILiteral::null();
    354354        }
    355355
    356         if ((mode == PutModePut) && !isStructureExtensible(vm))
    357             return false;
     356        if ((mode == PutModePut || mode == PutModeDefineOwnProperty) && !isStructureExtensible(vm))
     357            return NonExtensibleObjectPropertyDefineError;
    358358
    359359        offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure);
     
    363363        if (attributes & PropertyAttribute::ReadOnly)
    364364            this->structure(vm)->setContainsReadOnlyProperties();
    365         return true;
     365        return ASCIILiteral::null();
    366366    }
    367367
     
    387387        setStructure(vm, newStructure);
    388388        slot.setNewProperty(this, offset);
    389         return true;
     389        return ASCIILiteral::null();
    390390    }
    391391
     
    393393    offset = structure->get(vm, propertyName, currentAttributes);
    394394    if (offset != invalidOffset) {
    395         if ((mode == PutModePut) && currentAttributes & PropertyAttribute::ReadOnlyOrAccessorOrCustomAccessor)
    396             return false;
     395        if ((mode == PutModePut || mode == PutModeDefineOwnProperty) && currentAttributes & PropertyAttribute::ReadOnlyOrAccessorOrCustomAccessor)
     396            return ReadonlyPropertyChangeError;
    397397
    398398        structure->didReplaceProperty(offset);
     
    401401        // FIXME: Check attributes against PropertyAttribute::CustomAccessorOrValue. Changing GetterSetter should work w/o transition.
    402402        // https://bugs.webkit.org/show_bug.cgi?id=214342
    403         if (mode == PutModeDefineOwnProperty && (attributes != currentAttributes || (attributes & PropertyAttribute::AccessorOrCustomAccessorOrValue))) {
     403        if ((mode == PutModeDefineOwnProperty || mode == PutModeDefineOwnPropertyIgnoringExtensibility) && (attributes != currentAttributes || (attributes & PropertyAttribute::AccessorOrCustomAccessorOrValue))) {
    404404            // We want the structure transition watchpoint to fire after this object has switched structure.
    405405            // This allows adaptive watchpoints to observe if the new structure is the one we want.
     
    411411        }
    412412
    413         return true;
    414     }
    415 
    416     if ((mode == PutModePut) && !isStructureExtensible(vm))
    417         return false;
     413        return ASCIILiteral::null();
     414    }
     415
     416    if ((mode == PutModePut || mode == PutModeDefineOwnProperty) && !isStructureExtensible(vm))
     417        return NonExtensibleObjectPropertyDefineError;
    418418   
    419419    // We want the structure transition watchpoint to fire after this object has switched structure.
     
    440440    if (attributes & PropertyAttribute::ReadOnly)
    441441        newStructure->setContainsReadOnlyProperties();
    442     return true;
     442    return ASCIILiteral::null();
    443443}
    444444
     
    574574{
    575575    validatePutOwnDataProperty(vm, propertyName, value);
    576     return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot);
     576    return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot).isNull();
    577577}
    578578
     
    584584        return putDirectIndex(globalObject, index.value(), value, 0, PutDirectIndexLikePutDirect);
    585585
    586     return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot);
     586    return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot).isNull();
    587587}
    588588
  • trunk/Source/WTF/ChangeLog

    r286248 r286251  
     12021-11-29  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Public Class Field initialization is slow
     4        https://bugs.webkit.org/show_bug.cgi?id=232479
     5
     6        Reviewed by Alexey Shvayka.
     7
     8        * wtf/text/ASCIILiteral.h:
     9
    1102021-11-29  Yusuke Suzuki  <ysuzuki@apple.com>
    211
  • trunk/Source/WTF/wtf/text/ASCIILiteral.h

    r285048 r286251  
    5050    }
    5151
     52    constexpr bool isNull() const { return !m_characters; }
     53
    5254    constexpr const char* characters() const { return m_characters; }
    5355    const LChar* characters8() const { return bitwise_cast<const LChar*>(m_characters); }
Note: See TracChangeset for help on using the changeset viewer.