Changeset 259463 in webkit
- Timestamp:
- Apr 3, 2020, 8:58:59 AM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 28 edited
-
ChangeLog (modified) (1 diff)
-
bytecode/AccessCase.cpp (modified) (3 diffs)
-
bytecode/AccessCase.h (modified) (1 diff)
-
dfg/DFGSpeculativeJIT.cpp (modified) (5 diffs)
-
ftl/FTLAbstractHeapRepository.h (modified) (1 diff)
-
ftl/FTLLowerDFGToB3.cpp (modified) (5 diffs)
-
jit/AssemblyHelpers.h (modified) (1 diff)
-
jit/JITOpcodes.cpp (modified) (1 diff)
-
jit/JITOpcodes32_64.cpp (modified) (1 diff)
-
jit/Repatch.cpp (modified) (2 diffs)
-
llint/LLIntSlowPaths.cpp (modified) (2 diffs)
-
runtime/ClonedArguments.cpp (modified) (1 diff)
-
runtime/ConcurrentJSLock.h (modified) (8 diffs)
-
runtime/JSCell.h (modified) (2 diffs)
-
runtime/JSObject.cpp (modified) (2 diffs)
-
runtime/JSObject.h (modified) (2 diffs)
-
runtime/JSObjectInlines.h (modified) (1 diff)
-
runtime/JSType.cpp (modified) (1 diff)
-
runtime/JSType.h (modified) (1 diff)
-
runtime/Structure.cpp (modified) (45 diffs)
-
runtime/Structure.h (modified) (26 diffs)
-
runtime/StructureInlines.h (modified) (16 diffs)
-
runtime/StructureRareData.cpp (modified) (3 diffs)
-
runtime/StructureRareData.h (modified) (4 diffs)
-
runtime/StructureRareDataInlines.h (modified) (1 diff)
-
runtime/StructureTransitionTable.h (modified) (1 diff)
-
tools/JSDollarVM.cpp (modified) (2 diffs)
-
wasm/js/WebAssemblyFunction.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r259444 r259463 1 2020-04-03 Yusuke Suzuki <ysuzuki@apple.com> 2 3 Unreviewed, partially reverting Structure change due to Speedometer2 regression 4 https://bugs.webkit.org/show_bug.cgi?id=207827 5 6 Not reverting WTF changes. 7 8 * bytecode/AccessCase.cpp: 9 (JSC::AccessCase::createTransition): 10 (JSC::AccessCase::createDelete): 11 (JSC::AccessCase::propagateTransitions const): 12 * bytecode/AccessCase.h: 13 (JSC::AccessCase::structure const): 14 * dfg/DFGSpeculativeJIT.cpp: 15 (JSC::DFG::SpeculativeJIT::compileCheckSubClass): 16 (JSC::DFG::SpeculativeJIT::compileObjectKeys): 17 (JSC::DFG::SpeculativeJIT::compileCreateThis): 18 (JSC::DFG::SpeculativeJIT::compileCreatePromise): 19 (JSC::DFG::SpeculativeJIT::compileCreateInternalFieldObject): 20 * ftl/FTLAbstractHeapRepository.h: 21 * ftl/FTLLowerDFGToB3.cpp: 22 (JSC::FTL::DFG::LowerDFGToB3::compileObjectKeys): 23 (JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise): 24 (JSC::FTL::DFG::LowerDFGToB3::compileCreateInternalFieldObject): 25 (JSC::FTL::DFG::LowerDFGToB3::compileCheckSubClass): 26 (JSC::FTL::DFG::LowerDFGToB3::loadStructureClassInfo): Deleted. 27 (JSC::FTL::DFG::LowerDFGToB3::loadStructureCachedPrototypeChainOrRareData): Deleted. 28 * jit/AssemblyHelpers.h: 29 (JSC::AssemblyHelpers::emitLoadClassInfoFromStructure): Deleted. 30 * jit/JITOpcodes.cpp: 31 (JSC::JIT::emit_op_create_this): 32 * jit/JITOpcodes32_64.cpp: 33 (JSC::JIT::emit_op_create_this): 34 * jit/Repatch.cpp: 35 (JSC::tryCachePutByID): 36 (JSC::tryCacheDeleteBy): 37 * llint/LLIntSlowPaths.cpp: 38 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 39 * runtime/ClonedArguments.cpp: 40 (JSC::ClonedArguments::createStructure): 41 * runtime/ConcurrentJSLock.h: 42 (JSC::ConcurrentJSLockerBase::ConcurrentJSLockerBase): 43 (JSC::GCSafeConcurrentJSLocker::GCSafeConcurrentJSLocker): 44 (JSC::GCSafeConcurrentJSLocker::~GCSafeConcurrentJSLocker): 45 (JSC::ConcurrentJSLocker::ConcurrentJSLocker): 46 (JSC::GCSafeConcurrentJSLockerImpl::GCSafeConcurrentJSLockerImpl): Deleted. 47 (JSC::GCSafeConcurrentJSLockerImpl::~GCSafeConcurrentJSLockerImpl): Deleted. 48 (JSC::ConcurrentJSLockerImpl::ConcurrentJSLockerImpl): Deleted. 49 * runtime/JSCell.h: 50 * runtime/JSObject.cpp: 51 (JSC::JSObject::deleteProperty): 52 (JSC::JSObject::shiftButterflyAfterFlattening): 53 * runtime/JSObject.h: 54 (JSC::JSObject::getDirectConcurrently const): 55 * runtime/JSObjectInlines.h: 56 (JSC::JSObject::prepareToPutDirectWithoutTransition): 57 * runtime/JSType.cpp: 58 (WTF::printInternal): 59 * runtime/JSType.h: 60 * runtime/Structure.cpp: 61 (JSC::StructureTransitionTable::contains const): 62 (JSC::StructureTransitionTable::get const): 63 (JSC::StructureTransitionTable::add): 64 (JSC::Structure::dumpStatistics): 65 (JSC::Structure::Structure): 66 (JSC::Structure::create): 67 (JSC::Structure::findStructuresAndMapForMaterialization): 68 (JSC::Structure::materializePropertyTable): 69 (JSC::Structure::addPropertyTransitionToExistingStructureImpl): 70 (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently): 71 (JSC::Structure::addNewPropertyTransition): 72 (JSC::Structure::removePropertyTransitionFromExistingStructureConcurrently): 73 (JSC::Structure::removeNewPropertyTransition): 74 (JSC::Structure::changePrototypeTransition): 75 (JSC::Structure::attributeChangeTransition): 76 (JSC::Structure::toDictionaryTransition): 77 (JSC::Structure::takePropertyTableOrCloneIfPinned): 78 (JSC::Structure::nonPropertyTransitionSlow): 79 (JSC::Structure::flattenDictionaryStructure): 80 (JSC::Structure::pin): 81 (JSC::Structure::pinForCaching): 82 (JSC::Structure::allocateRareData): 83 (JSC::Structure::ensurePropertyReplacementWatchpointSet): 84 (JSC::Structure::copyPropertyTableForPinning): 85 (JSC::Structure::add): 86 (JSC::Structure::remove): 87 (JSC::Structure::visitChildren): 88 (JSC::Structure::canCachePropertyNameEnumerator const): 89 * runtime/Structure.h: 90 * runtime/StructureInlines.h: 91 (JSC::Structure::get): 92 (JSC::Structure::forEachPropertyConcurrently): 93 (JSC::Structure::transitivelyTransitionedFrom): 94 (JSC::Structure::prototypeChain const): 95 (JSC::Structure::propertyReplacementWatchpointSet): 96 (JSC::Structure::checkOffsetConsistency const): 97 (JSC::Structure::add): 98 (JSC::Structure::remove): 99 (JSC::Structure::removePropertyWithoutTransition): 100 (JSC::Structure::setPropertyTable): 101 (JSC::Structure::setPreviousID): 102 (JSC::Structure::ruleOutUnseenProperty const): Deleted. 103 (JSC::Structure::seenProperties const): Deleted. 104 (JSC::Structure::addPropertyHashAndSeenProperty): Deleted. 105 (JSC::Structure::cachedPrototypeChain const): Deleted. 106 (JSC::Structure::setCachedPrototypeChain): Deleted. 107 (JSC::Structure::clearPropertyTable): Deleted. 108 (JSC::Structure::setOutOfLineTypeFlags): Deleted. 109 (JSC::Structure::setInlineCapacity): Deleted. 110 (JSC::Structure::setClassInfo): Deleted. 111 (JSC::Structure::clearPreviousID): Deleted. 112 * runtime/StructureRareData.cpp: 113 (JSC::StructureRareData::createStructure): 114 (JSC::StructureRareData::create): 115 (JSC::StructureRareData::StructureRareData): 116 (JSC::StructureRareData::visitChildren): 117 * runtime/StructureRareData.h: 118 * runtime/StructureRareDataInlines.h: 119 (JSC::StructureRareData::setPreviousID): 120 (JSC::StructureRareData::clearPreviousID): 121 (JSC::StructureRareData::setCachedPrototypeChain): Deleted. 122 * runtime/StructureTransitionTable.h: 123 * tools/JSDollarVM.cpp: 124 (JSC::JSDollarVMHelper::functionGetStructureTransitionList): 125 * wasm/js/WebAssemblyFunction.cpp: 126 (JSC::WebAssemblyFunction::jsCallEntrypointSlow): 127 1 128 2020-04-02 Alexey Shvayka <shvaikalesh@gmail.com> 2 129 -
trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp
r259175 r259463 113 113 const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain) 114 114 { 115 RELEASE_ASSERT(oldStructure == newStructure->previousID( vm));115 RELEASE_ASSERT(oldStructure == newStructure->previousID()); 116 116 117 117 // Skip optimizing the case where we need a realloc, if we don't have … … 129 129 VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure) 130 130 { 131 RELEASE_ASSERT(oldStructure == newStructure->previousID( vm));131 RELEASE_ASSERT(oldStructure == newStructure->previousID()); 132 132 // We do not cache this case so that we do not need to check the jscell, e.g. TypedArray cells require a check for neutering status. 133 133 // See the Delete code below. … … 743 743 case Transition: 744 744 case Delete: 745 if (visitor.vm().heap.isMarked(m_structure->previousID( visitor.vm())))745 if (visitor.vm().heap.isMarked(m_structure->previousID())) 746 746 visitor.appendUnbarriered(m_structure.get()); 747 747 else -
trunk/Source/JavaScriptCore/bytecode/AccessCase.h
r257399 r259463 164 164 { 165 165 if (m_type == Transition || m_type == Delete) 166 return m_structure->previousID( m_structure->vm());166 return m_structure->previousID(); 167 167 return m_structure.get(); 168 168 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r259320 r259463 9569 9569 9570 9570 m_jit.emitLoadStructure(vm(), baseGPR, otherGPR, specifiedGPR); 9571 m_jit. emitLoadClassInfoFromStructure(otherGPR, otherGPR);9571 m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR); 9572 9572 m_jit.move(CCallHelpers::TrustedImmPtr(node->classInfo()), specifiedGPR); 9573 9573 … … 12662 12662 CCallHelpers::JumpList slowCases; 12663 12663 m_jit.emitLoadStructure(vm(), objectGPR, structureGPR, scratchGPR); 12664 m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::offsetOfCachedPrototypeChainOrRareData()), scratchGPR); 12665 #if CPU(ADDRESS64) 12666 m_jit.andPtr(CCallHelpers::TrustedImmPtr(Structure::cachedPrototypeChainOrRareDataMask), scratchGPR); 12667 #endif 12664 m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::previousOrRareDataOffset()), scratchGPR); 12668 12665 12669 12666 slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratchGPR)); 12670 slowCases.append(m_jit.branch32(CCallHelpers:: NotEqual, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(vm().structureRareDataStructure->structureID()))));12667 slowCases.append(m_jit.branch32(CCallHelpers::Equal, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(vm().structureStructure->structureID())))); 12671 12668 12672 12669 m_jit.loadPtr(CCallHelpers::Address(scratchGPR, StructureRareData::offsetOfCachedOwnKeys()), scratchGPR); … … 12806 12803 emitAllocateJSObject(resultGPR, JITAllocator::variable(), allocatorGPR, structureGPR, butterfly, scratchGPR, slowPath); 12807 12804 12808 m_jit.load8(JITCompiler::Address(structureGPR, Structure:: offsetOfInlineCapacity()), inlineCapacityGPR);12805 m_jit.load8(JITCompiler::Address(structureGPR, Structure::inlineCapacityOffset()), inlineCapacityGPR); 12809 12806 m_jit.emitInitializeInlineStorage(resultGPR, inlineCapacityGPR); 12810 12807 m_jit.mutatorFence(vm()); … … 12844 12841 m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure() - JSFunction::rareDataTag), structureGPR); 12845 12842 slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR)); 12846 m_jit. emitLoadClassInfoFromStructure(structureGPR, scratch1GPR);12847 slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())));12843 m_jit.move(TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info()), scratch1GPR); 12844 slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset()))); 12848 12845 m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR); 12849 12846 slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset()))); … … 12892 12889 m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure() - JSFunction::rareDataTag), structureGPR); 12893 12890 slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR)); 12894 m_jit. emitLoadClassInfoFromStructure(structureGPR, scratch1GPR);12895 slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, TrustedImmPtr(JSClass::info())));12891 m_jit.move(TrustedImmPtr(JSClass::info()), scratch1GPR); 12892 slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset()))); 12896 12893 m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR); 12897 12894 slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset()))); -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r257201 r259463 140 140 macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \ 141 141 macro(StringImpl_length, StringImpl::lengthMemoryOffset()) \ 142 macro(Structure_classInfo, Structure:: offsetOfClassInfo()) \142 macro(Structure_classInfo, Structure::classInfoOffset()) \ 143 143 macro(Structure_globalObject, Structure::globalObjectOffset()) \ 144 144 macro(Structure_indexingModeIncludingHistory, Structure::indexingModeIncludingHistoryOffset()) \ 145 macro(Structure_inlineCapacity, Structure:: offsetOfInlineCapacity()) \146 macro(Structure_ cachedPrototypeChainOrRareData, Structure::offsetOfCachedPrototypeChainOrRareData()) \145 macro(Structure_inlineCapacity, Structure::inlineCapacityOffset()) \ 146 macro(Structure_previousOrRareData, Structure::previousOrRareDataOffset()) \ 147 147 macro(Structure_prototype, Structure::prototypeOffset()) \ 148 148 macro(Structure_structureID, Structure::structureIDOffset()) \ -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r259320 r259463 6252 6252 LValue object = lowObject(m_node->child1()); 6253 6253 LValue structure = loadStructure(object); 6254 LValue cachedPrototypeChainOrRareData = loadStructureCachedPrototypeChainOrRareData(structure);6255 m_out.branch(m_out.notNull( cachedPrototypeChainOrRareData), unsure(notNullCase), unsure(slowCase));6254 LValue previousOrRareData = m_out.loadPtr(structure, m_heaps.Structure_previousOrRareData); 6255 m_out.branch(m_out.notNull(previousOrRareData), unsure(notNullCase), unsure(slowCase)); 6256 6256 6257 6257 LBasicBlock lastNext = m_out.appendTo(notNullCase, rareDataCase); 6258 6258 m_out.branch( 6259 m_out. equal(m_out.load32(cachedPrototypeChainOrRareData, m_heaps.JSCell_structureID), m_out.constInt32(m_graph.m_vm.structureRareDataStructure->structureID())),6259 m_out.notEqual(m_out.load32(previousOrRareData, m_heaps.JSCell_structureID), m_out.constInt32(m_graph.m_vm.structureStructure->structureID())), 6260 6260 unsure(rareDataCase), unsure(slowCase)); 6261 6261 6262 6262 m_out.appendTo(rareDataCase, useCacheCase); 6263 6263 ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedOwnKeysSentinel()) == 1); 6264 LValue cachedOwnKeys = m_out.loadPtr( cachedPrototypeChainOrRareData, m_heaps.StructureRareData_cachedOwnKeys);6264 LValue cachedOwnKeys = m_out.loadPtr(previousOrRareData, m_heaps.StructureRareData_cachedOwnKeys); 6265 6265 m_out.branch(m_out.belowOrEqual(cachedOwnKeys, m_out.constIntPtr(bitwise_cast<void*>(StructureRareData::cachedOwnKeysSentinel()))), unsure(slowCase), unsure(useCacheCase)); 6266 6266 … … 6836 6836 6837 6837 m_out.appendTo(hasStructure, checkGlobalObjectCase); 6838 LValue classInfo = loadStructureClassInfo(structure); 6839 m_out.branch(m_out.equal(classInfo, m_out.constIntPtr(m_node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())), usually(checkGlobalObjectCase), rarely(slowCase)); 6838 m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(m_node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())), usually(checkGlobalObjectCase), rarely(slowCase)); 6840 6839 6841 6840 m_out.appendTo(checkGlobalObjectCase, fastAllocationCase); … … 6892 6891 6893 6892 m_out.appendTo(hasStructure, checkGlobalObjectCase); 6894 LValue classInfo = loadStructureClassInfo(structure); 6895 m_out.branch(m_out.equal(classInfo, m_out.constIntPtr(JSClass::info())), usually(checkGlobalObjectCase), rarely(slowCase)); 6893 m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(JSClass::info())), usually(checkGlobalObjectCase), rarely(slowCase)); 6896 6894 6897 6895 m_out.appendTo(checkGlobalObjectCase, fastAllocationCase); … … 13383 13381 13384 13382 LValue structure = loadStructure(cell); 13385 LValue classInfo = loadStructureClassInfo(structure);13383 LValue classInfo = m_out.loadPtr(structure, m_heaps.Structure_classInfo); 13386 13384 ValueFromBlock otherAtStart = m_out.anchor(classInfo); 13387 13385 m_out.jump(loop); … … 18399 18397 } 18400 18398 18401 LValue loadStructureClassInfo(LValue structure)18402 {18403 LValue result = m_out.loadPtr(structure, m_heaps.Structure_classInfo);18404 #if CPU(ADDRESS64)18405 return m_out.bitAnd(m_out.constIntPtr(Structure::classInfoMask), result);18406 #else18407 return result;18408 #endif18409 }18410 18411 LValue loadStructureCachedPrototypeChainOrRareData(LValue structure)18412 {18413 LValue result = m_out.loadPtr(structure, m_heaps.Structure_cachedPrototypeChainOrRareData);18414 #if CPU(ADDRESS64)18415 return m_out.bitAnd(m_out.constIntPtr(Structure::cachedPrototypeChainOrRareDataMask), result);18416 #else18417 return result;18418 #endif18419 }18420 18421 18399 LValue weakPointer(JSCell* pointer) 18422 18400 { -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h
r258952 r259463 1535 1535 1536 1536 void emitLoadStructure(VM&, RegisterID source, RegisterID dest, RegisterID scratch); 1537 1538 void emitLoadClassInfoFromStructure(RegisterID structure, RegisterID dst)1539 {1540 loadPtr(Address(structure, Structure::offsetOfClassInfo()), dst);1541 #if CPU(ADDRESS64)1542 andPtr(TrustedImmPtr(bitwise_cast<void*>(Structure::classInfoMask)), dst);1543 #endif1544 }1545 1537 1546 1538 void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID) -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r258874 r259463 980 980 auto butterfly = TrustedImmPtr(nullptr); 981 981 emitAllocateJSObject(resultReg, JITAllocator::variable(), allocatorReg, structureReg, butterfly, scratchReg, slowCases); 982 load8(Address(structureReg, Structure:: offsetOfInlineCapacity()), scratchReg);982 load8(Address(structureReg, Structure::inlineCapacityOffset()), scratchReg); 983 983 emitInitializeInlineStorage(resultReg, scratchReg); 984 984 addSlowCase(slowCases); -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r258874 r259463 1094 1094 auto butterfly = TrustedImmPtr(nullptr); 1095 1095 emitAllocateJSObject(resultReg, JITAllocator::variable(), allocatorReg, structureReg, butterfly, scratchReg, slowCases); 1096 load8(Address(structureReg, Structure:: offsetOfInlineCapacity()), scratchReg);1096 load8(Address(structureReg, Structure::inlineCapacityOffset()), scratchReg); 1097 1097 emitInitializeInlineStorage(resultReg, scratchReg); 1098 1098 addSlowCase(slowCases); -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r259357 r259463 619 619 return GiveUpOnCache; 620 620 621 ASSERT(newStructure->previousID( vm) == oldStructure);621 ASSERT(newStructure->previousID() == oldStructure); 622 622 ASSERT(!newStructure->isDictionary()); 623 623 ASSERT(newStructure->isObject()); … … 767 767 return GiveUpOnCache; 768 768 ASSERT(newOffset == slot.cachedOffset()); 769 ASSERT(newStructure->previousID( vm) == oldStructure);769 ASSERT(newStructure->previousID() == oldStructure); 770 770 ASSERT(newStructure->isPropertyDeletionTransition()); 771 771 ASSERT(newStructure->isObject()); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r257399 r259463 856 856 Structure* b = baseValue.asCell()->structure(vm); 857 857 if (slot.type() == PutPropertySlot::NewProperty) 858 b = b->previousID( vm);858 b = b->previousID(); 859 859 860 860 if (Structure::shouldConvertToPolyProto(a, b)) { … … 877 877 if (slot.type() == PutPropertySlot::NewProperty) { 878 878 GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap); 879 if (!newStructure->isDictionary() && newStructure->previousID( vm)->outOfLineCapacity() == newStructure->outOfLineCapacity()) {880 ASSERT(oldStructure == newStructure->previousID( vm));881 if (oldStructure == newStructure->previousID( vm)) {879 if (!newStructure->isDictionary() && newStructure->previousID()->outOfLineCapacity() == newStructure->outOfLineCapacity()) { 880 ASSERT(oldStructure == newStructure->previousID()); 881 if (oldStructure == newStructure->previousID()) { 882 882 ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); 883 883 -
trunk/Source/JavaScriptCore/runtime/ClonedArguments.cpp
r257399 r259463 154 154 structure->addPropertyWithoutTransition( 155 155 vm, vm.propertyNames->length, static_cast<unsigned>(PropertyAttribute::DontEnum), 156 [&] (const GCSafeConcurrentJSCellLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {156 [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) { 157 157 RELEASE_ASSERT(offset == clonedArgumentsLengthPropertyOffset); 158 158 structure->setMaxOffset(vm, newMaxOffset); -
trunk/Source/JavaScriptCore/runtime/ConcurrentJSLock.h
r257201 r259463 34 34 35 35 using ConcurrentJSLock = Lock; 36 using ConcurrentJSLockerImpl = LockHolder; 36 37 37 static_assert(sizeof(ConcurrentJSLock) == 1, "Regardless of status of concurrent JS flag, size of Con currentJSLock is always one byte.");38 static_assert(sizeof(ConcurrentJSLock) == 1, "Regardless of status of concurrent JS flag, size of ConurrentJSLock is always one byte."); 38 39 39 template<typename Lock>40 40 class ConcurrentJSLockerBase : public AbstractLocker { 41 41 WTF_MAKE_NONCOPYABLE(ConcurrentJSLockerBase); 42 42 public: 43 explicit ConcurrentJSLockerBase( Lock& lockable)43 explicit ConcurrentJSLockerBase(ConcurrentJSLock& lockable) 44 44 : m_locker(&lockable) 45 45 { 46 46 } 47 explicit ConcurrentJSLockerBase( Lock* lockable)47 explicit ConcurrentJSLockerBase(ConcurrentJSLock* lockable) 48 48 : m_locker(lockable) 49 49 { … … 65 65 66 66 private: 67 Locker<Lock>m_locker;67 ConcurrentJSLockerImpl m_locker; 68 68 }; 69 69 70 template<typename Lock> 71 class GCSafeConcurrentJSLockerImpl : public ConcurrentJSLockerBase<Lock> { 70 class GCSafeConcurrentJSLocker : public ConcurrentJSLockerBase { 72 71 public: 73 GCSafeConcurrentJSLocker Impl(Lock& lockable, Heap& heap)74 : ConcurrentJSLockerBase <Lock>(lockable)72 GCSafeConcurrentJSLocker(ConcurrentJSLock& lockable, Heap& heap) 73 : ConcurrentJSLockerBase(lockable) 75 74 , m_deferGC(heap) 76 75 { 77 76 } 78 77 79 GCSafeConcurrentJSLocker Impl(Lock* lockable, Heap& heap)80 : ConcurrentJSLockerBase <Lock>(lockable)78 GCSafeConcurrentJSLocker(ConcurrentJSLock* lockable, Heap& heap) 79 : ConcurrentJSLockerBase(lockable) 81 80 , m_deferGC(heap) 82 81 { 83 82 } 84 83 85 ~GCSafeConcurrentJSLocker Impl()84 ~GCSafeConcurrentJSLocker() 86 85 { 87 86 // We have to unlock early due to the destruction order of base … … 89 88 // DeferGC object before unlocking the lock which could cause a GC 90 89 // and resulting deadlock. 91 ConcurrentJSLockerBase<Lock>::unlockEarly();90 unlockEarly(); 92 91 } 93 92 … … 96 95 }; 97 96 98 template<typename Lock> 99 class ConcurrentJSLockerImpl : public ConcurrentJSLockerBase<Lock> { 97 class ConcurrentJSLocker : public ConcurrentJSLockerBase { 100 98 public: 101 ConcurrentJSLocker Impl(Lock& lockable)102 : ConcurrentJSLockerBase <Lock>(lockable)99 ConcurrentJSLocker(ConcurrentJSLock& lockable) 100 : ConcurrentJSLockerBase(lockable) 103 101 #if !defined(NDEBUG) 104 102 , m_disallowGC(std::in_place) … … 107 105 } 108 106 109 ConcurrentJSLocker Impl(Lock* lockable)110 : ConcurrentJSLockerBase <Lock>(lockable)107 ConcurrentJSLocker(ConcurrentJSLock* lockable) 108 : ConcurrentJSLockerBase(lockable) 111 109 #if !defined(NDEBUG) 112 110 , m_disallowGC(std::in_place) … … 115 113 } 116 114 117 ConcurrentJSLocker Impl(NoLockingNecessaryTag)118 : ConcurrentJSLockerBase <Lock>(NoLockingNecessary)115 ConcurrentJSLocker(NoLockingNecessaryTag) 116 : ConcurrentJSLockerBase(NoLockingNecessary) 119 117 #if !defined(NDEBUG) 120 118 , m_disallowGC(WTF::nullopt) … … 123 121 } 124 122 125 ConcurrentJSLocker Impl(int) = delete;123 ConcurrentJSLocker(int) = delete; 126 124 127 125 #if !defined(NDEBUG) … … 131 129 }; 132 130 133 using ConcurrentJSLocker = ConcurrentJSLockerImpl<ConcurrentJSLock>;134 using GCSafeConcurrentJSLocker = GCSafeConcurrentJSLockerImpl<ConcurrentJSLock>;135 136 131 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r258386 r259463 25 25 #include "CallData.h" 26 26 #include "CellState.h" 27 #include "ConcurrentJSLock.h"28 27 #include "ConstructData.h" 29 28 #include "EnumerationMode.h" … … 291 290 }; 292 291 293 using ConcurrentJSCellLocker = ConcurrentJSLockerImpl<JSCellLock>;294 using GCSafeConcurrentJSCellLocker = GCSafeConcurrentJSLockerImpl<JSCellLock>;295 296 292 // FIXME: Refer to Subspace by reference. 297 293 // https://bugs.webkit.org/show_bug.cgi?id=166988 -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r258170 r259463 2008 2008 PropertyOffset offset = invalidOffset; 2009 2009 if (structure->isUncacheableDictionary()) 2010 offset = structure->removePropertyWithoutTransition(vm, propertyName, [] (const GCSafeConcurrentJSCellLocker&, PropertyOffset, PropertyOffset) { });2010 offset = structure->removePropertyWithoutTransition(vm, propertyName, [] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset) { }); 2011 2011 else { 2012 2012 structure = Structure::removePropertyTransition(vm, structure, propertyName, offset, &deferredWatchpointFire); … … 3777 3777 } 3778 3778 3779 void JSObject::shiftButterflyAfterFlattening(const GCSafeConcurrentJS CellLocker&, VM& vm, Structure* structure, size_t outOfLineCapacityAfter)3779 void JSObject::shiftButterflyAfterFlattening(const GCSafeConcurrentJSLocker&, VM& vm, Structure* structure, size_t outOfLineCapacityAfter) 3780 3780 { 3781 3781 // This could interleave visitChildren because some old structure could have been a non -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r258059 r259463 811 811 structure(vm)->flattenDictionaryStructure(vm, this); 812 812 } 813 void shiftButterflyAfterFlattening(const GCSafeConcurrentJS CellLocker&, VM&, Structure*, size_t outOfLineCapacityAfter);813 void shiftButterflyAfterFlattening(const GCSafeConcurrentJSLocker&, VM&, Structure* structure, size_t outOfLineCapacityAfter); 814 814 815 815 JSGlobalObject* globalObject() const … … 1327 1327 inline JSValue JSObject::getDirectConcurrently(Structure* structure, PropertyOffset offset) const 1328 1328 { 1329 ConcurrentJS CellLocker locker(structure->cellLock());1329 ConcurrentJSLocker locker(structure->lock()); 1330 1330 if (!structure->isValidOffset(offset)) 1331 1331 return { }; -
trunk/Source/JavaScriptCore/runtime/JSObjectInlines.h
r258059 r259463 217 217 structure->addPropertyWithoutTransition( 218 218 vm, propertyName, attributes, 219 [&] (const GCSafeConcurrentJSCellLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {219 [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) { 220 220 unsigned newOutOfLineCapacity = Structure::outOfLineCapacity(newMaxOffset); 221 221 if (newOutOfLineCapacity != oldOutOfLineCapacity) { -
trunk/Source/JavaScriptCore/runtime/JSType.cpp
r257201 r259463 45 45 CASE(SymbolType) 46 46 CASE(BigIntType) 47 CASE(StructureRareDataType)48 47 CASE(CustomGetterSetterType) 49 48 CASE(APIValueWrapperType) -
trunk/Source/JavaScriptCore/runtime/JSType.h
r257270 r259463 31 31 SymbolType, 32 32 33 StructureRareDataType,34 33 GetterSetterType, 35 34 CustomGetterSetterType, -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r257399 r259463 92 92 if (isUsingSingleSlot()) { 93 93 Structure* transition = singleTransition(); 94 return transition && transition-> transitionPropertyName()== rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition;94 return transition && transition->m_transitionPropertyName == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition; 95 95 } 96 96 return map()->get(StructureTransitionTable::Hash::Key(rep, attributes, isAddition)); … … 101 101 if (isUsingSingleSlot()) { 102 102 Structure* transition = singleTransition(); 103 return (transition && transition-> transitionPropertyName() == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition) ? transition : nullptr;103 return (transition && transition->m_transitionPropertyName == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition) ? transition : 0; 104 104 } 105 105 return map()->get(StructureTransitionTable::Hash::Key(rep, attributes, isAddition)); … … 124 124 125 125 // Add the structure to the map. 126 map()->set(StructureTransitionTable::Hash::Key(structure-> transitionPropertyName(), structure->transitionPropertyAttributes(), !structure->isPropertyDeletionTransition()), structure);126 map()->set(StructureTransitionTable::Hash::Key(structure->m_transitionPropertyName.get(), structure->transitionPropertyAttributes(), !structure->isPropertyDeletionTransition()), structure); 127 127 } 128 128 … … 143 143 case 0: 144 144 ++numberLeaf; 145 if (!structure->previousID( structure->vm()))145 if (!structure->previousID()) 146 146 ++numberSingletons; 147 147 break; … … 152 152 } 153 153 154 if (PropertyTable* table = structure->propertyTable UnsafeOrNull()) {154 if (PropertyTable* table = structure->propertyTableOrNull()) { 155 155 ++numberWithPropertyMaps; 156 156 totalPropertyMapsSize += table->sizeInMemory(); … … 175 175 : JSCell(vm, vm.structureStructure.get()) 176 176 , m_blob(vm.heap.structureIDTable().allocateID(this), indexingType, typeInfo) 177 , m_outOfLineTypeFlags(typeInfo.outOfLineTypeFlags()) 178 , m_inlineCapacity(inlineCapacity) 179 , m_bitField(0) 177 180 , m_globalObject(vm, this, globalObject, WriteBarrier<JSGlobalObject>::MayBeNull) 178 181 , m_prototype(vm, this, prototype) 182 , m_classInfo(classInfo) 179 183 , m_transitionWatchpointSet(IsWatched) 180 { 181 setInlineCapacity(inlineCapacity); 182 setClassInfo(classInfo); 184 , m_propertyHash(0) 185 { 183 186 setDictionaryKind(NoneDictionaryKind); 184 187 setIsPinnedPropertyTable(false); … … 198 201 setTransitionOffset(vm, invalidOffset); 199 202 setMaxOffset(vm, invalidOffset); 200 setOutOfLineTypeFlags(typeInfo.outOfLineTypeFlags()); 201 203 202 204 ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity()); 203 205 ASSERT(static_cast<PropertyOffset>(inlineCapacity) < firstOutOfLineOffset); 204 206 ASSERT(!hasRareData()); 205 ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || ! this->classInfo()->hasStaticSetterOrReadonlyProperties());206 ASSERT(hasGetterSetterProperties() || ! this->classInfo()->hasStaticSetterOrReadonlyProperties());207 ASSERT(!this->typeInfo().overridesGetCallData() || this->classInfo()->methodTable.getCallData != &JSCell::getCallData);207 ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 208 ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 209 ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData); 208 210 } 209 211 … … 212 214 Structure::Structure(VM& vm) 213 215 : JSCell(CreatingEarlyCell) 216 , m_inlineCapacity(0) 217 , m_bitField(0) 214 218 , m_prototype(vm, this, jsNull()) 219 , m_classInfo(info()) 215 220 , m_transitionWatchpointSet(IsWatched) 216 { 217 setInlineCapacity(0); 218 setClassInfo(info()); 221 , m_propertyHash(0) 222 { 219 223 setDictionaryKind(NoneDictionaryKind); 220 224 setIsPinnedPropertyTable(false); 221 setHasGetterSetterProperties( classInfo()->hasStaticSetterOrReadonlyProperties());225 setHasGetterSetterProperties(m_classInfo->hasStaticSetterOrReadonlyProperties()); 222 226 setHasCustomGetterSetterProperties(false); 223 setHasReadOnlyOrGetterSetterPropertiesExcludingProto( classInfo()->hasStaticSetterOrReadonlyProperties());227 setHasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties()); 224 228 setHasUnderscoreProtoPropertyExcludingOriginalProto(false); 225 229 setIsQuickPropertyAccessAllowedForEnumeration(true); … … 237 241 TypeInfo typeInfo = TypeInfo(CellType, StructureFlags); 238 242 m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo); 239 setOutOfLineTypeFlags(typeInfo.outOfLineTypeFlags());240 241 ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || ! classInfo()->hasStaticSetterOrReadonlyProperties());242 ASSERT(hasGetterSetterProperties() || ! classInfo()->hasStaticSetterOrReadonlyProperties());243 ASSERT(!this->typeInfo().overridesGetCallData() || classInfo()->methodTable.getCallData != &JSCell::getCallData);243 m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags(); 244 245 ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 246 ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 247 ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData); 244 248 } 245 249 246 250 Structure::Structure(VM& vm, Structure* previous, DeferredStructureTransitionWatchpointFire* deferred) 247 251 : JSCell(vm, vm.structureStructure.get()) 248 #if CPU(ADDRESS64) 249 , m_propertyHashAndSeenProperties(previous->m_propertyHashAndSeenProperties) 250 #else 252 , m_inlineCapacity(previous->m_inlineCapacity) 253 , m_bitField(0) 254 , m_prototype(vm, this, previous->m_prototype.get()) 255 , m_classInfo(previous->m_classInfo) 256 , m_transitionWatchpointSet(IsWatched) 251 257 , m_propertyHash(previous->m_propertyHash) 252 258 , m_seenProperties(previous->m_seenProperties) 253 #endif 254 , m_prototype(vm, this, previous->m_prototype.get()) 255 , m_transitionWatchpointSet(IsWatched) 256 { 257 setInlineCapacity(previous->inlineCapacity()); 258 setClassInfo(previous->classInfo()); 259 { 259 260 setDictionaryKind(previous->dictionaryKind()); 260 261 setIsPinnedPropertyTable(false); … … 277 278 TypeInfo typeInfo = previous->typeInfo(); 278 279 m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingModeIncludingHistory(), typeInfo); 279 setOutOfLineTypeFlags(typeInfo.outOfLineTypeFlags());280 m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags(); 280 281 281 282 ASSERT(!previous->typeInfo().structureIsImmortal()); … … 289 290 if (previous->m_globalObject) 290 291 m_globalObject.set(vm, this, previous->m_globalObject.get()); 291 ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || ! classInfo()->hasStaticSetterOrReadonlyProperties());292 ASSERT(hasGetterSetterProperties() || ! classInfo()->hasStaticSetterOrReadonlyProperties());293 ASSERT(!this->typeInfo().overridesGetCallData() || classInfo()->methodTable.getCallData != &JSCell::getCallData);292 ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 293 ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 294 ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData); 294 295 } 295 296 … … 313 314 result->addPropertyWithoutTransition( 314 315 vm, vm.propertyNames->builtinNames().polyProtoName(), static_cast<unsigned>(PropertyAttribute::DontEnum), 315 [&] (const GCSafeConcurrentJSCellLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {316 [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) { 316 317 RELEASE_ASSERT(Structure::outOfLineCapacity(newMaxOffset) == oldOutOfLineCapacity); 317 318 RELEASE_ASSERT(offset == knownPolyProtoOffset); … … 329 330 } 330 331 331 void Structure::findStructuresAndMapForMaterialization(V M& vm, Vector<Structure*, 8>& structures, Structure*& structure, PropertyTable*& table)332 void Structure::findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*& structure, PropertyTable*& table) 332 333 { 333 334 ASSERT(structures.isEmpty()); 334 table = nullptr;335 336 for (structure = this; structure; structure = structure->previousID( vm)) {337 structure-> cellLock().lock();335 table = 0; 336 337 for (structure = this; structure; structure = structure->previousID()) { 338 structure->m_lock.lock(); 338 339 339 table = structure->propertyTable UnsafeOrNull();340 table = structure->propertyTableOrNull(); 340 341 if (table) { 341 342 // Leave the structure locked, so that the caller can do things to it atomically … … 345 346 346 347 structures.append(structure); 347 structure-> cellLock().unlock();348 structure->m_lock.unlock(); 348 349 } 349 350 … … 363 364 PropertyTable* table; 364 365 365 findStructuresAndMapForMaterialization( vm,structures, structure, table);366 367 unsigned capacity = numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity());366 findStructuresAndMapForMaterialization(structures, structure, table); 367 368 unsigned capacity = numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity); 368 369 if (table) { 369 370 table = table->copy(vm, capacity); 370 structure-> cellLock().unlock();371 structure->m_lock.unlock(); 371 372 } else 372 373 table = PropertyTable::create(vm, capacity); … … 375 376 // property map. We don't want getConcurrently() to see the property map in a half-baked 376 377 // state. 377 GCSafeConcurrentJS CellLocker locker(cellLock(), vm.heap);378 GCSafeConcurrentJSLocker locker(m_lock, vm.heap); 378 379 if (setPropertyTable) 379 380 this->setPropertyTable(vm, table); … … 381 382 for (size_t i = structures.size(); i--;) { 382 383 structure = structures[i]; 383 UniquedStringImpl* transitionPropertyName = structure->transitionPropertyName(); 384 if (!transitionPropertyName) 384 if (!structure->m_transitionPropertyName) 385 385 continue; 386 386 if (structure->isPropertyDeletionTransition()) { 387 auto item = table->find( transitionPropertyName);387 auto item = table->find(structure->m_transitionPropertyName.get()); 388 388 ASSERT(item.first); 389 389 table->remove(item); … … 391 391 continue; 392 392 } 393 PropertyMapEntry entry( transitionPropertyName, structure->transitionOffset(), structure->transitionPropertyAttributes());393 PropertyMapEntry entry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes()); 394 394 auto nextOffset = table->nextOffset(structure->inlineCapacity()); 395 395 ASSERT_UNUSED(nextOffset, nextOffset == structure->transitionOffset()); … … 426 426 } 427 427 428 return nullptr;428 return 0; 429 429 } 430 430 … … 437 437 Structure* Structure::addPropertyTransitionToExistingStructureConcurrently(Structure* structure, UniquedStringImpl* uid, unsigned attributes, PropertyOffset& offset) 438 438 { 439 ConcurrentJS CellLocker locker(structure->cellLock());439 ConcurrentJSLocker locker(structure->m_lock); 440 440 return addPropertyTransitionToExistingStructureImpl(structure, uid, attributes, offset); 441 441 } … … 498 498 499 499 Structure* transition = create(vm, structure, deferred); 500 transition->setCachedPrototypeChain(vm, structure->cachedPrototypeChain()); 500 501 transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get()); 501 502 502 503 // While we are adding the property, rematerializing the property table is super weird: we already … … 510 511 // protectPropertyTableWhileTransitioning before we set it to true, and then blow the table away after. 511 512 { 512 ConcurrentJS CellLocker locker(transition->cellLock());513 ConcurrentJSLocker locker(transition->m_lock); 513 514 transition->setProtectPropertyTableWhileTransitioning(true); 514 transition->setTransitionPropertyName(locker, propertyName.uid());515 515 } 516 516 517 517 transition->m_blob.setIndexingModeIncludingHistory(structure->indexingModeIncludingHistory() & ~CopyOnWrite); 518 transition->m_transitionPropertyName = propertyName.uid(); 518 519 transition->setTransitionPropertyAttributes(attributes); 519 520 transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm)); … … 530 531 checkOffset(transition->transitionOffset(), transition->inlineCapacity()); 531 532 { 532 GCSafeConcurrentJS CellLocker locker(structure->cellLock(), vm.heap);533 GCSafeConcurrentJSLocker locker(structure->m_lock, vm.heap); 533 534 structure->m_transitionTable.add(vm, transition); 534 535 } … … 578 579 if (structure->getConcurrently(propertyName.uid(), attributes) == invalidOffset) 579 580 return nullptr; 580 ConcurrentJS CellLocker locker(structure->cellLock());581 ConcurrentJSLocker locker(structure->m_lock); 581 582 return removePropertyTransitionFromExistingStructureImpl(structure, propertyName, attributes, offset); 582 583 } … … 591 592 592 593 int transitionCount = 0; 593 for (auto* s = structure; s && transitionCount <= s_maxTransitionLength; s = s->previousID( vm))594 for (auto* s = structure; s && transitionCount <= s_maxTransitionLength; s = s->previousID()) 594 595 ++transitionCount; 595 596 … … 603 604 604 605 Structure* transition = create(vm, structure, deferred); 605 transition-> setCachedPrototypeChain(vm, structure->cachedPrototypeChain());606 transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get()); 606 607 607 608 // While we are deleting the property, we need to make sure the table is not cleared. 608 609 { 609 ConcurrentJS CellLocker locker(transition->cellLock());610 ConcurrentJSLocker locker(transition->m_lock); 610 611 transition->setProtectPropertyTableWhileTransitioning(true); 611 transition->setTransitionPropertyName(locker, propertyName.uid());612 612 } 613 613 614 614 transition->m_blob.setIndexingModeIncludingHistory(structure->indexingModeIncludingHistory() & ~CopyOnWrite); 615 transition->m_transitionPropertyName = propertyName.uid(); 615 616 transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm)); 616 617 transition->setMaxOffset(vm, structure->maxOffset()); … … 628 629 checkOffset(transition->transitionOffset(), transition->inlineCapacity()); 629 630 { 630 GCSafeConcurrentJS CellLocker locker(structure->cellLock(), vm.heap);631 GCSafeConcurrentJSLocker locker(structure->m_lock, vm.heap); 631 632 structure->m_transitionTable.add(vm, transition); 632 633 } … … 646 647 647 648 PropertyTable* table = structure->copyPropertyTableForPinning(vm); 648 transition->pin(holdLock(transition-> cellLock()), vm, table);649 transition->pin(holdLock(transition->m_lock), vm, table); 649 650 transition->setMaxOffset(vm, structure->maxOffset()); 650 651 … … 659 660 660 661 PropertyTable* table = structure->copyPropertyTableForPinning(vm); 661 transition->pin(holdLock(transition-> cellLock()), vm, table);662 transition->pin(holdLock(transition->m_lock), vm, table); 662 663 transition->setMaxOffset(vm, structure->maxOffset()); 663 664 … … 681 682 682 683 PropertyTable* table = structure->copyPropertyTableForPinning(vm); 683 transition->pin(holdLock(transition-> cellLock()), vm, table);684 transition->pin(holdLock(transition->m_lock), vm, table); 684 685 transition->setMaxOffset(vm, structure->maxOffset()); 685 686 transition->setDictionaryKind(kind); … … 717 718 PropertyTable* Structure::takePropertyTableOrCloneIfPinned(VM& vm) 718 719 { 719 // This functionmust always return a property table. It can't return null.720 PropertyTable* result = propertyTable UnsafeOrNull();720 // This must always return a property table. It can't return null. 721 PropertyTable* result = propertyTableOrNull(); 721 722 if (result) { 722 723 if (isPinnedPropertyTable()) 723 724 return result->copy(vm, result->size() + 1); 724 ConcurrentJS CellLocker locker(cellLock());725 ConcurrentJSLocker locker(m_lock); 725 726 setPropertyTable(vm, nullptr); 726 727 return result; … … 759 760 760 761 PropertyTable* table = structure->copyPropertyTableForPinning(vm); 761 transition->pinForCaching(holdLock(transition-> cellLock()), vm, table);762 transition->pinForCaching(holdLock(transition->m_lock), vm, table); 762 763 transition->setMaxOffset(vm, structure->maxOffset()); 763 764 764 table = transition->propertyTable UnsafeOrNull();765 table = transition->propertyTableOrNull(); 765 766 RELEASE_ASSERT(table); 766 767 for (auto& entry : *table) { … … 777 778 778 779 if (setsReadOnlyOnNonAccessorProperties(transitionKind) 779 && !transition->propertyTable UnsafeOrNull()->isEmpty())780 && !transition->propertyTableOrNull()->isEmpty()) 780 781 transition->setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true); 781 782 782 783 if (structure->isDictionary()) { 783 784 PropertyTable* table = transition->ensurePropertyTable(vm); 784 transition->pin(holdLock(transition-> cellLock()), vm, table);785 transition->pin(holdLock(transition->m_lock), vm, table); 785 786 } else { 786 auto locker = holdLock(structure-> cellLock());787 auto locker = holdLock(structure->m_lock); 787 788 structure->m_transitionTable.add(vm, transition); 788 789 } … … 836 837 ASSERT(object->structure(vm) == this); 837 838 838 GCSafeConcurrentJS CellLocker locker(cellLock(), vm.heap);839 GCSafeConcurrentJSLocker locker(m_lock, vm.heap); 839 840 840 841 object->setStructureIDDirectly(nuke(id())); … … 843 844 size_t beforeOutOfLineCapacity = this->outOfLineCapacity(); 844 845 if (isUncacheableDictionary()) { 845 PropertyTable* table = propertyTable UnsafeOrNull();846 PropertyTable* table = propertyTableOrNull(); 846 847 ASSERT(table); 847 848 … … 857 858 for (PropertyTable::iterator iter = table->begin(); iter != end; ++iter, ++i) { 858 859 values[i] = object->getDirect(iter->offset); 859 offset = iter->offset = offsetForPropertyNumber(i, inlineCapacity());860 offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity); 860 861 } 861 862 setMaxOffset(vm, offset); … … 864 865 // Copies in our values to their compacted locations. 865 866 for (unsigned i = 0; i < propertyCount; i++) 866 object->putDirect(vm, offsetForPropertyNumber(i, inlineCapacity()), values[i]);867 object->putDirect(vm, offsetForPropertyNumber(i, m_inlineCapacity), values[i]); 867 868 868 869 table->clearDeletedOffsets(); … … 910 911 } 911 912 912 void Structure::pin(const AbstractLocker& locker, VM& vm, PropertyTable* table)913 void Structure::pin(const AbstractLocker&, VM& vm, PropertyTable* table) 913 914 { 914 915 setIsPinnedPropertyTable(true); 915 916 setPropertyTable(vm, table); 916 917 clearPreviousID(); 917 setTransitionPropertyName(locker, nullptr);918 } 919 920 void Structure::pinForCaching(const AbstractLocker& locker, VM& vm, PropertyTable* table)918 m_transitionPropertyName = nullptr; 919 } 920 921 void Structure::pinForCaching(const AbstractLocker&, VM& vm, PropertyTable* table) 921 922 { 922 923 setIsPinnedPropertyTable(true); 923 924 setPropertyTable(vm, table); 924 setTransitionPropertyName(locker, nullptr);925 m_transitionPropertyName = nullptr; 925 926 } 926 927 … … 928 929 { 929 930 ASSERT(!hasRareData()); 930 StructureRareData* rareData = StructureRareData::create(vm, cachedPrototypeChain());931 StructureRareData* rareData = StructureRareData::create(vm, previousID()); 931 932 WTF::storeStoreFence(); 932 #if CPU(ADDRESS64) 933 m_inlineCapacityAndCachedPrototypeChainOrRareData.setPointer(rareData); 934 vm.heap.writeBarrier(this, rareData); 935 #else 936 m_cachedPrototypeChainOrRareData.set(vm, this, rareData); 937 #endif 933 m_previousOrRareData.set(vm, this, rareData); 938 934 ASSERT(hasRareData()); 939 935 } … … 949 945 if (!hasRareData()) 950 946 allocateRareData(vm); 951 ConcurrentJS CellLocker locker(cellLock());947 ConcurrentJSLocker locker(m_lock); 952 948 StructureRareData* rareData = this->rareData(); 953 949 if (!rareData->m_replacementWatchpointSets) { … … 1019 1015 PropertyTable* Structure::copyPropertyTableForPinning(VM& vm) 1020 1016 { 1021 if (PropertyTable* table = propertyTable UnsafeOrNull())1017 if (PropertyTable* table = propertyTableOrNull()) 1022 1018 return PropertyTable::clone(vm, *table); 1023 1019 bool setPropertyTable = false; … … 1059 1055 return add<ShouldPin::No>( 1060 1056 vm, propertyName, attributes, 1061 [this, &vm] (const GCSafeConcurrentJSCellLocker&, PropertyOffset, PropertyOffset newMaxOffset) {1057 [this, &vm] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset newMaxOffset) { 1062 1058 setMaxOffset(vm, newMaxOffset); 1063 1059 }); … … 1066 1062 PropertyOffset Structure::remove(VM& vm, PropertyName propertyName) 1067 1063 { 1068 return remove<ShouldPin::No>(vm, propertyName, [this, &vm] (const GCSafeConcurrentJSCellLocker&, PropertyOffset, PropertyOffset newMaxOffset) {1064 return remove<ShouldPin::No>(vm, propertyName, [this, &vm] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset newMaxOffset) { 1069 1065 setMaxOffset(vm, newMaxOffset); 1070 1066 }); … … 1137 1133 Base::visitChildren(thisObject, visitor); 1138 1134 1139 ConcurrentJS CellLocker locker(thisObject->cellLock());1135 ConcurrentJSLocker locker(thisObject->m_lock); 1140 1136 1141 1137 visitor.append(thisObject->m_globalObject); 1142 visitor.append(thisObject->m_prototype); 1143 visitor.appendUnbarriered(thisObject->previousID(visitor.vm())); 1144 visitor.appendUnbarriered(thisObject->cachedPrototypeChainOrRareData()); 1138 if (!thisObject->isObject()) 1139 thisObject->m_cachedPrototypeChain.clear(); 1140 else { 1141 visitor.append(thisObject->m_prototype); 1142 visitor.append(thisObject->m_cachedPrototypeChain); 1143 } 1144 visitor.append(thisObject->m_previousOrRareData); 1145 1145 1146 1146 if (thisObject->isPinnedPropertyTable() || thisObject->protectPropertyTableWhileTransitioning()) { 1147 1147 // NOTE: This can interleave in pin(), in which case it may see a null property table. 1148 1148 // That's fine, because then the barrier will fire and we will scan this again. 1149 visitor.append Unbarriered(thisObject->propertyTableUnsafeOrNull());1149 visitor.append(thisObject->m_propertyTableUnsafe); 1150 1150 } else if (visitor.isAnalyzingHeap()) 1151 visitor.append Unbarriered(thisObject->propertyTableUnsafeOrNull());1152 else if (thisObject-> propertyTableUnsafeOrNull())1153 thisObject-> clearPropertyTable();1151 visitor.append(thisObject->m_propertyTableUnsafe); 1152 else if (thisObject->m_propertyTableUnsafe) 1153 thisObject->m_propertyTableUnsafe.clear(); 1154 1154 } 1155 1155 … … 1307 1307 return false; 1308 1308 1309 StructureChain* structureChain = cachedPrototypeChain();1309 StructureChain* structureChain = m_cachedPrototypeChain.get(); 1310 1310 ASSERT(structureChain); 1311 1311 StructureID* currentStructureID = structureChain->head(); -
trunk/Source/JavaScriptCore/runtime/Structure.h
r258427 r259463 44 44 #include "Watchpoint.h" 45 45 #include "WriteBarrierInlines.h" 46 #include <wtf/CompactRefPtrTuple.h>47 46 #include <wtf/PrintStream.h> 48 47 … … 262 261 return typeInfo().getOwnPropertySlotIsImpure(); 263 262 } 264 265 TypeInfo::OutOfLineTypeFlags outOfLineTypeFlags() const266 {267 #if CPU(ADDRESS64)268 return m_outOfLineTypeFlagsAndPropertyTableUnsafe.type();269 #else270 return m_outOfLineTypeFlags;271 #endif272 }273 263 274 264 // Type accessors. 275 TypeInfo typeInfo() const { return m_blob.typeInfo( outOfLineTypeFlags()); }265 TypeInfo typeInfo() const { return m_blob.typeInfo(m_outOfLineTypeFlags); } 276 266 bool isObject() const { return typeInfo().isObject(); } 277 267 … … 328 318 bool hasRareData() const 329 319 { 330 return isRareData( cachedPrototypeChainOrRareData());320 return isRareData(m_previousOrRareData.get()); 331 321 } 332 322 … … 334 324 { 335 325 ASSERT(hasRareData()); 336 return static_cast<StructureRareData*>( cachedPrototypeChainOrRareData());326 return static_cast<StructureRareData*>(m_previousOrRareData.get()); 337 327 } 338 328 … … 340 330 { 341 331 ASSERT(hasRareData()); 342 return static_cast<const StructureRareData*>( cachedPrototypeChainOrRareData());332 return static_cast<const StructureRareData*>(m_previousOrRareData.get()); 343 333 } 344 334 345 335 const StructureRareData* rareDataConcurrently() const 346 336 { 347 JSCell* cell = cachedPrototypeChainOrRareData();337 JSCell* cell = m_previousOrRareData.get(); 348 338 if (isRareData(cell)) 349 339 return static_cast<StructureRareData*>(cell); … … 358 348 } 359 349 360 Structure* previousID(VM& vm) const 361 { 362 if (!m_previousID) 363 return nullptr; 364 return vm.getStructure(m_previousID); 350 Structure* previousID() const 351 { 352 ASSERT(structure()->classInfo() == info()); 353 // This is so written because it's used concurrently. We only load from m_previousOrRareData 354 // once, and this load is guaranteed atomic. 355 JSCell* cell = m_previousOrRareData.get(); 356 if (isRareData(cell)) 357 return static_cast<StructureRareData*>(cell)->previousID(); 358 return static_cast<Structure*>(cell); 365 359 } 366 360 bool transitivelyTransitionedFrom(Structure* structureToFind); … … 368 362 PropertyOffset maxOffset() const 369 363 { 370 #if CPU(ADDRESS64)371 uint16_t maxOffset = m_maxOffsetAndTransitionPropertyName.type();372 #else373 364 uint16_t maxOffset = m_maxOffset; 374 #endif375 365 if (maxOffset == shortInvalidOffset) 376 366 return invalidOffset; … … 382 372 void setMaxOffset(VM& vm, PropertyOffset offset) 383 373 { 384 ASSERT(!isCompilationThread() && !Thread::mayBeGCThread()); 385 auto commit = [&](uint16_t value) { 386 #if CPU(ADDRESS64) 387 m_maxOffsetAndTransitionPropertyName.setType(value); 388 #else 389 m_maxOffset = value; 390 #endif 391 }; 392 393 if (offset == invalidOffset) { 394 commit(shortInvalidOffset); 395 return; 374 if (offset == invalidOffset) 375 m_maxOffset = shortInvalidOffset; 376 else if (offset < useRareDataFlag && offset < shortInvalidOffset) 377 m_maxOffset = offset; 378 else if (m_maxOffset == useRareDataFlag) 379 rareData()->m_maxOffset = offset; 380 else { 381 ensureRareData(vm)->m_maxOffset = offset; 382 WTF::storeStoreFence(); 383 m_maxOffset = useRareDataFlag; 396 384 } 397 if (offset < useRareDataFlag && offset < shortInvalidOffset) {398 commit(offset);399 return;400 }401 #if CPU(ADDRESS64)402 uint16_t maxOffset = m_maxOffsetAndTransitionPropertyName.type();403 #else404 uint16_t maxOffset = m_maxOffset;405 #endif406 if (maxOffset == useRareDataFlag) {407 rareData()->m_maxOffset = offset;408 return;409 }410 411 ensureRareData(vm)->m_maxOffset = offset;412 WTF::storeStoreFence();413 commit(useRareDataFlag);414 385 } 415 386 416 387 PropertyOffset transitionOffset() const 417 388 { 418 #if CPU(ADDRESS64)419 uint16_t transitionOffset = m_transitionOffsetAndClassInfo.type();420 #else421 389 uint16_t transitionOffset = m_transitionOffset; 422 #endif423 390 if (transitionOffset == shortInvalidOffset) 424 391 return invalidOffset; … … 430 397 void setTransitionOffset(VM& vm, PropertyOffset offset) 431 398 { 432 ASSERT(!isCompilationThread() && !Thread::mayBeGCThread()); 433 auto commit = [&](uint16_t value) { 434 #if CPU(ADDRESS64) 435 m_transitionOffsetAndClassInfo.setType(value); 436 #else 437 m_transitionOffset = value; 438 #endif 439 }; 440 441 if (offset == invalidOffset) { 442 commit(shortInvalidOffset); 443 return; 399 if (offset == invalidOffset) 400 m_transitionOffset = shortInvalidOffset; 401 else if (offset < useRareDataFlag && offset < shortInvalidOffset) 402 m_transitionOffset = offset; 403 else if (m_transitionOffset == useRareDataFlag) 404 rareData()->m_transitionOffset = offset; 405 else { 406 ensureRareData(vm)->m_transitionOffset = offset; 407 WTF::storeStoreFence(); 408 m_transitionOffset = useRareDataFlag; 444 409 } 445 if (offset < useRareDataFlag && offset < shortInvalidOffset) {446 commit(offset);447 return;448 }449 #if CPU(ADDRESS64)450 uint16_t transitionOffset = m_transitionOffsetAndClassInfo.type();451 #else452 uint16_t transitionOffset = m_transitionOffset;453 #endif454 if (transitionOffset == useRareDataFlag) {455 rareData()->m_transitionOffset = offset;456 return;457 }458 459 ensureRareData(vm)->m_transitionOffset = offset;460 WTF::storeStoreFence();461 commit(useRareDataFlag);462 410 } 463 411 … … 495 443 return outOfLineSize(maxOffset()); 496 444 } 497 bool hasInlineStorage() const { return !!inlineCapacity(); } 445 bool hasInlineStorage() const 446 { 447 return !!m_inlineCapacity; 448 } 498 449 unsigned inlineCapacity() const 499 450 { 500 #if CPU(ADDRESS64)501 return static_cast<uint8_t>(m_inlineCapacityAndCachedPrototypeChainOrRareData.type());502 #else503 451 return m_inlineCapacity; 504 #endif505 452 } 506 453 unsigned inlineSize() const 507 454 { 508 return std::min<unsigned>(maxOffset() + 1, inlineCapacity());455 return std::min<unsigned>(maxOffset() + 1, m_inlineCapacity); 509 456 } 510 457 unsigned totalStorageCapacity() const … … 518 465 return JSC::isValidOffset(offset) 519 466 && offset <= maxOffset() 520 && (offset < static_cast<int>(inlineCapacity())|| offset >= firstOutOfLineOffset);467 && (offset < m_inlineCapacity || offset >= firstOutOfLineOffset); 521 468 } 522 469 523 470 bool hijacksIndexingHeader() const 524 471 { 525 return isTypedView( classInfo()->typedArrayStorageType);472 return isTypedView(m_classInfo->typedArrayStorageType); 526 473 } 527 474 … … 593 540 void setObjectToStringValue(JSGlobalObject*, VM&, JSString* value, PropertySlot toStringTagSymbolSlot); 594 541 595 const ClassInfo* classInfo() const 596 { 597 #if CPU(ADDRESS64) 598 return m_transitionOffsetAndClassInfo.pointer(); 599 #else 600 return m_classInfo; 601 #endif 602 } 542 const ClassInfo* classInfo() const { return m_classInfo; } 603 543 604 544 static ptrdiff_t structureIDOffset() … … 617 557 } 618 558 619 static ptrdiff_t offsetOfClassInfo() 620 { 621 #if CPU(ADDRESS64) 622 return OBJECT_OFFSETOF(Structure, m_transitionOffsetAndClassInfo); 623 #else 559 static ptrdiff_t classInfoOffset() 560 { 624 561 return OBJECT_OFFSETOF(Structure, m_classInfo); 625 #endif 626 } 627 562 } 563 628 564 static ptrdiff_t indexingModeIncludingHistoryOffset() 629 565 { 630 566 return OBJECT_OFFSETOF(Structure, m_blob) + StructureIDBlob::indexingModeIncludingHistoryOffset(); 631 567 } 632 633 #if CPU(LITTLE_ENDIAN) 634 static ptrdiff_t offsetOfInlineCapacity() 635 { 636 #if CPU(ADDRESS64) 637 return OBJECT_OFFSETOF(Structure, m_inlineCapacityAndCachedPrototypeChainOrRareData) + CompactPointerTuple<JSCell*, uint16_t>::offsetOfType(); 638 #else 568 569 static ptrdiff_t propertyTableUnsafeOffset() 570 { 571 return OBJECT_OFFSETOF(Structure, m_propertyTableUnsafe); 572 } 573 574 static ptrdiff_t inlineCapacityOffset() 575 { 639 576 return OBJECT_OFFSETOF(Structure, m_inlineCapacity); 640 #endif 641 642 } 643 #endif 644 645 static ptrdiff_t offsetOfCachedPrototypeChainOrRareData() 646 { 647 #if CPU(ADDRESS64) 648 return OBJECT_OFFSETOF(Structure, m_inlineCapacityAndCachedPrototypeChainOrRareData); 649 #else 650 return OBJECT_OFFSETOF(Structure, m_cachedPrototypeChainOrRareData); 651 #endif 577 } 578 579 static ptrdiff_t previousOrRareDataOffset() 580 { 581 return OBJECT_OFFSETOF(Structure, m_previousOrRareData); 652 582 } 653 583 … … 728 658 static void dumpContextHeader(PrintStream&); 729 659 660 ConcurrentJSLock& lock() { return m_lock; } 661 662 unsigned propertyHash() const { return m_propertyHash; } 663 730 664 static bool shouldConvertToPolyProto(const Structure* a, const Structure* b); 731 732 UniquedStringImpl* transitionPropertyName() const733 {734 #if CPU(ADDRESS64)735 return m_maxOffsetAndTransitionPropertyName.pointer();736 #else737 return m_transitionPropertyName.get();738 #endif739 }740 665 741 666 struct PropertyHashEntry { … … 748 673 749 674 private: 750 bool ruleOutUnseenProperty(UniquedStringImpl*) const;751 #if CPU(ADDRESS64)752 // As a propertyHash, 64bit environment uses 16bit property-hash + seenProperties set.753 uintptr_t propertyHash() const { return m_propertyHashAndSeenProperties.data(); }754 #else755 uint32_t propertyHash() const { return m_propertyHash; }756 #endif757 TinyBloomFilter seenProperties() const;758 void addPropertyHashAndSeenProperty(unsigned, UniquedStringImpl*);759 760 void setTransitionPropertyName(const AbstractLocker&, UniquedStringImpl* transitionPropertyName)761 {762 #if CPU(ADDRESS64)763 m_maxOffsetAndTransitionPropertyName.setPointer(transitionPropertyName);764 #else765 m_transitionPropertyName = transitionPropertyName;766 #endif767 }768 769 675 typedef enum { 770 676 NoneDictionaryKind = 0, … … 783 689 m_bitField &= ~(s_##lowerName##Mask << offset);\ 784 690 m_bitField |= (newValue & s_##lowerName##Mask) << offset;\ 785 ASSERT(newValue == lowerName());\786 691 } 787 692 … … 791 696 DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4); 792 697 DEFINE_BITFIELD(bool, isQuickPropertyAccessAllowedForEnumeration, IsQuickPropertyAccessAllowedForEnumeration, 1, 5); 793 DEFINE_BITFIELD(unsigned, transitionPropertyAttributes, TransitionPropertyAttributes, 8, 6);794 DEFINE_BITFIELD(bool, didPreventExtensions, DidPreventExtensions, 1, 14);795 DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 15);796 DEFINE_BITFIELD(bool, staticPropertiesReified, StaticPropertiesReified, 1, 16);797 DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 17);798 DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 18);799 DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 19);800 DEFINE_BITFIELD(bool, transitionWatchpointIsLikelyToBeFired, TransitionWatchpointIsLikelyToBeFired, 1, 2 0);801 DEFINE_BITFIELD(bool, hasBeenDictionary, HasBeenDictionary, 1, 2 1);802 DEFINE_BITFIELD(bool, protectPropertyTableWhileTransitioning, ProtectPropertyTableWhileTransitioning, 1, 2 2);803 DEFINE_BITFIELD(bool, hasUnderscoreProtoPropertyExcludingOriginalProto, HasUnderscoreProtoPropertyExcludingOriginalProto, 1, 2 3);804 DEFINE_BITFIELD(bool, isPropertyDeletionTransition, IsPropertyDeletionTransition, 1, 24);698 DEFINE_BITFIELD(unsigned, transitionPropertyAttributes, TransitionPropertyAttributes, 14, 6); 699 DEFINE_BITFIELD(bool, didPreventExtensions, DidPreventExtensions, 1, 20); 700 DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 21); 701 DEFINE_BITFIELD(bool, staticPropertiesReified, StaticPropertiesReified, 1, 22); 702 DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 23); 703 DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 24); 704 DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 25); 705 DEFINE_BITFIELD(bool, transitionWatchpointIsLikelyToBeFired, TransitionWatchpointIsLikelyToBeFired, 1, 26); 706 DEFINE_BITFIELD(bool, hasBeenDictionary, HasBeenDictionary, 1, 27); 707 DEFINE_BITFIELD(bool, protectPropertyTableWhileTransitioning, ProtectPropertyTableWhileTransitioning, 1, 28); 708 DEFINE_BITFIELD(bool, hasUnderscoreProtoPropertyExcludingOriginalProto, HasUnderscoreProtoPropertyExcludingOriginalProto, 1, 29); 709 DEFINE_BITFIELD(bool, isPropertyDeletionTransition, IsPropertyDeletionTransition, 1, 30); 805 710 806 711 static_assert(s_bitWidthOfTransitionPropertyAttributes <= sizeof(TransitionPropertyAttributes) * 8); … … 822 727 // non-null structure, it will also lock the structure that it returns; it is your job 823 728 // to unlock it. 824 void findStructuresAndMapForMaterialization(V M&, Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);729 void findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&); 825 730 826 731 static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind, DeferredStructureTransitionWatchpointFire* = nullptr); … … 839 744 PropertyTable* ensurePropertyTableIfNotEmpty(VM& vm) 840 745 { 841 if (PropertyTable* result = propertyTableUnsafeOrNull())746 if (PropertyTable* result = m_propertyTableUnsafe.get()) 842 747 return result; 843 if (!previousID( vm))748 if (!previousID()) 844 749 return nullptr; 845 750 return materializePropertyTable(vm); … … 849 754 PropertyTable* ensurePropertyTable(VM& vm) 850 755 { 851 if (PropertyTable* result = propertyTableUnsafeOrNull())756 if (PropertyTable* result = m_propertyTableUnsafe.get()) 852 757 return result; 853 758 return materializePropertyTable(vm); 854 759 } 855 760 856 PropertyTable* propertyTableUnsafeOrNull() const 857 { 858 #if CPU(ADDRESS64) 859 return m_outOfLineTypeFlagsAndPropertyTableUnsafe.pointer(); 860 #else 761 PropertyTable* propertyTableOrNull() const 762 { 861 763 return m_propertyTableUnsafe.get(); 862 #endif863 764 } 864 765 … … 867 768 868 769 void setPropertyTable(VM& vm, PropertyTable* table); 869 void clearPropertyTable();870 770 871 771 PropertyTable* takePropertyTableOrCloneIfPinned(VM&); … … 873 773 874 774 void setPreviousID(VM&, Structure*); 875 void clearPreviousID(); 775 776 void clearPreviousID() 777 { 778 if (hasRareData()) 779 rareData()->clearPreviousID(); 780 else 781 m_previousOrRareData.clear(); 782 } 876 783 877 784 int transitionCountEstimate() const … … 879 786 // Since the number of transitions is often the same as the last offset (except if there are deletes) 880 787 // we keep the size of Structure down by not storing both. 881 return numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity());788 return numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity); 882 789 } 883 790 … … 890 797 bool isRareData(JSCell* cell) const 891 798 { 892 return cell && cell-> type() == StructureRareDataType;799 return cell && cell->structureID() != structureID(); 893 800 } 894 801 … … 901 808 void startWatchingInternalProperties(VM&); 902 809 903 StructureChain* cachedPrototypeChain() const;904 void setCachedPrototypeChain(VM&, StructureChain*);905 906 void setOutOfLineTypeFlags(TypeInfo::OutOfLineTypeFlags);907 void setClassInfo(const ClassInfo*);908 void setInlineCapacity(uint8_t);909 910 JSCell* cachedPrototypeChainOrRareData() const911 {912 #if CPU(ADDRESS64)913 return m_inlineCapacityAndCachedPrototypeChainOrRareData.pointer();914 #else915 return m_cachedPrototypeChainOrRareData.get();916 #endif917 }918 919 810 static constexpr int s_maxTransitionLength = 64; 920 811 static constexpr int s_maxTransitionLengthForNonEvalPutById = 512; … … 923 814 // part of the object. 924 815 StructureIDBlob m_blob; 925 926 // The property table pointer should be accessed through ensurePropertyTable(). During GC, m_propertyTableUnsafe field part may be set to 0 by another thread. 927 // During a Heap Snapshot GC we avoid clearing the table so it is safe to use. 928 #if CPU(ADDRESS64) 929 public: 930 static constexpr uintptr_t classInfoMask = CompactPointerTuple<const ClassInfo*, uint16_t>::pointerMask; 931 static constexpr uintptr_t cachedPrototypeChainOrRareDataMask = CompactPointerTuple<JSCell*, uint16_t>::pointerMask; 932 private: 933 // Structure is one of the most frequently allocated data structure. Moreover, Structure tends to be alive a long time! 934 // This motivates extra complicated hack which optimizes sizeof(Structure). 935 // 936 // We combine 16bit data and 64bit pointer into one pointer-size field to (1) save memory while (2) not losing atomic load/store. 937 // The key here is analyzing data access patterns carefully. They are categoriezed into three types. 938 // 1. ImmutableAfterConstruction 939 // 2. MutableFromAnyThread 940 // 3. MutableFromMainThread 941 // We assume that loading happens from any threads. Under this assumption, MutableFromAnyThread + (MutableFromMainThread / MutableFromAnyThread) is the pair which is racy. 942 // Other pairs works well. We carefully put assertions to setters, analyze access patterns and pick appropriate pairs in Structure fields. 943 CompactPointerTuple<PropertyTable*, TypeInfo::OutOfLineTypeFlags> m_outOfLineTypeFlagsAndPropertyTableUnsafe; // ImmutableAfterConstruction(m_outOfLineTypeFlags) and MutableFromAnyThread(m_propertyTableUnsafe). 944 CompactRefPtrTuple<UniquedStringImpl, uint16_t> m_maxOffsetAndTransitionPropertyName; // MutableFromMainThread(m_maxOffset) and MutableFromMainThread(m_transitionPropertyName). 945 CompactPointerTuple<const ClassInfo*, uint16_t> m_transitionOffsetAndClassInfo; // MutableFromMainThread(m_transitionOffset) and ImmutableAfterConstruction(m_classInfo). 946 CompactPointerTuple<JSCell*, uint16_t> m_inlineCapacityAndCachedPrototypeChainOrRareData; // ImmutableAfterConstruction(m_inlineCapacity) and MutableFromMainThread(m_cachedPrototypeChainOrRareData). 947 CompactPointerTuple<UniquedStringImpl*, uint16_t> m_propertyHashAndSeenProperties; // MutableFromMainThread(m_propertyHash) and MutableFromMainThread(m_seenProperties). 948 #else 949 TypeInfo::OutOfLineTypeFlags m_outOfLineTypeFlags { 0 }; 950 uint8_t m_inlineCapacity { 0 }; 951 uint32_t m_propertyHash { 0 }; 952 uint16_t m_transitionOffset { 0 }; 953 uint16_t m_maxOffset { 0 }; 954 WriteBarrier<PropertyTable> m_propertyTableUnsafe; 955 const ClassInfo* m_classInfo { nullptr }; 956 WriteBarrier<JSCell> m_cachedPrototypeChainOrRareData; 957 uintptr_t m_seenProperties { 0 }; 958 RefPtr<UniquedStringImpl> m_transitionPropertyName; 959 #endif 960 StructureID m_previousID { 0 }; 961 uint32_t m_bitField { 0 }; 962 963 StructureTransitionTable m_transitionTable; 816 TypeInfo::OutOfLineTypeFlags m_outOfLineTypeFlags; 817 818 uint8_t m_inlineCapacity; 819 820 ConcurrentJSLock m_lock; 821 822 uint32_t m_bitField; 823 964 824 WriteBarrier<JSGlobalObject> m_globalObject; 965 825 WriteBarrier<Unknown> m_prototype; 826 mutable WriteBarrier<StructureChain> m_cachedPrototypeChain; 827 828 WriteBarrier<JSCell> m_previousOrRareData; 829 830 RefPtr<UniquedStringImpl> m_transitionPropertyName; 831 832 const ClassInfo* m_classInfo; 833 834 StructureTransitionTable m_transitionTable; 835 836 // Should be accessed through ensurePropertyTable(). During GC, it may be set to 0 by another thread. 837 // During a Heap Snapshot GC we avoid clearing the table so it is safe to use. 838 WriteBarrier<PropertyTable> m_propertyTableUnsafe; 966 839 967 840 mutable InlineWatchpointSet m_transitionWatchpointSet; 968 841 969 842 COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits); 843 844 uint16_t m_transitionOffset; 845 uint16_t m_maxOffset; 846 847 uint32_t m_propertyHash; 848 TinyBloomFilter m_seenProperties; 970 849 971 850 friend class VMInspector; 972 851 friend class JSDollarVMHelper; 973 852 }; 974 #if CPU(ADDRESS64)975 static_assert(sizeof(Structure) <= 96, "Do not increase sizeof(Structure), it immediately causes memory regression");976 #endif977 853 978 854 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/StructureInlines.h
r259355 r259463 145 145 ASSERT(structure(vm)->classInfo() == info()); 146 146 147 if ( ruleOutUnseenProperty(propertyName.uid()))147 if (m_seenProperties.ruleOut(bitwise_cast<uintptr_t>(propertyName.uid()))) 148 148 return invalidOffset; 149 149 … … 160 160 } 161 161 162 inline bool Structure::ruleOutUnseenProperty(UniquedStringImpl* uid) const163 {164 ASSERT(uid);165 return seenProperties().ruleOut(bitwise_cast<uintptr_t>(uid));166 }167 168 inline TinyBloomFilter Structure::seenProperties() const169 {170 #if CPU(ADDRESS64)171 return TinyBloomFilter(bitwise_cast<uintptr_t>(m_propertyHashAndSeenProperties.pointer()));172 #else173 return TinyBloomFilter(m_seenProperties);174 #endif175 }176 177 inline void Structure::addPropertyHashAndSeenProperty(unsigned hash, UniquedStringImpl* pointer)178 {179 #if CPU(ADDRESS64)180 m_propertyHashAndSeenProperties.setType(m_propertyHashAndSeenProperties.type() ^ hash);181 m_propertyHashAndSeenProperties.setPointer(bitwise_cast<UniquedStringImpl*>(bitwise_cast<uintptr_t>(m_propertyHashAndSeenProperties.pointer()) | bitwise_cast<uintptr_t>(pointer)));182 #else183 m_propertyHash = m_propertyHash ^ hash;184 m_seenProperties = bitwise_cast<uintptr_t>(pointer) | m_seenProperties;185 #endif186 }187 188 162 template<typename Functor> 189 163 void Structure::forEachPropertyConcurrently(const Functor& functor) … … 192 166 Structure* tableStructure; 193 167 PropertyTable* table; 194 VM& vm = this->vm(); 195 196 findStructuresAndMapForMaterialization(vm, structures, tableStructure, table); 168 169 findStructuresAndMapForMaterialization(structures, tableStructure, table); 197 170 198 171 HashSet<UniquedStringImpl*> seenProperties; 199 172 200 for (Structure* structure : structures) { 201 UniquedStringImpl* transitionPropertyName = structure->transitionPropertyName(); 202 if (!transitionPropertyName || seenProperties.contains(transitionPropertyName)) 173 for (auto* structure : structures) { 174 if (!structure->m_transitionPropertyName || seenProperties.contains(structure->m_transitionPropertyName.get())) 203 175 continue; 204 176 205 seenProperties.add( transitionPropertyName);177 seenProperties.add(structure->m_transitionPropertyName.get()); 206 178 207 179 if (structure->isPropertyDeletionTransition()) 208 180 continue; 209 181 210 if (!functor(PropertyMapEntry( transitionPropertyName, structure->transitionOffset(), structure->transitionPropertyAttributes()))) {182 if (!functor(PropertyMapEntry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes()))) { 211 183 if (table) 212 tableStructure-> cellLock().unlock();184 tableStructure->m_lock.unlock(); 213 185 return; 214 186 } … … 221 193 222 194 if (!functor(entry)) { 223 tableStructure-> cellLock().unlock();195 tableStructure->m_lock.unlock(); 224 196 return; 225 197 } 226 198 } 227 tableStructure-> cellLock().unlock();199 tableStructure->m_lock.unlock(); 228 200 } 229 201 } … … 280 252 inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind) 281 253 { 282 VM& vm = this->vm(); 283 for (Structure* current = this; current; current = current->previousID(vm)) { 254 for (Structure* current = this; current; current = current->previousID()) { 284 255 if (current == structureToFind) 285 256 return true; … … 348 319 } 349 320 350 inline StructureChain* Structure::cachedPrototypeChain() const351 {352 JSCell* cell = cachedPrototypeChainOrRareData();353 if (isRareData(cell))354 return jsCast<StructureRareData*>(cell)->cachedPrototypeChain();355 return jsCast<StructureChain*>(cell);356 }357 358 inline void Structure::setCachedPrototypeChain(VM& vm, StructureChain* chain)359 {360 ASSERT(isObject());361 ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());362 JSCell* cell = cachedPrototypeChainOrRareData();363 if (isRareData(cell)) {364 jsCast<StructureRareData*>(cell)->setCachedPrototypeChain(vm, chain);365 return;366 }367 #if CPU(ADDRESS64)368 m_inlineCapacityAndCachedPrototypeChainOrRareData.setPointer(chain);369 vm.heap.writeBarrier(this, chain);370 #else371 m_cachedPrototypeChainOrRareData.setMayBeNull(vm, this, chain);372 #endif373 }374 375 321 inline StructureChain* Structure::prototypeChain(VM& vm, JSGlobalObject* globalObject, JSObject* base) const 376 322 { 377 ASSERT(this->isObject());378 323 ASSERT(base->structure(vm) == this); 379 324 // We cache our prototype chain so our clients can share it. 380 if (!isValid(globalObject, cachedPrototypeChain(), base)) {325 if (!isValid(globalObject, m_cachedPrototypeChain.get(), base)) { 381 326 JSValue prototype = prototypeForLookup(globalObject, base); 382 const_cast<Structure*>(this)->setCachedPrototypeChain(vm, StructureChain::create(vm, prototype.isNull() ? nullptr : asObject(prototype)));383 } 384 return cachedPrototypeChain();327 m_cachedPrototypeChain.set(vm, this, StructureChain::create(vm, prototype.isNull() ? nullptr : asObject(prototype))); 328 } 329 return m_cachedPrototypeChain.get(); 385 330 } 386 331 … … 422 367 inline WatchpointSet* Structure::propertyReplacementWatchpointSet(PropertyOffset offset) 423 368 { 424 ConcurrentJS CellLocker locker(cellLock());369 ConcurrentJSLocker locker(m_lock); 425 370 if (!hasRareData()) 426 371 return nullptr; … … 443 388 444 389 unsigned totalSize = propertyTable->propertyStorageSize(); 445 unsigned inlineOverflowAccordingToTotalSize = totalSize < inlineCapacity() ? 0 : totalSize - inlineCapacity();390 unsigned inlineOverflowAccordingToTotalSize = totalSize < m_inlineCapacity ? 0 : totalSize - m_inlineCapacity; 446 391 447 392 auto fail = [&] (const char* description) { … … 450 395 dataLog("transitionOffset = ", transitionOffset(), "\n"); 451 396 dataLog("maxOffset = ", maxOffset(), "\n"); 452 dataLog("m_inlineCapacity = ", inlineCapacity(), "\n");397 dataLog("m_inlineCapacity = ", m_inlineCapacity, "\n"); 453 398 dataLog("propertyTable = ", RawPointer(propertyTable), "\n"); 454 dataLog("numberOfSlotsForMaxOffset = ", numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity()), "\n");399 dataLog("numberOfSlotsForMaxOffset = ", numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity), "\n"); 455 400 dataLog("totalSize = ", totalSize, "\n"); 456 401 dataLog("inlineOverflowAccordingToTotalSize = ", inlineOverflowAccordingToTotalSize, "\n"); … … 460 405 }; 461 406 462 if (numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity()) != totalSize)407 if (numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity) != totalSize) 463 408 fail("numberOfSlotsForMaxOffset doesn't match totalSize"); 464 409 if (inlineOverflowAccordingToTotalSize != numberOfOutOfLineSlotsForMaxOffset(maxOffset())) … … 470 415 ALWAYS_INLINE bool Structure::checkOffsetConsistency() const 471 416 { 472 PropertyTable* propertyTable = propertyTable UnsafeOrNull();417 PropertyTable* propertyTable = propertyTableOrNull(); 473 418 474 419 if (!propertyTable) { … … 511 456 PropertyTable* table = ensurePropertyTable(vm); 512 457 513 GCSafeConcurrentJS CellLocker locker(cellLock(), vm.heap);458 GCSafeConcurrentJSLocker locker(m_lock, vm.heap); 514 459 515 460 switch (shouldPin) { … … 532 477 auto rep = propertyName.uid(); 533 478 534 PropertyOffset newOffset = table->nextOffset(inlineCapacity()); 535 536 addPropertyHashAndSeenProperty(rep->existingSymbolAwareHash(), rep); 479 PropertyOffset newOffset = table->nextOffset(m_inlineCapacity); 480 481 m_propertyHash = m_propertyHash ^ rep->existingSymbolAwareHash(); 482 m_seenProperties.add(bitwise_cast<uintptr_t>(rep)); 537 483 538 484 auto result = table->add(PropertyMapEntry(rep, newOffset, attributes)); … … 553 499 { 554 500 PropertyTable* table = ensurePropertyTable(vm); 555 GCSafeConcurrentJS CellLocker locker(cellLock(), vm.heap);501 GCSafeConcurrentJSLocker locker(m_lock, vm.heap); 556 502 557 503 switch (shouldPin) { … … 603 549 ASSERT(isUncacheableDictionary()); 604 550 ASSERT(isPinnedPropertyTable()); 605 ASSERT(propertyTable UnsafeOrNull());551 ASSERT(propertyTableOrNull()); 606 552 607 553 return remove<ShouldPin::Yes>(vm, propertyName, func); … … 621 567 ALWAYS_INLINE void Structure::setPropertyTable(VM& vm, PropertyTable* table) 622 568 { 623 #if CPU(ADDRESS64)624 m_outOfLineTypeFlagsAndPropertyTableUnsafe.setPointer(table);625 vm.heap.writeBarrier(this, table);626 #else627 569 m_propertyTableUnsafe.setMayBeNull(vm, this, table); 628 #endif629 }630 631 ALWAYS_INLINE void Structure::clearPropertyTable()632 {633 #if CPU(ADDRESS64)634 m_outOfLineTypeFlagsAndPropertyTableUnsafe.setPointer(nullptr);635 #else636 m_propertyTableUnsafe.clear();637 #endif638 }639 640 ALWAYS_INLINE void Structure::setOutOfLineTypeFlags(TypeInfo::OutOfLineTypeFlags outOfLineTypeFlags)641 {642 #if CPU(ADDRESS64)643 m_outOfLineTypeFlagsAndPropertyTableUnsafe.setType(outOfLineTypeFlags);644 #else645 m_outOfLineTypeFlags = outOfLineTypeFlags;646 #endif647 }648 649 ALWAYS_INLINE void Structure::setInlineCapacity(uint8_t inlineCapacity)650 {651 #if CPU(ADDRESS64)652 m_inlineCapacityAndCachedPrototypeChainOrRareData.setType(inlineCapacity);653 #else654 m_inlineCapacity = inlineCapacity;655 #endif656 }657 658 ALWAYS_INLINE void Structure::setClassInfo(const ClassInfo* classInfo)659 {660 #if CPU(ADDRESS64)661 m_transitionOffsetAndClassInfo.setPointer(classInfo);662 #else663 m_classInfo = classInfo;664 #endif665 570 } 666 571 667 572 ALWAYS_INLINE void Structure::setPreviousID(VM& vm, Structure* structure) 668 573 { 669 ASSERT(structure); 670 m_previousID = structure->id(); 671 vm.heap.writeBarrier(this, structure); 672 } 673 674 inline void Structure::clearPreviousID() 675 { 676 m_previousID = 0; 574 if (hasRareData()) 575 rareData()->setPreviousID(vm, structure); 576 else 577 m_previousOrRareData.set(vm, this, structure); 677 578 } 678 579 -
trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp
r257201 r259463 41 41 Structure* StructureRareData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 42 42 { 43 return Structure::create(vm, globalObject, prototype, TypeInfo( StructureRareDataType, StructureFlags), info());43 return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info()); 44 44 } 45 45 46 StructureRareData* StructureRareData::create(VM& vm, Structure Chain* chain)46 StructureRareData* StructureRareData::create(VM& vm, Structure* previous) 47 47 { 48 StructureRareData* rareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, chain);48 StructureRareData* rareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, previous); 49 49 rareData->finishCreation(vm); 50 50 return rareData; … … 56 56 } 57 57 58 StructureRareData::StructureRareData(VM& vm, Structure Chain* chain)58 StructureRareData::StructureRareData(VM& vm, Structure* previous) 59 59 : JSCell(vm, vm.structureRareDataStructure.get()) 60 60 , m_maxOffset(invalidOffset) 61 61 , m_transitionOffset(invalidOffset) 62 62 { 63 if ( chain)64 m_ cachedPrototypeChain.set(vm, this, chain);63 if (previous) 64 m_previous.set(vm, this, previous); 65 65 } 66 66 … … 71 71 72 72 Base::visitChildren(thisObject, visitor); 73 visitor.append(thisObject->m_ cachedPrototypeChain);73 visitor.append(thisObject->m_previous); 74 74 visitor.appendUnbarriered(thisObject->objectToStringValue()); 75 75 visitor.append(thisObject->m_cachedPropertyNameEnumerator); -
trunk/Source/JavaScriptCore/runtime/StructureRareData.h
r257201 r259463 36 36 class JSPropertyNameEnumerator; 37 37 class Structure; 38 class StructureChain;39 38 class ObjectToStringAdaptiveInferredPropertyValueWatchpoint; 40 39 class ObjectToStringAdaptiveStructureWatchpoint; … … 51 50 } 52 51 53 static StructureRareData* create(VM&, Structure Chain*);52 static StructureRareData* create(VM&, Structure*); 54 53 55 54 static constexpr bool needsDestruction = true; … … 60 59 static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); 61 60 62 Structure Chain* cachedPrototypeChain() const61 Structure* previousID() const 63 62 { 64 return m_ cachedPrototypeChain.get();63 return m_previous.get(); 65 64 } 66 void setCachedPrototypeChain(VM&, StructureChain*); 65 void setPreviousID(VM&, Structure*); 66 void clearPreviousID(); 67 67 68 68 JSString* objectToStringValue() const; … … 103 103 void clearObjectToStringValue(); 104 104 105 StructureRareData(VM&, Structure Chain*);105 StructureRareData(VM&, Structure*); 106 106 107 WriteBarrier<Structure Chain> m_cachedPrototypeChain;107 WriteBarrier<Structure> m_previous; 108 108 WriteBarrier<JSString> m_objectToStringValue; 109 109 // FIXME: We should have some story for clearing these property names caches in GC. -
trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h
r257201 r259463 33 33 namespace JSC { 34 34 35 inline void StructureRareData::set CachedPrototypeChain(VM& vm, StructureChain* chain)35 inline void StructureRareData::setPreviousID(VM& vm, Structure* structure) 36 36 { 37 m_cachedPrototypeChain.setMayBeNull(vm, this, chain); 37 m_previous.set(vm, this, structure); 38 } 39 40 inline void StructureRareData::clearPreviousID() 41 { 42 m_previous.clear(); 38 43 } 39 44 -
trunk/Source/JavaScriptCore/runtime/StructureTransitionTable.h
r257201 r259463 151 151 struct Key { 152 152 friend struct Hash; 153 static_assert( OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH)<= 48);153 static_assert(WTF_OS_CONSTANT_EFFECTIVE_ADDRESS_WIDTH <= 48); 154 154 static constexpr uintptr_t isAdditionMask = 1ULL; 155 155 static constexpr uintptr_t stringMask = ((1ULL << 48) - 1) & (~isAdditionMask); -
trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp
r258664 r259463 2875 2875 Vector<Structure*, 8> structures; 2876 2876 2877 for (auto* structure = obj->structure(); structure; structure = structure->previousID( vm))2877 for (auto* structure = obj->structure(); structure; structure = structure->previousID()) 2878 2878 structures.append(structure); 2879 2879 … … 2889 2889 result->push(globalObject, JSValue(structure->maxOffset())); 2890 2890 RETURN_IF_EXCEPTION(scope, { }); 2891 if ( auto* transitionPropertyName = structure->transitionPropertyName())2892 result->push(globalObject, jsString(vm, String(* transitionPropertyName)));2891 if (structure->m_transitionPropertyName) 2892 result->push(globalObject, jsString(vm, String(*structure->m_transitionPropertyName))); 2893 2893 else 2894 2894 result->push(globalObject, jsNull()); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r257201 r259463 276 276 stackLimitGPRIsClobbered = true; 277 277 jit.emitLoadStructure(vm, scratchGPR, scratchGPR, stackLimitGPR); 278 jit. emitLoadClassInfoFromStructure(scratchGPR, scratchGPR);278 jit.loadPtr(CCallHelpers::Address(scratchGPR, Structure::classInfoOffset()), scratchGPR); 279 279 280 280 static_assert(std::is_final<WebAssemblyFunction>::value, "We do not check for subtypes below");
Note:
See TracChangeset
for help on using the changeset viewer.