Changeset 265934 in webkit


Ignore:
Timestamp:
Aug 19, 2020 10:07:28 PM (4 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Add Object.getOwnPropertyNames caching as it is done for Object.keys, and accelerate Object.getOwnPropertyDescriptor
https://bugs.webkit.org/show_bug.cgi?id=215666

Reviewed by Saam Barati.

JSTests:

  • microbenchmarks/get-own-property-descriptor.js: Added.

(object.get test):
(object.set test):

  • stress/get-own-property-names-bad-time.js: Added.

(shouldBe):
(test):

  • stress/get-own-property-names-dfg.js: Added.

(shouldBe):
(test):

  • stress/keys-bad-time.js: Added.

(shouldBe):
(test):

  • stress/keys-dfg.js: Added.

(shouldBe):
(test):

  • stress/object-get-own-property-names-cached-zero.js: Added.

(shouldBe):
(test):

  • stress/object-get-own-property-names-changed-attribute.js: Added.

(shouldBe):
(test):

  • stress/object-get-own-property-names-changed-index.js: Added.

(shouldBe):
(test):

  • stress/object-get-own-property-names-changed.js: Added.

(shouldBe):
(test):

  • stress/object-get-own-property-names-indexed-non-cache.js: Added.

(shouldBe):
(test):

  • stress/object-get-own-property-names-overrides-get-property-names.js: Added.

(shouldBe):
(test):
(noInline):

  • stress/object-keys-cache.js: Added.

(shouldBe):
(symbol):

Source/JavaScriptCore:

Object.getOwnPropertyNames is immutable for Structure if structure meets some conditions. And we have optimization for Object.keys.
This patch wires existing caching mechanism for Object.keys to Object.getOwnPropertyNames so that Object.getOwnPropertyNames has
full support of caching & inlined code in DFG / FTL.

We also pre-bake structure for the result of Object.getOwnPropertyDescriptor so that we do not need to perform hash table lookup every
time we create an object for Object.getOwnPropertyDescriptor. This makes Object.getOwnPropertyDescriptor 2x faster from the microbenchmark.

The above two optimization makes Speedometer2/Inferno-TodoMVC 7% faster, and it also optimizes Speedometer2/EmberJS-Debug by 5%.
In total, we can get 0.7 - 1.0% progression in Speedometer2.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsicCall):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames):
(JSC::DFG::SpeculativeJIT::compileObjectKeys): Deleted.

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileObjectKeysOrObjectGetOwnPropertyNames):
(JSC::FTL::DFG::LowerDFGToB3::compileObjectKeys): Deleted.

  • runtime/Intrinsic.cpp:

(JSC::intrinsicName):

  • runtime/Intrinsic.h:
  • runtime/IteratorOperations.cpp:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::dataPropertyDescriptorObjectStructure const):
(JSC::JSGlobalObject::accessorPropertyDescriptorObjectStructure const):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncOwnKeys):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorGetOwnPropertyNames):
(JSC::objectConstructorGetOwnPropertySymbols):
(JSC::objectConstructorKeys):
(JSC::ownPropertyKeys):
(JSC::constructObjectFromPropertyDescriptorSlow):

  • runtime/ObjectConstructor.h:

(JSC::createDataPropertyDescriptorObjectStructure):
(JSC::createAccessorPropertyDescriptorObjectStructure):
(JSC::constructObjectFromPropertyDescriptor):

  • runtime/ReflectObject.cpp:

(JSC::reflectObjectOwnKeys):

  • runtime/Structure.cpp:

(JSC::Structure::canCachePropertyNameEnumerator const):

  • runtime/Structure.h:
  • runtime/StructureInlines.h:

(JSC::Structure::setCachedPropertyNames):
(JSC::Structure::cachedPropertyNames const):
(JSC::Structure::cachedPropertyNamesIgnoringSentinel const):
(JSC::Structure::canCacheOwnPropertyNames const):
(JSC::Structure::setCachedOwnKeys): Deleted.
(JSC::Structure::cachedOwnKeys const): Deleted.
(JSC::Structure::cachedOwnKeysIgnoringSentinel const): Deleted.
(JSC::Structure::canCacheOwnKeys const): Deleted.

  • runtime/StructureRareData.cpp:

(JSC::StructureRareData::visitChildren):

  • runtime/StructureRareData.h:
  • runtime/StructureRareDataInlines.h:

(JSC::StructureRareData::cachedPropertyNames const):
(JSC::StructureRareData::cachedPropertyNamesIgnoringSentinel const):
(JSC::StructureRareData::cachedPropertyNamesConcurrently const):
(JSC::StructureRareData::setCachedPropertyNames):
(JSC::StructureRareData::cachedOwnKeys const): Deleted.
(JSC::StructureRareData::cachedOwnKeysIgnoringSentinel const): Deleted.
(JSC::StructureRareData::cachedOwnKeysConcurrently const): Deleted.
(JSC::StructureRareData::setCachedOwnKeys): Deleted.

