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
bug-233379-20211122093610.patch (text/plain), 207.55 KB, created by
Keith Miller
on 2021-11-22 06:36:11 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Keith Miller
Created:
2021-11-22 06:36:11 PST
Size:
207.55 KB
patch
obsolete
>Subversion Revision: 286065 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 92b19a6ff1aec6743a1ac394058acfc994d374e0..d0dd49c69a05158ea2971727cd5820c104c32622 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,278 @@ >+2021-11-19 Keith Miller <keith_miller@apple.com> >+ >+ Structures should be allocated out of an aligned pool of memory so StructureID->Structure* is fast. >+ https://bugs.webkit.org/show_bug.cgi?id=233379 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch changes the 64-bit pointer variant of StructureID to >+ just be the bottom bits of a reserved address space for >+ structures. With this system the decoding of a StructureID is just >+ adding the bits to the start of the structure address space (saved >+ in JSCConfig). We also take care to ignore any high bits of a >+ StructureID outside the reserved address range. This prevents a >+ data corruption from causing us to read past the structure space, >+ much like the gigacage. >+ >+ Now that StructureIDs can be directly determined from the >+ Structure* (and visa versa) we no longer need StructureIDTable, >+ which has been removed. Also, as Structures are still IsoHeaped >+ but not allocated by fastMalloc, there's a new >+ AlignedMemoryAllocator subclass that gets MarkedBlocks out of a >+ simple static allocator. >+ >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * bytecode/AccessCase.cpp: >+ (JSC::AccessCase::forEachDependentCell const): >+ (JSC::AccessCase::propagateTransitions const): >+ (JSC::AccessCase::generateWithGuard): >+ * bytecode/ArrayProfile.cpp: >+ (JSC::ArrayProfile::computeUpdatedPrediction): >+ * bytecode/ArrayProfile.h: >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::propagateTransitions): >+ (JSC::CodeBlock::determineLiveness): >+ (JSC::CodeBlock::finalizeLLIntInlineCaches): >+ (JSC::CodeBlock::stronglyVisitWeakReferences): >+ * bytecode/GetByIdMetadata.h: >+ (JSC::GetByIdModeMetadata::GetByIdModeMetadata): >+ (JSC::GetByIdModeMetadata::clearToDefaultModeWithoutCache): >+ * bytecode/GetByStatus.cpp: >+ (JSC::GetByStatus::computeFromLLInt): >+ * bytecode/InlineAccess.cpp: >+ (JSC::InlineAccess::rewireStubAsJumpInAccess): >+ (JSC::InlineAccess::resetStubAsJumpInAccess): >+ * 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): >+ * bytecode/SpeculatedType.cpp: >+ (JSC::speculationFromCell): >+ * bytecode/StructureStubInfo.cpp: >+ (JSC::StructureStubInfo::addAccessCase): >+ (JSC::StructureStubInfo::reset): >+ * bytecode/StructureStubInfo.h: >+ (JSC::StructureStubInfo::inlineAccessBaseStructure): >+ * 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/FTLLowerDFGToB3.cpp: >+ (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): >+ * heap/Heap.cpp: >+ (JSC::Heap::runEndPhase): >+ * heap/Heap.h: >+ (JSC::Heap::structureIDTable): Deleted. >+ * heap/IsoAlignedMemoryAllocator.cpp: >+ (JSC::IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator): >+ (JSC::IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator): >+ (JSC::IsoAlignedMemoryAllocator::tryMallocBlock): >+ (JSC::IsoAlignedMemoryAllocator::freeBlock): >+ (JSC::IsoAlignedMemoryAllocator::commitBlock): >+ (JSC::IsoAlignedMemoryAllocator::decommitBlock): >+ (JSC::IsoAlignedMemoryAllocator::tryAllocateAlignedMemory): Deleted. >+ (JSC::IsoAlignedMemoryAllocator::freeAlignedMemory): Deleted. >+ * heap/IsoAlignedMemoryAllocator.h: >+ * heap/IsoMemoryAllocatorBase.cpp: Copied from Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp. >+ (JSC::IsoMemoryAllocatorBase::IsoMemoryAllocatorBase): >+ (JSC::IsoMemoryAllocatorBase::~IsoMemoryAllocatorBase): >+ (JSC::IsoMemoryAllocatorBase::releaseMemoryFromSubclassDestructor): >+ (JSC::IsoMemoryAllocatorBase::tryAllocateAlignedMemory): >+ (JSC::IsoMemoryAllocatorBase::freeAlignedMemory): >+ * heap/IsoMemoryAllocatorBase.h: Copied from Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h. >+ * heap/IsoSubspace.cpp: >+ (JSC::IsoSubspace::IsoSubspace): >+ (JSC::IsoSubspace::tryAllocateFromLowerTier): >+ * heap/IsoSubspace.h: >+ * heap/PreciseAllocation.cpp: >+ (JSC::PreciseAllocation::tryCreateForLowerTier): >+ (JSC::PreciseAllocation::createForLowerTier): Deleted. >+ * heap/PreciseAllocation.h: >+ * heap/SlotVisitor.cpp: >+ (JSC::SlotVisitor::appendJSCellOrAuxiliary): >+ * heap/StructureAlignedMemoryAllocator.cpp: Added. >+ (JSC::StructureAlignedMemoryAllocator::StructureAlignedMemoryAllocator): >+ (JSC::StructureAlignedMemoryAllocator::~StructureAlignedMemoryAllocator): >+ (JSC::StructureAlignedMemoryAllocator::dump const): >+ (JSC::StructureAlignedMemoryAllocator::tryAllocateMemory): >+ (JSC::StructureAlignedMemoryAllocator::freeMemory): >+ (JSC::StructureAlignedMemoryAllocator::tryReallocateMemory): >+ (JSC::StructureMemoryManager::StructureMemoryManager): >+ (JSC::StructureMemoryManager::tryMallocStructureBlock): >+ (JSC::StructureMemoryManager::freeStructureBlock): >+ (JSC::StructureAlignedMemoryAllocator::initializeStructureAddressSpace): >+ (JSC::StructureAlignedMemoryAllocator::tryMallocBlock): >+ (JSC::StructureAlignedMemoryAllocator::freeBlock): >+ (JSC::StructureAlignedMemoryAllocator::commitBlock): >+ (JSC::StructureAlignedMemoryAllocator::decommitBlock): >+ * heap/StructureAlignedMemoryAllocator.h: Copied from Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h. >+ * heap/StructureAllignedMemoryAllocator.h: Copied from Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h. >+ * jit/AssemblyHelpers.cpp: >+ (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): >+ (JSC::AssemblyHelpers::emitLoadStructure): >+ (JSC::AssemblyHelpers::emitLoadPrototype): >+ (JSC::AssemblyHelpers::emitRandomThunk): >+ (JSC::AssemblyHelpers::emitConvertValueToBoolean): >+ (JSC::AssemblyHelpers::branchIfValue): >+ * jit/AssemblyHelpers.h: >+ (JSC::AssemblyHelpers::branchStructure): >+ (JSC::AssemblyHelpers::nukeStructureAndStoreButterfly): >+ * jit/GCAwareJITStubRoutine.cpp: >+ (JSC::PolymorphicAccessJITStubRoutine::computeHash): >+ * 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/FunctionPrototype.cpp: >+ (JSC::JSC_DEFINE_HOST_FUNCTION): >+ * 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/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::visitChildrenImpl): >+ * runtime/StructureID.h: Added. >+ (JSC::StructureID::nuke const): >+ (JSC::StructureID::isNuked const): >+ (JSC::StructureID::decontaminate const): >+ (JSC::StructureID::operator bool const): >+ (JSC::StructureID::operator== const): >+ (JSC::StructureID::operator!= const): >+ (JSC::StructureID::bits const): >+ (JSC::StructureID::StructureID): >+ (JSC::StructureID::isHashTableDeletedValue const): >+ (JSC::StructureID::decode const): >+ (JSC::StructureID::encode): >+ (JSC::StructureIDHash::hash): >+ (JSC::StructureIDHash::equal): >+ * runtime/StructureIDBlob.h: >+ * runtime/StructureIDTable.cpp: Removed. >+ * runtime/StructureIDTable.h: Removed. >+ * 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.cpp: >+ (JSC::VM::VM): >+ * runtime/VM.h: >+ (JSC::VM::getStructure): Deleted. >+ (JSC::VM::tryGetStructure): 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): >+ * wasm/js/WebAssemblyFunction.cpp: >+ (JSC::WebAssemblyFunction::jsCallEntrypointSlow): >+ * wasm/js/WebAssemblyGlobalPrototype.cpp: >+ (JSC::getGlobal): >+ > 2021-11-19 Robin Morisset <rmorisset@apple.com> > > AirFixObviousSpills should be optimized >diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt >index 08badc32775c2280a7a60dda6027eccc3343ef8d..f3ff098ab74be3d50103024631ea74168f102da2 100644 >--- a/Source/JavaScriptCore/CMakeLists.txt >+++ b/Source/JavaScriptCore/CMakeLists.txt >@@ -763,6 +763,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS > heap/IncrementalSweeper.h > heap/IsoCellSet.h > heap/IsoHeapCellType.h >+ heap/IsoMemoryAllocatorBase.h > heap/IsoSubspace.h > heap/IsoSubspaceInlines.h > heap/IsoSubspacePerVM.h >@@ -789,6 +790,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS > heap/Strong.h > heap/StrongForward.h > heap/StrongInlines.h >+ heap/StructureAlignedMemoryAllocator.h > heap/Subspace.h > heap/SubspaceInlines.h > heap/Synchronousness.h >@@ -1180,8 +1182,8 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS > 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 >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 211da72c86970ad25c1d0e804413dc0033339753..dd1f1a084f0f20c6e38febb82c746bd36053c1da 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -857,7 +857,6 @@ > 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 */; }; >@@ -1091,6 +1090,10 @@ > 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 */; }; >@@ -3635,8 +3638,6 @@ > 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>"; }; >@@ -3739,6 +3740,7 @@ > 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>"; }; >@@ -3927,6 +3929,11 @@ > 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>"; }; >@@ -5783,6 +5790,7 @@ > 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */, > 9322A00306C341D3009067BB /* libicucore.dylib */, > 51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */, >+ 531013F3274419F40009009C /* libWTF.a */, > 1498CAD3214656C400710879 /* libWTF.a */, > A8A4748D151A8306004123FF /* libWTF.a */, > 371D842C17C98B6E00ECF994 /* libz.dylib */, >@@ -6606,6 +6614,8 @@ > E3C8ED4123A1DBC400131958 /* IsoHeapCellType.cpp */, > E3BF1BAD238AAED1003A1C2B /* IsoHeapCellType.h */, > E3C8ED4223A1DBC500131958 /* IsoInlinedHeapCellType.h */, >+ 537FEECD2742BDE000C9EFEE /* IsoMemoryAllocatorBase.h */, >+ 537FEECA2742BDE000C9EFEE /* IsoMemoryAllocatorBaseInlines.h */, > 0FDCE12C1FAFB4DE006F3901 /* IsoSubspace.cpp */, > 0FDCE12B1FAFB4DE006F3901 /* IsoSubspace.h */, > 0FD2FD9220B52BDC00F09441 /* IsoSubspaceInlines.h */, >@@ -6665,6 +6675,8 @@ > 142E3132134FF0A600AFADB5 /* Strong.h */, > CD1F9B4A270CFE0F00617EB6 /* StrongForward.h */, > 145722851437E140005FDE26 /* StrongInlines.h */, >+ 537FEECB2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.cpp */, >+ 537FEECC2742BDE000C9EFEE /* StructureAlignedMemoryAllocator.h */, > 0F7DF1311E2970D50095951B /* Subspace.cpp */, > 0F7DF1321E2970D50095951B /* Subspace.h */, > 0F7DF1331E2970D50095951B /* SubspaceInlines.h */, >@@ -8066,9 +8078,8 @@ > 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 */, >@@ -10265,6 +10276,8 @@ > 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 */, >@@ -10676,12 +10689,12 @@ > 147341D41DC02E6D00AA29BA /* ProgramExecutable.h in Headers */, > 0FD3E40E1B618B6600C80E1E /* PropertyCondition.h in Headers */, > A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, >- BC95437D0EBA70FD0072B6D3 /* PropertyTable.h in Headers */, > 86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */, > BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */, > 0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */, > BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */, > 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */, >+ BC95437D0EBA70FD0072B6D3 /* PropertyTable.h in Headers */, > BC18C4560E16F5CD00B34460 /* Protect.h in Headers */, > FE1D6D752362649F007A5C26 /* ProtoCallFrameInlines.h in Headers */, > 0F74B93B1F89614800B935D3 /* PrototypeKey.h in Headers */, >@@ -10814,10 +10827,11 @@ > 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 */, >diff --git a/Source/JavaScriptCore/Sources.txt b/Source/JavaScriptCore/Sources.txt >index 793f46f7bc58e508cda6cb9015aa092e8c9860d9..a380966e0490f4e2ab6fd1cbf12a968e850b2e49 100644 >--- a/Source/JavaScriptCore/Sources.txt >+++ b/Source/JavaScriptCore/Sources.txt >@@ -536,6 +536,7 @@ heap/IncrementalSweeper.cpp > heap/IsoAlignedMemoryAllocator.cpp > heap/IsoCellSet.cpp > heap/IsoHeapCellType.cpp >+heap/IsoMemoryAllocatorBase.cpp > heap/IsoSubspace.cpp > heap/IsoSubspacePerVM.cpp > heap/JITStubRoutineSet.cpp >@@ -557,6 +558,7 @@ 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,7 +1009,6 @@ runtime/StringRecursionChecker.cpp > runtime/Structure.cpp > runtime/StructureCache.cpp > runtime/StructureChain.cpp >-runtime/StructureIDTable.cpp > runtime/StructureRareData.cpp > runtime/Symbol.cpp > runtime/SymbolConstructor.cpp >diff --git a/Source/JavaScriptCore/bytecode/AccessCase.cpp b/Source/JavaScriptCore/bytecode/AccessCase.cpp >index 13250ec4842f7903599cb587fd8be2848c676a83..df08e0f63a5b3a6addd0fbf2876f2dde7cca6ad5 100644 >--- a/Source/JavaScriptCore/bytecode/AccessCase.cpp >+++ b/Source/JavaScriptCore/bytecode/AccessCase.cpp >@@ -536,14 +536,14 @@ bool AccessCase::needsScratchFPR() const > } > > template<typename Functor> >-void AccessCase::forEachDependentCell(VM& vm, const Functor& functor) const >+void AccessCase::forEachDependentCell(VM&, const Functor& functor) const > { > m_conditionSet.forEachDependentCell(functor); > if (m_structure) > functor(m_structure.get()); > if (m_polyProtoAccessChain) { > for (StructureID structureID : m_polyProtoAccessChain->chain()) >- functor(vm.getStructure(structureID)); >+ functor(structureID.decode()); > } > > switch (type()) { >@@ -909,7 +909,7 @@ void AccessCase::propagateTransitions(Visitor& visitor) const > > if (m_polyProtoAccessChain) { > for (StructureID structureID : m_polyProtoAccessChain->chain()) >- visitor.vm().getStructure(structureID)->markIfCheap(visitor); >+ structureID.decode()->markIfCheap(visitor); > } > > switch (m_type) { >@@ -1720,7 +1720,7 @@ void AccessCase::generateWithGuard( > JSValueRegs resultRegs(scratchGPR, scratch2GPR); > #endif > >- jit.emitLoadPrototype(vm, valueGPR, resultRegs, scratchGPR, failAndIgnore); >+ jit.emitLoadPrototype(vm, valueGPR, resultRegs, failAndIgnore); > jit.move(scratch2GPR, valueGPR); > > CCallHelpers::Jump isInstance = jit.branchPtr(CCallHelpers::Equal, valueGPR, prototypeGPR); >diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp >index 945ea89a9dd8f24cf879e55b2a49428caf1cda2a..6b0b8cab89ffdf7fceeb1aba7f9b0b0a44cb8e2d 100644 >--- a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp >+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp >@@ -123,9 +123,9 @@ void ArrayProfile::computeUpdatedPrediction(const ConcurrentJSLocker& locker, Co > if (!m_lastSeenStructureID) > return; > >- Structure* lastSeenStructure = codeBlock->heap()->structureIDTable().get(m_lastSeenStructureID); >+ Structure* lastSeenStructure = m_lastSeenStructureID.decode(); > computeUpdatedPrediction(locker, codeBlock, lastSeenStructure); >- m_lastSeenStructureID = 0; >+ m_lastSeenStructureID = StructureID(); > } > > void ArrayProfile::computeUpdatedPrediction(const ConcurrentJSLocker&, CodeBlock* codeBlock, Structure* lastSeenStructure) >diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.h b/Source/JavaScriptCore/bytecode/ArrayProfile.h >index 36feb144bad380d561b70082253cc504c078005c..a61587573b3287a2114c4d5f8325db7fd83f0eb2 100644 >--- a/Source/JavaScriptCore/bytecode/ArrayProfile.h >+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.h >@@ -249,7 +249,7 @@ private: > > static Structure* polymorphicStructure() { return static_cast<Structure*>(reinterpret_cast<void*>(1)); } > >- StructureID m_lastSeenStructureID { 0 }; >+ StructureID m_lastSeenStructureID; > 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) >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index bfe18678e75d41333509285b04804ccb62ff044f..f9ab710fb42cda4df00ca6350250898ef274e514 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -1192,7 +1192,6 @@ 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) { >@@ -1202,9 +1201,9 @@ void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, Visitor& visitor > if (!oldStructureID || !newStructureID) > return; > >- Structure* oldStructure = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > if (visitor.isMarked(oldStructure)) { >- Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); >+ Structure* newStructure = newStructureID.decode(); > visitor.appendUnbarriered(newStructure); > } > }); >@@ -1220,9 +1219,9 @@ void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, Visitor& visitor > if (!visitor.isMarked(property)) > return; > >- Structure* oldStructure = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > if (visitor.isMarked(oldStructure)) { >- Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); >+ Structure* newStructure = newStructureID.decode(); > visitor.appendUnbarriered(newStructure); > } > }); >@@ -1238,9 +1237,9 @@ void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, Visitor& visitor > if (!visitor.isMarked(brand)) > return; > >- Structure* oldStructure = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > if (visitor.isMarked(oldStructure)) { >- Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); >+ Structure* newStructure = newStructureID.decode(); > visitor.appendUnbarriered(newStructure); > } > }); >@@ -1269,7 +1268,7 @@ void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, Visitor& visitor > dfgCommon->recordedStatuses.markIfCheap(visitor); > > for (StructureID structureID : dfgCommon->m_weakStructureReferences) >- vm.getStructure(structureID)->markIfCheap(visitor); >+ structureID.decode()->markIfCheap(visitor); > > for (auto& transition : dfgCommon->m_transitions) { > if (shouldMarkTransition(visitor, transition)) { >@@ -1309,6 +1308,7 @@ void CodeBlock::determineLiveness(const ConcurrentJSLocker&, Visitor& visitor) > > #if ENABLE(DFG_JIT) > VM& vm = *m_vm; >+ UNUSED_VARIABLE(vm); > if (visitor.isMarked(this)) > return; > >@@ -1333,7 +1333,7 @@ void CodeBlock::determineLiveness(const ConcurrentJSLocker&, Visitor& visitor) > } > if (allAreLiveSoFar) { > for (StructureID structureID : dfgCommon->m_weakStructureReferences) { >- Structure* structure = vm.getStructure(structureID); >+ Structure* structure = structureID.decode(); > if (!visitor.isMarked(structure)) { > allAreLiveSoFar = false; > break; >@@ -1367,7 +1367,7 @@ void CodeBlock::finalizeLLIntInlineCaches() > if (modeMetadata.mode != GetByIdMode::Default) > return; > StructureID oldStructureID = modeMetadata.defaultMode.structureID; >- if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) >+ if (!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing ", opName, " LLInt property access."); > LLIntPrototypeLoadAdaptiveStructureWatchpoint::clearLLIntGetByIdCache(modeMetadata); >@@ -1388,10 +1388,10 @@ void CodeBlock::finalizeLLIntInlineCaches() > > m_metadata->forEach<OpGetByIdDirect>([&] (auto& metadata) { > StructureID oldStructureID = metadata.m_structureID; >- if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) >+ if (!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt property access."); >- metadata.m_structureID = 0; >+ metadata.m_structureID = StructureID(); > metadata.m_offset = 0; > }); > >@@ -1399,11 +1399,11 @@ void CodeBlock::finalizeLLIntInlineCaches() > JSCell* property = metadata.m_property.get(); > StructureID structureID = metadata.m_structureID; > >- if ((!property || vm.heap.isMarked(property)) && (!structureID || vm.heap.isMarked(vm.heap.structureIDTable().get(structureID)))) >+ if ((!property || vm.heap.isMarked(property)) && (!structureID || vm.heap.isMarked(structureID.decode()))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt private property access."); >- metadata.m_structureID = 0; >+ metadata.m_structureID = StructureID(); > metadata.m_offset = 0; > metadata.m_property.clear(); > }); >@@ -1412,14 +1412,14 @@ void CodeBlock::finalizeLLIntInlineCaches() > StructureID oldStructureID = metadata.m_oldStructureID; > StructureID newStructureID = metadata.m_newStructureID; > StructureChain* chain = metadata.m_structureChain.get(); >- if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) >- && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID))) >+ if ((!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) >+ && (!newStructureID || vm.heap.isMarked(newStructureID.decode())) > && (!chain || vm.heap.isMarked(chain))) > return; > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt put transition."); >- metadata.m_oldStructureID = 0; >+ metadata.m_oldStructureID = StructureID(); > metadata.m_offset = 0; >- metadata.m_newStructureID = 0; >+ metadata.m_newStructureID = StructureID(); > metadata.m_structureChain.clear(); > }); > >@@ -1427,15 +1427,15 @@ void CodeBlock::finalizeLLIntInlineCaches() > StructureID oldStructureID = metadata.m_oldStructureID; > StructureID newStructureID = metadata.m_newStructureID; > JSCell* property = metadata.m_property.get(); >- if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) >+ if ((!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) > && (!property || vm.heap.isMarked(property)) >- && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))) >+ && (!newStructureID || vm.heap.isMarked(newStructureID.decode()))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt put_private_name transition."); >- metadata.m_oldStructureID = 0; >+ metadata.m_oldStructureID = StructureID(); > metadata.m_offset = 0; >- metadata.m_newStructureID = 0; >+ metadata.m_newStructureID = StructureID(); > metadata.m_property.clear(); > }); > >@@ -1443,37 +1443,37 @@ void CodeBlock::finalizeLLIntInlineCaches() > StructureID oldStructureID = metadata.m_oldStructureID; > StructureID newStructureID = metadata.m_newStructureID; > JSCell* brand = metadata.m_brand.get(); >- if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID))) >+ if ((!oldStructureID || vm.heap.isMarked(oldStructureID.decode())) > && (!brand || vm.heap.isMarked(brand)) >- && (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))) >+ && (!newStructureID || vm.heap.isMarked(newStructureID.decode()))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt set_private_brand transition."); >- metadata.m_oldStructureID = 0; >- metadata.m_newStructureID = 0; >+ metadata.m_oldStructureID = StructureID(); >+ metadata.m_newStructureID = StructureID(); > 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(vm.heap.structureIDTable().get(structureID))) >+ if ((!structureID || vm.heap.isMarked(structureID.decode())) > && (!brand || vm.heap.isMarked(brand))) > return; > > dataLogLnIf(Options::verboseOSR(), "Clearing LLInt set_private_brand transition."); >- metadata.m_structureID = 0; >+ metadata.m_structureID = StructureID(); > metadata.m_brand.clear(); > }); > > m_metadata->forEach<OpToThis>([&] (auto& metadata) { >- if (!metadata.m_cachedStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(metadata.m_cachedStructureID))) >+ if (!metadata.m_cachedStructureID || vm.heap.isMarked(metadata.m_cachedStructureID.decode())) > return; > if (Options::verboseOSR()) { >- Structure* structure = vm.heap.structureIDTable().get(metadata.m_cachedStructureID); >+ Structure* structure = metadata.m_cachedStructureID.decode(); > dataLogF("Clearing LLInt to_this with structure %p.\n", structure); > } >- metadata.m_cachedStructureID = 0; >+ metadata.m_cachedStructureID = StructureID(); > metadata.m_toThisStatus = merge(metadata.m_toThisStatus, ToThisClearedByGC); > }); > >@@ -1560,7 +1560,7 @@ void CodeBlock::finalizeLLIntInlineCaches() > return true; > }; > >- if (!vm.heap.isMarked(vm.heap.structureIDTable().get(std::get<0>(pair.key)))) >+ if (!vm.heap.isMarked(std::get<0>(pair.key).decode())) > return clear(); > > for (const LLIntPrototypeLoadAdaptiveStructureWatchpoint& watchpoint : pair.value) { >@@ -1908,7 +1908,7 @@ void CodeBlock::stronglyVisitWeakReferences(const ConcurrentJSLocker&, Visitor& > visitor.append(weakReference); > > for (StructureID structureID : dfgCommon->m_weakStructureReferences) >- visitor.appendUnbarriered(visitor.vm().getStructure(structureID)); >+ visitor.appendUnbarriered(structureID.decode()); > #endif > } > >diff --git a/Source/JavaScriptCore/bytecode/GetByIdMetadata.h b/Source/JavaScriptCore/bytecode/GetByIdMetadata.h >index a7876b3cbd5eb81da10200455891a8604ad5b4de..ab86eef165cf874d6ba64fd4e8f66e6cea47603a 100644 >--- a/Source/JavaScriptCore/bytecode/GetByIdMetadata.h >+++ b/Source/JavaScriptCore/bytecode/GetByIdMetadata.h >@@ -69,7 +69,7 @@ static_assert(sizeof(GetByIdModeMetadataProtoLoad) == 16); > union GetByIdModeMetadata { > GetByIdModeMetadata() > { >- defaultMode.structureID = 0; >+ defaultMode.structureID = StructureID(); > defaultMode.cachedOffset = 0; > defaultMode.padding1 = 0; > mode = GetByIdMode::Default; >@@ -100,7 +100,7 @@ static_assert(sizeof(GetByIdModeMetadata) == 16); > struct GetByIdModeMetadata { > GetByIdModeMetadata() > { >- defaultMode.structureID = 0; >+ defaultMode.structureID = StructureID(); > defaultMode.cachedOffset = 0; > defaultMode.padding1 = 0; > mode = GetByIdMode::Default; >@@ -127,7 +127,7 @@ struct GetByIdModeMetadata { > inline void GetByIdModeMetadata::clearToDefaultModeWithoutCache() > { > mode = GetByIdMode::Default; >- defaultMode.structureID = 0; >+ defaultMode.structureID = StructureID(); > defaultMode.cachedOffset = 0; > } > >diff --git a/Source/JavaScriptCore/bytecode/GetByStatus.cpp b/Source/JavaScriptCore/bytecode/GetByStatus.cpp >index c1e3e1b91cd4a2ef0217428c5637382b4d2def63..f7df405663ce30f9faa0ae03db8992d1c9ce4ac5 100644 >--- a/Source/JavaScriptCore/bytecode/GetByStatus.cpp >+++ b/Source/JavaScriptCore/bytecode/GetByStatus.cpp >@@ -127,7 +127,7 @@ GetByStatus GetByStatus::computeFromLLInt(CodeBlock* profiledBlock, BytecodeInde > if (!structureID) > return GetByStatus(NoInformation, false); > >- Structure* structure = vm.heap.structureIDTable().get(structureID); >+ Structure* structure = structureID.decode(); > > if (structure->takesSlowPathInDFGForImpureProperty()) > return GetByStatus(NoInformation, false); >diff --git a/Source/JavaScriptCore/bytecode/InlineAccess.cpp b/Source/JavaScriptCore/bytecode/InlineAccess.cpp >index 7d18c4bb2bdf45d612bbd74a7e0b3e13ddc78ed7..21eb4c221d367a84f0299180da7c8e8a903b572c 100644 >--- a/Source/JavaScriptCore/bytecode/InlineAccess.cpp >+++ b/Source/JavaScriptCore/bytecode/InlineAccess.cpp >@@ -447,7 +447,7 @@ void InlineAccess::rewireStubAsJumpInAccess(CodeBlock* codeBlock, StructureStubI > } > > stubInfo.m_codePtr = target; >- stubInfo.m_inlineAccessBaseStructure = 0; // Clear out the inline access code. >+ stubInfo.m_inlineAccessBaseStructure = StructureID(); // Clear out the inline access code. > return; > } > >@@ -464,7 +464,7 @@ void InlineAccess::resetStubAsJumpInAccess(CodeBlock* codeBlock, StructureStubIn > { > if (codeBlock->useDataIC() && codeBlock->jitType() == JITType::BaselineJIT) { > stubInfo.m_codePtr = stubInfo.slowPathStartLocation; >- stubInfo.m_inlineAccessBaseStructure = 0; // Clear out the inline access code. >+ stubInfo.m_inlineAccessBaseStructure = StructureID(); // Clear out the inline access code. > return; > } > >diff --git a/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp b/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp >index e2b7b6628ac0ff5e405e88b04643a93ad61fd6fd..76fe6ae44a113e52db8a53eb37d3fec10144d727 100644 >--- a/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp >+++ b/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp >@@ -80,10 +80,10 @@ RefPtr<PolyProtoAccessChain> PolyProtoAccessChain::tryCreate(JSGlobalObject* glo > return adoptRef(*new PolyProtoAccessChain(WTFMove(chain))); > } > >-bool PolyProtoAccessChain::needImpurePropertyWatchpoint(VM& vm) const >+bool PolyProtoAccessChain::needImpurePropertyWatchpoint(VM&) const > { > for (StructureID structureID : m_chain) { >- if (vm.getStructure(structureID)->needImpurePropertyWatchpoint()) >+ if (structureID.decode()->needImpurePropertyWatchpoint()) > return true; > } > return false; >diff --git a/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h b/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >index a29b4bf69da74713b1c6284b503a641e963c7c79..107e4bf8772df044261ec858f0c9fe7c62fed5f8 100644 >--- a/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >+++ b/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h >@@ -25,7 +25,7 @@ > > #pragma once > >-#include "StructureIDTable.h" >+#include "StructureID.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& vm, Structure* baseStructure, const Func& func) const >+ void forEach(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(vm.getStructure(m_chain[i]), atEnd); >+ func(m_chain[i].decode(), atEnd); > } > } > >- Structure* slotBaseStructure(VM& vm, Structure* baseStructure) const >+ Structure* slotBaseStructure(VM&, Structure* baseStructure) const > { > if (m_chain.size()) >- return vm.getStructure(m_chain.last()); >+ return m_chain.last().decode(); > return baseStructure; > } > >diff --git a/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp b/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >index 4b9a4959fd8ff351d29dafca0972453b7bc16766..943768eed9a4078202cbb14a3b9c745a612be9f8 100644 >--- a/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >+++ b/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >@@ -381,7 +381,7 @@ bool PolymorphicAccess::visitWeak(VM& vm) const > } > if (m_stubRoutine) { > for (StructureID weakReference : m_stubRoutine->weakStructures()) { >- Structure* structure = vm.getStructure(weakReference); >+ Structure* structure = weakReference.decode(); > if (!vm.heap.isMarked(structure)) > return false; > } >diff --git a/Source/JavaScriptCore/bytecode/PutByIdFlags.h b/Source/JavaScriptCore/bytecode/PutByIdFlags.h >index 81d46718a5f75999acce9c10ff47175626683e37..3eac132947fce8aab84e85337f9d31f52f0aa2c3 100644 >--- a/Source/JavaScriptCore/bytecode/PutByIdFlags.h >+++ b/Source/JavaScriptCore/bytecode/PutByIdFlags.h >@@ -26,7 +26,6 @@ > #pragma once > > #include "ECMAMode.h" >-#include "StructureIDTable.h" > > namespace JSC { > >diff --git a/Source/JavaScriptCore/bytecode/PutByStatus.cpp b/Source/JavaScriptCore/bytecode/PutByStatus.cpp >index 92ac0948456c140e1a4599fbea4a6c69e2832f4e..5c6399760181f9afa66d55ed0ebe48cc14b1192c 100644 >--- a/Source/JavaScriptCore/bytecode/PutByStatus.cpp >+++ b/Source/JavaScriptCore/bytecode/PutByStatus.cpp >@@ -81,7 +81,7 @@ PutByStatus PutByStatus::computeFromLLInt(CodeBlock* profiledBlock, BytecodeInde > if (!structureID) > return PutByStatus(NoInformation); > >- Structure* structure = vm.heap.structureIDTable().get(structureID); >+ Structure* structure = structureID.decode(); > > StructureID newStructureID = metadata.m_newStructureID; > if (!newStructureID) { >@@ -92,7 +92,7 @@ PutByStatus PutByStatus::computeFromLLInt(CodeBlock* profiledBlock, BytecodeInde > return PutByVariant::replace(nullptr, structure, offset); > } > >- Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); >+ Structure* newStructure = newStructureID.decode(); > > ASSERT(structure->transitionWatchpointSetHasBeenInvalidated()); > >diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp >index 7fb7db29acd9af79fe660bbfcaee812f187cc2cc..a759dd0f116e2f86b1479e4a8da4046cd95b74e5 100644 >--- a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp >+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp >@@ -596,13 +596,7 @@ SpeculatedType speculationFromCell(JSCell* cell) > } > return SpecString; > } >- // 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); >+ return speculationFromStructure(cell->structure()); > } > > SpeculatedType speculationFromValue(JSValue value) >diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp >index 901fc5369a7ce68c37a721a9b4ca94ed327fdcff..8fcfb7c687d9decf4c68b02ba1607c7254281cfd 100644 >--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp >+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp >@@ -220,7 +220,7 @@ AccessGenerationResult StructureStubInfo::addAccessCase( > // we're buffered is because we rely on it to reset during GC if m_inlineAccessBaseStructure > // is collected. > m_identifier = nullptr; >- m_inlineAccessBaseStructure = 0; >+ m_inlineAccessBaseStructure = StructureID(); > > // If we generated some code then we don't want to attempt to repatch in the future until we > // gather enough cases. >@@ -235,7 +235,7 @@ void StructureStubInfo::reset(const ConcurrentJSLockerBase& locker, CodeBlock* c > { > clearBufferedStructures(); > m_identifier = nullptr; >- m_inlineAccessBaseStructure = 0; >+ m_inlineAccessBaseStructure = StructureID(); > > if (m_cacheType == CacheType::Unset) > return; >diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h >index 243519ae10c55875b503cd65acc167c75e4de858..73bb3e05a62ec0b21e761187831ef7d1397d9839 100644 >--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h >+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h >@@ -357,13 +357,13 @@ public: > union { > PolymorphicAccess* stub; > } u; >- Structure* inlineAccessBaseStructure(VM& vm) >+ Structure* inlineAccessBaseStructure(VM&) > { > if (!m_inlineAccessBaseStructure) > return nullptr; >- return vm.getStructure(m_inlineAccessBaseStructure); >+ return m_inlineAccessBaseStructure.decode(); > } >- StructureID m_inlineAccessBaseStructure { 0 }; >+ StructureID m_inlineAccessBaseStructure; > private: > CacheableIdentifier m_identifier; > // Represents those structures that already have buffered AccessCases in the PolymorphicAccess. >diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >index eb8a9ef5a8536eb0e56eef831d0fab3b36127a6b..3299f5c37ccc030afe1dcde9d02ed9233f42a1fb 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >@@ -2201,7 +2201,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > // 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 (isNuked(structureIDEarly)) >+ if (structureIDEarly.isNuked()) > return false; > > if (node->arrayMode().arrayClass() == Array::OriginalCopyOnWriteArray) { >@@ -2215,7 +2215,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > if (structureIDEarly != structureIDLate) > return false; > >- Structure* structure = m_vm.getStructure(structureIDLate); >+ Structure* structure = structureIDLate.decode(); > switch (node->arrayMode().type()) { > case Array::Int32: > case Array::Contiguous: >@@ -2273,7 +2273,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > if (structureIDEarly != structureIDLate) > return false; > >- Structure* structure = m_vm.getStructure(structureIDLate); >+ Structure* structure = structureIDLate.decode(); > if (!hasAnyArrayStorage(structure->indexingMode())) > return false; > >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index e1f9b87dc92ec08a1e2986129f5fb7ff7091f5fd..a1e950bfeea37be6f0fb342df1355f90a53dae47 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -5513,7 +5513,7 @@ void ByteCodeParser::parseBlock(unsigned limit) > StructureID cachedStructureID = metadata.m_cachedStructureID; > Structure* cachedStructure = nullptr; > if (cachedStructureID) >- cachedStructure = m_vm->heap.structureIDTable().get(cachedStructureID); >+ cachedStructure = cachedStructureID.decode(); > if (metadata.m_toThisStatus != ToThisOK > || !cachedStructure > || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis >diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp >index 8c6adec5e35946de260c3cdb2cb601d49e9cf245..144cc192873d076e1effbf84dde6e161a85c1778 100644 >--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp >+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp >@@ -262,7 +262,7 @@ void Graph::dump(PrintStream& out, const char* prefixStr, Node* node, DumpContex > if (node->hasTransition()) { > out.print(comma, pointerDumpInContext(node->transition(), context)); > #if USE(JSVALUE64) >- out.print(", ID:", node->transition()->next->id()); >+ out.print(", ID:", node->transition()->next->id().bits()); > #else > out.print(", ID:", RawPointer(node->transition()->next.get())); > #endif >diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h >index 361747781fcd6e7915e7a25968465d07b691b29e..483f96f8a44e74b6430c8cfef49be14bd5c641e1 100644 >--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h >+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h >@@ -268,7 +268,7 @@ public: > { > Structure* structure = weakStructure.get(); > #if USE(JSVALUE64) >- Jump result = branch32(cond, left, TrustedImm32(structure->id())); >+ Jump result = branch32(cond, left, TrustedImm32(structure->id().bits())); > return result; > #else > return branchPtr(cond, left, TrustedImmPtr(structure)); >diff --git a/Source/JavaScriptCore/dfg/DFGPlan.cpp b/Source/JavaScriptCore/dfg/DFGPlan.cpp >index c2bbd5e9c3e835da91e9615ee1f83f836dd06ddd..0ebc2a8311965a9ceb009336bc463f7c0476eaef 100644 >--- a/Source/JavaScriptCore/dfg/DFGPlan.cpp >+++ b/Source/JavaScriptCore/dfg/DFGPlan.cpp >@@ -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(m_vm->getStructure(structureID)); >+ trackedReferences.add(structureID.decode()); > for (WriteBarrier<Unknown>& constant : m_codeBlock->constants()) > trackedReferences.add(constant.get()); > >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index 525ae17c7cfbb6cae0ab4d39992438622f1385d5..b072cda704675b87bb30c270e4ca0123a0cdacae 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -8533,8 +8533,7 @@ void SpeculativeJIT::compileGetGlobalObject(Node* node) > { > SpeculateCellOperand object(this, node->child1()); > GPRTemporary result(this); >- GPRTemporary scratch(this); >- m_jit.emitLoadStructure(vm(), object.gpr(), result.gpr(), scratch.gpr()); >+ m_jit.emitLoadStructure(vm(), object.gpr(), result.gpr()); > m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), result.gpr()); > cellResult(result.gpr(), node); > } >@@ -11042,7 +11041,7 @@ void SpeculativeJIT::compileCheckJSCast(Node* node) > GPRReg otherGPR = other.gpr(); > GPRReg specifiedGPR = specified.gpr(); > >- m_jit.emitLoadStructure(vm(), baseGPR, otherGPR, specifiedGPR); >+ m_jit.emitLoadStructure(vm(), baseGPR, otherGPR); > m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR); > m_jit.move(CCallHelpers::TrustedImmPtr(node->classInfo()), specifiedGPR); > >@@ -11253,7 +11252,7 @@ void SpeculativeJIT::compileFunctionToString(Node* node) > > speculateFunction(node->child1(), function.gpr()); > >- m_jit.emitLoadStructure(vm(), function.gpr(), result.gpr(), executable.gpr()); >+ m_jit.emitLoadStructure(vm(), function.gpr(), result.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()))); >@@ -14268,13 +14267,11 @@ void SpeculativeJIT::compileGetPropertyEnumerator(Node* node) > 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; >@@ -14326,7 +14323,7 @@ void SpeculativeJIT::compileGetPropertyEnumerator(Node* node) > if (onlyStructure) > m_jit.move(TrustedImmPtr(onlyStructure), scratch1GPR); > else >- m_jit.emitLoadStructure(vm(), baseRegs.payloadGPR(), scratch1GPR, scratch2GPR); >+ m_jit.emitLoadStructure(vm(), baseRegs.payloadGPR(), scratch1GPR); > m_jit.loadPtr(CCallHelpers::Address(scratch1GPR, Structure::previousOrRareDataOffset()), scratch1GPR); > slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratch1GPR)); > slowCases.append(m_jit.branchIfStructure(scratch1GPR)); >@@ -14338,7 +14335,7 @@ void SpeculativeJIT::compileGetPropertyEnumerator(Node* node) > doneCases.append(m_jit.jump()); > > slowCases.link(&m_jit); >- silentSpillAllRegisters(scratch1GPR, scratch2GPR); >+ silentSpillAllRegisters(scratch1GPR); > callOperation(operationGetPropertyEnumeratorCell, scratch1GPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseRegs.payloadGPR()); > silentFillAllRegisters(); > m_jit.exceptionCheck(); >@@ -14605,7 +14602,7 @@ void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node) > speculateObject(node->child1(), objectGPR); > > CCallHelpers::JumpList slowCases; >- m_jit.emitLoadStructure(vm(), objectGPR, structureGPR, scratchGPR); >+ m_jit.emitLoadStructure(vm(), objectGPR, structureGPR); > m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::previousOrRareDataOffset()), scratchGPR); > > slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratchGPR)); >@@ -15332,15 +15329,14 @@ void SpeculativeJIT::compileWeakMapSet(Node* node) > 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 >- JSValueRegs resultRegs(temp2GPR, tempGPR); >+ GPRTemorary temp2(this); >+ JSValueRegs resultRegs(temp2.gpr(), tempGPR); > #endif > > switch (node->child1().useKind()) { >@@ -15365,7 +15361,7 @@ void SpeculativeJIT::compileGetPrototypeOf(Node* node) > break; > } > >- m_jit.emitLoadStructure(vm(), objectGPR, tempGPR, temp2GPR); >+ m_jit.emitLoadStructure(vm(), objectGPR, tempGPR); > > AbstractValue& value = m_state.forNode(node->child1()); > if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) { >@@ -15404,7 +15400,7 @@ void SpeculativeJIT::compileGetPrototypeOf(Node* node) > speculateObject(node->child1(), objectGPR); > > JITCompiler::JumpList slowCases; >- m_jit.emitLoadPrototype(vm(), objectGPR, resultRegs, temp2GPR, slowCases); >+ m_jit.emitLoadPrototype(vm(), objectGPR, resultRegs, slowCases); > addSlowPathGenerator(slowPathCall(slowCases, this, operationGetPrototypeOfObject, > resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), objectGPR)); > >@@ -15421,7 +15417,7 @@ void SpeculativeJIT::compileGetPrototypeOf(Node* node) > GPRReg valueGPR = valueRegs.payloadGPR(); > slowCases.append(m_jit.branchIfNotObject(valueGPR)); > >- m_jit.emitLoadPrototype(vm(), valueGPR, resultRegs, temp2GPR, slowCases); >+ m_jit.emitLoadPrototype(vm(), valueGPR, resultRegs, slowCases); > addSlowPathGenerator(slowPathCall(slowCases, this, operationGetPrototypeOf, > resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), valueRegs)); > >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >index 77073f34afbfdf95fe5825a3c8989c3223ddaa5a..691257e40d0fae09f45e3c7fbdaae14c7c29f1e2 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >@@ -244,7 +244,6 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operan > } else { > GPRTemporary localGlobalObject(this); > GPRTemporary remoteGlobalObject(this); >- GPRTemporary scratch(this); > > JITCompiler::Jump notCell; > if (!isKnownCell(operand.node())) >@@ -259,7 +258,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operan > 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, scratch.gpr()); >+ m_jit.emitLoadStructure(vm(), argGPR, resultGPR); > m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR); > m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultGPR); > done.append(m_jit.jump()); >@@ -299,7 +298,6 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, N > } else { > GPRTemporary localGlobalObject(this); > GPRTemporary remoteGlobalObject(this); >- GPRTemporary scratch(this); > > JITCompiler::Jump notCell; > if (!isKnownCell(operand.node())) >@@ -312,7 +310,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, N > 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, scratch.gpr()); >+ m_jit.emitLoadStructure(vm(), argGPR, resultGPR); > m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR); > branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, taken); > >@@ -1905,8 +1903,6 @@ void SpeculativeJIT::compileToBooleanObjectOrOther(Edge nodeUse, bool invert) > GPRReg resultGPR = result.gpr(); > GPRTemporary structure; > GPRReg structureGPR = InvalidGPRReg; >- GPRTemporary scratch; >- GPRReg scratchGPR = InvalidGPRReg; > > bool masqueradesAsUndefinedWatchpointValid = > masqueradesAsUndefinedWatchpointIsStillValid(); >@@ -1915,11 +1911,8 @@ void SpeculativeJIT::compileToBooleanObjectOrOther(Edge nodeUse, bool invert) > // 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)); >@@ -1936,7 +1929,7 @@ void SpeculativeJIT::compileToBooleanObjectOrOther(Edge nodeUse, bool invert) > MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), > MacroAssembler::TrustedImm32(MasqueradesAsUndefined)); > >- m_jit.emitLoadStructure(vm(), valueGPR, structureGPR, scratchGPR); >+ m_jit.emitLoadStructure(vm(), valueGPR, structureGPR); > speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, > m_jit.branchPtr( > MacroAssembler::Equal, >@@ -2091,7 +2084,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, Ba > MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), > TrustedImm32(MasqueradesAsUndefined)); > >- m_jit.emitLoadStructure(vm(), valueGPR, structureGPR, scratchGPR); >+ m_jit.emitLoadStructure(vm(), valueGPR, structureGPR); > speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, > m_jit.branchPtr( > MacroAssembler::Equal, >@@ -2185,7 +2178,7 @@ void SpeculativeJIT::emitUntypedBranch(Edge nodeUse, BasicBlock* taken, BasicBlo > bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid(); > if (shouldCheckMasqueradesAsUndefined) { > branchTest8(MacroAssembler::Zero, MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), taken); >- m_jit.emitLoadStructure(vm(), valueGPR, temp1GPR, temp2GPR); >+ m_jit.emitLoadStructure(vm(), valueGPR, temp1GPR); > 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); >@@ -4446,7 +4439,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()), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset())); >+ m_jit.store32(MacroAssembler::TrustedImm32(newStructure->id().bits()), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset())); > > noResult(node); > break; >@@ -4665,7 +4658,6 @@ 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()); > >@@ -4689,7 +4681,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(), scratch.gpr()); >+ m_jit.emitLoadStructure(vm(), value.gpr(), result.gpr()); > m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR); > m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr()); > } >diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >index 771e6286dede66af8150aaa62c1f386dccdb1c87..0cd7214974748cb9efda9e206be84db519322bdd 100644 >--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >@@ -13709,7 +13709,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()); >+ structureID = m_out.constInt32(structure->id().bits()); > else > structureID = m_out.load32(base, m_heaps.JSCell_structureID); > >@@ -16788,7 +16788,7 @@ IGNORE_CLANG_WARNINGS_END > > void storeStructure(LValue object, Structure* structure) > { >- m_out.store32(m_out.constInt32(structure->id()), object, m_heaps.JSCell_structureID); >+ m_out.store32(m_out.constInt32(structure->id().bits()), object, m_heaps.JSCell_structureID); > m_out.store32( > m_out.constInt32(structure->objectInitializationBlob()), > object, m_heaps.JSCell_usefulBytes); >@@ -19569,7 +19569,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())); >+ m_out.constInt32(vm().stringStructure->id().bits())); > } > > LValue isString(LValue cell, SpeculatedType type = SpecFullTop) >@@ -19578,7 +19578,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())); >+ m_out.constInt32(vm().stringStructure->id().bits())); > } > > LValue isRopeString(LValue string, Edge edge = Edge()) >@@ -19625,7 +19625,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())); >+ m_out.constInt32(vm().symbolStructure->id().bits())); > } > > LValue isSymbol(LValue cell, SpeculatedType type = SpecFullTop) >@@ -19634,7 +19634,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())); >+ m_out.constInt32(vm().symbolStructure->id().bits())); > } > > LValue isNotHeapBigIntUnknownWhetherCell(LValue value, SpeculatedType type = SpecFullTop) >@@ -19663,7 +19663,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())); >+ m_out.constInt32(vm().bigIntStructure->id().bits())); > } > > LValue isHeapBigInt(LValue cell, SpeculatedType type = SpecFullTop) >@@ -19672,7 +19672,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())); >+ m_out.constInt32(vm().bigIntStructure->id().bits())); > } > > LValue isArrayTypeForArrayify(LValue cell, ArrayMode arrayMode) >@@ -20399,7 +20399,7 @@ IGNORE_CLANG_WARNINGS_END > m_out.store32( > m_out.bitOr( > m_out.load32(object, m_heaps.JSCell_structureID), >- m_out.constInt32(nukedStructureIDBit())), >+ m_out.constInt32(StructureID::nukedStructureIDBit)), > object, m_heaps.JSCell_structureID); > m_out.fence(&m_heaps.root, nullptr); > m_out.storePtr(butterfly, object, m_heaps.JSObject_butterfly); >@@ -20427,7 +20427,7 @@ IGNORE_CLANG_WARNINGS_END > m_out.store32( > m_out.bitOr( > m_out.load32(object, m_heaps.JSCell_structureID), >- m_out.constInt32(nukedStructureIDBit())), >+ m_out.constInt32(StructureID::nukedStructureIDBit)), > object, m_heaps.JSCell_structureID); > m_out.fence(&m_heaps.root, nullptr); > m_out.storePtr(butterfly, object, m_heaps.JSObject_butterfly); >@@ -20975,12 +20975,8 @@ IGNORE_CLANG_WARNINGS_END > LValue loadStructure(LValue value) > { > LValue structureID = m_out.load32(value, m_heaps.JSCell_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 maskedStructureID = m_out.bitAnd(structureID, m_out.constInt32(structureIDMask)); >+ return m_out.add(m_out.constIntPtr(g_jscConfig.startOfStructureHeap), m_out.zeroExtPtr(maskedStructureID)); > } > > LValue weakPointer(JSCell* pointer) >@@ -20996,7 +20992,7 @@ IGNORE_CLANG_WARNINGS_END > > LValue weakStructureID(RegisteredStructure structure) > { >- return m_out.constInt32(structure->id()); >+ return m_out.constInt32(structure->id().bits()); > } > > LValue weakStructure(RegisteredStructure structure) >diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp >index 0b4838c90b8c7fb35fccce92611f3fc2dc0c9a59..05e3c7e2f7bd434349cf0c9b83d383e874a17e08 100644 >--- a/Source/JavaScriptCore/heap/Heap.cpp >+++ b/Source/JavaScriptCore/heap/Heap.cpp >@@ -1493,8 +1493,6 @@ NEVER_INLINE bool Heap::runEndPhase(GCConductor conn) > if (vm().typeProfiler()) > vm().typeProfiler()->invalidateTypeSetCache(vm()); > >- m_structureIDTable.flushOldTables(); >- > reapWeakHandles(); > pruneStaleEntriesFromWeakGCHashTables(); > sweepArrayBuffers(); >diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h >index be579934d4dcc93afdb0758346329c1b29c36dbf..36f0c4bb992c3b1a503e151041ce4674d3e67229 100644 >--- a/Source/JavaScriptCore/heap/Heap.h >+++ b/Source/JavaScriptCore/heap/Heap.h >@@ -37,7 +37,7 @@ > #include "MarkedSpace.h" > #include "MutatorState.h" > #include "Options.h" >-#include "StructureIDTable.h" >+#include "StructureID.h" > #include "Synchronousness.h" > #include "WeakHandleOwner.h" > #include <wtf/AutomaticThread.h> >@@ -267,8 +267,6 @@ public: > > bool isDeferred() const { return !!m_deferralDepth; } > >- StructureIDTable& structureIDTable() { return m_structureIDTable; } >- > CodeBlockSet& codeBlockSet() { return *m_codeBlocks; } > > #if USE(FOUNDATION) >@@ -588,7 +586,6 @@ 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 }; >diff --git a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >index f729373119312bc864735138622c0da441102589..41954ba809d13d58908e3a397451285018857024 100644 >--- a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >+++ b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >@@ -30,72 +30,13 @@ > namespace JSC { > > IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator(CString name) >-#if ENABLE(MALLOC_HEAP_BREAKDOWN) >- : m_debugHeap(name.data()) >-#endif >+ : Base(name) > { >- UNUSED_PARAM(name); > } > > IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator() > { >-#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 >+ releaseMemoryFromSubclassDestructor(); > } > > void IsoAlignedMemoryAllocator::dump(PrintStream& out) const >@@ -127,5 +68,25 @@ void* IsoAlignedMemoryAllocator::tryReallocateMemory(void*, size_t) > 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 > >diff --git a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >index 2bb65170467dd65baf233c65926261bc755033cc..df7d77da38fa82c348f204ca3d20f290b03f2aa4 100644 >--- a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >+++ b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >@@ -25,7 +25,7 @@ > > #pragma once > >-#include "AlignedMemoryAllocator.h" >+#include "IsoMemoryAllocatorBase.h" > #include <wtf/BitVector.h> > #include <wtf/DebugHeap.h> > #include <wtf/HashMap.h> >@@ -34,31 +34,24 @@ > > namespace JSC { > >-class IsoAlignedMemoryAllocator final : public AlignedMemoryAllocator { >+class IsoAlignedMemoryAllocator final : public IsoMemoryAllocatorBase { > 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; > >-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 >+protected: >+ void* tryMallocBlock() final; >+ void freeBlock(void* block) final; >+ void commitBlock(void* block) final; >+ void decommitBlock(void* block) final; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.cpp b/Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..223bee5cb29e02d89173e444829213288dfe1da4 >--- /dev/null >+++ b/Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.cpp >@@ -0,0 +1,108 @@ >+/* >+ * 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 >+ >diff --git a/Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.h b/Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5fdb8ff5577432b77ada39cc19663b5bf498ce0a >--- /dev/null >+++ b/Source/JavaScriptCore/heap/IsoMemoryAllocatorBase.h >@@ -0,0 +1,67 @@ >+/* >+ * 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 >+ >diff --git a/Source/JavaScriptCore/heap/IsoSubspace.cpp b/Source/JavaScriptCore/heap/IsoSubspace.cpp >index b8f096ad7f4b1e7cf1cd7b8b8889a9955bb016fe..1ed2e2903b3928480eacb30cb0931d45b6bc2009 100644 >--- a/Source/JavaScriptCore/heap/IsoSubspace.cpp >+++ b/Source/JavaScriptCore/heap/IsoSubspace.cpp >@@ -26,18 +26,18 @@ > #include "config.h" > #include "IsoSubspace.h" > >-#include "IsoAlignedMemoryAllocator.h" > #include "IsoCellSetInlines.h" >+#include "IsoMemoryAllocatorBase.h" > #include "JSCellInlines.h" > #include "MarkedSpaceInlines.h" > > namespace JSC { > >-IsoSubspace::IsoSubspace(CString name, Heap& heap, const HeapCellType& heapCellType, size_t size, uint8_t numberOfLowerTierCells) >+IsoSubspace::IsoSubspace(CString name, Heap& heap, const HeapCellType& heapCellType, size_t size, uint8_t numberOfLowerTierCells, std::unique_ptr<IsoMemoryAllocatorBase>&& allocator) > : Subspace(name, heap) > , m_directory(WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size)) > , m_localAllocator(&m_directory) >- , m_isoAlignedMemoryAllocator(makeUnique<IsoAlignedMemoryAllocator>(name)) >+ , m_isoAlignedMemoryAllocator(allocator ? WTFMove(allocator) : makeUnique<IsoAlignedMemoryAllocator>(name)) > { > m_remainingLowerTierCellCount = numberOfLowerTierCells; > ASSERT(WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size) == cellSize()); >@@ -109,8 +109,9 @@ void* IsoSubspace::tryAllocateFromLowerTier() > return revive(allocation); > } > if (m_remainingLowerTierCellCount) { >- PreciseAllocation* allocation = PreciseAllocation::createForLowerTier(m_space.heap(), cellSize(), this, --m_remainingLowerTierCellCount); >- return revive(allocation); >+ PreciseAllocation* allocation = PreciseAllocation::tryCreateForLowerTier(m_space.heap(), cellSize(), this, --m_remainingLowerTierCellCount); >+ if (allocation) >+ return revive(allocation); > } > return nullptr; > } >diff --git a/Source/JavaScriptCore/heap/IsoSubspace.h b/Source/JavaScriptCore/heap/IsoSubspace.h >index eacbd6515ce237234218d7aac75354d1dc9e1c3a..4b18bc0ffd4aabc230ff7297f6ec5b3cb68c9963 100644 >--- a/Source/JavaScriptCore/heap/IsoSubspace.h >+++ b/Source/JavaScriptCore/heap/IsoSubspace.h >@@ -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, uint8_t numberOfLowerTierCells); >+ JS_EXPORT_PRIVATE IsoSubspace(CString name, Heap&, const HeapCellType&, size_t size, uint8_t numberOfLowerTierCells, std::unique_ptr<IsoMemoryAllocatorBase>&& = nullptr); > JS_EXPORT_PRIVATE ~IsoSubspace() override; > > size_t cellSize() { return m_directory.cellSize(); } >@@ -67,7 +67,7 @@ private: > > BlockDirectory m_directory; > LocalAllocator m_localAllocator; >- std::unique_ptr<IsoAlignedMemoryAllocator> m_isoAlignedMemoryAllocator; >+ std::unique_ptr<IsoMemoryAllocatorBase> m_isoAlignedMemoryAllocator; > SentinelLinkedList<PreciseAllocation, PackedRawSentinelNode<PreciseAllocation>> m_lowerTierFreeList; > SentinelLinkedList<IsoCellSet, PackedRawSentinelNode<IsoCellSet>> m_cellSets; > }; >diff --git a/Source/JavaScriptCore/heap/PreciseAllocation.cpp b/Source/JavaScriptCore/heap/PreciseAllocation.cpp >index fa1bf3c3dc1c1415b4de4939461cae81e53045a0..836e7da64a98c72f33be6376b8b3342531776ad6 100644 >--- a/Source/JavaScriptCore/heap/PreciseAllocation.cpp >+++ b/Source/JavaScriptCore/heap/PreciseAllocation.cpp >@@ -120,7 +120,7 @@ PreciseAllocation* PreciseAllocation::tryReallocate(size_t size, Subspace* subsp > } > > >-PreciseAllocation* PreciseAllocation::createForLowerTier(Heap& heap, size_t size, Subspace* subspace, uint8_t lowerTierIndex) >+PreciseAllocation* PreciseAllocation::tryCreateForLowerTier(Heap& heap, size_t size, Subspace* subspace, uint8_t lowerTierIndex) > { > if constexpr (validateDFGDoesGC) > heap.vm().verifyCanGC(); >diff --git a/Source/JavaScriptCore/heap/PreciseAllocation.h b/Source/JavaScriptCore/heap/PreciseAllocation.h >index 9ce3da8ef3ba5184bcedfa2d7ab36f016d6bf51f..e79a27bb3f2424ed2c1da4898c1794a52a306971 100644 >--- a/Source/JavaScriptCore/heap/PreciseAllocation.h >+++ b/Source/JavaScriptCore/heap/PreciseAllocation.h >@@ -45,7 +45,7 @@ public: > > static PreciseAllocation* tryCreate(Heap&, size_t, Subspace*, unsigned indexInSpace); > >- static PreciseAllocation* createForLowerTier(Heap&, size_t, Subspace*, uint8_t lowerTierIndex); >+ static PreciseAllocation* tryCreateForLowerTier(Heap&, size_t, Subspace*, uint8_t lowerTierIndex); > PreciseAllocation* reuseForLowerTier(); > > PreciseAllocation* tryReallocate(size_t, Subspace*); >diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp >index 4981795745240c8482c29f9a1c4d4ea2fbbcc4c9..0ed06be5fd182eb9013310a3e564b5b07e479969 100644 >--- a/Source/JavaScriptCore/heap/SlotVisitor.cpp >+++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp >@@ -152,10 +152,9 @@ void SlotVisitor::appendJSCellOrAuxiliary(HeapCell* heapCell) > out.print("GC type: ", heap()->collectionScope(), "\n"); > out.print("Object at: ", RawPointer(jsCell), "\n"); > #if USE(JSVALUE64) >- out.print("Structure ID: ", structureID, " (0x", format("%x", structureID), ")\n"); >- out.print("Structure ID table size: ", heap()->structureIDTable().size(), "\n"); >+ out.print("Structure ID: ", structureID.bits(), " (", RawPointer(structureID.decode()), ")\n"); > #else >- out.print("Structure: ", RawPointer(structureID), "\n"); >+ out.print("Structure: ", RawPointer(structureID.decode()), "\n"); > #endif > out.print("Object contents:"); > for (unsigned i = 0; i < 2; ++i) >@@ -186,13 +185,13 @@ void SlotVisitor::appendJSCellOrAuxiliary(HeapCell* heapCell) > 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 (isNuked(structureID)) >+ if (structureID.isNuked()) > die("GC scan found object in bad state: structureID is nuked!\n"); >- >+ > // This detects the worst of the badness. >- Integrity::auditStructureID(heap()->structureIDTable(), structureID); >+ Integrity::auditStructureID(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())) >diff --git a/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp b/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..81e09470b507846d6e1ba944dd1fea012a2b7292 >--- /dev/null >+++ b/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp >@@ -0,0 +1,198 @@ >+/* >+ * 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)); >+ >+ s_structureMemoryManager.construct(); >+ >+ // Double the size so we can ensure enough mapped memory to get an aligned start. >+ size_t mappedSize = structureHeapAddressSize * 2; >+ char* mapped = reinterpret_cast<char*>(OSAllocator::reserveUncommitted(mappedSize, OSAllocator::FastMallocPages)); >+ if (!mapped) >+ CRASH(); >+ char* mappedEnd = mapped + mappedSize; >+ >+ char* aligned = roundUpToMultipleOf<structureHeapAddressSize>(mapped); >+ char* alignedEnd = aligned + structureHeapAddressSize; >+ >+ RELEASE_ASSERT(alignedEnd <= mappedEnd); >+ >+ if (size_t leftExtra = aligned - mapped) >+ OSAllocator::releaseDecommitted(mapped, leftExtra); >+ >+ if (size_t rightExtra = mappedEnd - alignedEnd) >+ OSAllocator::releaseDecommitted(alignedEnd, rightExtra); >+ >+ g_jscConfig.startOfStructureHeap = reinterpret_cast<uintptr_t>(aligned); >+ 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 >+ >diff --git a/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.h b/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b255cfb28c2119188a7ef97709224e71095a8c01 >--- /dev/null >+++ b/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.h >@@ -0,0 +1,60 @@ >+/* >+ * 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 >+ >diff --git a/Source/JavaScriptCore/heap/StructureAllignedMemoryAllocator.h b/Source/JavaScriptCore/heap/StructureAllignedMemoryAllocator.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9cab41d7342c68a0a2101bf66f5c317f47420aad >--- /dev/null >+++ b/Source/JavaScriptCore/heap/StructureAllignedMemoryAllocator.h >@@ -0,0 +1,58 @@ >+/* >+ * 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 "AlignedMemoryAllocator.h" >+#include <wtf/Gigacage.h> >+ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#include <wtf/DebugHeap.h> >+#endif >+ >+namespace JSC { >+ >+class StructureAlignedMemoryAllocator final : public IsoMemoryAllocatorBase { >+public: >+ StructureAlignedMemoryAllocator(Gigacage::Kind); >+ ~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 >+ >diff --git a/Source/JavaScriptCore/jit/AssemblyHelpers.cpp b/Source/JavaScriptCore/jit/AssemblyHelpers.cpp >index e6458531ebc904de5dd04ce3aba53c5bd3c70b0f..93d9b33a3d452a17a11d3afdb8eb26f66746c1db 100644 >--- a/Source/JavaScriptCore/jit/AssemblyHelpers.cpp >+++ b/Source/JavaScriptCore/jit/AssemblyHelpers.cpp >@@ -320,7 +320,7 @@ void AssemblyHelpers::emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, Trust > #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())); >+ Jump correctStructure = jit.branch32(Equal, MacroAssembler::Address(dest, JSCell::structureIDOffset()), TrustedImm32(structurePtr->id().bits())); > jit.abortWithReason(AHStructureIDIsValid); > correctStructure.link(&jit); > >@@ -389,44 +389,23 @@ void AssemblyHelpers::storeProperty(JSValueRegs value, GPRReg object, GPRReg off > BaseIndex(scratch, offset, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue))); > } > >-void AssemblyHelpers::emitLoadStructure(VM& vm, RegisterID source, RegisterID dest, RegisterID scratch) >+void AssemblyHelpers::emitLoadStructure(VM&, RegisterID source, RegisterID dest) > { >-#if USE(JSVALUE64) >-#if CPU(ARM64) >- RegisterID scratch2 = dataTempRegister; >-#elif CPU(X86_64) >- RegisterID scratch2 = scratchRegister(); >-#else >-#error "Unsupported cpu" >-#endif >- >- 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) >+ load32(MacroAssembler::Address(source, JSCell::structureIDOffset()), 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) > } > >-void AssemblyHelpers::emitLoadPrototype(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, JumpList& slowPath) >+void AssemblyHelpers::emitLoadPrototype(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, JumpList& slowPath) > { > ASSERT(resultRegs.payloadGPR() != objectGPR); >- ASSERT(resultRegs.payloadGPR() != scratchGPR); >- ASSERT(objectGPR != scratchGPR); > >- emitLoadStructure(vm, objectGPR, resultRegs.payloadGPR(), scratchGPR); >+ emitLoadStructure(vm, objectGPR, resultRegs.payloadGPR()); > >- load16(MacroAssembler::Address(resultRegs.payloadGPR(), Structure::outOfLineTypeFlagsOffset()), scratchGPR); >- auto overridesGetPrototype = branchTest32(MacroAssembler::NonZero, scratchGPR, TrustedImm32(OverridesGetPrototypeOutOfLine)); >+ auto overridesGetPrototype = branchTest32(MacroAssembler::NonZero, MacroAssembler::Address(resultRegs.payloadGPR(), Structure::outOfLineTypeFlagsOffset()), TrustedImm32(OverridesGetPrototypeOutOfLine)); > slowPath.append(overridesGetPrototype); > > loadValue(MacroAssembler::Address(resultRegs.payloadGPR(), Structure::prototypeOffset()), resultRegs); >@@ -525,7 +504,7 @@ void AssemblyHelpers::emitRandomThunk(JSGlobalObject* globalObject, GPRReg scrat > void AssemblyHelpers::emitRandomThunk(VM& vm, GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg result) > { > emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, scratch3); >- emitLoadStructure(vm, scratch3, scratch3, scratch0); >+ emitLoadStructure(vm, scratch3, scratch3); > loadPtr(Address(scratch3, Structure::globalObjectOffset()), scratch3); > // Now, scratch3 holds JSGlobalObject*. > >@@ -838,7 +817,7 @@ void AssemblyHelpers::emitConvertValueToBoolean(VM& vm, JSValueRegs value, GPRRe > ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg); > JumpList isNotMasqueradesAsUndefined; > isNotMasqueradesAsUndefined.append(branchTest8(Zero, Address(value.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined))); >- emitLoadStructure(vm, value.payloadGPR(), result, scratchIfShouldCheckMasqueradesAsUndefined); >+ emitLoadStructure(vm, value.payloadGPR(), result); > move(TrustedImmPtr(globalObject), scratchIfShouldCheckMasqueradesAsUndefined); > isNotMasqueradesAsUndefined.append(branchPtr(NotEqual, Address(result, Structure::globalObjectOffset()), scratchIfShouldCheckMasqueradesAsUndefined)); > >@@ -929,7 +908,7 @@ AssemblyHelpers::JumpList AssemblyHelpers::branchIfValue(VM& vm, JSValueRegs val > ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg); > JumpList isNotMasqueradesAsUndefined; > isNotMasqueradesAsUndefined.append(branchTest8(Zero, Address(value.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined))); >- emitLoadStructure(vm, value.payloadGPR(), scratch, scratchIfShouldCheckMasqueradesAsUndefined); >+ emitLoadStructure(vm, value.payloadGPR(), scratch); > if (std::holds_alternative<JSGlobalObject*>(globalObject)) > move(TrustedImmPtr(std::get<JSGlobalObject*>(globalObject)), scratchIfShouldCheckMasqueradesAsUndefined); > else >diff --git a/Source/JavaScriptCore/jit/AssemblyHelpers.h b/Source/JavaScriptCore/jit/AssemblyHelpers.h >index a44aa5cf954f2c165479ec2dcd923d5ff4f3d1f8..bee43637cfe95bf0c4a47258e08014880522ed67 100644 >--- a/Source/JavaScriptCore/jit/AssemblyHelpers.h >+++ b/Source/JavaScriptCore/jit/AssemblyHelpers.h >@@ -1103,7 +1103,7 @@ public: > Jump branchStructure(RelationalCondition condition, T leftHandSide, Structure* structure) > { > #if USE(JSVALUE64) >- return branch32(condition, leftHandSide, TrustedImm32(structure->id())); >+ return branch32(condition, leftHandSide, TrustedImm32(structure->id().bits())); > #else > return branchPtr(condition, leftHandSide, TrustedImmPtr(structure)); > #endif >@@ -1546,8 +1546,8 @@ public: > return argumentCount(codeOrigin.inlineCallFrame()); > } > >- void emitLoadStructure(VM&, RegisterID source, RegisterID dest, RegisterID scratch); >- void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, JumpList& slowPath); >+ void emitLoadStructure(VM&, RegisterID source, RegisterID dest); >+ void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, JumpList& slowPath); > > void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID) > { >@@ -1632,13 +1632,13 @@ public: > void nukeStructureAndStoreButterfly(VM& vm, GPRReg butterfly, GPRReg object) > { > if (isX86()) { >- or32(TrustedImm32(bitwise_cast<int32_t>(nukedStructureIDBit())), Address(object, JSCell::structureIDOffset())); >+ or32(TrustedImm32(bitwise_cast<int32_t>(StructureID::nukedStructureIDBit)), Address(object, JSCell::structureIDOffset())); > storePtr(butterfly, Address(object, JSObject::butterflyOffset())); > return; > } > > Jump ok = jumpIfMutatorFenceNotNeeded(vm); >- or32(TrustedImm32(bitwise_cast<int32_t>(nukedStructureIDBit())), Address(object, JSCell::structureIDOffset())); >+ or32(TrustedImm32(bitwise_cast<int32_t>(StructureID::nukedStructureIDBit)), Address(object, JSCell::structureIDOffset())); > storeFence(); > storePtr(butterfly, Address(object, JSObject::butterflyOffset())); > storeFence(); >diff --git a/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp b/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp >index 20c2ce49bd44af1b13f0f4a1e11535d6661aeaa6..f03321c54d96603e5fcf2974e13e09900ecebc33 100644 >--- a/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp >+++ b/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp >@@ -99,7 +99,7 @@ unsigned PolymorphicAccessJITStubRoutine::computeHash(const FixedVector<RefPtr<A > for (auto& key : cases) > WTF::add(hasher, key->hash()); > for (auto& structureID : weakStructures) >- WTF::add(hasher, structureID); >+ WTF::add(hasher, structureID.bits()); > return hasher.hash(); > } > >diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp >index 2fe23c49fd0f94091f68605b757ae2ce322014a2..c5128f73a2f07d1a40263284179ecc73fd1ae2a3 100644 >--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp >+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp >@@ -247,7 +247,7 @@ void JIT::emit_op_typeof_is_undefined(const Instruction* currentInstruction) > Jump notMasqueradesAsUndefined = jump(); > > isMasqueradesAsUndefined.link(this); >- emitLoadStructure(vm(), regT0, regT1, regT2); >+ emitLoadStructure(vm(), regT0, regT1); > loadGlobalObject(regT0); > loadPtr(Address(regT1, Structure::globalObjectOffset()), regT1); > comparePtr(Equal, regT0, regT1, regT0); >@@ -493,7 +493,7 @@ void JIT::emit_op_jeq_null(const Instruction* currentInstruction) > > // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. > Jump isNotMasqueradesAsUndefined = branchTest8(Zero, Address(regT0, JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)); >- emitLoadStructure(vm(), regT0, regT2, regT1); >+ emitLoadStructure(vm(), regT0, regT2); > loadGlobalObject(regT0); > addJump(branchPtr(Equal, Address(regT2, Structure::globalObjectOffset()), regT0), target); > Jump masqueradesGlobalObjectIsForeign = jump(); >@@ -517,7 +517,7 @@ void JIT::emit_op_jneq_null(const Instruction* currentInstruction) > > // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure. > addJump(branchTest8(Zero, Address(regT0, JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target); >- emitLoadStructure(vm(), regT0, regT2, regT1); >+ emitLoadStructure(vm(), regT0, regT2); > loadGlobalObject(regT0); > addJump(branchPtr(NotEqual, Address(regT2, Structure::globalObjectOffset()), regT0), target); > Jump wasNotImmediate = jump(); >@@ -1113,7 +1113,7 @@ void JIT::emit_op_eq_null(const Instruction* currentInstruction) > Jump wasNotMasqueradesAsUndefined = jump(); > > isMasqueradesAsUndefined.link(this); >- emitLoadStructure(vm(), regT0, regT2, regT1); >+ emitLoadStructure(vm(), regT0, regT2); > loadGlobalObject(regT0); > loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2); > comparePtr(Equal, regT0, regT2, regT0); >@@ -1145,7 +1145,7 @@ void JIT::emit_op_neq_null(const Instruction* currentInstruction) > Jump wasNotMasqueradesAsUndefined = jump(); > > isMasqueradesAsUndefined.link(this); >- emitLoadStructure(vm(), regT0, regT2, regT1); >+ emitLoadStructure(vm(), regT0, regT2); > loadGlobalObject(regT0); > loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2); > comparePtr(NotEqual, regT0, regT2, regT0); >@@ -1878,12 +1878,9 @@ void JIT::emit_op_get_prototype_of(const Instruction* currentInstruction) > #if USE(JSVALUE64) > JSValueRegs valueRegs(regT0); > JSValueRegs resultRegs(regT2); >- GPRReg scratchGPR = regT3; > #else > JSValueRegs valueRegs(regT1, regT0); > JSValueRegs resultRegs(regT3, regT2); >- GPRReg scratchGPR = regT1; >- ASSERT(valueRegs.tagGPR() == scratchGPR); > #endif > emitGetVirtualRegister(bytecode.m_value, valueRegs); > >@@ -1891,7 +1888,7 @@ void JIT::emit_op_get_prototype_of(const Instruction* currentInstruction) > slowCases.append(branchIfNotCell(valueRegs)); > slowCases.append(branchIfNotObject(valueRegs.payloadGPR())); > >- emitLoadPrototype(vm(), valueRegs.payloadGPR(), resultRegs, scratchGPR, slowCases); >+ emitLoadPrototype(vm(), valueRegs.payloadGPR(), resultRegs, slowCases); > addSlowCase(slowCases); > > emitValueProfilingSite(bytecode, resultRegs); >diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >index 957695b30e9399bba0e30f2eff490d30fb67cb5f..c81acd668a292fc22655ff62370877427e6549be 100644 >--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >@@ -3048,7 +3048,7 @@ void JIT::emit_op_get_property_enumerator(const Instruction* currentInstruction) > and32(TrustedImm32(IndexingTypeMask), regT1); > genericCases.append(branch32(Above, regT1, TrustedImm32(ArrayWithUndecided))); > >- emitLoadStructure(vm(), regT0, regT1, regT2); >+ emitLoadStructure(vm(), regT0, regT1); > loadPtr(Address(regT1, Structure::previousOrRareDataOffset()), regT1); > genericCases.append(branchTestPtr(Zero, regT1)); > genericCases.append(branchIfStructure(regT1)); >diff --git a/Source/JavaScriptCore/jit/JITStubRoutine.h b/Source/JavaScriptCore/jit/JITStubRoutine.h >index aecf54202c455ba290454a77e3bf9765f8ed3364..3551ab6480ab6a77cdd009151bf3ba5d1f1ebca9 100644 >--- a/Source/JavaScriptCore/jit/JITStubRoutine.h >+++ b/Source/JavaScriptCore/jit/JITStubRoutine.h >@@ -29,18 +29,13 @@ > > #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 >diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >index f9d1db5a46934c66716ef67580a5c5a228c1d4b5..0585b5881aeb6e1536806b55d14e2573b7cd8287 100644 >--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >@@ -685,7 +685,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id_direct) > { > StructureID oldStructureID = metadata.m_structureID; > if (oldStructureID) { >- Structure* a = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* a = oldStructureID.decode(); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -699,7 +699,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id_direct) > Structure* structure = baseCell->structure(vm); > if (slot.isValue()) { > // Start out by clearing out the old cache. >- metadata.m_structureID = 0; >+ metadata.m_structureID = StructureID(); > metadata.m_offset = 0; > > if (structure->propertyAccessesAreCacheable() && !structure->needImpurePropertyWatchpoint()) { >@@ -812,10 +812,10 @@ static JSValue performLLIntGetByID(const Instruction* pc, CodeBlock* codeBlock, > oldStructureID = metadata.protoLoadMode.structureID; > break; > default: >- oldStructureID = 0; >+ oldStructureID = StructureID(); > } > if (oldStructureID) { >- Structure* a = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* a = oldStructureID.decode(); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -950,7 +950,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id) > { > StructureID oldStructureID = metadata.m_oldStructureID; > if (oldStructureID) { >- Structure* a = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* a = oldStructureID.decode(); > Structure* b = baseValue.asCell()->structure(vm); > if (slot.type() == PutPropertySlot::NewProperty) > b = b->previousID(); >@@ -963,9 +963,9 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id) > } > > // Start out by clearing out the old cache. >- metadata.m_oldStructureID = 0; >+ metadata.m_oldStructureID = StructureID(); > metadata.m_offset = 0; >- metadata.m_newStructureID = 0; >+ metadata.m_newStructureID = StructureID(); > metadata.m_structureChain.clear(); > > JSCell* baseCell = baseValue.asCell(); >@@ -1139,7 +1139,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_private_name) > { > StructureID oldStructureID = metadata.m_structureID; > if (oldStructureID) { >- Structure* a = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* a = oldStructureID.decode(); > Structure* b = baseValue.asCell()->structure(vm); > > if (Structure::shouldConvertToPolyProto(a, b)) { >@@ -1153,7 +1153,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_private_name) > Structure* structure = baseCell->structure(vm); > if (slot.isValue()) { > // Start out by clearing out the old cache. >- metadata.m_structureID = 0; >+ metadata.m_structureID = StructureID(); > metadata.m_offset = 0; > > if (!structure->isUncacheableDictionary()) { >@@ -1272,7 +1272,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_private_name) > { > StructureID oldStructureID = metadata.m_oldStructureID; > if (oldStructureID) { >- Structure* a = vm.heap.structureIDTable().get(oldStructureID); >+ Structure* a = oldStructureID.decode(); > Structure* b = baseValue.asCell()->structure(vm); > if (slot.type() == PutPropertySlot::NewProperty) > b = b->previousID(); >@@ -1285,9 +1285,9 @@ LLINT_SLOW_PATH_DECL(slow_path_put_private_name) > } > > // Start out by clearing out the old cache. >- metadata.m_oldStructureID = 0; >+ metadata.m_oldStructureID = StructureID(); > metadata.m_offset = 0; >- metadata.m_newStructureID = 0; >+ metadata.m_newStructureID = StructureID(); > metadata.m_property.clear(); > > JSCell* baseCell = baseValue.asCell(); >@@ -1361,8 +1361,8 @@ LLINT_SLOW_PATH_DECL(slow_path_set_private_brand) > ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); > > // Start out by clearing out the old cache. >- metadata.m_oldStructureID = 0; >- metadata.m_newStructureID = 0; >+ metadata.m_oldStructureID = StructureID(); >+ metadata.m_newStructureID = StructureID(); > metadata.m_brand.clear(); > > if (!newStructure->isDictionary()) { >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >index d35c224fb9133eb61de7bec2e7170b6bc99ca3aa..c64668603da92fd3f91896de0c1f712ab9568d2d 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >@@ -212,11 +212,6 @@ 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 >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >index cdfd6e218c956b43106a27484fdec4642ae068ab..5259849e83bb01b43ce843ce5385c9168397ad66 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -694,20 +694,15 @@ macro writeBarrierOnGlobalLexicalEnvironment(size, get, valueFieldName) > end) > end > >-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 >+macro structureIDToStructureWithScratch(structureIDThenStructure, scratch) >+ andq constexpr structureIDMask, structureIDThenStructure >+ loadp JSCConfig + constexpr (offsetof(Config, startOfStructureHeap)), scratch >+ addp scratch, structureIDThenStructure > end > >-macro loadStructureWithScratch(cell, structure, scratch, scratch2) >+macro loadStructureWithScratch(cell, structure, scratch) > loadi JSCell::m_structureID[cell], structure >- structureIDToStructureWithScratch(structure, scratch, scratch2) >+ structureIDToStructureWithScratch(structure, scratch) > end > > # Entrypoints into the interpreter. >@@ -930,7 +925,7 @@ macro equalNullComparisonOp(opcodeName, opcodeStruct, fn) > move 0, t0 > jmp .done > .masqueradesAsUndefined: >- loadStructureWithScratch(t0, t2, t1, t3) >+ loadStructureWithScratch(t0, t2, t1) > loadp CodeBlock[cfr], t0 > loadp CodeBlock::m_globalObject[t0], t0 > cpeq Structure::m_globalObject[t2], t0, t0 >@@ -1432,7 +1427,7 @@ llintOpWithReturn(op_typeof_is_undefined, OpTypeofIsUndefined, macro (size, get, > move ValueFalse, t1 > return(t1) > .masqueradesAsUndefined: >- loadStructureWithScratch(t0, t3, t1, t2) >+ loadStructureWithScratch(t0, t3, t1) > loadp CodeBlock[cfr], t1 > loadp CodeBlock::m_globalObject[t1], t1 > cpeq Structure::m_globalObject[t3], t1, t0 >@@ -1627,7 +1622,7 @@ llintOpWithProfile(op_get_prototype_of, OpGetPrototypeOf, macro (size, get, disp > btqnz t0, notCellMask, .opGetPrototypeOfSlow > bbb JSCell::m_type[t0], ObjectType, .opGetPrototypeOfSlow > >- loadStructureWithScratch(t0, t2, t1, t3) >+ loadStructureWithScratch(t0, t2, t1) > loadh Structure::m_outOfLineTypeFlags[t2], t3 > btinz t3, OverridesGetPrototypeOutOfLine, .opGetPrototypeOfSlow > >@@ -1667,19 +1662,7 @@ llintOpWithMetadata(op_put_by_id, OpPutById, macro (size, get, dispatch, metadat > loadp OpPutById::Metadata::m_structureChain[t5], t3 > btpz t3, .opPutByIdTransitionDirect > >- 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) >+ structureIDToStructureWithScratch(t2, t1) > > loadp StructureChain::m_vector[t3], t3 > assert(macro (ok) btpnz t3, ok end) >@@ -1690,7 +1673,7 @@ llintOpWithMetadata(op_put_by_id, OpPutById, macro (size, get, dispatch, metadat > loadi JSCell::m_structureID[t2], t2 > bineq t2, [t3], .opPutByIdSlow > addp 4, t3 >- structureIDToStructureWithScratchAndTable(t2, t1, t0) >+ structureIDToStructureWithScratch(t2, t1) > loadq Structure::m_prototype[t2], t2 > bqneq t2, ValueNull, .opPutByIdTransitionChainLoop > >@@ -2065,7 +2048,7 @@ macro equalNullJumpOp(opcodeName, opcodeStruct, cellHandler, immediateHandler) > assertNotConstant(size, t0) > loadq [cfr, t0, 8], t0 > btqnz t0, notCellMask, .immediate >- loadStructureWithScratch(t0, t2, t1, t3) >+ loadStructureWithScratch(t0, t2, t1) > cellHandler(t2, JSCell::m_flags[t0], .target) > dispatch() > >@@ -2784,7 +2767,7 @@ end) > macro loadWithStructureCheck(opcodeStruct, get, slowPath) > get(m_scope, t0) > loadq [cfr, t0, 8], t0 >- loadStructureWithScratch(t0, t2, t1, t3) >+ loadStructureWithScratch(t0, t2, t1) > loadp %opcodeStruct%::Metadata::m_structure[t5], t1 > bpneq t2, t1, slowPath > end >@@ -3235,7 +3218,7 @@ llintOpWithReturn(op_get_property_enumerator, OpGetPropertyEnumerator, macro (si > andi IndexingTypeMask, t1 > bia t1, ArrayWithUndecided, .slowPath > >- loadStructureWithScratch(t0, t1, t2, t3) >+ loadStructureWithScratch(t0, t1, t2) > loadp Structure::m_previousOrRareData[t1], t1 > btpz t1, .slowPath > bbeq JSCell::m_type[t1], StructureType, .slowPath >diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp >index de9285c9837e748e6c445f5a31b92605b3404307..58ab4f0bf4fb37ef564d892716f6d2a7ecf664f8 100644 >--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp >@@ -604,7 +604,7 @@ JSC_DEFINE_HOST_FUNCTION(arrayProtoFuncToString, (JSGlobalObject* globalObject, > JSObject* thisObject = thisValue.toObject(globalObject); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); > >- Integrity::auditStructureID(vm, thisObject->structureID()); >+ Integrity::auditStructureID(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); >diff --git a/Source/JavaScriptCore/runtime/BigIntPrototype.cpp b/Source/JavaScriptCore/runtime/BigIntPrototype.cpp >index 97b23e5ebe529be64971a73cc7e5c6568bf4b88c..952209d371655c6098db6bee7b5b3e756f6f9bdf 100644 >--- a/Source/JavaScriptCore/runtime/BigIntPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/BigIntPrototype.cpp >@@ -113,7 +113,7 @@ JSC_DEFINE_HOST_FUNCTION(bigIntProtoFuncToString, (JSGlobalObject* globalObject, > > ASSERT(value); > >- Integrity::auditStructureID(vm, value->structureID()); >+ Integrity::auditStructureID(value->structureID()); > int32_t radix = extractToStringRadixArgument(globalObject, callFrame->argument(0), scope); > RETURN_IF_EXCEPTION(scope, { }); > >@@ -156,7 +156,7 @@ JSC_DEFINE_HOST_FUNCTION(bigIntProtoFuncValueOf, (JSGlobalObject* globalObject, > JSBigInt* value = toThisBigIntValue(globalObject, callFrame->thisValue()); > RETURN_IF_EXCEPTION(scope, { }); > >- Integrity::auditStructureID(vm, value->structureID()); >+ Integrity::auditStructureID(value->structureID()); > return JSValue::encode(value); > } > >diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp >index bb4a459c65b25040186f23b89be0e3d2eb75ba8d..af007a35ea0e40f537f167cd30f353f697da035b 100644 >--- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp >@@ -76,7 +76,7 @@ JSC_DEFINE_HOST_FUNCTION(booleanProtoFuncToString, (JSGlobalObject* globalObject > if (UNLIKELY(!thisObject)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(vm, thisObject->structureID()); >+ Integrity::auditStructureID(thisObject->structureID()); > if (thisObject->internalValue() == jsBoolean(false)) > return JSValue::encode(vm.smallStrings.falseString()); > >@@ -96,7 +96,7 @@ JSC_DEFINE_HOST_FUNCTION(booleanProtoFuncValueOf, (JSGlobalObject* globalObject, > if (UNLIKELY(!thisObject)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(vm, thisObject->structureID()); >+ Integrity::auditStructureID(thisObject->structureID()); > return JSValue::encode(thisObject->internalValue()); > } > >diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >index 738382ec124275512ba9e5f7275ba5dbfbfabf32..8c044173d381992572e9680df8714805bd423e6f 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -355,11 +355,11 @@ JSC_DEFINE_COMMON_SLOW_PATH(slow_path_to_this) > if (otherStructureID) > metadata.m_toThisStatus = ToThisConflicted; > metadata.m_cachedStructureID = myStructureID; >- vm.writeBarrier(codeBlock, vm.getStructure(myStructureID)); >+ vm.writeBarrier(codeBlock, myStructureID.decode()); > } > } else { > metadata.m_toThisStatus = ToThisConflicted; >- metadata.m_cachedStructureID = 0; >+ metadata.m_cachedStructureID = StructureID(); > } > // 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 >diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp >index 576fd3b31a258bf93855e41da60dcf46236a18c0..ee9c1630eea3194d3314cf9d15eda2361766218f 100644 >--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp >+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp >@@ -97,7 +97,7 @@ static EncodedJSValue formateDateInstance(JSGlobalObject* globalObject, CallFram > if (UNLIKELY(!thisDateObj)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(vm, thisDateObj->structureID()); >+ Integrity::auditStructureID(thisDateObj->structureID()); > const GregorianDateTime* gregorianDateTime = asUTCVariant > ? thisDateObj->gregorianDateTimeUTC(cache) > : thisDateObj->gregorianDateTime(cache); >@@ -308,7 +308,7 @@ JSC_DEFINE_HOST_FUNCTION(dateProtoFuncToISOString, (JSGlobalObject* globalObject > if (UNLIKELY(!thisDateObj)) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(vm, thisDateObj->structureID()); >+ Integrity::auditStructureID(thisDateObj->structureID()); > if (!std::isfinite(thisDateObj->internalNumber())) > return throwVMError(globalObject, scope, createRangeError(globalObject, "Invalid Date"_s)); > >@@ -356,7 +356,7 @@ JSC_DEFINE_HOST_FUNCTION(dateProtoFuncToPrimitiveSymbol, (JSGlobalObject* global > if (!thisValue.isObject()) > return throwVMTypeError(globalObject, scope, "Date.prototype[Symbol.toPrimitive] expected |this| to be an object."); > JSObject* thisObject = jsCast<JSObject*>(thisValue); >- Integrity::auditStructureID(vm, thisObject->structureID()); >+ Integrity::auditStructureID(thisObject->structureID()); > > if (!callFrame->argumentCount()) > return throwVMTypeError(globalObject, scope, "Date.prototype[Symbol.toPrimitive] expected a first argument."); >diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp >index dfb18a33033c5531da350cb6046488f967225daa..674206523d1c4bcdee8c500a07131615c241e58a 100644 >--- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp >+++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp >@@ -154,7 +154,7 @@ String ErrorInstance::sanitizedMessageString(JSGlobalObject* globalObject) > { > VM& vm = globalObject->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- Integrity::auditStructureID(vm, structureID()); >+ Integrity::auditStructureID(structureID()); > > JSValue messageValue; > auto messagePropertName = vm.propertyNames->message; >@@ -172,7 +172,7 @@ String ErrorInstance::sanitizedNameString(JSGlobalObject* globalObject) > { > VM& vm = globalObject->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- Integrity::auditStructureID(vm, structureID()); >+ Integrity::auditStructureID(structureID()); > > JSValue nameValue; > auto namePropertName = vm.propertyNames->name; >@@ -203,7 +203,7 @@ String ErrorInstance::sanitizedToString(JSGlobalObject* globalObject) > { > VM& vm = globalObject->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- Integrity::auditStructureID(vm, structureID()); >+ Integrity::auditStructureID(structureID()); > > String nameString = sanitizedNameString(globalObject); > RETURN_IF_EXCEPTION(scope, String()); >diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp >index b8c62d37599554ed5775d3f6994bb9a169ac213d..ef431f395e3425a26354e9320acc4f9252b3829c 100644 >--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp >@@ -79,7 +79,7 @@ JSC_DEFINE_HOST_FUNCTION(errorProtoFuncToString, (JSGlobalObject* globalObject, > if (!thisValue.isObject()) > return throwVMTypeError(globalObject, scope); > JSObject* thisObj = asObject(thisValue); >- Integrity::auditStructureID(vm, thisObj->structureID()); >+ Integrity::auditStructureID(thisObj->structureID()); > > // Guard against recursion! > StringRecursionChecker checker(globalObject, thisObj); >diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp >index b6c99610955b7d0a176021d86edae86d33c20c3c..b31cfc1c905e9684a9a781e47df16a0faac83c36 100644 >--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp >@@ -81,19 +81,19 @@ JSC_DEFINE_HOST_FUNCTION(functionProtoFuncToString, (JSGlobalObject* globalObjec > JSValue thisValue = callFrame->thisValue(); > if (thisValue.inherits<JSFunction>(vm)) { > JSFunction* function = jsCast<JSFunction*>(thisValue); >- Integrity::auditStructureID(vm, function->structureID()); >+ Integrity::auditStructureID(function->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(function->toString(globalObject))); > } > > if (thisValue.inherits<InternalFunction>(vm)) { > InternalFunction* function = jsCast<InternalFunction*>(thisValue); >- Integrity::auditStructureID(vm, function->structureID()); >+ Integrity::auditStructureID(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(vm, object->structureID()); >+ Integrity::auditStructureID(object->structureID()); > if (object->isCallable(vm)) > RELEASE_AND_RETURN(scope, JSValue::encode(jsMakeNontrivialString(globalObject, "function ", object->classInfo(vm)->className, "() {\n [native code]\n}"))); > } >diff --git a/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h b/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >index 205e1a93943b35aad1bff529092de313ace0580d..c1aa3c9b7a3bd421ca8817187de80064957b43c3 100644 >--- a/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >+++ b/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >@@ -43,7 +43,7 @@ public: > static ptrdiff_t offsetOfResult() { return OBJECT_OFFSETOF(Entry, result); } > > RefPtr<UniquedStringImpl> impl; >- StructureID structureID { 0 }; >+ StructureID structureID; > bool result { false }; > }; > >diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp >index 915bc6c541b87eef5b05ce383f7a7bb69ee41ada..38e70ed18d656ee91b701572836513a48e64d057 100644 >--- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp >+++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp >@@ -36,6 +36,7 @@ > #include "LLIntData.h" > #include "Options.h" > #include "SigillCrashAnalyzer.h" >+#include "StructureAlignedMemoryAllocator.h" > #include "SuperSampler.h" > #include "VMTraps.h" > #include "WasmCalleeRegistry.h" >@@ -65,6 +66,7 @@ void initialize() > #endif > { > Options::AllowUnfinalizedAccessScope scope; >+ StructureAlignedMemoryAllocator::initializeStructureAddressSpace(); > JITOperationList::initialize(); > ExecutableAllocator::initialize(); > VM::computeCanUseJIT(); >diff --git a/Source/JavaScriptCore/runtime/JSCConfig.h b/Source/JavaScriptCore/runtime/JSCConfig.h >index c83c66473d76a3309c9cd28ffb474b6369361512..e1f6fdb591a11d25e0f7fb37b26478a92fd537da 100644 >--- a/Source/JavaScriptCore/runtime/JSCConfig.h >+++ b/Source/JavaScriptCore/runtime/JSCConfig.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2019-2020 Apple Inc. All rights reserved. >+ * Copyright (C) 2019-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 >@@ -40,6 +40,8 @@ class VM; > using JITWriteSeparateHeapsFunction = void (*)(off_t, const void*, size_t); > #endif > >+constexpr uintptr_t structureHeapAddressSize = 1 * GB; >+ > struct Config { > static Config& singleton(); > >@@ -81,6 +83,7 @@ struct Config { > void* startExecutableMemory; > void* endExecutableMemory; > uintptr_t startOfFixedWritableMemoryPool; >+ uintptr_t startOfStructureHeap; > > #if ENABLE(SEPARATED_WX_HEAP) > JITWriteSeparateHeapsFunction jitWriteSeparateHeaps; >@@ -118,6 +121,7 @@ extern "C" JS_EXPORT_PRIVATE Config g_jscConfig; > > 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 > >diff --git a/Source/JavaScriptCore/runtime/JSCJSValue.cpp b/Source/JavaScriptCore/runtime/JSCJSValue.cpp >index af27016abc7e337c7738b96d354570b058b8b7ef..1118796d17d3c9b88703e3893161ef3121885abe 100644 >--- a/Source/JavaScriptCore/runtime/JSCJSValue.cpp >+++ b/Source/JavaScriptCore/runtime/JSCJSValue.cpp >@@ -320,7 +320,7 @@ void JSValue::dumpInContextAssumingStructure( > out.print(" (", inContext(*structure, context), ")"); > } > #if USE(JSVALUE64) >- out.print(", StructureID: ", asCell()->structureID()); >+ out.print(", StructureID: ", asCell()->structureID().bits()); > #endif > } else if (isTrue()) > out.print("True"); >@@ -357,15 +357,9 @@ void JSValue::dumpForBacktrace(PrintStream& out) const > 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()) >diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp >index b1ca692743c6afddaff1ead357694b746fc064d5..63942867a130fe6c5fe018e744f14d6119db4c2a 100644 >--- a/Source/JavaScriptCore/runtime/JSCell.cpp >+++ b/Source/JavaScriptCore/runtime/JSCell.cpp >@@ -173,7 +173,7 @@ double JSCell::toNumber(JSGlobalObject* globalObject) const > > JSObject* JSCell::toObjectSlow(JSGlobalObject* globalObject) const > { >- Integrity::auditStructureID(globalObject->vm(), structureID()); >+ Integrity::auditStructureID(structureID()); > ASSERT(!isObject()); > if (isString()) > return static_cast<const JSString*>(this)->toObject(globalObject); >diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h >index 9bb06ad0d4b8960feed156f7d35a186c838c47e3..7c88834392b01643a1c58780dded95f6c425b3fb 100644 >--- a/Source/JavaScriptCore/runtime/JSCell.h >+++ b/Source/JavaScriptCore/runtime/JSCell.h >@@ -135,7 +135,7 @@ public: > Structure* structure(VM&) const; > void setStructure(VM&, Structure*); > void setStructureIDDirectly(StructureID id) { m_structureID = id; } >- void clearStructure() { m_structureID = 0; } >+ void clearStructure() { m_structureID = StructureID(); } > > TypeInfo::InlineTypeFlags inlineTypeFlags() const { return m_flags; } > >diff --git a/Source/JavaScriptCore/runtime/JSCellInlines.h b/Source/JavaScriptCore/runtime/JSCellInlines.h >index b2409931cf42cf7431cad09ca28dd2b4b34d22a4..e743b9e6ecb56c19be1256a6c978f7901951f5c2 100644 >--- a/Source/JavaScriptCore/runtime/JSCellInlines.h >+++ b/Source/JavaScriptCore/runtime/JSCellInlines.h >@@ -133,12 +133,13 @@ inline IndexingType JSCell::indexingMode() const > > ALWAYS_INLINE Structure* JSCell::structure() const > { >- return structure(vm()); >+ return m_structureID.decode(); > } > >-ALWAYS_INLINE Structure* JSCell::structure(VM& vm) const >+// FIXME: Delete this in a cleanup fixup. >+ALWAYS_INLINE Structure* JSCell::structure(VM&) const > { >- return vm.getStructure(m_structureID); >+ return structure(); > } > > template<typename Visitor> >@@ -304,7 +305,7 @@ ALWAYS_INLINE void JSCell::setStructure(VM& vm, Structure* structure) > ASSERT(structure->classInfo() == this->structure(vm)->classInfo()); > ASSERT(!this->structure(vm) > || this->structure(vm)->transitionWatchpointSetHasBeenInvalidated() >- || Heap::heap(this)->structureIDTable().get(structure->id()) == structure); >+ || structure->id().decode() == structure); > m_structureID = structure->id(); > m_flags = TypeInfo::mergeInlineTypeFlags(structure->typeInfo().inlineTypeFlags(), m_flags); > m_type = structure->typeInfo().type(); >diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp >index 0b2eeb68b1c25692ed921e0e9019049ec05cc4b0..8bddf0a068eff4b8c1887320c33c53461efcf225 100644 >--- a/Source/JavaScriptCore/runtime/JSObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSObject.cpp >@@ -369,9 +369,9 @@ ALWAYS_INLINE Structure* JSObject::visitButterflyImpl(Visitor& visitor) > // https://pdfs.semanticscholar.org/343f/7182cde7669ca2a7de3dc01127927f384ef7.pdf > > StructureID structureID = this->structureID(); >- if (isNuked(structureID)) >+ if (structureID.isNuked()) > return nullptr; >- structure = vm.getStructure(structureID); >+ structure = structureID.decode(); > maxOffset = structure->maxOffset(); > IndexingType indexingMode; > Dependency indexingModeDependency = structure->fencedIndexingMode(indexingMode); >@@ -1169,7 +1169,7 @@ Butterfly* JSObject::createInitialUndecided(VM& vm, unsigned length) > DeferGC deferGC(vm); > Butterfly* newButterfly = createInitialIndexedStorage(vm, length); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateUndecided); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1183,7 +1183,7 @@ ContiguousJSValues JSObject::createInitialInt32(VM& vm, unsigned length) > for (unsigned i = newButterfly->vectorLength(); i--;) > newButterfly->contiguous().at(this, i).setWithoutWriteBarrier(JSValue()); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateInt32); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1197,7 +1197,7 @@ ContiguousDoubles JSObject::createInitialDouble(VM& vm, unsigned length) > for (unsigned i = newButterfly->vectorLength(); i--;) > newButterfly->contiguousDouble().at(this, i) = PNaN; > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateDouble); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1211,7 +1211,7 @@ ContiguousJSValues JSObject::createInitialContiguous(VM& vm, unsigned length) > for (unsigned i = newButterfly->vectorLength(); i--;) > newButterfly->contiguous().at(this, i).setWithoutWriteBarrier(JSValue()); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, TransitionKind::AllocateContiguous); > nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly); > setStructure(vm, newStructure); >@@ -1241,7 +1241,7 @@ ArrayStorage* JSObject::createArrayStorage(VM& vm, unsigned length, unsigned vec > { > DeferGC deferGC(vm); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > IndexingType oldType = indexingType(); > ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType)); > >@@ -1331,7 +1331,7 @@ ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, TransitionKind tr > storage->m_vector[i].setWithoutWriteBarrier(JSValue()); > > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > nukeStructureAndSetButterfly(vm, oldStructureID, storage->butterfly()); > setStructure(vm, newStructure); >@@ -1390,7 +1390,7 @@ ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, TransitionKind transi > } > > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly()); > setStructure(vm, newStructure); >@@ -1444,7 +1444,7 @@ ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, TransitionKind trans > } > > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition); > nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly()); > setStructure(vm, newStructure); >@@ -1522,7 +1522,7 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, TransitionKind t > > ASSERT(newStorage->butterfly() != butterfly); > StructureID oldStructureID = this->structureID(); >- Structure* oldStructure = vm.getStructure(oldStructureID); >+ Structure* oldStructure = oldStructureID.decode(); > 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::putDirectCustomGetterSetterWithoutTransition(VM& vm, PropertyName > ASSERT(attributes & PropertyAttribute::CustomAccessorOrValue); > > StructureID structureID = this->structureID(); >- Structure* structure = vm.heap.structureIDTable().get(structureID); >+ Structure* structure = structureID.decode(); > PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure); > putDirect(vm, offset, value); > >@@ -2051,7 +2051,7 @@ void JSObject::putDirectNonIndexAccessorWithoutTransition(VM& vm, PropertyName p > { > ASSERT(attributes & PropertyAttribute::Accessor); > StructureID structureID = this->structureID(); >- Structure* structure = vm.heap.structureIDTable().get(structureID); >+ Structure* structure = structureID.decode(); > PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure); > putDirect(vm, offset, accessor); > if (attributes & PropertyAttribute::ReadOnly) >diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h >index 0c4dfa31d873b7a93299ad7edd11840aea8c2e9b..3747e22903a37dfa52e4565327006c717d914d7f 100644 >--- a/Source/JavaScriptCore/runtime/JSObject.h >+++ b/Source/JavaScriptCore/runtime/JSObject.h >@@ -1365,7 +1365,7 @@ inline void JSObject::setButterfly(VM& vm, Butterfly* butterfly) > inline void JSObject::nukeStructureAndSetButterfly(VM& vm, StructureID oldStructureID, Butterfly* butterfly) > { > if (isX86() || vm.heap.mutatorShouldBeFenced()) { >- setStructureIDDirectly(nuke(oldStructureID)); >+ setStructureIDDirectly(oldStructureID.nuke()); > WTF::storeStoreFence(); > m_butterfly.set(vm, this, butterfly); > WTF::storeStoreFence(); >@@ -1498,7 +1498,6 @@ 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()))) { >@@ -1513,10 +1512,10 @@ ALWAYS_INLINE bool JSObject::getPropertySlot(JSGlobalObject* globalObject, Prope > return object->getNonIndexPropertySlot(globalObject, propertyName, slot); > } > ASSERT(object->type() != ProxyObjectType); >- Structure* structure = structureIDTable.get(object->structureID()); >+ Structure* structure = object->structureID().decode(); > #if USE(JSVALUE64) > if (checkNullStructure && UNLIKELY(!structure)) >- CRASH_WITH_INFO(object->type(), object->structureID(), structureIDTable.size()); >+ CRASH_WITH_INFO(object->type(), object->structureID().bits()); > #endif > if (object->getOwnNonIndexPropertySlot(vm, structure, propertyName, slot)) > return true; >diff --git a/Source/JavaScriptCore/runtime/JSObjectInlines.h b/Source/JavaScriptCore/runtime/JSObjectInlines.h >index 760a9a9e2ec47db38fa23bad894e0e80da6740d1..151191e27d08e97e69be54d1176a31dbd4f1d58d 100644 >--- a/Source/JavaScriptCore/runtime/JSObjectInlines.h >+++ b/Source/JavaScriptCore/runtime/JSObjectInlines.h >@@ -110,10 +110,9 @@ ALWAYS_INLINE bool JSObject::getPropertySlot(JSGlobalObject* globalObject, unsig > { > VM& vm = getVM(globalObject); > auto scope = DECLARE_THROW_SCOPE(vm); >- auto& structureIDTable = vm.heap.structureIDTable(); > JSObject* object = this; > while (true) { >- Structure* structure = structureIDTable.get(object->structureID()); >+ Structure* structure = object->structureID().decode(); > bool hasSlot = structure->classInfo()->methodTable.getOwnPropertySlotByIndex(object, globalObject, propertyName, slot); > RETURN_IF_EXCEPTION(scope, false); > if (hasSlot) >@@ -151,10 +150,9 @@ ALWAYS_INLINE bool JSObject::getNonIndexPropertySlot(JSGlobalObject* globalObjec > > VM& vm = getVM(globalObject); > auto scope = DECLARE_THROW_SCOPE(vm); >- auto& structureIDTable = vm.heap.structureIDTable(); > JSObject* object = this; > while (true) { >- Structure* structure = structureIDTable.get(object->structureID()); >+ Structure* structure = object->structureID().decode(); > if (LIKELY(!TypeInfo::overridesGetOwnPropertySlot(object->inlineTypeFlags()))) { > if (object->getOwnNonIndexPropertySlot(vm, structure, propertyName, slot)) > return true; >@@ -219,7 +217,7 @@ inline void JSObject::putDirectWithoutTransition(VM& vm, PropertyName propertyNa > ASSERT(!value.isGetterSetter() && !(attributes & PropertyAttribute::Accessor)); > ASSERT(!value.isCustomGetterSetter()); > StructureID structureID = this->structureID(); >- Structure* structure = vm.heap.structureIDTable().get(structureID); >+ Structure* structure = structureID.decode(); > PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure); > putDirect(vm, offset, value); > if (attributes & PropertyAttribute::ReadOnly) >@@ -328,7 +326,7 @@ ALWAYS_INLINE bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName > ASSERT(!parseIndex(propertyName)); > > StructureID structureID = this->structureID(); >- Structure* structure = vm.heap.structureIDTable().get(structureID); >+ Structure* structure = structureID.decode(); > if (structure->isDictionary()) { > ASSERT(!isCopyOnWrite(indexingMode())); > >diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp >index 8f1c3c169a721d42cae3433777161ff03448bd77..a77d81a879f33a90bec2de6f8bff95a26f6f3870 100644 >--- a/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp >+++ b/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp >@@ -50,7 +50,7 @@ JSPropertyNameEnumerator* JSPropertyNameEnumerator::create(VM& vm, Structure* st > 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(structure ? structure->id() : 0) >+ , m_cachedStructureID(structure ? structure->id() : StructureID()) > , m_indexedLength(indexedLength) > , m_endStructurePropertyIndex(numberStructureProperties) > , m_endGenericPropertyIndex(propertyNamesSize) >@@ -87,10 +87,8 @@ void JSPropertyNameEnumerator::visitChildrenImpl(JSCell* cell, Visitor& visitor) > visitor.append(propertyNames, propertyNames + thisObject->sizeOfPropertyNames()); > } > >- if (thisObject->cachedStructureID()) { >- VM& vm = visitor.vm(); >- visitor.appendUnbarriered(vm.getStructure(thisObject->cachedStructureID())); >- } >+ if (thisObject->cachedStructureID()) >+ visitor.appendUnbarriered(thisObject->cachedStructureID().decode()); > } > > DEFINE_VISIT_CHILDREN(JSPropertyNameEnumerator); >diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h b/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h >index 616ccf86ae81a66760e0eb11331a3cd99cbcebec..5f483c14190d3cf9c36097e5ab918f99f3d471db 100644 >--- a/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h >+++ b/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h >@@ -72,9 +72,10 @@ public: > > Structure* cachedStructure(VM& vm) const > { >+ UNUSED_PARAM(vm); > if (!m_cachedStructureID) > return nullptr; >- return vm.heap.structureIDTable().get(m_cachedStructureID); >+ return m_cachedStructureID.decode(); > } > StructureID cachedStructureID() const { return m_cachedStructureID; } > uint32_t indexedLength() const { return m_indexedLength; } >diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp >index 92ccefb3f8cc7e513cc6418a5914f937a470646e..888591ddc06ffacad2f0a0973bf02554d65180b6 100644 >--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp >@@ -94,7 +94,7 @@ static ALWAYS_INLINE bool toThisNumber(VM& vm, JSValue thisValue, double& x) > } > > if (auto* numberObject = jsDynamicCast<NumberObject*>(vm, thisValue)) { >- Integrity::auditStructureID(vm, numberObject->structureID()); >+ Integrity::auditStructureID(numberObject->structureID()); > x = numberObject->internalValue().asNumber(); > return true; > } >diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp >index 0db824a336ffedf7eb9618a7435de97ed121379f..258891d77d1ef270d294b2308ae4830e63e6011e 100644 >--- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp >@@ -85,7 +85,7 @@ JSC_DEFINE_HOST_FUNCTION(objectProtoFuncValueOf, (JSGlobalObject* globalObject, > JSObject* valueObj = thisValue.toObject(globalObject); > if (UNLIKELY(!valueObj)) > return encodedJSValue(); >- Integrity::auditStructureID(globalObject->vm(), valueObj->structureID()); >+ Integrity::auditStructureID(valueObj->structureID()); > return JSValue::encode(valueObj); > } > >@@ -361,7 +361,7 @@ JSString* objectPrototypeToString(JSGlobalObject* globalObject, JSValue thisValu > JSObject* thisObject = thisValue.toObject(globalObject); > RETURN_IF_EXCEPTION(scope, nullptr); > >- Integrity::auditStructureID(vm, thisObject->structureID()); >+ Integrity::auditStructureID(thisObject->structureID()); > auto result = thisObject->structure(vm)->cachedSpecialProperty(CachedSpecialPropertyKey::ToStringTag); > if (result) > return asString(result); >diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp >index fc5d95b3a7ca2e1735e18d31188e8059e54c50a6..5824a42c3b6a1573f001655a692d679fdfa009f4 100644 >--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp >@@ -199,7 +199,7 @@ JSC_DEFINE_HOST_FUNCTION(regExpProtoFuncToString, (JSGlobalObject* globalObject, > return throwVMTypeError(globalObject, scope); > > JSObject* thisObject = asObject(thisValue); >- Integrity::auditStructureID(vm, thisObject->structureID()); >+ Integrity::auditStructureID(thisObject->structureID()); > > StringRecursionChecker checker(globalObject, thisObject); > EXCEPTION_ASSERT(!scope.exception() || checker.earlyReturnValue()); >diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp >index e019e97b72f27f875c9c92baf1c31abb3e36ab40..f3b383dcba4253a4ac925584d19bc8076b94a54a 100644 >--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp >@@ -960,7 +960,7 @@ JSC_DEFINE_HOST_FUNCTION(stringProtoFuncToString, (JSGlobalObject* globalObject, > // Also used for valueOf. > > if (thisValue.isString()) { >- Integrity::auditStructureID(vm, thisValue.asCell()->structureID()); >+ Integrity::auditStructureID(thisValue.asCell()->structureID()); > return JSValue::encode(thisValue); > } > >@@ -968,7 +968,7 @@ JSC_DEFINE_HOST_FUNCTION(stringProtoFuncToString, (JSGlobalObject* globalObject, > if (!stringObject) > return throwVMTypeError(globalObject, scope); > >- Integrity::auditStructureID(vm, stringObject->structureID()); >+ Integrity::auditStructureID(stringObject->structureID()); > return JSValue::encode(stringObject->internalValue()); > } > >diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp >index 0b03f31010652c596fd080b9e45dec5835e46335..b60e3cb0e3bf5638732f85c0dcb07c396d3fd68b 100644 >--- a/Source/JavaScriptCore/runtime/Structure.cpp >+++ b/Source/JavaScriptCore/runtime/Structure.cpp >@@ -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(vm.heap.structureIDTable().allocateID(this), indexingType, typeInfo) >+ , m_blob(StructureID::encode(this), indexingType, typeInfo) > , m_outOfLineTypeFlags(typeInfo.outOfLineTypeFlags()) > , m_inlineCapacity(inlineCapacity) > , m_bitField(0) >@@ -264,7 +264,7 @@ Structure::Structure(VM& vm, CreatingEarlyCellTag) > setMaxOffset(vm, invalidOffset); > > TypeInfo typeInfo = TypeInfo(StructureType, StructureFlags); >- m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo); >+ m_blob = StructureIDBlob(StructureID::encode(this), 0, typeInfo); > m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags(); > > ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); >@@ -301,7 +301,7 @@ Structure::Structure(VM& vm, Structure* previous, DeferredStructureTransitionWat > setMaxOffset(vm, invalidOffset); > > TypeInfo typeInfo = previous->typeInfo(); >- m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingModeIncludingHistory(), typeInfo); >+ m_blob = StructureIDBlob(StructureID::encode(this), previous->indexingModeIncludingHistory(), typeInfo); > m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags(); > > ASSERT(!previous->typeInfo().structureIsImmortal()); >@@ -326,7 +326,6 @@ Structure::~Structure() > > if (isBrandedStructure()) > static_cast<BrandedStructure*>(this)->destruct(); >- Heap::heap(this)->structureIDTable().deallocateID(this, m_blob.structureID()); > } > > void Structure::destroy(JSCell* cell) >@@ -910,7 +909,7 @@ Structure* Structure::flattenDictionaryStructure(VM& vm, JSObject* object) > > GCSafeConcurrentJSLocker locker(m_lock, vm); > >- object->setStructureIDDirectly(nuke(id())); >+ object->setStructureIDDirectly(id().nuke()); > WTF::storeStoreFence(); > > size_t beforeOutOfLineCapacity = this->outOfLineCapacity(); >@@ -1370,7 +1369,7 @@ Ref<StructureShape> Structure::toStructureShape(JSValue value, bool& sawPolyProt > > void Structure::dump(PrintStream& out) const > { >- auto* structureID = reinterpret_cast<void*>(id()); >+ auto* structureID = reinterpret_cast<void*>(id().bits()); > out.print(RawPointer(this), ":[", RawPointer(structureID), > "/", (uint32_t)(reinterpret_cast<uintptr_t>(structureID)), ", ", > classInfo()->className, ", (", inlineSize(), "/", inlineCapacity(), ", ", >@@ -1470,7 +1469,7 @@ uintptr_t Structure::cachedPropertyNameEnumeratorAndFlag() const > return rareData()->cachedPropertyNameEnumeratorAndFlag(); > } > >-bool Structure::canCachePropertyNameEnumerator(VM& vm) const >+bool Structure::canCachePropertyNameEnumerator(VM&) const > { > if (!this->canCacheOwnPropertyNames()) > return false; >@@ -1482,7 +1481,7 @@ bool Structure::canCachePropertyNameEnumerator(VM& vm) const > StructureID structureID = *currentStructureID; > if (!structureID) > return true; >- Structure* structure = vm.getStructure(structureID); >+ Structure* structure = structureID.decode(); > if (!structure->canCacheOwnPropertyNames()) > return false; > currentStructureID++; >diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h >index 38b5e76106f849c444c5a7ecd9f99128b630dc8c..8550225740505193bde6b6cb6751feacd6e74606 100644 >--- a/Source/JavaScriptCore/runtime/Structure.h >+++ b/Source/JavaScriptCore/runtime/Structure.h >@@ -118,6 +118,7 @@ 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); >@@ -164,7 +165,7 @@ private: > void validateFlags(); > > public: >- StructureID id() const { return m_blob.structureID(); } >+ StructureID id() const { ASSERT(m_blob.structureID() == StructureID::encode(this)); return m_blob.structureID(); } > int32_t objectInitializationBlob() const { return m_blob.blobExcludingStructureID(); } > int64_t idBlob() const { return m_blob.blob(); } > >diff --git a/Source/JavaScriptCore/runtime/StructureChain.cpp b/Source/JavaScriptCore/runtime/StructureChain.cpp >index b537bc9fad642592010ceeeb4655d74cf4a44b17..52d0cfeec62ba0d885d2607448c78520a5f2a758 100644 >--- a/Source/JavaScriptCore/runtime/StructureChain.cpp >+++ b/Source/JavaScriptCore/runtime/StructureChain.cpp >@@ -73,10 +73,9 @@ void StructureChain::visitChildrenImpl(JSCell* cell, Visitor& visitor) > 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 = vm.getStructure(structureID); >+ Structure* structure = structureID.decode(); > visitor.appendUnbarriered(structure); > } > } >diff --git a/Source/JavaScriptCore/runtime/StructureID.h b/Source/JavaScriptCore/runtime/StructureID.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8203bf776ed90a4d11a92ae1ab5718ea0e425729 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/StructureID.h >@@ -0,0 +1,118 @@ >+/* >+ * 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" >+ >+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; } >+ 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; >+}; >+ >+} >diff --git a/Source/JavaScriptCore/runtime/StructureIDBlob.h b/Source/JavaScriptCore/runtime/StructureIDBlob.h >index 7309272bac08383496ae2fa2ab173f96c6f1275b..b50135ba73b09014512bcb3515956c25c605ce7b 100644 >--- a/Source/JavaScriptCore/runtime/StructureIDBlob.h >+++ b/Source/JavaScriptCore/runtime/StructureIDBlob.h >@@ -28,17 +28,14 @@ > #include "CellState.h" > #include "IndexingType.h" > #include "JSTypeInfo.h" >-#include "StructureIDTable.h" >+#include "StructureID.h" > > namespace JSC { > > class StructureIDBlob { > friend class LLIntOffsetsExtractor; > public: >- StructureIDBlob() >- { >- u.doubleWord = 0xbbadbeef; >- } >+ StructureIDBlob() = default; > > StructureIDBlob(StructureID structureID, IndexingType indexingModeIncludingHistory, const TypeInfo& typeInfo) > { >@@ -79,6 +76,7 @@ public: > private: > union { > struct { >+ // FIXME: We should remove this since the structureID can be directly computed from the Structure* > StructureID structureID; > IndexingType indexingModeIncludingHistory; > JSType type; >@@ -90,7 +88,7 @@ private: > int32_t word2; > } words; > int64_t doubleWord; >- } u; >+ } u { .doubleWord = 0xbbadbeef }; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/StructureIDTable.cpp b/Source/JavaScriptCore/runtime/StructureIDTable.cpp >deleted file mode 100644 >index f6b4f17560694558ec77f136cf89239ab122d07e..0000000000000000000000000000000000000000 >--- a/Source/JavaScriptCore/runtime/StructureIDTable.cpp >+++ /dev/null >@@ -1,204 +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. >- */ >- >-#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 >diff --git a/Source/JavaScriptCore/runtime/StructureIDTable.h b/Source/JavaScriptCore/runtime/StructureIDTable.h >deleted file mode 100644 >index eac2a138aeef002eaa323b215a080212d5624431..0000000000000000000000000000000000000000 >--- a/Source/JavaScriptCore/runtime/StructureIDTable.h >+++ /dev/null >@@ -1,225 +0,0 @@ >-/* >- * 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 >diff --git a/Source/JavaScriptCore/runtime/StructureRareDataInlines.h b/Source/JavaScriptCore/runtime/StructureRareDataInlines.h >index 1592208fb3f119bac0972d3f6a2ab6fb0f3b2f7d..edfcf3a258b4d42ebc2275547d99dd0daf3d246c 100644 >--- a/Source/JavaScriptCore/runtime/StructureRareDataInlines.h >+++ b/Source/JavaScriptCore/runtime/StructureRareDataInlines.h >@@ -177,7 +177,7 @@ inline void StructureChainInvalidationWatchpoint::fireInternal(VM&, const FireDe > m_structureRareData->clearCachedPropertyNameEnumerator(); > } > >-inline bool StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint(VM& vm, Structure* baseStructure, StructureChain* chain) >+inline bool StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint(VM&, Structure* baseStructure, StructureChain* chain) > { > if (baseStructure->hasPolyProto()) > return false; >@@ -186,7 +186,7 @@ inline bool StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint(VM& v > for (auto* current = chain->head(); *current; ++current) { > ++size; > StructureID structureID = *current; >- Structure* structure = vm.getStructure(structureID); >+ Structure* structure = structureID.decode(); > if (!structure->propertyNameEnumeratorShouldWatch()) > return false; > } >@@ -194,7 +194,7 @@ inline bool StructureRareData::tryCachePropertyNameEnumeratorViaWatchpoint(VM& v > unsigned index = 0; > for (auto* current = chain->head(); *current; ++current) { > StructureID structureID = *current; >- Structure* structure = vm.getStructure(structureID); >+ Structure* structure = structureID.decode(); > m_cachedPropertyNameEnumeratorWatchpoints[index].install(this, structure); > ++index; > } >diff --git a/Source/JavaScriptCore/runtime/SymbolPrototype.cpp b/Source/JavaScriptCore/runtime/SymbolPrototype.cpp >index 0260145ee62f626fbc83985d10ea2b5f96a0d189..bcf1635169c0247724c7103915531c120d89c388 100644 >--- a/Source/JavaScriptCore/runtime/SymbolPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/SymbolPrototype.cpp >@@ -96,7 +96,7 @@ JSC_DEFINE_CUSTOM_GETTER(symbolProtoGetterDescription, (JSGlobalObject* globalOb > if (!symbol) > return throwVMTypeError(globalObject, scope, SymbolDescriptionTypeError); > scope.release(); >- Integrity::auditStructureID(vm, symbol->structureID()); >+ Integrity::auditStructureID(symbol->structureID()); > const auto description = symbol->description(); > return JSValue::encode(description.isNull() ? jsUndefined() : jsString(vm, description)); > } >@@ -109,7 +109,7 @@ JSC_DEFINE_HOST_FUNCTION(symbolProtoFuncToString, (JSGlobalObject* globalObject, > Symbol* symbol = tryExtractSymbol(vm, callFrame->thisValue()); > if (!symbol) > return throwVMTypeError(globalObject, scope, SymbolToStringTypeError); >- Integrity::auditStructureID(vm, symbol->structureID()); >+ Integrity::auditStructureID(symbol->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(jsNontrivialString(vm, symbol->descriptiveString()))); > } > >@@ -122,7 +122,7 @@ JSC_DEFINE_HOST_FUNCTION(symbolProtoFuncValueOf, (JSGlobalObject* globalObject, > if (!symbol) > return throwVMTypeError(globalObject, scope, SymbolValueOfTypeError); > >- Integrity::auditStructureID(vm, symbol->structureID()); >+ Integrity::auditStructureID(symbol->structureID()); > RELEASE_AND_RETURN(scope, JSValue::encode(symbol)); > } > >diff --git a/Source/JavaScriptCore/runtime/TypeProfilerLog.cpp b/Source/JavaScriptCore/runtime/TypeProfilerLog.cpp >index 4ff9df0b2ec0a41667f82f54dc94ebd8d7b2dd0f..8ed3304baa93522593a482fb0b8064ad56d8754b 100644 >--- a/Source/JavaScriptCore/runtime/TypeProfilerLog.cpp >+++ b/Source/JavaScriptCore/runtime/TypeProfilerLog.cpp >@@ -80,7 +80,7 @@ void TypeProfilerLog::processLogEntries(VM& vm, const String& reason) > Structure* structure = nullptr; > bool sawPolyProtoStructure = false; > if (id) { >- structure = Heap::heap(value.asCell())->structureIDTable().get(id); >+ structure = id.decode(); > auto iter = cachedMonoProtoShapes.find(structure); > if (iter == cachedMonoProtoShapes.end()) { > auto key = std::make_pair(structure, value.asCell()); >@@ -131,7 +131,7 @@ void TypeProfilerLog::visit(AbstractSlotVisitor& visitor) > for (LogEntry* entry = m_logStartPtr; entry != m_currentLogEntryPtr; ++entry) { > visitor.appendUnbarriered(entry->value); > if (StructureID id = entry->structureID) { >- Structure* structure = visitor.heap()->structureIDTable().get(id); >+ Structure* structure = id.decode(); > visitor.appendUnbarriered(structure); > } > } >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 65233a4fe956bd40999e7dede8b28f07cea04cab..465db83e717daaa7ee4e4838185159de6726e290 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -164,6 +164,7 @@ > #include "StrictEvalActivation.h" > #include "StringObject.h" > #include "StrongInlines.h" >+#include "StructureAlignedMemoryAllocator.h" > #include "StructureChain.h" > #include "StructureInlines.h" > #include "SymbolObject.h" >@@ -385,8 +386,8 @@ VM::VM(VMType vmType, HeapType heapType, WTF::RunLoop* runLoop, bool* success) > , stringObjectSpace ISO_SUBSPACE_INIT(heap, *cellHeapCellType, StringObject) > , structureChainSpace ISO_SUBSPACE_INIT(heap, *cellHeapCellType, StructureChain) > , structureRareDataSpace ISO_SUBSPACE_INIT(heap, *destructibleCellHeapCellType, StructureRareData) // Hash:0xaca4e62d >- , structureSpace ISO_SUBSPACE_INIT(heap, *destructibleCellHeapCellType, Structure) // Hash:0x1f1bcdca >- , brandedStructureSpace ISO_SUBSPACE_INIT(heap, *destructibleCellHeapCellType, BrandedStructure) >+ , structureSpace("IsolatedStructureSpace", heap, *destructibleCellHeapCellType, sizeof(Structure), Structure::numberOfLowerTierCells, makeUnique<StructureAlignedMemoryAllocator>("Structure")) >+ , brandedStructureSpace("IsolatedBrandedStructureSpace", heap, *destructibleCellHeapCellType, sizeof(BrandedStructure), BrandedStructure::numberOfLowerTierCells, makeUnique<StructureAlignedMemoryAllocator>("Structure")) > , symbolTableSpace ISO_SUBSPACE_INIT(heap, *destructibleCellHeapCellType, SymbolTable) // Hash:0xc5215afd > , executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace) > , executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace) >diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h >index 6dbe1555fedee44ebce395f9d6bbb1be73799e16..85957c6b1e34f199b26c368b267d1c18f1e2d884 100644 >--- a/Source/JavaScriptCore/runtime/VM.h >+++ b/Source/JavaScriptCore/runtime/VM.h >@@ -968,17 +968,6 @@ 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*); > >diff --git a/Source/JavaScriptCore/tools/HeapVerifier.cpp b/Source/JavaScriptCore/tools/HeapVerifier.cpp >index 3ce0de4241c9595ba88617b15b37bfc56973ce51..2aaa3eb78184a5b2bd56b2c00253c712c3483473 100644 >--- a/Source/JavaScriptCore/tools/HeapVerifier.cpp >+++ b/Source/JavaScriptCore/tools/HeapVerifier.cpp >@@ -230,14 +230,10 @@ bool HeapVerifier::validateJSCell(VM* expectedVM, JSCell* cell, CellProfile* pro > > // 2. Validate the cell's structure > >- Structure* structure = vm.getStructure(structureID); >+ Structure* structure = structureID.decode(); > if (!structure) { > printHeaderAndCell(); >-#if USE(JSVALUE64) >- uint32_t structureIDAsUint32 = structureID; >-#else >- uint32_t structureIDAsUint32 = reinterpret_cast<uint32_t>(structureID); >-#endif >+ uint32_t structureIDAsUint32 = structureID.bits(); > dataLog(" with structureID ", structureIDAsUint32, " maps to a NULL Structure pointer\n"); > return false; > } >@@ -285,7 +281,7 @@ bool HeapVerifier::validateJSCell(VM* expectedVM, JSCell* cell, CellProfile* pro > > // 3. Validate the cell's structure's structure. > >- Structure* structureStructure = vm.getStructure(structureID); >+ Structure* structureStructure = structureID.decode(); > if (!structureStructure) { > printHeaderAndCell(); > dataLog(" has structure ", RawPointer(structure), " whose structure is NULL\n"); >diff --git a/Source/JavaScriptCore/tools/Integrity.cpp b/Source/JavaScriptCore/tools/Integrity.cpp >index 0c98fd4a0cbb83781737d5ed3b8d04ebd9c8c3e6..12f1913ac5157c8c3a10e5c9b9cbbdfb8119df14 100644 >--- a/Source/JavaScriptCore/tools/Integrity.cpp >+++ b/Source/JavaScriptCore/tools/Integrity.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * Copyright (C) 2019-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 >diff --git a/Source/JavaScriptCore/tools/Integrity.h b/Source/JavaScriptCore/tools/Integrity.h >index 71e81b823b504504886e93e0a94acb22b593e8d9..d633f4aa969adbe136833863786d4bf5a6225389 100644 >--- a/Source/JavaScriptCore/tools/Integrity.h >+++ b/Source/JavaScriptCore/tools/Integrity.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2019-2020 Apple Inc. All rights reserved. >+ * Copyright (C) 2019-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 >@@ -26,7 +26,6 @@ > #pragma once > > #include "JSCJSValue.h" >-#include "StructureIDTable.h" > #include <wtf/Gigacage.h> > #include <wtf/Lock.h> > >@@ -100,8 +99,7 @@ ALWAYS_INLINE void auditCell(VM& vm, JSValue value) > auditCell<auditLevel>(vm, value.asCell()); > } > >-ALWAYS_INLINE void auditStructureID(StructureIDTable&, StructureID); >-ALWAYS_INLINE void auditStructureID(VM&, StructureID); >+ALWAYS_INLINE void auditStructureID(StructureID); > > } // namespace Integrity > >diff --git a/Source/JavaScriptCore/tools/IntegrityInlines.h b/Source/JavaScriptCore/tools/IntegrityInlines.h >index f504dc939021f65176ca0e528fc372d94c829b2a..ca93fd0bb0787f600c55a1af1405fe9d33c8b643 100644 >--- a/Source/JavaScriptCore/tools/IntegrityInlines.h >+++ b/Source/JavaScriptCore/tools/IntegrityInlines.h >@@ -73,14 +73,13 @@ ALWAYS_INLINE void auditCellRandomly(VM& vm, JSCell* cell) > auditCellFully(vm, cell); > } > >-ALWAYS_INLINE void auditStructureID(StructureIDTable& table, StructureID id) >-{ >- table.validate(id); >-} > >-ALWAYS_INLINE void auditStructureID(VM& vm, StructureID id) >+ALWAYS_INLINE void auditStructureID(StructureID structureID) > { >- auditStructureID(vm.heap.structureIDTable(), id); >+ UNUSED_PARAM(structureID); >+#if CPU(ADDRESS64) >+ ASSERT(structureID.bits() <= structureHeapAddressSize + StructureID::nukedStructureIDBit); >+#endif > } > > } // namespace Integrity >diff --git a/Source/JavaScriptCore/tools/JSDollarVM.cpp b/Source/JavaScriptCore/tools/JSDollarVM.cpp >index 83ee8f2b621e1f7ede13bcfa9e26bff2ff153b0d..c4e6e43414278dae7f0d54589ca78fa5a273b9d4 100644 >--- a/Source/JavaScriptCore/tools/JSDollarVM.cpp >+++ b/Source/JavaScriptCore/tools/JSDollarVM.cpp >@@ -3583,7 +3583,7 @@ JSC_DEFINE_HOST_FUNCTION(functionGetStructureTransitionList, (JSGlobalObject* gl > > for (size_t i = 0; i < structures.size(); ++i) { > auto* structure = structures[structures.size() - i - 1]; >- result->push(globalObject, JSValue(structure->id())); >+ result->push(globalObject, JSValue(structure->id().bits())); > RETURN_IF_EXCEPTION(scope, { }); > result->push(globalObject, JSValue(structure->transitionOffset())); > RETURN_IF_EXCEPTION(scope, { }); >diff --git a/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp b/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >index f464a7a0045f6cee4858765a3317bafd28a2ca37..ca3228a450ae95e103faa1ac5e0f45e217ddd431 100644 >--- a/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >+++ b/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >@@ -266,7 +266,7 @@ MacroAssemblerCodePtr<JSEntryPtrTag> WebAssemblyFunction::jsCallEntrypointSlow() > slowPath.append(jit.branchIfNotCell(scratchGPR)); > > stackLimitGPRIsClobbered = true; >- jit.emitLoadStructure(vm, scratchGPR, scratchGPR, stackLimitGPR); >+ jit.emitLoadStructure(vm, scratchGPR, scratchGPR); > jit.loadPtr(CCallHelpers::Address(scratchGPR, Structure::classInfoOffset()), scratchGPR); > > static_assert(std::is_final<WebAssemblyFunction>::value, "We do not check for subtypes below"); >diff --git a/Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp b/Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp >index c7b3d6f7e94511c18adfd7a76c8921969064e95c..18a4d1f91dffe4d485bc67c9911bb804d239cda1 100644 >--- a/Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp >+++ b/Source/JavaScriptCore/wasm/js/WebAssemblyGlobalPrototype.cpp >@@ -64,7 +64,7 @@ static ALWAYS_INLINE JSWebAssemblyGlobal* getGlobal(JSGlobalObject* globalObject > createTypeError(globalObject, "expected |this| value to be an instance of WebAssembly.Global"_s)); > return nullptr; > } >- Integrity::auditStructureID(vm, result->structureID()); >+ Integrity::auditStructureID(result->structureID()); > return result; > } >
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
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 233379
:
444852
|
444863
|
444962
|
444986
|
445142
|
445143
|
445145
|
445146
|
445147
|
445150
|
445204
|
445431
|
445436
|
445466
|
445487
|
445488
|
445493
|
445583