Changeset 239231 in webkit
- Timestamp:
- Dec 14, 2018 1:40:27 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 6 deleted
- 34 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r239227 r239231 1 2018-12-14 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r239153, r239154, and r239155. 4 https://bugs.webkit.org/show_bug.cgi?id=192715 5 6 Caused flaky GC-related crashes seen with layout tests 7 (Requested by ryanhaddad on #webkit). 8 9 Reverted changesets: 10 11 "[JSC] Optimize Object.keys by caching own keys results in 12 StructureRareData" 13 https://bugs.webkit.org/show_bug.cgi?id=190047 14 https://trac.webkit.org/changeset/239153 15 16 "Unreviewed, build fix after r239153" 17 https://bugs.webkit.org/show_bug.cgi?id=190047 18 https://trac.webkit.org/changeset/239154 19 20 "Unreviewed, build fix after r239153, part 2" 21 https://bugs.webkit.org/show_bug.cgi?id=190047 22 https://trac.webkit.org/changeset/239155 23 1 24 2018-12-14 Keith Miller <keith_miller@apple.com> 2 25 -
trunk/Source/JavaScriptCore/ChangeLog
r239227 r239231 1 2018-12-14 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r239153, r239154, and r239155. 4 https://bugs.webkit.org/show_bug.cgi?id=192715 5 6 Caused flaky GC-related crashes seen with layout tests 7 (Requested by ryanhaddad on #webkit). 8 9 Reverted changesets: 10 11 "[JSC] Optimize Object.keys by caching own keys results in 12 StructureRareData" 13 https://bugs.webkit.org/show_bug.cgi?id=190047 14 https://trac.webkit.org/changeset/239153 15 16 "Unreviewed, build fix after r239153" 17 https://bugs.webkit.org/show_bug.cgi?id=190047 18 https://trac.webkit.org/changeset/239154 19 20 "Unreviewed, build fix after r239153, part 2" 21 https://bugs.webkit.org/show_bug.cgi?id=190047 22 https://trac.webkit.org/changeset/239155 23 1 24 2018-12-14 Keith Miller <keith_miller@apple.com> 2 25 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r239158 r239231 44 44 #include "PutByIdStatus.h" 45 45 #include "StringObject.h" 46 #include "StructureRareDataInlines.h"47 46 #include <wtf/BooleanLattice.h> 48 47 #include <wtf/CheckedArithmetic.h> … … 2579 2578 clobberWorld(); 2580 2579 setTypeForNode(node, SpecFinalObject); 2581 break;2582 }2583 2584 case ObjectKeys: {2585 if (node->child1().useKind() == ObjectUse) {2586 auto& structureSet = forNode(node->child1()).m_structure;2587 if (structureSet.isFinite() && structureSet.size() == 1) {2588 RegisteredStructure structure = structureSet.onlyStructure();2589 if (auto* rareData = structure->rareDataConcurrently()) {2590 auto* immutableButterfly = rareData->cachedOwnKeysConcurrently();2591 if (immutableButterfly && immutableButterfly != m_vm.sentinelImmutableButterfly.get()) {2592 if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {2593 m_state.setFoundConstants(true);2594 didFoldClobberWorld();2595 setTypeForNode(node, SpecArray);2596 break;2597 }2598 }2599 }2600 }2601 }2602 2603 clobberWorld();2604 setTypeForNode(node, SpecArray);2605 2580 break; 2606 2581 } -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r239158 r239231 2690 2690 insertChecks(); 2691 2691 set(result, addToGraph(SameValue, get(virtualRegisterForArgument(1, registerOffset)), get(virtualRegisterForArgument(2, registerOffset)))); 2692 return true;2693 }2694 2695 case ObjectKeysIntrinsic: {2696 if (argumentCountIncludingThis < 2)2697 return false;2698 2699 insertChecks();2700 set(result, addToGraph(ObjectKeys, get(virtualRegisterForArgument(1, registerOffset))));2701 2692 return true; 2702 2693 } -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r239158 r239231 669 669 case InstanceOf: 670 670 case StringValueOf: 671 case ObjectKeys:672 671 read(World); 673 672 write(Heap); … … 1530 1529 } 1531 1530 } 1531 1532 1532 1533 1533 case NewObject: -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r239153 r239231 767 767 } 768 768 769 case ObjectKeys: {770 if (node->child1().useKind() == ObjectUse) {771 auto& structureSet = m_state.forNode(node->child1()).m_structure;772 if (structureSet.isFinite() && structureSet.size() == 1) {773 RegisteredStructure structure = structureSet.onlyStructure();774 if (auto* rareData = structure->rareDataConcurrently()) {775 auto* immutableButterfly = rareData->cachedOwnKeysConcurrently();776 if (immutableButterfly && immutableButterfly != m_graph.m_vm.sentinelImmutableButterfly.get()) {777 if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {778 node->convertToNewArrayBuffer(m_graph.freeze(immutableButterfly));779 changed = true;780 break;781 }782 }783 }784 }785 }786 break;787 }788 789 769 case ToNumber: { 790 770 if (m_state.forNode(node->child1()).m_type & ~SpecBytecodeNumber) -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r239158 r239231 340 340 case CreateThis: 341 341 case ObjectCreate: 342 case ObjectKeys:343 342 case AllocatePropertyStorage: 344 343 case ReallocatePropertyStorage: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r239158 r239231 1592 1592 node->clearFlags(NodeMustGenerate); 1593 1593 break; 1594 }1595 break;1596 }1597 1598 case ObjectKeys: {1599 if (node->child1()->shouldSpeculateObject()) {1600 watchHavingABadTime(node);1601 fixEdge<ObjectUse>(node->child1());1602 1594 } 1603 1595 break; -
trunk/Source/JavaScriptCore/dfg/DFGNode.cpp
r239153 r239231 32 32 #include "DFGPromotedHeapLocation.h" 33 33 #include "JSCInlines.h" 34 #include "JSImmutableButterfly.h"35 34 36 35 namespace JSC { namespace DFG { … … 225 224 } 226 225 227 void Node::convertToNewArrayBuffer(FrozenValue* immutableButterfly)228 {229 setOpAndDefaultFlags(NewArrayBuffer);230 NewArrayBufferData data { };231 data.indexingMode = immutableButterfly->cast<JSImmutableButterfly*>()->indexingMode();232 data.vectorLengthHint = immutableButterfly->cast<JSImmutableButterfly*>()->toButterfly()->vectorLength();233 children.reset();234 m_opInfo = immutableButterfly;235 m_opInfo2 = data.asQuadWord;236 }237 238 226 void Node::convertToDirectCall(FrozenValue* executable) 239 227 { -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r239158 r239231 762 762 m_opInfo2 = OpInfoWrapper(); 763 763 } 764 765 void convertToNewArrayBuffer(FrozenValue* immutableButterfly);766 764 767 765 void convertToDirectCall(FrozenValue*); -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r239158 r239231 266 266 macro(GetPrototypeOf, NodeMustGenerate | NodeResultJS) \ 267 267 macro(ObjectCreate, NodeMustGenerate | NodeResultJS) \ 268 macro(ObjectKeys, NodeMustGenerate | NodeResultJS) \269 268 \ 270 269 /* Atomics object functions. */\ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r239158 r239231 249 249 } 250 250 251 JSArray* JIT_OPERATION operationObjectKeys(ExecState* exec, EncodedJSValue encodedObject)252 {253 VM& vm = exec->vm();254 NativeCallFrameTracer tracer(&vm, exec);255 auto scope = DECLARE_THROW_SCOPE(vm);256 257 JSObject* object = JSValue::decode(encodedObject).toObject(exec);258 RETURN_IF_EXCEPTION(scope, nullptr);259 scope.release();260 return ownPropertyKeys(exec, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);261 }262 263 JSArray* JIT_OPERATION operationObjectKeysObject(ExecState* exec, JSObject* object)264 {265 VM& vm = exec->vm();266 NativeCallFrameTracer tracer(&vm, exec);267 return ownPropertyKeys(exec, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);268 }269 270 251 JSCell* JIT_OPERATION operationObjectCreate(ExecState* exec, EncodedJSValue encodedPrototype) 271 252 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r239158 r239231 44 44 JSCell* JIT_OPERATION operationCallObjectConstructor(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget) WTF_INTERNAL; 45 45 JSCell* JIT_OPERATION operationToObject(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget, UniquedStringImpl*) WTF_INTERNAL; 46 JSArray* JIT_OPERATION operationObjectKeys(ExecState*, EncodedJSValue) WTF_INTERNAL;47 JSArray* JIT_OPERATION operationObjectKeysObject(ExecState*, JSObject*) WTF_INTERNAL;48 46 JSCell* JIT_OPERATION operationObjectCreate(ExecState*, EncodedJSValue) WTF_INTERNAL; 49 47 JSCell* JIT_OPERATION operationObjectCreateObject(ExecState*, JSObject*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r239158 r239231 985 985 case NewArrayWithSize: 986 986 case CreateRest: 987 case NewArrayBuffer: 988 case ObjectKeys: { 987 case NewArrayBuffer: { 989 988 setPrediction(SpecArray); 990 989 break; -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r239158 r239231 179 179 case CreateThis: 180 180 case ObjectCreate: 181 case ObjectKeys:182 181 case GetCallee: 183 182 case SetCallee: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r239187 r239231 12366 12366 } 12367 12367 12368 void SpeculativeJIT::compileObjectKeys(Node* node)12369 {12370 switch (node->child1().useKind()) {12371 case ObjectUse: {12372 if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {12373 SpeculateCellOperand object(this, node->child1());12374 GPRTemporary structure(this);12375 GPRTemporary scratch(this);12376 GPRTemporary scratch2(this);12377 GPRTemporary scratch3(this);12378 GPRTemporary result(this);12379 12380 GPRReg objectGPR = object.gpr();12381 GPRReg structureGPR = structure.gpr();12382 GPRReg scratchGPR = scratch.gpr();12383 GPRReg scratch2GPR = scratch2.gpr();12384 GPRReg scratch3GPR = scratch3.gpr();12385 GPRReg resultGPR = result.gpr();12386 12387 speculateObject(node->child1(), objectGPR);12388 12389 CCallHelpers::JumpList slowCases;12390 m_jit.emitLoadStructure(*m_jit.vm(), objectGPR, structureGPR, scratchGPR);12391 m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::previousOrRareDataOffset()), scratchGPR);12392 12393 slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratchGPR));12394 slowCases.append(m_jit.branch32(CCallHelpers::Equal, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(m_jit.vm()->structureStructure->structureID()))));12395 12396 m_jit.loadPtr(CCallHelpers::Address(scratchGPR, StructureRareData::offsetOfCachedOwnKeys()), scratchGPR);12397 12398 slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratchGPR));12399 slowCases.append(m_jit.branchPtr(CCallHelpers::Equal, scratchGPR, TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.vm()->sentinelImmutableButterfly.get())));12400 12401 MacroAssembler::JumpList slowButArrayBufferCases;12402 12403 JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);12404 RegisteredStructure arrayStructure = m_jit.graph().registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(CopyOnWriteArrayWithContiguous));12405 12406 m_jit.move(scratchGPR, scratch3GPR);12407 m_jit.addPtr(TrustedImmPtr(JSImmutableButterfly::offsetOfData()), scratchGPR);12408 12409 emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(arrayStructure), scratchGPR, structureGPR, scratch2GPR, slowButArrayBufferCases);12410 12411 addSlowPathGenerator(slowPathCall(slowButArrayBufferCases, this, operationNewArrayBuffer, resultGPR, arrayStructure, scratch3GPR));12412 12413 addSlowPathGenerator(slowPathCall(slowCases, this, operationObjectKeysObject, resultGPR, objectGPR));12414 12415 cellResult(resultGPR, node);12416 break;12417 }12418 12419 SpeculateCellOperand object(this, node->child1());12420 12421 GPRReg objectGPR = object.gpr();12422 12423 speculateObject(node->child1(), objectGPR);12424 12425 flushRegisters();12426 GPRFlushedCallResult result(this);12427 GPRReg resultGPR = result.gpr();12428 callOperation(operationObjectKeysObject, resultGPR, objectGPR);12429 m_jit.exceptionCheck();12430 12431 cellResult(resultGPR, node);12432 break;12433 }12434 12435 case UntypedUse: {12436 JSValueOperand object(this, node->child1());12437 12438 JSValueRegs objectRegs = object.jsValueRegs();12439 12440 flushRegisters();12441 GPRFlushedCallResult result(this);12442 GPRReg resultGPR = result.gpr();12443 callOperation(operationObjectKeys, resultGPR, objectRegs);12444 m_jit.exceptionCheck();12445 12446 cellResult(resultGPR, node);12447 break;12448 }12449 12450 default:12451 RELEASE_ASSERT_NOT_REACHED();12452 break;12453 }12454 }12455 12456 12368 void SpeculativeJIT::compileObjectCreate(Node* node) 12457 12369 { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r239187 r239231 1480 1480 void compileNewTypedArray(Node*); 1481 1481 void compileToThis(Node*); 1482 void compileObjectKeys(Node*);1483 1482 void compileObjectCreate(Node*); 1484 1483 void compileCreateThis(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r239187 r239231 3165 3165 case ObjectCreate: { 3166 3166 compileObjectCreate(node); 3167 break;3168 }3169 3170 case ObjectKeys: {3171 compileObjectKeys(node);3172 3167 break; 3173 3168 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r239187 r239231 3407 3407 case ObjectCreate: { 3408 3408 compileObjectCreate(node); 3409 break;3410 }3411 3412 case ObjectKeys: {3413 compileObjectKeys(node);3414 3409 break; 3415 3410 } -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r239153 r239231 117 117 macro(Structure_indexingModeIncludingHistory, Structure::indexingModeIncludingHistoryOffset()) \ 118 118 macro(Structure_inlineCapacity, Structure::inlineCapacityOffset()) \ 119 macro(Structure_previousOrRareData, Structure::previousOrRareDataOffset()) \120 119 macro(Structure_prototype, Structure::prototypeOffset()) \ 121 120 macro(Structure_structureID, Structure::structureIDOffset()) \ 122 macro(StructureRareData_cachedOwnKeys, StructureRareData::offsetOfCachedOwnKeys()) \123 121 macro(HashMapImpl_capacity, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfCapacity()) \ 124 122 macro(HashMapImpl_buffer, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfBuffer()) \ -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r239158 r239231 202 202 case CallStringConstructor: 203 203 case ObjectCreate: 204 case ObjectKeys:205 204 case MakeRope: 206 205 case NewArrayWithSize: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r239187 r239231 867 867 compileObjectCreate(); 868 868 break; 869 case ObjectKeys:870 compileObjectKeys();871 break;872 869 case NewObject: 873 870 compileNewObject(); … … 5499 5496 m_out.appendTo(continuation, lastNext); 5500 5497 setInt32(m_out.phi(Int32, zeroLengthResult, nonZeroLengthResult)); 5501 }5502 5503 void compileObjectKeys()5504 {5505 switch (m_node->child1().useKind()) {5506 case ObjectUse: {5507 if (m_graph.isWatchingHavingABadTimeWatchpoint(m_node)) {5508 LBasicBlock notNullCase = m_out.newBlock();5509 LBasicBlock rareDataCase = m_out.newBlock();5510 LBasicBlock notNullCacheCase = m_out.newBlock();5511 LBasicBlock useCacheCase = m_out.newBlock();5512 LBasicBlock slowButArrayBufferCase = m_out.newBlock();5513 LBasicBlock slowCase = m_out.newBlock();5514 LBasicBlock continuation = m_out.newBlock();5515 5516 LValue object = lowObject(m_node->child1());5517 LValue structure = loadStructure(object);5518 LValue previousOrRareData = m_out.loadPtr(structure, m_heaps.Structure_previousOrRareData);5519 m_out.branch(m_out.notNull(previousOrRareData), unsure(notNullCase), unsure(slowCase));5520 5521 LBasicBlock lastNext = m_out.appendTo(notNullCase, rareDataCase);5522 m_out.branch(5523 m_out.notEqual(m_out.load32(previousOrRareData, m_heaps.JSCell_structureID), m_out.constInt32(m_graph.m_vm.structureStructure->structureID())),5524 unsure(rareDataCase), unsure(slowCase));5525 5526 m_out.appendTo(rareDataCase, notNullCacheCase);5527 LValue cachedOwnKeys = m_out.loadPtr(previousOrRareData, m_heaps.StructureRareData_cachedOwnKeys);5528 m_out.branch(m_out.notNull(cachedOwnKeys), unsure(notNullCacheCase), unsure(slowCase));5529 5530 m_out.appendTo(notNullCacheCase, useCacheCase);5531 m_out.branch(m_out.notEqual(cachedOwnKeys, weakPointer(m_graph.m_vm.sentinelImmutableButterfly.get())), unsure(useCacheCase), unsure(slowCase));5532 5533 m_out.appendTo(useCacheCase, slowButArrayBufferCase);5534 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);5535 RegisteredStructure arrayStructure = m_graph.registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(CopyOnWriteArrayWithContiguous));5536 LValue fastArray = allocateObject<JSArray>(arrayStructure, m_out.addPtr(cachedOwnKeys, JSImmutableButterfly::offsetOfData()), slowButArrayBufferCase);5537 ValueFromBlock fastResult = m_out.anchor(fastArray);5538 m_out.jump(continuation);5539 5540 m_out.appendTo(slowButArrayBufferCase, slowCase);5541 LValue slowArray = vmCall(Int64, m_out.operation(operationNewArrayBuffer), m_callFrame, weakStructure(arrayStructure), cachedOwnKeys);5542 ValueFromBlock slowButArrayBufferResult = m_out.anchor(slowArray);5543 m_out.jump(continuation);5544 5545 m_out.appendTo(slowCase, continuation);5546 VM& vm = this->vm();5547 LValue slowResultValue = lazySlowPath(5548 [=, &vm] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {5549 return createLazyCallGenerator(vm,5550 operationObjectKeysObject, locations[0].directGPR(), locations[1].directGPR());5551 },5552 object);5553 ValueFromBlock slowResult = m_out.anchor(slowResultValue);5554 m_out.jump(continuation);5555 5556 m_out.appendTo(continuation, lastNext);5557 setJSValue(m_out.phi(pointerType(), fastResult, slowButArrayBufferResult, slowResult));5558 break;5559 }5560 setJSValue(vmCall(Int64, m_out.operation(operationObjectKeysObject), m_callFrame, lowObject(m_node->child1())));5561 break;5562 }5563 case UntypedUse:5564 setJSValue(vmCall(Int64, m_out.operation(operationObjectKeys), m_callFrame, lowJSValue(m_node->child1())));5565 break;5566 default:5567 RELEASE_ASSERT_NOT_REACHED();5568 break;5569 }5570 5498 } 5571 5499 -
trunk/Source/JavaScriptCore/runtime/Intrinsic.cpp
r239153 r239231 120 120 case ObjectIsIntrinsic: 121 121 return "ObjectIsIntrinsic"; 122 case ObjectKeysIntrinsic:123 return "ObjectKeysIntrinsic";124 122 case ReflectGetPrototypeOfIntrinsic: 125 123 return "ReflectGetPrototypeOfIntrinsic"; -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r239153 r239231 73 73 ObjectGetPrototypeOfIntrinsic, 74 74 ObjectIsIntrinsic, 75 ObjectKeysIntrinsic,76 75 ReflectGetPrototypeOfIntrinsic, 77 76 StringPrototypeValueOfIntrinsic, -
trunk/Source/JavaScriptCore/runtime/JSImmutableButterfly.h
r239153 r239231 68 68 } 69 69 70 static JSImmutableButterfly* createSentinel(VM& vm)71 {72 return create(vm, CopyOnWriteArrayWithContiguous, 0);73 }74 75 70 unsigned publicLength() const { return m_header.publicLength(); } 76 71 unsigned vectorLength() const { return m_header.vectorLength(); } -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
r239153 r239231 31 31 #include "JSGlobalObject.h" 32 32 #include "JSGlobalObjectFunctions.h" 33 #include "JSImmutableButterfly.h"34 33 #include "Lookup.h" 35 34 #include "ObjectPrototype.h" … … 75 74 getOwnPropertyNames objectConstructorGetOwnPropertyNames DontEnum|Function 1 76 75 getOwnPropertySymbols objectConstructorGetOwnPropertySymbols DontEnum|Function 1 77 keys objectConstructorKeys DontEnum|Function 1 ObjectKeysIntrinsic76 keys objectConstructorKeys DontEnum|Function 1 78 77 defineProperty objectConstructorDefineProperty DontEnum|Function 3 79 78 defineProperties objectConstructorDefineProperties DontEnum|Function 2 … … 273 272 } 274 273 274 // FIXME: Use the enumeration cache. 275 275 EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec) 276 276 { … … 893 893 } 894 894 895 // FIXME: Use the enumeration cache. 895 896 JSArray* ownPropertyKeys(ExecState* exec, JSObject* object, PropertyNameMode propertyNameMode, DontEnumPropertiesMode dontEnumPropertiesMode) 896 897 { 897 898 VM& vm = exec->vm(); 898 899 auto scope = DECLARE_THROW_SCOPE(vm); 899 900 auto* globalObject = exec->lexicalGlobalObject();901 bool isObjectKeys = propertyNameMode == PropertyNameMode::Strings && dontEnumPropertiesMode == DontEnumPropertiesMode::Exclude;902 // We attempt to look up own property keys cache in Object.keys case.903 if (isObjectKeys) {904 if (LIKELY(!globalObject->isHavingABadTime())) {905 if (auto* immutableButterfly = object->structure(vm)->cachedOwnKeys()) {906 if (immutableButterfly != vm.sentinelImmutableButterfly.get()) {907 Structure* arrayStructure = globalObject->originalArrayStructureForIndexingType(immutableButterfly->indexingMode());908 return JSArray::createWithButterfly(vm, nullptr, arrayStructure, immutableButterfly->toButterfly());909 }910 }911 }912 }913 914 900 PropertyNameArray properties(&vm, propertyNameMode, PrivateSymbolMode::Exclude); 915 901 object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(dontEnumPropertiesMode)); … … 933 919 ASSERT(propertyNameMode == PropertyNameMode::Strings || propertyNameMode == PropertyNameMode::Symbols); 934 920 if (!mustFilterProperty && properties.size() < MIN_SPARSE_ARRAY_INDEX) { 921 auto* globalObject = exec->lexicalGlobalObject(); 935 922 if (LIKELY(!globalObject->isHavingABadTime())) { 936 if (isObjectKeys) {937 Structure* structure = object->structure(vm);938 if (structure->canCacheOwnKeys()) {939 auto* cachedButterfly = structure->cachedOwnKeys();940 if (cachedButterfly == vm.sentinelImmutableButterfly.get()) {941 // Cache the immutable butterfly!942 size_t numProperties = properties.size();943 auto* newButterfly = JSImmutableButterfly::create(vm, CopyOnWriteArrayWithContiguous, numProperties);944 for (size_t i = 0; i < numProperties; i++) {945 const auto& identifier = properties[i];946 ASSERT(!identifier.isSymbol());947 newButterfly->setIndex(vm, i, jsOwnedString(&vm, identifier.string()));948 }949 950 structure->setCachedOwnKeys(vm, newButterfly);951 Structure* arrayStructure = globalObject->originalArrayStructureForIndexingType(newButterfly->indexingMode());952 return JSArray::createWithButterfly(vm, nullptr, arrayStructure, newButterfly->toButterfly());953 }954 955 if (cachedButterfly == nullptr)956 structure->setCachedOwnKeys(vm, jsCast<JSImmutableButterfly*>(vm.sentinelImmutableButterfly.get()));957 }958 }959 960 923 size_t numProperties = properties.size(); 961 924 JSArray* keys = JSArray::create(vm, globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous), numProperties); -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r239153 r239231 1253 1253 bool Structure::canCachePropertyNameEnumerator() const 1254 1254 { 1255 if (!this->canCacheOwnKeys()) 1255 auto canCache = [] (const Structure* structure) { 1256 if (structure->isDictionary()) 1257 return false; 1258 if (hasIndexedProperties(structure->indexingType())) 1259 return false; 1260 if (structure->typeInfo().overridesGetPropertyNames()) 1261 return false; 1262 return true; 1263 }; 1264 1265 if (!canCache(this)) 1256 1266 return false; 1257 1267 … … 1262 1272 if (!structure->get()) 1263 1273 return true; 1264 if (! structure->get()->canCacheOwnKeys())1274 if (!canCache(structure->get())) 1265 1275 return false; 1266 1276 structure++; -
trunk/Source/JavaScriptCore/runtime/Structure.h
r239153 r239231 39 39 #include "StructureIDBlob.h" 40 40 #include "StructureRareData.h" 41 #include "StructureRareDataInlines.h" 41 42 #include "StructureTransitionTable.h" 42 43 #include "JSTypeInfo.h" … … 326 327 } 327 328 328 const StructureRareData* rareDataConcurrently() const329 {330 JSCell* cell = m_previousOrRareData.get();331 WTF::loadLoadFence();332 if (isRareData(cell))333 return static_cast<StructureRareData*>(cell);334 return nullptr;335 }336 337 329 StructureRareData* ensureRareData(VM& vm) 338 330 { … … 481 473 bool canAccessPropertiesQuicklyForEnumeration() const; 482 474 483 void setCachedOwnKeys(VM&, JSImmutableButterfly*);484 JSImmutableButterfly* cachedOwnKeys() const;485 bool canCacheOwnKeys() const;486 487 475 void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode); 488 476 … … 531 519 { 532 520 return OBJECT_OFFSETOF(Structure, m_inlineCapacity); 533 }534 535 static ptrdiff_t previousOrRareDataOffset()536 {537 return OBJECT_OFFSETOF(Structure, m_previousOrRareData);538 521 } 539 522 -
trunk/Source/JavaScriptCore/runtime/StructureInlines.h
r239153 r239231 220 220 } 221 221 222 inline void Structure::setCachedOwnKeys(VM& vm, JSImmutableButterfly* ownKeys)223 {224 ensureRareData(vm)->setCachedOwnKeys(vm, ownKeys);225 }226 227 inline JSImmutableButterfly* Structure::cachedOwnKeys() const228 {229 if (!hasRareData())230 return nullptr;231 return rareData()->cachedOwnKeys();232 }233 234 inline bool Structure::canCacheOwnKeys() const235 {236 if (isDictionary())237 return false;238 if (hasIndexedProperties(indexingType()))239 return false;240 if (typeInfo().overridesGetPropertyNames())241 return false;242 return true;243 }244 245 222 ALWAYS_INLINE JSValue prototypeForLookupPrimitiveImpl(JSGlobalObject* globalObject, const Structure* structure) 246 223 { -
trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp
r239153 r239231 28 28 29 29 #include "AdaptiveInferredPropertyValueWatchpointBase.h" 30 #include "JSImmutableButterfly.h"31 30 #include "JSPropertyNameEnumerator.h" 32 31 #include "JSString.h" … … 72 71 visitor.append(thisObject->m_objectToStringValue); 73 72 visitor.append(thisObject->m_cachedPropertyNameEnumerator); 74 visitor.append(thisObject->m_cachedOwnKeys); 73 } 74 75 JSPropertyNameEnumerator* StructureRareData::cachedPropertyNameEnumerator() const 76 { 77 return m_cachedPropertyNameEnumerator.get(); 78 } 79 80 void StructureRareData::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator) 81 { 82 m_cachedPropertyNameEnumerator.set(vm, this, enumerator); 75 83 } 76 84 -
trunk/Source/JavaScriptCore/runtime/StructureRareData.h
r239153 r239231 59 59 static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); 60 60 61 Structure* previousID() const 62 { 63 return m_previous.get(); 64 } 61 Structure* previousID() const; 65 62 void setPreviousID(VM&, Structure*); 66 63 void clearPreviousID(); … … 72 69 void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*); 73 70 74 JSImmutableButterfly* cachedOwnKeys() const;75 JSImmutableButterfly* cachedOwnKeysConcurrently() const;76 void setCachedOwnKeys(VM&, JSImmutableButterfly*);77 78 71 Box<InlineWatchpointSet> copySharedPolyProtoWatchpoint() const { return m_polyProtoWatchpoint; } 79 72 const Box<InlineWatchpointSet>& sharedPolyProtoWatchpoint() const { return m_polyProtoWatchpoint; } 80 73 void setSharedPolyProtoWatchpoint(Box<InlineWatchpointSet>&& sharedPolyProtoWatchpoint) { m_polyProtoWatchpoint = WTFMove(sharedPolyProtoWatchpoint); } 81 74 bool hasSharedPolyProtoWatchpoint() const { return static_cast<bool>(m_polyProtoWatchpoint); } 82 83 static ptrdiff_t offsetOfCachedOwnKeys()84 {85 return OBJECT_OFFSETOF(StructureRareData, m_cachedOwnKeys);86 }87 75 88 76 DECLARE_EXPORT_INFO; … … 99 87 WriteBarrier<Structure> m_previous; 100 88 WriteBarrier<JSString> m_objectToStringValue; 101 // FIXME: We should have some story for clearing these property names caches in GC.102 // https://bugs.webkit.org/show_bug.cgi?id=192659103 89 WriteBarrier<JSPropertyNameEnumerator> m_cachedPropertyNameEnumerator; 104 WriteBarrier<JSImmutableButterfly> m_cachedOwnKeys;105 90 106 91 typedef HashMap<PropertyOffset, RefPtr<WatchpointSet>, WTF::IntHash<PropertyOffset>, WTF::UnsignedWithZeroKeyHashTraits<PropertyOffset>> PropertyWatchpointMap; -
trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h
r239155 r239231 26 26 #pragma once 27 27 28 #include "JSImmutableButterfly.h"29 #include "JSPropertyNameEnumerator.h"30 28 #include "JSString.h" 31 29 #include "StructureRareData.h" 32 30 33 31 namespace JSC { 32 33 inline Structure* StructureRareData::previousID() const 34 { 35 return m_previous.get(); 36 } 34 37 35 38 inline void StructureRareData::setPreviousID(VM& vm, Structure* structure) … … 48 51 } 49 52 50 inline JSPropertyNameEnumerator* StructureRareData::cachedPropertyNameEnumerator() const51 {52 return m_cachedPropertyNameEnumerator.get();53 }54 55 inline void StructureRareData::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)56 {57 m_cachedPropertyNameEnumerator.set(vm, this, enumerator);58 }59 60 inline JSImmutableButterfly* StructureRareData::cachedOwnKeys() const61 {62 ASSERT(!isCompilationThread());63 return m_cachedOwnKeys.get();64 }65 66 inline JSImmutableButterfly* StructureRareData::cachedOwnKeysConcurrently() const67 {68 auto* result = m_cachedOwnKeys.get();69 WTF::loadLoadFence();70 return result;71 }72 73 inline void StructureRareData::setCachedOwnKeys(VM& vm, JSImmutableButterfly* butterfly)74 {75 WTF::storeStoreFence();76 m_cachedOwnKeys.set(vm, this, butterfly);77 }78 79 53 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r239195 r239231 435 435 promiseDeferredStructure.set(*this, JSPromiseDeferred::createStructure(*this, 0, jsNull())); 436 436 internalPromiseDeferredStructure.set(*this, JSInternalPromiseDeferred::createStructure(*this, 0, jsNull())); 437 nativeStdFunctionCellStructure.set(*this, NativeStdFunctionCell::createStructure(*this, 0, jsNull()));438 437 programCodeBlockStructure.set(*this, ProgramCodeBlock::createStructure(*this, 0, jsNull())); 439 438 moduleProgramCodeBlockStructure.set(*this, ModuleProgramCodeBlock::createStructure(*this, 0, jsNull())); … … 449 448 sentinelSetBucket.set(*this, JSSet::BucketType::createSentinel(*this)); 450 449 sentinelMapBucket.set(*this, JSMap::BucketType::createSentinel(*this)); 451 sentinelImmutableButterfly.set(*this, JSImmutableButterfly::createSentinel(*this)); 452 450 451 nativeStdFunctionCellStructure.set(*this, NativeStdFunctionCell::createStructure(*this, 0, jsNull())); 453 452 smallStrings.initializeCommonStrings(*this); 454 453 -
trunk/Source/JavaScriptCore/runtime/VM.h
r239195 r239231 572 572 Strong<JSCell> sentinelSetBucket; 573 573 Strong<JSCell> sentinelMapBucket; 574 Strong<JSCell> sentinelImmutableButterfly;575 574 576 575 std::unique_ptr<PromiseDeferredTimer> promiseDeferredTimer;
Note: See TracChangeset
for help on using the changeset viewer.