Location:
trunk
Files:
12 added
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r265907 r265934  
     12020-08-19  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Add Object.getOwnPropertyNames caching as it is done for Object.keys, and accelerate Object.getOwnPropertyDescriptor
     4        https://bugs.webkit.org/show_bug.cgi?id=215666
     5
     6        Reviewed by Saam Barati.
     7
     8        * microbenchmarks/get-own-property-descriptor.js: Added.
     9        (object.get test):
     10        (object.set test):
     11        * stress/get-own-property-names-bad-time.js: Added.
     12        (shouldBe):
     13        (test):
     14        * stress/get-own-property-names-dfg.js: Added.
     15        (shouldBe):
     16        (test):
     17        * stress/keys-bad-time.js: Added.
     18        (shouldBe):
     19        (test):
     20        * stress/keys-dfg.js: Added.
     21        (shouldBe):
     22        (test):
     23        * stress/object-get-own-property-names-cached-zero.js: Added.
     24        (shouldBe):
     25        (test):
     26        * stress/object-get-own-property-names-changed-attribute.js: Added.
     27        (shouldBe):
     28        (test):
     29        * stress/object-get-own-property-names-changed-index.js: Added.
     30        (shouldBe):
     31        (test):
     32        * stress/object-get-own-property-names-changed.js: Added.
     33        (shouldBe):
     34        (test):
     35        * stress/object-get-own-property-names-indexed-non-cache.js: Added.
     36        (shouldBe):
     37        (test):
     38        * stress/object-get-own-property-names-overrides-get-property-names.js: Added.
     39        (shouldBe):
     40        (test):
     41        (noInline):
     42        * stress/object-keys-cache.js: Added.
     43        (shouldBe):
     44        (symbol):
     45
    1462020-08-19  Alexey Shvayka  <shvaikalesh@gmail.com>
    247
  • trunk/Source/JavaScriptCore/ChangeLog

    r265907 r265934  
     12020-08-19  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Add Object.getOwnPropertyNames caching as it is done for Object.keys, and accelerate Object.getOwnPropertyDescriptor
     4        https://bugs.webkit.org/show_bug.cgi?id=215666
     5
     6        Reviewed by Saam Barati.
     7
     8        Object.getOwnPropertyNames is immutable for Structure if structure meets some conditions. And we have optimization for Object.keys.
     9        This patch wires existing caching mechanism for Object.keys to Object.getOwnPropertyNames so that Object.getOwnPropertyNames has
     10        full support of caching & inlined code in DFG / FTL.
     11
     12        We also pre-bake structure for the result of Object.getOwnPropertyDescriptor so that we do not need to perform hash table lookup every
     13        time we create an object for Object.getOwnPropertyDescriptor. This makes Object.getOwnPropertyDescriptor 2x faster from the microbenchmark.
     14
     15        The above two optimization makes Speedometer2/Inferno-TodoMVC 7% faster, and it also optimizes Speedometer2/EmberJS-Debug by 5%.
     16        In total, we can get 0.7 - 1.0% progression in Speedometer2.
     17
     18        * dfg/DFGAbstractInterpreterInlines.h:
     19        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     20        * dfg/DFGByteCodeParser.cpp:
     21        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
     22        * dfg/DFGClobberize.h:
     23        (JSC::DFG::clobberize):
     24        * dfg/DFGConstantFoldingPhase.cpp:
     25        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     26        * dfg/DFGDoesGC.cpp:
     27        (JSC::DFG::doesGC):
     28        * dfg/DFGFixupPhase.cpp:
     29        (JSC::DFG::FixupPhase::fixupNode):
     30        * dfg/DFGNodeType.h:
     31        * dfg/DFGOperations.cpp:
     32        * dfg/DFGOperations.h:
     33        * dfg/DFGPredictionPropagationPhase.cpp:
     34        * dfg/DFGSafeToExecute.h:
     35        (JSC::DFG::safeToExecute):
     36        * dfg/DFGSpeculativeJIT.cpp:
     37        (JSC::DFG::SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames):
     38        (JSC::DFG::SpeculativeJIT::compileObjectKeys): Deleted.
     39        * dfg/DFGSpeculativeJIT.h:
     40        * dfg/DFGSpeculativeJIT32_64.cpp:
     41        (JSC::DFG::SpeculativeJIT::compile):
     42        * dfg/DFGSpeculativeJIT64.cpp:
     43        (JSC::DFG::SpeculativeJIT::compile):
     44        * ftl/FTLAbstractHeapRepository.h:
     45        * ftl/FTLCapabilities.cpp:
     46        (JSC::FTL::canCompile):
     47        * ftl/FTLLowerDFGToB3.cpp:
     48        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     49        (JSC::FTL::DFG::LowerDFGToB3::compileObjectKeysOrObjectGetOwnPropertyNames):
     50        (JSC::FTL::DFG::LowerDFGToB3::compileObjectKeys): Deleted.
     51        * runtime/Intrinsic.cpp:
     52        (JSC::intrinsicName):
     53        * runtime/Intrinsic.h:
     54        * runtime/IteratorOperations.cpp:
     55        * runtime/JSGlobalObject.cpp:
     56        (JSC::JSGlobalObject::init):
     57        (JSC::JSGlobalObject::visitChildren):
     58        * runtime/JSGlobalObject.h:
     59        (JSC::JSGlobalObject::dataPropertyDescriptorObjectStructure const):
     60        (JSC::JSGlobalObject::accessorPropertyDescriptorObjectStructure const):
     61        * runtime/JSGlobalObjectFunctions.cpp:
     62        (JSC::globalFuncOwnKeys):
     63        * runtime/ObjectConstructor.cpp:
     64        (JSC::objectConstructorGetOwnPropertyNames):
     65        (JSC::objectConstructorGetOwnPropertySymbols):
     66        (JSC::objectConstructorKeys):
     67        (JSC::ownPropertyKeys):
     68        (JSC::constructObjectFromPropertyDescriptorSlow):
     69        * runtime/ObjectConstructor.h:
     70        (JSC::createDataPropertyDescriptorObjectStructure):
     71        (JSC::createAccessorPropertyDescriptorObjectStructure):
     72        (JSC::constructObjectFromPropertyDescriptor):
     73        * runtime/ReflectObject.cpp:
     74        (JSC::reflectObjectOwnKeys):
     75        * runtime/Structure.cpp:
     76        (JSC::Structure::canCachePropertyNameEnumerator const):
     77        * runtime/Structure.h:
     78        * runtime/StructureInlines.h:
     79        (JSC::Structure::setCachedPropertyNames):
     80        (JSC::Structure::cachedPropertyNames const):
     81        (JSC::Structure::cachedPropertyNamesIgnoringSentinel const):
     82        (JSC::Structure::canCacheOwnPropertyNames const):
     83        (JSC::Structure::setCachedOwnKeys): Deleted.
     84        (JSC::Structure::cachedOwnKeys const): Deleted.
     85        (JSC::Structure::cachedOwnKeysIgnoringSentinel const): Deleted.
     86        (JSC::Structure::canCacheOwnKeys const): Deleted.
     87        * runtime/StructureRareData.cpp:
     88        (JSC::StructureRareData::visitChildren):
     89        * runtime/StructureRareData.h:
     90        * runtime/StructureRareDataInlines.h:
     91        (JSC::StructureRareData::cachedPropertyNames const):
     92        (JSC::StructureRareData::cachedPropertyNamesIgnoringSentinel const):
     93        (JSC::StructureRareData::cachedPropertyNamesConcurrently const):
     94        (JSC::StructureRareData::setCachedPropertyNames):
     95        (JSC::StructureRareData::cachedOwnKeys const): Deleted.
     96        (JSC::StructureRareData::cachedOwnKeysIgnoringSentinel const): Deleted.
     97        (JSC::StructureRareData::cachedOwnKeysConcurrently const): Deleted.
     98        (JSC::StructureRareData::setCachedOwnKeys): Deleted.
     99
    11002020-08-19  Alexey Shvayka  <shvaikalesh@gmail.com>
    2101
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r265907 r265934  
    30663066    }
    30673067
     3068    case ObjectGetOwnPropertyNames:
    30683069    case ObjectKeys: {
    30693070        if (node->child1().useKind() == ObjectUse) {
     
    30723073                RegisteredStructure structure = structureSet.onlyStructure();
    30733074                if (auto* rareData = structure->rareDataConcurrently()) {
    3074                     if (!!rareData->cachedOwnKeysConcurrently()) {
     3075                    if (!!rareData->cachedPropertyNamesConcurrently(node->op() == ObjectGetOwnPropertyNames ? CachedPropertyNamesKind::GetOwnPropertyNames : CachedPropertyNamesKind::Keys)) {
    30753076                        if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
    30763077                            m_state.setShouldTryConstantFolding(true);
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r265907 r265934  
    29462946            insertChecks();
    29472947            setResult(addToGraph(ObjectKeys, get(virtualRegisterForArgumentIncludingThis(1, registerOffset))));
     2948            return true;
     2949        }
     2950
     2951        case ObjectGetOwnPropertyNamesIntrinsic: {
     2952            if (argumentCountIncludingThis < 2)
     2953                return false;
     2954
     2955            insertChecks();
     2956            setResult(addToGraph(ObjectGetOwnPropertyNames, get(virtualRegisterForArgumentIncludingThis(1, registerOffset))));
    29482957            return true;
    29492958        }
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r265907 r265934  
    719719    case StringValueOf:
    720720    case ObjectKeys:
     721    case ObjectGetOwnPropertyNames:
    721722        clobberTop();
    722723        return;
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r263134 r265934  
    935935            }
    936936
     937            case ObjectGetOwnPropertyNames:
    937938            case ObjectKeys: {
    938939                if (node->child1().useKind() == ObjectUse) {
     
    941942                        RegisteredStructure structure = structureSet.onlyStructure();
    942943                        if (auto* rareData = structure->rareDataConcurrently()) {
    943                             if (auto* immutableButterfly = rareData->cachedOwnKeysConcurrently()) {
     944                            if (auto* immutableButterfly = rareData->cachedPropertyNamesConcurrently(node->op() == ObjectGetOwnPropertyNames ? CachedPropertyNamesKind::GetOwnPropertyNames : CachedPropertyNamesKind::Keys)) {
    944945                                if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
    945946                                    node->convertToNewArrayBuffer(m_graph.freeze(immutableButterfly));
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r265907 r265934  
    354354    case ObjectCreate:
    355355    case ObjectKeys:
     356    case ObjectGetOwnPropertyNames:
    356357    case AllocatePropertyStorage:
    357358    case ReallocatePropertyStorage:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r265907 r265934  
    19321932        }
    19331933
     1934        case ObjectGetOwnPropertyNames:
    19341935        case ObjectKeys: {
    19351936            if (node->child1()->shouldSpeculateObject()) {
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r265907 r265934  
    287287    macro(ObjectCreate, NodeMustGenerate | NodeResultJS) \
    288288    macro(ObjectKeys, NodeMustGenerate | NodeResultJS) \
     289    macro(ObjectGetOwnPropertyNames, NodeMustGenerate | NodeResultJS) \
    289290    \
    290291    /* Atomics object functions. */\
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r265907 r265934  
    248248    RETURN_IF_EXCEPTION(scope, nullptr);
    249249    scope.release();
    250     return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);
     250    return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude, CachedPropertyNamesKind::Keys);
    251251}
    252252
     
    256256    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
    257257    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
    258     return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);
     258    return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude, CachedPropertyNamesKind::Keys);
     259}
     260
     261JSArray* JIT_OPERATION operationObjectGetOwnPropertyNames(JSGlobalObject* globalObject, EncodedJSValue encodedObject)
     262{
     263    VM& vm = globalObject->vm();
     264    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     265    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     266    auto scope = DECLARE_THROW_SCOPE(vm);
     267
     268    JSObject* object = JSValue::decode(encodedObject).toObject(globalObject);
     269    RETURN_IF_EXCEPTION(scope, nullptr);
     270    scope.release();
     271    return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include, CachedPropertyNamesKind::GetOwnPropertyNames);
     272}
     273
     274JSArray* JIT_OPERATION operationObjectGetOwnPropertyNamesObject(JSGlobalObject* globalObject, JSObject* object)
     275{
     276    VM& vm = globalObject->vm();
     277    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     278    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     279    return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include, CachedPropertyNamesKind::GetOwnPropertyNames);
    259280}
    260281
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r265907 r265934  
    5050JSArray* JIT_OPERATION operationObjectKeys(JSGlobalObject*, EncodedJSValue) WTF_INTERNAL;
    5151JSArray* JIT_OPERATION operationObjectKeysObject(JSGlobalObject*, JSObject*) WTF_INTERNAL;
     52JSArray* JIT_OPERATION operationObjectGetOwnPropertyNames(JSGlobalObject*, EncodedJSValue) WTF_INTERNAL;
     53JSArray* JIT_OPERATION operationObjectGetOwnPropertyNamesObject(JSGlobalObject*, JSObject*) WTF_INTERNAL;
    5254JSCell* JIT_OPERATION operationObjectCreate(JSGlobalObject*, EncodedJSValue) WTF_INTERNAL;
    5355JSCell* JIT_OPERATION operationObjectCreateObject(JSGlobalObject*, JSObject*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r265907 r265934  
    11121112        case CreateRest:
    11131113        case NewArrayBuffer:
    1114         case ObjectKeys: {
     1114        case ObjectKeys:
     1115        case ObjectGetOwnPropertyNames: {
    11151116            setPrediction(SpecArray);
    11161117            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r265907 r265934  
    496496    case ObjectCreate:
    497497    case ObjectKeys:
     498    case ObjectGetOwnPropertyNames:
    498499    case SetLocal:
    499500    case SetCallee:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r265907 r265934  
    1318013180}
    1318113181
    13182 void SpeculativeJIT::compileObjectKeys(Node* node)
     13182void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node)
    1318313183{
    1318413184    switch (node->child1().useKind()) {
     
    1320813208            slowCases.append(m_jit.branch32(CCallHelpers::Equal, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(vm().structureStructure->structureID()))));
    1320913209
    13210             m_jit.loadPtr(CCallHelpers::Address(scratchGPR, StructureRareData::offsetOfCachedOwnKeys()), scratchGPR);
    13211 
    13212             ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedOwnKeysSentinel()) == 1);
    13213             slowCases.append(m_jit.branchPtr(CCallHelpers::BelowOrEqual, scratchGPR, TrustedImmPtr(bitwise_cast<void*>(StructureRareData::cachedOwnKeysSentinel()))));
     13210            m_jit.loadPtr(CCallHelpers::Address(scratchGPR, StructureRareData::offsetOfCachedPropertyNames(node->op() == ObjectKeys ? CachedPropertyNamesKind::Keys : CachedPropertyNamesKind::GetOwnPropertyNames)), scratchGPR);
     13211
     13212            ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedPropertyNamesSentinel()) == 1);
     13213            slowCases.append(m_jit.branchPtr(CCallHelpers::BelowOrEqual, scratchGPR, TrustedImmPtr(bitwise_cast<void*>(StructureRareData::cachedPropertyNamesSentinel()))));
    1321413214
    1321513215            MacroAssembler::JumpList slowButArrayBufferCases;
     
    1322513225            addSlowPathGenerator(slowPathCall(slowButArrayBufferCases, this, operationNewArrayBuffer, resultGPR, &vm(), arrayStructure, scratch3GPR));
    1322613226
    13227             addSlowPathGenerator(slowPathCall(slowCases, this, operationObjectKeysObject, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectGPR));
     13227            addSlowPathGenerator(slowPathCall(slowCases, this, node->op() == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectGPR));
    1322813228
    1322913229            cellResult(resultGPR, node);
     
    1324013240        GPRFlushedCallResult result(this);
    1324113241        GPRReg resultGPR = result.gpr();
    13242         callOperation(operationObjectKeysObject, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectGPR);
     13242        callOperation(node->op() == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectGPR);
    1324313243        m_jit.exceptionCheck();
    1324413244
     
    1325513255        GPRFlushedCallResult result(this);
    1325613256        GPRReg resultGPR = result.gpr();
    13257         callOperation(operationObjectKeys, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectRegs);
     13257        callOperation(node->op() == ObjectKeys ? operationObjectKeys : operationObjectGetOwnPropertyNames, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectRegs);
    1325813258        m_jit.exceptionCheck();
    1325913259
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r265907 r265934  
    14671467    void compileNewTypedArray(Node*);
    14681468    void compileToThis(Node*);
    1469     void compileObjectKeys(Node*);
     1469    void compileObjectKeysOrObjectGetOwnPropertyNames(Node*);
    14701470    void compileObjectCreate(Node*);
    14711471    void compileCreateThis(Node*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r265907 r265934  
    32333233    }
    32343234
    3235     case ObjectKeys: {
    3236         compileObjectKeys(node);
     3235    case ObjectKeys:
     3236    case ObjectGetOwnPropertyNames: {
     3237        compileObjectKeysOrObjectGetOwnPropertyNames(node);
    32373238        break;
    32383239    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r265907 r265934  
    38193819    }
    38203820
    3821     case ObjectKeys: {
    3822         compileObjectKeys(node);
     3821    case ObjectKeys:
     3822    case ObjectGetOwnPropertyNames: {
     3823        compileObjectKeysOrObjectGetOwnPropertyNames(node);
    38233824        break;
    38243825    }
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r263470 r265934  
    147147    macro(Structure_prototype, Structure::prototypeOffset()) \
    148148    macro(Structure_structureID, Structure::structureIDOffset()) \
    149     macro(StructureRareData_cachedOwnKeys, StructureRareData::offsetOfCachedOwnKeys()) \
     149    macro(StructureRareData_cachedKeys, StructureRareData::offsetOfCachedPropertyNames(CachedPropertyNamesKind::Keys)) \
     150    macro(StructureRareData_cachedGetOwnPropertyNames, StructureRareData::offsetOfCachedPropertyNames(CachedPropertyNamesKind::GetOwnPropertyNames)) \
    150151    macro(HashMapImpl_capacity, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfCapacity()) \
    151152    macro(HashMapImpl_buffer,  HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfBuffer()) \
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r265907 r265934  
    223223    case ObjectCreate:
    224224    case ObjectKeys:
     225    case ObjectGetOwnPropertyNames:
    225226    case MakeRope:
    226227    case NewArrayWithSize:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r265907 r265934  
    10791079            break;
    10801080        case ObjectKeys:
    1081             compileObjectKeys();
     1081        case ObjectGetOwnPropertyNames:
     1082            compileObjectKeysOrObjectGetOwnPropertyNames();
    10821083            break;
    10831084        case NewObject:
     
    65736574    }
    65746575
    6575     void compileObjectKeys()
     6576    void compileObjectKeysOrObjectGetOwnPropertyNames()
    65766577    {
    65776578        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
     6579        NodeType op = m_node->op();
    65786580        switch (m_node->child1().useKind()) {
    65796581        case ObjectUse: {
     
    65976599
    65986600                m_out.appendTo(rareDataCase, useCacheCase);
    6599                 ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedOwnKeysSentinel()) == 1);
    6600                 LValue cachedOwnKeys = m_out.loadPtr(previousOrRareData, m_heaps.StructureRareData_cachedOwnKeys);
    6601                 m_out.branch(m_out.belowOrEqual(cachedOwnKeys, m_out.constIntPtr(bitwise_cast<void*>(StructureRareData::cachedOwnKeysSentinel()))), unsure(slowCase), unsure(useCacheCase));
     6601                ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedPropertyNamesSentinel()) == 1);
     6602                LValue cached = m_out.loadPtr(previousOrRareData, op == ObjectKeys ? m_heaps.StructureRareData_cachedKeys : m_heaps.StructureRareData_cachedGetOwnPropertyNames);
     6603                m_out.branch(m_out.belowOrEqual(cached, m_out.constIntPtr(bitwise_cast<void*>(StructureRareData::cachedPropertyNamesSentinel()))), unsure(slowCase), unsure(useCacheCase));
    66026604
    66036605                m_out.appendTo(useCacheCase, slowButArrayBufferCase);
    66046606                RegisteredStructure arrayStructure = m_graph.registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(CopyOnWriteArrayWithContiguous));
    6605                 LValue fastArray = allocateObject<JSArray>(arrayStructure, m_out.addPtr(cachedOwnKeys, JSImmutableButterfly::offsetOfData()), slowButArrayBufferCase);
     6607                LValue fastArray = allocateObject<JSArray>(arrayStructure, m_out.addPtr(cached, JSImmutableButterfly::offsetOfData()), slowButArrayBufferCase);
    66066608                ValueFromBlock fastResult = m_out.anchor(fastArray);
    66076609                m_out.jump(continuation);
    66086610
    66096611                m_out.appendTo(slowButArrayBufferCase, slowCase);
    6610                 LValue slowArray = vmCall(Int64, operationNewArrayBuffer, m_vmValue, weakStructure(arrayStructure), cachedOwnKeys);
     6612                LValue slowArray = vmCall(Int64, operationNewArrayBuffer, m_vmValue, weakStructure(arrayStructure), cached);
    66116613                ValueFromBlock slowButArrayBufferResult = m_out.anchor(slowArray);
    66126614                m_out.jump(continuation);
     
    66176619                    [=, &vm] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
    66186620                        return createLazyCallGenerator(vm,
    6619                             operationObjectKeysObject, locations[0].directGPR(), globalObject, locations[1].directGPR());
     6621                            op == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, locations[0].directGPR(), globalObject, locations[1].directGPR());
    66206622                    },
    66216623                    object);
     
    66276629                break;
    66286630            }
    6629             setJSValue(vmCall(Int64, operationObjectKeysObject, weakPointer(globalObject), lowObject(m_node->child1())));
     6631            setJSValue(vmCall(Int64, op == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, weakPointer(globalObject), lowObject(m_node->child1())));
    66306632            break;
    66316633        }
    66326634        case UntypedUse:
    6633             setJSValue(vmCall(Int64, operationObjectKeys, weakPointer(globalObject), lowJSValue(m_node->child1())));
     6635            setJSValue(vmCall(Int64, op == ObjectKeys ? operationObjectKeys : operationObjectGetOwnPropertyNames, weakPointer(globalObject), lowJSValue(m_node->child1())));
    66346636            break;
    66356637        default:
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.cpp

    r260323 r265934  
    160160    case ObjectCreateIntrinsic:
    161161        return "ObjectCreateIntrinsic";
     162    case ObjectGetOwnPropertyNamesIntrinsic:
     163        return "ObjectGetOwnPropertyNamesIntrinsic";
    162164    case ObjectGetPrototypeOfIntrinsic:
    163165        return "ObjectGetPrototypeOfIntrinsic";
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.h

    r260417 r265934  
    9696    RegExpMatchFastIntrinsic,
    9797    ObjectCreateIntrinsic,
     98    ObjectGetOwnPropertyNamesIntrinsic,
    9899    ObjectGetPrototypeOfIntrinsic,
    99100    ObjectIsIntrinsic,
  • trunk/Source/JavaScriptCore/runtime/IteratorOperations.cpp

    r262567 r265934  
    128128}
    129129
    130 static const PropertyOffset valuePropertyOffset = 0;
    131 static const PropertyOffset donePropertyOffset = 1;
     130static constexpr PropertyOffset valuePropertyOffset = 0;
     131static constexpr PropertyOffset donePropertyOffset = 1;
    132132
    133133Structure* createIteratorResultObjectStructure(VM& vm, JSGlobalObject& globalObject)
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r264736 r265934  
    971971            init.set(createIteratorResultObjectStructure(init.vm, *init.owner));
    972972        });
     973    m_dataPropertyDescriptorObjectStructure.initLater(
     974        [] (const Initializer<Structure>& init) {
     975            init.set(createDataPropertyDescriptorObjectStructure(init.vm, *init.owner));
     976        });
     977    m_accessorPropertyDescriptorObjectStructure.initLater(
     978        [] (const Initializer<Structure>& init) {
     979            init.set(createAccessorPropertyDescriptorObjectStructure(init.vm, *init.owner));
     980        });
    973981   
    974982    m_evalFunction.initLater(
     
    19361944    visitor.append(thisObject->m_setIteratorStructure);
    19371945    thisObject->m_iteratorResultObjectStructure.visit(visitor);
     1946    thisObject->m_dataPropertyDescriptorObjectStructure.visit(visitor);
     1947    thisObject->m_accessorPropertyDescriptorObjectStructure.visit(visitor);
    19381948    visitor.append(thisObject->m_regExpMatchesArrayStructure);
    19391949    thisObject->m_moduleRecordStructure.visit(visitor);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r264639 r265934  
    395395    WriteBarrier<Structure> m_setIteratorStructure;
    396396    LazyProperty<JSGlobalObject, Structure> m_iteratorResultObjectStructure;
     397    LazyProperty<JSGlobalObject, Structure> m_dataPropertyDescriptorObjectStructure;
     398    LazyProperty<JSGlobalObject, Structure> m_accessorPropertyDescriptorObjectStructure;
    397399    WriteBarrier<Structure> m_regExpMatchesArrayStructure;
    398400    LazyProperty<JSGlobalObject, Structure> m_moduleRecordStructure;
     
    785787    Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
    786788    Structure* iteratorResultObjectStructure() const { return m_iteratorResultObjectStructure.get(this); }
     789    Structure* dataPropertyDescriptorObjectStructure() const { return m_dataPropertyDescriptorObjectStructure.get(this); }
     790    Structure* accessorPropertyDescriptorObjectStructure() const { return m_accessorPropertyDescriptorObjectStructure.get(this); }
    787791    Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
    788792    Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(this); }
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r263905 r265934  
    831831    JSObject* object = callFrame->argument(0).toObject(globalObject);
    832832    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    833     RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include)));
     833    RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include, WTF::nullopt)));
    834834}
    835835
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r263035 r265934  
    6363  getOwnPropertyDescriptor  objectConstructorGetOwnPropertyDescriptor   DontEnum|Function 2
    6464  getOwnPropertyDescriptors objectConstructorGetOwnPropertyDescriptors  DontEnum|Function 1
    65   getOwnPropertyNames       objectConstructorGetOwnPropertyNames        DontEnum|Function 1
     65  getOwnPropertyNames       objectConstructorGetOwnPropertyNames        DontEnum|Function 1 ObjectGetOwnPropertyNamesIntrinsic
    6666  getOwnPropertySymbols     objectConstructorGetOwnPropertySymbols      DontEnum|Function 1
    6767  keys                      objectConstructorKeys                       DontEnum|Function 1 ObjectKeysIntrinsic
     
    236236}
    237237
    238 // FIXME: Use the enumeration cache.
    239238EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(JSGlobalObject* globalObject, CallFrame* callFrame)
    240239{
     
    243242    JSObject* object = callFrame->argument(0).toObject(globalObject);
    244243    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    245     RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include)));
     244    RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include, CachedPropertyNamesKind::GetOwnPropertyNames)));
    246245}
    247246
     
    253252    JSObject* object = callFrame->argument(0).toObject(globalObject);
    254253    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    255     RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::Symbols, DontEnumPropertiesMode::Include)));
     254    RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::Symbols, DontEnumPropertiesMode::Include, WTF::nullopt)));
    256255}
    257256
     
    262261    JSObject* object = callFrame->argument(0).toObject(globalObject);
    263262    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    264     RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude)));
     263    RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude, CachedPropertyNamesKind::Keys)));
    265264}
    266265
     
    887886}
    888887
    889 JSArray* ownPropertyKeys(JSGlobalObject* globalObject, JSObject* object, PropertyNameMode propertyNameMode, DontEnumPropertiesMode dontEnumPropertiesMode)
    890 {
    891     VM& vm = globalObject->vm();
    892     auto scope = DECLARE_THROW_SCOPE(vm);
    893 
    894     bool isObjectKeys = propertyNameMode == PropertyNameMode::Strings && dontEnumPropertiesMode == DontEnumPropertiesMode::Exclude;
    895     // We attempt to look up own property keys cache in Object.keys case.
    896     if (isObjectKeys) {
     888JSArray* ownPropertyKeys(JSGlobalObject* globalObject, JSObject* object, PropertyNameMode propertyNameMode, DontEnumPropertiesMode dontEnumPropertiesMode, Optional<CachedPropertyNamesKind> kind)
     889{
     890    VM& vm = globalObject->vm();
     891    auto scope = DECLARE_THROW_SCOPE(vm);
     892
     893    // We attempt to look up own property keys cache in Object.keys / Object.getOwnPropertyNames cases.
     894    if (kind) {
    897895        if (LIKELY(!globalObject->isHavingABadTime())) {
    898             if (auto* immutableButterfly = object->structure(vm)->cachedOwnKeys()) {
     896            if (auto* immutableButterfly = object->structure(vm)->cachedPropertyNames(kind.value())) {
    899897                Structure* arrayStructure = globalObject->originalArrayStructureForIndexingType(immutableButterfly->indexingMode());
    900898                return JSArray::createWithButterfly(vm, nullptr, arrayStructure, immutableButterfly->toButterfly());
     
    911909        if (properties.size() < MIN_SPARSE_ARRAY_INDEX) {
    912910            if (LIKELY(!globalObject->isHavingABadTime())) {
    913                 if (isObjectKeys) {
     911                if (kind) {
    914912                    Structure* structure = object->structure(vm);
    915                     if (structure->canCacheOwnKeys()) {
    916                         auto* cachedButterfly = structure->cachedOwnKeysIgnoringSentinel();
    917                         if (cachedButterfly == StructureRareData::cachedOwnKeysSentinel()) {
     913                    if (structure->canCacheOwnPropertyNames()) {
     914                        auto* cachedButterfly = structure->cachedPropertyNamesIgnoringSentinel(kind.value());
     915                        if (cachedButterfly == StructureRareData::cachedPropertyNamesSentinel()) {
    918916                            size_t numProperties = properties.size();
    919917                            auto* newButterfly = JSImmutableButterfly::create(vm, CopyOnWriteArrayWithContiguous, numProperties);
     
    924922                            }
    925923
    926                             structure->setCachedOwnKeys(vm, newButterfly);
     924                            structure->setCachedPropertyNames(vm, kind.value(), newButterfly);
    927925                            Structure* arrayStructure = globalObject->originalArrayStructureForIndexingType(newButterfly->indexingMode());
    928926                            return JSArray::createWithButterfly(vm, nullptr, arrayStructure, newButterfly->toButterfly());
     
    930928
    931929                        if (cachedButterfly == nullptr)
    932                             structure->setCachedOwnKeys(vm, StructureRareData::cachedOwnKeysSentinel());
     930                            structure->setCachedPropertyNames(vm, kind.value(), StructureRareData::cachedPropertyNamesSentinel());
    933931                    }
    934932                }
     
    10121010}
    10131011
     1012JSObject* constructObjectFromPropertyDescriptorSlow(JSGlobalObject* globalObject, const PropertyDescriptor& descriptor)
     1013{
     1014    VM& vm = getVM(globalObject);
     1015
     1016    JSObject* result = constructEmptyObject(globalObject);
     1017
     1018    if (descriptor.value())
     1019        result->putDirect(vm, vm.propertyNames->value, descriptor.value());
     1020    if (descriptor.writablePresent())
     1021        result->putDirect(vm, vm.propertyNames->writable, jsBoolean(descriptor.writable()));
     1022    if (descriptor.getterPresent())
     1023        result->putDirect(vm, vm.propertyNames->get, descriptor.getter());
     1024    if (descriptor.setterPresent())
     1025        result->putDirect(vm, vm.propertyNames->set, descriptor.setter());
     1026    if (descriptor.enumerablePresent())
     1027        result->putDirect(vm, vm.propertyNames->enumerable, jsBoolean(descriptor.enumerable()));
     1028    if (descriptor.configurablePresent())
     1029        result->putDirect(vm, vm.propertyNames->configurable, jsBoolean(descriptor.configurable()));
     1030
     1031    return result;
     1032}
     1033
    10141034} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h

    r260447 r265934  
    9090}
    9191
     92JS_EXPORT_PRIVATE JSObject* constructObjectFromPropertyDescriptorSlow(JSGlobalObject*, const PropertyDescriptor&);
     93
     94static constexpr PropertyOffset dataPropertyDescriptorValuePropertyOffset = 0;
     95static constexpr PropertyOffset dataPropertyDescriptorWritablePropertyOffset = 1;
     96static constexpr PropertyOffset dataPropertyDescriptorEnumerablePropertyOffset = 2;
     97static constexpr PropertyOffset dataPropertyDescriptorConfigurablePropertyOffset = 3;
     98
     99static constexpr PropertyOffset accessorPropertyDescriptorGetPropertyOffset = 0;
     100static constexpr PropertyOffset accessorPropertyDescriptorSetPropertyOffset = 1;
     101static constexpr PropertyOffset accessorPropertyDescriptorEnumerablePropertyOffset = 2;
     102static constexpr PropertyOffset accessorPropertyDescriptorConfigurablePropertyOffset = 3;
     103
     104inline Structure* createDataPropertyDescriptorObjectStructure(VM& vm, JSGlobalObject& globalObject)
     105{
     106    Structure* structure = vm.structureCache.emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), JSFinalObject::defaultInlineCapacity());
     107    PropertyOffset offset;
     108    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->value, 0, offset);
     109    RELEASE_ASSERT(offset == dataPropertyDescriptorValuePropertyOffset);
     110    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->writable, 0, offset);
     111    RELEASE_ASSERT(offset == dataPropertyDescriptorWritablePropertyOffset);
     112    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->enumerable, 0, offset);
     113    RELEASE_ASSERT(offset == dataPropertyDescriptorEnumerablePropertyOffset);
     114    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->configurable, 0, offset);
     115    RELEASE_ASSERT(offset == dataPropertyDescriptorConfigurablePropertyOffset);
     116    return structure;
     117}
     118
     119inline Structure* createAccessorPropertyDescriptorObjectStructure(VM& vm, JSGlobalObject& globalObject)
     120{
     121    Structure* structure = vm.structureCache.emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), JSFinalObject::defaultInlineCapacity());
     122    PropertyOffset offset;
     123    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->get, 0, offset);
     124    RELEASE_ASSERT(offset == accessorPropertyDescriptorGetPropertyOffset);
     125    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->set, 0, offset);
     126    RELEASE_ASSERT(offset == accessorPropertyDescriptorSetPropertyOffset);
     127    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->enumerable, 0, offset);
     128    RELEASE_ASSERT(offset == accessorPropertyDescriptorEnumerablePropertyOffset);
     129    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->configurable, 0, offset);
     130    RELEASE_ASSERT(offset == accessorPropertyDescriptorConfigurablePropertyOffset);
     131    return structure;
     132}
     133
    92134// https://tc39.es/ecma262/#sec-frompropertydescriptor
    93135inline JSObject* constructObjectFromPropertyDescriptor(JSGlobalObject* globalObject, const PropertyDescriptor& descriptor)
    94136{
    95137    VM& vm = getVM(globalObject);
    96     JSObject* result = constructEmptyObject(globalObject);
    97138
    98     if (descriptor.value())
    99         result->putDirect(vm, vm.propertyNames->value, descriptor.value());
    100     if (descriptor.writablePresent())
    101         result->putDirect(vm, vm.propertyNames->writable, jsBoolean(descriptor.writable()));
    102     if (descriptor.getterPresent())
    103         result->putDirect(vm, vm.propertyNames->get, descriptor.getter());
    104     if (descriptor.setterPresent())
    105         result->putDirect(vm, vm.propertyNames->set, descriptor.setter());
    106     if (descriptor.enumerablePresent())
    107         result->putDirect(vm, vm.propertyNames->enumerable, jsBoolean(descriptor.enumerable()));
    108     if (descriptor.configurablePresent())
    109         result->putDirect(vm, vm.propertyNames->configurable, jsBoolean(descriptor.configurable()));
     139    if (descriptor.enumerablePresent() && descriptor.configurablePresent()) {
     140        if (descriptor.value() && descriptor.writablePresent()) {
     141            JSObject* result = constructEmptyObject(vm, globalObject->dataPropertyDescriptorObjectStructure());
     142            result->putDirect(vm, dataPropertyDescriptorValuePropertyOffset, descriptor.value());
     143            result->putDirect(vm, dataPropertyDescriptorWritablePropertyOffset, jsBoolean(descriptor.writable()));
     144            result->putDirect(vm, dataPropertyDescriptorEnumerablePropertyOffset, jsBoolean(descriptor.enumerable()));
     145            result->putDirect(vm, dataPropertyDescriptorConfigurablePropertyOffset, jsBoolean(descriptor.configurable()));
     146            return result;
     147        }
    110148
    111     return result;
     149        if (descriptor.getterPresent() && descriptor.setterPresent()) {
     150            JSObject* result = constructEmptyObject(vm, globalObject->accessorPropertyDescriptorObjectStructure());
     151            result->putDirect(vm, accessorPropertyDescriptorGetPropertyOffset, descriptor.getter());
     152            result->putDirect(vm, accessorPropertyDescriptorSetPropertyOffset, descriptor.setter());
     153            result->putDirect(vm, accessorPropertyDescriptorEnumerablePropertyOffset, jsBoolean(descriptor.enumerable()));
     154            result->putDirect(vm, accessorPropertyDescriptorConfigurablePropertyOffset, jsBoolean(descriptor.configurable()));
     155            return result;
     156        }
     157    }
     158    return constructObjectFromPropertyDescriptorSlow(globalObject, descriptor);
    112159}
    113160
     
    117164JSValue objectConstructorGetOwnPropertyDescriptor(JSGlobalObject*, JSObject*, const Identifier&);
    118165JSValue objectConstructorGetOwnPropertyDescriptors(JSGlobalObject*, JSObject*);
    119 JSArray* ownPropertyKeys(JSGlobalObject*, JSObject*, PropertyNameMode, DontEnumPropertiesMode);
     166JSArray* ownPropertyKeys(JSGlobalObject*, JSObject*, PropertyNameMode, DontEnumPropertiesMode, Optional<CachedPropertyNamesKind>);
    120167bool toPropertyDescriptor(JSGlobalObject*, JSValue, PropertyDescriptor&);
    121168
  • trunk/Source/JavaScriptCore/runtime/ReflectObject.cpp

    r265034 r265934  
    223223    if (!target.isObject())
    224224        return JSValue::encode(throwTypeError(globalObject, scope, "Reflect.ownKeys requires the first argument be an object"_s));
    225     RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, jsCast<JSObject*>(target), PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include)));
     225    RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, jsCast<JSObject*>(target), PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include, WTF::nullopt)));
    226226}
    227227
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r265642 r265934  
    14101410bool Structure::canCachePropertyNameEnumerator(VM& vm) const
    14111411{
    1412     if (!this->canCacheOwnKeys())
     1412    if (!this->canCacheOwnPropertyNames())
    14131413        return false;
    14141414
     
    14211421            return true;
    14221422        Structure* structure = vm.getStructure(structureID);
    1423         if (!structure->canCacheOwnKeys())
     1423        if (!structure->canCacheOwnPropertyNames())
    14241424            return false;
    14251425        currentStructureID++;
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r265642 r265934  
    523523    bool canAccessPropertiesQuicklyForEnumeration() const;
    524524
    525     void setCachedOwnKeys(VM&, JSImmutableButterfly*);
    526     JSImmutableButterfly* cachedOwnKeys() const;
    527     JSImmutableButterfly* cachedOwnKeysIgnoringSentinel() const;
    528     bool canCacheOwnKeys() const;
     525    JSImmutableButterfly* cachedPropertyNames(CachedPropertyNamesKind) const;
     526    JSImmutableButterfly* cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind) const;
     527    void setCachedPropertyNames(VM&, CachedPropertyNamesKind, JSImmutableButterfly*);
     528    bool canCacheOwnPropertyNames() const;
    529529
    530530    void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode);
  • trunk/Source/JavaScriptCore/runtime/StructureInlines.h

    r265640 r265934  
    243243}
    244244
    245 inline void Structure::setCachedOwnKeys(VM& vm, JSImmutableButterfly* ownKeys)
    246 {
    247     ensureRareData(vm)->setCachedOwnKeys(vm, ownKeys);
    248 }
    249 
    250 inline JSImmutableButterfly* Structure::cachedOwnKeys() const
     245inline void Structure::setCachedPropertyNames(VM& vm, CachedPropertyNamesKind kind, JSImmutableButterfly* cached)
     246{
     247    ensureRareData(vm)->setCachedPropertyNames(vm, kind, cached);
     248}
     249
     250inline JSImmutableButterfly* Structure::cachedPropertyNames(CachedPropertyNamesKind kind) const
    251251{
    252252    if (!hasRareData())
    253253        return nullptr;
    254     return rareData()->cachedOwnKeys();
    255 }
    256 
    257 inline JSImmutableButterfly* Structure::cachedOwnKeysIgnoringSentinel() const
     254    return rareData()->cachedPropertyNames(kind);
     255}
     256
     257inline JSImmutableButterfly* Structure::cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind kind) const
    258258{
    259259    if (!hasRareData())
    260260        return nullptr;
    261     return rareData()->cachedOwnKeysIgnoringSentinel();
    262 }
    263 
    264 inline bool Structure::canCacheOwnKeys() const
     261    return rareData()->cachedPropertyNamesIgnoringSentinel(kind);
     262}
     263
     264inline bool Structure::canCacheOwnPropertyNames() const
    265265{
    266266    if (isDictionary())
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp

    r264736 r265934  
    7777    visitor.appendUnbarriered(thisObject->objectToStringValue());
    7878    visitor.append(thisObject->m_cachedPropertyNameEnumerator);
    79     auto* cachedOwnKeys = thisObject->m_cachedOwnKeys.unvalidatedGet();
    80     if (cachedOwnKeys != cachedOwnKeysSentinel())
    81         visitor.appendUnbarriered(cachedOwnKeys);
     79    for (unsigned index = 0; index < numberOfCachedPropertyNames; ++index) {
     80        auto* cached = thisObject->m_cachedPropertyNames[index].unvalidatedGet();
     81        if (cached != cachedPropertyNamesSentinel())
     82            visitor.appendUnbarriered(cached);
     83    }
    8284}
    8385
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.h

    r264736 r265934  
    3838class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;
    3939class ObjectToStringAdaptiveStructureWatchpoint;
     40enum class CachedPropertyNamesKind : uint8_t {
     41    Keys = 0,
     42    GetOwnPropertyNames,
     43};
     44static constexpr unsigned numberOfCachedPropertyNames = 2;
    4045
    4146class StructureRareData final : public JSCell {
     
    7580    void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
    7681
    77     JSImmutableButterfly* cachedOwnKeys() const;
    78     JSImmutableButterfly* cachedOwnKeysIgnoringSentinel() const;
    79     JSImmutableButterfly* cachedOwnKeysConcurrently() const;
    80     void setCachedOwnKeys(VM&, JSImmutableButterfly*);
     82    JSImmutableButterfly* cachedPropertyNames(CachedPropertyNamesKind) const;
     83    JSImmutableButterfly* cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind) const;
     84    JSImmutableButterfly* cachedPropertyNamesConcurrently(CachedPropertyNamesKind) const;
     85    void setCachedPropertyNames(VM&, CachedPropertyNamesKind, JSImmutableButterfly*);
    8186
    8287    Box<InlineWatchpointSet> copySharedPolyProtoWatchpoint() const { return m_polyProtoWatchpoint; }
     
    8590    bool hasSharedPolyProtoWatchpoint() const { return static_cast<bool>(m_polyProtoWatchpoint); }
    8691
    87     static JSImmutableButterfly* cachedOwnKeysSentinel() { return bitwise_cast<JSImmutableButterfly*>(static_cast<uintptr_t>(1)); }
     92    static JSImmutableButterfly* cachedPropertyNamesSentinel() { return bitwise_cast<JSImmutableButterfly*>(static_cast<uintptr_t>(1)); }
    8893
    89     static ptrdiff_t offsetOfCachedOwnKeys()
     94    static ptrdiff_t offsetOfCachedPropertyNames(CachedPropertyNamesKind kind)
    9095    {
    91         return OBJECT_OFFSETOF(StructureRareData, m_cachedOwnKeys);
     96        return OBJECT_OFFSETOF(StructureRareData, m_cachedPropertyNames) + sizeof(WriteBarrier<JSImmutableButterfly>) * static_cast<unsigned>(kind);
    9297    }
    9398
     
    110115    // https://bugs.webkit.org/show_bug.cgi?id=192659
    111116    WriteBarrier<JSPropertyNameEnumerator> m_cachedPropertyNameEnumerator;
    112     WriteBarrier<JSImmutableButterfly> m_cachedOwnKeys;
     117    WriteBarrier<JSImmutableButterfly> m_cachedPropertyNames[numberOfCachedPropertyNames] { };
    113118
    114119    typedef HashMap<PropertyOffset, RefPtr<WatchpointSet>, WTF::IntHash<PropertyOffset>, WTF::UnsignedWithZeroKeyHashTraits<PropertyOffset>> PropertyWatchpointMap;
  • trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h

    r259463 r265934  
    6363}
    6464
    65 inline JSImmutableButterfly* StructureRareData::cachedOwnKeys() const
     65inline JSImmutableButterfly* StructureRareData::cachedPropertyNames(CachedPropertyNamesKind kind) const
    6666{
    6767    ASSERT(!isCompilationThread());
    68     auto* butterfly = m_cachedOwnKeys.unvalidatedGet();
    69     if (butterfly == cachedOwnKeysSentinel())
     68    auto* butterfly = m_cachedPropertyNames[static_cast<unsigned>(kind)].unvalidatedGet();
     69    if (butterfly == cachedPropertyNamesSentinel())
    7070        return nullptr;
    7171    return butterfly;
    7272}
    7373
    74 inline JSImmutableButterfly* StructureRareData::cachedOwnKeysIgnoringSentinel() const
     74inline JSImmutableButterfly* StructureRareData::cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind kind) const
    7575{
    7676    ASSERT(!isCompilationThread());
    77     return m_cachedOwnKeys.unvalidatedGet();
     77    return m_cachedPropertyNames[static_cast<unsigned>(kind)].unvalidatedGet();
    7878}
    7979
    80 inline JSImmutableButterfly* StructureRareData::cachedOwnKeysConcurrently() const
     80inline JSImmutableButterfly* StructureRareData::cachedPropertyNamesConcurrently(CachedPropertyNamesKind kind) const
    8181{
    82     auto* butterfly = m_cachedOwnKeys.unvalidatedGet();
    83     if (butterfly == cachedOwnKeysSentinel())
     82    auto* butterfly = m_cachedPropertyNames[static_cast<unsigned>(kind)].unvalidatedGet();
     83    if (butterfly == cachedPropertyNamesSentinel())
    8484        return nullptr;
    8585    return butterfly;
    8686}
    8787
    88 inline void StructureRareData::setCachedOwnKeys(VM& vm, JSImmutableButterfly* butterfly)
     88inline void StructureRareData::setCachedPropertyNames(VM& vm, CachedPropertyNamesKind kind, JSImmutableButterfly* butterfly)
    8989{
    90     if (butterfly == cachedOwnKeysSentinel()) {
    91         m_cachedOwnKeys.setWithoutWriteBarrier(butterfly);
     90    if (butterfly == cachedPropertyNamesSentinel()) {
     91        m_cachedPropertyNames[static_cast<unsigned>(kind)].setWithoutWriteBarrier(butterfly);
    9292        return;
    9393    }
    9494
    9595    WTF::storeStoreFence();
    96     m_cachedOwnKeys.set(vm, this, butterfly);
     96    m_cachedPropertyNames[static_cast<unsigned>(kind)].set(vm, this, butterfly);
    9797}
    9898
Note: See TracChangeset for help on using the changeset viewer.