Changeset 265934 in webkit
- Timestamp:
- Aug 19, 2020 10:07:28 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r265907 r265934 1 2020-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 1 46 2020-08-19 Alexey Shvayka <shvaikalesh@gmail.com> 2 47 -
trunk/Source/JavaScriptCore/ChangeLog
r265907 r265934 1 2020-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 1 100 2020-08-19 Alexey Shvayka <shvaikalesh@gmail.com> 2 101 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r265907 r265934 3066 3066 } 3067 3067 3068 case ObjectGetOwnPropertyNames: 3068 3069 case ObjectKeys: { 3069 3070 if (node->child1().useKind() == ObjectUse) { … … 3072 3073 RegisteredStructure structure = structureSet.onlyStructure(); 3073 3074 if (auto* rareData = structure->rareDataConcurrently()) { 3074 if (!!rareData->cached OwnKeysConcurrently()) {3075 if (!!rareData->cachedPropertyNamesConcurrently(node->op() == ObjectGetOwnPropertyNames ? CachedPropertyNamesKind::GetOwnPropertyNames : CachedPropertyNamesKind::Keys)) { 3075 3076 if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) { 3076 3077 m_state.setShouldTryConstantFolding(true); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r265907 r265934 2946 2946 insertChecks(); 2947 2947 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)))); 2948 2957 return true; 2949 2958 } -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r265907 r265934 719 719 case StringValueOf: 720 720 case ObjectKeys: 721 case ObjectGetOwnPropertyNames: 721 722 clobberTop(); 722 723 return; -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r263134 r265934 935 935 } 936 936 937 case ObjectGetOwnPropertyNames: 937 938 case ObjectKeys: { 938 939 if (node->child1().useKind() == ObjectUse) { … … 941 942 RegisteredStructure structure = structureSet.onlyStructure(); 942 943 if (auto* rareData = structure->rareDataConcurrently()) { 943 if (auto* immutableButterfly = rareData->cached OwnKeysConcurrently()) {944 if (auto* immutableButterfly = rareData->cachedPropertyNamesConcurrently(node->op() == ObjectGetOwnPropertyNames ? CachedPropertyNamesKind::GetOwnPropertyNames : CachedPropertyNamesKind::Keys)) { 944 945 if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) { 945 946 node->convertToNewArrayBuffer(m_graph.freeze(immutableButterfly)); -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r265907 r265934 354 354 case ObjectCreate: 355 355 case ObjectKeys: 356 case ObjectGetOwnPropertyNames: 356 357 case AllocatePropertyStorage: 357 358 case ReallocatePropertyStorage: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r265907 r265934 1932 1932 } 1933 1933 1934 case ObjectGetOwnPropertyNames: 1934 1935 case ObjectKeys: { 1935 1936 if (node->child1()->shouldSpeculateObject()) { -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r265907 r265934 287 287 macro(ObjectCreate, NodeMustGenerate | NodeResultJS) \ 288 288 macro(ObjectKeys, NodeMustGenerate | NodeResultJS) \ 289 macro(ObjectGetOwnPropertyNames, NodeMustGenerate | NodeResultJS) \ 289 290 \ 290 291 /* Atomics object functions. */\ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r265907 r265934 248 248 RETURN_IF_EXCEPTION(scope, nullptr); 249 249 scope.release(); 250 return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude );250 return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude, CachedPropertyNamesKind::Keys); 251 251 } 252 252 … … 256 256 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 257 257 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 261 JSArray* 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 274 JSArray* 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); 259 280 } 260 281 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r265907 r265934 50 50 JSArray* JIT_OPERATION operationObjectKeys(JSGlobalObject*, EncodedJSValue) WTF_INTERNAL; 51 51 JSArray* JIT_OPERATION operationObjectKeysObject(JSGlobalObject*, JSObject*) WTF_INTERNAL; 52 JSArray* JIT_OPERATION operationObjectGetOwnPropertyNames(JSGlobalObject*, EncodedJSValue) WTF_INTERNAL; 53 JSArray* JIT_OPERATION operationObjectGetOwnPropertyNamesObject(JSGlobalObject*, JSObject*) WTF_INTERNAL; 52 54 JSCell* JIT_OPERATION operationObjectCreate(JSGlobalObject*, EncodedJSValue) WTF_INTERNAL; 53 55 JSCell* JIT_OPERATION operationObjectCreateObject(JSGlobalObject*, JSObject*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r265907 r265934 1112 1112 case CreateRest: 1113 1113 case NewArrayBuffer: 1114 case ObjectKeys: { 1114 case ObjectKeys: 1115 case ObjectGetOwnPropertyNames: { 1115 1116 setPrediction(SpecArray); 1116 1117 break; -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r265907 r265934 496 496 case ObjectCreate: 497 497 case ObjectKeys: 498 case ObjectGetOwnPropertyNames: 498 499 case SetLocal: 499 500 case SetCallee: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r265907 r265934 13180 13180 } 13181 13181 13182 void SpeculativeJIT::compileObjectKeys (Node* node)13182 void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node) 13183 13183 { 13184 13184 switch (node->child1().useKind()) { … … 13208 13208 slowCases.append(m_jit.branch32(CCallHelpers::Equal, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(vm().structureStructure->structureID())))); 13209 13209 13210 m_jit.loadPtr(CCallHelpers::Address(scratchGPR, StructureRareData::offsetOfCached OwnKeys()), scratchGPR);13211 13212 ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cached OwnKeysSentinel()) == 1);13213 slowCases.append(m_jit.branchPtr(CCallHelpers::BelowOrEqual, scratchGPR, TrustedImmPtr(bitwise_cast<void*>(StructureRareData::cached OwnKeysSentinel()))));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())))); 13214 13214 13215 13215 MacroAssembler::JumpList slowButArrayBufferCases; … … 13225 13225 addSlowPathGenerator(slowPathCall(slowButArrayBufferCases, this, operationNewArrayBuffer, resultGPR, &vm(), arrayStructure, scratch3GPR)); 13226 13226 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)); 13228 13228 13229 13229 cellResult(resultGPR, node); … … 13240 13240 GPRFlushedCallResult result(this); 13241 13241 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); 13243 13243 m_jit.exceptionCheck(); 13244 13244 … … 13255 13255 GPRFlushedCallResult result(this); 13256 13256 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); 13258 13258 m_jit.exceptionCheck(); 13259 13259 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r265907 r265934 1467 1467 void compileNewTypedArray(Node*); 1468 1468 void compileToThis(Node*); 1469 void compileObjectKeys (Node*);1469 void compileObjectKeysOrObjectGetOwnPropertyNames(Node*); 1470 1470 void compileObjectCreate(Node*); 1471 1471 void compileCreateThis(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r265907 r265934 3233 3233 } 3234 3234 3235 case ObjectKeys: { 3236 compileObjectKeys(node); 3235 case ObjectKeys: 3236 case ObjectGetOwnPropertyNames: { 3237 compileObjectKeysOrObjectGetOwnPropertyNames(node); 3237 3238 break; 3238 3239 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r265907 r265934 3819 3819 } 3820 3820 3821 case ObjectKeys: { 3822 compileObjectKeys(node); 3821 case ObjectKeys: 3822 case ObjectGetOwnPropertyNames: { 3823 compileObjectKeysOrObjectGetOwnPropertyNames(node); 3823 3824 break; 3824 3825 } -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r263470 r265934 147 147 macro(Structure_prototype, Structure::prototypeOffset()) \ 148 148 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)) \ 150 151 macro(HashMapImpl_capacity, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfCapacity()) \ 151 152 macro(HashMapImpl_buffer, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfBuffer()) \ -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r265907 r265934 223 223 case ObjectCreate: 224 224 case ObjectKeys: 225 case ObjectGetOwnPropertyNames: 225 226 case MakeRope: 226 227 case NewArrayWithSize: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r265907 r265934 1079 1079 break; 1080 1080 case ObjectKeys: 1081 compileObjectKeys(); 1081 case ObjectGetOwnPropertyNames: 1082 compileObjectKeysOrObjectGetOwnPropertyNames(); 1082 1083 break; 1083 1084 case NewObject: … … 6573 6574 } 6574 6575 6575 void compileObjectKeys ()6576 void compileObjectKeysOrObjectGetOwnPropertyNames() 6576 6577 { 6577 6578 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); 6579 NodeType op = m_node->op(); 6578 6580 switch (m_node->child1().useKind()) { 6579 6581 case ObjectUse: { … … 6597 6599 6598 6600 m_out.appendTo(rareDataCase, useCacheCase); 6599 ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cached OwnKeysSentinel()) == 1);6600 LValue cached OwnKeys = m_out.loadPtr(previousOrRareData, m_heaps.StructureRareData_cachedOwnKeys);6601 m_out.branch(m_out.belowOrEqual(cached OwnKeys, 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)); 6602 6604 6603 6605 m_out.appendTo(useCacheCase, slowButArrayBufferCase); 6604 6606 RegisteredStructure arrayStructure = m_graph.registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(CopyOnWriteArrayWithContiguous)); 6605 LValue fastArray = allocateObject<JSArray>(arrayStructure, m_out.addPtr(cached OwnKeys, JSImmutableButterfly::offsetOfData()), slowButArrayBufferCase);6607 LValue fastArray = allocateObject<JSArray>(arrayStructure, m_out.addPtr(cached, JSImmutableButterfly::offsetOfData()), slowButArrayBufferCase); 6606 6608 ValueFromBlock fastResult = m_out.anchor(fastArray); 6607 6609 m_out.jump(continuation); 6608 6610 6609 6611 m_out.appendTo(slowButArrayBufferCase, slowCase); 6610 LValue slowArray = vmCall(Int64, operationNewArrayBuffer, m_vmValue, weakStructure(arrayStructure), cached OwnKeys);6612 LValue slowArray = vmCall(Int64, operationNewArrayBuffer, m_vmValue, weakStructure(arrayStructure), cached); 6611 6613 ValueFromBlock slowButArrayBufferResult = m_out.anchor(slowArray); 6612 6614 m_out.jump(continuation); … … 6617 6619 [=, &vm] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> { 6618 6620 return createLazyCallGenerator(vm, 6619 op erationObjectKeysObject, locations[0].directGPR(), globalObject, locations[1].directGPR());6621 op == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, locations[0].directGPR(), globalObject, locations[1].directGPR()); 6620 6622 }, 6621 6623 object); … … 6627 6629 break; 6628 6630 } 6629 setJSValue(vmCall(Int64, op erationObjectKeysObject, weakPointer(globalObject), lowObject(m_node->child1())));6631 setJSValue(vmCall(Int64, op == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, weakPointer(globalObject), lowObject(m_node->child1()))); 6630 6632 break; 6631 6633 } 6632 6634 case UntypedUse: 6633 setJSValue(vmCall(Int64, op erationObjectKeys, weakPointer(globalObject), lowJSValue(m_node->child1())));6635 setJSValue(vmCall(Int64, op == ObjectKeys ? operationObjectKeys : operationObjectGetOwnPropertyNames, weakPointer(globalObject), lowJSValue(m_node->child1()))); 6634 6636 break; 6635 6637 default: -
trunk/Source/JavaScriptCore/runtime/Intrinsic.cpp
r260323 r265934 160 160 case ObjectCreateIntrinsic: 161 161 return "ObjectCreateIntrinsic"; 162 case ObjectGetOwnPropertyNamesIntrinsic: 163 return "ObjectGetOwnPropertyNamesIntrinsic"; 162 164 case ObjectGetPrototypeOfIntrinsic: 163 165 return "ObjectGetPrototypeOfIntrinsic"; -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r260417 r265934 96 96 RegExpMatchFastIntrinsic, 97 97 ObjectCreateIntrinsic, 98 ObjectGetOwnPropertyNamesIntrinsic, 98 99 ObjectGetPrototypeOfIntrinsic, 99 100 ObjectIsIntrinsic, -
trunk/Source/JavaScriptCore/runtime/IteratorOperations.cpp
r262567 r265934 128 128 } 129 129 130 static const PropertyOffset valuePropertyOffset = 0;131 static const PropertyOffset donePropertyOffset = 1;130 static constexpr PropertyOffset valuePropertyOffset = 0; 131 static constexpr PropertyOffset donePropertyOffset = 1; 132 132 133 133 Structure* createIteratorResultObjectStructure(VM& vm, JSGlobalObject& globalObject) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r264736 r265934 971 971 init.set(createIteratorResultObjectStructure(init.vm, *init.owner)); 972 972 }); 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 }); 973 981 974 982 m_evalFunction.initLater( … … 1936 1944 visitor.append(thisObject->m_setIteratorStructure); 1937 1945 thisObject->m_iteratorResultObjectStructure.visit(visitor); 1946 thisObject->m_dataPropertyDescriptorObjectStructure.visit(visitor); 1947 thisObject->m_accessorPropertyDescriptorObjectStructure.visit(visitor); 1938 1948 visitor.append(thisObject->m_regExpMatchesArrayStructure); 1939 1949 thisObject->m_moduleRecordStructure.visit(visitor); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r264639 r265934 395 395 WriteBarrier<Structure> m_setIteratorStructure; 396 396 LazyProperty<JSGlobalObject, Structure> m_iteratorResultObjectStructure; 397 LazyProperty<JSGlobalObject, Structure> m_dataPropertyDescriptorObjectStructure; 398 LazyProperty<JSGlobalObject, Structure> m_accessorPropertyDescriptorObjectStructure; 397 399 WriteBarrier<Structure> m_regExpMatchesArrayStructure; 398 400 LazyProperty<JSGlobalObject, Structure> m_moduleRecordStructure; … … 785 787 Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } 786 788 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); } 787 791 Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } 788 792 Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(this); } -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r263905 r265934 831 831 JSObject* object = callFrame->argument(0).toObject(globalObject); 832 832 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))); 834 834 } 835 835 -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
r263035 r265934 63 63 getOwnPropertyDescriptor objectConstructorGetOwnPropertyDescriptor DontEnum|Function 2 64 64 getOwnPropertyDescriptors objectConstructorGetOwnPropertyDescriptors DontEnum|Function 1 65 getOwnPropertyNames objectConstructorGetOwnPropertyNames DontEnum|Function 1 65 getOwnPropertyNames objectConstructorGetOwnPropertyNames DontEnum|Function 1 ObjectGetOwnPropertyNamesIntrinsic 66 66 getOwnPropertySymbols objectConstructorGetOwnPropertySymbols DontEnum|Function 1 67 67 keys objectConstructorKeys DontEnum|Function 1 ObjectKeysIntrinsic … … 236 236 } 237 237 238 // FIXME: Use the enumeration cache.239 238 EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(JSGlobalObject* globalObject, CallFrame* callFrame) 240 239 { … … 243 242 JSObject* object = callFrame->argument(0).toObject(globalObject); 244 243 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))); 246 245 } 247 246 … … 253 252 JSObject* object = callFrame->argument(0).toObject(globalObject); 254 253 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))); 256 255 } 257 256 … … 262 261 JSObject* object = callFrame->argument(0).toObject(globalObject); 263 262 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))); 265 264 } 266 265 … … 887 886 } 888 887 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) { 888 JSArray* 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) { 897 895 if (LIKELY(!globalObject->isHavingABadTime())) { 898 if (auto* immutableButterfly = object->structure(vm)->cached OwnKeys()) {896 if (auto* immutableButterfly = object->structure(vm)->cachedPropertyNames(kind.value())) { 899 897 Structure* arrayStructure = globalObject->originalArrayStructureForIndexingType(immutableButterfly->indexingMode()); 900 898 return JSArray::createWithButterfly(vm, nullptr, arrayStructure, immutableButterfly->toButterfly()); … … 911 909 if (properties.size() < MIN_SPARSE_ARRAY_INDEX) { 912 910 if (LIKELY(!globalObject->isHavingABadTime())) { 913 if ( isObjectKeys) {911 if (kind) { 914 912 Structure* structure = object->structure(vm); 915 if (structure->canCacheOwn Keys()) {916 auto* cachedButterfly = structure->cached OwnKeysIgnoringSentinel();917 if (cachedButterfly == StructureRareData::cached OwnKeysSentinel()) {913 if (structure->canCacheOwnPropertyNames()) { 914 auto* cachedButterfly = structure->cachedPropertyNamesIgnoringSentinel(kind.value()); 915 if (cachedButterfly == StructureRareData::cachedPropertyNamesSentinel()) { 918 916 size_t numProperties = properties.size(); 919 917 auto* newButterfly = JSImmutableButterfly::create(vm, CopyOnWriteArrayWithContiguous, numProperties); … … 924 922 } 925 923 926 structure->setCached OwnKeys(vm, newButterfly);924 structure->setCachedPropertyNames(vm, kind.value(), newButterfly); 927 925 Structure* arrayStructure = globalObject->originalArrayStructureForIndexingType(newButterfly->indexingMode()); 928 926 return JSArray::createWithButterfly(vm, nullptr, arrayStructure, newButterfly->toButterfly()); … … 930 928 931 929 if (cachedButterfly == nullptr) 932 structure->setCached OwnKeys(vm, StructureRareData::cachedOwnKeysSentinel());930 structure->setCachedPropertyNames(vm, kind.value(), StructureRareData::cachedPropertyNamesSentinel()); 933 931 } 934 932 } … … 1012 1010 } 1013 1011 1012 JSObject* 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 1014 1034 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h
r260447 r265934 90 90 } 91 91 92 JS_EXPORT_PRIVATE JSObject* constructObjectFromPropertyDescriptorSlow(JSGlobalObject*, const PropertyDescriptor&); 93 94 static constexpr PropertyOffset dataPropertyDescriptorValuePropertyOffset = 0; 95 static constexpr PropertyOffset dataPropertyDescriptorWritablePropertyOffset = 1; 96 static constexpr PropertyOffset dataPropertyDescriptorEnumerablePropertyOffset = 2; 97 static constexpr PropertyOffset dataPropertyDescriptorConfigurablePropertyOffset = 3; 98 99 static constexpr PropertyOffset accessorPropertyDescriptorGetPropertyOffset = 0; 100 static constexpr PropertyOffset accessorPropertyDescriptorSetPropertyOffset = 1; 101 static constexpr PropertyOffset accessorPropertyDescriptorEnumerablePropertyOffset = 2; 102 static constexpr PropertyOffset accessorPropertyDescriptorConfigurablePropertyOffset = 3; 103 104 inline 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 119 inline 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 92 134 // https://tc39.es/ecma262/#sec-frompropertydescriptor 93 135 inline JSObject* constructObjectFromPropertyDescriptor(JSGlobalObject* globalObject, const PropertyDescriptor& descriptor) 94 136 { 95 137 VM& vm = getVM(globalObject); 96 JSObject* result = constructEmptyObject(globalObject);97 138 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 } 110 148 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); 112 159 } 113 160 … … 117 164 JSValue objectConstructorGetOwnPropertyDescriptor(JSGlobalObject*, JSObject*, const Identifier&); 118 165 JSValue objectConstructorGetOwnPropertyDescriptors(JSGlobalObject*, JSObject*); 119 JSArray* ownPropertyKeys(JSGlobalObject*, JSObject*, PropertyNameMode, DontEnumPropertiesMode );166 JSArray* ownPropertyKeys(JSGlobalObject*, JSObject*, PropertyNameMode, DontEnumPropertiesMode, Optional<CachedPropertyNamesKind>); 120 167 bool toPropertyDescriptor(JSGlobalObject*, JSValue, PropertyDescriptor&); 121 168 -
trunk/Source/JavaScriptCore/runtime/ReflectObject.cpp
r265034 r265934 223 223 if (!target.isObject()) 224 224 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))); 226 226 } 227 227 -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r265642 r265934 1410 1410 bool Structure::canCachePropertyNameEnumerator(VM& vm) const 1411 1411 { 1412 if (!this->canCacheOwn Keys())1412 if (!this->canCacheOwnPropertyNames()) 1413 1413 return false; 1414 1414 … … 1421 1421 return true; 1422 1422 Structure* structure = vm.getStructure(structureID); 1423 if (!structure->canCacheOwn Keys())1423 if (!structure->canCacheOwnPropertyNames()) 1424 1424 return false; 1425 1425 currentStructureID++; -
trunk/Source/JavaScriptCore/runtime/Structure.h
r265642 r265934 523 523 bool canAccessPropertiesQuicklyForEnumeration() const; 524 524 525 void setCachedOwnKeys(VM&, JSImmutableButterfly*);526 JSImmutableButterfly* cached OwnKeys() const;527 JSImmutableButterfly* cachedOwnKeysIgnoringSentinel() const;528 bool canCacheOwn Keys() const;525 JSImmutableButterfly* cachedPropertyNames(CachedPropertyNamesKind) const; 526 JSImmutableButterfly* cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind) const; 527 void setCachedPropertyNames(VM&, CachedPropertyNamesKind, JSImmutableButterfly*); 528 bool canCacheOwnPropertyNames() const; 529 529 530 530 void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode); -
trunk/Source/JavaScriptCore/runtime/StructureInlines.h
r265640 r265934 243 243 } 244 244 245 inline void Structure::setCached OwnKeys(VM& vm, JSImmutableButterfly* ownKeys)246 { 247 ensureRareData(vm)->setCached OwnKeys(vm, ownKeys);248 } 249 250 inline JSImmutableButterfly* Structure::cached OwnKeys() const245 inline void Structure::setCachedPropertyNames(VM& vm, CachedPropertyNamesKind kind, JSImmutableButterfly* cached) 246 { 247 ensureRareData(vm)->setCachedPropertyNames(vm, kind, cached); 248 } 249 250 inline JSImmutableButterfly* Structure::cachedPropertyNames(CachedPropertyNamesKind kind) const 251 251 { 252 252 if (!hasRareData()) 253 253 return nullptr; 254 return rareData()->cached OwnKeys();255 } 256 257 inline JSImmutableButterfly* Structure::cached OwnKeysIgnoringSentinel() const254 return rareData()->cachedPropertyNames(kind); 255 } 256 257 inline JSImmutableButterfly* Structure::cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind kind) const 258 258 { 259 259 if (!hasRareData()) 260 260 return nullptr; 261 return rareData()->cached OwnKeysIgnoringSentinel();262 } 263 264 inline bool Structure::canCacheOwn Keys() const261 return rareData()->cachedPropertyNamesIgnoringSentinel(kind); 262 } 263 264 inline bool Structure::canCacheOwnPropertyNames() const 265 265 { 266 266 if (isDictionary()) -
trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp
r264736 r265934 77 77 visitor.appendUnbarriered(thisObject->objectToStringValue()); 78 78 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 } 82 84 } 83 85 -
trunk/Source/JavaScriptCore/runtime/StructureRareData.h
r264736 r265934 38 38 class ObjectToStringAdaptiveInferredPropertyValueWatchpoint; 39 39 class ObjectToStringAdaptiveStructureWatchpoint; 40 enum class CachedPropertyNamesKind : uint8_t { 41 Keys = 0, 42 GetOwnPropertyNames, 43 }; 44 static constexpr unsigned numberOfCachedPropertyNames = 2; 40 45 41 46 class StructureRareData final : public JSCell { … … 75 80 void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*); 76 81 77 JSImmutableButterfly* cached OwnKeys() const;78 JSImmutableButterfly* cached OwnKeysIgnoringSentinel() const;79 JSImmutableButterfly* cached OwnKeysConcurrently() const;80 void setCached OwnKeys(VM&, JSImmutableButterfly*);82 JSImmutableButterfly* cachedPropertyNames(CachedPropertyNamesKind) const; 83 JSImmutableButterfly* cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind) const; 84 JSImmutableButterfly* cachedPropertyNamesConcurrently(CachedPropertyNamesKind) const; 85 void setCachedPropertyNames(VM&, CachedPropertyNamesKind, JSImmutableButterfly*); 81 86 82 87 Box<InlineWatchpointSet> copySharedPolyProtoWatchpoint() const { return m_polyProtoWatchpoint; } … … 85 90 bool hasSharedPolyProtoWatchpoint() const { return static_cast<bool>(m_polyProtoWatchpoint); } 86 91 87 static JSImmutableButterfly* cached OwnKeysSentinel() { return bitwise_cast<JSImmutableButterfly*>(static_cast<uintptr_t>(1)); }92 static JSImmutableButterfly* cachedPropertyNamesSentinel() { return bitwise_cast<JSImmutableButterfly*>(static_cast<uintptr_t>(1)); } 88 93 89 static ptrdiff_t offsetOfCached OwnKeys()94 static ptrdiff_t offsetOfCachedPropertyNames(CachedPropertyNamesKind kind) 90 95 { 91 return OBJECT_OFFSETOF(StructureRareData, m_cached OwnKeys);96 return OBJECT_OFFSETOF(StructureRareData, m_cachedPropertyNames) + sizeof(WriteBarrier<JSImmutableButterfly>) * static_cast<unsigned>(kind); 92 97 } 93 98 … … 110 115 // https://bugs.webkit.org/show_bug.cgi?id=192659 111 116 WriteBarrier<JSPropertyNameEnumerator> m_cachedPropertyNameEnumerator; 112 WriteBarrier<JSImmutableButterfly> m_cached OwnKeys;117 WriteBarrier<JSImmutableButterfly> m_cachedPropertyNames[numberOfCachedPropertyNames] { }; 113 118 114 119 typedef HashMap<PropertyOffset, RefPtr<WatchpointSet>, WTF::IntHash<PropertyOffset>, WTF::UnsignedWithZeroKeyHashTraits<PropertyOffset>> PropertyWatchpointMap; -
trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h
r259463 r265934 63 63 } 64 64 65 inline JSImmutableButterfly* StructureRareData::cached OwnKeys() const65 inline JSImmutableButterfly* StructureRareData::cachedPropertyNames(CachedPropertyNamesKind kind) const 66 66 { 67 67 ASSERT(!isCompilationThread()); 68 auto* butterfly = m_cached OwnKeys.unvalidatedGet();69 if (butterfly == cached OwnKeysSentinel())68 auto* butterfly = m_cachedPropertyNames[static_cast<unsigned>(kind)].unvalidatedGet(); 69 if (butterfly == cachedPropertyNamesSentinel()) 70 70 return nullptr; 71 71 return butterfly; 72 72 } 73 73 74 inline JSImmutableButterfly* StructureRareData::cached OwnKeysIgnoringSentinel() const74 inline JSImmutableButterfly* StructureRareData::cachedPropertyNamesIgnoringSentinel(CachedPropertyNamesKind kind) const 75 75 { 76 76 ASSERT(!isCompilationThread()); 77 return m_cached OwnKeys.unvalidatedGet();77 return m_cachedPropertyNames[static_cast<unsigned>(kind)].unvalidatedGet(); 78 78 } 79 79 80 inline JSImmutableButterfly* StructureRareData::cached OwnKeysConcurrently() const80 inline JSImmutableButterfly* StructureRareData::cachedPropertyNamesConcurrently(CachedPropertyNamesKind kind) const 81 81 { 82 auto* butterfly = m_cached OwnKeys.unvalidatedGet();83 if (butterfly == cached OwnKeysSentinel())82 auto* butterfly = m_cachedPropertyNames[static_cast<unsigned>(kind)].unvalidatedGet(); 83 if (butterfly == cachedPropertyNamesSentinel()) 84 84 return nullptr; 85 85 return butterfly; 86 86 } 87 87 88 inline void StructureRareData::setCached OwnKeys(VM& vm, JSImmutableButterfly* butterfly)88 inline void StructureRareData::setCachedPropertyNames(VM& vm, CachedPropertyNamesKind kind, JSImmutableButterfly* butterfly) 89 89 { 90 if (butterfly == cached OwnKeysSentinel()) {91 m_cached OwnKeys.setWithoutWriteBarrier(butterfly);90 if (butterfly == cachedPropertyNamesSentinel()) { 91 m_cachedPropertyNames[static_cast<unsigned>(kind)].setWithoutWriteBarrier(butterfly); 92 92 return; 93 93 } 94 94 95 95 WTF::storeStoreFence(); 96 m_cached OwnKeys.set(vm, this, butterfly);96 m_cachedPropertyNames[static_cast<unsigned>(kind)].set(vm, this, butterfly); 97 97 } 98 98
Note: See TracChangeset
for help on using the changeset viewer.