WebKit Bugzilla
Attachment 369130 Details for
Bug 197110
: Remove Gigacage from arm64 and use PAC for arm64e instead
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197110-20190506100050.patch (text/plain), 128.86 KB, created by
Keith Miller
on 2019-05-06 10:00:52 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Keith Miller
Created:
2019-05-06 10:00:52 PDT
Size:
128.86 KB
patch
obsolete
>Subversion Revision: 244940 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index ac70cb61f481bf89008ab6697a6fb2849a56fd7e..b7fda6e7415be3cd95bd61c8f261888b5f70dffe 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,171 @@ >+2019-05-03 Keith Miller <keith_miller@apple.com> >+ >+ Remove Gigacage from arm64 and use PAC for arm64e instead >+ https://bugs.webkit.org/show_bug.cgi?id=197110 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * assembler/MacroAssemblerARM64E.h: >+ (JSC::MacroAssemblerARM64E::tagArrayPtr): >+ (JSC::MacroAssemblerARM64E::untagArrayPtr): >+ (JSC::MacroAssemblerARM64E::removeArrayPtrTag): >+ * b3/B3LowerToAir.cpp: >+ * b3/B3PatchpointSpecial.cpp: >+ (JSC::B3::PatchpointSpecial::admitsStack): >+ * b3/B3StackmapSpecial.cpp: >+ (JSC::B3::StackmapSpecial::forEachArgImpl): >+ (JSC::B3::StackmapSpecial::isArgValidForRep): >+ * b3/B3Validate.cpp: >+ * b3/B3ValueRep.cpp: >+ (JSC::B3::ValueRep::addUsedRegistersTo const): >+ (JSC::B3::ValueRep::dump const): >+ (WTF::printInternal): >+ * b3/B3ValueRep.h: >+ (JSC::B3::ValueRep::ValueRep): >+ (JSC::B3::ValueRep::isReg const): >+ * dfg/DFGOperations.cpp: >+ (JSC::DFG::newTypedArrayWithSize): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds): >+ (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage): >+ (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): >+ (JSC::DFG::SpeculativeJIT::compileGetTypedArrayByteOffset): >+ (JSC::DFG::SpeculativeJIT::compileNewTypedArrayWithSize): >+ * dfg/DFGSpeculativeJIT.h: >+ * dfg/DFGSpeculativeJIT64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ * ftl/FTLLowerDFGToB3.cpp: >+ (JSC::FTL::DFG::LowerDFGToB3::compileGetIndexedPropertyStorage): >+ (JSC::FTL::DFG::LowerDFGToB3::compileGetTypedArrayByteOffset): >+ (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): >+ (JSC::FTL::DFG::LowerDFGToB3::compileDataViewGet): >+ (JSC::FTL::DFG::LowerDFGToB3::compileDataViewSet): >+ (JSC::FTL::DFG::LowerDFGToB3::untagArrayPtr): >+ (JSC::FTL::DFG::LowerDFGToB3::caged): >+ (JSC::FTL::DFG::LowerDFGToB3::speculateTypedArrayIsNotNeutered): >+ * jit/AssemblyHelpers.h: >+ (JSC::AssemblyHelpers::cageConditionally): >+ * jit/ExecutableAllocator.cpp: >+ (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): >+ * jit/IntrinsicEmitter.cpp: >+ (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter): >+ * jit/JITPropertyAccess.cpp: >+ (JSC::JIT::emitDirectArgumentsGetByVal): >+ (JSC::JIT::emitIntTypedArrayGetByVal): >+ (JSC::JIT::emitFloatTypedArrayGetByVal): >+ (JSC::JIT::emitIntTypedArrayPutByVal): >+ (JSC::JIT::emitFloatTypedArrayPutByVal): >+ * jit/PolymorphicCallStubRoutine.cpp: >+ (JSC::PolymorphicCallNode::clearCallLinkInfo): >+ * llint/LowLevelInterpreter64.asm: >+ * offlineasm/arm64.rb: >+ * offlineasm/arm64e.rb: Added. >+ * offlineasm/ast.rb: >+ * offlineasm/instructions.rb: >+ * offlineasm/registers.rb: >+ * offlineasm/x86.rb: >+ * runtime/ArrayBuffer.cpp: >+ (JSC::SharedArrayBufferContents::SharedArrayBufferContents): >+ (JSC::SharedArrayBufferContents::~SharedArrayBufferContents): >+ (JSC::ArrayBufferContents::ArrayBufferContents): >+ (JSC::ArrayBufferContents::destroy): >+ (JSC::ArrayBufferContents::tryAllocate): >+ (JSC::ArrayBufferContents::makeShared): >+ (JSC::ArrayBufferContents::copyTo): >+ * runtime/ArrayBuffer.h: >+ (JSC::SharedArrayBufferContents::data const): >+ (JSC::ArrayBufferContents::data const): >+ (JSC::ArrayBuffer::data): >+ (JSC::ArrayBuffer::data const): >+ (JSC::ArrayBuffer::byteLength const): >+ * runtime/ArrayBufferView.cpp: >+ (JSC::ArrayBufferView::ArrayBufferView): >+ * runtime/ArrayBufferView.h: >+ (JSC::ArrayBufferView::baseAddress const): >+ (JSC::ArrayBufferView::byteLength const): >+ (JSC::ArrayBufferView::setRangeImpl): >+ (JSC::ArrayBufferView::getRangeImpl): >+ * runtime/CachedTypes.cpp: >+ (JSC::CachedScopedArgumentsTable::encode): >+ (JSC::CachedScopedArgumentsTable::decode const): >+ * runtime/CagedBarrierPtr.h: >+ (JSC::CagedBarrierPtr::CagedBarrierPtr): >+ (JSC::CagedBarrierPtr::set): >+ (JSC::CagedBarrierPtr::get const): >+ (JSC::CagedBarrierPtr::getMayBeNull const): >+ (JSC::CagedBarrierPtr::getUnsafe const): >+ (JSC::CagedBarrierPtr::at const): >+ (JSC::CagedBarrierPtr::operator== const): >+ (JSC::CagedBarrierPtr::operator bool const): >+ (JSC::CagedBarrierPtr::setWithoutBarrier): >+ (JSC::CagedBarrierPtr::operator* const): Deleted. >+ (JSC::CagedBarrierPtr::operator-> const): Deleted. >+ (JSC::CagedBarrierPtr::operator[] const): Deleted. >+ (): Deleted. >+ * runtime/DataView.cpp: >+ (JSC::DataView::DataView): >+ * runtime/DataView.h: >+ (JSC::DataView::get): >+ (JSC::DataView::set): >+ * runtime/DirectArguments.cpp: >+ (JSC::DirectArguments::visitChildren): >+ (JSC::DirectArguments::overrideThings): >+ (JSC::DirectArguments::unmapArgument): >+ * runtime/DirectArguments.h: >+ * runtime/GenericArguments.h: >+ * runtime/GenericArgumentsInlines.h: >+ (JSC::GenericArguments<Type>::visitChildren): >+ (JSC::GenericArguments<Type>::initModifiedArgumentsDescriptor): >+ (JSC::GenericArguments<Type>::setModifiedArgumentDescriptor): >+ (JSC::GenericArguments<Type>::isModifiedArgumentDescriptor): >+ * runtime/GenericTypedArrayView.h: >+ * runtime/GenericTypedArrayViewInlines.h: >+ (JSC::GenericTypedArrayView<Adaptor>::GenericTypedArrayView): >+ * runtime/JSArrayBufferView.cpp: >+ (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext): >+ (JSC::JSArrayBufferView::JSArrayBufferView): >+ (JSC::JSArrayBufferView::finalize): >+ (JSC::JSArrayBufferView::slowDownAndWasteMemory): >+ * runtime/JSArrayBufferView.h: >+ (JSC::JSArrayBufferView::ConstructionContext::vector const): >+ (JSC::JSArrayBufferView::isNeutered): >+ (JSC::JSArrayBufferView::hasVector const): >+ (JSC::JSArrayBufferView::vector const): >+ * runtime/JSGenericTypedArrayViewInlines.h: >+ (JSC::JSGenericTypedArrayView<Adaptor>::createUninitialized): >+ (JSC::JSGenericTypedArrayView<Adaptor>::estimatedSize): >+ (JSC::JSGenericTypedArrayView<Adaptor>::visitChildren): >+ * runtime/Options.h: >+ * runtime/ScopedArgumentsTable.cpp: >+ (JSC::ScopedArgumentsTable::clone): >+ (JSC::ScopedArgumentsTable::setLength): >+ * runtime/ScopedArgumentsTable.h: >+ * runtime/SymbolTable.h: >+ * wasm/WasmAirIRGenerator.cpp: >+ (JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState): >+ (JSC::Wasm::AirIRGenerator::addCallIndirect): >+ * wasm/WasmB3IRGenerator.cpp: >+ (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState): >+ (JSC::Wasm::B3IRGenerator::addCallIndirect): >+ * wasm/WasmBBQPlan.cpp: >+ (JSC::Wasm::BBQPlan::complete): >+ * wasm/WasmBinding.cpp: >+ (JSC::Wasm::wasmToWasm): >+ * wasm/WasmInstance.h: >+ (JSC::Wasm::Instance::cachedMemory const): >+ (JSC::Wasm::Instance::updateCachedMemory): >+ * wasm/WasmMemory.cpp: >+ (JSC::Wasm::Memory::Memory): >+ (JSC::Wasm::Memory::~Memory): >+ (JSC::Wasm::Memory::grow): >+ (JSC::Wasm::Memory::dump const): >+ * wasm/WasmMemory.h: >+ (JSC::Wasm::Memory::memory const): >+ * wasm/js/JSToWasm.cpp: >+ (JSC::Wasm::createJSToWasmWrapper): >+ * wasm/js/WebAssemblyFunction.cpp: >+ (JSC::WebAssemblyFunction::jsCallEntrypointSlow): >+ > 2019-05-03 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] Need to emit SetLocal if we emit MovHint in DFGByteCodeParser >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index 8da671ede38b89b43d1d1a714ce7ab6090cfe38b..99dba4c9344f363ce87f062602b6ecdd64d69d1d 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,44 @@ >+2019-05-03 Keith Miller <keith_miller@apple.com> >+ >+ Remove Gigacage from arm64 and use PAC for arm64e instead >+ https://bugs.webkit.org/show_bug.cgi?id=197110 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WTF.xcodeproj/project.pbxproj: >+ * wtf/CagedPtr.h: >+ (WTF::CagedPtr::CagedPtr): >+ (WTF::CagedPtr::get const): >+ (WTF::CagedPtr::getMayBeNull const): >+ (WTF::CagedPtr::getUnsafe const): >+ (WTF::CagedPtr::at const): >+ (WTF::CagedPtr::reauthenticate): >+ (WTF::CagedPtr::operator=): >+ (WTF::CagedPtr::operator== const): >+ (WTF::CagedPtr::operator bool const): >+ (WTF::CagedPtr::operator* const): Deleted. >+ (WTF::CagedPtr::operator-> const): Deleted. >+ (WTF::CagedPtr::operator[] const): Deleted. >+ (): Deleted. >+ * wtf/CagedUniquePtr.h: >+ (WTF::CagedUniquePtr::CagedUniquePtr): >+ (WTF::CagedUniquePtr::create): >+ (WTF::CagedUniquePtr::~CagedUniquePtr): >+ (WTF::CagedUniquePtr::destroy): >+ (): Deleted. >+ * wtf/Gigacage.h: >+ * wtf/PtrTag.h: >+ (WTF::tagArrayPtr): >+ (WTF::untagArrayPtr): >+ (WTF::removeArrayPtrTag): >+ (WTF::retagArrayPtr): >+ * wtf/TaggedArrayStoragePtr.h: Added. >+ (WTF::TaggedArrayStoragePtr::TaggedArrayStoragePtr): >+ (WTF::TaggedArrayStoragePtr::get const): >+ (WTF::TaggedArrayStoragePtr::getUnsafe const): >+ (WTF::TaggedArrayStoragePtr::resize): >+ (WTF::TaggedArrayStoragePtr::operator bool const): >+ > 2019-05-03 Sihui Liu <sihui_liu@apple.com> > > Add assertion to check whether shm files have maximum FileProtection of CompleteUnlessOpen >diff --git a/Source/bmalloc/ChangeLog b/Source/bmalloc/ChangeLog >index d265b8620735bfb977eeec8eafb1f046600c1569..1fab33b0c944a65eb5a24cdcebddaecf0972f55f 100644 >--- a/Source/bmalloc/ChangeLog >+++ b/Source/bmalloc/ChangeLog >@@ -1,3 +1,14 @@ >+ >+ 2019-05-03 Keith Miller <keith_miller@apple.com> >+ >+ Remove Gigacage from arm64 and use PAC for arm64e instead >+ https://bugs.webkit.org/show_bug.cgi?id=197110 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * bmalloc/Gigacage.h: >+ (Gigacage::cagedMayBeNull): >+ > 2019-04-29 Alex Christensen <achristensen@webkit.org> > > <rdar://problem/50299396> Fix internal High Sierra build >diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h >index 41940cde66ec51161fc904520e5572f85b46d068..fc561fa01fbe9f7b0af3bedc41a829216e5ffcad 100644 >--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h >+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h >@@ -82,6 +82,28 @@ public: > m_assembler.xpaci(target); > } > >+ ALWAYS_INLINE void tagArrayPtr(RegisterID target, RegisterID length) >+ { >+ m_assembler.pacdb(target, length); >+ } >+ >+ ALWAYS_INLINE void untagArrayPtr(RegisterID target, RegisterID length) >+ { >+ m_assembler.autdb(target, length); >+ } >+ >+ ALWAYS_INLINE void untagArrayPtr(RegisterID target, Address length) >+ { >+ auto lengthGPR = getCachedDataTempRegisterIDAndInvalidate(); >+ load32(length, lengthGPR); >+ m_assembler.autdb(target, lengthGPR); >+ } >+ >+ ALWAYS_INLINE void removeArrayPtrTag(RegisterID target) >+ { >+ m_assembler.xpacd(target); >+ } >+ > static const RegisterID InvalidGPR = static_cast<RegisterID>(-1); > > enum class CallSignatureType { >diff --git a/Source/JavaScriptCore/b3/B3LowerToAir.cpp b/Source/JavaScriptCore/b3/B3LowerToAir.cpp >index 1b3a92e5226320365dfaae6303c0fe1e2dbb9ee8..b4098bcdd19796a3fb213196d8a03ea92c64cf21 100644 >--- a/Source/JavaScriptCore/b3/B3LowerToAir.cpp >+++ b/Source/JavaScriptCore/b3/B3LowerToAir.cpp >@@ -1274,6 +1274,7 @@ private: > arg = tmp(value.value()); > break; > case ValueRep::SomeRegister: >+ case ValueRep::SomeLateRegister: > arg = tmp(value.value()); > break; > case ValueRep::SomeRegisterWithClobber: { >diff --git a/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp b/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp >index daae2432c5b5bf44d8ec3f16f709e03c0cc57a23..1532edff2b94f94dea81da472eeeca0ca3e46d10 100644 >--- a/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp >+++ b/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp >@@ -120,6 +120,7 @@ bool PatchpointSpecial::admitsStack(Inst& inst, unsigned argIndex) > case ValueRep::SomeRegister: > case ValueRep::SomeRegisterWithClobber: > case ValueRep::SomeEarlyRegister: >+ case ValueRep::SomeLateRegister: > case ValueRep::Register: > case ValueRep::LateRegister: > return false; >diff --git a/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp b/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp >index 2f07111470188a9ce9aeca3f1ebcf37ebdbd3f3d..298c94c95a5c5d01ddeca45ca4adb6073d5ee31f 100644 >--- a/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp >+++ b/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp >@@ -113,6 +113,7 @@ void StackmapSpecial::forEachArgImpl( > case ValueRep::SomeRegisterWithClobber: > role = Arg::UseDef; > break; >+ case ValueRep::SomeLateRegister: > case ValueRep::LateRegister: > role = Arg::LateUse; > break; >@@ -254,6 +255,7 @@ bool StackmapSpecial::isArgValidForRep(Air::Code& code, const Air::Arg& arg, con > case ValueRep::SomeRegister: > case ValueRep::SomeRegisterWithClobber: > case ValueRep::SomeEarlyRegister: >+ case ValueRep::SomeLateRegister: > return arg.isTmp(); > case ValueRep::LateRegister: > case ValueRep::Register: >diff --git a/Source/JavaScriptCore/b3/B3Validate.cpp b/Source/JavaScriptCore/b3/B3Validate.cpp >index f5cd7d2f0c91e86868d12ef809a150ddffb4d08b..f7b3c55f8eef099b0bd78c405fdff0775b613c7a 100644 >--- a/Source/JavaScriptCore/b3/B3Validate.cpp >+++ b/Source/JavaScriptCore/b3/B3Validate.cpp >@@ -580,6 +580,7 @@ private: > break; > case ValueRep::Register: > case ValueRep::LateRegister: >+ case ValueRep::SomeLateRegister: > if (value.rep().kind() == ValueRep::LateRegister) > VALIDATE(role == ConstraintRole::Use, ("At ", *context, ": ", value)); > if (value.rep().reg().isGPR()) >diff --git a/Source/JavaScriptCore/b3/B3ValueRep.cpp b/Source/JavaScriptCore/b3/B3ValueRep.cpp >index 45a1113e0de435469d93029ba48913b1e71d5da3..d4b47f14b0e89c08cd661b488b5e6eeb9440f195 100644 >--- a/Source/JavaScriptCore/b3/B3ValueRep.cpp >+++ b/Source/JavaScriptCore/b3/B3ValueRep.cpp >@@ -42,6 +42,7 @@ void ValueRep::addUsedRegistersTo(RegisterSet& set) const > case SomeRegister: > case SomeRegisterWithClobber: > case SomeEarlyRegister: >+ case SomeLateRegister: > case Constant: > return; > case LateRegister: >@@ -74,6 +75,7 @@ void ValueRep::dump(PrintStream& out) const > case SomeRegister: > case SomeRegisterWithClobber: > case SomeEarlyRegister: >+ case SomeLateRegister: > return; > case LateRegister: > case Register: >@@ -183,6 +185,9 @@ void printInternal(PrintStream& out, ValueRep::Kind kind) > case ValueRep::SomeEarlyRegister: > out.print("SomeEarlyRegister"); > return; >+ case ValueRep::SomeLateRegister: >+ out.print("SomeLateRegister"); >+ return; > case ValueRep::Register: > out.print("Register"); > return; >diff --git a/Source/JavaScriptCore/b3/B3ValueRep.h b/Source/JavaScriptCore/b3/B3ValueRep.h >index 463f27e40d64e1bfd2e212e368cbea2fbdf370b7..fcfa7fcfdda066d58c7c71a5852d5bdbb35d9194 100644 >--- a/Source/JavaScriptCore/b3/B3ValueRep.h >+++ b/Source/JavaScriptCore/b3/B3ValueRep.h >@@ -74,7 +74,12 @@ public: > // that the def happens before any of the effects of the stackmap. This is only valid for > // the result constraint of a Patchpoint. > SomeEarlyRegister, >- >+ >+ // As an input representation, this tells us that B3 should pick some register, but implies >+ // that the use happens after any of the effects of the patchpoint. >+ // This is only works for patchpoints. >+ SomeLateRegister, >+ > // As an input representation, this forces a particular register. As an output > // representation, this tells us what register B3 picked. > Register, >@@ -111,7 +116,7 @@ public: > ValueRep(Kind kind) > : m_kind(kind) > { >- ASSERT(kind == WarmAny || kind == ColdAny || kind == LateColdAny || kind == SomeRegister || kind == SomeRegisterWithClobber || kind == SomeEarlyRegister); >+ ASSERT(kind == WarmAny || kind == ColdAny || kind == LateColdAny || kind == SomeRegister || kind == SomeRegisterWithClobber || kind == SomeEarlyRegister || kind == SomeLateRegister); > } > > static ValueRep reg(Reg reg) >@@ -185,7 +190,7 @@ public: > > bool isAny() const { return kind() == WarmAny || kind() == ColdAny || kind() == LateColdAny; } > >- bool isReg() const { return kind() == Register || kind() == LateRegister; } >+ bool isReg() const { return kind() == Register || kind() == LateRegister || kind() == SomeLateRegister; } > > Reg reg() const > { >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp >index fea350da028fe031092d780ee6989c81ebfa0312..b87913e04b2414ba55521f7784ed9f9017209771 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -198,7 +198,7 @@ char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size, > } > > if (vector) >- return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, vector)); >+ return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, WTF::removeArrayPtrTag(vector))); > > RELEASE_AND_RETURN(scope, bitwise_cast<char*>(ViewClass::create(exec, structure, size))); > } >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index 3c0390725e83572eba1b6297603f0c30f583d917..dc2d91cde1e912fe4272e57e6e75fc25dc78357a 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -40,6 +40,7 @@ > #include "DFGSlowPathGenerator.h" > #include "DFGSnippetParams.h" > #include "DirectArguments.h" >+#include "DisallowMacroScratchRegisterUsage.h" > #include "JITAddGenerator.h" > #include "JITBitAndGenerator.h" > #include "JITBitOrGenerator.h" >@@ -2871,9 +2872,21 @@ JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds(Node* > MacroAssembler::Address(base, JSArrayBufferView::offsetOfMode()), > TrustedImm32(WastefulTypedArray)); > >- JITCompiler::Jump hasNullVector = m_jit.branchTestPtr( >+ JITCompiler::Jump hasNullVector; >+#if CPU(ARM64E) >+ { >+ GPRReg scratch = m_jit.scratchRegister(); >+ DisallowMacroScratchRegisterUsage disallowScratch(m_jit); >+ >+ m_jit.loadPtr(MacroAssembler::Address(base, JSArrayBufferView::offsetOfVector()), scratch); >+ m_jit.removeArrayPtrTag(scratch); >+ hasNullVector = m_jit.branchTestPtr(MacroAssembler::Zero, scratch); >+ } >+#else // CPU(ARM64E) >+ hasNullVector = m_jit.branchTestPtr( > MacroAssembler::Zero, > MacroAssembler::Address(base, JSArrayBufferView::offsetOfVector())); >+#endif > speculationCheck(Uncountable, JSValueSource(), node, hasNullVector); > notWasteful.link(&m_jit); > } >@@ -6670,9 +6683,10 @@ void SpeculativeJIT::compileConstantStoragePointer(Node* node) > storageResult(storageGPR, node); > } > >-void SpeculativeJIT::cageTypedArrayStorage(GPRReg storageReg) >+void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg) > { > #if GIGACAGE_ENABLED >+ UNUSED_PARAM(baseReg); > if (!Gigacage::shouldBeEnabled()) > return; > >@@ -6684,7 +6698,10 @@ void SpeculativeJIT::cageTypedArrayStorage(GPRReg storageReg) > } > > m_jit.cage(Gigacage::Primitive, storageReg); >+#elif CPU(ARM64E) >+ m_jit.untagArrayPtr(storageReg, MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength())); > #else >+ UNUSED_PARAM(baseReg); > UNUSED_PARAM(storageReg); > #endif > } >@@ -6708,16 +6725,17 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node) > > m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg); > break; >- >- default: >+ >+ default: { > auto typedArrayType = node->arrayMode().typedArrayType(); > ASSERT_UNUSED(typedArrayType, isTypedView(typedArrayType)); > > m_jit.loadPtr(JITCompiler::Address(baseReg, JSArrayBufferView::offsetOfVector()), storageReg); >- cageTypedArrayStorage(storageReg); >+ cageTypedArrayStorage(baseReg, storageReg); > break; > } >- >+ } >+ > storageResult(storageReg, node); > } > >@@ -6747,7 +6765,7 @@ void SpeculativeJIT::compileGetTypedArrayByteOffset(Node* node) > m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), dataGPR); > m_jit.cage(Gigacage::JSValue, dataGPR); > >- cageTypedArrayStorage(vectorGPR); >+ cageTypedArrayStorage(baseGPR, vectorGPR); > > m_jit.loadPtr(MacroAssembler::Address(dataGPR, Butterfly::offsetOfArrayBuffer()), arrayBufferGPR); > // FIXME: This needs caging. >@@ -9745,6 +9763,11 @@ void SpeculativeJIT::compileNewTypedArrayWithSize(Node* node) > MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesFour)); > m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit); > done.link(&m_jit); >+#if !GIGACAGE_ENABLED && CPU(ARM64E) >+ // sizeGPR is still boxed as a number and there is no 32-bit variant of the PAC instructions. >+ m_jit.zeroExtend32ToPtr(sizeGPR, scratchGPR); >+ m_jit.tagArrayPtr(storageGPR, scratchGPR); >+#endif > > auto butterfly = TrustedImmPtr(nullptr); > emitAllocateJSObject<JSArrayBufferView>( >@@ -9766,7 +9789,7 @@ void SpeculativeJIT::compileNewTypedArrayWithSize(Node* node) > addSlowPathGenerator(slowPathCall( > slowCases, this, operationNewTypedArrayWithSizeForType(typedArrayType), > resultGPR, structure, sizeGPR, storageGPR)); >- >+ > cellResult(resultGPR, node); > } > >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >index e65de38b0bb1becead325f552f4685c7ffa0f314..531f951aabddc983e7a3a33151bf950def178306 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >@@ -1650,7 +1650,7 @@ public: > template<bool strict> > GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat); > >- void cageTypedArrayStorage(GPRReg); >+ void cageTypedArrayStorage(GPRReg, GPRReg); > > void recordSetLocal( > VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format) >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >index f009e6b08b3f0c97ad91f8c303a6e2a0172ecca5..7fabe1f3b61ff3bc5fbf434593cfc16182f12bea 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >@@ -4673,7 +4673,7 @@ void SpeculativeJIT::compile(Node* node) > m_jit.branch64(MacroAssembler::AboveOrEqual, t2, t1)); > > m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2); >- cageTypedArrayStorage(t2); >+ cageTypedArrayStorage(dataViewGPR, t2); > > m_jit.zeroExtend32ToPtr(indexGPR, t1); > auto baseIndex = JITCompiler::BaseIndex(t2, t1, MacroAssembler::TimesOne); >@@ -4869,7 +4869,7 @@ void SpeculativeJIT::compile(Node* node) > m_jit.branch64(MacroAssembler::AboveOrEqual, t2, t1)); > > m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2); >- cageTypedArrayStorage(t2); >+ cageTypedArrayStorage(dataViewGPR, t2); > > m_jit.zeroExtend32ToPtr(indexGPR, t1); > auto baseIndex = JITCompiler::BaseIndex(t2, t1, MacroAssembler::TimesOne); >diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >index c2564d317b11c99e67bf3743431a18973727da6c..fe080c101764b1619ec0ca7d5fcb38297fbd6b9f 100644 >--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >@@ -3839,7 +3839,7 @@ private: > > DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()), m_node->arrayMode().typedArrayType()); > LValue vector = m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector); >- setStorage(caged(Gigacage::Primitive, vector)); >+ setStorage(caged(Gigacage::Primitive, vector, cell)); > } > > void compileCheckArray() >@@ -3883,10 +3883,10 @@ private: > > m_out.appendTo(notNull, continuation); > >- LValue butterflyPtr = caged(Gigacage::JSValue, m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly)); >+ LValue butterflyPtr = caged(Gigacage::JSValue, m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly), basePtr); > LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer); > >- LValue vectorPtr = caged(Gigacage::Primitive, vector); >+ LValue vectorPtr = caged(Gigacage::Primitive, vector, basePtr); > > // FIXME: This needs caging. > // https://bugs.webkit.org/show_bug.cgi?id=175515 >@@ -6438,6 +6438,17 @@ private: > m_out.int64Zero, > m_heaps.typedArrayProperties); > >+#if !GIGACAGE_ENABLED && CPU(ARM64E) >+ PatchpointValue* authenticate = m_out.patchpoint(pointerType()); >+ authenticate->appendSomeRegister(storage); >+ authenticate->append(size, B3::ValueRep(B3::ValueRep::SomeLateRegister)); >+ authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { >+ jit.move(params[1].gpr(), params[0].gpr()); >+ jit.tagArrayPtr(params[0].gpr(), params[2].gpr()); >+ }); >+ storage = authenticate; >+#endif >+ > ValueFromBlock haveStorage = m_out.anchor(storage); > > LValue fastResultValue = >@@ -12656,7 +12667,7 @@ private: > indexToCheck = m_out.add(indexToCheck, m_out.constInt64(data.byteSize - 1)); > speculate(OutOfBounds, noValue(), nullptr, m_out.aboveOrEqual(indexToCheck, length)); > >- LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector)); >+ LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector), dataView); > > TypedPointer pointer(m_heaps.typedArrayProperties, m_out.add(vector, m_out.zeroExtPtr(index))); > >@@ -12815,7 +12826,7 @@ private: > RELEASE_ASSERT_NOT_REACHED(); > } > >- LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector)); >+ LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector), dataView); > TypedPointer pointer(m_heaps.typedArrayProperties, m_out.add(vector, m_out.zeroExtPtr(index))); > > if (data.isFloatingPoint) { >@@ -14062,10 +14073,29 @@ private: > m_out.appendTo(performStore, lastNext); > } > } >- >- LValue caged(Gigacage::Kind kind, LValue ptr) >+ >+ LValue untagArrayPtr(LValue ptr, LValue size) >+ { >+ >+#if !GIGACAGE_ENABLED && CPU(ARM64E) >+ PatchpointValue* authenticate = m_out.patchpoint(pointerType()); >+ authenticate->appendSomeRegister(ptr); >+ authenticate->append(size, B3::ValueRep(B3::ValueRep::SomeLateRegister)); >+ authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { >+ jit.move(params[1].gpr(), params[0].gpr()); >+ jit.untagArrayPtr(params[0].gpr(), params[2].gpr()); >+ }); >+ return authenticate; >+#else >+ UNUSED_PARAM(size); >+ return ptr; >+#endif >+ } >+ >+ LValue caged(Gigacage::Kind kind, LValue ptr, LValue base) > { > #if GIGACAGE_ENABLED >+ UNUSED_PARAM(base); > if (!Gigacage::isEnabled(kind)) > return ptr; > >@@ -14094,6 +14124,13 @@ private: > // and possibly other smart things if we want to be able to remove this opaque. > // https://bugs.webkit.org/show_bug.cgi?id=175493 > return m_out.opaque(result); >+#elif CPU(ARM64E) >+ if (kind == Gigacage::Primitive) { >+ LValue size = m_out.load32(base, m_heaps.JSArrayBufferView_length); >+ return untagArrayPtr(ptr, size); >+ } >+ >+ return ptr; > #else > UNUSED_PARAM(kind); > return ptr; >@@ -16509,6 +16546,15 @@ private: > > LBasicBlock lastNext = m_out.appendTo(isWasteful, continuation); > LValue vector = m_out.loadPtr(base, m_heaps.JSArrayBufferView_vector); >+#if CPU(ARM64E) >+ PatchpointValue* authenticate = m_out.patchpoint(pointerType()); >+ authenticate->appendSomeRegister(vector); >+ authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { >+ jit.move(params[1].gpr(), params[0].gpr()); >+ jit.removeArrayPtrTag(params[0].gpr()); >+ }); >+ vector = authenticate; >+#endif > speculate(Uncountable, jsValueValue(vector), m_node, m_out.isZero64(vector)); > m_out.jump(continuation); > >diff --git a/Source/JavaScriptCore/jit/AssemblyHelpers.h b/Source/JavaScriptCore/jit/AssemblyHelpers.h >index 7602b2a93dab7a17b29d5b5eb832c15da253663e..32d8e068f3c5b031e57d6bbc2c2f96496c2476bc 100644 >--- a/Source/JavaScriptCore/jit/AssemblyHelpers.h >+++ b/Source/JavaScriptCore/jit/AssemblyHelpers.h >@@ -1569,7 +1569,7 @@ public: > #endif > } > >- void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg scratch) >+ void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg scratchOrLength) > { > #if GIGACAGE_ENABLED > if (!Gigacage::isEnabled(kind)) >@@ -1578,11 +1578,14 @@ public: > if (kind != Gigacage::Primitive || Gigacage::isDisablingPrimitiveGigacageDisabled()) > return cage(kind, storage); > >- loadPtr(&Gigacage::basePtr(kind), scratch); >- Jump done = branchTestPtr(Zero, scratch); >+ loadPtr(&Gigacage::basePtr(kind), scratchOrLength); >+ Jump done = branchTestPtr(Zero, scratchOrLength); > andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage); >- addPtr(scratch, storage); >+ addPtr(scratchOrLength, storage); > done.link(this); >+#elif CPU(ARM64E) >+ if (kind == Gigacage::Primitive) >+ untagArrayPtr(storage, scratchOrLength); > #else > UNUSED_PARAM(kind); > UNUSED_PARAM(storage); >diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp >index 7230cb7eef8c9f53cbb1a91248cbcc8ce06706eb..3a0a0c2a83b55baf349ac3e312ee2621b96982d4 100644 >--- a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp >+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp >@@ -182,15 +182,9 @@ public: > void* reservationBase = m_reservation.base(); > > #if ENABLE(FAST_JIT_PERMISSIONS) && !ENABLE(SEPARATED_WX_HEAP) >- RELEASE_ASSERT(os_thread_self_restrict_rwx_is_supported()); >- os_thread_self_restrict_rwx_to_rx(); >- > #else // not ENABLE(FAST_JIT_PERMISSIONS) or ENABLE(SEPARATED_WX_HEAP) > #if ENABLE(FAST_JIT_PERMISSIONS) >- if (os_thread_self_restrict_rwx_is_supported()) { >- useFastPermisionsJITCopy = true; >- os_thread_self_restrict_rwx_to_rx(); >- } else >+ > #endif > if (Options::useSeparatedWXHeap()) { > // First page of our JIT allocation is reserved. >diff --git a/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp b/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp >index cae39e935cb93ed97618370ed71b9945b55425d0..06c6127641bf4b688e315e279145278a32384b4d 100644 >--- a/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp >+++ b/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp >@@ -114,6 +114,9 @@ void IntrinsicGetterAccessCase::emitIntrinsicGetter(AccessGenerationState& state > > jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR); > jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), valueGPR); >+#if !GIGACAGE_ENABLED && CPU(ARM64E) >+ jit.removeArrayPtrTag(valueGPR); >+#endif > jit.loadPtr(MacroAssembler::Address(scratchGPR, Butterfly::offsetOfArrayBuffer()), scratchGPR); > jit.loadPtr(MacroAssembler::Address(scratchGPR, ArrayBuffer::offsetOfData()), scratchGPR); > jit.subPtr(scratchGPR, valueGPR); >diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >index 0b34400ab93ac7f651a823aba52862fcccddb722..519ad7aec364aba9266014c2d3eb462d259b3713 100644 >--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >@@ -1589,7 +1589,7 @@ JIT::JumpList JIT::emitDirectArgumentsGetByVal(const Instruction*, PatchableJump > load32(Address(base, DirectArguments::offsetOfLength()), scratch2); > slowCases.append(branch32(AboveOrEqual, property, scratch2)); > slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfMappedArguments()))); >- >+ > loadValue(BaseIndex(base, property, TimesEight, DirectArguments::storageOffset()), result); > > return slowCases; >@@ -1669,7 +1669,8 @@ JIT::JumpList JIT::emitIntTypedArrayGetByVal(const Instruction*, PatchableJump& > > load8(Address(base, JSCell::typeInfoTypeOffset()), scratch); > badType = patchableBranch32(NotEqual, scratch, TrustedImm32(typeForTypedArrayType(type))); >- slowCases.append(branch32(AboveOrEqual, property, Address(base, JSArrayBufferView::offsetOfLength()))); >+ load32(Address(base, JSArrayBufferView::offsetOfLength()), scratch2); >+ slowCases.append(branch32(AboveOrEqual, property, scratch2)); > loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch); > cageConditionally(Gigacage::Primitive, scratch, scratch2); > >@@ -1732,7 +1733,8 @@ JIT::JumpList JIT::emitFloatTypedArrayGetByVal(const Instruction*, PatchableJump > > load8(Address(base, JSCell::typeInfoTypeOffset()), scratch); > badType = patchableBranch32(NotEqual, scratch, TrustedImm32(typeForTypedArrayType(type))); >- slowCases.append(branch32(AboveOrEqual, property, Address(base, JSArrayBufferView::offsetOfLength()))); >+ load32(Address(base, JSArrayBufferView::offsetOfLength()), scratch2); >+ slowCases.append(branch32(AboveOrEqual, property, scratch2)); > loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch); > cageConditionally(Gigacage::Primitive, scratch, scratch2); > >@@ -1782,7 +1784,8 @@ JIT::JumpList JIT::emitIntTypedArrayPutByVal(Op bytecode, PatchableJump& badType > > load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); > badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); >- Jump inBounds = branch32(Below, property, Address(base, JSArrayBufferView::offsetOfLength())); >+ load32(Address(base, JSArrayBufferView::offsetOfLength()), lateScratch2); >+ Jump inBounds = branch32(Below, property, lateScratch2); > emitArrayProfileOutOfBoundsSpecialCase(profile); > slowCases.append(jump()); > inBounds.link(this); >@@ -1857,7 +1860,8 @@ JIT::JumpList JIT::emitFloatTypedArrayPutByVal(Op bytecode, PatchableJump& badTy > > load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); > badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); >- Jump inBounds = branch32(Below, property, Address(base, JSArrayBufferView::offsetOfLength())); >+ load32(Address(base, JSArrayBufferView::offsetOfLength()), lateScratch2); >+ Jump inBounds = branch32(Below, property, lateScratch2); > emitArrayProfileOutOfBoundsSpecialCase(profile); > slowCases.append(jump()); > inBounds.link(this); >diff --git a/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp b/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp >index 7cf74b164d3cbb06428a73432ce774245d6e18d0..91bb5856d178beaa4b9f77917a0cc35d2bd9c116 100644 >--- a/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp >+++ b/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp >@@ -57,9 +57,6 @@ void PolymorphicCallNode::unlink(VM& vm) > > void PolymorphicCallNode::clearCallLinkInfo() > { >- if (Options::dumpDisassembly()) >- dataLog("Clearing call link info for polymorphic call at ", m_callLinkInfo->callReturnLocation(), ", ", m_callLinkInfo->codeOrigin(), "\n"); >- > m_callLinkInfo = nullptr; > } > >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >index 3a13c6749b7ae576939fb0bfbabb320ea1aa60bd..c80743584509cfee30993a6eb11255d213351c62 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -408,19 +408,28 @@ macro checkSwitchToJITForLoop() > end) > end > >-macro uncage(basePtr, mask, ptr, scratch) >+macro uncage(basePtr, mask, ptr, scratchOrLength) > if GIGACAGE_ENABLED and not C_LOOP >- loadp basePtr, scratch >- btpz scratch, .done >+ loadp basePtr, scratchOrLength >+ btpz scratchOrLength, .done > andp mask, ptr >- addp scratch, ptr >+ addp scratchOrLength, ptr > .done: > end > end > >-macro loadCaged(basePtr, mask, source, dest, scratch) >+macro loadCagedPrimitive(source, dest, scratchOrLength) > loadp source, dest >- uncage(basePtr, mask, dest, scratch) >+ if GIGACAGE_ENABLED >+ uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, dest, scratchOrLength) >+ elsif ARM64E >+ untagArrayPtr scratchOrLength, dest >+ end >+end >+ >+macro loadCagedJSValue(source, dest, scratchOrLength) >+ loadp source, dest >+ uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, dest, scratchOrLength) > end > > macro loadVariable(get, fieldName, valueReg) >@@ -1310,7 +1319,7 @@ llintOpWithMetadata(op_get_by_id, OpGetById, macro (size, get, dispatch, metadat > arrayProfile(OpGetById::Metadata::m_modeMetadata.arrayLengthMode.arrayProfile, t0, t2, t5) > btiz t0, IsArray, .opGetByIdSlow > btiz t0, IndexingShapeMask, .opGetByIdSlow >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t3], t0, t1) >+ loadCagedJSValue(JSObject::m_butterfly[t3], t0, t1) > loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0 > bilt t0, 0, .opGetByIdSlow > orq tagTypeNumber, t0 >@@ -1433,7 +1442,7 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > loadConstantOrVariableInt32(size, t3, t1, .opGetByValSlow) > sxi2q t1, t1 > >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t0], t3, tagTypeNumber) >+ loadCagedJSValue(JSObject::m_butterfly[t0], t3, tagTypeNumber) > move TagTypeNumber, tagTypeNumber > > andi IndexingShapeMask, t2 >@@ -1477,7 +1486,17 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > biaeq t2, NumberOfTypedArrayTypesExcludingDataView, .opGetByValSlow > > # Sweet, now we know that we have a typed array. Do some basic things now. >- biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow >+ >+ if ARM64E >+ const scratchOrLength = t6 >+ loadi JSArrayBufferView::m_length[t0], scratchOrLength >+ biaeq t1, scratchOrLength, .opGetByValSlow >+ else >+ const scratchOrLength = t0 >+ biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow >+ end >+ >+ loadCagedPrimitive(JSArrayBufferView::m_vector[t0], t3, scratchOrLength) > > # Now bisect through the various types: > # Int8ArrayType, >@@ -1499,7 +1518,6 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > bia t2, Int8ArrayType - FirstTypedArrayType, .opGetByValUint8ArrayOrUint8ClampedArray > > # We have Int8ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadbs [t3, t1], t0 > finishIntGetByVal(t0, t1) > >@@ -1507,13 +1525,11 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > bia t2, Uint8ArrayType - FirstTypedArrayType, .opGetByValUint8ClampedArray > > # We have Uint8ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadb [t3, t1], t0 > finishIntGetByVal(t0, t1) > > .opGetByValUint8ClampedArray: > # We have Uint8ClampedArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadb [t3, t1], t0 > finishIntGetByVal(t0, t1) > >@@ -1522,13 +1538,11 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > bia t2, Int16ArrayType - FirstTypedArrayType, .opGetByValUint16Array > > # We have Int16ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadhs [t3, t1, 2], t0 > finishIntGetByVal(t0, t1) > > .opGetByValUint16Array: > # We have Uint16ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadh [t3, t1, 2], t0 > finishIntGetByVal(t0, t1) > >@@ -1540,13 +1554,11 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > bia t2, Int32ArrayType - FirstTypedArrayType, .opGetByValUint32Array > > # We have Int32ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadi [t3, t1, 4], t0 > finishIntGetByVal(t0, t1) > > .opGetByValUint32Array: > # We have Uint32ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > # This is the hardest part because of large unsigned values. > loadi [t3, t1, 4], t0 > bilt t0, 0, .opGetByValSlow # This case is still awkward to implement in LLInt. >@@ -1558,7 +1570,6 @@ llintOpWithMetadata(op_get_by_val, OpGetByVal, macro (size, get, dispatch, metad > bieq t2, Float32ArrayType - FirstTypedArrayType, .opGetByValSlow > > # We have Float64ArrayType. >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) > loadd [t3, t1, 8], ft0 > bdnequn ft0, ft0, .opGetByValSlow > finishDoubleGetByVal(ft0, t0, t1) >@@ -1594,7 +1605,7 @@ macro putByValOp(opcodeName, opcodeStruct) > get(m_property, t0) > loadConstantOrVariableInt32(size, t0, t3, .opPutByValSlow) > sxi2q t3, t3 >- loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t1], t0, tagTypeNumber) >+ loadCagedJSValue(JSObject::m_butterfly[t1], t0, tagTypeNumber) > move TagTypeNumber, tagTypeNumber > btinz t2, CopyOnWrite, .opPutByValSlow > andi IndexingShapeMask, t2 >diff --git a/Source/JavaScriptCore/offlineasm/arm64.rb b/Source/JavaScriptCore/offlineasm/arm64.rb >index c09e1570270d51d992341b2e2e6dd2cd1748b127..416fe369688008b70414d2ddc5830cfac42a8fbf 100644 >--- a/Source/JavaScriptCore/offlineasm/arm64.rb >+++ b/Source/JavaScriptCore/offlineasm/arm64.rb >@@ -123,7 +123,9 @@ class RegisterID > when 't4' > arm64GPRName('x4', kind) > when 't5' >- arm64GPRName('x5', kind) >+ arm64GPRName('x5', kind) >+ when 't6' >+ arm64GPRName('x6', kind) > when 'cfr' > arm64GPRName('x29', kind) > when 'csr0' >@@ -361,8 +363,7 @@ def arm64CortexA53Fix835769(list) > end > > class Sequence >- def getModifiedListARM64 >- result = @list >+ def getModifiedListARM64(result = @list) > result = riscLowerNot(result) > result = riscLowerSimpleBranchOps(result) > >@@ -387,7 +388,7 @@ class Sequence > "jmp", "call", "leap", "leaq" > size = $currentSettings["ADDRESS64"] ? 8 : 4 > else >- raise "Bad instruction #{node.opcode} for heap access at #{node.codeOriginString}" >+ raise "Bad instruction #{node.opcode} for heap access at #{node.codeOriginString}: #{node.dump}" > end > > if address.is_a? BaseIndex >diff --git a/Source/JavaScriptCore/offlineasm/arm64e.rb b/Source/JavaScriptCore/offlineasm/arm64e.rb >new file mode 100644 >index 0000000000000000000000000000000000000000..17bf669a556281c93effe6272b56ffc222f7c113 >--- /dev/null >+++ b/Source/JavaScriptCore/offlineasm/arm64e.rb >@@ -0,0 +1,117 @@ >+# Copyright (C) 2018 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. >+ >+class ARM64E >+ # FIXME: This is fragile and needs to match the enum value in PtrTag.h. >+ CFunctionPtrTag = 2 >+end >+ >+class Sequence >+ def getModifiedListARM64E >+ result = riscLowerMisplacedAddresses(@list) >+ getModifiedListARM64(result) >+ end >+end >+ >+class Instruction >+ def self.lowerMisplacedAddressesARM64E(node, newList) >+ wasHandled = false >+ if node.is_a? Instruction >+ postInstructions = [] >+ annotation = node.annotation >+ codeOrigin = node.codeOrigin >+ case node.opcode >+ when "jmp", "call" >+ if node.operands.size > 1 >+ if node.operands[1].is_a? RegisterID >+ tag = riscAsRegister(newList, postInstructions, node.operands[1], "p", false) >+ else >+ tag = Tmp.new(codeOrigin, :gpr) >+ newList << Instruction.new(codeOrigin, "move", [node.operands[1], tag], annotation) >+ end >+ operands = [riscAsRegister(newList, postInstructions, node.operands[0], "p", false), tag] >+ newList << Instruction.new(codeOrigin, node.opcode, operands, annotation) >+ wasHandled = true >+ end >+ when "untagArrayPtr" >+ newOperands = node.operands.map { >+ | operand | >+ if operand.address? >+ tmp = Tmp.new(codeOrigin, :gpr) >+ newList << Instruction.new(codeOrigin, "loadp", [operand, tmp], annotation) >+ tmp >+ else >+ operand >+ end >+ } >+ newList << Instruction.new(codeOrigin, node.opcode, newOperands, annotation) >+ wasHandled = true >+ end >+ newList += postInstructions if wasHandled >+ end >+ return wasHandled, newList >+ end >+ >+ def lowerARM64E >+ case opcode >+ when "call" >+ if operands.size == 1 or operands[0].label? >+ lowerARM64 >+ elsif operands[1] == ARM64E::CFunctionPtrTag >+ emitARM64Unflipped("blraaz", [operands[0]], :ptr) >+ else >+ emitARM64Unflipped("blrab", operands, :ptr) >+ end >+ when "jmp" >+ if operands[0].label? >+ lowerARM64 >+ else >+ emitARM64Unflipped("brab", operands, :ptr) >+ end >+ when "tagReturnAddress" >+ raise if operands.size < 1 or not operands[0].is_a? RegisterID >+ if operands[0].is_a? RegisterID and operands[0].name == "sp" >+ $asm.puts "pacibsp" >+ else >+ emitARM64Unflipped("pacib lr,", operands, :ptr) >+ end >+ when "untagReturnAddress" >+ raise if operands.size < 1 or not operands[0].is_a? RegisterID >+ if operands[0].is_a? RegisterID and operands[0].name == "sp" >+ $asm.puts "autibsp" >+ else >+ emitARM64Unflipped("autib lr,", operands, :ptr) >+ end >+ when "removeCodePtrTag" >+ raise unless operands[0].is_a? RegisterID >+ emitARM64Unflipped("xpaci ", operands, :ptr) >+ when "untagArrayPtr" >+ raise if operands.size != 2 or not operands.each { |operand| operand.is_a? RegisterID or operand.is_a? Tmp } >+ emitARM64("autdb ", operands, :ptr) >+ when "ret" >+ $asm.puts "retab" >+ else >+ lowerARM64 >+ end >+ end >+end >diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb >index 586ba5cd6b0f5c96d0b4041c2f5ef15662ab374b..2edca7235132583ef50d0c217babbd65369cba18 100644 >--- a/Source/JavaScriptCore/offlineasm/ast.rb >+++ b/Source/JavaScriptCore/offlineasm/ast.rb >@@ -938,7 +938,7 @@ class Instruction < Node > $asm.putGlobalAnnotation > when "emit" > $asm.puts "#{operands[0].dump}" >- when "tagReturnAddress", "untagReturnAddress", "removeCodePtrTag" >+ when "tagReturnAddress", "untagReturnAddress", "removeCodePtrTag", "untagArrayPtr" > else > raise "Unhandled opcode #{opcode} at #{codeOriginString}" > end >diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb >index c658b9b13738310be7272deb1466e2f830d4da6f..69e4b6aa8fe4b468b1a48df380e9741c7bf9d417 100644 >--- a/Source/JavaScriptCore/offlineasm/instructions.rb >+++ b/Source/JavaScriptCore/offlineasm/instructions.rb >@@ -253,7 +253,8 @@ MACRO_INSTRUCTIONS = > "memfence", > "tagReturnAddress", > "untagReturnAddress", >- "removeCodePtrTag" >+ "removeCodePtrTag", >+ "untagArrayPtr", > ] > > X86_INSTRUCTIONS = >diff --git a/Source/JavaScriptCore/offlineasm/registers.rb b/Source/JavaScriptCore/offlineasm/registers.rb >index b6ed36d002bfd2aefcd5915cf36ff57f7e8f3053..aa8a40fd4e853cd48d45ecc2666cd9a164609d39 100644 >--- a/Source/JavaScriptCore/offlineasm/registers.rb >+++ b/Source/JavaScriptCore/offlineasm/registers.rb >@@ -31,6 +31,7 @@ GPRS = > "t3", > "t4", > "t5", >+ "t6", > "cfr", > "a0", > "a1", >diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb >index 796996468e23b190ce76db6d482ca8c181691104..f2deba81b76317568d812e6b8dc750ad34245bd8 100644 >--- a/Source/JavaScriptCore/offlineasm/x86.rb >+++ b/Source/JavaScriptCore/offlineasm/x86.rb >@@ -49,7 +49,8 @@ require "config" > # rdx => t2, a2, r1 > # rcx => t3, a3 > # r8 => t4 >-# r10 => t5 >+# r9 => t5 >+# r10 => t6 > # rbx => csr0 (callee-save, PB, unused in baseline) > # r12 => csr1 (callee-save) > # r13 => csr2 (callee-save) >diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.cpp b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp >index 8f8556b897ba70ac7e9db38e0f8ab9c045ad3905..0d8bcaeed492269670196d889d1fc5dface293e3 100644 >--- a/Source/JavaScriptCore/runtime/ArrayBuffer.cpp >+++ b/Source/JavaScriptCore/runtime/ArrayBuffer.cpp >@@ -33,15 +33,16 @@ > > namespace JSC { > >-SharedArrayBufferContents::SharedArrayBufferContents(void* data, ArrayBufferDestructorFunction&& destructor) >- : m_data(data) >+SharedArrayBufferContents::SharedArrayBufferContents(void* data, unsigned size, ArrayBufferDestructorFunction&& destructor) >+ : m_data(data, size) > , m_destructor(WTFMove(destructor)) >+ , m_sizeInBytes(size) > { > } > > SharedArrayBufferContents::~SharedArrayBufferContents() > { >- m_destructor(m_data.getMayBeNull()); >+ m_destructor(m_data.getUnsafe()); > } > > ArrayBufferContents::ArrayBufferContents() >@@ -56,7 +57,7 @@ ArrayBufferContents::ArrayBufferContents(ArrayBufferContents&& other) > } > > ArrayBufferContents::ArrayBufferContents(void* data, unsigned sizeInBytes, ArrayBufferDestructorFunction&& destructor) >- : m_data(data) >+ : m_data(data, sizeInBytes) > , m_sizeInBytes(sizeInBytes) > { > RELEASE_ASSERT(m_sizeInBytes <= MAX_ARRAY_BUFFER_SIZE); >@@ -82,7 +83,7 @@ void ArrayBufferContents::clear() > > void ArrayBufferContents::destroy() > { >- m_destructor(m_data.getMayBeNull()); >+ m_destructor(m_data.getUnsafe()); > } > > void ArrayBufferContents::reset() >@@ -106,14 +107,16 @@ void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByte > size_t size = static_cast<size_t>(numElements) * static_cast<size_t>(elementByteSize); > if (!size) > size = 1; // Make sure malloc actually allocates something, but not too much. We use null to mean that the buffer is neutered. >- m_data = Gigacage::tryMalloc(Gigacage::Primitive, size); >- if (!m_data) { >+ >+ void* data = Gigacage::tryMalloc(Gigacage::Primitive, numElements * elementByteSize); >+ m_data = DataType(data, size); >+ if (!data) { > reset(); > return; > } > > if (policy == ZeroInitialize) >- memset(m_data.get(), 0, size); >+ memset(data, 0, size); > > m_sizeInBytes = numElements * elementByteSize; > RELEASE_ASSERT(m_sizeInBytes <= MAX_ARRAY_BUFFER_SIZE); >@@ -122,7 +125,7 @@ void ArrayBufferContents::tryAllocate(unsigned numElements, unsigned elementByte > > void ArrayBufferContents::makeShared() > { >- m_shared = adoptRef(new SharedArrayBufferContents(m_data.getMayBeNull(), WTFMove(m_destructor))); >+ m_shared = adoptRef(new SharedArrayBufferContents(data(), sizeInBytes(), WTFMove(m_destructor))); > m_destructor = [] (void*) { }; > } > >@@ -143,7 +146,7 @@ void ArrayBufferContents::copyTo(ArrayBufferContents& other) > other.tryAllocate(m_sizeInBytes, sizeof(char), ArrayBufferContents::DontInitialize); > if (!other.m_data) > return; >- memcpy(other.m_data.get(), m_data.get(), m_sizeInBytes); >+ memcpy(other.data(), data(), m_sizeInBytes); > other.m_sizeInBytes = m_sizeInBytes; > RELEASE_ASSERT(other.m_sizeInBytes <= MAX_ARRAY_BUFFER_SIZE); > } >diff --git a/Source/JavaScriptCore/runtime/ArrayBuffer.h b/Source/JavaScriptCore/runtime/ArrayBuffer.h >index baf2b856a21004954ba5c43bf5eb1cd7b6a4404c..7c05bbc5d24d41bdf1e23b7ec189d22694fe300e 100644 >--- a/Source/JavaScriptCore/runtime/ArrayBuffer.h >+++ b/Source/JavaScriptCore/runtime/ArrayBuffer.h >@@ -48,14 +48,16 @@ typedef Function<void(void*)> ArrayBufferDestructorFunction; > > class SharedArrayBufferContents : public ThreadSafeRefCounted<SharedArrayBufferContents> { > public: >- SharedArrayBufferContents(void* data, ArrayBufferDestructorFunction&&); >+ SharedArrayBufferContents(void* data, unsigned size, ArrayBufferDestructorFunction&&); > ~SharedArrayBufferContents(); > >- void* data() const { return m_data.getMayBeNull(); } >+ void* data() const { return m_data.getMayBeNull(m_sizeInBytes); } > > private: >- CagedPtr<Gigacage::Primitive, void> m_data; >+ using DataType = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; >+ DataType m_data; > ArrayBufferDestructorFunction m_destructor; >+ unsigned m_sizeInBytes; > }; > > class ArrayBufferContents { >@@ -73,7 +75,7 @@ public: > > explicit operator bool() { return !!m_data; } > >- void* data() const { return m_data.getMayBeNull(); } >+ void* data() const { return m_data.getMayBeNull(sizeInBytes()); } > unsigned sizeInBytes() const { return m_sizeInBytes; } > > bool isShared() const { return m_shared; } >@@ -98,7 +100,8 @@ private: > > ArrayBufferDestructorFunction m_destructor; > RefPtr<SharedArrayBufferContents> m_shared; >- CagedPtr<Gigacage::Primitive, void> m_data; >+ using DataType = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; >+ DataType m_data; > unsigned m_sizeInBytes; > }; > >@@ -174,17 +177,17 @@ public: > > void* ArrayBuffer::data() > { >- return m_contents.m_data.getMayBeNull(); >+ return m_contents.data(); > } > > const void* ArrayBuffer::data() const > { >- return m_contents.m_data.getMayBeNull(); >+ return m_contents.data(); > } > > unsigned ArrayBuffer::byteLength() const > { >- return m_contents.m_sizeInBytes; >+ return m_contents.sizeInBytes(); > } > > bool ArrayBuffer::isShared() const >diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp >index 9fed7c786b6be97a31e5943526cbbdbeb6050da7..b795fe4f55a3ecd23146e77d5fdfb8c7262fdc1c 100644 >--- a/Source/JavaScriptCore/runtime/ArrayBufferView.cpp >+++ b/Source/JavaScriptCore/runtime/ArrayBufferView.cpp >@@ -25,17 +25,22 @@ > > #include "config.h" > #include "ArrayBufferView.h" >+#include <wtf/CheckedArithmetic.h> > > namespace JSC { > > ArrayBufferView::ArrayBufferView( >- RefPtr<ArrayBuffer>&& buffer, >- unsigned byteOffset) >+ RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned byteLength) > : m_byteOffset(byteOffset) > , m_isNeuterable(true) >+ , m_byteLength(byteLength) > , m_buffer(WTFMove(buffer)) > { >- m_baseAddress = m_buffer ? (static_cast<char*>(m_buffer->data()) + m_byteOffset) : 0; >+ Checked<unsigned, CrashOnOverflow> length(byteOffset); >+ length += byteLength; >+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(length <= m_buffer->byteLength()); >+ if (m_buffer) >+ m_baseAddress = BaseAddress(static_cast<char*>(m_buffer->data()) + m_byteOffset, byteLength); > } > > ArrayBufferView::~ArrayBufferView() >diff --git a/Source/JavaScriptCore/runtime/ArrayBufferView.h b/Source/JavaScriptCore/runtime/ArrayBufferView.h >index 754784e864fcc3377b164a8d1af87a7542e7e619..9340245f1e205f474645533dcb62da3c23953ed8 100644 >--- a/Source/JavaScriptCore/runtime/ArrayBufferView.h >+++ b/Source/JavaScriptCore/runtime/ArrayBufferView.h >@@ -71,8 +71,8 @@ public: > void* baseAddress() const > { > if (isNeutered()) >- return 0; >- return m_baseAddress.getMayBeNull(); >+ return nullptr; >+ return m_baseAddress.getMayBeNull(byteLength()); > } > > void* data() const { return baseAddress(); } >@@ -84,7 +84,7 @@ public: > return m_byteOffset; > } > >- virtual unsigned byteLength() const = 0; >+ unsigned byteLength() const { return m_byteLength; } > > JS_EXPORT_PRIVATE void setNeuterable(bool flag); > bool isNeuterable() const { return m_isNeuterable; } >@@ -113,13 +113,12 @@ public: > virtual JSArrayBufferView* wrap(ExecState*, JSGlobalObject*) = 0; > > protected: >- JS_EXPORT_PRIVATE ArrayBufferView(RefPtr<ArrayBuffer>&&, unsigned byteOffset); >+ JS_EXPORT_PRIVATE ArrayBufferView(RefPtr<ArrayBuffer>&&, unsigned byteOffset, unsigned byteLength); > > inline bool setImpl(ArrayBufferView*, unsigned byteOffset); > >- // Caller passes in bufferByteLength to avoid a virtual function call. >- inline bool setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength); >- inline bool getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength); >+ inline bool setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset); >+ inline bool getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset); > > inline bool zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength); > >@@ -150,9 +149,11 @@ protected: > > unsigned m_byteOffset : 31; > bool m_isNeuterable : 1; >+ unsigned m_byteLength; > >+ using BaseAddress = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; > // This is the address of the ArrayBuffer's storage, plus the byte offset. >- CagedPtr<Gigacage::Primitive, void> m_baseAddress; >+ BaseAddress m_baseAddress; > > private: > friend class ArrayBuffer; >@@ -173,35 +174,31 @@ bool ArrayBufferView::setImpl(ArrayBufferView* array, unsigned byteOffset) > return true; > } > >-bool ArrayBufferView::setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength) >+bool ArrayBufferView::setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset) > { >- // Do not replace with RELEASE_ASSERT; we want to avoid the virtual byteLength() function call in release. >- ASSERT_WITH_SECURITY_IMPLICATION(bufferByteLength == byteLength()); >- if (byteOffset > bufferByteLength >- || byteOffset + dataByteLength > bufferByteLength >+ if (byteOffset > byteLength() >+ || byteOffset + dataByteLength > byteLength() > || byteOffset + dataByteLength < byteOffset) { > // Out of range offset or overflow > return false; > } > > uint8_t* base = static_cast<uint8_t*>(baseAddress()); >- memmove(base + byteOffset, data, dataByteLength); >+ memmove(base + byteOffset, data, byteLength()); > return true; > } > >-bool ArrayBufferView::getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength) >+bool ArrayBufferView::getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset) > { >- // Do not replace with RELEASE_ASSERT; we want to avoid the virtual byteLength() function call in release. >- ASSERT_WITH_SECURITY_IMPLICATION(bufferByteLength == byteLength()); >- if (byteOffset > bufferByteLength >- || byteOffset + dataByteLength > bufferByteLength >+ if (byteOffset > byteLength() >+ || byteOffset + dataByteLength > byteLength() > || byteOffset + dataByteLength < byteOffset) { > // Out of range offset or overflow > return false; > } > > const uint8_t* base = static_cast<const uint8_t*>(baseAddress()); >- memmove(destination, base + byteOffset, dataByteLength); >+ memmove(destination, base + byteOffset, byteLength()); > return true; > } > >diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp >index 93f2224efb0c0c1e802cbfcbaa3744f3b8eaf600..7278ddfb2543740f65ec1b696bd5789ebf287f27 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.cpp >+++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp >@@ -1028,13 +1028,13 @@ public: > void encode(Encoder& encoder, const ScopedArgumentsTable& scopedArgumentsTable) > { > m_length = scopedArgumentsTable.m_length; >- m_arguments.encode(encoder, scopedArgumentsTable.m_arguments.get(), m_length); >+ m_arguments.encode(encoder, scopedArgumentsTable.m_arguments.get(m_length), m_length); > } > > ScopedArgumentsTable* decode(Decoder& decoder) const > { > ScopedArgumentsTable* scopedArgumentsTable = ScopedArgumentsTable::create(decoder.vm(), m_length); >- m_arguments.decode(decoder, scopedArgumentsTable->m_arguments.get(), m_length); >+ m_arguments.decode(decoder, scopedArgumentsTable->m_arguments.get(m_length), m_length); > return scopedArgumentsTable; > } > >diff --git a/Source/JavaScriptCore/runtime/CagedBarrierPtr.h b/Source/JavaScriptCore/runtime/CagedBarrierPtr.h >index 918ddf2f3f7d3d3b862b281dc6dc690751639913..425a87c668e3ced8df727fc9c6c914f7ffb3591f 100644 >--- a/Source/JavaScriptCore/runtime/CagedBarrierPtr.h >+++ b/Source/JavaScriptCore/runtime/CagedBarrierPtr.h >@@ -35,87 +35,41 @@ class VM; > > // This is a convenient combo of AuxiliaryBarrier and CagedPtr. > >-template<Gigacage::Kind passedKind, typename T> >+template<Gigacage::Kind passedKind, typename T, bool shouldTag = false> > class CagedBarrierPtr { > public: > static constexpr Gigacage::Kind kind = passedKind; >- typedef T Type; >+ using Type = T; >+ using CagedType = CagedPtr<kind, Type, shouldTag>; > >- CagedBarrierPtr() { } >+ CagedBarrierPtr() = default; > > template<typename U> >- CagedBarrierPtr(VM& vm, JSCell* cell, U&& value) >+ CagedBarrierPtr(VM& vm, JSCell* cell, U&& value, unsigned size) > { >- m_barrier.set(vm, cell, std::forward<U>(value)); >+ m_barrier.set(vm, cell, CagedType(std::forward<U>(value), size)); > } > > void clear() { m_barrier.clear(); } > > template<typename U> >- void set(VM& vm, JSCell* cell, U&& value) >+ void set(VM& vm, JSCell* cell, U&& value, unsigned size) > { >- m_barrier.set(vm, cell, std::forward<U>(value)); >+ m_barrier.set(vm, cell, CagedType(std::forward<U>(value), size)); > } > >- T* get() const { return m_barrier.get().get(); } >- T* getMayBeNull() const { return m_barrier.get().getMayBeNull(); } >- >- bool operator==(const CagedBarrierPtr& other) const >- { >- return getMayBeNull() == other.getMayBeNull(); >- } >- >- bool operator!=(const CagedBarrierPtr& other) const >- { >- return !(*this == other); >- } >- >- explicit operator bool() const >- { >- return *this != CagedBarrierPtr(); >- } >- >- template<typename U> >- void setWithoutBarrier(U&& value) { m_barrier.setWithoutBarrier(std::forward<U>(value)); } >- >- T& operator*() const { return *get(); } >- T* operator->() const { return get(); } >- >- template<typename IndexType> >- T& operator[](IndexType index) const { return get()[index]; } >- >-private: >- AuxiliaryBarrier<CagedPtr<kind, T>> m_barrier; >-}; >+ T* get(unsigned size) const { return m_barrier.get().get(size); } >+ T* getMayBeNull(unsigned size) const { return m_barrier.get().getMayBeNull(size); } >+ T* getUnsafe() const { return m_barrier.get().getUnsafe(); } >+ >+ // We need the template here so that the type of U is deduced at usage time rather than class time. U should always be T. >+ template<typename U = T> >+ typename std::enable_if<!std::is_same<void, U>::value, T>::type& >+ /* T& */ at(unsigned index, unsigned size) const { return get(size)[index]; } > >-template<Gigacage::Kind passedKind> >-class CagedBarrierPtr<passedKind, void> { >-public: >- static constexpr Gigacage::Kind kind = passedKind; >- typedef void Type; >- >- CagedBarrierPtr() { } >- >- template<typename U> >- CagedBarrierPtr(VM& vm, JSCell* cell, U&& value) >- { >- m_barrier.set(vm, cell, std::forward<U>(value)); >- } >- >- void clear() { m_barrier.clear(); } >- >- template<typename U> >- void set(VM& vm, JSCell* cell, U&& value) >- { >- m_barrier.set(vm, cell, std::forward<U>(value)); >- } >- >- void* get() const { return m_barrier.get().get(); } >- void* getMayBeNull() const { return m_barrier.get().getMayBeNull(); } >- > bool operator==(const CagedBarrierPtr& other) const > { >- return getMayBeNull() == other.getMayBeNull(); >+ return m_barrier.get() == other.m_barrier.get(); > } > > bool operator!=(const CagedBarrierPtr& other) const >@@ -125,14 +79,14 @@ public: > > explicit operator bool() const > { >- return *this != CagedBarrierPtr(); >+ return !!m_barrier.get(); > } > > template<typename U> >- void setWithoutBarrier(U&& value) { m_barrier.setWithoutBarrier(std::forward<U>(value)); } >+ void setWithoutBarrier(U&& value, unsigned size) { m_barrier.setWithoutBarrier(CagedType(std::forward<U>(value), size)); } > > private: >- AuxiliaryBarrier<CagedPtr<kind, void>> m_barrier; >+ AuxiliaryBarrier<CagedType> m_barrier; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/DataView.cpp b/Source/JavaScriptCore/runtime/DataView.cpp >index 3b5871ba3be2a1ebcf41b3d7b74eaf9f636ede8b..5e073f54f7910873929baf9fd097a48310bf58a5 100644 >--- a/Source/JavaScriptCore/runtime/DataView.cpp >+++ b/Source/JavaScriptCore/runtime/DataView.cpp >@@ -33,8 +33,7 @@ > namespace JSC { > > DataView::DataView(RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned byteLength) >- : ArrayBufferView(WTFMove(buffer), byteOffset) >- , m_byteLength(byteLength) >+ : ArrayBufferView(WTFMove(buffer), byteOffset, byteLength) > { > } > >diff --git a/Source/JavaScriptCore/runtime/DataView.h b/Source/JavaScriptCore/runtime/DataView.h >index 7a397636659b188d9d7b9cec84c70db63d2713ea..22a23fdbb8c6264cb08ccc83da0396fc1e5c2fd6 100644 >--- a/Source/JavaScriptCore/runtime/DataView.h >+++ b/Source/JavaScriptCore/runtime/DataView.h >@@ -38,11 +38,6 @@ public: > JS_EXPORT_PRIVATE static Ref<DataView> create(RefPtr<ArrayBuffer>&&, unsigned byteOffset, unsigned length); > static Ref<DataView> create(RefPtr<ArrayBuffer>&&); > >- unsigned byteLength() const override >- { >- return m_byteLength; >- } >- > TypedArrayType getType() const override > { > return TypeDataView; >@@ -62,7 +57,7 @@ public: > } else > RELEASE_ASSERT(offset + sizeof(T) <= byteLength()); > return flipBytesIfLittleEndian( >- *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get()) + offset), >+ *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get(byteLength())) + offset), > littleEndian); > } > >@@ -86,12 +81,9 @@ public: > *status = true; > } else > RELEASE_ASSERT(offset + sizeof(T) <= byteLength()); >- *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get()) + offset) = >+ *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get(byteLength())) + offset) = > flipBytesIfLittleEndian(value, littleEndian); > } >- >-private: >- unsigned m_byteLength; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/DirectArguments.cpp b/Source/JavaScriptCore/runtime/DirectArguments.cpp >index e001be294b66829d137afcb7b1b20dfef323cc66..3ee876be72837e778d701da2112ae45b3ab37022 100644 >--- a/Source/JavaScriptCore/runtime/DirectArguments.cpp >+++ b/Source/JavaScriptCore/runtime/DirectArguments.cpp >@@ -101,7 +101,7 @@ void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor) > visitor.append(thisObject->m_callee); > > if (thisObject->m_mappedArguments) >- visitor.markAuxiliary(thisObject->m_mappedArguments.get()); >+ visitor.markAuxiliary(thisObject->m_mappedArguments.get(thisObject->internalLength())); > GenericArguments<DirectArguments>::visitChildren(thisCell, visitor); > } > >@@ -120,8 +120,8 @@ void DirectArguments::overrideThings(VM& vm) > > void* backingStore = vm.gigacageAuxiliarySpace(m_mappedArguments.kind).allocateNonVirtual(vm, mappedArgumentsSize(), nullptr, AllocationFailureMode::Assert); > bool* overrides = static_cast<bool*>(backingStore); >- m_mappedArguments.set(vm, this, overrides); >- for (unsigned i = m_length; i--;) >+ m_mappedArguments.set(vm, this, overrides, internalLength()); >+ for (unsigned i = internalLength(); i--;) > overrides[i] = false; > } > >@@ -134,7 +134,7 @@ void DirectArguments::overrideThingsIfNecessary(VM& vm) > void DirectArguments::unmapArgument(VM& vm, unsigned index) > { > overrideThingsIfNecessary(vm); >- m_mappedArguments[index] = true; >+ m_mappedArguments.at(index, internalLength()) = true; > } > > void DirectArguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length) >diff --git a/Source/JavaScriptCore/runtime/DirectArguments.h b/Source/JavaScriptCore/runtime/DirectArguments.h >index 32cdd0b7046cc8f6186b58c439d65745efe9dced..9ca01f33c733859206f97039ff5e57ade63d62ae 100644 >--- a/Source/JavaScriptCore/runtime/DirectArguments.h >+++ b/Source/JavaScriptCore/runtime/DirectArguments.h >@@ -86,7 +86,7 @@ public: > > bool isMappedArgument(uint32_t i) const > { >- return i < m_length && (!m_mappedArguments || !m_mappedArguments[i]); >+ return i < m_length && (!m_mappedArguments || !m_mappedArguments.at(i, m_length)); > } > > bool isMappedArgumentInDFG(uint32_t i) const >@@ -182,7 +182,8 @@ private: > WriteBarrier<JSFunction> m_callee; > uint32_t m_length; // Always the actual length of captured arguments and never what was stored into the length property. > uint32_t m_minCapacity; // The max of this and length determines the capacity of this object. It may be the actual capacity, or maybe something smaller. We arrange it this way to be kind to the JITs. >- CagedBarrierPtr<Gigacage::Primitive, bool> m_mappedArguments; // If non-null, it means that length, callee, and caller are fully materialized properties. >+ using MappedArguments = CagedBarrierPtr<Gigacage::Primitive, bool>; >+ MappedArguments m_mappedArguments; // If non-null, it means that length, callee, and caller are fully materialized properties. > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/GenericArguments.h b/Source/JavaScriptCore/runtime/GenericArguments.h >index 6a6380e7f1b9d51e9d3a376f920e3e6d676b7166..b1c78684274145964f71a2b7490fa3c1098641d6 100644 >--- a/Source/JavaScriptCore/runtime/GenericArguments.h >+++ b/Source/JavaScriptCore/runtime/GenericArguments.h >@@ -60,8 +60,9 @@ protected: > bool isModifiedArgumentDescriptor(unsigned index, unsigned length); > > void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length); >- >- CagedBarrierPtr<Gigacage::Primitive, bool> m_modifiedArgumentsDescriptor; >+ >+ using ModifiedArgumentsPtr = CagedBarrierPtr<Gigacage::Primitive, bool>; >+ ModifiedArgumentsPtr m_modifiedArgumentsDescriptor; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h b/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h >index 2be41fe99726cebd9a88f8a429f5de01a3923cd2..d56ebf5b7832595c8bf9a4ed4d554c1db4ca2ba6 100644 >--- a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h >+++ b/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h >@@ -38,7 +38,7 @@ void GenericArguments<Type>::visitChildren(JSCell* thisCell, SlotVisitor& visito > Base::visitChildren(thisCell, visitor); > > if (thisObject->m_modifiedArgumentsDescriptor) >- visitor.markAuxiliary(thisObject->m_modifiedArgumentsDescriptor.get()); >+ visitor.markAuxiliary(thisObject->m_modifiedArgumentsDescriptor.getUnsafe()); > } > > template<typename Type> >@@ -265,7 +265,7 @@ void GenericArguments<Type>::initModifiedArgumentsDescriptor(VM& vm, unsigned ar > if (argsLength) { > void* backingStore = vm.gigacageAuxiliarySpace(m_modifiedArgumentsDescriptor.kind).allocateNonVirtual(vm, WTF::roundUpToMultipleOf<8>(argsLength), nullptr, AllocationFailureMode::Assert); > bool* modifiedArguments = static_cast<bool*>(backingStore); >- m_modifiedArgumentsDescriptor.set(vm, this, modifiedArguments); >+ m_modifiedArgumentsDescriptor.set(vm, this, modifiedArguments, argsLength); > for (unsigned i = argsLength; i--;) > modifiedArguments[i] = false; > } >@@ -283,7 +283,7 @@ void GenericArguments<Type>::setModifiedArgumentDescriptor(VM& vm, unsigned inde > { > initModifiedArgumentsDescriptorIfNecessary(vm, length); > if (index < length) >- m_modifiedArgumentsDescriptor[index] = true; >+ m_modifiedArgumentsDescriptor.at(index, length) = true; > } > > template<typename Type> >@@ -292,7 +292,7 @@ bool GenericArguments<Type>::isModifiedArgumentDescriptor(unsigned index, unsign > if (!m_modifiedArgumentsDescriptor) > return false; > if (index < length) >- return m_modifiedArgumentsDescriptor[index]; >+ return m_modifiedArgumentsDescriptor.at(index, length); > return false; > } > >diff --git a/Source/JavaScriptCore/runtime/GenericTypedArrayView.h b/Source/JavaScriptCore/runtime/GenericTypedArrayView.h >index ef2e80f4ea03bde6491cf7333a27b7c577f0eb5e..be2d4201b60f1f2bd199510b1edc229772e997f6 100644 >--- a/Source/JavaScriptCore/runtime/GenericTypedArrayView.h >+++ b/Source/JavaScriptCore/runtime/GenericTypedArrayView.h >@@ -58,8 +58,7 @@ public: > return setRangeImpl( > reinterpret_cast<const char*>(data), > count * sizeof(typename Adaptor::Type), >- offset * sizeof(typename Adaptor::Type), >- internalByteLength()); >+ offset * sizeof(typename Adaptor::Type)); > } > > bool zeroRange(unsigned offset, size_t count) >@@ -73,12 +72,7 @@ public: > { > if (isNeutered()) > return 0; >- return m_length; >- } >- >- unsigned byteLength() const override >- { >- return internalByteLength(); >+ return byteLength() / sizeof(typename Adaptor::Type); > } > > typename Adaptor::Type item(unsigned index) const >@@ -105,7 +99,7 @@ public: > reinterpret_cast<char*>(data), > count * sizeof(typename Adaptor::Type), > offset * sizeof(typename Adaptor::Type), >- internalByteLength()); >+ byteLength()); > } > > bool checkInboundData(unsigned offset, size_t count) const >@@ -126,14 +120,6 @@ public: > } > > JSArrayBufferView* wrap(ExecState*, JSGlobalObject*) override; >- >-private: >- unsigned internalByteLength() const >- { >- return length() * sizeof(typename Adaptor::Type); >- } >- >- unsigned m_length; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h b/Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h >index e660cfcdd4894562d174f646575d5622b1223793..aa5848ae02b4fa89947d0e9745df808d5f9e64c4 100644 >--- a/Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h >+++ b/Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h >@@ -31,10 +31,8 @@ > namespace JSC { > > template<typename Adaptor> >-GenericTypedArrayView<Adaptor>::GenericTypedArrayView( >- RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned length) >- : ArrayBufferView(WTFMove(buffer), byteOffset) >- , m_length(length) >+GenericTypedArrayView<Adaptor>::GenericTypedArrayView(RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned length) >+ : ArrayBufferView(WTFMove(buffer), byteOffset, length) > { > } > >diff --git a/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp b/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >index c2de003ff6b710dde7ddbbe81994a5828e4572cc..479ee98516310e8dc32e5d58aab60b269eabcd0d 100644 >--- a/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >+++ b/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2013-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -50,11 +50,12 @@ String JSArrayBufferView::toStringName(const JSObject*, ExecState*) > JSArrayBufferView::ConstructionContext::ConstructionContext( > Structure* structure, uint32_t length, void* vector) > : m_structure(structure) >- , m_vector(vector) >+ , m_vector(vector, length) > , m_length(length) > , m_mode(FastTypedArray) > , m_butterfly(nullptr) > { >+ ASSERT(vector == WTF::removeArrayPtrTag(vector)); > RELEASE_ASSERT(length <= fastSizeLimit); > } > >@@ -74,11 +75,11 @@ JSArrayBufferView::ConstructionContext::ConstructionContext( > return; > > m_structure = structure; >- m_vector = temp; >+ m_vector = VectorType(temp, length); > m_mode = FastTypedArray; > > if (mode == ZeroFill) { >- uint64_t* asWords = static_cast<uint64_t*>(m_vector.getMayBeNull()); >+ uint64_t* asWords = static_cast<uint64_t*>(vector()); > for (unsigned i = size / sizeof(uint64_t); i--;) > asWords[i] = 0; > } >@@ -91,11 +92,11 @@ JSArrayBufferView::ConstructionContext::ConstructionContext( > return; > > size_t size = static_cast<size_t>(length) * static_cast<size_t>(elementSize); >- m_vector = Gigacage::tryMalloc(Gigacage::Primitive, size); >+ m_vector = VectorType(Gigacage::tryMalloc(Gigacage::Primitive, size), length); > if (!m_vector) > return; > if (mode == ZeroFill) >- memset(m_vector.get(), 0, size); >+ memset(vector(), 0, size); > > vm.heap.reportExtraMemoryAllocated(static_cast<size_t>(length) * elementSize); > >@@ -110,7 +111,8 @@ JSArrayBufferView::ConstructionContext::ConstructionContext( > , m_length(length) > , m_mode(WastefulTypedArray) > { >- m_vector = static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset; >+ ASSERT(arrayBuffer->data() == WTF::removeArrayPtrTag(arrayBuffer->data())); >+ m_vector = VectorType(static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset, length); > IndexingHeader indexingHeader; > indexingHeader.setArrayBuffer(arrayBuffer.get()); > m_butterfly = Butterfly::create(vm, 0, 0, 0, true, indexingHeader, 0); >@@ -124,7 +126,8 @@ JSArrayBufferView::ConstructionContext::ConstructionContext( > , m_mode(DataViewMode) > , m_butterfly(0) > { >- m_vector = static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset; >+ ASSERT(arrayBuffer->data() == WTF::removeArrayPtrTag(arrayBuffer->data())); >+ m_vector = VectorType(static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset, length); > } > > JSArrayBufferView::JSArrayBufferView(VM& vm, ConstructionContext& context) >@@ -133,7 +136,8 @@ JSArrayBufferView::JSArrayBufferView(VM& vm, ConstructionContext& context) > , m_mode(context.mode()) > { > setButterfly(vm, context.butterfly()); >- m_vector.setWithoutBarrier(context.vector()); >+ ASSERT(context.vector() == WTF::removeArrayPtrTag(context.vector())); >+ m_vector.setWithoutBarrier(context.vector(), m_length); > } > > void JSArrayBufferView::finishCreation(VM& vm) >@@ -194,7 +198,7 @@ void JSArrayBufferView::finalize(JSCell* cell) > JSArrayBufferView* thisObject = static_cast<JSArrayBufferView*>(cell); > ASSERT(thisObject->m_mode == OversizeTypedArray || thisObject->m_mode == WastefulTypedArray); > if (thisObject->m_mode == OversizeTypedArray) >- Gigacage::free(Gigacage::Primitive, thisObject->m_vector.get()); >+ Gigacage::free(Gigacage::Primitive, thisObject->vector()); > } > > JSArrayBuffer* JSArrayBufferView::unsharedJSBuffer(ExecState* exec) >@@ -283,7 +287,7 @@ ArrayBuffer* JSArrayBufferView::slowDownAndWasteMemory() > { > auto locker = holdLock(cellLock()); > butterfly()->indexingHeader()->setArrayBuffer(buffer.get()); >- m_vector.setWithoutBarrier(buffer->data()); >+ m_vector.setWithoutBarrier(buffer->data(), m_length); > WTF::storeStoreFence(); > m_mode = WastefulTypedArray; > } >diff --git a/Source/JavaScriptCore/runtime/JSArrayBufferView.h b/Source/JavaScriptCore/runtime/JSArrayBufferView.h >index ef7ebe1ad2a5d17613299295e478b4774bd66796..49985cb39a5459154390ae47e4e88e295ca9b2e9 100644 >--- a/Source/JavaScriptCore/runtime/JSArrayBufferView.h >+++ b/Source/JavaScriptCore/runtime/JSArrayBufferView.h >@@ -27,6 +27,7 @@ > > #include "AuxiliaryBarrier.h" > #include "JSObject.h" >+#include <wtf/TaggedArrayStoragePtr.h> > > namespace JSC { > >@@ -96,6 +97,7 @@ class JSArrayBufferView : public JSNonFinalObject { > public: > typedef JSNonFinalObject Base; > static const unsigned fastSizeLimit = 1000; >+ using VectorPtr = CagedBarrierPtr<Gigacage::Primitive, void, tagCagedPtr>; > > static size_t sizeOf(uint32_t length, uint32_t elementSize) > { >@@ -133,14 +135,15 @@ protected: > bool operator!() const { return !m_structure; } > > Structure* structure() const { return m_structure; } >- void* vector() const { return m_vector.getMayBeNull(); } >+ void* vector() const { return m_vector.get(m_length); } > uint32_t length() const { return m_length; } > TypedArrayMode mode() const { return m_mode; } > Butterfly* butterfly() const { return m_butterfly; } > > private: > Structure* m_structure; >- CagedPtr<Gigacage::Primitive, void> m_vector; >+ using VectorType = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; >+ VectorType m_vector; > uint32_t m_length; > TypedArrayMode m_mode; > Butterfly* m_butterfly; >@@ -164,10 +167,11 @@ public: > JSArrayBuffer* possiblySharedJSBuffer(ExecState* exec); > RefPtr<ArrayBufferView> unsharedImpl(); > JS_EXPORT_PRIVATE RefPtr<ArrayBufferView> possiblySharedImpl(); >- bool isNeutered() { return hasArrayBuffer() && !vector(); } >+ bool isNeutered() { return hasArrayBuffer() && !hasVector(); } > void neuter(); >- >- void* vector() const { return m_vector.getMayBeNull(); } >+ >+ bool hasVector() const { return !!m_vector; } >+ void* vector() const { ASSERT(hasVector()); return m_vector.get(length()); } > > unsigned byteOffset(); > unsigned length() const { return m_length; } >@@ -191,7 +195,7 @@ protected: > > static String toStringName(const JSObject*, ExecState*); > >- CagedBarrierPtr<Gigacage::Primitive, void> m_vector; >+ VectorPtr m_vector; > uint32_t m_length; > TypedArrayMode m_mode; > }; >diff --git a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h >index 1c5d5732a8be57f3390fa2f039e2b3e70dc873df..4965c9c88c974079c8a7354f56cc3eb8137586b7 100644 >--- a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h >+++ b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h >@@ -77,8 +77,7 @@ JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createWithFa > } > > template<typename Adaptor> >-JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createUninitialized( >- ExecState* exec, Structure* structure, unsigned length) >+JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createUninitialized(ExecState* exec, Structure* structure, unsigned length) > { > VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >@@ -496,7 +495,7 @@ size_t JSGenericTypedArrayView<Adaptor>::estimatedSize(JSCell* cell, VM& vm) > > if (thisObject->m_mode == OversizeTypedArray) > return Base::estimatedSize(thisObject, vm) + thisObject->byteSize(); >- if (thisObject->m_mode == FastTypedArray && thisObject->m_vector) >+ if (thisObject->m_mode == FastTypedArray && thisObject->hasVector()) > return Base::estimatedSize(thisObject, vm) + thisObject->byteSize(); > > return Base::estimatedSize(thisObject, vm); >@@ -515,7 +514,7 @@ void JSGenericTypedArrayView<Adaptor>::visitChildren(JSCell* cell, SlotVisitor& > { > auto locker = holdLock(thisObject->cellLock()); > mode = thisObject->m_mode; >- vector = thisObject->m_vector.getMayBeNull(); >+ vector = thisObject->vector(); > byteSize = thisObject->byteSize(); > } > >diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h >index aa37c00791b95423b168647bea1f741e9b9d6369..72e4413da0b53e5d1056599f7fe4092beccf09fc 100644 >--- a/Source/JavaScriptCore/runtime/Options.h >+++ b/Source/JavaScriptCore/runtime/Options.h >@@ -491,8 +491,7 @@ constexpr bool enableWebAssemblyStreamingApi = false; > v(unsigned, webAssemblyLoopDecrement, 15, Normal, "The amount the tier up countdown is decremented on each loop backedge.") \ > v(unsigned, webAssemblyFunctionEntryDecrement, 1, Normal, "The amount the tier up countdown is decremented on each function entry.") \ > \ >- /* FIXME: enable fast memories on iOS and pre-allocate them. https://bugs.webkit.org/show_bug.cgi?id=170774 */ \ >- v(bool, useWebAssemblyFastMemory, !isIOS(), Normal, "If true, we will try to use a 32-bit address space with a signal handler to bounds check wasm memory.") \ >+ v(bool, useWebAssemblyFastMemory, true, Normal, "If true, we will try to use a 32-bit address space with a signal handler to bounds check wasm memory.") \ > v(bool, logWebAssemblyMemory, false, Normal, nullptr) \ > v(unsigned, webAssemblyFastMemoryRedzonePages, 128, Normal, "WebAssembly fast memories use 4GiB virtual allocations, plus a redzone (counted as multiple of 64KiB WebAssembly pages) at the end to catch reg+imm accesses which exceed 32-bit, anything beyond the redzone is explicitly bounds-checked") \ > v(bool, crashIfWebAssemblyCantFastMemory, false, Normal, "If true, we will crash if we can't obtain fast memory for wasm.") \ >diff --git a/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp >index 955a307d23e1669efba4c03229ee1e52c7604d15..5b0e9af06cfb04a0ed247ab7fb4e9481af69f9b4 100644 >--- a/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp >+++ b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp >@@ -68,16 +68,16 @@ ScopedArgumentsTable* ScopedArgumentsTable::clone(VM& vm) > { > ScopedArgumentsTable* result = create(vm, m_length); > for (unsigned i = m_length; i--;) >- result->m_arguments[i] = m_arguments[i]; >+ result->at(i) = this->at(i); > return result; > } > > ScopedArgumentsTable* ScopedArgumentsTable::setLength(VM& vm, uint32_t newLength) > { > if (LIKELY(!m_locked)) { >- ArgumentsPtr newArguments = ArgumentsPtr::create(newLength); >+ ArgumentsPtr newArguments = ArgumentsPtr::create(newLength, newLength); > for (unsigned i = std::min(m_length, newLength); i--;) >- newArguments[i] = m_arguments[i]; >+ newArguments.at(i, newLength) = this->at(i); > m_length = newLength; > m_arguments = WTFMove(newArguments); > return this; >@@ -85,10 +85,12 @@ ScopedArgumentsTable* ScopedArgumentsTable::setLength(VM& vm, uint32_t newLength > > ScopedArgumentsTable* result = create(vm, newLength); > for (unsigned i = std::min(m_length, newLength); i--;) >- result->m_arguments[i] = m_arguments[i]; >+ result->at(i) = this->at(i); > return result; > } > >+static_assert(std::is_trivially_destructible<ScopeOffset>::value, ""); >+ > ScopedArgumentsTable* ScopedArgumentsTable::set(VM& vm, uint32_t i, ScopeOffset value) > { > ScopedArgumentsTable* result; >diff --git a/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h >index e81234297b0bb8a025802f37a89847088a5ae135..558a9eba39de500b86035446076328ca84499b35 100644 >--- a/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h >+++ b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h >@@ -61,10 +61,7 @@ public: > uint32_t length() const { return m_length; } > ScopedArgumentsTable* setLength(VM&, uint32_t newLength); > >- ScopeOffset get(uint32_t i) const >- { >- return const_cast<ScopedArgumentsTable*>(this)->at(i); >- } >+ ScopeOffset get(uint32_t i) const { return at(i); } > > void lock() > { >@@ -80,13 +77,13 @@ public: > static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_length); } > static ptrdiff_t offsetOfArguments() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_arguments); } > >- typedef CagedUniquePtr<Gigacage::Primitive, ScopeOffset[]> ArgumentsPtr; >+ typedef CagedUniquePtr<Gigacage::Primitive, ScopeOffset> ArgumentsPtr; > > private: >- ScopeOffset& at(uint32_t i) >+ ScopeOffset& at(uint32_t i) const > { > ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); >- return m_arguments[i]; >+ return m_arguments.get(length())[i]; > } > > uint32_t m_length; >diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h >index 8e80d4bb2e85161be315e868d5f81363f95bb6b2..3fd1c46e1adf7ceade4e16b11ba7c10000274fb0 100644 >--- a/Source/JavaScriptCore/runtime/SymbolTable.h >+++ b/Source/JavaScriptCore/runtime/SymbolTable.h >@@ -631,8 +631,9 @@ public: > void setArgumentsLength(VM& vm, uint32_t length) > { > if (UNLIKELY(!m_arguments)) >- m_arguments.set(vm, this, ScopedArgumentsTable::create(vm)); >- m_arguments.set(vm, this, m_arguments->setLength(vm, length)); >+ m_arguments.set(vm, this, ScopedArgumentsTable::create(vm, length)); >+ else >+ m_arguments.set(vm, this, m_arguments->setLength(vm, length)); > } > > ScopeOffset argumentOffset(uint32_t i) const >diff --git a/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp b/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp >index 07e219ce2a53a117e792f8bceed4dc0c52fd1d03..9daf7852faf949539343a9dea9316dbdac74e36f 100644 >--- a/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp >+++ b/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp >@@ -833,6 +833,9 @@ void AirIRGenerator::restoreWebAssemblyGlobalState(RestoreCachedStackLimit resto > patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { > jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister); > jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), pinnedRegs->baseMemoryPointer); >+#if CPU(ARM64E) >+ jit.untagArrayPtr(pinnedRegs->baseMemoryPointer, pinnedRegs->sizeRegister); >+#endif > }); > > emitPatchpoint(block, patchpoint, Tmp(), instance); >@@ -1856,6 +1859,9 @@ auto AirIRGenerator::addCallIndirect(const Signature& signature, Vector<Expressi > ASSERT(pinnedRegs.sizeRegister != newContextInstance); > jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. > jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. >+#if CPU(ARM64E) >+ jit.untagArrayPtr(baseMemory, pinnedRegs.sizeRegister); >+#endif > }); > > emitPatchpoint(doContextSwitch, patchpoint, Tmp(), newContextInstance, instanceValue()); >diff --git a/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp b/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp >index 7a7bdc33dce376db123847c608a56984a8dc2049..aba9dac82fc0ca6efd0944c3fe87309b94d0cdb8 100644 >--- a/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp >+++ b/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp >@@ -482,6 +482,9 @@ void B3IRGenerator::restoreWebAssemblyGlobalState(RestoreCachedStackLimit restor > GPRReg baseMemory = pinnedRegs->baseMemoryPointer; > jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister); > jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); >+#if CPU(ARM64E) >+ jit.untagArrayPtr(baseMemory, pinnedRegs->sizeRegister); >+#endif > }); > } > } >@@ -1285,6 +1288,9 @@ auto B3IRGenerator::addCallIndirect(const Signature& signature, Vector<Expressio > ASSERT(pinnedRegs.sizeRegister != newContextInstance); > jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. > jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. >+#if CPU(ARM64E) >+ jit.untagArrayPtr(baseMemory, pinnedRegs.sizeRegister); >+#endif > }); > doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation); > >diff --git a/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp b/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp >index df0c08d41ce33e16c01235c4abdd1a5312a4347d..fe09d3300e4d34523e445c0a91e98044b806fe07 100644 >--- a/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp >+++ b/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp >@@ -318,7 +318,7 @@ void BBQPlan::complete(const AbstractLocker& locker) > } > > m_wasmInternalFunctions[functionIndex]->entrypoint.compilation = std::make_unique<B3::Compilation>( >- FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly function[%i] %s", functionIndex, signature.toString().ascii().data()), >+ FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly BBQ function[%i] %s", functionIndex, signature.toString().ascii().data()), > WTFMove(context.wasmEntrypointByproducts)); > } > >diff --git a/Source/JavaScriptCore/wasm/WasmBinding.cpp b/Source/JavaScriptCore/wasm/WasmBinding.cpp >index ea13a25c0e102f7181f90266ec61962b9e75b997..99df975e7d7f2c11b50242fca09863a70ca7fc6d 100644 >--- a/Source/JavaScriptCore/wasm/WasmBinding.cpp >+++ b/Source/JavaScriptCore/wasm/WasmBinding.cpp >@@ -66,7 +66,10 @@ Expected<MacroAssemblerCodeRef<WasmEntryPtrTag>, BindingFailure> wasmToWasm(unsi > // FIXME the following code assumes that all Wasm::Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952 > // Set up the callee's baseMemory register as well as the memory size registers. > jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. >- jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::void*. >+ jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::TaggedArrayStoragePtr<void> (void*). >+#if CPU(ARM64E) >+ jit.untagArrayPtr(baseMemory, pinnedRegs.sizeRegister); >+#endif > > // Tail call into the callee WebAssembly function. > jit.loadPtr(scratch, scratch); >diff --git a/Source/JavaScriptCore/wasm/WasmInstance.h b/Source/JavaScriptCore/wasm/WasmInstance.h >index 1d389bec0695cce1910fa08ce50caa78a3515d8f..387bdd15a52b5f084e67ac50f07925515d4ee414 100644 >--- a/Source/JavaScriptCore/wasm/WasmInstance.h >+++ b/Source/JavaScriptCore/wasm/WasmInstance.h >@@ -64,7 +64,7 @@ public: > Memory* memory() { return m_memory.get(); } > Table* table() { return m_table.get(); } > >- void* cachedMemory() const { return m_cachedMemory; } >+ void* cachedMemory() const { return m_cachedMemory.get(cachedMemorySize()); } > size_t cachedMemorySize() const { return m_cachedMemorySize; } > > void setMemory(Ref<Memory>&& memory) >@@ -76,7 +76,7 @@ public: > void updateCachedMemory() > { > if (m_memory != nullptr) { >- m_cachedMemory = memory()->memory(); >+ m_cachedMemory = TaggedArrayStoragePtr<void>(memory()->memory(), memory()->size()); > m_cachedMemorySize = memory()->size(); > } > } >@@ -143,7 +143,7 @@ private: > } > void* m_owner { nullptr }; // In a JS embedding, this is a JSWebAssemblyInstance*. > Context* m_context { nullptr }; >- void* m_cachedMemory { nullptr }; >+ TaggedArrayStoragePtr<void> m_cachedMemory; > size_t m_cachedMemorySize { 0 }; > Ref<Module> m_module; > RefPtr<CodeBlock> m_codeBlock; >diff --git a/Source/JavaScriptCore/wasm/WasmMemory.cpp b/Source/JavaScriptCore/wasm/WasmMemory.cpp >index b2da87084c2ba1162cd31b6cb99ad8e0afec305b..6b0d3454deb5dfa2e1cc687d488485ee22561c45 100644 >--- a/Source/JavaScriptCore/wasm/WasmMemory.cpp >+++ b/Source/JavaScriptCore/wasm/WasmMemory.cpp >@@ -253,10 +253,11 @@ Memory::Memory(PageCount initial, PageCount maximum, Function<void(NotifyPressur > ASSERT(!initial.bytes()); > ASSERT(m_mode == MemoryMode::BoundsChecking); > dataLogLnIf(verbose, "Memory::Memory allocating ", *this); >+ ASSERT(!memory()); > } > > Memory::Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode mode, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback) >- : m_memory(memory) >+ : m_memory(memory, initial.bytes()) > , m_size(initial.bytes()) > , m_initial(initial) > , m_maximum(maximum) >@@ -267,6 +268,7 @@ Memory::Memory(void* memory, PageCount initial, PageCount maximum, size_t mapped > , m_growSuccessCallback(WTFMove(growSuccessCallback)) > { > dataLogLnIf(verbose, "Memory::Memory allocating ", *this); >+ this->memory(); > } > > Ref<Memory> Memory::create() >@@ -338,14 +340,14 @@ Memory::~Memory() > memoryManager().freePhysicalBytes(m_size); > switch (m_mode) { > case MemoryMode::Signaling: >- if (mprotect(m_memory, Memory::fastMappedBytes(), PROT_READ | PROT_WRITE)) { >+ if (mprotect(memory(), Memory::fastMappedBytes(), PROT_READ | PROT_WRITE)) { > dataLog("mprotect failed: ", strerror(errno), "\n"); > RELEASE_ASSERT_NOT_REACHED(); > } >- memoryManager().freeFastMemory(m_memory); >+ memoryManager().freeFastMemory(memory()); > break; > case MemoryMode::BoundsChecking: >- Gigacage::freeVirtualPages(Gigacage::Primitive, m_memory, m_size); >+ Gigacage::freeVirtualPages(Gigacage::Primitive, memory(), m_size); > break; > } > } >@@ -419,25 +421,28 @@ Expected<PageCount, Memory::GrowFailReason> Memory::grow(PageCount delta) > if (!newMemory) > return makeUnexpected(GrowFailReason::OutOfMemory); > >- memcpy(newMemory, m_memory, m_size); >+ memcpy(newMemory, memory(), m_size); > if (m_memory) >- Gigacage::freeVirtualPages(Gigacage::Primitive, m_memory, m_size); >- m_memory = newMemory; >+ Gigacage::freeVirtualPages(Gigacage::Primitive, memory(), m_size); >+ m_memory = TaggedArrayStoragePtr<void>(newMemory, desiredSize); > m_mappedCapacity = desiredSize; > m_size = desiredSize; >+ ASSERT(memory() == newMemory); > return success(); > } > case MemoryMode::Signaling: { >- RELEASE_ASSERT(m_memory); >+ RELEASE_ASSERT(memory()); > // Signaling memory must have been pre-allocated virtually. >- uint8_t* startAddress = static_cast<uint8_t*>(m_memory) + m_size; >+ uint8_t* startAddress = static_cast<uint8_t*>(memory()) + m_size; > >- dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(m_memory), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")"); >+ dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(memory()), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")"); > if (mprotect(startAddress, extraBytes, PROT_READ | PROT_WRITE)) { > dataLog("mprotect failed: ", strerror(errno), "\n"); > RELEASE_ASSERT_NOT_REACHED(); > } >+ m_memory.resize(m_size, desiredSize); > m_size = desiredSize; >+ memory(); > return success(); > } > } >@@ -460,7 +465,7 @@ void Memory::registerInstance(Instance* instance) > > void Memory::dump(PrintStream& out) const > { >- out.print("Memory at ", RawPointer(m_memory), ", size ", m_size, "B capacity ", m_mappedCapacity, "B, initial ", m_initial, " maximum ", m_maximum, " mode ", makeString(m_mode)); >+ out.print("Memory at ", RawPointer(memory()), ", size ", m_size, "B capacity ", m_mappedCapacity, "B, initial ", m_initial, " maximum ", m_maximum, " mode ", makeString(m_mode)); > } > > } // namespace JSC >diff --git a/Source/JavaScriptCore/wasm/WasmMemory.h b/Source/JavaScriptCore/wasm/WasmMemory.h >index 00737fc1e65e2b28d0b008a9e3953dc772c99111..9adbb1193292e4c2500c2b83812de2791d3b8411 100644 >--- a/Source/JavaScriptCore/wasm/WasmMemory.h >+++ b/Source/JavaScriptCore/wasm/WasmMemory.h >@@ -34,6 +34,7 @@ > #include <wtf/Function.h> > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> >+#include <wtf/TaggedArrayStoragePtr.h> > #include <wtf/Vector.h> > #include <wtf/WeakPtr.h> > >@@ -68,7 +69,7 @@ public: > static size_t fastMappedBytes(); // Includes redzone. > static bool addressIsInActiveFastMemory(void*); > >- void* memory() const { return m_memory; } >+ void* memory() const { ASSERT(m_memory.get(size()) == m_memory.getUnsafe()); return m_memory.get(size()); } > size_t size() const { return m_size; } > PageCount sizeInPages() const { return PageCount::fromBytes(m_size); } > >@@ -96,7 +97,7 @@ private: > Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback); > Memory(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback); > >- void* m_memory { nullptr }; >+ TaggedArrayStoragePtr<void> m_memory; > size_t m_size { 0 }; > PageCount m_initial; > PageCount m_maximum; >diff --git a/Source/JavaScriptCore/wasm/js/JSToWasm.cpp b/Source/JavaScriptCore/wasm/js/JSToWasm.cpp >index 20a6e8dbc971d4d7b9e572912da5c2bd2f7e8e3d..ef050cfd0f88ce9aceabe90575815eab8251e855 100644 >--- a/Source/JavaScriptCore/wasm/js/JSToWasm.cpp >+++ b/Source/JavaScriptCore/wasm/js/JSToWasm.cpp >@@ -29,6 +29,7 @@ > #if ENABLE(WEBASSEMBLY) > > #include "CCallHelpers.h" >+#include "DisallowMacroScratchRegisterUsage.h" > #include "JSCInlines.h" > #include "JSWebAssemblyInstance.h" > #include "JSWebAssemblyRuntimeError.h" >@@ -214,10 +215,24 @@ std::unique_ptr<InternalFunction> createJSToWasmWrapper(CompilationContext& comp > jit.loadWasmContextInstance(baseMemory); > > GPRReg currentInstanceGPR = Context::useFastTLS() ? baseMemory : wasmContextInstanceGPR; >- if (mode != MemoryMode::Signaling) >+ if (mode != MemoryMode::Signaling) { > jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); >- >- jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+ jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+#if CPU(ARM64E) >+ jit.untagArrayPtr(baseMemory, pinnedRegs.sizeRegister); >+#endif >+ } else { >+#if CPU(ARM64E) >+ GPRReg scratch = jit.scratchRegister(); >+ DisallowMacroScratchRegisterUsage disallowScratch(jit); >+ >+ jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), scratch); >+ jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+ jit.untagArrayPtr(baseMemory, scratch); >+#else >+ jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+#endif >+ } > } > > CCallHelpers::Call call = jit.threadSafePatchableNearCall(); >diff --git a/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp b/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >index 8f6e56db6e114b55784a66345278c7519ff7e86e..b57f2514d42fab92c9f4a3a5399140fcede21dba 100644 >--- a/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >+++ b/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp >@@ -29,6 +29,7 @@ > #if ENABLE(WEBASSEMBLY) > > #include "B3Compilation.h" >+#include "DisallowMacroScratchRegisterUsage.h" > #include "JSCInlines.h" > #include "JSFunctionInlines.h" > #include "JSObject.h" >@@ -397,11 +398,24 @@ MacroAssemblerCodePtr<JSEntryPtrTag> WebAssemblyFunction::jsCallEntrypointSlow() > GPRReg baseMemory = pinnedRegs.baseMemoryPointer; > > if (instance()->memoryMode() != Wasm::MemoryMode::Signaling) { >- ASSERT(pinnedRegs.sizeRegister != scratchGPR); > jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); >+ jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+#if CPU(ARM64E) >+ jit.removeArrayPtrTag(baseMemory); >+#endif >+ } else { >+#if CPU(ARM64E) >+ UNREACHABLE_FOR_PLATFORM(); >+ GPRReg scratch = jit.scratchRegister(); >+ DisallowMacroScratchRegisterUsage disallowScratch(jit); >+ >+ jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), scratch); >+ jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+ // jit.removeArrayPtrTag(baseMemory, scratch); >+#else >+ jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); >+#endif > } >- >- jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); > } > > // We use this callee to indicate how to unwind past these types of frames: >@@ -468,6 +482,7 @@ MacroAssemblerCodePtr<JSEntryPtrTag> WebAssemblyFunction::jsCallEntrypointSlow() > > slowPath.link(&jit); > emitRestoreCalleeSaves(); >+ jit.breakpoint(); > jit.move(CCallHelpers::TrustedImmPtr(this), GPRInfo::regT0); > jit.emitFunctionEpilogue(); > #if CPU(ARM64E) >diff --git a/Source/WTF/WTF.xcodeproj/project.pbxproj b/Source/WTF/WTF.xcodeproj/project.pbxproj >index 89c91b096d1c32a6796c487d38cdc165588bc8be..43b926b94ce497d66d31dd2d4177fe6764208865 100644 >--- a/Source/WTF/WTF.xcodeproj/project.pbxproj >+++ b/Source/WTF/WTF.xcodeproj/project.pbxproj >@@ -650,6 +650,7 @@ > DCEE21FC1CEA7551000C2396 /* BlockObjCExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockObjCExceptions.h; sourceTree = "<group>"; }; > DCEE21FD1CEA7551000C2396 /* BlockObjCExceptions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockObjCExceptions.mm; sourceTree = "<group>"; }; > DCEE22041CEB9869000C2396 /* BackwardsGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackwardsGraph.h; sourceTree = "<group>"; }; >+ DEF7FE5F22581AC800C15129 /* TaggedArrayStoragePtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaggedArrayStoragePtr.h; sourceTree = "<group>"; }; > E15556F318A0CC18006F48FB /* CryptographicUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptographicUtilities.cpp; sourceTree = "<group>"; }; > E15556F418A0CC18006F48FB /* CryptographicUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptographicUtilities.h; sourceTree = "<group>"; }; > E300E521203D645F00DA79BE /* UniqueArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UniqueArray.h; sourceTree = "<group>"; }; >@@ -1152,6 +1153,7 @@ > 5597F82C1D94B9970066BC21 /* SynchronizedFixedQueue.h */, > E3E158251EADA53C004A079D /* SystemFree.h */, > 0FB317C31C488001007E395A /* SystemTracing.h */, >+ DEF7FE5F22581AC800C15129 /* TaggedArrayStoragePtr.h */, > E311FB151F0A568B003C08DE /* ThreadGroup.cpp */, > E311FB161F0A568B003C08DE /* ThreadGroup.h */, > A8A47332151A825B004123FF /* Threading.cpp */, >diff --git a/Source/WTF/wtf/CagedPtr.h b/Source/WTF/wtf/CagedPtr.h >index d4b4ba1bb3d07feede914d25197a05b5cdfdf2d0..7c80efb7766e905dc19fc178e90f4f4ba6dddcac 100644 >--- a/Source/WTF/wtf/CagedPtr.h >+++ b/Source/WTF/wtf/CagedPtr.h >@@ -27,107 +27,91 @@ > > #include <wtf/DumbPtrTraits.h> > #include <wtf/Gigacage.h> >+#include <wtf/PtrTag.h> > > namespace WTF { > >-template<Gigacage::Kind passedKind, typename T, typename PtrTraits = DumbPtrTraits<T>> >+constexpr bool tagCagedPtr = true; >+ >+template<Gigacage::Kind passedKind, typename T, bool shouldTag = false, typename PtrTraits = DumbPtrTraits<T>> > class CagedPtr { > public: > static constexpr Gigacage::Kind kind = passedKind; > > CagedPtr() : CagedPtr(nullptr) { } >- CagedPtr(std::nullptr_t) : m_ptr(nullptr) { } >+ CagedPtr(std::nullptr_t) >+ : m_ptr(shouldTag ? tagArrayPtr<T>(nullptr, 0) : nullptr) >+ { } > >- explicit CagedPtr(T* ptr) >- : m_ptr(ptr) >- { >- } >- >- T* get() const >+ CagedPtr(T* ptr, unsigned size) >+ : m_ptr(shouldTag ? tagArrayPtr(ptr, size) : ptr) >+ { } >+ >+ >+ T* get(unsigned size) const > { > ASSERT(m_ptr); >- return Gigacage::caged(kind, PtrTraits::unwrap(m_ptr)); >- } >- >- T* getMayBeNull() const >- { >- if (!m_ptr) >- return nullptr; >- return get(); >+ T* ptr = PtrTraits::unwrap(m_ptr); >+ if (shouldTag) >+ ptr = untagArrayPtr(ptr, size); >+ return Gigacage::caged(kind, ptr); > } > >- CagedPtr& operator=(T* ptr) >+ T* getMayBeNull(unsigned size) const > { >- m_ptr = ptr; >- return *this; >+ T* ptr = PtrTraits::unwrap(m_ptr); >+ if (shouldTag) >+ ptr = untagArrayPtr(ptr, size); >+ return Gigacage::cagedMayBeNull(kind, ptr); > } > >- CagedPtr& operator=(T*&& ptr) >+ T* getUnsafe() const > { >- m_ptr = WTFMove(ptr); >- return *this; >+ T* ptr = PtrTraits::unwrap(m_ptr); >+ if (shouldTag) >+ ptr = removeArrayPtrTag(ptr); >+ return Gigacage::cagedMayBeNull(kind, ptr); > } > >- bool operator==(const CagedPtr& other) const >- { >- return getMayBeNull() == other.getMayBeNull(); >- } >- >- bool operator!=(const CagedPtr& other) const >- { >- return !(*this == other); >- } >- >- explicit operator bool() const >+ // We need the template here so that the type of U is deduced at usage time rather than class time. U should always be T. >+ template<typename U = T> >+ typename std::enable_if<!std::is_same<void, U>::value, T>::type& >+ /* T& */ at(unsigned index, unsigned size) const { return get(size)[index]; } >+ >+ void reauthenticate(unsigned oldSize, unsigned newSize) > { >- return *this != CagedPtr(); >+ auto ptr = get(oldSize); >+ ASSERT(ptr == getUnsafe()); >+ *this = CagedPtr(ptr, newSize); > } >- >- T& operator*() const { return *get(); } >- T* operator->() const { return get(); } >- >- template<typename IndexType> >- T& operator[](IndexType index) const { return get()[index]; } >- >-protected: >- typename PtrTraits::StorageType m_ptr; >-}; > >-template<Gigacage::Kind passedKind, typename PtrTraits> >-class CagedPtr<passedKind, void, PtrTraits> { >-public: >- static constexpr Gigacage::Kind kind = passedKind; >- >- CagedPtr() : CagedPtr(nullptr) { } >- CagedPtr(std::nullptr_t) : m_ptr(nullptr) { } >- >- explicit CagedPtr(void* ptr) >- : m_ptr(ptr) >+ CagedPtr(CagedPtr& other) >+ : m_ptr(other.m_ptr) > { > } >- >- void* get() const >+ >+ CagedPtr& operator=(const CagedPtr& ptr) > { >- ASSERT(m_ptr); >- return Gigacage::caged(kind, PtrTraits::unwrap(m_ptr)); >+ m_ptr = ptr.m_ptr; >+ return *this; > } >- >- void* getMayBeNull() const >+ >+ CagedPtr(CagedPtr&& other) >+ : m_ptr(PtrTraits::exchange(other.m_ptr, nullptr)) > { >- if (!m_ptr) >- return nullptr; >- return get(); > } > >- CagedPtr& operator=(void* ptr) >+ CagedPtr& operator=(CagedPtr&& ptr) > { >- m_ptr = ptr; >+ m_ptr = PtrTraits::exchange(ptr.m_ptr, nullptr); > return *this; > } > > bool operator==(const CagedPtr& other) const > { >- return getMayBeNull() == other.getMayBeNull(); >+ bool result = m_ptr == other.m_ptr; >+ ASSERT(result == (getUnsafe() == other.getUnsafe())); >+ return result; > } > > bool operator!=(const CagedPtr& other) const >@@ -137,7 +121,7 @@ public: > > explicit operator bool() const > { >- return *this != CagedPtr(); >+ return getUnsafe() != nullptr; > } > > protected: >@@ -147,4 +131,5 @@ protected: > } // namespace WTF > > using WTF::CagedPtr; >+using WTF::tagCagedPtr; > >diff --git a/Source/WTF/wtf/CagedUniquePtr.h b/Source/WTF/wtf/CagedUniquePtr.h >index 4aae2878f617c72db317f2893ba612c8efc23a09..2ed083c165ce0d5f618db3d20197ef29889e81dc 100644 >--- a/Source/WTF/wtf/CagedUniquePtr.h >+++ b/Source/WTF/wtf/CagedUniquePtr.h >@@ -29,80 +29,30 @@ > > namespace WTF { > >-template<Gigacage::Kind kind, typename T, typename Enable = void> >-class CagedUniquePtr : public CagedPtr<kind, T> { >+template<Gigacage::Kind kind, typename T, bool shouldTag = false> >+class CagedUniquePtr : public CagedPtr<kind, T, shouldTag> { >+ static_assert(std::is_trivially_destructible<T>::value, "We expect the contents of a caged pointer to be trivially destructable."); > public: >- CagedUniquePtr(T* ptr = nullptr) >- : CagedPtr<kind, T>(ptr) >- { >- } >- >- CagedUniquePtr(CagedUniquePtr&& ptr) >- : CagedPtr<kind, T>(ptr.m_ptr) >- { >- ptr.m_ptr = nullptr; >- } >- >- CagedUniquePtr(const CagedUniquePtr&) = delete; >- >- template<typename... Arguments> >- static CagedUniquePtr create(Arguments&&... arguments) >- { >- T* result = static_cast<T*>(Gigacage::malloc(kind, sizeof(T))); >- new (result) T(std::forward<Arguments>(arguments)...); >- return CagedUniquePtr(result); >- } >- >- CagedUniquePtr& operator=(CagedUniquePtr&& ptr) >- { >- destroy(); >- this->m_ptr = ptr.m_ptr; >- ptr.m_ptr = nullptr; >- return *this; >- } >- >- CagedUniquePtr& operator=(const CagedUniquePtr&) = delete; >- >- ~CagedUniquePtr() >- { >- destroy(); >- } >- >-private: >- void destroy() >- { >- if (!this->m_ptr) >- return; >- this->m_ptr->~T(); >- Gigacage::free(kind, this->m_ptr); >- } >-}; >+ using Base = CagedPtr<kind, T, shouldTag>; >+ CagedUniquePtr() = default; >+ >+ CagedUniquePtr(T* ptr, unsigned size) >+ : Base(ptr, size) >+ { } > >-template<Gigacage::Kind kind, typename T> >-class CagedUniquePtr<kind, T[], typename std::enable_if<std::is_trivially_destructible<T>::value>::type> : public CagedPtr<kind, T> { >-public: >- CagedUniquePtr() : CagedPtr<kind, T>() { } >- >- CagedUniquePtr(T* ptr) >- : CagedPtr<kind, T>(ptr) >- { >- } >- > CagedUniquePtr(CagedUniquePtr&& ptr) >- : CagedPtr<kind, T>(ptr.m_ptr) >- { >- ptr.m_ptr = nullptr; >- } >+ : Base(std::forward<CagedUniquePtr&&>(ptr)) >+ { } > > CagedUniquePtr(const CagedUniquePtr&) = delete; > > template<typename... Arguments> >- static CagedUniquePtr create(size_t count, Arguments&&... arguments) >+ static CagedUniquePtr create(unsigned length, Arguments&&... arguments) > { >- T* result = static_cast<T*>(Gigacage::mallocArray(kind, count, sizeof(T))); >- while (count--) >- new (result + count) T(std::forward<Arguments>(arguments)...); >- return CagedUniquePtr(result); >+ T* result = static_cast<T*>(Gigacage::malloc(kind, sizeof(T) * length)); >+ while (length--) >+ new (result + length) T(arguments...); >+ return CagedUniquePtr(result, length); > } > > CagedUniquePtr& operator=(CagedUniquePtr&& ptr) >@@ -119,83 +69,16 @@ public: > { > destroy(); > } >- >-private: >- void destroy() >- { >- if (!this->m_ptr) >- return; >- Gigacage::free(kind, this->m_ptr); >- } >-}; > >-template<Gigacage::Kind kind, typename T> >-class CagedUniquePtr<kind, T[], typename std::enable_if<!std::is_trivially_destructible<T>::value>::type> : public CagedPtr<kind, T> { >-public: >- CagedUniquePtr() : CagedPtr<kind, T>() { } >- >- CagedUniquePtr(T* ptr, size_t count) >- : CagedPtr<kind, T>(ptr) >- , m_count(count) >- { >- } >- >- CagedUniquePtr(CagedUniquePtr&& ptr) >- : CagedPtr<kind, T>(ptr.m_ptr) >- , m_count(ptr.m_count) >- { >- ptr.clear(); >- } >- >- CagedUniquePtr(const CagedUniquePtr&) = delete; >- >- template<typename... Arguments> >- static CagedUniquePtr create(size_t count, Arguments&&... arguments) >- { >- T* result = static_cast<T*>(Gigacage::mallocArray(kind, count, sizeof(T))); >- while (count--) >- new (result + count) T(std::forward<Arguments>(arguments)...); >- return CagedUniquePtr(result, count); >- } >- >- CagedUniquePtr& operator=(CagedUniquePtr&& ptr) >- { >- destroy(); >- this->m_ptr = ptr.m_ptr; >- m_count = ptr.m_count; >- ptr.clear(); >- return *this; >- } >- >- CagedUniquePtr& operator=(const CagedUniquePtr&) = delete; >- >- ~CagedUniquePtr() >- { >- destroy(); >- } >- >- // FIXME: It's weird that we inherit CagedPtr::operator== and friends, which don't do anything >- // about m_count. It "works" because pointer equality is enough so long as everything is sane, but >- // it seems like a missed opportunity to assert things. >- // https://bugs.webkit.org/show_bug.cgi?id=175541 >- > private: > void destroy() > { >- if (!this->m_ptr) >+ T* ptr = Base::getUnsafe(); >+ if (!ptr) > return; >- while (m_count--) >- this->m_ptr[m_count].~T(); >- Gigacage::free(kind, this->m_ptr); >+ ptr->~T(); >+ Gigacage::free(kind, ptr); > } >- >- void clear() >- { >- this->m_ptr = nullptr; >- m_count = 0; >- } >- >- size_t m_count { 0 }; > }; > > } // namespace WTF >diff --git a/Source/WTF/wtf/PtrTag.h b/Source/WTF/wtf/PtrTag.h >index 342a40faf104c23f9c334a22c2911ec4ea717c13..685b27f54cf5167bbb64de130d7f051a82fe2a6d 100644 >--- a/Source/WTF/wtf/PtrTag.h >+++ b/Source/WTF/wtf/PtrTag.h >@@ -121,6 +121,39 @@ constexpr bool enablePtrTagDebugAssert = true; > } \ > } while (false) > >+ >+template<typename T> >+inline T* tagArrayPtr(nullptr_t ptr, size_t length) >+{ >+ ASSERT(!length); >+ return ptrauth_sign_unauthenticated(static_cast<T*>(ptr), ptrauth_key_process_dependent_data, length); >+} >+ >+ >+template<typename T> >+inline T* tagArrayPtr(T* ptr, size_t length) >+{ >+ return ptrauth_sign_unauthenticated(ptr, ptrauth_key_process_dependent_data, length); >+} >+ >+template<typename T> >+inline T* untagArrayPtr(T* ptr, size_t length) >+{ >+ return ptrauth_auth_data(ptr, ptrauth_key_process_dependent_data, length); >+} >+ >+template<typename T> >+inline T* removeArrayPtrTag(T* ptr) >+{ >+ return ptrauth_strip(ptr, ptrauth_key_process_dependent_data); >+} >+ >+template<typename T> >+inline T* retagArrayPtr(T* ptr, size_t oldLength, size_t newLength) >+{ >+ return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_data, oldLength, ptrauth_key_process_dependent_data, newLength); >+} >+ > template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>> > inline constexpr T removeCodePtrTag(PtrType ptr) > { >@@ -394,6 +427,38 @@ inline bool usesPointerTagging() { return true; } > inline void registerPtrTagLookup(PtrTagLookup*) { } > inline void reportBadTag(const void*, PtrTag) { } > >+template<typename T> >+inline T* tagArrayPtr(nullptr_t, size_t size) >+{ >+ ASSERT(!size); >+ return nullptr; >+} >+ >+template<typename T> >+inline T* tagArrayPtr(T* ptr, size_t) >+{ >+ return ptr; >+} >+ >+template<typename T> >+inline T* untagArrayPtr(T* ptr, size_t) >+{ >+ return ptr; >+} >+ >+template<typename T> >+inline T* removeArrayPtrTag(T* ptr) >+{ >+ return ptr; >+} >+ >+template<typename T> >+inline T* retagArrayPtr(T* ptr, size_t, size_t) >+{ >+ return ptr; >+} >+ >+ > template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>> > constexpr T tagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); } > >diff --git a/Source/WTF/wtf/TaggedArrayStoragePtr.h b/Source/WTF/wtf/TaggedArrayStoragePtr.h >new file mode 100644 >index 0000000000000000000000000000000000000000..553e86f77399847d0e07117f609eec517ca579d1 >--- /dev/null >+++ b/Source/WTF/wtf/TaggedArrayStoragePtr.h >@@ -0,0 +1,59 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * 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 <wtf/PtrTag.h> >+ >+namespace WTF { >+ >+template<typename PtrType> >+class TaggedArrayStoragePtr { >+public: >+ TaggedArrayStoragePtr() >+ : m_ptr(tagArrayPtr<PtrType>(nullptr, 0)) >+ { } >+ >+ TaggedArrayStoragePtr(PtrType* ptr, unsigned length) >+ : m_ptr(tagArrayPtr(ptr, length)) >+ { } >+ >+ PtrType* get(unsigned length) const { return untagArrayPtr(m_ptr, length); } >+ PtrType* getUnsafe() const { return removeArrayPtrTag(m_ptr); } >+ >+ void resize(unsigned oldLength, unsigned newLength) >+ { >+ m_ptr = retagArrayPtr(m_ptr, oldLength, newLength); >+ } >+ >+ explicit operator bool() const { return !!getUnsafe(); } >+ >+private: >+ PtrType* m_ptr; >+}; >+ >+} >+ >+using WTF::TaggedArrayStoragePtr; >diff --git a/Source/bmalloc/bmalloc/Gigacage.h b/Source/bmalloc/bmalloc/Gigacage.h >index 70cce67a245b43395132bfddaa4166a3be833b42..bcde37c34bde2664544004376228feabcc62e450 100644 >--- a/Source/bmalloc/bmalloc/Gigacage.h >+++ b/Source/bmalloc/bmalloc/Gigacage.h >@@ -34,8 +34,7 @@ > #include <cstddef> > #include <inttypes.h> > >-#if ((BOS(DARWIN) || BOS(LINUX)) && \ >-(BCPU(X86_64) || (BCPU(ARM64) && !defined(__ILP32__) && (!BPLATFORM(IOS_FAMILY) || BPLATFORM(IOS))))) >+#if ((BOS(DARWIN) || BOS(LINUX)) && BCPU(X86_64)) > #define GIGACAGE_ENABLED 1 > #else > #define GIGACAGE_ENABLED 0 >@@ -200,6 +199,14 @@ BINLINE T* caged(Kind kind, T* ptr) > reinterpret_cast<uintptr_t>(ptr) & mask(kind))); > } > >+template<typename T> >+BINLINE T* cagedMayBeNull(Kind kind, T* ptr) >+{ >+ if (!ptr) >+ return ptr; >+ return caged(kind, ptr); >+} >+ > BINLINE bool isCaged(Kind kind, const void* ptr) > { > return caged(kind, ptr) == ptr; >@@ -221,6 +228,7 @@ BINLINE bool wasEnabled() { return false; } > BINLINE bool isCaged(Kind, const void*) { return true; } > BINLINE bool isEnabled() { return false; } > template<typename T> BINLINE T* caged(Kind, T* ptr) { return ptr; } >+template<typename T> BINLINE T* cagedMayBeNull(Kind, T* ptr) { return ptr; } > BINLINE void disableDisablingPrimitiveGigacageIfShouldBeEnabled() { } > BINLINE bool canPrimitiveGigacageBeDisabled() { return false; } > BINLINE void disablePrimitiveGigacage() { } >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 52420d8cef82a38cb140eceb1d7f8c1dd8371b8b..3e73cda5f27a870e491a344d805dc3da57610de4 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,16 @@ >+2019-05-03 Keith Miller <keith_miller@apple.com> >+ >+ Remove Gigacage from arm64 and use PAC for arm64e instead >+ https://bugs.webkit.org/show_bug.cgi?id=197110 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/StringObject-define-length-getter-rope-string-oom.js: >+ * stress/create-error-out-of-memory-rope-string-2.js: >+ * stress/create-error-out-of-memory-rope-string.js: >+ * stress/generator-arguments.js: >+ * stress/string-16bit-repeat-overflow.js: >+ > 2019-05-03 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] Need to emit SetLocal if we emit MovHint in DFGByteCodeParser >diff --git a/JSTests/stress/create-error-out-of-memory-rope-string.js b/JSTests/stress/create-error-out-of-memory-rope-string.js >index 81d8817ddf347d9a977192a64a1bab96543a6ed9..5ff72ac8efd670c4347e797845facb99d03ba5e9 100644 >--- a/JSTests/stress/create-error-out-of-memory-rope-string.js >+++ b/JSTests/stress/create-error-out-of-memory-rope-string.js >@@ -1,4 +1,5 @@ > //@ skip if $memoryLimited >+ > function assert(a, message) { > if (!a) > throw new Error(message); >diff --git a/JSTests/stress/generator-arguments.js b/JSTests/stress/generator-arguments.js >index b26478fa23e4be33abaaf1447292a459b7b86d1c..23b1c24f147029d175429a6102f2866bccc08e8a 100644 >--- a/JSTests/stress/generator-arguments.js >+++ b/JSTests/stress/generator-arguments.js >@@ -17,6 +17,7 @@ function shouldBe(actual, expected) > > function *g2(a, b, c) > { >+ print(arguments); > yield arguments; > yield arguments; > a = yield a; >diff --git a/JSTests/stress/string-16bit-repeat-overflow.js b/JSTests/stress/string-16bit-repeat-overflow.js >index f7c41c87c2e69a6b51ee76013a8f8a1b21149302..635e91e6714b802587d0745e74eb275951c12e92 100644 >--- a/JSTests/stress/string-16bit-repeat-overflow.js >+++ b/JSTests/stress/string-16bit-repeat-overflow.js >@@ -1,4 +1,5 @@ > //@ skip if $memoryLimited >+ > var exception; > try { > print('\ud000'.repeat(2**30));
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 197110
:
367808
|
368301
|
368517
|
369032
|
369130
|
369131
|
369141
|
369144
|
369145
|
369146
|
369150
|
369158
|
369159
|
369162
|
369164
|
369167
|
369177
|
369183
|
369186
|
369191
|
369192
|
369217
|
369235
|
369405