WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
patch
a-backup.diff (text/plain), 256.24 KB, created by
Saam Barati
on 2021-12-13 14:14:37 PST
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2021-12-13 14:14:37 PST
Size:
256.24 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 286980) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,334 @@ >+2021-12-13 Saam Barati <sbarati@apple.com> >+ >+ Roll back r286345, r286387, r286471, r286667, r286849 >+ https://bugs.webkit.org/show_bug.cgi?id=234268 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * CMakeLists.txt: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * bytecode/AccessCase.cpp: >+ (JSC::AccessCase::AccessCase): >+ (JSC::AccessCase::forEachDependentCell const): >+ (JSC::AccessCase::dump const): >+ (JSC::AccessCase::propagateTransitions const): >+ (JSC::AccessCase::generateWithGuard): >+ (JSC::AccessCase::canBeShared): >+ * bytecode/AccessCase.h: >+ (JSC::AccessCase::structure const): >+ (JSC::AccessCase::newStructure const): >+ (JSC::AccessCase::hash const): >+ (JSC::AccessCase::AccessCase): >+ * bytecode/ArrayProfile.cpp: >+ (JSC::ArrayProfile::computeUpdatedPrediction): >+ * bytecode/ArrayProfile.h: >+ * bytecode/CheckPrivateBrandStatus.cpp: >+ (JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback): >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::propagateTransitions): >+ (JSC::CodeBlock::determineLiveness): >+ (JSC::CodeBlock::finalizeLLIntInlineCaches): >+ (JSC::CodeBlock::stronglyVisitWeakReferences): >+ * bytecode/DeleteByStatus.cpp: >+ (JSC::DeleteByStatus::computeForStubInfoWithoutExitSiteFeedback): >+ * bytecode/GetByIdMetadata.h: >+ (JSC::GetByIdModeMetadata::GetByIdModeMetadata): >+ (JSC::GetByIdModeMetadata::clearToDefaultModeWithoutCache): >+ * bytecode/GetByStatus.cpp: >+ (JSC::GetByStatus::computeFromLLInt): >+ (JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback): >+ * bytecode/InByStatus.cpp: >+ (JSC::InByStatus::computeForStubInfoWithoutExitSiteFeedback): >+ * bytecode/InlineAccess.cpp: >+ (JSC::InlineAccess::rewireStubAsJumpInAccess): >+ (JSC::InlineAccess::resetStubAsJumpInAccess): >+ * bytecode/InstanceOfStatus.cpp: >+ (JSC::InstanceOfStatus::computeForStubInfo): >+ * bytecode/InternalFunctionAllocationProfile.h: >+ (JSC::InternalFunctionAllocationProfile::offsetOfStructure): >+ (JSC::InternalFunctionAllocationProfile::structure): >+ (JSC::InternalFunctionAllocationProfile::clear): >+ (JSC::InternalFunctionAllocationProfile::visitAggregate): >+ (JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase): >+ (JSC::InternalFunctionAllocationProfile::offsetOfStructureID): Deleted. >+ * bytecode/PolyProtoAccessChain.cpp: >+ (JSC::PolyProtoAccessChain::needImpurePropertyWatchpoint const): >+ * bytecode/PolyProtoAccessChain.h: >+ * bytecode/PolymorphicAccess.cpp: >+ (JSC::PolymorphicAccess::visitWeak const): >+ * bytecode/PutByIdFlags.h: >+ * bytecode/PutByStatus.cpp: >+ (JSC::PutByStatus::computeFromLLInt): >+ (JSC::PutByStatus::computeForStubInfo): >+ * bytecode/SetPrivateBrandStatus.cpp: >+ (JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback): >+ * bytecode/SpeculatedType.cpp: >+ (JSC::speculationFromCell): >+ * bytecode/StructureStubInfo.cpp: >+ (JSC::StructureStubInfo::initGetByIdSelf): >+ (JSC::StructureStubInfo::initPutByIdReplace): >+ (JSC::StructureStubInfo::initInByIdSelf): >+ (JSC::StructureStubInfo::deref): >+ (JSC::StructureStubInfo::aboutToDie): >+ (JSC::StructureStubInfo::addAccessCase): >+ (JSC::StructureStubInfo::reset): >+ (JSC::StructureStubInfo::visitAggregateImpl): >+ (JSC::StructureStubInfo::visitWeakReferences): >+ (JSC::StructureStubInfo::propagateTransitions): >+ (JSC::StructureStubInfo::summary const): >+ (JSC::StructureStubInfo::containsPC const): >+ * bytecode/StructureStubInfo.h: >+ (JSC::StructureStubInfo::offsetOfByIdSelfOffset): >+ (JSC::StructureStubInfo::offsetOfInlineAccessBaseStructure): >+ (JSC::StructureStubInfo::inlineAccessBaseStructure): >+ (JSC::StructureStubInfo::offsetOfInlineAccessBaseStructureID): Deleted. >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::parseBlock): >+ * dfg/DFGGraph.cpp: >+ (JSC::DFG::Graph::dump): >+ * dfg/DFGJITCompiler.h: >+ (JSC::DFG::JITCompiler::branchWeakStructure): >+ * dfg/DFGPlan.cpp: >+ (JSC::DFG::Plan::finalize): >+ * dfg/DFGSpeculativeJIT.cpp: >+ * dfg/DFGSpeculativeJIT64.cpp: >+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined): >+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined): >+ (JSC::DFG::SpeculativeJIT::compileToBooleanObjectOrOther): >+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch): >+ (JSC::DFG::SpeculativeJIT::emitUntypedBranch): >+ (JSC::DFG::SpeculativeJIT::compile): >+ * ftl/FTLAbstractHeapRepository.h: >+ * ftl/FTLLowerDFGToB3.cpp: >+ (JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise): >+ (JSC::FTL::DFG::LowerDFGToB3::compileCreateInternalFieldObject): >+ (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): >+ * heap/AbstractSlotVisitor.h: >+ * heap/AbstractSlotVisitorInlines.h: >+ * heap/Heap.cpp: >+ (JSC::Heap::Heap): >+ (JSC::Heap::runEndPhase): >+ * heap/Heap.h: >+ (JSC::Heap::structureIDTable): >+ * heap/IsoAlignedMemoryAllocator.cpp: >+ (JSC::IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator): >+ (JSC::IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator): >+ (JSC::IsoAlignedMemoryAllocator::tryAllocateAlignedMemory): >+ (JSC::IsoAlignedMemoryAllocator::freeAlignedMemory): >+ (JSC::IsoAlignedMemoryAllocator::tryMallocBlock): Deleted. >+ (JSC::IsoAlignedMemoryAllocator::freeBlock): Deleted. >+ (JSC::IsoAlignedMemoryAllocator::commitBlock): Deleted. >+ (JSC::IsoAlignedMemoryAllocator::decommitBlock): Deleted. >+ * heap/IsoAlignedMemoryAllocator.h: >+ * heap/IsoMemoryAllocatorBase.cpp: Removed. >+ * heap/IsoMemoryAllocatorBase.h: Removed. >+ * heap/IsoSubspace.cpp: >+ (JSC::IsoSubspace::IsoSubspace): >+ (JSC::IsoSubspace::tryAllocateFromLowerTier): >+ * heap/IsoSubspace.h: >+ * heap/PreciseAllocation.cpp: >+ (JSC::PreciseAllocation::createForLowerTier): >+ (JSC::PreciseAllocation::tryCreateForLowerTier): Deleted. >+ * heap/PreciseAllocation.h: >+ * heap/SlotVisitor.cpp: >+ (JSC::SlotVisitor::appendJSCellOrAuxiliary): >+ * heap/SlotVisitor.h: >+ * heap/SlotVisitorInlines.h: >+ * heap/StructureAlignedMemoryAllocator.cpp: Removed. >+ * heap/StructureAlignedMemoryAllocator.h: Removed. >+ * jit/AssemblyHelpers.cpp: >+ (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): >+ (JSC::AssemblyHelpers::emitLoadStructure): >+ (JSC::AssemblyHelpers::emitLoadPrototype): >+ (JSC::AssemblyHelpers::emitRandomThunk): >+ (JSC::AssemblyHelpers::emitConvertValueToBoolean): >+ (JSC::AssemblyHelpers::branchIfValue): >+ (JSC::AssemblyHelpers::emitNonNullDecodeStructureID): Deleted. >+ * jit/AssemblyHelpers.h: >+ (JSC::AssemblyHelpers::branchStructure): >+ (JSC::AssemblyHelpers::nukeStructureAndStoreButterfly): >+ * jit/GCAwareJITStubRoutine.cpp: >+ (JSC::PolymorphicAccessJITStubRoutine::computeHash): >+ * jit/JITInlineCacheGenerator.cpp: >+ (JSC::generateGetByIdInlineAccess): >+ (JSC::JITPutByIdGenerator::generateBaselineDataICFastPath): >+ (JSC::JITInByIdGenerator::generateBaselineDataICFastPath): >+ * jit/JITOpcodes.cpp: >+ (JSC::JIT::emit_op_typeof_is_undefined): >+ (JSC::JIT::emit_op_jeq_null): >+ (JSC::JIT::emit_op_jneq_null): >+ (JSC::JIT::emit_op_eq_null): >+ (JSC::JIT::emit_op_neq_null): >+ (JSC::JIT::emit_op_get_prototype_of): >+ * jit/JITPropertyAccess.cpp: >+ (JSC::JIT::emit_op_get_property_enumerator): >+ * jit/JITStubRoutine.h: >+ * llint/LLIntSlowPaths.cpp: >+ (JSC::LLInt::LLINT_SLOW_PATH_DECL): >+ (JSC::LLInt::performLLIntGetByID): >+ * llint/LowLevelInterpreter.asm: >+ * llint/LowLevelInterpreter64.asm: >+ * runtime/ArrayPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/BigIntPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/BooleanPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/CommonSlowPaths.cpp: >+ (JSC::JSC_DEFINE_COMMON_SLOW_PATH): >+ * runtime/DatePrototype.cpp: >+ (JSC::formateDateInstance): >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/ErrorInstance.cpp: >+ (JSC::ErrorInstance::sanitizedMessageString): >+ (JSC::ErrorInstance::sanitizedNameString): >+ (JSC::ErrorInstance::sanitizedToString): >+ * runtime/ErrorPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/FunctionExecutable.cpp: >+ (JSC::FunctionExecutable::visitChildrenImpl): >+ * runtime/FunctionExecutable.h: >+ * runtime/FunctionPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/FunctionRareData.cpp: >+ (JSC::FunctionRareData::visitChildrenImpl): >+ * runtime/FunctionRareData.h: >+ * runtime/HasOwnPropertyCache.h: >+ * runtime/InitializeThreading.cpp: >+ (JSC::initialize): >+ * runtime/JSCConfig.h: >+ * runtime/JSCJSValue.cpp: >+ (JSC::JSValue::dumpInContextAssumingStructure const): >+ (JSC::JSValue::dumpForBacktrace const): >+ * runtime/JSCell.cpp: >+ (JSC::JSCell::toObjectSlow const): >+ * runtime/JSCell.h: >+ (JSC::JSCell::clearStructure): >+ * runtime/JSCellInlines.h: >+ (JSC::JSCell::structure const): >+ (JSC::JSCell::setStructure): >+ * runtime/JSGlobalObject.cpp: >+ (JSC::JSGlobalObject::visitChildrenImpl): >+ * runtime/JSGlobalObject.h: >+ * runtime/JSObject.cpp: >+ (JSC::JSObject::visitButterflyImpl): >+ (JSC::JSObject::createInitialUndecided): >+ (JSC::JSObject::createInitialInt32): >+ (JSC::JSObject::createInitialDouble): >+ (JSC::JSObject::createInitialContiguous): >+ (JSC::JSObject::createArrayStorage): >+ (JSC::JSObject::convertUndecidedToArrayStorage): >+ (JSC::JSObject::convertInt32ToArrayStorage): >+ (JSC::JSObject::convertDoubleToArrayStorage): >+ (JSC::JSObject::convertContiguousToArrayStorage): >+ (JSC::JSObject::putDirectCustomGetterSetterWithoutTransition): >+ (JSC::JSObject::putDirectNonIndexAccessorWithoutTransition): >+ * runtime/JSObject.h: >+ (JSC::JSObject::nukeStructureAndSetButterfly): >+ (JSC::JSObject::getPropertySlot): >+ * runtime/JSObjectInlines.h: >+ (JSC::JSObject::getPropertySlot): >+ (JSC::JSObject::getNonIndexPropertySlot): >+ (JSC::JSObject::putDirectWithoutTransition): >+ (JSC::JSObject::putDirectInternal): >+ * runtime/JSPropertyNameEnumerator.cpp: >+ (JSC::JSPropertyNameEnumerator::JSPropertyNameEnumerator): >+ (JSC::JSPropertyNameEnumerator::visitChildrenImpl): >+ * runtime/JSPropertyNameEnumerator.h: >+ * runtime/NumberPrototype.cpp: >+ (JSC::toThisNumber): >+ * runtime/ObjectPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ (JSC::objectPrototypeToString): >+ * runtime/RegExpPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/StringPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/Structure.cpp: >+ (JSC::Structure::Structure): >+ (JSC::Structure::~Structure): >+ (JSC::Structure::flattenDictionaryStructure): >+ (JSC::Structure::dump const): >+ (JSC::Structure::canCachePropertyNameEnumerator const): >+ * runtime/Structure.h: >+ (JSC::Structure::id const): >+ * runtime/StructureChain.cpp: >+ (JSC::StructureChain::create): >+ (JSC::StructureChain::visitChildrenImpl): >+ * runtime/StructureID.h: Removed. >+ * runtime/StructureIDBlob.h: >+ (JSC::StructureIDBlob::StructureIDBlob): >+ * runtime/StructureIDTable.cpp: Added. >+ (JSC::StructureIDTable::StructureIDTable): >+ (JSC::StructureIDTable::makeFreeListFromRange): >+ (JSC::StructureIDTable::resize): >+ (JSC::StructureIDTable::flushOldTables): >+ (JSC::StructureIDTable::allocateID): >+ (JSC::StructureIDTable::deallocateID): >+ * runtime/StructureIDTable.h: Added. >+ (JSC::nukedStructureIDBit): >+ (JSC::nuke): >+ (JSC::isNuked): >+ (JSC::decontaminate): >+ (JSC::StructureIDTable::base): >+ (JSC::StructureIDTable::size const): >+ (JSC::StructureIDTable::table const): >+ (JSC::StructureIDTable::decode): >+ (JSC::StructureIDTable::encode): >+ (JSC::StructureIDTable::get): >+ (JSC::StructureIDTable::tryGet): >+ (JSC::StructureIDTable::validate): >+ (JSC::StructureIDTable::deallocateID): >+ (JSC::StructureIDTable::allocateID): >+ (JSC::StructureIDTable::flushOldTables): >+ * runtime/StructureRareData.cpp: >+ (JSC::StructureRareData::StructureRareData): >+ * runtime/StructureRareData.h: >+ * runtime/StructureRareDataInlines.h: >+ (JSC::StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint): >+ * runtime/SymbolPrototype.cpp: >+ (JSC::JSC_DEFINE_CUSTOM_GETTER): >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * runtime/TypeProfilerLog.cpp: >+ (JSC::TypeProfilerLog::processLogEntries): >+ (JSC::TypeProfilerLog::visit): >+ * runtime/VM.h: >+ (JSC::VM::getStructure): >+ (JSC::VM::tryGetStructure): >+ * runtime/WriteBarrier.h: >+ (JSC::WriteBarrierStructureID::WriteBarrierStructureID): Deleted. >+ (JSC::WriteBarrierStructureID::get const): Deleted. >+ (JSC::WriteBarrierStructureID::operator* const): Deleted. >+ (JSC::WriteBarrierStructureID::operator-> const): Deleted. >+ (JSC::WriteBarrierStructureID::clear): Deleted. >+ (JSC::WriteBarrierStructureID::operator bool const): Deleted. >+ (JSC::WriteBarrierStructureID::operator! const): Deleted. >+ (JSC::WriteBarrierStructureID::setWithoutWriteBarrier): Deleted. >+ (JSC::WriteBarrierStructureID::unvalidatedGet const): Deleted. >+ (JSC::WriteBarrierStructureID::value const): Deleted. >+ * runtime/WriteBarrierInlines.h: >+ (JSC::WriteBarrierStructureID::set): Deleted. >+ (JSC::WriteBarrierStructureID::setMayBeNull): Deleted. >+ (JSC::WriteBarrierStructureID::setEarlyValue): Deleted. >+ * tools/HeapVerifier.cpp: >+ (JSC::HeapVerifier::validateJSCell): >+ * tools/Integrity.cpp: >+ * tools/Integrity.h: >+ * tools/IntegrityInlines.h: >+ (JSC::Integrity::auditStructureID): >+ * tools/JSDollarVM.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ (JSC::JSDollarVM::finishCreation): >+ (JSC::JSDollarVM::visitChildrenImpl): >+ * tools/JSDollarVM.h: >+ * wasm/js/WebAssemblyFunction.cpp: >+ (JSC::WebAssemblyFunction::jsCallEntrypointSlow): >+ * wasm/js/WebAssemblyGlobalPrototype.cpp: >+ (JSC::getGlobal): >+ > 2021-12-13 waddlesplash <waddlesplash@gmail.com> > > ExecutableAllocator: Do not store things in g_config when USE(SYSTEM_MALLOC). >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 286965) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -762,11 +762,11 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEA > heap/HeapSnapshotBuilder.h > heap/HeapSubspaceTypes.h > heap/IncrementalSweeper.h >+ heap/IsoAlignedMemoryAllocator.h.h > heap/IsoCellSet.h > heap/IsoHeapCellType.h > heap/IsoInlinedHeapCellType.h > heap/IsoInlinedHeapCellTypeInlines.h >- heap/IsoMemoryAllocatorBase.h > heap/IsoSubspace.h > heap/IsoSubspaceInlines.h > heap/IsoSubspacePerVM.h >@@ -793,7 +793,6 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEA > heap/Strong.h > heap/StrongForward.h > heap/StrongInlines.h >- heap/StructureAlignedMemoryAllocator.h > heap/Subspace.h > heap/SubspaceInlines.h > heap/Synchronousness.h >@@ -1186,8 +1185,8 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEA > runtime/Structure.h > runtime/StructureCache.h > runtime/StructureChain.h >- runtime/StructureID.h > runtime/StructureIDBlob.h >+ runtime/StructureIDTable.h > runtime/StructureInlines.h > runtime/StructureRareData.h > runtime/StructureRareDataInlines.h >Index: Source/JavaScriptCore/Sources.txt >=================================================================== >--- Source/JavaScriptCore/Sources.txt (revision 286965) >+++ Source/JavaScriptCore/Sources.txt (working copy) >@@ -537,7 +537,6 @@ heap/IncrementalSweeper.cpp > heap/IsoAlignedMemoryAllocator.cpp > heap/IsoCellSet.cpp > heap/IsoHeapCellType.cpp >-heap/IsoMemoryAllocatorBase.cpp > heap/IsoSubspace.cpp > heap/IsoSubspacePerVM.cpp > heap/JITStubRoutineSet.cpp >@@ -559,7 +558,6 @@ heap/SlotVisitor.cpp > heap/SpaceTimeMutatorScheduler.cpp > heap/StochasticSpaceTimeMutatorScheduler.cpp > heap/StopIfNecessaryTimer.cpp >-heap/StructureAlignedMemoryAllocator.cpp > heap/Subspace.cpp > heap/SynchronousStopTheWorldMutatorScheduler.cpp > heap/Synchronousness.cpp >@@ -1007,6 +1005,7 @@ runtime/StringRecursionChecker.cpp > runtime/Structure.cpp > runtime/StructureCache.cpp > runtime/StructureChain.cpp >+runtime/StructureIDTable.cpp > runtime/StructureRareData.cpp > runtime/Symbol.cpp > runtime/SymbolConstructor.cpp >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 286965) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -857,6 +857,7 @@ > 2AACE63D18CA5A0300ED0191 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AACE63B18CA5A0300ED0191 /* GCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD8932917E3868F00668276 /* HeapIterationScope.h */; }; >+ 2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 2D342F36F7244096804ADB24 /* SourceOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 425BA1337E4344E1B269A671 /* SourceOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 33111B8B2397256500AA34CE /* Scribble.h in Headers */ = {isa = PBXBuildFile; fileRef = 33111B8A2397256500AA34CE /* Scribble.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 3395C70722555F6D00BDBFAD /* B3EliminateDeadCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3395C70522555F6D00BDBFAD /* B3EliminateDeadCode.h */; }; >@@ -1089,10 +1090,6 @@ > 536B319E1F735F160037FC33 /* LowLevelInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */; }; > 5370806B1FE232DF00299E44 /* JSArrayBufferView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66BB17B6B5AB00A7AE3F /* JSArrayBufferView.h */; }; > 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; }; >- 537FEEC92742BDA300C9EFEE /* StructureID.h in Headers */ = {isa = PBXBuildFile; fileRef = 537FEEC82742BDA300C9EFEE /* StructureID.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 537FEECE2742BDE100C9EFEE /* IsoMemoryAllocatorBaseInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 537FEECA2742BDE000C9EFEE /* IsoMemoryAllocatorBaseInlines.h */; }; >- 537FEED02742BDE100C9EFEE /* StructureAlignedMemoryAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 537FEECC2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.h */; }; >- 537FEED12742BDE100C9EFEE /* IsoMemoryAllocatorBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 537FEECD2742BDE000C9EFEE /* IsoMemoryAllocatorBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 5381B9391E60E97D0090F794 /* WasmFaultSignalHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 538F15E7268FBBB600D601C4 /* UnifiedSource148.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 538F15DD268FBBB300D601C4 /* UnifiedSource148.cpp */; }; > 538F15E8268FBBB600D601C4 /* UnifiedSource151.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 538F15DE268FBBB300D601C4 /* UnifiedSource151.cpp */; }; >@@ -3639,6 +3636,8 @@ > 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnumerationMode.h; sourceTree = "<group>"; }; > 2AD8932917E3868F00668276 /* HeapIterationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapIterationScope.h; sourceTree = "<group>"; }; > 2ADFA26218EF3540004F9FCC /* GCLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCLogging.cpp; sourceTree = "<group>"; }; >+ 2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureIDTable.cpp; sourceTree = "<group>"; }; >+ 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureIDTable.h; sourceTree = "<group>"; }; > 3032175DF1AD47D8998B34E1 /* JSSourceCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSourceCode.h; sourceTree = "<group>"; }; > 30A5F403F11C4F599CD596D5 /* WasmSignatureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignatureInlines.h; sourceTree = "<group>"; }; > 33111B8A2397256500AA34CE /* Scribble.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Scribble.h; sourceTree = "<group>"; }; >@@ -3741,7 +3740,6 @@ > 530FB3011E7A0B6E003C19DD /* WasmWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmWorklist.h; sourceTree = "<group>"; }; > 530FB3031E7A1146003C19DD /* WasmWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmWorklist.cpp; sourceTree = "<group>"; }; > 530FDE7321FAAFC600059D65 /* testIncludes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = testIncludes.m; path = API/tests/testIncludes.m; sourceTree = "<group>"; }; >- 531013F3274419F40009009C /* libWTF.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libWTF.a; sourceTree = BUILT_PRODUCTS_DIR; }; > 5311BD481EA581E500525281 /* WasmOMGPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOMGPlan.cpp; sourceTree = "<group>"; }; > 5311BD491EA581E500525281 /* WasmOMGPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOMGPlan.h; sourceTree = "<group>"; }; > 531374BC1D5CE67600AF7A0B /* WasmPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmPlan.h; sourceTree = "<group>"; }; >@@ -3930,11 +3928,6 @@ > 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = "<group>"; }; > 5373B4D322AD8BF700803572 /* WeakObjectRefPrototype.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeakObjectRefPrototype.cpp; sourceTree = "<group>"; }; > 5373B4D422ADB31400803572 /* WeakObjectRefConstructor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeakObjectRefConstructor.cpp; sourceTree = "<group>"; }; >- 537FEEC82742BDA300C9EFEE /* StructureID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureID.h; sourceTree = "<group>"; }; >- 537FEECA2742BDE000C9EFEE /* IsoMemoryAllocatorBaseInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IsoMemoryAllocatorBaseInlines.h; sourceTree = "<group>"; }; >- 537FEECB2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureAlignedMemoryAllocator.cpp; sourceTree = "<group>"; }; >- 537FEECC2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureAlignedMemoryAllocator.h; sourceTree = "<group>"; }; >- 537FEECD2742BDE000C9EFEE /* IsoMemoryAllocatorBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IsoMemoryAllocatorBase.h; sourceTree = "<group>"; }; > 5381B9361E60E9660090F794 /* WasmFaultSignalHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmFaultSignalHandler.cpp; sourceTree = "<group>"; }; > 5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmFaultSignalHandler.h; sourceTree = "<group>"; }; > 5383AA2F1E65E8A100A532FC /* JSWebAssemblyCodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyCodeBlock.cpp; path = js/JSWebAssemblyCodeBlock.cpp; sourceTree = "<group>"; }; >@@ -5790,7 +5783,6 @@ > 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */, > 9322A00306C341D3009067BB /* libicucore.dylib */, > 51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */, >- 531013F3274419F40009009C /* libWTF.a */, > 1498CAD3214656C400710879 /* libWTF.a */, > A8A4748D151A8306004123FF /* libWTF.a */, > 371D842C17C98B6E00ECF994 /* libz.dylib */, >@@ -6672,8 +6664,6 @@ > 142E3132134FF0A600AFADB5 /* Strong.h */, > CD1F9B4A270CFE0F00617EB6 /* StrongForward.h */, > 145722851437E140005FDE26 /* StrongInlines.h */, >- 537FEECB2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.cpp */, >- 537FEECC2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.h */, > 0F7DF1311E2970D50095951B /* Subspace.cpp */, > 0F7DF1321E2970D50095951B /* Subspace.h */, > 0F7DF1331E2970D50095951B /* SubspaceInlines.h */, >@@ -8075,8 +8065,9 @@ > 7986943A1F8C0AC8009232AE /* StructureCache.h */, > 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */, > 7E4EE7080EBB7963005934AA /* StructureChain.h */, >- 537FEEC82742BDA300C9EFEE /* StructureID.h */, > 2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */, >+ 2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */, >+ 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */, > 0FD2C92316D01EE900C7803F /* StructureInlines.h */, > C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */, > C2FE18A316BAEC4000AF3061 /* StructureRareData.h */, >@@ -10276,8 +10267,6 @@ > 0FB467811FDDA6F7003FCB09 /* IsoCellSetInlines.h in Headers */, > E3BF1BAE238AAEDB003A1C2B /* IsoHeapCellType.h in Headers */, > E3C8ED4323A1DBCB00131958 /* IsoInlinedHeapCellType.h in Headers */, >- 537FEED12742BDE100C9EFEE /* IsoMemoryAllocatorBase.h in Headers */, >- 537FEECE2742BDE100C9EFEE /* IsoMemoryAllocatorBaseInlines.h in Headers */, > 0FDCE12D1FAFB4E5006F3901 /* IsoSubspace.h in Headers */, > 0FD2FD9520B52BE200F09441 /* IsoSubspaceInlines.h in Headers */, > 0F5E0FE72086AD480097F0DE /* IsoSubspacePerVM.h in Headers */, >@@ -10828,11 +10817,10 @@ > CD1F9B4B270CFE0F00617EB6 /* StrongForward.h in Headers */, > 145722861437E140005FDE26 /* StrongInlines.h in Headers */, > BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */, >- 537FEED02742BDE100C9EFEE /* StructureAlignedMemoryAllocator.h in Headers */, > 7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */, > 7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */, >- 537FEEC92742BDA300C9EFEE /* StructureID.h in Headers */, > 2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */, >+ 2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */, > 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */, > C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */, > C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */, >Index: Source/JavaScriptCore/bytecode/AccessCase.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/AccessCase.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/AccessCase.cpp (working copy) >@@ -63,7 +63,7 @@ AccessCase::AccessCase(VM& vm, JSCell* o > , m_polyProtoAccessChain(WTFMove(prototypeAccessChain)) > , m_identifier(identifier) > { >- m_structureID.setMayBeNull(vm, owner, structure); >+ m_structure.setMayBeNull(vm, owner, structure); > m_conditionSet = conditionSet; > RELEASE_ASSERT(m_conditionSet.isValid()); > } >@@ -536,14 +536,14 @@ bool AccessCase::needsScratchFPR() const > } > > template<typename Functor> >-void AccessCase::forEachDependentCell(VM&, const Functor& functor) const >+void AccessCase::forEachDependentCell(VM& vm, const Functor& functor) const > { > m_conditionSet.forEachDependentCell(functor); >- if (m_structureID) >- functor(m_structureID.get()); >+ if (m_structure) >+ functor(m_structure.get()); > if (m_polyProtoAccessChain) { > for (StructureID structureID : m_polyProtoAccessChain->chain()) >- functor(structureID.decode()); >+ functor(vm.getStructure(structureID)); > } > > switch (type()) { >@@ -874,8 +874,8 @@ void AccessCase::dump(PrintStream& out) > if (m_type == Transition || m_type == Delete || m_type == SetPrivateBrand) > out.print("\n", indent, "from structure = ", pointerDump(structure()), > "\n", indent, "to structure = ", pointerDump(newStructure())); >- else if (m_structureID) >- out.print("\n", indent, "structure = ", pointerDump(m_structureID.get())); >+ else if (m_structure) >+ out.print("\n", indent, "structure = ", pointerDump(m_structure.get())); > } > > if (!m_conditionSet.isEmpty()) >@@ -904,19 +904,19 @@ bool AccessCase::visitWeak(VM& vm) const > template<typename Visitor> > void AccessCase::propagateTransitions(Visitor& visitor) const > { >- if (m_structureID) >- m_structureID->markIfCheap(visitor); >+ if (m_structure) >+ m_structure->markIfCheap(visitor); > > if (m_polyProtoAccessChain) { > for (StructureID structureID : m_polyProtoAccessChain->chain()) >- structureID.decode()->markIfCheap(visitor); >+ visitor.vm().getStructure(structureID)->markIfCheap(visitor); > } > > switch (m_type) { > case Transition: > case Delete: >- if (visitor.isMarked(m_structureID->previousID())) >- visitor.appendUnbarriered(m_structureID.get()); >+ if (visitor.isMarked(m_structure->previousID())) >+ visitor.appendUnbarriered(m_structure.get()); > break; > default: > break; >@@ -1720,7 +1720,7 @@ void AccessCase::generateWithGuard( > JSValueRegs resultRegs(scratchGPR, scratch2GPR); > #endif > >- jit.emitLoadPrototype(vm, valueGPR, resultRegs, failAndIgnore); >+ jit.emitLoadPrototype(vm, valueGPR, resultRegs, scratchGPR, failAndIgnore); > jit.move(scratch2GPR, valueGPR); > > CCallHelpers::Jump isInstance = jit.branchPtr(CCallHelpers::Equal, valueGPR, prototypeGPR); >@@ -2613,7 +2613,7 @@ bool AccessCase::canBeShared(const Acces > return false; > if (lhs.m_viaProxy != rhs.m_viaProxy) > return false; >- if (lhs.m_structureID.get() != rhs.m_structureID.get()) >+ if (lhs.m_structure.get() != rhs.m_structure.get()) > return false; > if (lhs.m_identifier != rhs.m_identifier) > return false; >Index: Source/JavaScriptCore/bytecode/AccessCase.h >=================================================================== >--- Source/JavaScriptCore/bytecode/AccessCase.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/AccessCase.h (working copy) >@@ -184,15 +184,15 @@ public: > Structure* structure() const > { > if (m_type == Transition || m_type == Delete || m_type == SetPrivateBrand) >- return m_structureID->previousID(); >- return m_structureID.get(); >+ return m_structure->previousID(); >+ return m_structure.get(); > } > bool guardedByStructureCheck(const StructureStubInfo&) const; > > Structure* newStructure() const > { > ASSERT(m_type == Transition || m_type == Delete || m_type == SetPrivateBrand); >- return m_structureID.get(); >+ return m_structure.get(); > } > > ObjectPropertyConditionSet conditionSet() const { return m_conditionSet; } >@@ -272,7 +272,7 @@ public: > > unsigned hash() const > { >- return computeHash(m_conditionSet.hash(), static_cast<unsigned>(m_type), m_viaProxy, m_structureID.unvalidatedGet(), m_offset); >+ return computeHash(m_conditionSet.hash(), static_cast<unsigned>(m_type), m_viaProxy, m_structure.unvalidatedGet(), m_offset); > } > > static bool canBeShared(const AccessCase&, const AccessCase&); >@@ -284,7 +284,7 @@ protected: > , m_state(WTFMove(other.m_state)) > , m_viaProxy(WTFMove(other.m_viaProxy)) > , m_offset(WTFMove(other.m_offset)) >- , m_structureID(WTFMove(other.m_structureID)) >+ , m_structure(WTFMove(other.m_structure)) > , m_conditionSet(WTFMove(other.m_conditionSet)) > , m_polyProtoAccessChain(WTFMove(other.m_polyProtoAccessChain)) > , m_identifier(WTFMove(other.m_identifier)) >@@ -295,7 +295,7 @@ protected: > , m_state(other.m_state) > , m_viaProxy(other.m_viaProxy) > , m_offset(other.m_offset) >- , m_structureID(other.m_structureID) >+ , m_structure(other.m_structure) > , m_conditionSet(other.m_conditionSet) > , m_polyProtoAccessChain(other.m_polyProtoAccessChain) > , m_identifier(other.m_identifier) >@@ -348,7 +348,7 @@ private: > // Usually this is the structure that we expect the base object to have. But, this is the *new* > // structure for a transition and we rely on the fact that it has a strong reference to the old > // structure. For proxies, this is the structure of the object behind the proxy. >- WriteBarrierStructureID m_structureID; >+ WriteBarrier<Structure> m_structure; > > ObjectPropertyConditionSet m_conditionSet; > >Index: Source/JavaScriptCore/bytecode/ArrayProfile.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/ArrayProfile.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/ArrayProfile.cpp (working copy) >@@ -123,9 +123,9 @@ void ArrayProfile::computeUpdatedPredict > if (!m_lastSeenStructureID) > return; > >- Structure* lastSeenStructure = m_lastSeenStructureID.decode(); >+ Structure* lastSeenStructure = codeBlock->heap()->structureIDTable().get(m_lastSeenStructureID); > computeUpdatedPrediction(locker, codeBlock, lastSeenStructure); >- m_lastSeenStructureID = StructureID(); >+ m_lastSeenStructureID = 0; > } > > void ArrayProfile::computeUpdatedPrediction(const ConcurrentJSLocker&, CodeBlock* codeBlock, Structure* lastSeenStructure) >Index: Source/JavaScriptCore/bytecode/ArrayProfile.h >=================================================================== >--- Source/JavaScriptCore/bytecode/ArrayProfile.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/ArrayProfile.h (working copy) >@@ -249,7 +249,7 @@ private: > > static Structure* polymorphicStructure() { return static_cast<Structure*>(reinterpret_cast<void*>(1)); } > >- StructureID m_lastSeenStructureID; >+ StructureID m_lastSeenStructureID { 0 }; > bool m_mayStoreToHole { false }; // This flag may become overloaded to indicate other special cases that were encountered during array access, as it depends on indexing type. Since we currently have basically just one indexing type (two variants of ArrayStorage), this flag for now just means exactly what its name implies. > bool m_outOfBounds { false }; > #if USE(LARGE_TYPED_ARRAYS) >Index: Source/JavaScriptCore/bytecode/CheckPrivateBrandStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/CheckPrivateBrandStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/CheckPrivateBrandStatus.cpp (working copy) >@@ -100,7 +100,7 @@ CheckPrivateBrandStatus CheckPrivateBran > return CheckPrivateBrandStatus(NoInformation); > > case CacheType::Stub: { >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > > for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { > const AccessCase& access = list->at(listIndex); >Index: Source/JavaScriptCore/bytecode/CodeBlock.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/CodeBlock.cpp (working copy) >@@ -1192,6 +1192,7 @@ template<typename Visitor> > void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, Visitor& visitor) > { > typename Visitor::SuppressGCVerifierScope suppressScope(visitor); >+ VM& vm = *m_vm; > > if (jitType() == JITType::InterpreterThunk) { > if (m_metadata) { >@@ -1201,9 +1202,9 @@ void CodeBlock::propagateTransitions(con > if (!oldStructureID || !newStructureID) > return; > >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.heap.structureIDTable().get(oldStructureID); > if (visitor.isMarked(oldStructure)) { >- Structure* newStructure = newStructureID.decode(); >+ Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); > visitor.appendUnbarriered(newStructure); > } > }); >@@ -1219,9 +1220,9 @@ void CodeBlock::propagateTransitions(con > if (!visitor.isMarked(property)) > return; > >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.heap.structureIDTable().get(oldStructureID); > if (visitor.isMarked(oldStructure)) { >- Structure* newStructure = newStructureID.decode(); >+ Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); > visitor.appendUnbarriered(newStructure); > } > }); >@@ -1237,9 +1238,9 @@ void CodeBlock::propagateTransitions(con > if (!visitor.isMarked(brand)) > return; > >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.heap.structureIDTable().get(oldStructureID); > if (visitor.isMarked(oldStructure)) { >- Structure* newStructure = newStructureID.decode(); >+ Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); > visitor.appendUnbarriered(newStructure); > } > }); >@@ -1268,7 +1269,7 @@ void CodeBlock::propagateTransitions(con > dfgCommon->recordedStatuses.markIfCheap(visitor); > > for (StructureID structureID : dfgCommon->m_weakStructureReferences) >- structureID.decode()->markIfCheap(visitor); >+ vm.getStructure(structureID)->markIfCheap(visitor); > > for (auto& transition : dfgCommon->m_transitions) { > if (shouldMarkTransition(visitor, transition)) { >@@ -1308,7 +1309,6 @@ void CodeBlock::determineLiveness(const > > #if ENABLE(DFG_JIT) > VM& vm = *m_vm; >- UNUSED_VARIABLE(vm); > if (visitor.isMarked(this)) > return; > >@@ -1333,7 +1333,7 @@ void CodeBlock::determineLiveness(const > } > if (allAreLiveSoFar) { > for (StructureID structureID : dfgCommon->m_weakStructureReferences) { >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.getStructure(structureID); > if (!visitor.isMarked(structure)) { > allAreLiveSoFar = false; > break; >@@ -1367,7 +1367,7 @@ void CodeBlock::finalizeLLIntInlineCache > if (modeMetadata.mode != GetByIdMode::Default) > return; > StructureID oldStructureID = modeMetadata.defaultMode.structureID; >- if (!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >+ if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing ", opName, " LLInt property access."); > LLIntPrototypeLoadAdaptiveStructureWatchpoint::clearLLIntGetByIdCache(modeMetadata); >@@ -1388,19 +1388,19 @@ void CodeBlock::finalizeLLIntInlineCache > > m_metadata->forEach<OpTryGetById>([&] (auto& metadata) { > StructureID oldStructureID = metadata.m_structureID; >- if (!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >+ if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing try_get_by_id LLInt property access."); >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_offset = 0; > }); > > m_metadata->forEach<OpGetByIdDirect>([&] (auto& metadata) { > StructureID oldStructureID = metadata.m_structureID; >- if (!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >+ if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing get_by_id_direct LLInt property access."); >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_offset = 0; > }); > >@@ -1408,11 +1408,11 @@ void CodeBlock::finalizeLLIntInlineCache > JSCell* property = metadata.m_property.get(); > StructureID structureID = metadata.m_structureID; > >- if ((!property || vm.heap.isMarked(property)) && (!structureID || vm.heap.isMarked(structureID.decode()))) >+ if ((!property || vm.heap.isMarked(property)) && (!structureID || vm.heap.isMarked(vm.heap.structureIDTable().get(structureID)))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt private property access."); >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_offset = 0; > metadata.m_property.clear(); > }); >@@ -1421,14 +1421,14 @@ void CodeBlock::finalizeLLIntInlineCache > StructureID oldStructureID = metadata.m_oldStructureID; > StructureID newStructureID = metadata.m_newStructureID; > StructureChain* chain = metadata.m_structureChain.get(); >- if ((!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >- && (!newStructureID || vm.heap.isMarked(newStructureID.decode())) >+ if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) >+ && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID))) > && (!chain || vm.heap.isMarked(chain))) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt put transition."); >- metadata.m_oldStructureID = StructureID(); >+ metadata.m_oldStructureID = 0; > metadata.m_offset = 0; >- metadata.m_newStructureID = StructureID(); >+ metadata.m_newStructureID = 0; > metadata.m_structureChain.clear(); > }); > >@@ -1436,15 +1436,15 @@ void CodeBlock::finalizeLLIntInlineCache > StructureID oldStructureID = metadata.m_oldStructureID; > StructureID newStructureID = metadata.m_newStructureID; > JSCell* property = metadata.m_property.get(); >- if ((!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >+ if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) > && (!property || vm.heap.isMarked(property)) >- && (!newStructureID || vm.heap.isMarked(newStructureID.decode()))) >+ && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt put_private_name transition."); >- metadata.m_oldStructureID = StructureID(); >+ metadata.m_oldStructureID = 0; > metadata.m_offset = 0; >- metadata.m_newStructureID = StructureID(); >+ metadata.m_newStructureID = 0; > metadata.m_property.clear(); > }); > >@@ -1452,37 +1452,37 @@ void CodeBlock::finalizeLLIntInlineCache > StructureID oldStructureID = metadata.m_oldStructureID; > StructureID newStructureID = metadata.m_newStructureID; > JSCell* brand = metadata.m_brand.get(); >- if ((!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >+ if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) > && (!brand || vm.heap.isMarked(brand)) >- && (!newStructureID || vm.heap.isMarked(newStructureID.decode()))) >+ && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt set_private_brand transition."); >- metadata.m_oldStructureID = StructureID(); >- metadata.m_newStructureID = StructureID(); >+ metadata.m_oldStructureID = 0; >+ metadata.m_newStructureID = 0; > metadata.m_brand.clear(); > }); > > m_metadata->forEach<OpCheckPrivateBrand>([&] (auto& metadata) { > StructureID structureID = metadata.m_structureID; > JSCell* brand = metadata.m_brand.get(); >- if ((!structureID || vm.heap.isMarked(structureID.decode())) >+ if ((!structureID || vm.heap.isMarked(vm.heap.structureIDTable().get(structureID))) > && (!brand || vm.heap.isMarked(brand))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt check_private_brand transition."); >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_brand.clear(); > }); > > m_metadata->forEach<OpToThis>([&] (auto& metadata) { >- if (!metadata.m_cachedStructureID || vm.heap.isMarked(metadata.m_cachedStructureID.decode())) >+ if (!metadata.m_cachedStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(metadata.m_cachedStructureID))) > return; > if (Options::verboseOSR()) { >- Structure* structure = metadata.m_cachedStructureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(metadata.m_cachedStructureID); > dataLogF("Clearing LLInt to_this with structure %p.\n", structure); > } >- metadata.m_cachedStructureID = StructureID(); >+ metadata.m_cachedStructureID = 0; > metadata.m_toThisStatus = merge(metadata.m_toThisStatus, ToThisClearedByGC); > }); > >@@ -1569,7 +1569,7 @@ void CodeBlock::finalizeLLIntInlineCache > return true; > }; > >- if (!vm.heap.isMarked(std::get<0>(pair.key).decode())) >+ if (!vm.heap.isMarked(vm.heap.structureIDTable().get(std::get<0>(pair.key)))) > return clear(); > > for (const LLIntPrototypeLoadAdaptiveStructureWatchpoint& watchpoint : pair.value) { >@@ -1917,7 +1917,7 @@ void CodeBlock::stronglyVisitWeakReferen > visitor.append(weakReference); > > for (StructureID structureID : dfgCommon->m_weakStructureReferences) >- visitor.appendUnbarriered(structureID.decode()); >+ visitor.appendUnbarriered(visitor.vm().getStructure(structureID)); > #endif > } > >Index: Source/JavaScriptCore/bytecode/DeleteByStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/DeleteByStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/DeleteByStatus.cpp (working copy) >@@ -99,7 +99,7 @@ DeleteByStatus DeleteByStatus::computeFo > return DeleteByStatus(NoInformation); > > case CacheType::Stub: { >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > > for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { > const AccessCase& access = list->at(listIndex); >Index: Source/JavaScriptCore/bytecode/GetByIdMetadata.h >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdMetadata.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/GetByIdMetadata.h (working copy) >@@ -69,7 +69,7 @@ static_assert(sizeof(GetByIdModeMetadata > union GetByIdModeMetadata { > GetByIdModeMetadata() > { >- defaultMode.structureID = StructureID(); >+ defaultMode.structureID = 0; > defaultMode.cachedOffset = 0; > defaultMode.padding1 = 0; > mode = GetByIdMode::Default; >@@ -100,7 +100,7 @@ static_assert(sizeof(GetByIdModeMetadata > struct GetByIdModeMetadata { > GetByIdModeMetadata() > { >- defaultMode.structureID = StructureID(); >+ defaultMode.structureID = 0; > defaultMode.cachedOffset = 0; > defaultMode.padding1 = 0; > mode = GetByIdMode::Default; >@@ -127,7 +127,7 @@ struct GetByIdModeMetadata { > inline void GetByIdModeMetadata::clearToDefaultModeWithoutCache() > { > mode = GetByIdMode::Default; >- defaultMode.structureID = StructureID(); >+ defaultMode.structureID = 0; > defaultMode.cachedOffset = 0; > } > >Index: Source/JavaScriptCore/bytecode/GetByStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/GetByStatus.cpp (working copy) >@@ -127,7 +127,7 @@ GetByStatus GetByStatus::computeFromLLIn > if (!structureID) > return GetByStatus(NoInformation, false); > >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(structureID); > > if (structure->takesSlowPathInDFGForImpureProperty()) > return GetByStatus(NoInformation, false); >@@ -236,7 +236,7 @@ GetByStatus GetByStatus::computeForStubI > } > > case CacheType::Stub: { >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > if (list->size() == 1) { > const AccessCase& access = list->at(0); > switch (access.type()) { >Index: Source/JavaScriptCore/bytecode/InByStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/InByStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/InByStatus.cpp (working copy) >@@ -160,7 +160,7 @@ InByStatus InByStatus::computeForStubInf > } > > case CacheType::Stub: { >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { > const AccessCase& access = list->at(listIndex); > if (access.viaProxy()) >Index: Source/JavaScriptCore/bytecode/InlineAccess.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/InlineAccess.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/InlineAccess.cpp (working copy) >@@ -447,7 +447,7 @@ void InlineAccess::rewireStubAsJumpInAcc > } > > stubInfo.m_codePtr = target; >- stubInfo.m_inlineAccessBaseStructureID.clear(); // Clear out the inline access code. >+ stubInfo.m_inlineAccessBaseStructure = 0; // Clear out the inline access code. > return; > } > >@@ -464,7 +464,7 @@ void InlineAccess::resetStubAsJumpInAcce > { > if (codeBlock->useDataIC() && codeBlock->jitType() == JITType::BaselineJIT) { > stubInfo.m_codePtr = stubInfo.slowPathStartLocation; >- stubInfo.m_inlineAccessBaseStructureID.clear(); // Clear out the inline access code. >+ stubInfo.m_inlineAccessBaseStructure = 0; // Clear out the inline access code. > return; > } > >Index: Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp (working copy) >@@ -83,7 +83,7 @@ InstanceOfStatus InstanceOfStatus::compu > if (stubInfo->cacheType() != CacheType::Stub) > return TakesSlowPath; // This is conservative. It could be that we have no information. > >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > InstanceOfStatus result; > for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { > const AccessCase& access = list->at(listIndex); >Index: Source/JavaScriptCore/bytecode/InternalFunctionAllocationProfile.h >=================================================================== >--- Source/JavaScriptCore/bytecode/InternalFunctionAllocationProfile.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/InternalFunctionAllocationProfile.h (working copy) >@@ -33,21 +33,21 @@ namespace JSC { > > class InternalFunctionAllocationProfile { > public: >- static inline ptrdiff_t offsetOfStructureID() { return OBJECT_OFFSETOF(InternalFunctionAllocationProfile, m_structureID); } >+ static inline ptrdiff_t offsetOfStructure() { return OBJECT_OFFSETOF(InternalFunctionAllocationProfile, m_structure); } > >- Structure* structure() { return m_structureID.get(); } >+ Structure* structure() { return m_structure.get(); } > Structure* createAllocationStructureFromBase(VM&, JSGlobalObject*, JSCell* owner, JSObject* prototype, Structure* base); > >- void clear() { m_structureID.clear(); } >- template<typename Visitor> void visitAggregate(Visitor& visitor) { visitor.append(m_structureID); } >+ void clear() { m_structure.clear(); } >+ template<typename Visitor> void visitAggregate(Visitor& visitor) { visitor.append(m_structure); } > > private: >- WriteBarrierStructureID m_structureID; >+ WriteBarrier<Structure> m_structure; > }; > > inline Structure* InternalFunctionAllocationProfile::createAllocationStructureFromBase(VM& vm, JSGlobalObject* baseGlobalObject, JSCell* owner, JSObject* prototype, Structure* baseStructure) > { >- ASSERT(!m_structureID || m_structureID.get()->classInfo() != baseStructure->classInfo() || m_structureID->globalObject() != baseStructure->globalObject()); >+ ASSERT(!m_structure || m_structure.get()->classInfo() != baseStructure->classInfo() || m_structure->globalObject() != baseStructure->globalObject()); > ASSERT(baseStructure->hasMonoProto()); > > Structure* structure; >@@ -61,8 +61,8 @@ inline Structure* InternalFunctionAlloca > // Ensure that if another thread sees the structure, it will see it properly created. > WTF::storeStoreFence(); > >- m_structureID.set(vm, owner, structure); >- return structure; >+ m_structure.set(vm, owner, structure); >+ return m_structure.get(); > } > > } // namespace JSC >Index: Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp (working copy) >@@ -80,10 +80,10 @@ RefPtr<PolyProtoAccessChain> PolyProtoAc > return adoptRef(*new PolyProtoAccessChain(WTFMove(chain))); > } > >-bool PolyProtoAccessChain::needImpurePropertyWatchpoint(VM&) const >+bool PolyProtoAccessChain::needImpurePropertyWatchpoint(VM& vm) const > { > for (StructureID structureID : m_chain) { >- if (structureID.decode()->needImpurePropertyWatchpoint()) >+ if (vm.getStructure(structureID)->needImpurePropertyWatchpoint()) > return true; > } > return false; >Index: Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >=================================================================== >--- Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h (working copy) >@@ -25,7 +25,7 @@ > > #pragma once > >-#include "StructureID.h" >+#include "StructureIDTable.h" > #include "VM.h" > #include <wtf/FixedVector.h> > #include <wtf/Vector.h> >@@ -57,20 +57,20 @@ public: > bool needImpurePropertyWatchpoint(VM&) const; > > template <typename Func> >- void forEach(VM&, Structure* baseStructure, const Func& func) const >+ void forEach(VM& vm, Structure* baseStructure, const Func& func) const > { > bool atEnd = !m_chain.size(); > func(baseStructure, atEnd); > for (unsigned i = 0; i < m_chain.size(); ++i) { > atEnd = i + 1 == m_chain.size(); >- func(m_chain[i].decode(), atEnd); >+ func(vm.getStructure(m_chain[i]), atEnd); > } > } > >- Structure* slotBaseStructure(VM&, Structure* baseStructure) const >+ Structure* slotBaseStructure(VM& vm, Structure* baseStructure) const > { > if (m_chain.size()) >- return m_chain.last().decode(); >+ return vm.getStructure(m_chain.last()); > return baseStructure; > } > >Index: Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (working copy) >@@ -381,7 +381,7 @@ bool PolymorphicAccess::visitWeak(VM& vm > } > if (m_stubRoutine) { > for (StructureID weakReference : m_stubRoutine->weakStructures()) { >- Structure* structure = weakReference.decode(); >+ Structure* structure = vm.getStructure(weakReference); > if (!vm.heap.isMarked(structure)) > return false; > } >Index: Source/JavaScriptCore/bytecode/PutByIdFlags.h >=================================================================== >--- Source/JavaScriptCore/bytecode/PutByIdFlags.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/PutByIdFlags.h (working copy) >@@ -26,6 +26,7 @@ > #pragma once > > #include "ECMAMode.h" >+#include "StructureIDTable.h" > > namespace JSC { > >Index: Source/JavaScriptCore/bytecode/PutByStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/PutByStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/PutByStatus.cpp (working copy) >@@ -81,7 +81,7 @@ PutByStatus PutByStatus::computeFromLLIn > if (!structureID) > return PutByStatus(NoInformation); > >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(structureID); > > StructureID newStructureID = metadata.m_newStructureID; > if (!newStructureID) { >@@ -92,7 +92,7 @@ PutByStatus PutByStatus::computeFromLLIn > return PutByVariant::replace(nullptr, structure, offset); > } > >- Structure* newStructure = newStructureID.decode(); >+ Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); > > ASSERT(structure->transitionWatchpointSetHasBeenInvalidated()); > >@@ -188,7 +188,7 @@ PutByStatus PutByStatus::computeForStubI > } > > case CacheType::Stub: { >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > > PutByStatus result; > result.m_state = Simple; >Index: Source/JavaScriptCore/bytecode/SetPrivateBrandStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/SetPrivateBrandStatus.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/SetPrivateBrandStatus.cpp (working copy) >@@ -100,7 +100,7 @@ SetPrivateBrandStatus SetPrivateBrandSta > return SetPrivateBrandStatus(NoInformation); > > case CacheType::Stub: { >- PolymorphicAccess* list = stubInfo->m_stub; >+ PolymorphicAccess* list = stubInfo->u.stub; > > for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { > const AccessCase& access = list->at(listIndex); >Index: Source/JavaScriptCore/bytecode/SpeculatedType.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/SpeculatedType.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/SpeculatedType.cpp (working copy) >@@ -596,7 +596,13 @@ SpeculatedType speculationFromCell(JSCel > } > return SpecString; > } >- return speculationFromStructure(cell->structure()); >+ // FIXME: rdar://69036888: undo this when no longer needed. >+ auto* structure = cell->vm().tryGetStructure(cell->structureID()); >+ if (UNLIKELY(!isSanePointer(structure))) { >+ ASSERT_NOT_REACHED(); >+ return SpecNone; >+ } >+ return speculationFromStructure(structure); > } > > SpeculatedType speculationFromValue(JSValue value) >Index: Source/JavaScriptCore/bytecode/StructureStubInfo.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (revision 286965) >+++ Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (working copy) >@@ -49,7 +49,8 @@ void StructureStubInfo::initGetByIdSelf( > ASSERT(hasConstantIdentifier); > setCacheType(locker, CacheType::GetByIdSelf); > m_identifier = identifier; >- m_inlineAccessBaseStructureID.set(codeBlock->vm(), codeBlock, inlineAccessBaseStructure); >+ m_inlineAccessBaseStructure = inlineAccessBaseStructure->id(); >+ codeBlock->vm().writeBarrier(codeBlock); > byIdSelfOffset = offset; > } > >@@ -70,7 +71,8 @@ void StructureStubInfo::initPutByIdRepla > ASSERT(m_cacheType == CacheType::Unset); > setCacheType(locker, CacheType::PutByIdReplace); > m_identifier = identifier; >- m_inlineAccessBaseStructureID.set(codeBlock->vm(), codeBlock, inlineAccessBaseStructure); >+ m_inlineAccessBaseStructure = inlineAccessBaseStructure->id(); >+ codeBlock->vm().writeBarrier(codeBlock); > byIdSelfOffset = offset; > } > >@@ -79,7 +81,8 @@ void StructureStubInfo::initInByIdSelf(c > ASSERT(m_cacheType == CacheType::Unset); > setCacheType(locker, CacheType::InByIdSelf); > m_identifier = identifier; >- m_inlineAccessBaseStructureID.set(codeBlock->vm(), codeBlock, inlineAccessBaseStructure); >+ m_inlineAccessBaseStructure = inlineAccessBaseStructure->id(); >+ codeBlock->vm().writeBarrier(codeBlock); > byIdSelfOffset = offset; > } > >@@ -87,7 +90,7 @@ void StructureStubInfo::deref() > { > switch (m_cacheType) { > case CacheType::Stub: >- delete m_stub; >+ delete u.stub; > return; > case CacheType::Unset: > case CacheType::GetByIdSelf: >@@ -105,7 +108,7 @@ void StructureStubInfo::aboutToDie() > { > switch (m_cacheType) { > case CacheType::Stub: >- m_stub->aboutToDie(); >+ u.stub->aboutToDie(); > return; > case CacheType::Unset: > case CacheType::GetByIdSelf: >@@ -136,7 +139,7 @@ AccessGenerationResult StructureStubInfo > AccessGenerationResult result; > > if (m_cacheType == CacheType::Stub) { >- result = m_stub->addCase(locker, vm, codeBlock, *this, accessCase.releaseNonNull()); >+ result = u.stub->addCase(locker, vm, codeBlock, *this, accessCase.releaseNonNull()); > > if (StructureStubInfoInternal::verbose) > dataLog("Had stub, result: ", result, "\n"); >@@ -173,7 +176,7 @@ AccessGenerationResult StructureStubInfo > } > > setCacheType(locker, CacheType::Stub); >- m_stub = access.release(); >+ u.stub = access.release(); > } > > ASSERT(m_cacheType == CacheType::Stub); >@@ -199,7 +202,7 @@ AccessGenerationResult StructureStubInfo > // PolymorphicAccess. > clearBufferedStructures(); > >- result = m_stub->regenerate(locker, vm, globalObject, codeBlock, ecmaMode, *this); >+ result = u.stub->regenerate(locker, vm, globalObject, codeBlock, ecmaMode, *this); > > if (StructureStubInfoInternal::verbose) > dataLog("Regeneration result: ", result, "\n"); >@@ -213,11 +216,11 @@ AccessGenerationResult StructureStubInfo > // access code. That's because when we first transition to becoming a Stub, we may > // be buffered, and we have not yet generated any code. Once the Stub finally generates > // code, we're no longer running the inline access code, so we can then clear out >- // m_inlineAccessBaseStructureID. The reason we don't clear m_inlineAccessBaseStructureID while >- // we're buffered is because we rely on it to reset during GC if m_inlineAccessBaseStructureID >+ // m_inlineAccessBaseStructure. The reason we don't clear m_inlineAccessBaseStructure while >+ // we're buffered is because we rely on it to reset during GC if m_inlineAccessBaseStructure > // is collected. > m_identifier = nullptr; >- m_inlineAccessBaseStructureID.clear(); >+ m_inlineAccessBaseStructure = 0; > > // If we generated some code then we don't want to attempt to repatch in the future until we > // gather enough cases. >@@ -232,7 +235,7 @@ void StructureStubInfo::reset(const Conc > { > clearBufferedStructures(); > m_identifier = nullptr; >- m_inlineAccessBaseStructureID.clear(); >+ m_inlineAccessBaseStructure = 0; > > if (m_cacheType == CacheType::Unset) > return; >@@ -320,7 +323,7 @@ void StructureStubInfo::visitAggregateIm > case CacheType::GetByIdSelf: > return; > case CacheType::Stub: >- m_stub->visitAggregate(visitor); >+ u.stub->visitAggregate(visitor); > return; > } > >@@ -345,7 +348,7 @@ void StructureStubInfo::visitWeakReferen > if (Structure* structure = inlineAccessBaseStructure(vm)) > isValid &= vm.heap.isMarked(structure); > if (m_cacheType == CacheType::Stub) >- isValid &= m_stub->visitWeak(vm); >+ isValid &= u.stub->visitWeak(vm); > > if (isValid) > return; >@@ -361,7 +364,7 @@ void StructureStubInfo::propagateTransit > structure->markIfCheap(visitor); > > if (m_cacheType == CacheType::Stub) >- m_stub->propagateTransitions(visitor); >+ u.stub->propagateTransitions(visitor); > } > > template void StructureStubInfo::propagateTransitions(AbstractSlotVisitor&); >@@ -372,7 +375,7 @@ StubInfoSummary StructureStubInfo::summa > StubInfoSummary takesSlowPath = StubInfoSummary::TakesSlowPath; > StubInfoSummary simple = StubInfoSummary::Simple; > if (m_cacheType == CacheType::Stub) { >- PolymorphicAccess* list = m_stub; >+ PolymorphicAccess* list = u.stub; > for (unsigned i = 0; i < list->size(); ++i) { > const AccessCase& access = list->at(i); > if (access.doesCalls(vm)) { >@@ -404,7 +407,7 @@ bool StructureStubInfo::containsPC(void* > { > if (m_cacheType != CacheType::Stub) > return false; >- return m_stub->containsPC(pc); >+ return u.stub->containsPC(pc); > } > > ALWAYS_INLINE void StructureStubInfo::setCacheType(const ConcurrentJSLockerBase&, CacheType newCacheType) >Index: Source/JavaScriptCore/bytecode/StructureStubInfo.h >=================================================================== >--- Source/JavaScriptCore/bytecode/StructureStubInfo.h (revision 286965) >+++ Source/JavaScriptCore/bytecode/StructureStubInfo.h (working copy) >@@ -211,14 +211,6 @@ public: > return considerCaching(vm, codeBlock, structure, impl); > } > >- Structure* inlineAccessBaseStructure(VM&) >- { >- return m_inlineAccessBaseStructureID.get(); >- } >- >- static ptrdiff_t offsetOfByIdSelfOffset() { return OBJECT_OFFSETOF(StructureStubInfo, byIdSelfOffset); } >- static ptrdiff_t offsetOfInlineAccessBaseStructureID() { return OBJECT_OFFSETOF(StructureStubInfo, m_inlineAccessBaseStructureID); } >- > private: > ALWAYS_INLINE bool considerCaching(VM& vm, CodeBlock* codeBlock, Structure* structure, CacheableIdentifier impl) > { >@@ -359,10 +351,19 @@ private: > > public: > CodeOrigin codeOrigin; >- PolymorphicAccess* m_stub { nullptr }; > PropertyOffset byIdSelfOffset; >- WriteBarrierStructureID m_inlineAccessBaseStructureID; >- >+ static ptrdiff_t offsetOfByIdSelfOffset() { return OBJECT_OFFSETOF(StructureStubInfo, byIdSelfOffset); } >+ static ptrdiff_t offsetOfInlineAccessBaseStructure() { return OBJECT_OFFSETOF(StructureStubInfo, m_inlineAccessBaseStructure); } >+ union { >+ PolymorphicAccess* stub; >+ } u; >+ Structure* inlineAccessBaseStructure(VM& vm) >+ { >+ if (!m_inlineAccessBaseStructure) >+ return nullptr; >+ return vm.getStructure(m_inlineAccessBaseStructure); >+ } >+ StructureID m_inlineAccessBaseStructure { 0 }; > private: > CacheableIdentifier m_identifier; > // Represents those structures that already have buffered AccessCases in the PolymorphicAccess. >@@ -421,11 +422,10 @@ public: > uint8_t countdown { 1 }; > uint8_t repatchCount { 0 }; > uint8_t numberOfCoolDowns { 0 }; >- uint8_t bufferingCountdown; >-private: >- Lock m_bufferedStructuresLock; >-public: >+ > CallSiteIndex callSiteIndex; >+ >+ uint8_t bufferingCountdown; > bool resetByGC : 1; > bool tookSlowPath : 1; > bool everConsidered : 1; >@@ -435,6 +435,8 @@ public: > bool propertyIsString : 1; > bool propertyIsInt32 : 1; > bool propertyIsSymbol : 1; >+private: >+ Lock m_bufferedStructuresLock; > }; > > inline CodeOrigin getStructureStubInfoCodeOrigin(StructureStubInfo& structureStubInfo) >Index: Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (working copy) >@@ -2201,7 +2201,7 @@ bool AbstractInterpreter<AbstractStateTy > // And we check the indexing mode of the structure. If the indexing mode is CoW, the butterfly is > // definitely JSImmutableButterfly. > StructureID structureIDEarly = array->structureID(); >- if (structureIDEarly.isNuked()) >+ if (isNuked(structureIDEarly)) > return false; > > if (node->arrayMode().arrayClass() == Array::OriginalCopyOnWriteArray) { >@@ -2215,7 +2215,7 @@ bool AbstractInterpreter<AbstractStateTy > if (structureIDEarly != structureIDLate) > return false; > >- Structure* structure = structureIDLate.decode(); >+ Structure* structure = m_vm.getStructure(structureIDLate); > switch (node->arrayMode().type()) { > case Array::Int32: > case Array::Contiguous: >@@ -2273,7 +2273,7 @@ bool AbstractInterpreter<AbstractStateTy > if (structureIDEarly != structureIDLate) > return false; > >- Structure* structure = structureIDLate.decode(); >+ Structure* structure = m_vm.getStructure(structureIDLate); > if (!hasAnyArrayStorage(structure->indexingMode())) > return false; > >Index: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (working copy) >@@ -5504,7 +5504,7 @@ void ByteCodeParser::parseBlock(unsigned > StructureID cachedStructureID = metadata.m_cachedStructureID; > Structure* cachedStructure = nullptr; > if (cachedStructureID) >- cachedStructure = cachedStructureID.decode(); >+ cachedStructure = m_vm->heap.structureIDTable().get(cachedStructureID); > if (metadata.m_toThisStatus != ToThisOK > || !cachedStructure > || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis >Index: Source/JavaScriptCore/dfg/DFGGraph.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.cpp (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGGraph.cpp (working copy) >@@ -262,7 +262,7 @@ void Graph::dump(PrintStream& out, const > if (node->hasTransition()) { > out.print(comma, pointerDumpInContext(node->transition(), context)); > #if USE(JSVALUE64) >- out.print(", ID:", node->transition()->next->id().bits()); >+ out.print(", ID:", node->transition()->next->id()); > #else > out.print(", ID:", RawPointer(node->transition()->next.get())); > #endif >Index: Source/JavaScriptCore/dfg/DFGJITCompiler.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJITCompiler.h (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGJITCompiler.h (working copy) >@@ -268,7 +268,7 @@ public: > { > Structure* structure = weakStructure.get(); > #if USE(JSVALUE64) >- Jump result = branch32(cond, left, TrustedImm32(structure->id().bits())); >+ Jump result = branch32(cond, left, TrustedImm32(structure->id())); > return result; > #else > return branchPtr(cond, left, TrustedImmPtr(structure)); >Index: Source/JavaScriptCore/dfg/DFGPlan.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.cpp (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGPlan.cpp (working copy) >@@ -564,7 +564,7 @@ CompilationResult Plan::finalize() > for (WriteBarrier<JSCell>& reference : m_codeBlock->jitCode()->dfgCommon()->m_weakReferences) > trackedReferences.add(reference.get()); > for (StructureID structureID : m_codeBlock->jitCode()->dfgCommon()->m_weakStructureReferences) >- trackedReferences.add(structureID.decode()); >+ trackedReferences.add(m_vm->getStructure(structureID)); > for (WriteBarrier<Unknown>& constant : m_codeBlock->constants()) > trackedReferences.add(constant.get()); > >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (working copy) >@@ -244,6 +244,7 @@ void SpeculativeJIT::nonSpeculativeNonPe > } else { > GPRTemporary localGlobalObject(this); > GPRTemporary remoteGlobalObject(this); >+ GPRTemporary scratch(this); > > JITCompiler::Jump notCell; > if (!isKnownCell(operand.node())) >@@ -258,7 +259,7 @@ void SpeculativeJIT::nonSpeculativeNonPe > GPRReg localGlobalObjectGPR = localGlobalObject.gpr(); > GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr(); > m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)), localGlobalObjectGPR); >- m_jit.emitLoadStructure(vm(), argGPR, resultGPR); >+ m_jit.emitLoadStructure(vm(), argGPR, resultGPR, scratch.gpr()); > m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR); > m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultGPR); > done.append(m_jit.jump()); >@@ -298,6 +299,7 @@ void SpeculativeJIT::nonSpeculativePeeph > } else { > GPRTemporary localGlobalObject(this); > GPRTemporary remoteGlobalObject(this); >+ GPRTemporary scratch(this); > > JITCompiler::Jump notCell; > if (!isKnownCell(operand.node())) >@@ -310,7 +312,7 @@ void SpeculativeJIT::nonSpeculativePeeph > GPRReg localGlobalObjectGPR = localGlobalObject.gpr(); > GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr(); > m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)), localGlobalObjectGPR); >- m_jit.emitLoadStructure(vm(), argGPR, resultGPR); >+ m_jit.emitLoadStructure(vm(), argGPR, resultGPR, scratch.gpr()); > m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR); > branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, taken); > >@@ -1903,6 +1905,8 @@ void SpeculativeJIT::compileToBooleanObj > GPRReg resultGPR = result.gpr(); > GPRTemporary structure; > GPRReg structureGPR = InvalidGPRReg; >+ GPRTemporary scratch; >+ GPRReg scratchGPR = InvalidGPRReg; > > bool masqueradesAsUndefinedWatchpointValid = > masqueradesAsUndefinedWatchpointIsStillValid(); >@@ -1911,8 +1915,11 @@ void SpeculativeJIT::compileToBooleanObj > // The masquerades as undefined case will use the structure register, so allocate it here. > // Do this at the top of the function to avoid branching around a register allocation. > GPRTemporary realStructure(this); >+ GPRTemporary realScratch(this); > structure.adopt(realStructure); >+ scratch.adopt(realScratch); > structureGPR = structure.gpr(); >+ scratchGPR = scratch.gpr(); > } > > MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR)); >@@ -1929,7 +1936,7 @@ void SpeculativeJIT::compileToBooleanObj > MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), > MacroAssembler::TrustedImm32(MasqueradesAsUndefined)); > >- m_jit.emitLoadStructure(vm(), valueGPR, structureGPR); >+ m_jit.emitLoadStructure(vm(), valueGPR, structureGPR, scratchGPR); > speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, > m_jit.branchPtr( > MacroAssembler::Equal, >@@ -2084,7 +2091,7 @@ void SpeculativeJIT::emitObjectOrOtherBr > MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), > TrustedImm32(MasqueradesAsUndefined)); > >- m_jit.emitLoadStructure(vm(), valueGPR, structureGPR); >+ m_jit.emitLoadStructure(vm(), valueGPR, structureGPR, scratchGPR); > speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, > m_jit.branchPtr( > MacroAssembler::Equal, >@@ -2178,7 +2185,7 @@ void SpeculativeJIT::emitUntypedBranch(E > bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid(); > if (shouldCheckMasqueradesAsUndefined) { > branchTest8(MacroAssembler::Zero, MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), taken); >- m_jit.emitLoadStructure(vm(), valueGPR, temp1GPR); >+ m_jit.emitLoadStructure(vm(), valueGPR, temp1GPR, temp2GPR); > JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(m_currentNode->origin.semantic); > m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), temp2GPR); > branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp1GPR, Structure::globalObjectOffset()), temp2GPR, taken); >@@ -4440,7 +4447,7 @@ void SpeculativeJIT::compile(Node* node) > ASSERT_UNUSED(oldStructure, oldStructure->indexingMode() == newStructure->indexingMode()); > ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type()); > ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags()); >- m_jit.store32(MacroAssembler::TrustedImm32(newStructure->id().bits()), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset())); >+ m_jit.store32(MacroAssembler::TrustedImm32(newStructure->id()), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset())); > > noResult(node); > break; >@@ -4659,6 +4666,7 @@ void SpeculativeJIT::compile(Node* node) > GPRTemporary result(this); > GPRTemporary localGlobalObject(this); > GPRTemporary remoteGlobalObject(this); >+ GPRTemporary scratch(this); > > JITCompiler::Jump isCell = m_jit.branchIfCell(value.jsValueRegs()); > >@@ -4682,7 +4690,7 @@ void SpeculativeJIT::compile(Node* node) > GPRReg localGlobalObjectGPR = localGlobalObject.gpr(); > GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr(); > m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.globalObjectFor(node->origin.semantic)), localGlobalObjectGPR); >- m_jit.emitLoadStructure(vm(), value.gpr(), result.gpr()); >+ m_jit.emitLoadStructure(vm(), value.gpr(), result.gpr(), scratch.gpr()); > m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR); > m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr()); > } >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (revision 286965) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (working copy) >@@ -8533,7 +8533,8 @@ void SpeculativeJIT::compileGetGlobalObj > { > SpeculateCellOperand object(this, node->child1()); > GPRTemporary result(this); >- m_jit.emitLoadStructure(vm(), object.gpr(), result.gpr()); >+ GPRTemporary scratch(this); >+ m_jit.emitLoadStructure(vm(), object.gpr(), result.gpr(), scratch.gpr()); > m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), result.gpr()); > cellResult(result.gpr(), node); > } >@@ -11041,7 +11042,7 @@ void SpeculativeJIT::compileCheckJSCast( > GPRReg otherGPR = other.gpr(); > GPRReg specifiedGPR = specified.gpr(); > >- m_jit.emitLoadStructure(vm(), baseGPR, otherGPR); >+ m_jit.emitLoadStructure(vm(), baseGPR, otherGPR, specifiedGPR); > m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR); > m_jit.move(CCallHelpers::TrustedImmPtr(node->classInfo()), specifiedGPR); > >@@ -11252,7 +11253,7 @@ void SpeculativeJIT::compileFunctionToSt > > speculateFunction(node->child1(), function.gpr()); > >- m_jit.emitLoadStructure(vm(), function.gpr(), result.gpr()); >+ m_jit.emitLoadStructure(vm(), function.gpr(), result.gpr(), executable.gpr()); > m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::classInfoOffset()), result.gpr()); > static_assert(std::is_final_v<JSBoundFunction>, "We don't handle subclasses when comparing classInfo below"); > slowCases.append(m_jit.branchPtr(CCallHelpers::Equal, result.gpr(), TrustedImmPtr(JSBoundFunction::info()))); >@@ -14267,11 +14268,13 @@ void SpeculativeJIT::compileGetPropertyE > if (node->child1().useKind() == CellUse || node->child1().useKind() == CellOrOtherUse) { > JSValueOperand base(this, node->child1(), ManualOperandSpeculation); > GPRTemporary scratch1(this); >+ GPRTemporary scratch2(this); > > speculate(node, node->child1()); > > JSValueRegs baseRegs = base.jsValueRegs(); > GPRReg scratch1GPR = scratch1.gpr(); >+ GPRReg scratch2GPR = scratch2.gpr(); > > CCallHelpers::JumpList slowCases; > CCallHelpers::JumpList doneCases; >@@ -14323,7 +14326,7 @@ void SpeculativeJIT::compileGetPropertyE > if (onlyStructure) > m_jit.move(TrustedImmPtr(onlyStructure), scratch1GPR); > else >- m_jit.emitLoadStructure(vm(), baseRegs.payloadGPR(), scratch1GPR); >+ m_jit.emitLoadStructure(vm(), baseRegs.payloadGPR(), scratch1GPR, scratch2GPR); > m_jit.loadPtr(CCallHelpers::Address(scratch1GPR, Structure::previousOrRareDataOffset()), scratch1GPR); > slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratch1GPR)); > slowCases.append(m_jit.branchIfStructure(scratch1GPR)); >@@ -14335,7 +14338,7 @@ void SpeculativeJIT::compileGetPropertyE > doneCases.append(m_jit.jump()); > > slowCases.link(&m_jit); >- silentSpillAllRegisters(scratch1GPR); >+ silentSpillAllRegisters(scratch1GPR, scratch2GPR); > callOperation(operationGetPropertyEnumeratorCell, scratch1GPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseRegs.payloadGPR()); > silentFillAllRegisters(); > m_jit.exceptionCheck(); >@@ -14602,7 +14605,7 @@ void SpeculativeJIT::compileObjectKeysOr > speculateObject(node->child1(), objectGPR); > > CCallHelpers::JumpList slowCases; >- m_jit.emitLoadStructure(vm(), objectGPR, structureGPR); >+ m_jit.emitLoadStructure(vm(), objectGPR, structureGPR, scratchGPR); > m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::previousOrRareDataOffset()), scratchGPR); > > slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratchGPR)); >@@ -14819,9 +14822,8 @@ void SpeculativeJIT::compileCreatePromis > slowCases.append(m_jit.branchIfNotFunction(calleeGPR)); > m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfExecutableOrRareData()), rareDataGPR); > slowCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR, CCallHelpers::TrustedImm32(JSFunction::rareDataTag))); >- m_jit.load32(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructureID() - JSFunction::rareDataTag), structureGPR); >- slowCases.append(m_jit.branchTest32(CCallHelpers::Zero, structureGPR)); >- m_jit.emitNonNullDecodeStructureID(structureGPR, structureGPR); >+ m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure() - JSFunction::rareDataTag), structureGPR); >+ slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR)); > m_jit.move(TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info()), scratch1GPR); > slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset()))); > m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR); >@@ -14868,9 +14870,8 @@ void SpeculativeJIT::compileCreateIntern > slowCases.append(m_jit.branchIfNotFunction(calleeGPR)); > m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfExecutableOrRareData()), rareDataGPR); > slowCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR, CCallHelpers::TrustedImm32(JSFunction::rareDataTag))); >- m_jit.load32(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructureID() - JSFunction::rareDataTag), structureGPR); >- slowCases.append(m_jit.branchTest32(CCallHelpers::Zero, structureGPR)); >- m_jit.emitNonNullDecodeStructureID(structureGPR, structureGPR); >+ m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure() - JSFunction::rareDataTag), structureGPR); >+ slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR)); > m_jit.move(TrustedImmPtr(JSClass::info()), scratch1GPR); > slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset()))); > m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR); >@@ -15331,14 +15332,15 @@ void SpeculativeJIT::compileWeakMapSet(N > void SpeculativeJIT::compileGetPrototypeOf(Node* node) > { > GPRTemporary temp(this); >+ GPRTemporary temp2(this); > > GPRReg tempGPR = temp.gpr(); >+ GPRReg temp2GPR = temp2.gpr(); > > #if USE(JSVALUE64) > JSValueRegs resultRegs(tempGPR); > #else >- GPRTemporary temp2(this); >- JSValueRegs resultRegs(temp2.gpr(), tempGPR); >+ JSValueRegs resultRegs(temp2GPR, tempGPR); > #endif > > switch (node->child1().useKind()) { >@@ -15363,7 +15365,7 @@ void SpeculativeJIT::compileGetPrototype > break; > } > >- m_jit.emitLoadStructure(vm(), objectGPR, tempGPR); >+ m_jit.emitLoadStructure(vm(), objectGPR, tempGPR, temp2GPR); > > AbstractValue& value = m_state.forNode(node->child1()); > if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) { >@@ -15402,7 +15404,7 @@ void SpeculativeJIT::compileGetPrototype > speculateObject(node->child1(), objectGPR); > > JITCompiler::JumpList slowCases; >- m_jit.emitLoadPrototype(vm(), objectGPR, resultRegs, slowCases); >+ m_jit.emitLoadPrototype(vm(), objectGPR, resultRegs, temp2GPR, slowCases); > addSlowPathGenerator(slowPathCall(slowCases, this, operationGetPrototypeOfObject, > resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectGPR)); > >@@ -15419,7 +15421,7 @@ void SpeculativeJIT::compileGetPrototype > GPRReg valueGPR = valueRegs.payloadGPR(); > slowCases.append(m_jit.branchIfNotObject(valueGPR)); > >- m_jit.emitLoadPrototype(vm(), valueGPR, resultRegs, slowCases); >+ m_jit.emitLoadPrototype(vm(), valueGPR, resultRegs, temp2GPR, slowCases); > addSlowPathGenerator(slowPathCall(slowCases, this, operationGetPrototypeOf, > resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), valueRegs)); > >Index: Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (revision 286965) >+++ Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (working copy) >@@ -84,7 +84,9 @@ namespace JSC { namespace FTL { > macro(FunctionRareData_prototype, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfileWithPrototype::offsetOfPrototype()) \ > macro(FunctionRareData_allocationProfileWatchpointSet, FunctionRareData::offsetOfAllocationProfileWatchpointSet()) \ > macro(FunctionRareData_executable, FunctionRareData::offsetOfExecutable()) \ >- macro(FunctionRareData_internalFunctionAllocationProfile_structureID, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructureID()) \ >+ macro(FunctionRareData_internalFunctionAllocationProfile_structure, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure()) \ >+ macro(FunctionRareData_boundFunctionStructure, FunctionRareData::offsetOfBoundFunctionStructure()) \ >+ macro(FunctionRareData_allocationProfileClearingWatchpoint, FunctionRareData::offsetOfAllocationProfileClearingWatchpoint()) \ > macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \ > macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \ > macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \ >Index: Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (revision 286965) >+++ Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (working copy) >@@ -7877,11 +7877,10 @@ IGNORE_CLANG_WARNINGS_END > > m_out.appendTo(hasRareData, hasStructure); > LValue rareData = m_out.sub(rareDataTags, m_out.constIntPtr(JSFunction::rareDataTag)); >- LValue structureID = m_out.load32(rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structureID); >- m_out.branch(m_out.isZero32(structureID), rarely(slowCase), usually(hasStructure)); >+ LValue structure = m_out.loadPtr(rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structure); >+ m_out.branch(m_out.isZero64(structure), rarely(slowCase), usually(hasStructure)); > > m_out.appendTo(hasStructure, checkGlobalObjectCase); >- LValue structure = decodeNonNullStructure(structureID); > 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)); > > m_out.appendTo(checkGlobalObjectCase, fastAllocationCase); >@@ -7933,11 +7932,10 @@ IGNORE_CLANG_WARNINGS_END > > m_out.appendTo(hasRareData, hasStructure); > LValue rareData = m_out.sub(rareDataTags, m_out.constIntPtr(JSFunction::rareDataTag)); >- LValue structureID = m_out.load32(rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structureID); >- m_out.branch(m_out.isZero32(structureID), rarely(slowCase), usually(hasStructure)); >+ LValue structure = m_out.loadPtr(rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structure); >+ m_out.branch(m_out.isZero64(structure), rarely(slowCase), usually(hasStructure)); > > m_out.appendTo(hasStructure, checkGlobalObjectCase); >- LValue structure = decodeNonNullStructure(structureID); > m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(JSClass::info())), usually(checkGlobalObjectCase), rarely(slowCase)); > > m_out.appendTo(checkGlobalObjectCase, fastAllocationCase); >@@ -13712,7 +13710,7 @@ IGNORE_CLANG_WARNINGS_END > LValue structureID; > auto structure = m_state.forNode(baseEdge.node()).m_structure.onlyStructure(); > if (structure) >- structureID = m_out.constInt32(structure->id().bits()); >+ structureID = m_out.constInt32(structure->id()); > else > structureID = m_out.load32(base, m_heaps.JSCell_structureID); > >@@ -16791,7 +16789,7 @@ IGNORE_CLANG_WARNINGS_END > > void storeStructure(LValue object, Structure* structure) > { >- m_out.store32(m_out.constInt32(structure->id().bits()), object, m_heaps.JSCell_structureID); >+ m_out.store32(m_out.constInt32(structure->id()), object, m_heaps.JSCell_structureID); > m_out.store32( > m_out.constInt32(structure->objectInitializationBlob()), > object, m_heaps.JSCell_usefulBytes); >@@ -19572,7 +19570,7 @@ IGNORE_CLANG_WARNINGS_END > return proven; > return m_out.notEqual( > m_out.load32(cell, m_heaps.JSCell_structureID), >- m_out.constInt32(vm().stringStructure->id().bits())); >+ m_out.constInt32(vm().stringStructure->id())); > } > > LValue isString(LValue cell, SpeculatedType type = SpecFullTop) >@@ -19581,7 +19579,7 @@ IGNORE_CLANG_WARNINGS_END > return proven; > return m_out.equal( > m_out.load32(cell, m_heaps.JSCell_structureID), >- m_out.constInt32(vm().stringStructure->id().bits())); >+ m_out.constInt32(vm().stringStructure->id())); > } > > LValue isRopeString(LValue string, Edge edge = Edge()) >@@ -19628,7 +19626,7 @@ IGNORE_CLANG_WARNINGS_END > return proven; > return m_out.notEqual( > m_out.load32(cell, m_heaps.JSCell_structureID), >- m_out.constInt32(vm().symbolStructure->id().bits())); >+ m_out.constInt32(vm().symbolStructure->id())); > } > > LValue isSymbol(LValue cell, SpeculatedType type = SpecFullTop) >@@ -19637,7 +19635,7 @@ IGNORE_CLANG_WARNINGS_END > return proven; > return m_out.equal( > m_out.load32(cell, m_heaps.JSCell_structureID), >- m_out.constInt32(vm().symbolStructure->id().bits())); >+ m_out.constInt32(vm().symbolStructure->id())); > } > > LValue isNotHeapBigIntUnknownWhetherCell(LValue value, SpeculatedType type = SpecFullTop) >@@ -19666,7 +19664,7 @@ IGNORE_CLANG_WARNINGS_END > return proven; > return m_out.notEqual( > m_out.load32(cell, m_heaps.JSCell_structureID), >- m_out.constInt32(vm().bigIntStructure->id().bits())); >+ m_out.constInt32(vm().bigIntStructure->id())); > } > > LValue isHeapBigInt(LValue cell, SpeculatedType type = SpecFullTop) >@@ -19675,7 +19673,7 @@ IGNORE_CLANG_WARNINGS_END > return proven; > return m_out.equal( > m_out.load32(cell, m_heaps.JSCell_structureID), >- m_out.constInt32(vm().bigIntStructure->id().bits())); >+ m_out.constInt32(vm().bigIntStructure->id())); > } > > LValue isArrayTypeForArrayify(LValue cell, ArrayMode arrayMode) >@@ -20402,7 +20400,7 @@ IGNORE_CLANG_WARNINGS_END > m_out.store32( > m_out.bitOr( > m_out.load32(object, m_heaps.JSCell_structureID), >- m_out.constInt32(StructureID::nukedStructureIDBit)), >+ m_out.constInt32(nukedStructureIDBit())), > object, m_heaps.JSCell_structureID); > m_out.fence(&m_heaps.root, nullptr); > m_out.storePtr(butterfly, object, m_heaps.JSObject_butterfly); >@@ -20430,7 +20428,7 @@ IGNORE_CLANG_WARNINGS_END > m_out.store32( > m_out.bitOr( > m_out.load32(object, m_heaps.JSCell_structureID), >- m_out.constInt32(StructureID::nukedStructureIDBit)), >+ m_out.constInt32(nukedStructureIDBit())), > object, m_heaps.JSCell_structureID); > m_out.fence(&m_heaps.root, nullptr); > m_out.storePtr(butterfly, object, m_heaps.JSObject_butterfly); >@@ -20975,16 +20973,15 @@ IGNORE_CLANG_WARNINGS_END > m_graph.m_plan.weakReferences().addLazily(target); > } > >- LValue decodeNonNullStructure(LValue structureID) >- { >- LValue maskedStructureID = m_out.bitAnd(structureID, m_out.constInt32(structureIDMask)); >- return m_out.add(m_out.constIntPtr(g_jscConfig.startOfStructureHeap), m_out.zeroExtPtr(maskedStructureID)); >- } >- > LValue loadStructure(LValue value) > { > LValue structureID = m_out.load32(value, m_heaps.JSCell_structureID); >- return decodeNonNullStructure(structureID); >+ LValue tableBase = m_out.loadPtr(m_out.absolute(vm().heap.structureIDTable().base())); >+ LValue tableIndex = m_out.aShr(structureID, m_out.constInt32(StructureIDTable::s_numberOfEntropyBits)); >+ LValue entropyBits = m_out.shl(m_out.zeroExtPtr(structureID), m_out.constInt32(StructureIDTable::s_entropyBitsShiftForStructurePointer)); >+ TypedPointer address = m_out.baseIndex(m_heaps.structureTable, tableBase, m_out.zeroExtPtr(tableIndex)); >+ LValue encodedStructureBits = m_out.loadPtr(address); >+ return m_out.bitXor(encodedStructureBits, entropyBits); > } > > LValue weakPointer(JSCell* pointer) >@@ -21000,7 +20997,7 @@ IGNORE_CLANG_WARNINGS_END > > LValue weakStructureID(RegisteredStructure structure) > { >- return m_out.constInt32(structure->id().bits()); >+ return m_out.constInt32(structure->id()); > } > > LValue weakStructure(RegisteredStructure structure) >Index: Source/JavaScriptCore/heap/AbstractSlotVisitor.h >=================================================================== >--- Source/JavaScriptCore/heap/AbstractSlotVisitor.h (revision 286965) >+++ Source/JavaScriptCore/heap/AbstractSlotVisitor.h (working copy) >@@ -48,7 +48,6 @@ class VM; > class VerifierSlotVisitor; > template<typename T> class Weak; > template<typename T, typename Traits> class WriteBarrierBase; >-class WriteBarrierStructureID; > > class AbstractSlotVisitor { > WTF_MAKE_NONCOPYABLE(AbstractSlotVisitor); >@@ -144,8 +143,6 @@ public: > > template<typename T, typename Traits> void append(const WriteBarrierBase<T, Traits>&); > template<typename T, typename Traits> void appendHidden(const WriteBarrierBase<T, Traits>&); >- void append(const WriteBarrierStructureID&); >- void appendHidden(const WriteBarrierStructureID&); > template<typename Iterator> void append(Iterator begin , Iterator end); > ALWAYS_INLINE void appendValues(const WriteBarrierBase<Unknown, RawValueTraits<Unknown>>*, size_t count); > ALWAYS_INLINE void appendValuesHidden(const WriteBarrierBase<Unknown, RawValueTraits<Unknown>>*, size_t count); >Index: Source/JavaScriptCore/heap/AbstractSlotVisitorInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/AbstractSlotVisitorInlines.h (revision 286965) >+++ Source/JavaScriptCore/heap/AbstractSlotVisitorInlines.h (working copy) >@@ -158,16 +158,6 @@ ALWAYS_INLINE void AbstractSlotVisitor:: > appendHiddenUnbarriered(slot.get()); > } > >-ALWAYS_INLINE void AbstractSlotVisitor::append(const WriteBarrierStructureID& slot) >-{ >- appendUnbarriered(reinterpret_cast<JSCell*>(slot.get())); >-} >- >-ALWAYS_INLINE void AbstractSlotVisitor::appendHidden(const WriteBarrierStructureID& slot) >-{ >- appendHiddenUnbarriered(reinterpret_cast<JSCell*>(slot.get())); >-} >- > ALWAYS_INLINE void AbstractSlotVisitor::appendHiddenUnbarriered(JSValue value) > { > if (value.isCell()) >Index: Source/JavaScriptCore/heap/Heap.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Heap.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/Heap.cpp (working copy) >@@ -67,7 +67,6 @@ > #include "SpaceTimeMutatorScheduler.h" > #include "StochasticSpaceTimeMutatorScheduler.h" > #include "StopIfNecessaryTimer.h" >-#include "StructureAlignedMemoryAllocator.h" > #include "SubspaceInlines.h" > #include "SuperSampler.h" > #include "SweepingScope.h" >@@ -389,8 +388,8 @@ Heap::Heap(VM& vm, HeapType heapType) > , stringObjectSpace ISO_SUBSPACE_INIT(*this, cellHeapCellType, StringObject) > , structureChainSpace ISO_SUBSPACE_INIT(*this, cellHeapCellType, StructureChain) > , structureRareDataSpace ISO_SUBSPACE_INIT(*this, destructibleCellHeapCellType, StructureRareData) // Hash:0xaca4e62d >- , structureSpace("IsolatedStructureSpace", *this, destructibleCellHeapCellType, sizeof(Structure), Structure::numberOfLowerTierCells, makeUnique<StructureAlignedMemoryAllocator>("Structure")) >- , brandedStructureSpace("IsolatedBrandedStructureSpace", *this, destructibleCellHeapCellType, sizeof(BrandedStructure), BrandedStructure::numberOfLowerTierCells, makeUnique<StructureAlignedMemoryAllocator>("Structure")) >+ , structureSpace ISO_SUBSPACE_INIT(*this, destructibleCellHeapCellType, Structure) >+ , brandedStructureSpace ISO_SUBSPACE_INIT(*this, destructibleCellHeapCellType, BrandedStructure) > , symbolTableSpace ISO_SUBSPACE_INIT(*this, destructibleCellHeapCellType, SymbolTable) // Hash:0xc5215afd > , executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace) > , executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace) >@@ -1606,6 +1605,8 @@ NEVER_INLINE bool Heap::runEndPhase(GCCo > if (vm().typeProfiler()) > vm().typeProfiler()->invalidateTypeSetCache(vm()); > >+ m_structureIDTable.flushOldTables(); >+ > reapWeakHandles(); > pruneStaleEntriesFromWeakGCHashTables(); > sweepArrayBuffers(); >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 286965) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -43,7 +43,7 @@ > #include "MarkedSpace.h" > #include "MutatorState.h" > #include "Options.h" >-#include "StructureID.h" >+#include "StructureIDTable.h" > #include "Synchronousness.h" > #include "WeakHandleOwner.h" > #include <wtf/AutomaticThread.h> >@@ -275,6 +275,8 @@ public: > > bool isDeferred() const { return !!m_deferralDepth; } > >+ StructureIDTable& structureIDTable() { return m_structureIDTable; } >+ > CodeBlockSet& codeBlockSet() { return *m_codeBlocks; } > > #if USE(FOUNDATION) >@@ -594,6 +596,7 @@ private: > Markable<CollectionScope, EnumMarkableTraits<CollectionScope>> m_lastCollectionScope; > Lock m_raceMarkStackLock; > >+ StructureIDTable m_structureIDTable; > MarkedSpace m_objectSpace; > GCIncomingRefCountedSet<ArrayBuffer> m_arrayBuffers; > size_t m_extraMemorySize { 0 }; >Index: Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >=================================================================== >--- Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp (working copy) >@@ -30,13 +30,72 @@ > namespace JSC { > > IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator(CString name) >- : Base(name) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ : m_debugHeap(name.data()) >+#endif > { >+ UNUSED_PARAM(name); > } > > IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator() > { >- releaseMemoryFromSubclassDestructor(); >+#if !ENABLE(MALLOC_HEAP_BREAKDOWN) >+ for (unsigned i = 0; i < m_blocks.size(); ++i) { >+ void* block = m_blocks[i]; >+ if (!m_committed.quickGet(i)) >+ WTF::fastCommitAlignedMemory(block, MarkedBlock::blockSize); >+ fastAlignedFree(block); >+ } >+#endif >+} >+ >+void* IsoAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size_t size) >+{ >+ // Since this is designed specially for IsoSubspace, we know that we will only be asked to >+ // allocate MarkedBlocks. >+ RELEASE_ASSERT(alignment == MarkedBlock::blockSize); >+ RELEASE_ASSERT(size == MarkedBlock::blockSize); >+ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ return m_debugHeap.memalign(MarkedBlock::blockSize, MarkedBlock::blockSize, true); >+#else >+ Locker locker { m_lock }; >+ >+ m_firstUncommitted = m_committed.findBit(m_firstUncommitted, false); >+ if (m_firstUncommitted < m_blocks.size()) { >+ m_committed.quickSet(m_firstUncommitted); >+ void* result = m_blocks[m_firstUncommitted]; >+ WTF::fastCommitAlignedMemory(result, MarkedBlock::blockSize); >+ return result; >+ } >+ >+ void* result = tryFastAlignedMalloc(MarkedBlock::blockSize, MarkedBlock::blockSize); >+ if (!result) >+ return nullptr; >+ unsigned index = m_blocks.size(); >+ m_blocks.append(result); >+ m_blockIndices.add(result, index); >+ if (m_blocks.capacity() != m_committed.size()) >+ m_committed.resize(m_blocks.capacity()); >+ m_committed.quickSet(index); >+ return result; >+#endif >+} >+ >+void IsoAlignedMemoryAllocator::freeAlignedMemory(void* basePtr) >+{ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ m_debugHeap.free(basePtr); >+#else >+ Locker locker { m_lock }; >+ >+ auto iter = m_blockIndices.find(basePtr); >+ RELEASE_ASSERT(iter != m_blockIndices.end()); >+ unsigned index = iter->value; >+ m_committed.quickClear(index); >+ m_firstUncommitted = std::min(index, m_firstUncommitted); >+ WTF::fastDecommitAlignedMemory(basePtr, MarkedBlock::blockSize); >+#endif > } > > void IsoAlignedMemoryAllocator::dump(PrintStream& out) const >@@ -68,25 +127,5 @@ void* IsoAlignedMemoryAllocator::tryReal > RELEASE_ASSERT_NOT_REACHED(); > } > >-void* IsoAlignedMemoryAllocator::tryMallocBlock() >-{ >- return tryFastAlignedMalloc(MarkedBlock::blockSize, MarkedBlock::blockSize); >-} >- >-void IsoAlignedMemoryAllocator::freeBlock(void* block) >-{ >- fastAlignedFree(block); >-} >- >-void IsoAlignedMemoryAllocator::commitBlock(void* block) >-{ >- WTF::fastCommitAlignedMemory(block, MarkedBlock::blockSize); >-} >- >-void IsoAlignedMemoryAllocator::decommitBlock(void* block) >-{ >- WTF::fastDecommitAlignedMemory(block, MarkedBlock::blockSize); >-} >- > } // namespace JSC > >Index: Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h (revision 286965) >+++ Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h (working copy) >@@ -25,7 +25,7 @@ > > #pragma once > >-#include "IsoMemoryAllocatorBase.h" >+#include "AlignedMemoryAllocator.h" > #include <wtf/BitVector.h> > #include <wtf/DebugHeap.h> > #include <wtf/HashMap.h> >@@ -34,24 +34,31 @@ > > namespace JSC { > >-class IsoAlignedMemoryAllocator final : public IsoMemoryAllocatorBase { >+class IsoAlignedMemoryAllocator final : public AlignedMemoryAllocator { > public: >- using Base = IsoMemoryAllocatorBase; >- > IsoAlignedMemoryAllocator(CString); > ~IsoAlignedMemoryAllocator() final; > >+ void* tryAllocateAlignedMemory(size_t alignment, size_t size) final; >+ void freeAlignedMemory(void*) final; >+ > void dump(PrintStream&) const final; > > void* tryAllocateMemory(size_t) final; > void freeMemory(void*) final; > void* tryReallocateMemory(void*, size_t) final; > >-protected: >- void* tryMallocBlock() final; >- void freeBlock(void* block) final; >- void commitBlock(void* block) final; >- void decommitBlock(void* block) final; >+private: >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ // If breakdown is enabled, we do not ensure Iso-feature. This is totally OK since breakdown is memory bloat debugging feature. >+ WTF::DebugHeap m_debugHeap; >+#else >+ Vector<void*> m_blocks; >+ HashMap<void*, unsigned> m_blockIndices; >+ BitVector m_committed; >+ unsigned m_firstUncommitted { 0 }; >+ Lock m_lock; >+#endif > }; > > } // namespace JSC >Index: Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.cpp >=================================================================== >--- Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.cpp (nonexistent) >@@ -1,108 +0,0 @@ >-/* >- * Copyright (C) 2017-2021 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "IsoMemoryAllocatorBase.h" >- >-#include "MarkedBlock.h" >- >-namespace JSC { >- >-IsoMemoryAllocatorBase::IsoMemoryAllocatorBase(CString name) >-#if ENABLE(MALLOC_HEAP_BREAKDOWN) >- : m_debugHeap(name.data()) >-#endif >-{ >- UNUSED_PARAM(name); >-} >- >-IsoMemoryAllocatorBase::~IsoMemoryAllocatorBase() >-{ >-} >- >-// We need to call this from the derived class's destructor because it's undefined behavior to call pure virtual methods from within a destructor. >-void IsoMemoryAllocatorBase::releaseMemoryFromSubclassDestructor() >-{ >-#if !ENABLE(MALLOC_HEAP_BREAKDOWN) >- for (unsigned i = 0; i < m_blocks.size(); ++i) { >- void* block = m_blocks[i]; >- if (!m_committed.quickGet(i)) >- commitBlock(block); >- freeBlock(block); >- } >-#endif >-} >- >-void* IsoMemoryAllocatorBase::tryAllocateAlignedMemory(size_t alignment, size_t size) >-{ >- // Since this is designed specially for IsoSubspace, we know that we will only be asked to >- // allocate MarkedBlocks. >- RELEASE_ASSERT(alignment == MarkedBlock::blockSize); >- RELEASE_ASSERT(size == MarkedBlock::blockSize); >- >-#if ENABLE(MALLOC_HEAP_BREAKDOWN) >- return m_debugHeap.memalign(MarkedBlock::blockSize, MarkedBlock::blockSize, true); >-#else >- Locker locker { m_lock }; >- >- m_firstUncommitted = m_committed.findBit(m_firstUncommitted, false); >- if (m_firstUncommitted < m_blocks.size()) { >- m_committed.quickSet(m_firstUncommitted); >- void* result = m_blocks[m_firstUncommitted]; >- commitBlock(result); >- return result; >- } >- >- void* result = tryMallocBlock(); >- if (!result) >- return nullptr; >- unsigned index = m_blocks.size(); >- m_blocks.append(result); >- m_blockIndices.add(result, index); >- if (m_blocks.capacity() != m_committed.size()) >- m_committed.resize(m_blocks.capacity()); >- m_committed.quickSet(index); >- return result; >-#endif >-} >- >-void IsoMemoryAllocatorBase::freeAlignedMemory(void* basePtr) >-{ >-#if ENABLE(MALLOC_HEAP_BREAKDOWN) >- m_debugHeap.free(basePtr); >-#else >- Locker locker { m_lock }; >- >- auto iter = m_blockIndices.find(basePtr); >- RELEASE_ASSERT(iter != m_blockIndices.end()); >- unsigned index = iter->value; >- m_committed.quickClear(index); >- m_firstUncommitted = std::min(index, m_firstUncommitted); >- decommitBlock(basePtr); >-#endif >-} >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.h (revision 286965) >+++ Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.h (nonexistent) >@@ -1,67 +0,0 @@ >-/* >- * Copyright (C) 2017-2021 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "AlignedMemoryAllocator.h" >-#include <wtf/BitVector.h> >-#include <wtf/DebugHeap.h> >-#include <wtf/HashMap.h> >-#include <wtf/Vector.h> >- >- >-namespace JSC { >- >-class IsoMemoryAllocatorBase : public AlignedMemoryAllocator { >-public: >- IsoMemoryAllocatorBase(CString); >- ~IsoMemoryAllocatorBase() override; >- >- void* tryAllocateAlignedMemory(size_t alignment, size_t size) final; >- void freeAlignedMemory(void*) final; >- >-protected: >- void releaseMemoryFromSubclassDestructor(); >- virtual void* tryMallocBlock() = 0; >- virtual void freeBlock(void* block) = 0; >- virtual void commitBlock(void* block) = 0; >- virtual void decommitBlock(void* block) = 0; >- >-#if ENABLE(MALLOC_HEAP_BREAKDOWN) >-protected: >- // If breakdown is enabled, we do not ensure Iso-feature. This is totally OK since breakdown is memory bloat debugging feature. >- WTF::DebugHeap m_debugHeap; >-#else >-private: >- Vector<void*> m_blocks; >- HashMap<void*, unsigned> m_blockIndices; >- BitVector m_committed; >- unsigned m_firstUncommitted { 0 }; >- Lock m_lock; >-#endif >-}; >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/IsoSubspace.cpp >=================================================================== >--- Source/JavaScriptCore/heap/IsoSubspace.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/IsoSubspace.cpp (working copy) >@@ -33,11 +33,11 @@ > > namespace JSC { > >-IsoSubspace::IsoSubspace(CString name, Heap& heap, const HeapCellType& heapCellType, size_t size, uint8_t numberOfLowerTierCells, std::unique_ptr<IsoMemoryAllocatorBase>&& allocator) >+IsoSubspace::IsoSubspace(CString name, Heap& heap, const HeapCellType& heapCellType, size_t size, uint8_t numberOfLowerTierCells) > : Subspace(name, heap) > , m_directory(WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size)) > , m_localAllocator(&m_directory) >- , m_isoAlignedMemoryAllocator(allocator ? WTFMove(allocator) : makeUnique<IsoAlignedMemoryAllocator>(name)) >+ , m_isoAlignedMemoryAllocator(makeUnique<IsoAlignedMemoryAllocator>(name)) > { > m_remainingLowerTierCellCount = numberOfLowerTierCells; > ASSERT(WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size) == cellSize()); >@@ -99,9 +99,8 @@ void* IsoSubspace::tryAllocateFromLowerT > return revive(allocation); > } > if (m_remainingLowerTierCellCount) { >- PreciseAllocation* allocation = PreciseAllocation::tryCreateForLowerTier(m_space.heap(), cellSize(), this, --m_remainingLowerTierCellCount); >- if (allocation) >- return revive(allocation); >+ PreciseAllocation* allocation = PreciseAllocation::createForLowerTier(m_space.heap(), cellSize(), this, --m_remainingLowerTierCellCount); >+ return revive(allocation); > } > return nullptr; > } >Index: Source/JavaScriptCore/heap/IsoSubspace.h >=================================================================== >--- Source/JavaScriptCore/heap/IsoSubspace.h (revision 286965) >+++ Source/JavaScriptCore/heap/IsoSubspace.h (working copy) >@@ -26,18 +26,18 @@ > #pragma once > > #include "BlockDirectory.h" >-#include "IsoMemoryAllocatorBase.h" > #include "Subspace.h" > #include "SubspaceAccess.h" > #include <wtf/SinglyLinkedListWithTail.h> > > namespace JSC { > >+class IsoAlignedMemoryAllocator; > class IsoCellSet; > > class IsoSubspace : public Subspace { > public: >- JS_EXPORT_PRIVATE IsoSubspace(CString name, Heap&, const HeapCellType&, size_t size, uint8_t numberOfLowerTierCells, std::unique_ptr<IsoMemoryAllocatorBase>&& = nullptr); >+ JS_EXPORT_PRIVATE IsoSubspace(CString name, Heap&, const HeapCellType&, size_t, uint8_t numberOfLowerTierCells); > JS_EXPORT_PRIVATE ~IsoSubspace() override; > > size_t cellSize() { return m_directory.cellSize(); } >@@ -65,7 +65,7 @@ private: > > BlockDirectory m_directory; > LocalAllocator m_localAllocator; >- std::unique_ptr<IsoMemoryAllocatorBase> m_isoAlignedMemoryAllocator; >+ std::unique_ptr<IsoAlignedMemoryAllocator> m_isoAlignedMemoryAllocator; > SentinelLinkedList<PreciseAllocation, PackedRawSentinelNode<PreciseAllocation>> m_lowerTierFreeList; > SentinelLinkedList<IsoCellSet, PackedRawSentinelNode<IsoCellSet>> m_cellSets; > }; >Index: Source/JavaScriptCore/heap/PreciseAllocation.cpp >=================================================================== >--- Source/JavaScriptCore/heap/PreciseAllocation.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/PreciseAllocation.cpp (working copy) >@@ -120,7 +120,7 @@ PreciseAllocation* PreciseAllocation::tr > } > > >-PreciseAllocation* PreciseAllocation::tryCreateForLowerTier(Heap& heap, size_t size, Subspace* subspace, uint8_t lowerTierIndex) >+PreciseAllocation* PreciseAllocation::createForLowerTier(Heap& heap, size_t size, Subspace* subspace, uint8_t lowerTierIndex) > { > if constexpr (validateDFGDoesGC) > heap.vm().verifyCanGC(); >Index: Source/JavaScriptCore/heap/PreciseAllocation.h >=================================================================== >--- Source/JavaScriptCore/heap/PreciseAllocation.h (revision 286965) >+++ Source/JavaScriptCore/heap/PreciseAllocation.h (working copy) >@@ -45,7 +45,7 @@ public: > > static PreciseAllocation* tryCreate(Heap&, size_t, Subspace*, unsigned indexInSpace); > >- static PreciseAllocation* tryCreateForLowerTier(Heap&, size_t, Subspace*, uint8_t lowerTierIndex); >+ static PreciseAllocation* createForLowerTier(Heap&, size_t, Subspace*, uint8_t lowerTierIndex); > PreciseAllocation* reuseForLowerTier(); > > PreciseAllocation* tryReallocate(size_t, Subspace*); >Index: Source/JavaScriptCore/heap/SlotVisitor.cpp >=================================================================== >--- Source/JavaScriptCore/heap/SlotVisitor.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/SlotVisitor.cpp (working copy) >@@ -152,9 +152,10 @@ void SlotVisitor::appendJSCellOrAuxiliar > out.print("GC type: ", heap()->collectionScope(), "\n"); > out.print("Object at: ", RawPointer(jsCell), "\n"); > #if USE(JSVALUE64) >- out.print("Structure ID: ", structureID.bits(), " (", RawPointer(structureID.decode()), ")\n"); >+ out.print("Structure ID: ", structureID, " (0x", format("%x", structureID), ")\n"); >+ out.print("Structure ID table size: ", heap()->structureIDTable().size(), "\n"); > #else >- out.print("Structure: ", RawPointer(structureID.decode()), "\n"); >+ out.print("Structure: ", RawPointer(structureID), "\n"); > #endif > out.print("Object contents:"); > for (unsigned i = 0; i < 2; ++i) >@@ -185,13 +186,13 @@ void SlotVisitor::appendJSCellOrAuxiliar > die("GC scan found corrupt object: structureID is zero!\n"); > > // It's not OK for the structure to be nuked at any GC scan point. >- if (structureID.isNuked()) >+ if (isNuked(structureID)) > die("GC scan found object in bad state: structureID is nuked!\n"); >- >+ > // This detects the worst of the badness. >- Integrity::auditStructureID(structureID); >+ Integrity::auditStructureID(heap()->structureIDTable(), structureID); > }; >- >+ > // In debug mode, we validate before marking since this makes it clearer what the problem > // was. It's also slower, so we don't do it normally. > if (ASSERT_ENABLED && isJSCellKind(heapCell->cellKind())) >Index: Source/JavaScriptCore/heap/SlotVisitor.h >=================================================================== >--- Source/JavaScriptCore/heap/SlotVisitor.h (revision 286965) >+++ Source/JavaScriptCore/heap/SlotVisitor.h (working copy) >@@ -92,8 +92,6 @@ public: > > template<typename T, typename Traits> void append(const WriteBarrierBase<T, Traits>&); > template<typename T, typename Traits> void appendHidden(const WriteBarrierBase<T, Traits>&); >- void append(const WriteBarrierStructureID&); >- void appendHidden(const WriteBarrierStructureID&); > template<typename Iterator> void append(Iterator begin , Iterator end); > ALWAYS_INLINE void appendValues(const WriteBarrierBase<Unknown, RawValueTraits<Unknown>>*, size_t count); > ALWAYS_INLINE void appendValuesHidden(const WriteBarrierBase<Unknown, RawValueTraits<Unknown>>*, size_t count); >Index: Source/JavaScriptCore/heap/SlotVisitorInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/SlotVisitorInlines.h (revision 286965) >+++ Source/JavaScriptCore/heap/SlotVisitorInlines.h (working copy) >@@ -116,16 +116,6 @@ ALWAYS_INLINE void SlotVisitor::appendHi > appendHiddenUnbarriered(slot.get()); > } > >-ALWAYS_INLINE void SlotVisitor::append(const WriteBarrierStructureID& slot) >-{ >- appendUnbarriered(reinterpret_cast<JSCell*>(slot.get())); >-} >- >-ALWAYS_INLINE void SlotVisitor::appendHidden(const WriteBarrierStructureID& slot) >-{ >- appendHiddenUnbarriered(reinterpret_cast<JSCell*>(slot.get())); >-} >- > template<typename Iterator> > ALWAYS_INLINE void SlotVisitor::append(Iterator begin, Iterator end) > { >Index: Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp >=================================================================== >--- Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp (revision 286965) >+++ Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp (nonexistent) >@@ -1,180 +0,0 @@ >-/* >- * Copyright (C) 2017-2021 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "StructureAlignedMemoryAllocator.h" >- >-#include "JSCConfig.h" >-#include "MarkedBlock.h" >- >-#include <wtf/OSAllocator.h> >- >-namespace JSC { >- >-StructureAlignedMemoryAllocator::StructureAlignedMemoryAllocator(CString name) >- : Base(name) >-{ >-} >- >-StructureAlignedMemoryAllocator::~StructureAlignedMemoryAllocator() >-{ >- releaseMemoryFromSubclassDestructor(); >-} >- >-void StructureAlignedMemoryAllocator::dump(PrintStream& out) const >-{ >- out.print("Structure(", RawPointer(this), ")"); >-} >- >-void* StructureAlignedMemoryAllocator::tryAllocateMemory(size_t) >-{ >- return nullptr; >-} >- >-void StructureAlignedMemoryAllocator::freeMemory(void*) >-{ >- // Structures do not support Precise allocations right now. >- RELEASE_ASSERT_NOT_REACHED(); >-} >- >-void* StructureAlignedMemoryAllocator::tryReallocateMemory(void*, size_t) >-{ >- // Structures do not support Precise allocations right now. >- RELEASE_ASSERT_NOT_REACHED(); >-} >- >-#if CPU(ADDRESS64) >- >-class StructureMemoryManager { >-public: >- StructureMemoryManager() >- { >- // Don't use the first page because zero is used as the empty StructureID and the first allocation will conflict. >- m_usedBlocks.set(0); >- } >- >- void* tryMallocStructureBlock() >- { >- size_t freeIndex; >- { >- Locker locker(m_lock); >- constexpr size_t startIndex = 0; >- freeIndex = m_usedBlocks.findBit(startIndex, 0); >- ASSERT(freeIndex <= m_usedBlocks.bitCount()); >- if (freeIndex * MarkedBlock::blockSize >= structureHeapAddressSize) >- return nullptr; >- m_usedBlocks.set(freeIndex); >- } >- >- MarkedBlock* block = reinterpret_cast<MarkedBlock*>(g_jscConfig.startOfStructureHeap) + freeIndex * MarkedBlock::blockSize; >- constexpr bool writable = true; >- constexpr bool executable = false; >- OSAllocator::commit(block, MarkedBlock::blockSize, writable, executable); >- return block; >- } >- >- void freeStructureBlock(void* blockPtr) >- { >- OSAllocator::decommit(blockPtr, MarkedBlock::blockSize); >- uintptr_t block = reinterpret_cast<uintptr_t>(blockPtr); >- RELEASE_ASSERT(g_jscConfig.startOfStructureHeap <= block && block < g_jscConfig.startOfStructureHeap + structureHeapAddressSize); >- RELEASE_ASSERT(roundUpToMultipleOf<MarkedBlock::blockSize>(block) == block); >- >- Locker locker(m_lock); >- m_usedBlocks.quickClear((block - g_jscConfig.startOfStructureHeap) / MarkedBlock::blockSize); >- } >- >-private: >- Lock m_lock; >- BitVector m_usedBlocks; >-}; >- >-static LazyNeverDestroyed<StructureMemoryManager> s_structureMemoryManager; >- >-void StructureAlignedMemoryAllocator::initializeStructureAddressSpace() >-{ >- static_assert(hasOneBitSet(structureHeapAddressSize)); >- >- g_jscConfig.startOfStructureHeap = reinterpret_cast<uintptr_t>(OSAllocator::reserveUncommittedAligned(structureHeapAddressSize, OSAllocator::FastMallocPages)); >- s_structureMemoryManager.construct(); >- >- ASSERT((g_jscConfig.startOfStructureHeap & ~structureIDMask) == g_jscConfig.startOfStructureHeap); >-} >- >-void* StructureAlignedMemoryAllocator::tryMallocBlock() >-{ >- return s_structureMemoryManager->tryMallocStructureBlock(); >-} >- >-void StructureAlignedMemoryAllocator::freeBlock(void* block) >-{ >- s_structureMemoryManager->freeStructureBlock(block); >-} >- >-void StructureAlignedMemoryAllocator::commitBlock(void* block) >-{ >- constexpr bool writable = true; >- constexpr bool executable = false; >- OSAllocator::commit(block, MarkedBlock::blockSize, writable, executable); >-} >- >-void StructureAlignedMemoryAllocator::decommitBlock(void* block) >-{ >- OSAllocator::decommit(block, MarkedBlock::blockSize); >-} >- >-#else // not CPU(ADDRESS64) >- >-// FIXME: This is the same as IsoAlignedMemoryAllocator maybe we should just use that for 32-bit. >- >-void StructureAlignedMemoryAllocator::initializeStructureAddressSpace() >-{ >- g_jscConfig.startOfStructureHeap = 0; >-} >- >-void* StructureAlignedMemoryAllocator::tryMallocBlock() >-{ >- return tryFastAlignedMalloc(MarkedBlock::blockSize, MarkedBlock::blockSize); >-} >- >-void StructureAlignedMemoryAllocator::freeBlock(void* block) >-{ >- fastAlignedFree(block); >-} >- >-void StructureAlignedMemoryAllocator::commitBlock(void* block) >-{ >- WTF::fastCommitAlignedMemory(block, MarkedBlock::blockSize); >-} >- >-void StructureAlignedMemoryAllocator::decommitBlock(void* block) >-{ >- WTF::fastDecommitAlignedMemory(block, MarkedBlock::blockSize); >-} >- >-#endif // CPU(ADDRESS64) >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.h >=================================================================== >--- Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.h (revision 286965) >+++ Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.h (nonexistent) >@@ -1,60 +0,0 @@ >-/* >- * Copyright (C) 2021 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "IsoMemoryAllocatorBase.h" >-#include <wtf/Gigacage.h> >- >-#if ENABLE(MALLOC_HEAP_BREAKDOWN) >-#include <wtf/DebugHeap.h> >-#endif >- >-namespace JSC { >- >-class StructureAlignedMemoryAllocator final : public IsoMemoryAllocatorBase { >-public: >- using Base = IsoMemoryAllocatorBase; >- >- StructureAlignedMemoryAllocator(CString); >- ~StructureAlignedMemoryAllocator() final; >- >- void dump(PrintStream&) const final; >- >- void* tryAllocateMemory(size_t) final; >- void freeMemory(void*) final; >- void* tryReallocateMemory(void*, size_t) final; >- >- static void initializeStructureAddressSpace(); >- >-protected: >- void* tryMallocBlock() final; >- void freeBlock(void* block) final; >- void commitBlock(void* block) final; >- void decommitBlock(void* block) final; >-}; >- >-} // namespace JSC >- >Index: Source/JavaScriptCore/jit/AssemblyHelpers.cpp >=================================================================== >--- Source/JavaScriptCore/jit/AssemblyHelpers.cpp (revision 286965) >+++ Source/JavaScriptCore/jit/AssemblyHelpers.cpp (working copy) >@@ -320,7 +320,7 @@ void AssemblyHelpers::emitStoreStructure > #if USE(JSVALUE64) > jit.store64(TrustedImm64(structurePtr->idBlob()), MacroAssembler::Address(dest, JSCell::structureIDOffset())); > if (ASSERT_ENABLED) { >- Jump correctStructure = jit.branch32(Equal, MacroAssembler::Address(dest, JSCell::structureIDOffset()), TrustedImm32(structurePtr->id().bits())); >+ Jump correctStructure = jit.branch32(Equal, MacroAssembler::Address(dest, JSCell::structureIDOffset()), TrustedImm32(structurePtr->id())); > jit.abortWithReason(AHStructureIDIsValid); > correctStructure.link(&jit); > >@@ -389,29 +389,44 @@ void AssemblyHelpers::storeProperty(JSVa > BaseIndex(scratch, offset, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue))); > } > >-void AssemblyHelpers::emitNonNullDecodeStructureID(RegisterID source, RegisterID dest) >+void AssemblyHelpers::emitLoadStructure(VM& vm, RegisterID source, RegisterID dest, RegisterID scratch) > { >- move(source, dest); >-#if CPU(ADDRESS64) >- // This could use BFI on arm64 but that only helps if the start of structure heap is encodable as a mov and not as an immediate in the add so it's probably not super important. >- and32(TrustedImm32(structureIDMask), dest); >- add64(TrustedImm64(g_jscConfig.startOfStructureHeap), dest); >-#endif // not CPU(ADDRESS64) >-} >+#if USE(JSVALUE64) >+#if CPU(ARM64) >+ RegisterID scratch2 = dataTempRegister; >+#elif CPU(X86_64) >+ RegisterID scratch2 = scratchRegister(); >+#else >+#error "Unsupported cpu" >+#endif > >-void AssemblyHelpers::emitLoadStructure(VM&, RegisterID source, RegisterID dest) >-{ >- load32(MacroAssembler::Address(source, JSCell::structureIDOffset()), dest); >- emitNonNullDecodeStructureID(dest, dest); >+ ASSERT(dest != scratch); >+ ASSERT(dest != scratch2); >+ ASSERT(scratch != scratch2); >+ >+ load32(MacroAssembler::Address(source, JSCell::structureIDOffset()), scratch2); >+ loadPtr(vm.heap.structureIDTable().base(), scratch); >+ rshift32(scratch2, TrustedImm32(StructureIDTable::s_numberOfEntropyBits), dest); >+ loadPtr(MacroAssembler::BaseIndex(scratch, dest, MacroAssembler::ScalePtr), dest); >+ lshiftPtr(TrustedImm32(StructureIDTable::s_entropyBitsShiftForStructurePointer), scratch2); >+ xorPtr(scratch2, dest); >+#else // not USE(JSVALUE64) >+ UNUSED_PARAM(scratch); >+ UNUSED_PARAM(vm); >+ loadPtr(MacroAssembler::Address(source, JSCell::structureIDOffset()), dest); >+#endif // not USE(JSVALUE64) > } > >-void AssemblyHelpers::emitLoadPrototype(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, JumpList& slowPath) >+void AssemblyHelpers::emitLoadPrototype(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, JumpList& slowPath) > { > ASSERT(resultRegs.payloadGPR() != objectGPR); >+ ASSERT(resultRegs.payloadGPR() != scratchGPR); >+ ASSERT(objectGPR != scratchGPR); > >- emitLoadStructure(vm, objectGPR, resultRegs.payloadGPR()); >+ emitLoadStructure(vm, objectGPR, resultRegs.payloadGPR(), scratchGPR); > >- auto overridesGetPrototype = branchTest32(MacroAssembler::NonZero, MacroAssembler::Address(resultRegs.payloadGPR(), Structure::outOfLineTypeFlagsOffset()), TrustedImm32(OverridesGetPrototypeOutOfLine)); >+ load16(MacroAssembler::Address(resultRegs.payloadGPR(), Structure::outOfLineTypeFlagsOffset()), scratchGPR); >+ auto overridesGetPrototype = branchTest32(MacroAssembler::NonZero, scratchGPR, TrustedImm32(OverridesGetPrototypeOutOfLine)); > slowPath.append(overridesGetPrototype); > > loadValue(MacroAssembler::Address(resultRegs.payloadGPR(), Structure::prototypeOffset()), resultRegs); >@@ -510,7 +525,7 @@ void AssemblyHelpers::emitRandomThunk(JS > void AssemblyHelpers::emitRandomThunk(VM& vm, GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg result) > { > emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, scratch3); >- emitLoadStructure(vm, scratch3, scratch3); >+ emitLoadStructure(vm, scratch3, scratch3, scratch0); > loadPtr(Address(scratch3, Structure::globalObjectOffset()), scratch3); > // Now, scratch3 holds JSGlobalObject*. > >@@ -823,7 +838,7 @@ void AssemblyHelpers::emitConvertValueTo > ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg); > JumpList isNotMasqueradesAsUndefined; > isNotMasqueradesAsUndefined.append(branchTest8(Zero, Address(value.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined))); >- emitLoadStructure(vm, value.payloadGPR(), result); >+ emitLoadStructure(vm, value.payloadGPR(), result, scratchIfShouldCheckMasqueradesAsUndefined); > move(TrustedImmPtr(globalObject), scratchIfShouldCheckMasqueradesAsUndefined); > isNotMasqueradesAsUndefined.append(branchPtr(NotEqual, Address(result, Structure::globalObjectOffset()), scratchIfShouldCheckMasqueradesAsUndefined)); > >@@ -914,7 +929,7 @@ AssemblyHelpers::JumpList AssemblyHelper > ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg); > JumpList isNotMasqueradesAsUndefined; > isNotMasqueradesAsUndefined.append(branchTest8(Zero, Address(value.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined))); >- emitLoadStructure(vm, value.payloadGPR(), scratch); >+ emitLoadStructure(vm, value.payloadGPR(), scratch, scratchIfShouldCheckMasqueradesAsUndefined); > if (std::holds_alternative<JSGlobalObject*>(globalObject)) > move(TrustedImmPtr(std::get<JSGlobalObject*>(globalObject)), scratchIfShouldCheckMasqueradesAsUndefined); > else >Index: Source/JavaScriptCore/jit/AssemblyHelpers.h >=================================================================== >--- Source/JavaScriptCore/jit/AssemblyHelpers.h (revision 286965) >+++ Source/JavaScriptCore/jit/AssemblyHelpers.h (working copy) >@@ -1123,7 +1123,7 @@ public: > Jump branchStructure(RelationalCondition condition, T leftHandSide, Structure* structure) > { > #if USE(JSVALUE64) >- return branch32(condition, leftHandSide, TrustedImm32(structure->id().bits())); >+ return branch32(condition, leftHandSide, TrustedImm32(structure->id())); > #else > return branchPtr(condition, leftHandSide, TrustedImmPtr(structure)); > #endif >@@ -1577,9 +1577,8 @@ public: > return argumentCount(codeOrigin.inlineCallFrame()); > } > >- void emitNonNullDecodeStructureID(RegisterID source, RegisterID dest); >- void emitLoadStructure(VM&, RegisterID source, RegisterID dest); >- void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, JumpList& slowPath); >+ void emitLoadStructure(VM&, RegisterID source, RegisterID dest, RegisterID scratch); >+ void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, JumpList& slowPath); > > void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID) > { >@@ -1664,13 +1663,13 @@ public: > void nukeStructureAndStoreButterfly(VM& vm, GPRReg butterfly, GPRReg object) > { > if (isX86()) { >- or32(TrustedImm32(bitwise_cast<int32_t>(StructureID::nukedStructureIDBit)), Address(object, JSCell::structureIDOffset())); >+ or32(TrustedImm32(bitwise_cast<int32_t>(nukedStructureIDBit())), Address(object, JSCell::structureIDOffset())); > storePtr(butterfly, Address(object, JSObject::butterflyOffset())); > return; > } > > Jump ok = jumpIfMutatorFenceNotNeeded(vm); >- or32(TrustedImm32(bitwise_cast<int32_t>(StructureID::nukedStructureIDBit)), Address(object, JSCell::structureIDOffset())); >+ or32(TrustedImm32(bitwise_cast<int32_t>(nukedStructureIDBit())), Address(object, JSCell::structureIDOffset())); > storeFence(); > storePtr(butterfly, Address(object, JSObject::butterflyOffset())); > storeFence(); >Index: Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp >=================================================================== >--- Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp (revision 286965) >+++ Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp (working copy) >@@ -99,7 +99,7 @@ unsigned PolymorphicAccessJITStubRoutine > for (auto& key : cases) > WTF::add(hasher, key->hash()); > for (auto& structureID : weakStructures) >- WTF::add(hasher, structureID.bits()); >+ WTF::add(hasher, structureID); > return hasher.hash(); > } > >Index: Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (revision 286965) >+++ Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (working copy) >@@ -136,7 +136,7 @@ void JITGetByIdGenerator::generateFastPa > static void generateGetByIdInlineAccess(JIT& jit, GPRReg stubInfoGPR, JSValueRegs baseJSR, GPRReg scratchGPR, JSValueRegs resultJSR) > { > jit.load32(CCallHelpers::Address(baseJSR.payloadGPR(), JSCell::structureIDOffset()), scratchGPR); >- auto doInlineAccess = jit.branch32(CCallHelpers::Equal, scratchGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfInlineAccessBaseStructureID())); >+ auto doInlineAccess = jit.branch32(CCallHelpers::Equal, scratchGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfInlineAccessBaseStructure())); > jit.farJump(CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); > doInlineAccess.link(&jit); > jit.load32(CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfByIdSelfOffset()), scratchGPR); >@@ -221,7 +221,7 @@ void JITPutByIdGenerator::generateBaseli > using BaselinePutByIdRegisters::scratch2GPR; > > jit.load32(CCallHelpers::Address(baseJSR.payloadGPR(), JSCell::structureIDOffset()), scratchGPR); >- auto doInlineAccess = jit.branch32(CCallHelpers::Equal, scratchGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfInlineAccessBaseStructureID())); >+ auto doInlineAccess = jit.branch32(CCallHelpers::Equal, scratchGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfInlineAccessBaseStructure())); > jit.farJump(CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfCodePtr()), JITStubRoutinePtrTag); > doInlineAccess.link(&jit); > jit.load32(CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfByIdSelfOffset()), scratchGPR); >@@ -412,7 +412,7 @@ void JITInByIdGenerator::generateBaselin > CCallHelpers::JumpList done; > > jit.load32(CCallHelpers::Address(baseJSR.payloadGPR(), JSCell::structureIDOffset()), scratchGPR); >- auto skipInlineAccess = jit.branch32(CCallHelpers::NotEqual, scratchGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfInlineAccessBaseStructureID())); >+ auto skipInlineAccess = jit.branch32(CCallHelpers::NotEqual, scratchGPR, CCallHelpers::Address(stubInfoGPR, StructureStubInfo::offsetOfInlineAccessBaseStructure())); > jit.boxBoolean(true, resultJSR); > auto finished = jit.jump(); > >Index: Source/JavaScriptCore/jit/JITOpcodes.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITOpcodes.cpp (revision 286965) >+++ Source/JavaScriptCore/jit/JITOpcodes.cpp (working copy) >@@ -256,7 +256,7 @@ void JIT::emit_op_typeof_is_undefined(co > Jump notMasqueradesAsUndefined = jump(); > > isMasqueradesAsUndefined.link(this); >- emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT1); >+ emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT1, regT2); > loadGlobalObject(regT0); > loadPtr(Address(regT1, Structure::globalObjectOffset()), regT1); > comparePtr(Equal, regT0, regT1, regT0); >@@ -514,7 +514,7 @@ void JIT::emit_op_jeq_null(const Instruc > > // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. > Jump isNotMasqueradesAsUndefined = branchTest8(Zero, Address(jsRegT10.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)); >- emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2); >+ emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2, regT1); > loadGlobalObject(regT0); > addJump(branchPtr(Equal, Address(regT2, Structure::globalObjectOffset()), regT0), target); > Jump masqueradesGlobalObjectIsForeign = jump(); >@@ -539,7 +539,7 @@ void JIT::emit_op_jneq_null(const Instru > > // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. > addJump(branchTest8(Zero, Address(jsRegT10.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target); >- emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2); >+ emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2, regT1); > loadGlobalObject(regT0); > addJump(branchPtr(NotEqual, Address(regT2, Structure::globalObjectOffset()), regT0), target); > Jump wasNotImmediate = jump(); >@@ -1196,7 +1196,7 @@ void JIT::emit_op_eq_null(const Instruct > Jump wasNotMasqueradesAsUndefined = jump(); > > isMasqueradesAsUndefined.link(this); >- emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2); >+ emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2, regT1); > loadGlobalObject(regT0); > loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2); > comparePtr(Equal, regT0, regT2, regT0); >@@ -1228,7 +1228,7 @@ void JIT::emit_op_neq_null(const Instruc > Jump wasNotMasqueradesAsUndefined = jump(); > > isMasqueradesAsUndefined.link(this); >- emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2); >+ emitLoadStructure(vm(), jsRegT10.payloadGPR(), regT2, regT1); > loadGlobalObject(regT0); > loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2); > comparePtr(NotEqual, regT0, regT2, regT0); >@@ -1959,7 +1959,7 @@ void JIT::emit_op_get_prototype_of(const > slowCases.append(branchIfNotCell(jsRegT10)); > slowCases.append(branchIfNotObject(jsRegT10.payloadGPR())); > >- emitLoadPrototype(vm(), jsRegT10.payloadGPR(), jsRegT32, slowCases); >+ emitLoadPrototype(vm(), jsRegT10.payloadGPR(), jsRegT32, regT4, slowCases); > addSlowCase(slowCases); > > emitValueProfilingSite(bytecode, jsRegT32); >Index: Source/JavaScriptCore/jit/JITPropertyAccess.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITPropertyAccess.cpp (revision 286965) >+++ Source/JavaScriptCore/jit/JITPropertyAccess.cpp (working copy) >@@ -2731,7 +2731,7 @@ void JIT::emit_op_get_property_enumerato > and32(TrustedImm32(IndexingTypeMask), regT1); > genericCases.append(branch32(Above, regT1, TrustedImm32(ArrayWithUndecided))); > >- emitLoadStructure(vm(), regT0, regT1); >+ emitLoadStructure(vm(), regT0, regT1, regT2); > loadPtr(Address(regT1, Structure::previousOrRareDataOffset()), regT1); > genericCases.append(branchTestPtr(Zero, regT1)); > genericCases.append(branchIfStructure(regT1)); >Index: Source/JavaScriptCore/jit/JITStubRoutine.h >=================================================================== >--- Source/JavaScriptCore/jit/JITStubRoutine.h (revision 286965) >+++ Source/JavaScriptCore/jit/JITStubRoutine.h (working copy) >@@ -29,13 +29,18 @@ > > #include "ExecutableAllocator.h" > #include "MacroAssemblerCodeRef.h" >-#include "StructureID.h" > > namespace JSC { > > class JITStubRoutineSet; > class VM; > >+#if USE(JSVALUE64) >+using StructureID = uint32_t; >+#else >+using StructureID = Structure*; >+#endif >+ > class AccessCase; > > // This is a base-class for JIT stub routines, and also the class you want >Index: Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (revision 286965) >+++ Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (working copy) >@@ -672,7 +672,7 @@ LLINT_SLOW_PATH_DECL(slow_path_try_get_b > { > StructureID oldStructureID = metadata.m_structureID; > if (oldStructureID) { >- Structure* a = oldStructureID.decode(); >+ Structure* a = vm.heap.structureIDTable().get(oldStructureID); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -686,7 +686,7 @@ LLINT_SLOW_PATH_DECL(slow_path_try_get_b > Structure* structure = baseCell->structure(vm); > if (slot.isValue() && slot.slotBase() == baseValue) { > // Start out by clearing out the old cache. >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_offset = 0; > > if (structure->propertyAccessesAreCacheable() && !structure->needImpurePropertyWatchpoint()) { >@@ -721,7 +721,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id > { > StructureID oldStructureID = metadata.m_structureID; > if (oldStructureID) { >- Structure* a = oldStructureID.decode(); >+ Structure* a = vm.heap.structureIDTable().get(oldStructureID); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -735,7 +735,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id > Structure* structure = baseCell->structure(vm); > if (slot.isValue()) { > // Start out by clearing out the old cache. >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_offset = 0; > > if (structure->propertyAccessesAreCacheable() && !structure->needImpurePropertyWatchpoint()) { >@@ -848,10 +848,10 @@ static JSValue performLLIntGetByID(const > oldStructureID = metadata.protoLoadMode.structureID; > break; > default: >- oldStructureID = StructureID(); >+ oldStructureID = 0; > } > if (oldStructureID) { >- Structure* a = oldStructureID.decode(); >+ Structure* a = vm.heap.structureIDTable().get(oldStructureID); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -986,7 +986,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id > { > StructureID oldStructureID = metadata.m_oldStructureID; > if (oldStructureID) { >- Structure* a = oldStructureID.decode(); >+ Structure* a = vm.heap.structureIDTable().get(oldStructureID); > Structure* b = baseValue.asCell()->structure(vm); > if (slot.type() == PutPropertySlot::NewProperty) > b = b->previousID(); >@@ -999,9 +999,9 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id > } > > // Start out by clearing out the old cache. >- metadata.m_oldStructureID = StructureID(); >+ metadata.m_oldStructureID = 0; > metadata.m_offset = 0; >- metadata.m_newStructureID = StructureID(); >+ metadata.m_newStructureID = 0; > metadata.m_structureChain.clear(); > > JSCell* baseCell = baseValue.asCell(); >@@ -1175,7 +1175,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_priva > { > StructureID oldStructureID = metadata.m_structureID; > if (oldStructureID) { >- Structure* a = oldStructureID.decode(); >+ Structure* a = vm.heap.structureIDTable().get(oldStructureID); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -1189,7 +1189,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_priva > Structure* structure = baseCell->structure(vm); > if (slot.isValue()) { > // Start out by clearing out the old cache. >- metadata.m_structureID = StructureID(); >+ metadata.m_structureID = 0; > metadata.m_offset = 0; > > if (!structure->isUncacheableDictionary()) { >@@ -1308,7 +1308,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_priva > { > StructureID oldStructureID = metadata.m_oldStructureID; > if (oldStructureID) { >- Structure* a = oldStructureID.decode(); >+ Structure* a = vm.heap.structureIDTable().get(oldStructureID); > Structure* b = baseValue.asCell()->structure(vm); > if (slot.type() == PutPropertySlot::NewProperty) > b = b->previousID(); >@@ -1321,9 +1321,9 @@ LLINT_SLOW_PATH_DECL(slow_path_put_priva > } > > // Start out by clearing out the old cache. >- metadata.m_oldStructureID = StructureID(); >+ metadata.m_oldStructureID = 0; > metadata.m_offset = 0; >- metadata.m_newStructureID = StructureID(); >+ metadata.m_newStructureID = 0; > metadata.m_property.clear(); > > JSCell* baseCell = baseValue.asCell(); >@@ -1397,8 +1397,8 @@ LLINT_SLOW_PATH_DECL(slow_path_set_priva > ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); > > // Start out by clearing out the old cache. >- metadata.m_oldStructureID = StructureID(); >- metadata.m_newStructureID = StructureID(); >+ metadata.m_oldStructureID = 0; >+ metadata.m_newStructureID = 0; > metadata.m_brand.clear(); > > if (!newStructure->isDictionary()) { >Index: Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >=================================================================== >--- Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (revision 286965) >+++ Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (working copy) >@@ -694,16 +694,20 @@ macro writeBarrierOnGlobalLexicalEnviron > end) > end > >-macro structureIDToStructureWithScratch(structureIDThenStructure, scratch) >- andq constexpr structureIDMask, structureIDThenStructure >- leap JSCConfig + constexpr JSC::offsetOfJSCConfigStartOfStructureHeap, scratch >- loadp [scratch], scratch >- addp scratch, structureIDThenStructure >+macro structureIDToStructureWithScratch(structureIDThenStructure, scratch, scratch2) >+ loadp CodeBlock[cfr], scratch >+ move structureIDThenStructure, scratch2 >+ loadp CodeBlock::m_vm[scratch], scratch >+ rshifti NumberOfStructureIDEntropyBits, scratch2 >+ loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[scratch], scratch >+ loadp [scratch, scratch2, PtrSize], scratch2 >+ lshiftp StructureEntropyBitsShift, structureIDThenStructure >+ xorp scratch2, structureIDThenStructure > end > >-macro loadStructureWithScratch(cell, structure, scratch) >+macro loadStructureWithScratch(cell, structure, scratch, scratch2) > loadi JSCell::m_structureID[cell], structure >- structureIDToStructureWithScratch(structure, scratch) >+ structureIDToStructureWithScratch(structure, scratch, scratch2) > end > > # Entrypoints into the interpreter. >@@ -926,7 +930,7 @@ macro equalNullComparisonOp(opcodeName, > move 0, t0 > jmp .done > .masqueradesAsUndefined: >- loadStructureWithScratch(t0, t2, t1) >+ loadStructureWithScratch(t0, t2, t1, t3) > loadp CodeBlock[cfr], t0 > loadp CodeBlock::m_globalObject[t0], t0 > cpeq Structure::m_globalObject[t2], t0, t0 >@@ -1428,7 +1432,7 @@ llintOpWithReturn(op_typeof_is_undefined > move ValueFalse, t1 > return(t1) > .masqueradesAsUndefined: >- loadStructureWithScratch(t0, t3, t1) >+ loadStructureWithScratch(t0, t3, t1, t2) > loadp CodeBlock[cfr], t1 > loadp CodeBlock::m_globalObject[t1], t1 > cpeq Structure::m_globalObject[t3], t1, t0 >@@ -1640,7 +1644,7 @@ llintOpWithProfile(op_get_prototype_of, > btqnz t0, notCellMask, .opGetPrototypeOfSlow > bbb JSCell::m_type[t0], ObjectType, .opGetPrototypeOfSlow > >- loadStructureWithScratch(t0, t2, t1) >+ loadStructureWithScratch(t0, t2, t1, t3) > loadh Structure::m_outOfLineTypeFlags[t2], t3 > btinz t3, OverridesGetPrototypeOutOfLine, .opGetPrototypeOfSlow > >@@ -1680,7 +1684,19 @@ llintOpWithMetadata(op_put_by_id, OpPutB > loadp OpPutById::Metadata::m_structureChain[t5], t3 > btpz t3, .opPutByIdTransitionDirect > >- structureIDToStructureWithScratch(t2, t1) >+ loadp CodeBlock[cfr], t1 >+ loadp CodeBlock::m_vm[t1], t1 >+ loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[t1], t1 >+ >+ macro structureIDToStructureWithScratchAndTable(structureIDThenStructure, table, scratch) >+ move structureIDThenStructure, scratch >+ rshifti NumberOfStructureIDEntropyBits, scratch >+ loadp [table, scratch, PtrSize], scratch >+ lshiftp StructureEntropyBitsShift, structureIDThenStructure >+ xorp scratch, structureIDThenStructure >+ end >+ >+ structureIDToStructureWithScratchAndTable(t2, t1, t0) > > loadp StructureChain::m_vector[t3], t3 > assert(macro (ok) btpnz t3, ok end) >@@ -1691,7 +1707,7 @@ llintOpWithMetadata(op_put_by_id, OpPutB > loadi JSCell::m_structureID[t2], t2 > bineq t2, [t3], .opPutByIdSlow > addp 4, t3 >- structureIDToStructureWithScratch(t2, t1) >+ structureIDToStructureWithScratchAndTable(t2, t1, t0) > loadq Structure::m_prototype[t2], t2 > bqneq t2, ValueNull, .opPutByIdTransitionChainLoop > >@@ -2066,7 +2082,7 @@ macro equalNullJumpOp(opcodeName, opcode > assertNotConstant(size, t0) > loadq [cfr, t0, 8], t0 > btqnz t0, notCellMask, .immediate >- loadStructureWithScratch(t0, t2, t1) >+ loadStructureWithScratch(t0, t2, t1, t3) > cellHandler(t2, JSCell::m_flags[t0], .target) > dispatch() > >@@ -2785,7 +2801,7 @@ end) > macro loadWithStructureCheck(opcodeStruct, get, slowPath) > get(m_scope, t0) > loadq [cfr, t0, 8], t0 >- loadStructureWithScratch(t0, t2, t1) >+ loadStructureWithScratch(t0, t2, t1, t3) > loadp %opcodeStruct%::Metadata::m_structure[t5], t1 > bpneq t2, t1, slowPath > end >@@ -3236,7 +3252,7 @@ llintOpWithReturn(op_get_property_enumer > andi IndexingTypeMask, t1 > bia t1, ArrayWithUndecided, .slowPath > >- loadStructureWithScratch(t0, t1, t2) >+ loadStructureWithScratch(t0, t1, t2, t3) > loadp Structure::m_previousOrRareData[t1], t1 > btpz t1, .slowPath > bbeq JSCell::m_type[t1], StructureType, .slowPath >Index: Source/JavaScriptCore/llint/LowLevelInterpreter.asm >=================================================================== >--- Source/JavaScriptCore/llint/LowLevelInterpreter.asm (revision 286965) >+++ Source/JavaScriptCore/llint/LowLevelInterpreter.asm (working copy) >@@ -212,6 +212,11 @@ else > const LowestTag = constexpr JSValue::LowestTag > end > >+if JSVALUE64 >+ const NumberOfStructureIDEntropyBits = constexpr StructureIDTable::s_numberOfEntropyBits >+ const StructureEntropyBitsShift = constexpr StructureIDTable::s_entropyBitsShiftForStructurePointer >+end >+ > if LARGE_TYPED_ARRAYS > const SmallTypedArrayMaxLength = constexpr ArrayProfile::s_smallTypedArrayMaxLength > end >Index: Source/JavaScriptCore/runtime/ArrayPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ArrayPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/ArrayPrototype.cpp (working copy) >@@ -602,7 +602,7 @@ JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncT > JSObject* thisObject = thisValue.toObject(globalObject); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); > >- Integrity::auditStructureID(thisObject->structureID()); >+ Integrity::auditStructureID(vm, thisObject->structureID()); > if (!canUseDefaultArrayJoinForToString(vm, thisObject)) { > // 2. Let func be the result of calling the [[Get]] internal method of array with argument "join". > JSValue function = thisObject->get(globalObject, vm.propertyNames->join); >Index: Source/JavaScriptCore/runtime/BigIntPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/BigIntPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/BigIntPrototype.cpp (working copy) >@@ -113,7 +113,7 @@ JSC_DEFINE_HOST_FUNCTION(bigIntProtoFunc > > ASSERT(value); > >- Integrity::auditStructureID(value->structureID()); >+ Integrity::auditStructureID(vm, value->structureID()); > int32_t radix = extractToStringRadixArgument(globalObject, callFrame->argument(0), scope); > RETURN_IF_EXCEPTION(scope, { }); > >@@ -156,7 +156,7 @@ JSC_DEFINE_HOST_FUNCTION(bigIntProtoFunc > JSBigInt* value = toThisBigIntValue(globalObject, callFrame->thisValue()); > RETURN_IF_EXCEPTION(scope, { }); > >- Integrity::auditStructureID(value->structureID()); >+ Integrity::auditStructureID(vm, value->structureID()); > return JSValue::encode(value); > } > >Index: Source/JavaScriptCore/runtime/BooleanPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/BooleanPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/BooleanPrototype.cpp (working copy) >@@ -76,7 +76,7 @@ JSC_DEFINE_HOST_FUNCTION(booleanProtoFun > if (UNLIKELY(!thisObject)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(thisObject->structureID()); >+ Integrity::auditStructureID(vm, thisObject->structureID()); > if (thisObject->internalValue() == jsBoolean(false)) > return JSValue::encode(vm.smallStrings.falseString()); > >@@ -96,7 +96,7 @@ JSC_DEFINE_HOST_FUNCTION(booleanProtoFun > if (UNLIKELY(!thisObject)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(thisObject->structureID()); >+ Integrity::auditStructureID(vm, thisObject->structureID()); > return JSValue::encode(thisObject->internalValue()); > } > >Index: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (working copy) >@@ -355,11 +355,11 @@ JSC_DEFINE_COMMON_SLOW_PATH(slow_path_to > if (otherStructureID) > metadata.m_toThisStatus = ToThisConflicted; > metadata.m_cachedStructureID = myStructureID; >- vm.writeBarrier(codeBlock, myStructureID.decode()); >+ vm.writeBarrier(codeBlock, vm.getStructure(myStructureID)); > } > } else { > metadata.m_toThisStatus = ToThisConflicted; >- metadata.m_cachedStructureID = StructureID(); >+ metadata.m_cachedStructureID = 0; > } > // Note: We only need to do this value profiling here on the slow path. The fast path > // just returns the input to to_this if the structure check succeeds. If the structure >Index: Source/JavaScriptCore/runtime/DatePrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/DatePrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/DatePrototype.cpp (working copy) >@@ -99,7 +99,7 @@ static EncodedJSValue formateDateInstanc > if (UNLIKELY(!thisDateObj)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(thisDateObj->structureID()); >+ Integrity::auditStructureID(vm, thisDateObj->structureID()); > const GregorianDateTime* gregorianDateTime = asUTCVariant > ? thisDateObj->gregorianDateTimeUTC(cache) > : thisDateObj->gregorianDateTime(cache); >@@ -315,7 +315,7 @@ JSC_DEFINE_HOST_FUNCTION(dateProtoFuncTo > if (UNLIKELY(!thisDateObj)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(thisDateObj->structureID()); >+ Integrity::auditStructureID(vm, thisDateObj->structureID()); > if (!std::isfinite(thisDateObj->internalNumber())) > return throwVMError(globalObject, scope, createRangeError(globalObject, "Invalid Date"_s)); > >@@ -363,7 +363,7 @@ JSC_DEFINE_HOST_FUNCTION(dateProtoFuncTo > if (!thisValue.isObject()) > return throwVMTypeError(globalObject, scope, "Date.prototype[Symbol.toPrimitive] expected |this| to be an object."); > JSObject* thisObject = jsCast<JSObject*>(thisValue); >- Integrity::auditStructureID(thisObject->structureID()); >+ Integrity::auditStructureID(vm, thisObject->structureID()); > > if (!callFrame->argumentCount()) > return throwVMTypeError(globalObject, scope, "Date.prototype[Symbol.toPrimitive] expected a first argument."); >Index: Source/JavaScriptCore/runtime/ErrorInstance.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ErrorInstance.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/ErrorInstance.cpp (working copy) >@@ -154,7 +154,7 @@ String ErrorInstance::sanitizedMessageSt > { > VM& vm = globalObject->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- Integrity::auditStructureID(structureID()); >+ Integrity::auditStructureID(vm, structureID()); > > JSValue messageValue; > auto messagePropertName = vm.propertyNames->message; >@@ -172,7 +172,7 @@ String ErrorInstance::sanitizedNameStrin > { > VM& vm = globalObject->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- Integrity::auditStructureID(structureID()); >+ Integrity::auditStructureID(vm, structureID()); > > JSValue nameValue; > auto namePropertName = vm.propertyNames->name; >@@ -203,7 +203,7 @@ String ErrorInstance::sanitizedToString( > { > VM& vm = globalObject->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- Integrity::auditStructureID(structureID()); >+ Integrity::auditStructureID(vm, structureID()); > > String nameString = sanitizedNameString(globalObject); > RETURN_IF_EXCEPTION(scope, String()); >Index: Source/JavaScriptCore/runtime/ErrorPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ErrorPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/ErrorPrototype.cpp (working copy) >@@ -79,7 +79,7 @@ JSC_DEFINE_HOST_FUNCTION(errorProtoFuncT > if (!thisValue.isObject()) > return throwVMTypeError(globalObject, scope); > JSObject* thisObj = asObject(thisValue); >- Integrity::auditStructureID(thisObj->structureID()); >+ Integrity::auditStructureID(vm, thisObj->structureID()); > > // Guard against recursion! > StringRecursionChecker checker(globalObject, thisObj); >Index: Source/JavaScriptCore/runtime/FunctionExecutable.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/FunctionExecutable.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/FunctionExecutable.cpp (working copy) >@@ -78,7 +78,7 @@ void FunctionExecutable::visitChildrenIm > visitor.append(thisObject->m_codeBlockForConstruct); > visitor.append(thisObject->m_unlinkedExecutable); > if (RareData* rareData = thisObject->m_rareData.get()) { >- visitor.append(rareData->m_cachedPolyProtoStructureID); >+ visitor.append(rareData->m_cachedPolyProtoStructure); > visitor.append(rareData->m_asString); > if (TemplateObjectMap* map = rareData->m_templateObjectMap.get()) { > Locker locker { thisObject->cellLock() }; >Index: Source/JavaScriptCore/runtime/FunctionExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/FunctionExecutable.h (revision 286965) >+++ Source/JavaScriptCore/runtime/FunctionExecutable.h (working copy) >@@ -257,12 +257,12 @@ public: > Structure* cachedPolyProtoStructure() > { > if (UNLIKELY(m_rareData)) >- return m_rareData->m_cachedPolyProtoStructureID.get(); >+ return m_rareData->m_cachedPolyProtoStructure.get(); > return nullptr; > } > void setCachedPolyProtoStructure(VM& vm, Structure* structure) > { >- ensureRareData().m_cachedPolyProtoStructureID.set(vm, this, structure); >+ ensureRareData().m_cachedPolyProtoStructure.set(vm, this, structure); > } > > InlineWatchpointSet& ensurePolyProtoWatchpoint() >@@ -310,8 +310,8 @@ private: > unsigned m_parametersStartOffset { 0 }; > unsigned m_typeProfilingStartOffset { UINT_MAX }; > unsigned m_typeProfilingEndOffset { UINT_MAX }; >- WriteBarrierStructureID m_cachedPolyProtoStructureID; > std::unique_ptr<TemplateObjectMap> m_templateObjectMap; >+ WriteBarrier<Structure> m_cachedPolyProtoStructure; > WriteBarrier<JSString> m_asString; > }; > >Index: Source/JavaScriptCore/runtime/FunctionPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/FunctionPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/FunctionPrototype.cpp (working copy) >@@ -81,19 +81,19 @@ JSC_DEFINE_HOST_FUNCTION(functionProtoFu > JSValue thisValue = callFrame->thisValue(); > if (thisValue.inherits<JSFunction>(vm)) { > JSFunction* function = jsCast<JSFunction*>(thisValue); >- Integrity::auditStructureID(function->structureID()); >+ Integrity::auditStructureID(vm, function->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(function->toString(globalObject))); > } > > if (thisValue.inherits<InternalFunction>(vm)) { > InternalFunction* function = jsCast<InternalFunction*>(thisValue); >- Integrity::auditStructureID(function->structureID()); >+ Integrity::auditStructureID(vm, function->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(jsMakeNontrivialString(globalObject, "function ", function->name(), "() {\n [native code]\n}"))); > } > > if (thisValue.isObject()) { > JSObject* object = asObject(thisValue); >- Integrity::auditStructureID(object->structureID()); >+ Integrity::auditStructureID(vm, object->structureID()); > if (object->isCallable(vm)) > RELEASE_AND_RETURN(scope, JSValue::encode(jsMakeNontrivialString(globalObject, "function ", object->classInfo(vm)->className, "() {\n [native code]\n}"))); > } >Index: Source/JavaScriptCore/runtime/FunctionRareData.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/FunctionRareData.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/FunctionRareData.cpp (working copy) >@@ -60,7 +60,7 @@ void FunctionRareData::visitChildrenImpl > > rareData->m_objectAllocationProfile.visitAggregate(visitor); > rareData->m_internalFunctionAllocationProfile.visitAggregate(visitor); >- visitor.append(rareData->m_boundFunctionStructureID); >+ visitor.append(rareData->m_boundFunctionStructure); > visitor.append(rareData->m_executable); > } > >Index: Source/JavaScriptCore/runtime/FunctionRareData.h >=================================================================== >--- Source/JavaScriptCore/runtime/FunctionRareData.h (revision 286965) >+++ Source/JavaScriptCore/runtime/FunctionRareData.h (working copy) >@@ -72,7 +72,9 @@ public: > static inline ptrdiff_t offsetOfObjectAllocationProfile() { return OBJECT_OFFSETOF(FunctionRareData, m_objectAllocationProfile); } > static inline ptrdiff_t offsetOfAllocationProfileWatchpointSet() { return OBJECT_OFFSETOF(FunctionRareData, m_allocationProfileWatchpointSet); } > static inline ptrdiff_t offsetOfInternalFunctionAllocationProfile() { return OBJECT_OFFSETOF(FunctionRareData, m_internalFunctionAllocationProfile); } >+ static inline ptrdiff_t offsetOfBoundFunctionStructure() { return OBJECT_OFFSETOF(FunctionRareData, m_boundFunctionStructure); } > static inline ptrdiff_t offsetOfExecutable() { return OBJECT_OFFSETOF(FunctionRareData, m_executable); } >+ static inline ptrdiff_t offsetOfAllocationProfileClearingWatchpoint() { return OBJECT_OFFSETOF(FunctionRareData, m_allocationProfileClearingWatchpoint); } > > ObjectAllocationProfileWithPrototype* objectAllocationProfile() > { >@@ -111,8 +113,8 @@ public: > m_allocationProfileWatchpointSet.startWatching(); > } > >- Structure* getBoundFunctionStructure() { return m_boundFunctionStructureID.get(); } >- void setBoundFunctionStructure(VM& vm, Structure* structure) { m_boundFunctionStructureID.set(vm, this, structure); } >+ Structure* getBoundFunctionStructure() { return m_boundFunctionStructure.get(); } >+ void setBoundFunctionStructure(VM& vm, Structure* structure) { m_boundFunctionStructure.set(vm, this, structure); } > > ExecutableBase* executable() const { return m_executable.get(); } > >@@ -158,7 +160,7 @@ private: > ObjectAllocationProfileWithPrototype m_objectAllocationProfile; > InlineWatchpointSet m_allocationProfileWatchpointSet; > InternalFunctionAllocationProfile m_internalFunctionAllocationProfile; >- WriteBarrierStructureID m_boundFunctionStructureID; >+ WriteBarrier<Structure> m_boundFunctionStructure; > WriteBarrier<ExecutableBase> m_executable; > std::unique_ptr<AllocationProfileClearingWatchpoint> m_allocationProfileClearingWatchpoint; > bool m_hasReifiedLength : 1; >Index: Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >=================================================================== >--- Source/JavaScriptCore/runtime/HasOwnPropertyCache.h (revision 286965) >+++ Source/JavaScriptCore/runtime/HasOwnPropertyCache.h (working copy) >@@ -43,7 +43,7 @@ public: > static ptrdiff_t offsetOfResult() { return OBJECT_OFFSETOF(Entry, result); } > > RefPtr<UniquedStringImpl> impl; >- StructureID structureID; >+ StructureID structureID { 0 }; > bool result { false }; > }; > >Index: Source/JavaScriptCore/runtime/InitializeThreading.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/InitializeThreading.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/InitializeThreading.cpp (working copy) >@@ -36,7 +36,6 @@ > #include "LLIntData.h" > #include "Options.h" > #include "SigillCrashAnalyzer.h" >-#include "StructureAlignedMemoryAllocator.h" > #include "SuperSampler.h" > #include "VMTraps.h" > #include "WasmCalleeRegistry.h" >@@ -66,7 +65,6 @@ void initialize() > #endif > { > Options::AllowUnfinalizedAccessScope scope; >- StructureAlignedMemoryAllocator::initializeStructureAddressSpace(); > JITOperationList::initialize(); > ExecutableAllocator::initialize(); > VM::computeCanUseJIT(); >Index: Source/JavaScriptCore/runtime/JSCConfig.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSCConfig.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSCConfig.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2019-2021 Apple Inc. All rights reserved. >+ * Copyright (C) 2019-2020 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -40,12 +40,6 @@ class VM; > using JITWriteSeparateHeapsFunction = void (*)(off_t, const void*, size_t); > #endif > >-#if PLATFORM(IOS_FAMILY) && CPU(ARM64) && !CPU(ARM64E) >-constexpr uintptr_t structureHeapAddressSize = 512 * MB; >-#else >-constexpr uintptr_t structureHeapAddressSize = 1 * GB; >-#endif >- > struct Config { > static Config& singleton(); > >@@ -87,7 +81,6 @@ struct Config { > void* startExecutableMemory; > void* endExecutableMemory; > uintptr_t startOfFixedWritableMemoryPool; >- uintptr_t startOfStructureHeap; > > #if ENABLE(SEPARATED_WX_HEAP) > JITWriteSeparateHeapsFunction jitWriteSeparateHeaps; >@@ -125,7 +118,6 @@ extern "C" JS_EXPORT_PRIVATE Config g_js > > constexpr size_t offsetOfJSCConfigInitializeHasBeenCalled = offsetof(JSC::Config, initializeHasBeenCalled); > constexpr size_t offsetOfJSCConfigGateMap = offsetof(JSC::Config, llint.gateMap); >-constexpr size_t offsetOfJSCConfigStartOfStructureHeap = offsetof(JSC::Config, startOfStructureHeap); > > } // namespace JSC > >Index: Source/JavaScriptCore/runtime/JSCJSValue.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSCJSValue.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/JSCJSValue.cpp (working copy) >@@ -320,7 +320,7 @@ void JSValue::dumpInContextAssumingStruc > out.print(" (", inContext(*structure, context), ")"); > } > #if USE(JSVALUE64) >- out.print(", StructureID: ", asCell()->structureID().bits()); >+ out.print(", StructureID: ", asCell()->structureID()); > #endif > } else if (isTrue()) > out.print("True"); >@@ -357,9 +357,15 @@ void JSValue::dumpForBacktrace(PrintStre > out.print("(unresolved string)"); > } else if (asCell()->inherits<Structure>(vm)) { > out.print("Structure[ ", asCell()->structure()->classInfo()->className); >+#if USE(JSVALUE64) >+ out.print(" ID: ", asCell()->structureID()); >+#endif > out.print("]: ", RawPointer(asCell())); > } else { > out.print("Cell[", asCell()->structure()->classInfo()->className); >+#if USE(JSVALUE64) >+ out.print(" ID: ", asCell()->structureID()); >+#endif > out.print("]: ", RawPointer(asCell())); > } > } else if (isTrue()) >Index: Source/JavaScriptCore/runtime/JSCell.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSCell.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/JSCell.cpp (working copy) >@@ -173,7 +173,7 @@ double JSCell::toNumber(JSGlobalObject* > > JSObject* JSCell::toObjectSlow(JSGlobalObject* globalObject) const > { >- Integrity::auditStructureID(structureID()); >+ Integrity::auditStructureID(globalObject->vm(), structureID()); > ASSERT(!isObject()); > if (isString()) > return static_cast<const JSString*>(this)->toObject(globalObject); >Index: Source/JavaScriptCore/runtime/JSCell.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSCell.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSCell.h (working copy) >@@ -135,7 +135,7 @@ public: > Structure* structure(VM&) const; > void setStructure(VM&, Structure*); > void setStructureIDDirectly(StructureID id) { m_structureID = id; } >- void clearStructure() { m_structureID = StructureID(); } >+ void clearStructure() { m_structureID = 0; } > > TypeInfo::InlineTypeFlags inlineTypeFlags() const { return m_flags; } > >Index: Source/JavaScriptCore/runtime/JSCellInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSCellInlines.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSCellInlines.h (working copy) >@@ -133,13 +133,12 @@ inline IndexingType JSCell::indexingMode > > ALWAYS_INLINE Structure* JSCell::structure() const > { >- return m_structureID.decode(); >+ return structure(vm()); > } > >-// FIXME: Delete this in a cleanup fixup. >-ALWAYS_INLINE Structure* JSCell::structure(VM&) const >+ALWAYS_INLINE Structure* JSCell::structure(VM& vm) const > { >- return structure(); >+ return vm.getStructure(m_structureID); > } > > template<typename Visitor> >@@ -305,7 +304,7 @@ ALWAYS_INLINE void JSCell::setStructure( > ASSERT(structure->classInfo() == this->structure(vm)->classInfo()); > ASSERT(!this->structure(vm) > || this->structure(vm)->transitionWatchpointSetHasBeenInvalidated() >- || structure->id().decode() == structure); >+ || Heap::heap(this)->structureIDTable().get(structure->id()) == structure); > m_structureID = structure->id(); > m_flags = TypeInfo::mergeInlineTypeFlags(structure->typeInfo().inlineTypeFlags(), m_flags); > m_type = structure->typeInfo().type(); >Index: Source/JavaScriptCore/runtime/JSGlobalObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSGlobalObject.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/JSGlobalObject.cpp (working copy) >@@ -2281,16 +2281,13 @@ void JSGlobalObject::visitChildrenImpl(J > for (auto& property : thisObject->m_linkTimeConstants) > property.visit(visitor); > >-#define VISIT_SIMPLE_TYPE_PROTOTYPE(CapitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) if (featureFlag) \ >+#define VISIT_SIMPLE_TYPE(CapitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) if (featureFlag) { \ > visitor.append(thisObject->m_ ## lowerName ## Prototype); \ >- >-#define VISIT_SIMPLE_TYPE_STRUCTURE(CapitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) if (featureFlag) \ > visitor.append(thisObject->m_ ## properName ## Structure); \ >+ } > >- FOR_EACH_SIMPLE_BUILTIN_TYPE(VISIT_SIMPLE_TYPE_STRUCTURE) >- FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(VISIT_SIMPLE_TYPE_STRUCTURE) >- FOR_EACH_SIMPLE_BUILTIN_TYPE(VISIT_SIMPLE_TYPE_PROTOTYPE) >- FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(VISIT_SIMPLE_TYPE_PROTOTYPE) >+ FOR_EACH_SIMPLE_BUILTIN_TYPE(VISIT_SIMPLE_TYPE) >+ FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(VISIT_SIMPLE_TYPE) > > #define VISIT_LAZY_TYPE(CapitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) if (featureFlag) \ > thisObject->m_ ## properName ## Structure.visit(visitor); >Index: Source/JavaScriptCore/runtime/JSGlobalObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSGlobalObject.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSGlobalObject.h (working copy) >@@ -376,7 +376,20 @@ public: > LazyProperty<JSGlobalObject, Structure> m_debuggerScopeStructure; > LazyProperty<JSGlobalObject, Structure> m_withScopeStructure; > LazyProperty<JSGlobalObject, Structure> m_strictEvalActivationStructure; >+ WriteBarrier<Structure> m_lexicalEnvironmentStructure; > LazyProperty<JSGlobalObject, Structure> m_moduleEnvironmentStructure; >+ WriteBarrier<Structure> m_directArgumentsStructure; >+ WriteBarrier<Structure> m_scopedArgumentsStructure; >+ WriteBarrier<Structure> m_clonedArgumentsStructure; >+ >+ WriteBarrier<Structure> m_objectStructureForObjectConstructor; >+ >+ // Lists the actual structures used for having these particular indexing shapes. >+ WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfArrayIndexingModes]; >+ // Lists the structures we should use during allocation for these particular indexing shapes. >+ // These structures will differ from the originals list above when we are having a bad time. >+ WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfArrayIndexingModes]; >+ > LazyProperty<JSGlobalObject, Structure> m_callbackConstructorStructure; > LazyProperty<JSGlobalObject, Structure> m_callbackFunctionStructure; > LazyProperty<JSGlobalObject, Structure> m_callbackObjectStructure; >@@ -388,57 +401,42 @@ public: > LazyProperty<JSGlobalObject, Structure> m_glibCallbackFunctionStructure; > LazyProperty<JSGlobalObject, Structure> m_glibWrapperObjectStructure; > #endif >+ WriteBarrier<Structure> m_nullPrototypeObjectStructure; >+ WriteBarrier<Structure> m_calleeStructure; > >- WriteBarrierStructureID m_lexicalEnvironmentStructure; >- WriteBarrierStructureID m_directArgumentsStructure; >- WriteBarrierStructureID m_scopedArgumentsStructure; >- WriteBarrierStructureID m_clonedArgumentsStructure; >- >- WriteBarrierStructureID m_objectStructureForObjectConstructor; >- >- // Lists the actual structures used for having these particular indexing shapes. >- WriteBarrierStructureID m_originalArrayStructureForIndexingShape[NumberOfArrayIndexingModes]; >- // Lists the structures we should use during allocation for these particular indexing shapes. >- // These structures will differ from the originals list above when we are having a bad time. >- WriteBarrierStructureID m_arrayStructureForIndexingShapeDuringAllocation[NumberOfArrayIndexingModes]; >- >- WriteBarrierStructureID m_nullPrototypeObjectStructure; >- WriteBarrierStructureID m_calleeStructure; >- >- WriteBarrierStructureID m_hostFunctionStructure; >+ WriteBarrier<Structure> m_hostFunctionStructure; > > struct FunctionStructures { >- WriteBarrierStructureID arrowFunctionStructure; >- WriteBarrierStructureID sloppyFunctionStructure; >- WriteBarrierStructureID strictFunctionStructure; >+ WriteBarrier<Structure> arrowFunctionStructure; >+ WriteBarrier<Structure> sloppyFunctionStructure; >+ WriteBarrier<Structure> strictFunctionStructure; > }; > FunctionStructures m_builtinFunctions; > FunctionStructures m_ordinaryFunctions; > >- PropertyOffset m_functionNameOffset; >- WriteBarrierStructureID m_shadowRealmObjectStructure; >- WriteBarrierStructureID m_regExpStructure; >- WriteBarrierStructureID m_asyncFunctionStructure; >- WriteBarrierStructureID m_asyncGeneratorFunctionStructure; >- WriteBarrierStructureID m_generatorFunctionStructure; >- WriteBarrierStructureID m_generatorStructure; >- WriteBarrierStructureID m_asyncGeneratorStructure; >- WriteBarrierStructureID m_arrayIteratorStructure; >- WriteBarrierStructureID m_mapIteratorStructure; >- WriteBarrierStructureID m_setIteratorStructure; >- WriteBarrierStructureID m_regExpMatchesArrayStructure; >- WriteBarrierStructureID m_regExpMatchesArrayWithIndicesStructure; >- WriteBarrierStructureID m_regExpMatchesIndicesArrayStructure; >- > LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure; > LazyProperty<JSGlobalObject, Structure> m_customGetterFunctionStructure; > LazyProperty<JSGlobalObject, Structure> m_customSetterFunctionStructure; > LazyProperty<JSGlobalObject, Structure> m_nativeStdFunctionStructure; >+ PropertyOffset m_functionNameOffset; >+ WriteBarrier<Structure> m_shadowRealmObjectStructure; >+ WriteBarrier<Structure> m_regExpStructure; > WriteBarrier<AsyncFunctionPrototype> m_asyncFunctionPrototype; > WriteBarrier<AsyncGeneratorFunctionPrototype> m_asyncGeneratorFunctionPrototype; >+ WriteBarrier<Structure> m_asyncFunctionStructure; >+ WriteBarrier<Structure> m_asyncGeneratorFunctionStructure; >+ WriteBarrier<Structure> m_generatorFunctionStructure; >+ WriteBarrier<Structure> m_generatorStructure; >+ WriteBarrier<Structure> m_asyncGeneratorStructure; >+ WriteBarrier<Structure> m_arrayIteratorStructure; >+ WriteBarrier<Structure> m_mapIteratorStructure; >+ WriteBarrier<Structure> m_setIteratorStructure; > LazyProperty<JSGlobalObject, Structure> m_iteratorResultObjectStructure; > LazyProperty<JSGlobalObject, Structure> m_dataPropertyDescriptorObjectStructure; > LazyProperty<JSGlobalObject, Structure> m_accessorPropertyDescriptorObjectStructure; >+ WriteBarrier<Structure> m_regExpMatchesArrayStructure; >+ WriteBarrier<Structure> m_regExpMatchesArrayWithIndicesStructure; >+ WriteBarrier<Structure> m_regExpMatchesIndicesArrayStructure; > LazyProperty<JSGlobalObject, Structure> m_moduleRecordStructure; > LazyProperty<JSGlobalObject, Structure> m_moduleNamespaceObjectStructure; > LazyProperty<JSGlobalObject, Structure> m_proxyObjectStructure; >@@ -446,19 +444,15 @@ public: > LazyProperty<JSGlobalObject, Structure> m_proxyRevokeStructure; > LazyClassStructure m_sharedArrayBufferStructure; > >-#define DEFINE_STORAGE_FOR_SIMPLE_TYPE_PROTOTYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) \ >- WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; >- >-#define DEFINE_STORAGE_FOR_SIMPLE_TYPE_STRUCTURE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) \ >- WriteBarrierStructureID m_ ## properName ## Structure; >+#define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) \ >+ WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \ >+ WriteBarrier<Structure> m_ ## properName ## Structure; > > #define DEFINE_STORAGE_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase, featureFlag) \ > LazyClassStructure m_ ## properName ## Structure; > >- FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE_STRUCTURE) >- FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE_STRUCTURE) >- FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE_PROTOTYPE) >- FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE_PROTOTYPE) >+ FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) >+ FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) > > #if ENABLE(WEBASSEMBLY) > LazyProperty<JSGlobalObject, Structure> m_webAssemblyModuleRecordStructure; >@@ -470,8 +464,7 @@ public: > > FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_STORAGE_FOR_LAZY_TYPE) > >-#undef DEFINE_STORAGE_FOR_SIMPLE_TYPE_PROTOTYPE >-#undef DEFINE_STORAGE_FOR_SIMPLE_TYPE_STRUCTURE >+#undef DEFINE_STORAGE_FOR_SIMPLE_TYPE > #undef DEFINE_STORAGE_FOR_LAZY_TYPE > > WriteBarrier<GetterSetter> m_speciesGetterSetter; >@@ -581,7 +574,6 @@ public: > > bool m_evalEnabled { true }; > bool m_webAssemblyEnabled { true }; >- bool m_needsSiteSpecificQuirks { false }; > unsigned m_globalLexicalBindingEpoch { 1 }; > String m_evalDisabledErrorMessage; > String m_webAssemblyDisabledErrorMessage; >@@ -1202,6 +1194,7 @@ private: > > JS_EXPORT_PRIVATE static void clearRareData(JSCell*); > >+ bool m_needsSiteSpecificQuirks { false }; > #if JSC_OBJC_API_ENABLED > RetainPtr<JSWrapperMap> m_wrapperMap; > #endif >Index: Source/JavaScriptCore/runtime/JSObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSObject.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/JSObject.cpp (working copy) >@@ -369,9 +369,9 @@ ALWAYS_INLINE Structure* JSObject::visit > // https://pdfs.semanticscholar.org/343f/7182cde7669ca2a7de3dc01127927f384ef7.pdf > > StructureID structureID = this->structureID(); >- if (structureID.isNuked()) >+ if (isNuked(structureID)) > return nullptr; >- structure = structureID.decode(); >+ structure = vm.getStructure(structureID); > maxOffset = structure->maxOffset(); > IndexingType indexingMode; > Dependency indexingModeDependency = structure->fencedIndexingMode(indexingMode); >@@ -1169,7 +1169,7 @@ Butterfly* JSObject::createInitialUndeci > DeferGC deferGC(vm); > Butterfly* newButterfly = createInitialIndexedStorage(vm, length); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateUndecided); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1183,7 +1183,7 @@ ContiguousJSValues JSObject::createIniti > for (unsigned i = newButterfly->vectorLength(); i--;) > newButterfly->contiguous().at(this, i).setWithoutWriteBarrier(JSValue()); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateInt32); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1197,7 +1197,7 @@ ContiguousDoubles JSObject::createInitia > for (unsigned i = newButterfly->vectorLength(); i--;) > newButterfly->contiguousDouble().at(this, i) = PNaN; > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateDouble); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1211,7 +1211,7 @@ ContiguousJSValues JSObject::createIniti > for (unsigned i = newButterfly->vectorLength(); i--;) > newButterfly->contiguous().at(this, i).setWithoutWriteBarrier(JSValue()); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateContiguous); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1241,7 +1241,7 @@ ArrayStorage* JSObject::createArrayStora > { > DeferGC deferGC(vm); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > IndexingType oldType = indexingType(); > ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType)); > >@@ -1331,7 +1331,7 @@ ArrayStorage* JSObject::convertUndecided > storage->m_vector[i].setWithoutWriteBarrier(JSValue()); > > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > nukeStructureAndSetButterfly(vm, oldStructureID, storage->butterfly()); > setStructure(vm, newStructure); >@@ -1390,7 +1390,7 @@ ArrayStorage* JSObject::convertInt32ToAr > } > > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly()); > setStructure(vm, newStructure); >@@ -1444,7 +1444,7 @@ ArrayStorage* JSObject::convertDoubleToA > } > > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly()); > setStructure(vm, newStructure); >@@ -1522,7 +1522,7 @@ ArrayStorage* JSObject::convertContiguou > > ASSERT(newStorage->butterfly() != butterfly); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = oldStructureID.decode(); >+ Structure* oldStructure = vm.getStructure(oldStructureID); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > > // Ensure new Butterfly initialization is correctly done before exposing it to the concurrent threads. >@@ -2024,7 +2024,7 @@ void JSObject::putDirectCustomGetterSett > ASSERT(attributes & PropertyAttribute::CustomAccessorOrValue); > > StructureID structureID = this->structureID(); >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(structureID); > PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure); > putDirect(vm, offset, value); > >@@ -2051,7 +2051,7 @@ void JSObject::putDirectNonIndexAccessor > { > ASSERT(attributes & PropertyAttribute::Accessor); > StructureID structureID = this->structureID(); >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(structureID); > PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure); > putDirect(vm, offset, accessor); > if (attributes & PropertyAttribute::ReadOnly) >Index: Source/JavaScriptCore/runtime/JSObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSObject.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSObject.h (working copy) >@@ -1367,7 +1367,7 @@ inline void JSObject::setButterfly(VM& v > inline void JSObject::nukeStructureAndSetButterfly(VM& vm, StructureID oldStructureID, Butterfly* butterfly) > { > if (isX86() || vm.heap.mutatorShouldBeFenced()) { >- setStructureIDDirectly(oldStructureID.nuke()); >+ setStructureIDDirectly(nuke(oldStructureID)); > WTF::storeStoreFence(); > m_butterfly.set(vm, this, butterfly); > WTF::storeStoreFence(); >@@ -1500,6 +1500,7 @@ template<bool checkNullStructure> > ALWAYS_INLINE bool JSObject::getPropertySlot(JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot) > { > VM& vm = getVM(globalObject); >+ auto& structureIDTable = vm.heap.structureIDTable(); > JSObject* object = this; > while (true) { > if (UNLIKELY(TypeInfo::overridesGetOwnPropertySlot(object->inlineTypeFlags()))) { >@@ -1514,10 +1515,10 @@ ALWAYS_INLINE bool JSObject::getProperty > return object->getNonIndexPropertySlot(globalObject, propertyName, slot); > } > ASSERT(object->type() != ProxyObjectType); >- Structure* structure = object->structureID().decode(); >+ Structure* structure = structureIDTable.get(object->structureID()); > #if USE(JSVALUE64) > if (checkNullStructure && UNLIKELY(!structure)) >- CRASH_WITH_INFO(object->type(), object->structureID().bits()); >+ CRASH_WITH_INFO(object->type(), object->structureID(), structureIDTable.size()); > #endif > if (object->getOwnNonIndexPropertySlot(vm, structure, propertyName, slot)) > return true; >Index: Source/JavaScriptCore/runtime/JSObjectInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSObjectInlines.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSObjectInlines.h (working copy) >@@ -110,9 +110,10 @@ ALWAYS_INLINE bool JSObject::getProperty > { > VM& vm = getVM(globalObject); > auto scope = DECLARE_THROW_SCOPE(vm); >+ auto& structureIDTable = vm.heap.structureIDTable(); > JSObject* object = this; > while (true) { >- Structure* structure = object->structureID().decode(); >+ Structure* structure = structureIDTable.get(object->structureID()); > bool hasSlot = structure->classInfo()->methodTable.getOwnPropertySlotByIndex(object, globalObject, propertyName, slot); > RETURN_IF_EXCEPTION(scope, false); > if (hasSlot) >@@ -150,9 +151,10 @@ ALWAYS_INLINE bool JSObject::getNonIndex > > VM& vm = getVM(globalObject); > auto scope = DECLARE_THROW_SCOPE(vm); >+ auto& structureIDTable = vm.heap.structureIDTable(); > JSObject* object = this; > while (true) { >- Structure* structure = object->structureID().decode(); >+ Structure* structure = structureIDTable.get(object->structureID()); > if (LIKELY(!TypeInfo::overridesGetOwnPropertySlot(object->inlineTypeFlags()))) { > if (object->getOwnNonIndexPropertySlot(vm, structure, propertyName, slot)) > return true; >@@ -217,7 +219,7 @@ inline void JSObject::putDirectWithoutTr > ASSERT(!value.isGetterSetter() && !(attributes & PropertyAttribute::Accessor)); > ASSERT(!value.isCustomGetterSetter()); > StructureID structureID = this->structureID(); >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(structureID); > PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure); > putDirect(vm, offset, value); > if (attributes & PropertyAttribute::ReadOnly) >@@ -326,7 +328,7 @@ ALWAYS_INLINE ASCIILiteral JSObject::put > ASSERT(!parseIndex(propertyName)); > > StructureID structureID = this->structureID(); >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.heap.structureIDTable().get(structureID); > if (structure->isDictionary()) { > ASSERT(!isCopyOnWrite(indexingMode())); > >Index: Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp (working copy) >@@ -50,7 +50,7 @@ JSPropertyNameEnumerator* JSPropertyName > JSPropertyNameEnumerator::JSPropertyNameEnumerator(VM& vm, Structure* structure, uint32_t indexedLength, uint32_t numberStructureProperties, WriteBarrier<JSString>* propertyNamesBuffer, unsigned propertyNamesSize) > : JSCell(vm, vm.propertyNameEnumeratorStructure.get()) > , m_propertyNames(vm, this, propertyNamesBuffer) >- , m_cachedStructureID(vm, this, structure, WriteBarrierStructureID::MayBeNull) >+ , m_cachedStructureID(structure ? structure->id() : 0) > , m_indexedLength(indexedLength) > , m_endStructurePropertyIndex(numberStructureProperties) > , m_endGenericPropertyIndex(propertyNamesSize) >@@ -86,7 +86,11 @@ void JSPropertyNameEnumerator::visitChil > visitor.markAuxiliary(propertyNames); > visitor.append(propertyNames, propertyNames + thisObject->sizeOfPropertyNames()); > } >- visitor.append(thisObject->m_cachedStructureID); >+ >+ if (thisObject->cachedStructureID()) { >+ VM& vm = visitor.vm(); >+ visitor.appendUnbarriered(vm.getStructure(thisObject->cachedStructureID())); >+ } > } > > DEFINE_VISIT_CHILDREN(JSPropertyNameEnumerator); >Index: Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h (revision 286965) >+++ Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h (working copy) >@@ -72,10 +72,11 @@ public: > > Structure* cachedStructure(VM& vm) const > { >- UNUSED_PARAM(vm); >- return m_cachedStructureID.get(); >+ if (!m_cachedStructureID) >+ return nullptr; >+ return vm.heap.structureIDTable().get(m_cachedStructureID); > } >- StructureID cachedStructureID() const { return m_cachedStructureID.value(); } >+ StructureID cachedStructureID() const { return m_cachedStructureID; } > uint32_t indexedLength() const { return m_indexedLength; } > uint32_t endStructurePropertyIndex() const { return m_endStructurePropertyIndex; } > uint32_t endGenericPropertyIndex() const { return m_endGenericPropertyIndex; } >@@ -106,7 +107,7 @@ private: > // JSPropertyNameEnumerator is immutable data structure, which allows VM to cache the empty one. > // After instantiating JSPropertyNameEnumerator, we must not change any fields. > AuxiliaryBarrier<WriteBarrier<JSString>*> m_propertyNames; >- WriteBarrierStructureID m_cachedStructureID; >+ StructureID m_cachedStructureID; > uint32_t m_indexedLength; > uint32_t m_endStructurePropertyIndex; > uint32_t m_endGenericPropertyIndex; >Index: Source/JavaScriptCore/runtime/NumberPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/NumberPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/NumberPrototype.cpp (working copy) >@@ -94,7 +94,7 @@ static ALWAYS_INLINE bool toThisNumber(V > } > > if (auto* numberObject = jsDynamicCast<NumberObject*>(vm, thisValue)) { >- Integrity::auditStructureID(numberObject->structureID()); >+ Integrity::auditStructureID(vm, numberObject->structureID()); > x = numberObject->internalValue().asNumber(); > return true; > } >Index: Source/JavaScriptCore/runtime/ObjectPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ObjectPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/ObjectPrototype.cpp (working copy) >@@ -85,7 +85,7 @@ JSC_DEFINE_HOST_FUNCTION(objectProtoFunc > JSObject* valueObj = thisValue.toObject(globalObject); > if (UNLIKELY(!valueObj)) > return encodedJSValue(); >- Integrity::auditStructureID(valueObj->structureID()); >+ Integrity::auditStructureID(globalObject->vm(), valueObj->structureID()); > return JSValue::encode(valueObj); > } > >@@ -361,7 +361,7 @@ JSString* objectPrototypeToString(JSGlob > JSObject* thisObject = thisValue.toObject(globalObject); > RETURN_IF_EXCEPTION(scope, nullptr); > >- Integrity::auditStructureID(thisObject->structureID()); >+ Integrity::auditStructureID(vm, thisObject->structureID()); > auto result = thisObject->structure(vm)->cachedSpecialProperty(CachedSpecialPropertyKey::ToStringTag); > if (result) > return asString(result); >Index: Source/JavaScriptCore/runtime/RegExpPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/RegExpPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/RegExpPrototype.cpp (working copy) >@@ -199,7 +199,7 @@ JSC_DEFINE_HOST_FUNCTION(regExpProtoFunc > return throwVMTypeError(globalObject, scope); > > JSObject* thisObject = asObject(thisValue); >- Integrity::auditStructureID(thisObject->structureID()); >+ Integrity::auditStructureID(vm, thisObject->structureID()); > > StringRecursionChecker checker(globalObject, thisObject); > EXCEPTION_ASSERT(!scope.exception() || checker.earlyReturnValue()); >Index: Source/JavaScriptCore/runtime/StringPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/StringPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/StringPrototype.cpp (working copy) >@@ -960,7 +960,7 @@ JSC_DEFINE_HOST_FUNCTION(stringProtoFunc > // Also used for valueOf. > > if (thisValue.isString()) { >- Integrity::auditStructureID(thisValue.asCell()->structureID()); >+ Integrity::auditStructureID(vm, thisValue.asCell()->structureID()); > return JSValue::encode(thisValue); > } > >@@ -968,7 +968,7 @@ JSC_DEFINE_HOST_FUNCTION(stringProtoFunc > if (!stringObject) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(stringObject->structureID()); >+ Integrity::auditStructureID(vm, stringObject->structureID()); > return JSValue::encode(stringObject->internalValue()); > } > >Index: Source/JavaScriptCore/runtime/Structure.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/Structure.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/Structure.cpp (working copy) >@@ -197,7 +197,7 @@ inline void Structure::validateFlags() { > > Structure::Structure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity) > : JSCell(vm, vm.structureStructure.get()) >- , m_blob(StructureID::encode(this), indexingType, typeInfo) >+ , m_blob(vm.heap.structureIDTable().allocateID(this), indexingType, typeInfo) > , m_outOfLineTypeFlags(typeInfo.outOfLineTypeFlags()) > , m_inlineCapacity(inlineCapacity) > , m_bitField(0) >@@ -264,7 +264,7 @@ Structure::Structure(VM& vm, CreatingEar > setMaxOffset(vm, invalidOffset); > > TypeInfo typeInfo = TypeInfo(StructureType, StructureFlags); >- m_blob = StructureIDBlob(StructureID::encode(this), 0, typeInfo); >+ m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo); > m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags(); > > ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); >@@ -301,7 +301,7 @@ Structure::Structure(VM& vm, Structure* > setMaxOffset(vm, invalidOffset); > > TypeInfo typeInfo = previous->typeInfo(); >- m_blob = StructureIDBlob(StructureID::encode(this), previous->indexingModeIncludingHistory(), typeInfo); >+ m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingModeIncludingHistory(), typeInfo); > m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags(); > > ASSERT(!previous->typeInfo().structureIsImmortal()); >@@ -326,6 +326,7 @@ Structure::~Structure() > > if (isBrandedStructure()) > static_cast<BrandedStructure*>(this)->destruct(); >+ Heap::heap(this)->structureIDTable().deallocateID(this, m_blob.structureID()); > } > > void Structure::destroy(JSCell* cell) >@@ -909,7 +910,7 @@ Structure* Structure::flattenDictionaryS > > GCSafeConcurrentJSLocker locker(m_lock, vm); > >- object->setStructureIDDirectly(id().nuke()); >+ object->setStructureIDDirectly(nuke(id())); > WTF::storeStoreFence(); > > size_t beforeOutOfLineCapacity = this->outOfLineCapacity(); >@@ -1369,7 +1370,7 @@ Ref<StructureShape> Structure::toStructu > > void Structure::dump(PrintStream& out) const > { >- auto* structureID = reinterpret_cast<void*>(id().bits()); >+ auto* structureID = reinterpret_cast<void*>(id()); > out.print(RawPointer(this), ":[", RawPointer(structureID), > "/", (uint32_t)(reinterpret_cast<uintptr_t>(structureID)), ", ", > classInfo()->className, ", (", inlineSize(), "/", inlineCapacity(), ", ", >@@ -1469,7 +1470,7 @@ uintptr_t Structure::cachedPropertyNameE > return rareData()->cachedPropertyNameEnumeratorAndFlag(); > } > >-bool Structure::canCachePropertyNameEnumerator(VM&) const >+bool Structure::canCachePropertyNameEnumerator(VM& vm) const > { > if (!this->canCacheOwnPropertyNames()) > return false; >@@ -1481,7 +1482,7 @@ bool Structure::canCachePropertyNameEnum > StructureID structureID = *currentStructureID; > if (!structureID) > return true; >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.getStructure(structureID); > if (!structure->canCacheOwnPropertyNames()) > return false; > currentStructureID++; >Index: Source/JavaScriptCore/runtime/Structure.h >=================================================================== >--- Source/JavaScriptCore/runtime/Structure.h (revision 286965) >+++ Source/JavaScriptCore/runtime/Structure.h (working copy) >@@ -118,7 +118,6 @@ public: > > typedef JSCell Base; > static constexpr unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; >- static constexpr uint8_t numberOfLowerTierCells = 0; > > enum PolyProtoTag { PolyProto }; > static Structure* create(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0); >@@ -165,7 +164,7 @@ private: > void validateFlags(); > > public: >- StructureID id() const { ASSERT(m_blob.structureID() == StructureID::encode(this)); return m_blob.structureID(); } >+ StructureID id() const { return m_blob.structureID(); } > int32_t objectInitializationBlob() const { return m_blob.blobExcludingStructureID(); } > int64_t idBlob() const { return m_blob.blob(); } > >Index: Source/JavaScriptCore/runtime/StructureChain.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/StructureChain.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/StructureChain.cpp (working copy) >@@ -49,7 +49,6 @@ StructureChain* StructureChain::create(V > ++size; // Sentinel nullptr. > size_t bytes = Checked<size_t>(size) * sizeof(StructureID); > void* vector = vm.jsValueGigacageAuxiliarySpace().allocate(vm, bytes, nullptr, AllocationFailureMode::Assert); >- static_assert(!StructureID().bits(), "Make sure the value we're going to memcpy below matches the default StructureID"); > memset(vector, 0, bytes); > StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm)) StructureChain(vm, vm.structureChainStructure.get(), static_cast<StructureID*>(vector)); > chain->finishCreation(vm, head); >@@ -74,9 +73,10 @@ void StructureChain::visitChildrenImpl(J > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); > Base::visitChildren(thisObject, visitor); > visitor.markAuxiliary(thisObject->m_vector.get()); >+ VM& vm = visitor.vm(); > for (auto* current = thisObject->m_vector.get(); *current; ++current) { > StructureID structureID = *current; >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.getStructure(structureID); > visitor.appendUnbarriered(structure); > } > } >Index: Source/JavaScriptCore/runtime/StructureID.h >=================================================================== >--- Source/JavaScriptCore/runtime/StructureID.h (revision 286965) >+++ Source/JavaScriptCore/runtime/StructureID.h (nonexistent) >@@ -1,120 +0,0 @@ >-/* >- * Copyright (C) 2013-2021 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "JSCConfig.h" >-#include <wtf/HashTraits.h> >-#include <wtf/StdIntExtras.h> >- >-namespace JSC { >- >-class Structure; >- >-constexpr CPURegister structureIDMask = structureHeapAddressSize - 1; >- >-class StructureID { >-public: >- static constexpr uint32_t nukedStructureIDBit = 1; >- >- StructureID() = default; >- StructureID(StructureID const&) = default; >- StructureID& operator=(StructureID const&) = default; >- >- StructureID nuke() const { return StructureID(m_bits | nukedStructureIDBit); } >- bool isNuked() const { return m_bits & nukedStructureIDBit; } >- StructureID decontaminate() const { return StructureID(m_bits & ~nukedStructureIDBit); } >- >- inline Structure* decode() const; >- static StructureID encode(const Structure*); >- >- explicit operator bool() const { return !!m_bits; } >- bool operator==(StructureID const& other) const { return m_bits == other.m_bits; } >- bool operator!=(StructureID const& other) const { return m_bits != other.m_bits; } >- constexpr uint32_t bits() const { return m_bits; } >- >- StructureID(WTF::HashTableDeletedValueType) : m_bits(nukedStructureIDBit) { } >- bool isHashTableDeletedValue() const { return *this == StructureID(WTF::HashTableDeletedValue); } >- >-private: >- explicit StructureID(uint32_t bits) : m_bits(bits) { } >- >- uint32_t m_bits { 0 }; >-}; >-static_assert(sizeof(StructureID) == sizeof(uint32_t)); >- >-#if CPU(ADDRESS64) >- >-ALWAYS_INLINE Structure* StructureID::decode() const >-{ >- // Take care to only use the bits from m_bits in the structure's address reservation. >- ASSERT(decontaminate()); >- return reinterpret_cast<Structure*>((static_cast<uintptr_t>(decontaminate().m_bits) & structureIDMask) + g_jscConfig.startOfStructureHeap); >-} >- >-ALWAYS_INLINE StructureID StructureID::encode(const Structure* structure) >-{ >- ASSERT(structure); >- ASSERT(g_jscConfig.startOfStructureHeap <= reinterpret_cast<uintptr_t>(structure) && reinterpret_cast<uintptr_t>(structure) < g_jscConfig.startOfStructureHeap + structureHeapAddressSize); >- auto result = StructureID(reinterpret_cast<uintptr_t>(structure) & structureIDMask); >- ASSERT(result.decode() == structure); >- return result; >-} >- >-#else // CPU(ADDRESS64) >- >-ALWAYS_INLINE Structure* StructureID::decode() const >-{ >- ASSERT(decontaminate()); >- return reinterpret_cast<Structure*>(m_bits); >-} >- >-ALWAYS_INLINE StructureID StructureID::encode(const Structure* structure) >-{ >- ASSERT(structure); >- return StructureID(reinterpret_cast<uint32_t>(structure)); >-} >- >-#endif >- >-struct StructureIDHash { >- static unsigned hash(const StructureID& key) { return key.bits(); } >- static bool equal(const StructureID& a, const StructureID& b) { return a == b; } >- static constexpr bool safeToCompareToEmptyOrDeleted = true; >-}; >- >-} // namespace JSC >- >-namespace WTF { >- >-template<typename T> struct DefaultHash; >-template<> struct DefaultHash<JSC::StructureID> : JSC::StructureIDHash { }; >- >-template<typename T> struct HashTraits; >-template<> struct HashTraits<JSC::StructureID> : SimpleClassHashTraits<JSC::StructureID> { >- static constexpr bool emptyValueIsZero = true; >-}; >- >-} >Index: Source/JavaScriptCore/runtime/StructureIDBlob.h >=================================================================== >--- Source/JavaScriptCore/runtime/StructureIDBlob.h (revision 286965) >+++ Source/JavaScriptCore/runtime/StructureIDBlob.h (working copy) >@@ -28,14 +28,17 @@ > #include "CellState.h" > #include "IndexingType.h" > #include "JSTypeInfo.h" >-#include "StructureID.h" >+#include "StructureIDTable.h" > > namespace JSC { > > class StructureIDBlob { > friend class LLIntOffsetsExtractor; > public: >- StructureIDBlob() = default; >+ StructureIDBlob() >+ { >+ u.doubleWord = 0xbbadbeef; >+ } > > StructureIDBlob(StructureID structureID, IndexingType indexingModeIncludingHistory, const TypeInfo& typeInfo) > { >@@ -74,9 +77,8 @@ public: > } > > private: >- union Data { >+ union { > struct { >- // FIXME: We should remove this since the structureID can be directly computed from the Structure* > StructureID structureID; > IndexingType indexingModeIncludingHistory; > JSType type; >@@ -88,11 +90,7 @@ private: > int32_t word2; > } words; > int64_t doubleWord; >- >- Data() { doubleWord = 0xbbadbeef; } >- }; >- >- Data u; >+ } u; > }; > > } // namespace JSC >Index: Source/JavaScriptCore/runtime/StructureIDTable.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/StructureIDTable.cpp (nonexistent) >+++ Source/JavaScriptCore/runtime/StructureIDTable.cpp (working copy) >@@ -0,0 +1,204 @@ >+/* >+ * Copyright (C) 2013-2021 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "StructureIDTable.h" >+ >+#include "ResourceExhaustion.h" >+#include <wtf/Atomics.h> >+#include <wtf/DataLog.h> >+#include <wtf/RawPointer.h> >+ >+namespace JSC { >+ >+#if USE(JSVALUE64) >+ >+namespace StructureIDTableInternal { >+static constexpr bool verbose = false; >+} >+ >+StructureIDTable::StructureIDTable() >+ : m_table(makeUniqueArray<StructureOrOffset>(s_initialSize)) >+ , m_size(1) >+ , m_capacity(s_initialSize) >+{ >+ // We pre-allocate the first offset so that the null Structure >+ // can still be represented as the StructureID '0'. >+ table()[0].encodedStructureBits = 0; >+ >+ makeFreeListFromRange(1, m_capacity - 1); >+} >+ >+void StructureIDTable::makeFreeListFromRange(uint32_t first, uint32_t last) >+{ >+ ASSERT(!m_firstFreeOffset); >+ ASSERT(!m_lastFreeOffset); >+ >+ // Put all the new IDs on the free list sequentially. >+ uint32_t head = first; >+ uint32_t tail = last; >+ for (uint32_t i = first; i < last; ++i) >+ table()[i].offset = i + 1; >+ table()[last].offset = 0; >+ >+ // Randomize the free list. >+ uint32_t size = last - first + 1; >+ uint32_t maxIterations = (size * 2) / 3; >+ for (uint32_t count = 0; count < maxIterations; ++count) { >+ // Move a random pick either to the head or the tail of the free list. >+ uint32_t random = m_weakRandom.getUint32(); >+ uint32_t nodeBefore = first + (random % size); >+ uint32_t pick = table()[nodeBefore].offset; >+ if (pick) { >+ uint32_t nodeAfter = table()[pick].offset; >+ table()[nodeBefore].offset = nodeAfter; >+ if ((random & 1) || !nodeAfter) { >+ // Move to the head. >+ table()[pick].offset = head; >+ head = pick; >+ if (!nodeAfter) >+ tail = nodeBefore; >+ } else { >+ // Move to the tail. >+ table()[pick].offset = 0; >+ table()[tail].offset = pick; >+ tail = pick; >+ } >+ } >+ } >+ >+ // Cut list in half and swap halves. >+ uint32_t cut = first + (m_weakRandom.getUint32() % size); >+ uint32_t afterCut = table()[cut].offset; >+ if (afterCut) { >+ table()[tail].offset = head; >+ tail = cut; >+ head = afterCut; >+ table()[cut].offset = 0; >+ } >+ >+ m_firstFreeOffset = head; >+ m_lastFreeOffset = tail; >+} >+ >+void StructureIDTable::resize(size_t newCapacity) >+{ >+ if (newCapacity > s_maximumNumberOfStructures) >+ newCapacity = s_maximumNumberOfStructures; >+ >+ // If m_size is already s_maximumNumberOfStructures, newCapacity becomes s_maximumNumberOfStructures in the above code. >+ // In that case, we should crash because of exhaust of StructureIDs. >+ RELEASE_ASSERT_RESOURCE_AVAILABLE(m_size < newCapacity, StructureIDExhaustion, "Crash intentionally because of exhaust of StructureIDs."); >+ >+ // Create the new table. >+ auto newTable = makeUniqueArray<StructureOrOffset>(newCapacity); >+ >+ // Copy the contents of the old table to the new table. >+ memcpy(newTable.get(), table(), m_capacity * sizeof(StructureOrOffset)); >+ >+ // Store fence to make sure we've copied everything before doing the swap. >+ WTF::storeStoreFence(); >+ >+ // Swap the old and new tables. >+ swap(m_table, newTable); >+ >+ // Put the old table (now labeled as new) into the list of old tables. >+ m_oldTables.append(WTFMove(newTable)); >+ >+ // Update the capacity. >+ m_capacity = newCapacity; >+ >+ makeFreeListFromRange(m_size, m_capacity - 1); >+} >+ >+void StructureIDTable::flushOldTables() >+{ >+ m_oldTables.clear(); >+} >+ >+StructureID StructureIDTable::allocateID(Structure* structure) >+{ >+ if (UNLIKELY(!m_firstFreeOffset)) { >+ RELEASE_ASSERT(m_capacity <= s_maximumNumberOfStructures); >+ ASSERT(m_size == m_capacity); >+ resize(m_capacity * 2); >+ ASSERT(m_size < m_capacity); >+ RELEASE_ASSERT(m_firstFreeOffset); >+ } >+ >+ // entropyBits must not be zero. This ensures that if a corrupted >+ // structureID is encountered (with incorrect entropyBits), the decoded >+ // structure pointer for that ID will be always be a bad pointer with >+ // high bits set. >+ constexpr uint32_t entropyBitsMask = (1 << s_numberOfEntropyBits) - 1; >+ uint32_t entropyBits = m_weakRandom.getUint32() & entropyBitsMask; >+ if (UNLIKELY(!entropyBits)) { >+ constexpr uint32_t numberOfValuesToPickFrom = entropyBitsMask; >+ entropyBits = (m_weakRandom.getUint32() % numberOfValuesToPickFrom) + 1; >+ } >+ >+ uint32_t structureIndex = m_firstFreeOffset; >+ m_firstFreeOffset = table()[m_firstFreeOffset].offset; >+ if (!m_firstFreeOffset) >+ m_lastFreeOffset = 0; >+ >+ StructureID result = (structureIndex << s_numberOfEntropyBits) | entropyBits; >+ table()[structureIndex].encodedStructureBits = encode(structure, result); >+ m_size++; >+ ASSERT(!isNuked(result)); >+ >+ dataLogLnIf(StructureIDTableInternal::verbose, "Allocated StructureID ", result, " for Structure ", RawPointer(structure)); >+ return result; >+} >+ >+void StructureIDTable::deallocateID(Structure* structure, StructureID structureID) >+{ >+ dataLogLnIf(StructureIDTableInternal::verbose, "Deallocated StructureID ", structureID); >+ ASSERT(structureID != s_unusedID); >+ uint32_t structureIndex = structureID >> s_numberOfEntropyBits; >+ ASSERT(structureIndex && structureIndex < s_maximumNumberOfStructures); >+ RELEASE_ASSERT(table()[structureIndex].encodedStructureBits == encode(structure, structureID)); >+ m_size--; >+ if (!m_firstFreeOffset) { >+ table()[structureIndex].offset = 0; >+ m_firstFreeOffset = structureIndex; >+ m_lastFreeOffset = structureIndex; >+ return; >+ } >+ >+ bool insertAtHead = m_weakRandom.getUint32() & 1; >+ if (insertAtHead) { >+ table()[structureIndex].offset = m_firstFreeOffset; >+ m_firstFreeOffset = structureIndex; >+ } else { >+ table()[structureIndex].offset = 0; >+ table()[m_lastFreeOffset].offset = structureIndex; >+ m_lastFreeOffset = structureIndex; >+ } >+} >+ >+#endif // USE(JSVALUE64) >+ >+} // namespace JSC >Index: Source/JavaScriptCore/runtime/StructureIDTable.h >=================================================================== >--- Source/JavaScriptCore/runtime/StructureIDTable.h (nonexistent) >+++ Source/JavaScriptCore/runtime/StructureIDTable.h (working copy) >@@ -0,0 +1,225 @@ >+/* >+ * Copyright (C) 2013-2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "EnsureStillAliveHere.h" >+#include "UnusedPointer.h" >+#include <wtf/UniqueArray.h> >+#include <wtf/Vector.h> >+#include <wtf/WeakRandom.h> >+ >+namespace JSC { >+ >+class Structure; >+ >+#if USE(JSVALUE64) >+using StructureID = uint32_t; >+ >+inline StructureID nukedStructureIDBit() >+{ >+ return 0x80000000u; >+} >+ >+inline StructureID nuke(StructureID id) >+{ >+ return id | nukedStructureIDBit(); >+} >+ >+inline bool isNuked(StructureID id) >+{ >+ return !!(id & nukedStructureIDBit()); >+} >+ >+inline StructureID decontaminate(StructureID id) >+{ >+ return id & ~nukedStructureIDBit(); >+} >+#else // not USE(JSVALUE64) >+using StructureID = Structure*; >+ >+inline StructureID nukedStructureIDBit() >+{ >+ return bitwise_cast<StructureID>(static_cast<uintptr_t>(1)); >+} >+ >+inline StructureID nuke(StructureID id) >+{ >+ return bitwise_cast<StructureID>(bitwise_cast<uintptr_t>(id) | bitwise_cast<uintptr_t>(nukedStructureIDBit())); >+} >+ >+inline bool isNuked(StructureID id) >+{ >+ return !!(bitwise_cast<uintptr_t>(id) & bitwise_cast<uintptr_t>(nukedStructureIDBit())); >+} >+ >+inline StructureID decontaminate(StructureID id) >+{ >+ return bitwise_cast<StructureID>(bitwise_cast<uintptr_t>(id) & ~bitwise_cast<uintptr_t>(nukedStructureIDBit())); >+} >+#endif // not USE(JSVALUE64) >+ >+#if USE(JSVALUE64) >+ >+using EncodedStructureBits = uintptr_t; >+ >+class StructureIDTable { >+ friend class LLIntOffsetsExtractor; >+public: >+ StructureIDTable(); >+ >+ void** base() { return reinterpret_cast<void**>(&m_table); } >+ >+ ALWAYS_INLINE void validate(StructureID); >+ >+ // FIXME: rdar://69036888: remove this when no longer needed. >+ // This is only used for a special case mitigation. It is not for general use. >+ Structure* tryGet(StructureID); >+ >+ Structure* get(StructureID); >+ void deallocateID(Structure*, StructureID); >+ StructureID allocateID(Structure*); >+ >+ void flushOldTables(); >+ >+ size_t size() const { return m_size; } >+ >+private: >+ void resize(size_t newCapacity); >+ void makeFreeListFromRange(uint32_t first, uint32_t last); >+ >+ union StructureOrOffset { >+ WTF_MAKE_FAST_ALLOCATED; >+ public: >+ EncodedStructureBits encodedStructureBits; >+ uintptr_t offset; >+ }; >+ >+ StructureOrOffset* table() const { return m_table.get(); } >+ static Structure* decode(EncodedStructureBits, StructureID); >+ static EncodedStructureBits encode(Structure*, StructureID); >+ >+ static constexpr size_t s_initialSize = 512; >+ >+ Vector<UniqueArray<StructureOrOffset>> m_oldTables; >+ >+ uint32_t m_firstFreeOffset { 0 }; >+ uint32_t m_lastFreeOffset { 0 }; >+ UniqueArray<StructureOrOffset> m_table; >+ >+ size_t m_size { 0 }; >+ size_t m_capacity; >+ >+ WeakRandom m_weakRandom; >+ >+ static constexpr StructureID s_unusedID = 0; >+ >+public: >+ // 1. StructureID is encoded as: >+ // >+ // ---------------------------------------------------------------- >+ // | 1 Nuke Bit | 26 StructureIDTable index bits | 5 entropy bits | >+ // ---------------------------------------------------------------- >+ // >+ // The entropy bits are chosen at random and assigned when a StructureID >+ // is allocated. >+ // >+ // 2. For each StructureID, the StructureIDTable stores encodedStructureBits >+ // which are encoded from the structure pointer as such: >+ // >+ // ------------------------------------------------------------------ >+ // | 11 low index bits | 5 entropy bits | 48 structure pointer bits | >+ // ------------------------------------------------------------------ >+ // >+ // The entropy bits here are the same 5 bits used in the encoding of the >+ // StructureID for this structure entry in the StructureIDTable. >+ >+ static constexpr uint32_t s_numberOfNukeBits = 1; >+ static constexpr uint32_t s_numberOfEntropyBits = 5; >+ static constexpr uint32_t s_entropyBitsShiftForStructurePointer = (sizeof(EncodedStructureBits) * 8) - 16; >+ >+ static constexpr uint32_t s_maximumNumberOfStructures = 1 << (32 - s_numberOfEntropyBits - s_numberOfNukeBits); >+}; >+ >+ALWAYS_INLINE Structure* StructureIDTable::decode(EncodedStructureBits bits, StructureID structureID) >+{ >+ return bitwise_cast<Structure*>(bits ^ (static_cast<uintptr_t>(structureID) << s_entropyBitsShiftForStructurePointer)); >+} >+ >+ALWAYS_INLINE EncodedStructureBits StructureIDTable::encode(Structure* structure, StructureID structureID) >+{ >+ return bitwise_cast<EncodedStructureBits>(structure) ^ (static_cast<EncodedStructureBits>(structureID) << s_entropyBitsShiftForStructurePointer); >+} >+ >+inline Structure* StructureIDTable::get(StructureID structureID) >+{ >+ ASSERT_WITH_SECURITY_IMPLICATION(structureID); >+ ASSERT_WITH_SECURITY_IMPLICATION(!isNuked(structureID)); >+ uint32_t structureIndex = structureID >> s_numberOfEntropyBits; >+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(structureIndex < m_capacity); >+ return decode(table()[structureIndex].encodedStructureBits, structureID); >+} >+ >+// FIXME: rdar://69036888: remove this function when no longer needed. >+inline Structure* StructureIDTable::tryGet(StructureID structureID) >+{ >+ uint32_t structureIndex = structureID >> s_numberOfEntropyBits; >+ if (structureIndex >= m_capacity) >+ return nullptr; >+ return decode(table()[structureIndex].encodedStructureBits, structureID); >+} >+ >+ALWAYS_INLINE void StructureIDTable::validate(StructureID structureID) >+{ >+ uint32_t structureIndex = structureID >> s_numberOfEntropyBits; >+ Structure* structure = decode(table()[structureIndex].encodedStructureBits, structureID); >+ RELEASE_ASSERT(structureIndex < m_capacity); >+ *bitwise_cast<volatile uint64_t*>(structure); >+} >+ >+#else // not USE(JSVALUE64) >+ >+class StructureIDTable { >+ friend class LLIntOffsetsExtractor; >+public: >+ StructureIDTable() = default; >+ >+ // FIXME: rdar://69036888: remove this function when no longer needed. >+ Structure* tryGet(StructureID structureID) { return structureID; } >+ Structure* get(StructureID structureID) { return structureID; } >+ void deallocateID(Structure*, StructureID) { } >+ StructureID allocateID(Structure* structure) >+ { >+ ASSERT(!isNuked(structure)); >+ return structure; >+ }; >+ >+ void flushOldTables() { } >+ void validate(StructureID) { } >+}; >+ >+#endif // not USE(JSVALUE64) >+ >+} // namespace JSC >Index: Source/JavaScriptCore/runtime/StructureRareData.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/StructureRareData.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/StructureRareData.cpp (working copy) >@@ -60,10 +60,11 @@ void StructureRareData::destroy(JSCell* > > StructureRareData::StructureRareData(VM& vm, Structure* previous) > : JSCell(vm, vm.structureRareDataStructure.get()) >- , m_previous(vm, this, previous, WriteBarrierStructureID::MayBeNull) > , m_maxOffset(invalidOffset) > , m_transitionOffset(invalidOffset) > { >+ if (previous) >+ m_previous.set(vm, this, previous); > } > > template<typename Visitor> >Index: Source/JavaScriptCore/runtime/StructureRareData.h >=================================================================== >--- Source/JavaScriptCore/runtime/StructureRareData.h (revision 286965) >+++ Source/JavaScriptCore/runtime/StructureRareData.h (working copy) >@@ -140,6 +140,7 @@ private: > > bool tryCachePropertyNameEnumeratorViaWatchpoint(VM&, Structure*, StructureChain*); > >+ WriteBarrier<Structure> m_previous; > // FIXME: We should have some story for clearing these property names caches in GC. > // https://bugs.webkit.org/show_bug.cgi?id=192659 > uintptr_t m_cachedPropertyNameEnumeratorAndFlag { 0 }; >@@ -155,7 +156,6 @@ private: > std::unique_ptr<SpecialPropertyCache> m_specialPropertyCache; > Box<InlineWatchpointSet> m_polyProtoWatchpoint; > >- WriteBarrierStructureID m_previous; > PropertyOffset m_maxOffset; > PropertyOffset m_transitionOffset; > }; >Index: Source/JavaScriptCore/runtime/StructureRareDataInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/StructureRareDataInlines.h (revision 286965) >+++ Source/JavaScriptCore/runtime/StructureRareDataInlines.h (working copy) >@@ -177,7 +177,7 @@ inline void StructureChainInvalidationWa > m_structureRareData->clearCachedPropertyNameEnumerator(); > } > >-inline bool StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint(VM&, Structure* baseStructure, StructureChain* chain) >+inline bool StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint(VM& vm, Structure* baseStructure, StructureChain* chain) > { > if (baseStructure->hasPolyProto()) > return false; >@@ -186,7 +186,7 @@ inline bool StructureRareData::tryCacheP > for (auto* current = chain->head(); *current; ++current) { > ++size; > StructureID structureID = *current; >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.getStructure(structureID); > if (!structure->propertyNameEnumeratorShouldWatch()) > return false; > } >@@ -194,7 +194,7 @@ inline bool StructureRareData::tryCacheP > unsigned index = 0; > for (auto* current = chain->head(); *current; ++current) { > StructureID structureID = *current; >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.getStructure(structureID); > m_cachedPropertyNameEnumeratorWatchpoints[index].install(this, structure); > ++index; > } >Index: Source/JavaScriptCore/runtime/SymbolPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/SymbolPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/SymbolPrototype.cpp (working copy) >@@ -96,7 +96,7 @@ JSC_DEFINE_CUSTOM_GETTER(symbolProtoGett > if (!symbol) > return throwVMTypeError(globalObject, scope, SymbolDescriptionTypeError); > scope.release(); >- Integrity::auditStructureID(symbol->structureID()); >+ Integrity::auditStructureID(vm, symbol->structureID()); > const auto description = symbol->description(); > return JSValue::encode(description.isNull() ? jsUndefined() : jsString(vm, description)); > } >@@ -109,7 +109,7 @@ JSC_DEFINE_HOST_FUNCTION(symbolProtoFunc > Symbol* symbol = tryExtractSymbol(vm, callFrame->thisValue()); > if (!symbol) > return throwVMTypeError(globalObject, scope, SymbolToStringTypeError); >- Integrity::auditStructureID(symbol->structureID()); >+ Integrity::auditStructureID(vm, symbol->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(jsNontrivialString(vm, symbol->descriptiveString()))); > } > >@@ -122,7 +122,7 @@ JSC_DEFINE_HOST_FUNCTION(symbolProtoFunc > if (!symbol) > return throwVMTypeError(globalObject, scope, SymbolValueOfTypeError); > >- Integrity::auditStructureID(symbol->structureID()); >+ Integrity::auditStructureID(vm, symbol->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(symbol)); > } > >Index: Source/JavaScriptCore/runtime/TypeProfilerLog.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/TypeProfilerLog.cpp (revision 286965) >+++ Source/JavaScriptCore/runtime/TypeProfilerLog.cpp (working copy) >@@ -80,7 +80,7 @@ void TypeProfilerLog::processLogEntries( > Structure* structure = nullptr; > bool sawPolyProtoStructure = false; > if (id) { >- structure = id.decode(); >+ structure = Heap::heap(value.asCell())->structureIDTable().get(id); > auto iter = cachedMonoProtoShapes.find(structure); > if (iter == cachedMonoProtoShapes.end()) { > auto key = std::make_pair(structure, value.asCell()); >@@ -131,7 +131,7 @@ void TypeProfilerLog::visit(AbstractSlot > for (LogEntry* entry = m_logStartPtr; entry != m_currentLogEntryPtr; ++entry) { > visitor.appendUnbarriered(entry->value); > if (StructureID id = entry->structureID) { >- Structure* structure = id.decode(); >+ Structure* structure = visitor.heap()->structureIDTable().get(id); > visitor.appendUnbarriered(structure); > } > } >Index: Source/JavaScriptCore/runtime/VM.h >=================================================================== >--- Source/JavaScriptCore/runtime/VM.h (revision 286965) >+++ Source/JavaScriptCore/runtime/VM.h (working copy) >@@ -750,6 +750,17 @@ public: > return result; > } > >+ ALWAYS_INLINE Structure* getStructure(StructureID id) >+ { >+ return heap.structureIDTable().get(decontaminate(id)); >+ } >+ >+ // FIXME: rdar://69036888: remove this function when no longer needed. >+ ALWAYS_INLINE Structure* tryGetStructure(StructureID id) >+ { >+ return heap.structureIDTable().tryGet(decontaminate(id)); >+ } >+ > void* stackPointerAtVMEntry() const { return m_stackPointerAtVMEntry; } > void setStackPointerAtVMEntry(void*); > >Index: Source/JavaScriptCore/runtime/WriteBarrier.h >=================================================================== >--- Source/JavaScriptCore/runtime/WriteBarrier.h (revision 286965) >+++ Source/JavaScriptCore/runtime/WriteBarrier.h (working copy) >@@ -27,7 +27,6 @@ > > #include "GCAssertions.h" > #include "HandleTypes.h" >-#include "StructureID.h" > #include <type_traits> > #include <wtf/RawPtrTraits.h> > #include <wtf/RawValueTraits.h> >@@ -249,104 +248,4 @@ inline bool operator==(const WriteBarrie > return lhs.get() == rhs.get(); > } > >-class WriteBarrierStructureID { >-public: >- constexpr WriteBarrierStructureID() = default; >- >- WriteBarrierStructureID(VM& vm, const JSCell* owner, Structure* value) >- { >- set(vm, owner, value); >- } >- >- WriteBarrierStructureID(DFG::DesiredWriteBarrier&, Structure* value) >- { >- ASSERT(isCompilationThread()); >- setWithoutWriteBarrier(value); >- } >- >- enum MayBeNullTag { MayBeNull }; >- WriteBarrierStructureID(VM& vm, const JSCell* owner, Structure* value, MayBeNullTag) >- { >- setMayBeNull(vm, owner, value); >- } >- >- void set(VM&, const JSCell* owner, Structure* value); >- >- void setMayBeNull(VM&, const JSCell* owner, Structure* value); >- >- // Should only be used by JSCell during early initialisation >- // when some basic types aren't yet completely instantiated >- void setEarlyValue(VM&, const JSCell* owner, Structure* value); >- >- Structure* get() const >- { >- // Copy m_structureID to a local to avoid multiple-read issues. (See <http://webkit.org/b/110854>) >- StructureID structureID = m_structureID; >- if (structureID) { >- Structure* structure = structureID.decode(); >- validateCell(reinterpret_cast<JSCell*>(structure)); >- return structure; >- } >- return nullptr; >- } >- >- Structure* operator*() const >- { >- StructureID structureID = m_structureID; >- ASSERT(structureID); >- Structure* structure = structureID.decode(); >- validateCell(reinterpret_cast<JSCell*>(structure)); >- return structure; >- } >- >- Structure* operator->() const >- { >- StructureID structureID = m_structureID; >- ASSERT(structureID); >- Structure* structure = structureID.decode(); >- validateCell(reinterpret_cast<JSCell*>(structure)); >- return structure; >- } >- >- void clear() >- { >- m_structureID = { }; >- } >- >- explicit operator bool() const >- { >- return !!m_structureID; >- } >- >- bool operator!() const >- { >- return !m_structureID; >- } >- >- void setWithoutWriteBarrier(Structure* value) >- { >-#if ENABLE(WRITE_BARRIER_PROFILING) >- WriteBarrierCounters::usesWithoutBarrierFromCpp.count(); >-#endif >- if (!value) { >- m_structureID = { }; >- return; >- } >- m_structureID = StructureID::encode(value); >- } >- >- Structure* unvalidatedGet() const >- { >- StructureID structureID = m_structureID; >- if (structureID) >- return structureID.decode(); >- return nullptr; >- } >- >- StructureID value() const { return m_structureID; } >- >-private: >- StructureID m_structureID; >-}; >- > } // namespace JSC >Index: Source/JavaScriptCore/runtime/WriteBarrierInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/WriteBarrierInlines.h (revision 286965) >+++ Source/JavaScriptCore/runtime/WriteBarrierInlines.h (working copy) >@@ -61,29 +61,4 @@ inline void WriteBarrierBase<Unknown, Ra > vm.writeBarrier(owner, value); > } > >-inline void WriteBarrierStructureID::set(VM& vm, const JSCell* owner, Structure* value) >-{ >- ASSERT(value); >- ASSERT(!Options::useConcurrentJIT() || !isCompilationThread()); >- validateCell(reinterpret_cast<JSCell*>(value)); >- setEarlyValue(vm, owner, value); >-} >- >-inline void WriteBarrierStructureID::setMayBeNull(VM& vm, const JSCell* owner, Structure* value) >-{ >- if (value) >- validateCell(reinterpret_cast<JSCell*>(value)); >- setEarlyValue(vm, owner, value); >-} >- >-inline void WriteBarrierStructureID::setEarlyValue(VM& vm, const JSCell* owner, Structure* value) >-{ >- if (!value) { >- m_structureID = { }; >- return; >- } >- m_structureID = StructureID::encode(value); >- vm.writeBarrier(owner, reinterpret_cast<JSCell*>(value)); >-} >- > } // namespace JSC >Index: Source/JavaScriptCore/tools/HeapVerifier.cpp >=================================================================== >--- Source/JavaScriptCore/tools/HeapVerifier.cpp (revision 286965) >+++ Source/JavaScriptCore/tools/HeapVerifier.cpp (working copy) >@@ -230,10 +230,14 @@ bool HeapVerifier::validateJSCell(VM* ex > > // 2. Validate the cell's structure > >- Structure* structure = structureID.decode(); >+ Structure* structure = vm.getStructure(structureID); > if (!structure) { > printHeaderAndCell(); >- uint32_t structureIDAsUint32 = structureID.bits(); >+#if USE(JSVALUE64) >+ uint32_t structureIDAsUint32 = structureID; >+#else >+ uint32_t structureIDAsUint32 = reinterpret_cast<uint32_t>(structureID); >+#endif > dataLog(" with structureID ", structureIDAsUint32, " maps to a NULL Structure pointer\n"); > return false; > } >@@ -281,7 +285,7 @@ bool HeapVerifier::validateJSCell(VM* ex > > // 3. Validate the cell's structure's structure. > >- Structure* structureStructure = structureID.decode(); >+ Structure* structureStructure = vm.getStructure(structureID); > if (!structureStructure) { > printHeaderAndCell(); > dataLog(" has structure ", RawPointer(structure), " whose structure is NULL\n"); >Index: Source/JavaScriptCore/tools/Integrity.cpp >=================================================================== >--- Source/JavaScriptCore/tools/Integrity.cpp (revision 286965) >+++ Source/JavaScriptCore/tools/Integrity.cpp (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2019-2021 Apple Inc. All rights reserved. >+ * Copyright (C) 2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >Index: Source/JavaScriptCore/tools/Integrity.h >=================================================================== >--- Source/JavaScriptCore/tools/Integrity.h (revision 286965) >+++ Source/JavaScriptCore/tools/Integrity.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2019-2021 Apple Inc. All rights reserved. >+ * Copyright (C) 2019-2020 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -26,7 +26,7 @@ > #pragma once > > #include "JSCJSValue.h" >-#include "StructureID.h" >+#include "StructureIDTable.h" > #include <wtf/Gigacage.h> > #include <wtf/Lock.h> > >@@ -100,7 +100,8 @@ ALWAYS_INLINE void auditCell(VM& vm, JSV > auditCell<auditLevel>(vm, value.asCell()); > } > >-ALWAYS_INLINE void auditStructureID(StructureID); >+ALWAYS_INLINE void auditStructureID(StructureIDTable&, StructureID); >+ALWAYS_INLINE void auditStructureID(VM&, StructureID); > > } // namespace Integrity > >Index: Source/JavaScriptCore/tools/IntegrityInlines.h >=================================================================== >--- Source/JavaScriptCore/tools/IntegrityInlines.h (revision 286965) >+++ Source/JavaScriptCore/tools/IntegrityInlines.h (working copy) >@@ -73,13 +73,14 @@ ALWAYS_INLINE void auditCellRandomly(VM& > auditCellFully(vm, cell); > } > >+ALWAYS_INLINE void auditStructureID(StructureIDTable& table, StructureID id) >+{ >+ table.validate(id); >+} > >-ALWAYS_INLINE void auditStructureID(StructureID structureID) >+ALWAYS_INLINE void auditStructureID(VM& vm, StructureID id) > { >- UNUSED_PARAM(structureID); >-#if CPU(ADDRESS64) >- ASSERT(structureID.bits() <= structureHeapAddressSize + StructureID::nukedStructureIDBit); >-#endif >+ auditStructureID(vm.heap.structureIDTable(), id); > } > > } // namespace Integrity >Index: Source/JavaScriptCore/tools/JSDollarVM.cpp >=================================================================== >--- Source/JavaScriptCore/tools/JSDollarVM.cpp (revision 286965) >+++ Source/JavaScriptCore/tools/JSDollarVM.cpp (working copy) >@@ -3585,7 +3585,7 @@ JSC_DEFINE_HOST_FUNCTION(functionGetStru > > for (size_t i = 0; i < structures.size(); ++i) { > auto* structure = structures[structures.size() - i - 1]; >- result->push(globalObject, JSValue(structure->id().bits())); >+ result->push(globalObject, JSValue(structure->id())); > RETURN_IF_EXCEPTION(scope, { }); > result->push(globalObject, JSValue(structure->transitionOffset())); > RETURN_IF_EXCEPTION(scope, { }); >@@ -4012,7 +4012,7 @@ void JSDollarVM::finishCreation(VM& vm) > > addFunction(vm, "ensureArrayStorage", functionEnsureArrayStorage, 1); > >- m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructureID.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull())); >+ m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull())); > } > > void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments) >@@ -4034,7 +4034,7 @@ void JSDollarVM::visitChildrenImpl(JSCel > { > JSDollarVM* thisObject = jsCast<JSDollarVM*>(cell); > Base::visitChildren(thisObject, visitor); >- visitor.append(thisObject->m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructureID); >+ visitor.append(thisObject->m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure); > } > > DEFINE_VISIT_CHILDREN(JSDollarVM); >Index: Source/JavaScriptCore/tools/JSDollarVM.h >=================================================================== >--- Source/JavaScriptCore/tools/JSDollarVM.h (revision 286965) >+++ Source/JavaScriptCore/tools/JSDollarVM.h (working copy) >@@ -61,7 +61,7 @@ public: > return instance; > } > >- Structure* objectDoingSideEffectPutWithoutCorrectSlotStatusStructure() { return m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructureID.get(); } >+ Structure* objectDoingSideEffectPutWithoutCorrectSlotStatusStructure() { return m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure.get(); } > > private: > JSDollarVM(VM& vm, Structure* structure) >@@ -76,7 +76,7 @@ private: > > DECLARE_VISIT_CHILDREN; > >- WriteBarrierStructureID m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructureID; >+ WriteBarrier<Structure> m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure; > }; > > } // namespace JSC >Index: Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (revision 286965) >+++ Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (working copy) >@@ -266,7 +266,7 @@ MacroAssemblerCodePtr<JSEntryPtrTag> Web > slowPath.append(jit.branchIfNotCell(scratchGPR)); > > stackLimitGPRIsClobbered = true; >- jit.emitLoadStructure(vm, scratchGPR, scratchGPR); >+ jit.emitLoadStructure(vm, scratchGPR, scratchGPR, stackLimitGPR); > jit.loadPtr(CCallHelpers::Address(scratchGPR, Structure::classInfoOffset()), scratchGPR); > > static_assert(std::is_final<WebAssemblyFunction>::value, "We do not check for subtypes below"); >Index: Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp (revision 286965) >+++ Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp (working copy) >@@ -64,7 +64,7 @@ static ALWAYS_INLINE JSWebAssemblyGlobal > createTypeError(globalObject, "expected |this| value to be an instance of WebAssembly.Global"_s)); > return nullptr; > } >- Integrity::auditStructureID(result->structureID()); >+ Integrity::auditStructureID(vm, result->structureID()); > return result; > } > >Index: Source/WTF/ChangeLog >=================================================================== >--- Source/WTF/ChangeLog (revision 286965) >+++ Source/WTF/ChangeLog (working copy) >@@ -1,3 +1,14 @@ >+2021-12-13 Saam Barati <sbarati@apple.com> >+ >+ Roll back r286345, r286387, r286471, r286667, r286849 >+ https://bugs.webkit.org/show_bug.cgi?id=234268 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * wtf/OSAllocator.h: >+ * wtf/posix/OSAllocatorPOSIX.cpp: >+ (WTF::OSAllocator::reserveUncommittedAligned): Deleted. >+ > 2021-12-13 Elliott Williams <emw@apple.com> > > Deployment target for macOS 11+ does not follow minor version bumps >Index: Source/WTF/wtf/OSAllocator.h >=================================================================== >--- Source/WTF/wtf/OSAllocator.h (revision 286965) >+++ Source/WTF/wtf/OSAllocator.h (working copy) >@@ -39,14 +39,11 @@ public: > JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, > }; > >- // These methods are symmetric; reserveUncommitted(Aligned) allocates VM in an uncommitted state, >+ // These methods are symmetric; reserveUncommitted allocates VM in an uncommitted state, > // releaseDecommitted should be called on a region of VM allocated by a single reservation, >- // the memory must all currently be in a decommitted state. reserveUncommitted(Aligned) returns to >+ // the memory must all currently be in a decommitted state. reserveUncommitted returns to > // you memory that is zeroed. > WTF_EXPORT_PRIVATE static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false); >- // This guarantees the memory will be aligned to a multiple of the requested size. The requested >- // size must be a power of two and greater than the system page size. >- WTF_EXPORT_PRIVATE static void* reserveUncommittedAligned(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool jitCageEnabled = false, bool includesGuardPages = false); > WTF_EXPORT_PRIVATE static void releaseDecommitted(void*, size_t); > > // These methods are symmetric; they commit or decommit a region of VM (uncommitted VM should >Index: Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp >=================================================================== >--- Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp (revision 286965) >+++ Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp (working copy) >@@ -29,7 +29,6 @@ > #include <errno.h> > #include <sys/mman.h> > #include <wtf/Assertions.h> >-#include <wtf/MathExtras.h> > #include <wtf/PageBlock.h> > > #if ENABLE(JIT_CAGE) >@@ -44,10 +43,6 @@ > #endif // OS(DARWIN) > #endif // ENABLE(JIT_CAGE) > >-#if OS(DARWIN) >-#include <wtf/spi/cocoa/MachVMSPI.h> >-#endif >- > namespace WTF { > > void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages) >@@ -77,56 +72,6 @@ void* OSAllocator::reserveUncommitted(si > return result; > } > >-void* OSAllocator::reserveUncommittedAligned(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages) >-{ >- ASSERT(hasOneBitSet(bytes) && bytes >= pageSize()); >- >-#if PLATFORM(MAC) || USE(APPLE_INTERNAL_SDK) >- UNUSED_PARAM(usage); // Not supported for mach API. >- ASSERT_UNUSED(includesGuardPages, !includesGuardPages); >- ASSERT_UNUSED(jitCageEnabled, !jitCageEnabled); // Not supported for mach API. >- vm_prot_t protections = VM_PROT_READ; >- if (writable) >- protections |= VM_PROT_WRITE; >- if (executable) >- protections |= VM_PROT_EXECUTE; >- >- const vm_inherit_t childProcessInheritance = VM_INHERIT_DEFAULT; >- const bool copy = false; >- const int flags = VM_FLAGS_ANYWHERE; >- >- void* aligned = nullptr; >- kern_return_t result = mach_vm_map(mach_task_self(), reinterpret_cast<mach_vm_address_t*>(&aligned), bytes, bytes - 1, flags, MEMORY_OBJECT_NULL, 0, copy, protections, protections, childProcessInheritance); >- RELEASE_ASSERT(result == KERN_SUCCESS, result, bytes); >-#if HAVE(MADV_FREE_REUSE) >- if (aligned) { >- // To support the "reserve then commit" model, we have to initially decommit. >- while (madvise(aligned, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { } >- } >-#endif >- >- return aligned; >-#else >- // Double the size so we can ensure enough mapped memory to get an aligned start. >- size_t mappedSize = bytes * 2; >- char* mapped = reinterpret_cast<char*>(reserveUncommitted(mappedSize, usage, writable, executable, jitCageEnabled, includesGuardPages)); >- char* mappedEnd = mapped + mappedSize; >- >- char* aligned = reinterpret_cast<char*>(roundUpToMultipleOf(bytes, reinterpret_cast<uintptr_t>(mapped))); >- char* alignedEnd = aligned + bytes; >- >- RELEASE_ASSERT(alignedEnd <= mappedEnd); >- >- if (size_t leftExtra = aligned - mapped) >- releaseDecommitted(mapped, leftExtra); >- >- if (size_t rightExtra = mappedEnd - alignedEnd) >- releaseDecommitted(alignedEnd, rightExtra); >- >- return aligned; >-#endif >-} >- > void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool jitCageEnabled, bool includesGuardPages) > { > // All POSIX reservations start out logically committed.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
mark.lam
:
review+
ews-feeder
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 234268
:
447063
|
447073
|
447081