Changeset 246322 in webkit
- Timestamp:
- Jun 11, 2019 10:18:47 AM (5 years ago)
- Location:
- trunk/Source
- Files:
-
- 1 deleted
- 60 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r246299 r246322 1 2019-06-11 Saam Barati <sbarati@apple.com> 2 3 Roll out PAC cage 4 https://bugs.webkit.org/show_bug.cgi?id=198726 5 6 Reviewed by Keith Miller. 7 8 This patch rolls out: r245064, r245145, r245168, r245313, r245432, r245622. 9 10 The resulting state we're in is we have Gigacage enabled on arm64. 11 There is no more PAC caging. 12 13 We're doing this because there are performance issues with PAC caging 14 that we haven't resolved yet. 15 16 * assembler/CPU.h: 17 (JSC::isARM64E): Deleted. 18 * assembler/MacroAssemblerARM64E.h: 19 (JSC::MacroAssemblerARM64E::tagArrayPtr): Deleted. 20 (JSC::MacroAssemblerARM64E::untagArrayPtr): Deleted. 21 (JSC::MacroAssemblerARM64E::removeArrayPtrTag): Deleted. 22 * b3/B3LowerToAir.cpp: 23 * b3/B3PatchpointSpecial.cpp: 24 (JSC::B3::PatchpointSpecial::admitsStack): 25 * b3/B3StackmapSpecial.cpp: 26 (JSC::B3::StackmapSpecial::forEachArgImpl): 27 (JSC::B3::StackmapSpecial::isArgValidForRep): 28 * b3/B3Validate.cpp: 29 * b3/B3ValueRep.cpp: 30 (JSC::B3::ValueRep::addUsedRegistersTo const): 31 (JSC::B3::ValueRep::dump const): 32 (WTF::printInternal): 33 * b3/B3ValueRep.h: 34 (JSC::B3::ValueRep::ValueRep): 35 (JSC::B3::ValueRep::isReg const): 36 * dfg/DFGOperations.cpp: 37 (JSC::DFG::newTypedArrayWithSize): 38 * dfg/DFGSpeculativeJIT.cpp: 39 (JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds): 40 (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage): 41 (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): 42 (JSC::DFG::SpeculativeJIT::compileGetTypedArrayByteOffset): 43 (JSC::DFG::SpeculativeJIT::compileNewTypedArrayWithSize): 44 * dfg/DFGSpeculativeJIT.h: 45 * dfg/DFGSpeculativeJIT64.cpp: 46 (JSC::DFG::SpeculativeJIT::compile): 47 * ftl/FTLLowerDFGToB3.cpp: 48 (JSC::FTL::DFG::LowerDFGToB3::compileGetIndexedPropertyStorage): 49 (JSC::FTL::DFG::LowerDFGToB3::compileGetTypedArrayByteOffset): 50 (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): 51 (JSC::FTL::DFG::LowerDFGToB3::compileDataViewGet): 52 (JSC::FTL::DFG::LowerDFGToB3::compileDataViewSet): 53 (JSC::FTL::DFG::LowerDFGToB3::caged): 54 (JSC::FTL::DFG::LowerDFGToB3::speculateTypedArrayIsNotNeutered): 55 (JSC::FTL::DFG::LowerDFGToB3::untagArrayPtr): Deleted. 56 (JSC::FTL::DFG::LowerDFGToB3::removeArrayPtrTag): Deleted. 57 * heap/ConservativeRoots.cpp: 58 (JSC::ConservativeRoots::genericAddPointer): 59 * jit/AssemblyHelpers.h: 60 (JSC::AssemblyHelpers::cageConditionally): 61 * jit/IntrinsicEmitter.cpp: 62 (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter): 63 * jit/JITPropertyAccess.cpp: 64 (JSC::JIT::emitDirectArgumentsGetByVal): 65 (JSC::JIT::emitIntTypedArrayGetByVal): 66 (JSC::JIT::emitFloatTypedArrayGetByVal): 67 (JSC::JIT::emitIntTypedArrayPutByVal): 68 (JSC::JIT::emitFloatTypedArrayPutByVal): 69 * jit/PolymorphicCallStubRoutine.cpp: 70 (JSC::PolymorphicCallNode::clearCallLinkInfo): 71 * jit/RegisterSet.h: 72 * llint/LowLevelInterpreter64.asm: 73 * runtime/ArrayBuffer.cpp: 74 (JSC::SharedArrayBufferContents::SharedArrayBufferContents): 75 (JSC::SharedArrayBufferContents::~SharedArrayBufferContents): 76 (JSC::ArrayBufferContents::ArrayBufferContents): 77 (JSC::ArrayBufferContents::destroy): 78 (JSC::ArrayBufferContents::tryAllocate): 79 (JSC::ArrayBufferContents::makeShared): 80 (JSC::ArrayBufferContents::copyTo): 81 * runtime/ArrayBuffer.h: 82 (JSC::SharedArrayBufferContents::data const): 83 (JSC::ArrayBufferContents::data const): 84 (JSC::ArrayBuffer::data): 85 (JSC::ArrayBuffer::data const): 86 (JSC::ArrayBuffer::byteLength const): 87 * runtime/ArrayBufferView.cpp: 88 (JSC::ArrayBufferView::ArrayBufferView): 89 * runtime/ArrayBufferView.h: 90 (JSC::ArrayBufferView::baseAddress const): 91 (JSC::ArrayBufferView::setRangeImpl): 92 (JSC::ArrayBufferView::getRangeImpl): 93 (JSC::ArrayBufferView::byteLength const): Deleted. 94 * runtime/CachedTypes.cpp: 95 (JSC::CachedScopedArgumentsTable::encode): 96 (JSC::CachedScopedArgumentsTable::decode const): 97 * runtime/CagedBarrierPtr.h: 98 (JSC::CagedBarrierPtr::CagedBarrierPtr): 99 (JSC::CagedBarrierPtr::set): 100 (JSC::CagedBarrierPtr::get const): 101 (JSC::CagedBarrierPtr::getMayBeNull const): 102 (JSC::CagedBarrierPtr::operator== const): 103 (JSC::CagedBarrierPtr::operator!= const): 104 (JSC::CagedBarrierPtr::operator bool const): 105 (JSC::CagedBarrierPtr::setWithoutBarrier): 106 (JSC::CagedBarrierPtr::operator* const): 107 (JSC::CagedBarrierPtr::operator-> const): 108 (JSC::CagedBarrierPtr::operator[] const): 109 (JSC::CagedBarrierPtr::getUnsafe const): Deleted. 110 (JSC::CagedBarrierPtr::at const): Deleted. 111 * runtime/DataView.cpp: 112 (JSC::DataView::DataView): 113 * runtime/DataView.h: 114 (JSC::DataView::get): 115 (JSC::DataView::set): 116 * runtime/DirectArguments.cpp: 117 (JSC::DirectArguments::visitChildren): 118 (JSC::DirectArguments::overrideThings): 119 (JSC::DirectArguments::unmapArgument): 120 * runtime/DirectArguments.h: 121 * runtime/GenericArguments.h: 122 * runtime/GenericArgumentsInlines.h: 123 (JSC::GenericArguments<Type>::visitChildren): 124 (JSC::GenericArguments<Type>::initModifiedArgumentsDescriptor): 125 (JSC::GenericArguments<Type>::setModifiedArgumentDescriptor): 126 (JSC::GenericArguments<Type>::isModifiedArgumentDescriptor): 127 * runtime/GenericTypedArrayView.h: 128 * runtime/GenericTypedArrayViewInlines.h: 129 (JSC::GenericTypedArrayView<Adaptor>::GenericTypedArrayView): 130 * runtime/JSArrayBufferView.cpp: 131 (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext): 132 (JSC::JSArrayBufferView::JSArrayBufferView): 133 (JSC::JSArrayBufferView::finalize): 134 (JSC::JSArrayBufferView::slowDownAndWasteMemory): 135 * runtime/JSArrayBufferView.h: 136 (JSC::JSArrayBufferView::ConstructionContext::vector const): 137 (JSC::JSArrayBufferView::isNeutered): 138 (JSC::JSArrayBufferView::vector const): 139 (JSC::JSArrayBufferView::hasVector const): Deleted. 140 * runtime/JSGenericTypedArrayViewInlines.h: 141 (JSC::JSGenericTypedArrayView<Adaptor>::createUninitialized): 142 (JSC::JSGenericTypedArrayView<Adaptor>::estimatedSize): 143 (JSC::JSGenericTypedArrayView<Adaptor>::visitChildren): 144 * runtime/Options.h: 145 * runtime/ScopedArgumentsTable.cpp: 146 (JSC::ScopedArgumentsTable::clone): 147 (JSC::ScopedArgumentsTable::setLength): 148 * runtime/ScopedArgumentsTable.h: 149 * runtime/SymbolTable.h: 150 * wasm/WasmAirIRGenerator.cpp: 151 (JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState): 152 (JSC::Wasm::AirIRGenerator::addCallIndirect): 153 * wasm/WasmB3IRGenerator.cpp: 154 (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState): 155 (JSC::Wasm::B3IRGenerator::addCallIndirect): 156 * wasm/WasmBBQPlan.cpp: 157 (JSC::Wasm::BBQPlan::complete): 158 * wasm/WasmBinding.cpp: 159 (JSC::Wasm::wasmToWasm): 160 * wasm/WasmInstance.h: 161 (JSC::Wasm::Instance::cachedMemory const): 162 (JSC::Wasm::Instance::updateCachedMemory): 163 * wasm/WasmMemory.cpp: 164 (JSC::Wasm::Memory::Memory): 165 (JSC::Wasm::Memory::~Memory): 166 (JSC::Wasm::Memory::grow): 167 (JSC::Wasm::Memory::dump const): 168 * wasm/WasmMemory.h: 169 (JSC::Wasm::Memory::memory const): 170 * wasm/js/JSToWasm.cpp: 171 (JSC::Wasm::createJSToWasmWrapper): 172 * wasm/js/WebAssemblyFunction.cpp: 173 (JSC::WebAssemblyFunction::jsCallEntrypointSlow): 174 1 175 2019-06-10 Basuke Suzuki <Basuke.Suzuki@sony.com> 2 176 -
trunk/Source/JavaScriptCore/assembler/CPU.h
r245432 r246322 51 51 { 52 52 #if CPU(ARM64) 53 return true;54 #else55 return false;56 #endif57 }58 59 constexpr bool isARM64E()60 {61 #if CPU(ARM64E)62 53 return true; 63 54 #else -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h
r246240 r246322 83 83 } 84 84 85 ALWAYS_INLINE void tagArrayPtr(RegisterID length, RegisterID target)86 {87 m_assembler.pacdb(target, length);88 }89 90 ALWAYS_INLINE void untagArrayPtr(RegisterID length, RegisterID target)91 {92 m_assembler.autdb(target, length);93 }94 95 ALWAYS_INLINE void untagArrayPtr(Address length, RegisterID target)96 {97 auto lengthGPR = getCachedDataTempRegisterIDAndInvalidate();98 load32(length, lengthGPR);99 m_assembler.autdb(target, lengthGPR);100 }101 102 ALWAYS_INLINE void removeArrayPtrTag(RegisterID target)103 {104 m_assembler.xpacd(target);105 }106 107 85 static const RegisterID InvalidGPR = static_cast<RegisterID>(-1); 108 86 -
trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp
r245064 r246322 1275 1275 break; 1276 1276 case ValueRep::SomeRegister: 1277 case ValueRep::SomeLateRegister:1278 1277 arg = tmp(value.value()); 1279 1278 break; -
trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp
r245064 r246322 121 121 case ValueRep::SomeRegisterWithClobber: 122 122 case ValueRep::SomeEarlyRegister: 123 case ValueRep::SomeLateRegister:124 123 case ValueRep::Register: 125 124 case ValueRep::LateRegister: -
trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp
r245064 r246322 114 114 role = Arg::UseDef; 115 115 break; 116 case ValueRep::SomeLateRegister:117 116 case ValueRep::LateRegister: 118 117 role = Arg::LateUse; … … 256 255 case ValueRep::SomeRegisterWithClobber: 257 256 case ValueRep::SomeEarlyRegister: 258 case ValueRep::SomeLateRegister:259 257 return arg.isTmp(); 260 258 case ValueRep::LateRegister: -
trunk/Source/JavaScriptCore/b3/B3Validate.cpp
r245064 r246322 581 581 case ValueRep::Register: 582 582 case ValueRep::LateRegister: 583 case ValueRep::SomeLateRegister:584 583 if (value.rep().kind() == ValueRep::LateRegister) 585 584 VALIDATE(role == ConstraintRole::Use, ("At ", *context, ": ", value)); -
trunk/Source/JavaScriptCore/b3/B3ValueRep.cpp
r245064 r246322 43 43 case SomeRegisterWithClobber: 44 44 case SomeEarlyRegister: 45 case SomeLateRegister:46 45 case Constant: 47 46 return; … … 76 75 case SomeRegisterWithClobber: 77 76 case SomeEarlyRegister: 78 case SomeLateRegister:79 77 return; 80 78 case LateRegister: … … 186 184 out.print("SomeEarlyRegister"); 187 185 return; 188 case ValueRep::SomeLateRegister:189 out.print("SomeLateRegister");190 return;191 186 case ValueRep::Register: 192 187 out.print("Register"); -
trunk/Source/JavaScriptCore/b3/B3ValueRep.h
r245064 r246322 75 75 // the result constraint of a Patchpoint. 76 76 SomeEarlyRegister, 77 78 // As an input representation, this tells us that B3 should pick some register, but implies 79 // the use happens after any defs. This is only works for patchpoints. 80 SomeLateRegister, 81 77 82 78 // As an input representation, this forces a particular register. As an output 83 79 // representation, this tells us what register B3 picked. … … 116 112 : m_kind(kind) 117 113 { 118 ASSERT(kind == WarmAny || kind == ColdAny || kind == LateColdAny || kind == SomeRegister || kind == SomeRegisterWithClobber || kind == SomeEarlyRegister || kind == SomeLateRegister);114 ASSERT(kind == WarmAny || kind == ColdAny || kind == LateColdAny || kind == SomeRegister || kind == SomeRegisterWithClobber || kind == SomeEarlyRegister); 119 115 } 120 116 … … 190 186 bool isAny() const { return kind() == WarmAny || kind() == ColdAny || kind() == LateColdAny; } 191 187 192 bool isReg() const { return kind() == Register || kind() == LateRegister || kind() == SomeLateRegister; }188 bool isReg() const { return kind() == Register || kind() == LateRegister; } 193 189 194 190 Reg reg() const -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r246041 r246322 199 199 200 200 if (vector) 201 return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, untagArrayPtr(vector, size)));201 return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, vector)); 202 202 203 203 RELEASE_AND_RETURN(scope, bitwise_cast<char*>(ViewClass::create(exec, structure, size))); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r246240 r246322 41 41 #include "DFGSnippetParams.h" 42 42 #include "DirectArguments.h" 43 #include "DisallowMacroScratchRegisterUsage.h"44 43 #include "JITAddGenerator.h" 45 44 #include "JITBitAndGenerator.h" … … 2873 2872 TrustedImm32(WastefulTypedArray)); 2874 2873 2875 JITCompiler::Jump hasNullVector; 2876 #if !GIGACAGE_ENABLED && CPU(ARM64E) 2877 { 2878 GPRReg scratch = m_jit.scratchRegister(); 2879 DisallowMacroScratchRegisterUsage disallowScratch(m_jit); 2880 2881 m_jit.loadPtr(MacroAssembler::Address(base, JSArrayBufferView::offsetOfVector()), scratch); 2882 m_jit.removeArrayPtrTag(scratch); 2883 hasNullVector = m_jit.branchTestPtr(MacroAssembler::Zero, scratch); 2884 } 2885 #else // !GIGACAGE_ENABLED && CPU(ARM64E) 2886 hasNullVector = m_jit.branchTestPtr( 2874 JITCompiler::Jump hasNullVector = m_jit.branchTestPtr( 2887 2875 MacroAssembler::Zero, 2888 2876 MacroAssembler::Address(base, JSArrayBufferView::offsetOfVector())); 2889 #endif2890 2877 speculationCheck(Uncountable, JSValueSource(), node, hasNullVector); 2891 2878 notWasteful.link(&m_jit); … … 6759 6746 } 6760 6747 6761 void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRRegstorageReg)6748 void SpeculativeJIT::cageTypedArrayStorage(GPRReg storageReg) 6762 6749 { 6763 6750 #if GIGACAGE_ENABLED 6764 UNUSED_PARAM(baseReg);6765 6751 if (!Gigacage::shouldBeEnabled()) 6766 6752 return; … … 6774 6760 6775 6761 m_jit.cage(Gigacage::Primitive, storageReg); 6776 #elif CPU(ARM64E)6777 m_jit.untagArrayPtr(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg);6778 6762 #else 6779 UNUSED_PARAM(baseReg);6780 6763 UNUSED_PARAM(storageReg); 6781 6764 #endif … … 6801 6784 m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg); 6802 6785 break; 6803 6804 default: {6786 6787 default: 6805 6788 auto typedArrayType = node->arrayMode().typedArrayType(); 6806 6789 ASSERT_UNUSED(typedArrayType, isTypedView(typedArrayType)); 6807 6790 6808 6791 m_jit.loadPtr(JITCompiler::Address(baseReg, JSArrayBufferView::offsetOfVector()), storageReg); 6809 cageTypedArrayStorage(baseReg, storageReg); 6810 break; 6811 } 6812 } 6813 6792 cageTypedArrayStorage(storageReg); 6793 break; 6794 } 6795 6814 6796 storageResult(storageReg, node); 6815 6797 } … … 6836 6818 6837 6819 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), vectorGPR); 6838 6839 // FIXME: This should mask the PAC bits6840 // https://bugs.webkit.org/show_bug.cgi?id=1977016841 6820 JITCompiler::Jump nullVector = m_jit.branchTestPtr(JITCompiler::Zero, vectorGPR); 6842 6821 … … 6844 6823 m_jit.cage(Gigacage::JSValue, dataGPR); 6845 6824 6846 cageTypedArrayStorage( baseGPR,vectorGPR);6825 cageTypedArrayStorage(vectorGPR); 6847 6826 6848 6827 m_jit.loadPtr(MacroAssembler::Address(dataGPR, Butterfly::offsetOfArrayBuffer()), arrayBufferGPR); … … 6850 6829 // https://bugs.webkit.org/show_bug.cgi?id=175515 6851 6830 m_jit.loadPtr(MacroAssembler::Address(arrayBufferGPR, ArrayBuffer::offsetOfData()), dataGPR); 6852 #if CPU(ARM64E)6853 m_jit.removeArrayPtrTag(dataGPR);6854 #endif6855 6856 6831 m_jit.subPtr(dataGPR, vectorGPR); 6857 6832 … … 9846 9821 m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit); 9847 9822 done.link(&m_jit); 9848 #if !GIGACAGE_ENABLED && CPU(ARM64E)9849 // sizeGPR is still boxed as a number and there is no 32-bit variant of the PAC instructions.9850 m_jit.zeroExtend32ToPtr(sizeGPR, scratchGPR);9851 m_jit.tagArrayPtr(scratchGPR, storageGPR);9852 #endif9853 9823 9854 9824 auto butterfly = TrustedImmPtr(nullptr); … … 9872 9842 slowCases, this, operationNewTypedArrayWithSizeForType(typedArrayType), 9873 9843 resultGPR, structure, sizeGPR, storageGPR)); 9874 9844 9875 9845 cellResult(resultGPR, node); 9876 9846 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r246041 r246322 1653 1653 GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat); 1654 1654 1655 void cageTypedArrayStorage(GPRReg , GPRReg);1655 void cageTypedArrayStorage(GPRReg); 1656 1656 1657 1657 void recordSetLocal( -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r246041 r246322 4683 4683 4684 4684 m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2); 4685 cageTypedArrayStorage( dataViewGPR,t2);4685 cageTypedArrayStorage(t2); 4686 4686 4687 4687 m_jit.zeroExtend32ToPtr(indexGPR, t1); … … 4879 4879 4880 4880 m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2); 4881 cageTypedArrayStorage( dataViewGPR,t2);4881 cageTypedArrayStorage(t2); 4882 4882 4883 4883 m_jit.zeroExtend32ToPtr(indexGPR, t1); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r246240 r246322 3884 3884 DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()), m_node->arrayMode().typedArrayType()); 3885 3885 LValue vector = m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector); 3886 setStorage(caged(Gigacage::Primitive, vector , cell));3886 setStorage(caged(Gigacage::Primitive, vector)); 3887 3887 } 3888 3888 … … 3928 3928 m_out.appendTo(notNull, continuation); 3929 3929 3930 LValue butterflyPtr = caged(Gigacage::JSValue, m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly) , basePtr);3930 LValue butterflyPtr = caged(Gigacage::JSValue, m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly)); 3931 3931 LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer); 3932 3932 3933 LValue vectorPtr = caged(Gigacage::Primitive, vector , basePtr);3933 LValue vectorPtr = caged(Gigacage::Primitive, vector); 3934 3934 3935 3935 // FIXME: This needs caging. 3936 3936 // https://bugs.webkit.org/show_bug.cgi?id=175515 3937 3937 LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data); 3938 dataPtr = removeArrayPtrTag(dataPtr);3939 3938 3940 3939 ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr)); … … 6485 6484 m_out.int64Zero, 6486 6485 m_heaps.typedArrayProperties); 6487 6488 #if !GIGACAGE_ENABLED && CPU(ARM64E)6489 {6490 LValue sizePtr = m_out.zeroExtPtr(size);6491 PatchpointValue* authenticate = m_out.patchpoint(pointerType());6492 authenticate->appendSomeRegister(storage);6493 authenticate->append(sizePtr, B3::ValueRep(B3::ValueRep::SomeLateRegister));6494 authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {6495 jit.move(params[1].gpr(), params[0].gpr());6496 jit.tagArrayPtr(params[2].gpr(), params[0].gpr());6497 });6498 storage = authenticate;6499 }6500 #endif6501 6486 6502 6487 ValueFromBlock haveStorage = m_out.anchor(storage); … … 12718 12703 speculate(OutOfBounds, noValue(), nullptr, m_out.aboveOrEqual(indexToCheck, length)); 12719 12704 12720 LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector) , dataView);12705 LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector)); 12721 12706 12722 12707 TypedPointer pointer(m_heaps.typedArrayProperties, m_out.add(vector, m_out.zeroExtPtr(index))); … … 12877 12862 } 12878 12863 12879 LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector) , dataView);12864 LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector)); 12880 12865 TypedPointer pointer(m_heaps.typedArrayProperties, m_out.add(vector, m_out.zeroExtPtr(index))); 12881 12866 … … 14124 14109 } 14125 14110 } 14126 14127 LValue untagArrayPtr(LValue ptr, LValue size) 14128 { 14129 #if CPU(ARM64E) 14130 PatchpointValue* authenticate = m_out.patchpoint(pointerType()); 14131 authenticate->appendSomeRegister(ptr); 14132 authenticate->append(size, B3::ValueRep(B3::ValueRep::SomeLateRegister)); 14133 authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 14134 jit.move(params[1].gpr(), params[0].gpr()); 14135 jit.untagArrayPtr(params[2].gpr(), params[0].gpr()); 14136 }); 14137 return authenticate; 14138 #else 14139 UNUSED_PARAM(size); 14140 return ptr; 14141 #endif 14142 } 14143 14144 LValue removeArrayPtrTag(LValue ptr) 14145 { 14146 #if CPU(ARM64E) 14147 PatchpointValue* authenticate = m_out.patchpoint(pointerType()); 14148 authenticate->appendSomeRegister(ptr); 14149 authenticate->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 14150 jit.move(params[1].gpr(), params[0].gpr()); 14151 jit.removeArrayPtrTag(params[0].gpr()); 14152 }); 14153 return authenticate; 14154 #endif 14155 return ptr; 14156 } 14157 14158 LValue caged(Gigacage::Kind kind, LValue ptr, LValue base) 14111 14112 LValue caged(Gigacage::Kind kind, LValue ptr) 14159 14113 { 14160 14114 #if GIGACAGE_ENABLED 14161 UNUSED_PARAM(base);14162 14115 if (!Gigacage::isEnabled(kind)) 14163 14116 return ptr; … … 14188 14141 // https://bugs.webkit.org/show_bug.cgi?id=175493 14189 14142 return m_out.opaque(result); 14190 #elif CPU(ARM64E)14191 if (kind == Gigacage::Primitive) {14192 LValue size = m_out.load32(base, m_heaps.JSArrayBufferView_length);14193 return untagArrayPtr(ptr, size);14194 }14195 14196 return ptr;14197 14143 #else 14198 14144 UNUSED_PARAM(kind); 14199 UNUSED_PARAM(base);14200 14145 return ptr; 14201 14146 #endif … … 16611 16556 LBasicBlock lastNext = m_out.appendTo(isWasteful, continuation); 16612 16557 LValue vector = m_out.loadPtr(base, m_heaps.JSArrayBufferView_vector); 16613 // FIXME: We could probably make this a mask.16614 // https://bugs.webkit.org/show_bug.cgi?id=19770116615 vector = removeArrayPtrTag(vector);16616 16558 speculate(Uncountable, jsValueValue(vector), m_node, m_out.isZero64(vector)); 16617 16559 m_out.jump(continuation); -
trunk/Source/JavaScriptCore/heap/ConservativeRoots.cpp
r245168 r246322 69 69 inline void ConservativeRoots::genericAddPointer(void* p, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter filter, MarkHook& markHook) 70 70 { 71 p = removeArrayPtrTag(p);72 71 markHook.mark(p); 73 72 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h
r246240 r246322 1570 1570 } 1571 1571 1572 void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg scratch OrLength)1572 void cageConditionally(Gigacage::Kind kind, GPRReg storage, GPRReg scratch) 1573 1573 { 1574 1574 #if GIGACAGE_ENABLED … … 1579 1579 return cage(kind, storage); 1580 1580 1581 loadPtr(&Gigacage::basePtr(kind), scratch OrLength);1582 Jump done = branchTestPtr(Zero, scratch OrLength);1581 loadPtr(&Gigacage::basePtr(kind), scratch); 1582 Jump done = branchTestPtr(Zero, scratch); 1583 1583 andPtr(TrustedImmPtr(Gigacage::mask(kind)), storage); 1584 addPtr(scratch OrLength, storage);1584 addPtr(scratch, storage); 1585 1585 done.link(this); 1586 #elif CPU(ARM64E)1587 if (kind == Gigacage::Primitive)1588 untagArrayPtr(scratchOrLength, storage);1589 1586 #else 1590 1587 UNUSED_PARAM(kind); 1591 1588 UNUSED_PARAM(storage); 1592 UNUSED_PARAM(scratch OrLength);1589 UNUSED_PARAM(scratch); 1593 1590 #endif 1594 1591 } -
trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp
r245313 r246322 115 115 jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR); 116 116 jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), valueGPR); 117 #if CPU(ARM64E)118 jit.removeArrayPtrTag(valueGPR);119 #endif120 117 jit.loadPtr(MacroAssembler::Address(scratchGPR, Butterfly::offsetOfArrayBuffer()), scratchGPR); 121 118 jit.loadPtr(MacroAssembler::Address(scratchGPR, ArrayBuffer::offsetOfData()), scratchGPR); 122 #if CPU(ARM64E)123 jit.removeArrayPtrTag(scratchGPR);124 #endif125 119 jit.subPtr(scratchGPR, valueGPR); 126 120 -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r246240 r246322 1590 1590 slowCases.append(branch32(AboveOrEqual, property, scratch2)); 1591 1591 slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfMappedArguments()))); 1592 1592 1593 1593 loadValue(BaseIndex(base, property, TimesEight, DirectArguments::storageOffset()), result); 1594 1594 … … 1670 1670 load8(Address(base, JSCell::typeInfoTypeOffset()), scratch); 1671 1671 badType = patchableBranch32(NotEqual, scratch, TrustedImm32(typeForTypedArrayType(type))); 1672 load32(Address(base, JSArrayBufferView::offsetOfLength()), scratch2); 1673 slowCases.append(branch32(AboveOrEqual, property, scratch2)); 1672 slowCases.append(branch32(AboveOrEqual, property, Address(base, JSArrayBufferView::offsetOfLength()))); 1674 1673 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch); 1675 1674 cageConditionally(Gigacage::Primitive, scratch, scratch2); … … 1734 1733 load8(Address(base, JSCell::typeInfoTypeOffset()), scratch); 1735 1734 badType = patchableBranch32(NotEqual, scratch, TrustedImm32(typeForTypedArrayType(type))); 1736 load32(Address(base, JSArrayBufferView::offsetOfLength()), scratch2); 1737 slowCases.append(branch32(AboveOrEqual, property, scratch2)); 1735 slowCases.append(branch32(AboveOrEqual, property, Address(base, JSArrayBufferView::offsetOfLength()))); 1738 1736 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch); 1739 1737 cageConditionally(Gigacage::Primitive, scratch, scratch2); … … 1785 1783 load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); 1786 1784 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 1787 load32(Address(base, JSArrayBufferView::offsetOfLength()), lateScratch2); 1788 Jump inBounds = branch32(Below, property, lateScratch2); 1785 Jump inBounds = branch32(Below, property, Address(base, JSArrayBufferView::offsetOfLength())); 1789 1786 emitArrayProfileOutOfBoundsSpecialCase(profile); 1790 1787 slowCases.append(jump()); … … 1861 1858 load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); 1862 1859 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(typeForTypedArrayType(type))); 1863 load32(Address(base, JSArrayBufferView::offsetOfLength()), lateScratch2); 1864 Jump inBounds = branch32(Below, property, lateScratch2); 1860 Jump inBounds = branch32(Below, property, Address(base, JSArrayBufferView::offsetOfLength())); 1865 1861 emitArrayProfileOutOfBoundsSpecialCase(profile); 1866 1862 slowCases.append(jump()); -
trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp
r245064 r246322 58 58 void PolymorphicCallNode::clearCallLinkInfo() 59 59 { 60 if (Options::dumpDisassembly()) 61 dataLog("Clearing call link info for polymorphic call at ", m_callLinkInfo->callReturnLocation(), ", ", m_callLinkInfo->codeOrigin(), "\n"); 62 60 63 m_callLinkInfo = nullptr; 61 64 } -
trunk/Source/JavaScriptCore/jit/RegisterSet.h
r245432 r246322 85 85 set(regs.payloadGPR(), value); 86 86 } 87 88 void set(const RegisterSet& other, bool value = true) { value ? merge(other) : exclude(other); } 89 87 90 88 void clear(Reg reg) 91 89 { -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r246240 r246322 423 423 end 424 424 425 macro uncage(basePtr, mask, ptr, scratch OrLength)426 if GIGACAGE_ENABLED and not (C_LOOP or C_LOOP_WIN)427 loadp basePtr, scratch OrLength428 btpz scratch OrLength, .done425 macro uncage(basePtr, mask, ptr, scratch) 426 if GIGACAGE_ENABLED and not C_LOOP 427 loadp basePtr, scratch 428 btpz scratch, .done 429 429 andp mask, ptr 430 addp scratch OrLength, ptr431 .done:432 end 433 end 434 435 macro loadCaged Primitive(source, dest, scratchOrLength)430 addp scratch, ptr 431 .done: 432 end 433 end 434 435 macro loadCaged(basePtr, mask, source, dest, scratch) 436 436 loadp source, dest 437 if GIGACAGE_ENABLED 438 uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, dest, scratchOrLength) 439 elsif ARM64E 440 untagArrayPtr scratchOrLength, dest 441 end 442 end 443 444 macro loadCagedJSValue(source, dest, scratchOrLength) 445 loadp source, dest 446 uncage(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, dest, scratchOrLength) 447 end 437 uncage(basePtr, mask, dest, scratch) 438 end 448 439 449 440 macro loadVariable(get, fieldName, valueReg) … … 1345 1336 btiz t0, IsArray, .opGetByIdSlow 1346 1337 btiz t0, IndexingShapeMask, .opGetByIdSlow 1347 loadCaged JSValue(JSObject::m_butterfly[t3], t0, t1)1338 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t3], t0, t1) 1348 1339 loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0 1349 1340 bilt t0, 0, .opGetByIdSlow … … 1468 1459 sxi2q t1, t1 1469 1460 1470 loadCaged JSValue(JSObject::m_butterfly[t0], t3, tagTypeNumber)1461 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t0], t3, tagTypeNumber) 1471 1462 move TagTypeNumber, tagTypeNumber 1472 1463 … … 1512 1503 1513 1504 # Sweet, now we know that we have a typed array. Do some basic things now. 1514 1515 if ARM64E 1516 const scratchOrLength = t6 1517 loadi JSArrayBufferView::m_length[t0], scratchOrLength 1518 biaeq t1, scratchOrLength, .opGetByValSlow 1519 else 1520 const scratchOrLength = t0 1521 biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow 1522 end 1523 1524 loadCagedPrimitive(JSArrayBufferView::m_vector[t0], t3, scratchOrLength) 1505 biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow 1525 1506 1526 1507 # Now bisect through the various types: … … 1544 1525 1545 1526 # We have Int8ArrayType. 1527 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1546 1528 loadbsi [t3, t1], t0 1547 1529 finishIntGetByVal(t0, t1) … … 1551 1533 1552 1534 # We have Uint8ArrayType. 1535 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1553 1536 loadb [t3, t1], t0 1554 1537 finishIntGetByVal(t0, t1) … … 1556 1539 .opGetByValUint8ClampedArray: 1557 1540 # We have Uint8ClampedArrayType. 1541 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1558 1542 loadb [t3, t1], t0 1559 1543 finishIntGetByVal(t0, t1) … … 1564 1548 1565 1549 # We have Int16ArrayType. 1550 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1566 1551 loadhsi [t3, t1, 2], t0 1567 1552 finishIntGetByVal(t0, t1) … … 1569 1554 .opGetByValUint16Array: 1570 1555 # We have Uint16ArrayType. 1556 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1571 1557 loadh [t3, t1, 2], t0 1572 1558 finishIntGetByVal(t0, t1) … … 1580 1566 1581 1567 # We have Int32ArrayType. 1568 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1582 1569 loadi [t3, t1, 4], t0 1583 1570 finishIntGetByVal(t0, t1) … … 1585 1572 .opGetByValUint32Array: 1586 1573 # We have Uint32ArrayType. 1574 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1587 1575 # This is the hardest part because of large unsigned values. 1588 1576 loadi [t3, t1, 4], t0 … … 1596 1584 1597 1585 # We have Float64ArrayType. 1586 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2) 1598 1587 loadd [t3, t1, 8], ft0 1599 1588 bdnequn ft0, ft0, .opGetByValSlow … … 1631 1620 loadConstantOrVariableInt32(size, t0, t3, .opPutByValSlow) 1632 1621 sxi2q t3, t3 1633 loadCaged JSValue(JSObject::m_butterfly[t1], t0, tagTypeNumber)1622 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t1], t0, tagTypeNumber) 1634 1623 move TagTypeNumber, tagTypeNumber 1635 1624 btinz t2, CopyOnWrite, .opPutByValSlow -
trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp
r245622 r246322 34 34 namespace JSC { 35 35 36 SharedArrayBufferContents::SharedArrayBufferContents(void* data, unsigned size,ArrayBufferDestructorFunction&& destructor)37 : m_data(data , size)36 SharedArrayBufferContents::SharedArrayBufferContents(void* data, ArrayBufferDestructorFunction&& destructor) 37 : m_data(data) 38 38 , m_destructor(WTFMove(destructor)) 39 , m_sizeInBytes(size)40 39 { 41 40 } … … 43 42 SharedArrayBufferContents::~SharedArrayBufferContents() 44 43 { 45 // FIXME: we shouldn't use getUnsafe here https://bugs.webkit.org/show_bug.cgi?id=197698 46 m_destructor(m_data.getUnsafe()); 44 m_destructor(m_data.getMayBeNull()); 47 45 } 48 46 … … 59 57 60 58 ArrayBufferContents::ArrayBufferContents(void* data, unsigned sizeInBytes, ArrayBufferDestructorFunction&& destructor) 61 : m_data(data , sizeInBytes)59 : m_data(data) 62 60 , m_sizeInBytes(sizeInBytes) 63 61 { … … 85 83 void ArrayBufferContents::destroy() 86 84 { 87 // FIXME: We shouldn't use getUnsafe here: https://bugs.webkit.org/show_bug.cgi?id=197698 88 m_destructor(m_data.getUnsafe()); 85 m_destructor(m_data.getMayBeNull()); 89 86 } 90 87 … … 107 104 } 108 105 } 109 size_t sizeInBytes = static_cast<size_t>(numElements) * static_cast<size_t>(elementByteSize); 110 size_t allocationSize = sizeInBytes; 111 if (!allocationSize) 112 allocationSize = 1; // Make sure malloc actually allocates something, but not too much. We use null to mean that the buffer is neutered. 113 114 void* data = Gigacage::tryMalloc(Gigacage::Primitive, allocationSize); 115 m_data = DataType(data, sizeInBytes); 116 if (!data) { 106 size_t size = static_cast<size_t>(numElements) * static_cast<size_t>(elementByteSize); 107 if (!size) 108 size = 1; // Make sure malloc actually allocates something, but not too much. We use null to mean that the buffer is neutered. 109 m_data = Gigacage::tryMalloc(Gigacage::Primitive, size); 110 if (!m_data) { 117 111 reset(); 118 112 return; … … 120 114 121 115 if (policy == ZeroInitialize) 122 memset( data, 0, allocationSize);123 124 m_sizeInBytes = sizeInBytes;116 memset(m_data.get(), 0, size); 117 118 m_sizeInBytes = numElements * elementByteSize; 125 119 RELEASE_ASSERT(m_sizeInBytes <= MAX_ARRAY_BUFFER_SIZE); 126 120 m_destructor = [] (void* p) { Gigacage::free(Gigacage::Primitive, p); }; … … 129 123 void ArrayBufferContents::makeShared() 130 124 { 131 m_shared = adoptRef(new SharedArrayBufferContents( data(), sizeInBytes(), WTFMove(m_destructor)));125 m_shared = adoptRef(new SharedArrayBufferContents(m_data.getMayBeNull(), WTFMove(m_destructor))); 132 126 m_destructor = [] (void*) { }; 133 127 } … … 150 144 if (!other.m_data) 151 145 return; 152 memcpy(other. data(), data(), m_sizeInBytes);146 memcpy(other.m_data.get(), m_data.get(), m_sizeInBytes); 153 147 other.m_sizeInBytes = m_sizeInBytes; 154 148 RELEASE_ASSERT(other.m_sizeInBytes <= MAX_ARRAY_BUFFER_SIZE); -
trunk/Source/JavaScriptCore/runtime/ArrayBuffer.h
r245064 r246322 49 49 class SharedArrayBufferContents : public ThreadSafeRefCounted<SharedArrayBufferContents> { 50 50 public: 51 SharedArrayBufferContents(void* data, unsigned size,ArrayBufferDestructorFunction&&);51 SharedArrayBufferContents(void* data, ArrayBufferDestructorFunction&&); 52 52 ~SharedArrayBufferContents(); 53 53 54 void* data() const { return m_data.getMayBeNull( m_sizeInBytes); }54 void* data() const { return m_data.getMayBeNull(); } 55 55 56 56 private: 57 using DataType = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; 58 DataType m_data; 57 CagedPtr<Gigacage::Primitive, void> m_data; 59 58 ArrayBufferDestructorFunction m_destructor; 60 unsigned m_sizeInBytes;61 59 }; 62 60 … … 76 74 explicit operator bool() { return !!m_data; } 77 75 78 void* data() const { return m_data.getMayBeNull( sizeInBytes()); }76 void* data() const { return m_data.getMayBeNull(); } 79 77 unsigned sizeInBytes() const { return m_sizeInBytes; } 80 78 … … 101 99 ArrayBufferDestructorFunction m_destructor; 102 100 RefPtr<SharedArrayBufferContents> m_shared; 103 using DataType = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; 104 DataType m_data; 101 CagedPtr<Gigacage::Primitive, void> m_data; 105 102 unsigned m_sizeInBytes; 106 103 }; … … 178 175 void* ArrayBuffer::data() 179 176 { 180 return m_contents. data();177 return m_contents.m_data.getMayBeNull(); 181 178 } 182 179 183 180 const void* ArrayBuffer::data() const 184 181 { 185 return m_contents. data();182 return m_contents.m_data.getMayBeNull(); 186 183 } 187 184 188 185 unsigned ArrayBuffer::byteLength() const 189 186 { 190 return m_contents. sizeInBytes();187 return m_contents.m_sizeInBytes; 191 188 } 192 189 -
trunk/Source/JavaScriptCore/runtime/ArrayBufferView.cpp
r245064 r246322 26 26 #include "config.h" 27 27 #include "ArrayBufferView.h" 28 #include <wtf/CheckedArithmetic.h>29 28 30 29 namespace JSC { 31 30 32 31 ArrayBufferView::ArrayBufferView( 33 RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned byteLength) 32 RefPtr<ArrayBuffer>&& buffer, 33 unsigned byteOffset) 34 34 : m_byteOffset(byteOffset) 35 35 , m_isNeuterable(true) 36 , m_byteLength(byteLength)37 36 , m_buffer(WTFMove(buffer)) 38 37 { 39 Checked<unsigned, CrashOnOverflow> length(byteOffset); 40 length += byteLength; 41 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(length <= m_buffer->byteLength()); 42 if (m_buffer) 43 m_baseAddress = BaseAddress(static_cast<char*>(m_buffer->data()) + m_byteOffset, byteLength); 38 m_baseAddress = m_buffer ? (static_cast<char*>(m_buffer->data()) + m_byteOffset) : 0; 44 39 } 45 40 -
trunk/Source/JavaScriptCore/runtime/ArrayBufferView.h
r245064 r246322 72 72 { 73 73 if (isNeutered()) 74 return nullptr;75 return m_baseAddress.getMayBeNull( byteLength());74 return 0; 75 return m_baseAddress.getMayBeNull(); 76 76 } 77 77 … … 85 85 } 86 86 87 unsigned byteLength() const { return m_byteLength; }87 virtual unsigned byteLength() const = 0; 88 88 89 89 JS_EXPORT_PRIVATE void setNeuterable(bool flag); … … 114 114 115 115 protected: 116 JS_EXPORT_PRIVATE ArrayBufferView(RefPtr<ArrayBuffer>&&, unsigned byteOffset , unsigned byteLength);116 JS_EXPORT_PRIVATE ArrayBufferView(RefPtr<ArrayBuffer>&&, unsigned byteOffset); 117 117 118 118 inline bool setImpl(ArrayBufferView*, unsigned byteOffset); 119 119 120 inline bool setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset); 121 inline bool getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset); 120 // Caller passes in bufferByteLength to avoid a virtual function call. 121 inline bool setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength); 122 inline bool getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength); 122 123 123 124 inline bool zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength); … … 150 151 unsigned m_byteOffset : 31; 151 152 bool m_isNeuterable : 1; 152 unsigned m_byteLength; 153 154 using BaseAddress = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; 153 155 154 // This is the address of the ArrayBuffer's storage, plus the byte offset. 156 BaseAddressm_baseAddress;155 CagedPtr<Gigacage::Primitive, void> m_baseAddress; 157 156 158 157 private: … … 175 174 } 176 175 177 bool ArrayBufferView::setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset) 178 { 179 if (byteOffset > byteLength() 180 || byteOffset + dataByteLength > byteLength() 176 bool ArrayBufferView::setRangeImpl(const void* data, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength) 177 { 178 // Do not replace with RELEASE_ASSERT; we want to avoid the virtual byteLength() function call in release. 179 ASSERT_WITH_SECURITY_IMPLICATION(bufferByteLength == byteLength()); 180 if (byteOffset > bufferByteLength 181 || byteOffset + dataByteLength > bufferByteLength 181 182 || byteOffset + dataByteLength < byteOffset) { 182 183 // Out of range offset or overflow … … 189 190 } 190 191 191 bool ArrayBufferView::getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset) 192 { 193 if (byteOffset > byteLength() 194 || byteOffset + dataByteLength > byteLength() 192 bool ArrayBufferView::getRangeImpl(void* destination, size_t dataByteLength, unsigned byteOffset, unsigned bufferByteLength) 193 { 194 // Do not replace with RELEASE_ASSERT; we want to avoid the virtual byteLength() function call in release. 195 ASSERT_WITH_SECURITY_IMPLICATION(bufferByteLength == byteLength()); 196 if (byteOffset > bufferByteLength 197 || byteOffset + dataByteLength > bufferByteLength 195 198 || byteOffset + dataByteLength < byteOffset) { 196 199 // Out of range offset or overflow -
trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp
r246272 r246322 1089 1089 { 1090 1090 m_length = scopedArgumentsTable.m_length; 1091 m_arguments.encode(encoder, scopedArgumentsTable.m_arguments.get( m_length), m_length);1091 m_arguments.encode(encoder, scopedArgumentsTable.m_arguments.get(), m_length); 1092 1092 } 1093 1093 … … 1095 1095 { 1096 1096 ScopedArgumentsTable* scopedArgumentsTable = ScopedArgumentsTable::create(decoder.vm(), m_length); 1097 m_arguments.decode(decoder, scopedArgumentsTable->m_arguments.get( m_length), m_length);1097 m_arguments.decode(decoder, scopedArgumentsTable->m_arguments.get(), m_length); 1098 1098 return scopedArgumentsTable; 1099 1099 } -
trunk/Source/JavaScriptCore/runtime/CagedBarrierPtr.h
r245064 r246322 36 36 // This is a convenient combo of AuxiliaryBarrier and CagedPtr. 37 37 38 template<Gigacage::Kind passedKind, typename T , bool shouldTag = false>38 template<Gigacage::Kind passedKind, typename T> 39 39 class CagedBarrierPtr { 40 40 public: 41 41 static constexpr Gigacage::Kind kind = passedKind; 42 using Type = T; 43 using CagedType = CagedPtr<kind, Type, shouldTag>; 42 typedef T Type; 44 43 45 CagedBarrierPtr() = default;44 CagedBarrierPtr() { } 46 45 47 46 template<typename U> 48 CagedBarrierPtr(VM& vm, JSCell* cell, U&& value , unsigned size)47 CagedBarrierPtr(VM& vm, JSCell* cell, U&& value) 49 48 { 50 m_barrier.set(vm, cell, CagedType(std::forward<U>(value), size));49 m_barrier.set(vm, cell, std::forward<U>(value)); 51 50 } 52 51 … … 54 53 55 54 template<typename U> 56 void set(VM& vm, JSCell* cell, U&& value , unsigned size)55 void set(VM& vm, JSCell* cell, U&& value) 57 56 { 58 m_barrier.set(vm, cell, CagedType(std::forward<U>(value), size));57 m_barrier.set(vm, cell, std::forward<U>(value)); 59 58 } 60 59 61 T* get(unsigned size) const { return m_barrier.get().get(size); } 62 T* getMayBeNull(unsigned size) const { return m_barrier.get().getMayBeNull(size); } 63 T* getUnsafe() const { return m_barrier.get().getUnsafe(); } 64 65 // 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. 66 template<typename U = T> 67 typename std::enable_if<!std::is_same<void, U>::value, T>::type& 68 /* T& */ at(unsigned index, unsigned size) const { return get(size)[index]; } 69 60 T* get() const { return m_barrier.get().get(); } 61 T* getMayBeNull() const { return m_barrier.get().getMayBeNull(); } 62 70 63 bool operator==(const CagedBarrierPtr& other) const 71 64 { 72 return m_barrier.get() == other.m_barrier.get();65 return getMayBeNull() == other.getMayBeNull(); 73 66 } 74 67 … … 80 73 explicit operator bool() const 81 74 { 82 return !!m_barrier.get();75 return *this != CagedBarrierPtr(); 83 76 } 84 77 85 78 template<typename U> 86 void setWithoutBarrier(U&& value, unsigned size) { m_barrier.setWithoutBarrier(CagedType(std::forward<U>(value), size)); } 79 void setWithoutBarrier(U&& value) { m_barrier.setWithoutBarrier(std::forward<U>(value)); } 80 81 T& operator*() const { return *get(); } 82 T* operator->() const { return get(); } 83 84 template<typename IndexType> 85 T& operator[](IndexType index) const { return get()[index]; } 87 86 88 87 private: 89 AuxiliaryBarrier<CagedType> m_barrier; 88 AuxiliaryBarrier<CagedPtr<kind, T>> m_barrier; 89 }; 90 91 template<Gigacage::Kind passedKind> 92 class CagedBarrierPtr<passedKind, void> { 93 public: 94 static constexpr Gigacage::Kind kind = passedKind; 95 typedef void Type; 96 97 CagedBarrierPtr() { } 98 99 template<typename U> 100 CagedBarrierPtr(VM& vm, JSCell* cell, U&& value) 101 { 102 m_barrier.set(vm, cell, std::forward<U>(value)); 103 } 104 105 void clear() { m_barrier.clear(); } 106 107 template<typename U> 108 void set(VM& vm, JSCell* cell, U&& value) 109 { 110 m_barrier.set(vm, cell, std::forward<U>(value)); 111 } 112 113 void* get() const { return m_barrier.get().get(); } 114 void* getMayBeNull() const { return m_barrier.get().getMayBeNull(); } 115 116 bool operator==(const CagedBarrierPtr& other) const 117 { 118 return getMayBeNull() == other.getMayBeNull(); 119 } 120 121 bool operator!=(const CagedBarrierPtr& other) const 122 { 123 return !(*this == other); 124 } 125 126 explicit operator bool() const 127 { 128 return *this != CagedBarrierPtr(); 129 } 130 131 template<typename U> 132 void setWithoutBarrier(U&& value) { m_barrier.setWithoutBarrier(std::forward<U>(value)); } 133 134 private: 135 AuxiliaryBarrier<CagedPtr<kind, void>> m_barrier; 90 136 }; 91 137 -
trunk/Source/JavaScriptCore/runtime/DataView.cpp
r245064 r246322 34 34 35 35 DataView::DataView(RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned byteLength) 36 : ArrayBufferView(WTFMove(buffer), byteOffset, byteLength) 36 : ArrayBufferView(WTFMove(buffer), byteOffset) 37 , m_byteLength(byteLength) 37 38 { 38 39 } -
trunk/Source/JavaScriptCore/runtime/DataView.h
r245064 r246322 39 39 static Ref<DataView> create(RefPtr<ArrayBuffer>&&); 40 40 41 unsigned byteLength() const override 42 { 43 return m_byteLength; 44 } 45 41 46 TypedArrayType getType() const override 42 47 { … … 58 63 RELEASE_ASSERT(offset + sizeof(T) <= byteLength()); 59 64 return flipBytesIfLittleEndian( 60 *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get( byteLength())) + offset),65 *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get()) + offset), 61 66 littleEndian); 62 67 } … … 82 87 } else 83 88 RELEASE_ASSERT(offset + sizeof(T) <= byteLength()); 84 *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get( byteLength())) + offset) =89 *reinterpret_cast<T*>(static_cast<uint8_t*>(m_baseAddress.get()) + offset) = 85 90 flipBytesIfLittleEndian(value, littleEndian); 86 91 } 92 93 private: 94 unsigned m_byteLength; 87 95 }; 88 96 -
trunk/Source/JavaScriptCore/runtime/DirectArguments.cpp
r245064 r246322 102 102 103 103 if (thisObject->m_mappedArguments) 104 visitor.markAuxiliary(thisObject->m_mappedArguments.get( thisObject->internalLength()));104 visitor.markAuxiliary(thisObject->m_mappedArguments.get()); 105 105 GenericArguments<DirectArguments>::visitChildren(thisCell, visitor); 106 106 } … … 121 121 void* backingStore = vm.gigacageAuxiliarySpace(m_mappedArguments.kind).allocateNonVirtual(vm, mappedArgumentsSize(), nullptr, AllocationFailureMode::Assert); 122 122 bool* overrides = static_cast<bool*>(backingStore); 123 m_mappedArguments.set(vm, this, overrides , internalLength());124 for (unsigned i = internalLength(); i--;)123 m_mappedArguments.set(vm, this, overrides); 124 for (unsigned i = m_length; i--;) 125 125 overrides[i] = false; 126 126 } … … 135 135 { 136 136 overrideThingsIfNecessary(vm); 137 m_mappedArguments .at(index, internalLength())= true;137 m_mappedArguments[index] = true; 138 138 } 139 139 -
trunk/Source/JavaScriptCore/runtime/DirectArguments.h
r245064 r246322 87 87 bool isMappedArgument(uint32_t i) const 88 88 { 89 return i < m_length && (!m_mappedArguments || !m_mappedArguments .at(i, m_length));89 return i < m_length && (!m_mappedArguments || !m_mappedArguments[i]); 90 90 } 91 91 … … 183 183 uint32_t m_length; // Always the actual length of captured arguments and never what was stored into the length property. 184 184 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. 185 using MappedArguments = CagedBarrierPtr<Gigacage::Primitive, bool>; 186 MappedArguments m_mappedArguments; // If non-null, it means that length, callee, and caller are fully materialized properties. 185 CagedBarrierPtr<Gigacage::Primitive, bool> m_mappedArguments; // If non-null, it means that length, callee, and caller are fully materialized properties. 187 186 }; 188 187 -
trunk/Source/JavaScriptCore/runtime/GenericArguments.h
r245064 r246322 61 61 62 62 void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length); 63 64 using ModifiedArgumentsPtr = CagedBarrierPtr<Gigacage::Primitive, bool>; 65 ModifiedArgumentsPtr m_modifiedArgumentsDescriptor; 63 64 CagedBarrierPtr<Gigacage::Primitive, bool> m_modifiedArgumentsDescriptor; 66 65 }; 67 66 -
trunk/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h
r245064 r246322 39 39 40 40 if (thisObject->m_modifiedArgumentsDescriptor) 41 visitor.markAuxiliary(thisObject->m_modifiedArgumentsDescriptor.get Unsafe());41 visitor.markAuxiliary(thisObject->m_modifiedArgumentsDescriptor.get()); 42 42 } 43 43 … … 266 266 void* backingStore = vm.gigacageAuxiliarySpace(m_modifiedArgumentsDescriptor.kind).allocateNonVirtual(vm, WTF::roundUpToMultipleOf<8>(argsLength), nullptr, AllocationFailureMode::Assert); 267 267 bool* modifiedArguments = static_cast<bool*>(backingStore); 268 m_modifiedArgumentsDescriptor.set(vm, this, modifiedArguments , argsLength);268 m_modifiedArgumentsDescriptor.set(vm, this, modifiedArguments); 269 269 for (unsigned i = argsLength; i--;) 270 270 modifiedArguments[i] = false; … … 284 284 initModifiedArgumentsDescriptorIfNecessary(vm, length); 285 285 if (index < length) 286 m_modifiedArgumentsDescriptor .at(index, length)= true;286 m_modifiedArgumentsDescriptor[index] = true; 287 287 } 288 288 … … 293 293 return false; 294 294 if (index < length) 295 return m_modifiedArgumentsDescriptor .at(index, length);295 return m_modifiedArgumentsDescriptor[index]; 296 296 return false; 297 297 } -
trunk/Source/JavaScriptCore/runtime/GenericTypedArrayView.h
r245093 r246322 59 59 reinterpret_cast<const char*>(data), 60 60 count * sizeof(typename Adaptor::Type), 61 offset * sizeof(typename Adaptor::Type)); 61 offset * sizeof(typename Adaptor::Type), 62 internalByteLength()); 62 63 } 63 64 … … 73 74 if (isNeutered()) 74 75 return 0; 75 return byteLength() / sizeof(typename Adaptor::Type); 76 return m_length; 77 } 78 79 unsigned byteLength() const override 80 { 81 return internalByteLength(); 76 82 } 77 83 … … 99 105 reinterpret_cast<char*>(data), 100 106 count * sizeof(typename Adaptor::Type), 101 offset * sizeof(typename Adaptor::Type)); 107 offset * sizeof(typename Adaptor::Type), 108 internalByteLength()); 102 109 } 103 110 … … 120 127 121 128 JSArrayBufferView* wrap(ExecState*, JSGlobalObject*) override; 129 130 private: 131 unsigned internalByteLength() const 132 { 133 return length() * sizeof(typename Adaptor::Type); 134 } 135 136 unsigned m_length; 122 137 }; 123 138 -
trunk/Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h
r245064 r246322 33 33 template<typename Adaptor> 34 34 GenericTypedArrayView<Adaptor>::GenericTypedArrayView( 35 RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned length) 36 : ArrayBufferView(WTFMove(buffer), byteOffset, length * sizeof(typename Adaptor::Type)) 35 RefPtr<ArrayBuffer>&& buffer, unsigned byteOffset, unsigned length) 36 : ArrayBufferView(WTFMove(buffer), byteOffset) 37 , m_length(length) 37 38 { 38 39 } -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
r245064 r246322 1 1 /* 2 * Copyright (C) 2013-201 9Apple Inc. All rights reserved.2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 51 51 Structure* structure, uint32_t length, void* vector) 52 52 : m_structure(structure) 53 , m_vector(vector , length)53 , m_vector(vector) 54 54 , m_length(length) 55 55 , m_mode(FastTypedArray) 56 56 , m_butterfly(nullptr) 57 57 { 58 ASSERT(vector == removeArrayPtrTag(vector));59 58 RELEASE_ASSERT(length <= fastSizeLimit); 60 59 } … … 76 75 77 76 m_structure = structure; 78 m_vector = VectorType(temp, length);77 m_vector = temp; 79 78 m_mode = FastTypedArray; 80 79 81 80 if (mode == ZeroFill) { 82 uint64_t* asWords = static_cast<uint64_t*>( vector());81 uint64_t* asWords = static_cast<uint64_t*>(m_vector.getMayBeNull()); 83 82 for (unsigned i = size / sizeof(uint64_t); i--;) 84 83 asWords[i] = 0; … … 93 92 94 93 size_t size = static_cast<size_t>(length) * static_cast<size_t>(elementSize); 95 m_vector = VectorType(Gigacage::tryMalloc(Gigacage::Primitive, size), length);94 m_vector = Gigacage::tryMalloc(Gigacage::Primitive, size); 96 95 if (!m_vector) 97 96 return; 98 97 if (mode == ZeroFill) 99 memset( vector(), 0, size);98 memset(m_vector.get(), 0, size); 100 99 101 100 vm.heap.reportExtraMemoryAllocated(static_cast<size_t>(length) * elementSize); … … 112 111 , m_mode(WastefulTypedArray) 113 112 { 114 ASSERT(arrayBuffer->data() == removeArrayPtrTag(arrayBuffer->data())); 115 m_vector = VectorType(static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset, length); 113 m_vector = static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset; 116 114 IndexingHeader indexingHeader; 117 115 indexingHeader.setArrayBuffer(arrayBuffer.get()); … … 127 125 , m_butterfly(0) 128 126 { 129 ASSERT(arrayBuffer->data() == removeArrayPtrTag(arrayBuffer->data())); 130 m_vector = VectorType(static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset, length); 127 m_vector = static_cast<uint8_t*>(arrayBuffer->data()) + byteOffset; 131 128 } 132 129 … … 137 134 { 138 135 setButterfly(vm, context.butterfly()); 139 ASSERT(context.vector() == removeArrayPtrTag(context.vector())); 140 m_vector.setWithoutBarrier(context.vector(), m_length); 136 m_vector.setWithoutBarrier(context.vector()); 141 137 } 142 138 … … 199 195 ASSERT(thisObject->m_mode == OversizeTypedArray || thisObject->m_mode == WastefulTypedArray); 200 196 if (thisObject->m_mode == OversizeTypedArray) 201 Gigacage::free(Gigacage::Primitive, thisObject-> vector());197 Gigacage::free(Gigacage::Primitive, thisObject->m_vector.get()); 202 198 } 203 199 … … 288 284 auto locker = holdLock(cellLock()); 289 285 butterfly()->indexingHeader()->setArrayBuffer(buffer.get()); 290 m_vector.setWithoutBarrier(buffer->data() , m_length);286 m_vector.setWithoutBarrier(buffer->data()); 291 287 WTF::storeStoreFence(); 292 288 m_mode = WastefulTypedArray; -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.h
r245145 r246322 1 1 /* 2 * Copyright (C) 2013 -2019Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #include "AuxiliaryBarrier.h" 29 29 #include "JSObject.h" 30 #include <wtf/TaggedArrayStoragePtr.h>31 30 32 31 namespace JSC { … … 98 97 typedef JSNonFinalObject Base; 99 98 static const unsigned fastSizeLimit = 1000; 100 using VectorPtr = CagedBarrierPtr<Gigacage::Primitive, void, tagCagedPtr>;101 99 102 100 static size_t sizeOf(uint32_t length, uint32_t elementSize) … … 136 134 137 135 Structure* structure() const { return m_structure; } 138 void* vector() const { return m_vector.getMayBeNull( m_length); }136 void* vector() const { return m_vector.getMayBeNull(); } 139 137 uint32_t length() const { return m_length; } 140 138 TypedArrayMode mode() const { return m_mode; } … … 143 141 private: 144 142 Structure* m_structure; 145 using VectorType = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; 146 VectorType m_vector; 143 CagedPtr<Gigacage::Primitive, void> m_vector; 147 144 uint32_t m_length; 148 145 TypedArrayMode m_mode; … … 168 165 RefPtr<ArrayBufferView> unsharedImpl(); 169 166 JS_EXPORT_PRIVATE RefPtr<ArrayBufferView> possiblySharedImpl(); 170 bool isNeutered() { return hasArrayBuffer() && ! hasVector(); }167 bool isNeutered() { return hasArrayBuffer() && !vector(); } 171 168 void neuter(); 172 173 bool hasVector() const { return !!m_vector; } 174 void* vector() const { return m_vector.getMayBeNull(length()); } 169 170 void* vector() const { return m_vector.getMayBeNull(); } 175 171 176 172 unsigned byteOffset(); … … 196 192 static String toStringName(const JSObject*, ExecState*); 197 193 198 VectorPtrm_vector;194 CagedBarrierPtr<Gigacage::Primitive, void> m_vector; 199 195 uint32_t m_length; 200 196 TypedArrayMode m_mode; -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
r245064 r246322 78 78 79 79 template<typename Adaptor> 80 JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createUninitialized(ExecState* exec, Structure* structure, unsigned length) 80 JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createUninitialized( 81 ExecState* exec, Structure* structure, unsigned length) 81 82 { 82 83 VM& vm = exec->vm(); … … 507 508 if (thisObject->m_mode == OversizeTypedArray) 508 509 return Base::estimatedSize(thisObject, vm) + thisObject->byteSize(); 509 if (thisObject->m_mode == FastTypedArray && thisObject-> hasVector())510 if (thisObject->m_mode == FastTypedArray && thisObject->m_vector) 510 511 return Base::estimatedSize(thisObject, vm) + thisObject->byteSize(); 511 512 … … 526 527 auto locker = holdLock(thisObject->cellLock()); 527 528 mode = thisObject->m_mode; 528 vector = thisObject-> vector();529 vector = thisObject->m_vector.getMayBeNull(); 529 530 byteSize = thisObject->byteSize(); 530 531 } -
trunk/Source/JavaScriptCore/runtime/Options.h
r246272 r246322 493 493 v(unsigned, webAssemblyFunctionEntryDecrement, 1, Normal, "The amount the tier up countdown is decremented on each function entry.") \ 494 494 \ 495 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.") \ 495 /* FIXME: enable fast memories on iOS and pre-allocate them. https://bugs.webkit.org/show_bug.cgi?id=170774 */ \ 496 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.") \ 496 497 v(bool, logWebAssemblyMemory, false, Normal, nullptr) \ 497 498 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") \ -
trunk/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp
r245064 r246322 69 69 ScopedArgumentsTable* result = create(vm, m_length); 70 70 for (unsigned i = m_length; i--;) 71 result-> at(i) = this->at(i);71 result->m_arguments[i] = m_arguments[i]; 72 72 return result; 73 73 } … … 76 76 { 77 77 if (LIKELY(!m_locked)) { 78 ArgumentsPtr newArguments = ArgumentsPtr::create(newLength , newLength);78 ArgumentsPtr newArguments = ArgumentsPtr::create(newLength); 79 79 for (unsigned i = std::min(m_length, newLength); i--;) 80 newArguments .at(i, newLength) = this->at(i);80 newArguments[i] = m_arguments[i]; 81 81 m_length = newLength; 82 82 m_arguments = WTFMove(newArguments); … … 86 86 ScopedArgumentsTable* result = create(vm, newLength); 87 87 for (unsigned i = std::min(m_length, newLength); i--;) 88 result-> at(i) = this->at(i);88 result->m_arguments[i] = m_arguments[i]; 89 89 return result; 90 90 } 91 92 static_assert(std::is_trivially_destructible<ScopeOffset>::value, "");93 91 94 92 ScopedArgumentsTable* ScopedArgumentsTable::set(VM& vm, uint32_t i, ScopeOffset value) -
trunk/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h
r245064 r246322 62 62 ScopedArgumentsTable* setLength(VM&, uint32_t newLength); 63 63 64 ScopeOffset get(uint32_t i) const { return at(i); } 64 ScopeOffset get(uint32_t i) const 65 { 66 return const_cast<ScopedArgumentsTable*>(this)->at(i); 67 } 65 68 66 69 void lock() … … 78 81 static ptrdiff_t offsetOfArguments() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_arguments); } 79 82 80 typedef CagedUniquePtr<Gigacage::Primitive, ScopeOffset > ArgumentsPtr;83 typedef CagedUniquePtr<Gigacage::Primitive, ScopeOffset[]> ArgumentsPtr; 81 84 82 85 private: 83 ScopeOffset& at(uint32_t i) const86 ScopeOffset& at(uint32_t i) 84 87 { 85 88 ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); 86 return m_arguments .get(length())[i];89 return m_arguments[i]; 87 90 } 88 91 -
trunk/Source/JavaScriptCore/runtime/SymbolTable.h
r246073 r246322 637 637 { 638 638 if (UNLIKELY(!m_arguments)) 639 m_arguments.set(vm, this, ScopedArgumentsTable::create(vm, length)); 640 else 641 m_arguments.set(vm, this, m_arguments->setLength(vm, length)); 639 m_arguments.set(vm, this, ScopedArgumentsTable::create(vm)); 640 m_arguments.set(vm, this, m_arguments->setLength(vm, length)); 642 641 } 643 642 -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r246240 r246322 837 837 clobbers.set(pinnedRegs->baseMemoryPointer); 838 838 clobbers.set(pinnedRegs->sizeRegister); 839 if (!isARM64())840 clobbers.set(RegisterSet::macroScratchRegisters());841 839 842 840 auto* patchpoint = addPatchpoint(B3::Void); … … 846 844 patchpoint->effects = effects; 847 845 patchpoint->clobber(clobbers); 848 patchpoint->numGPScratchRegisters = Gigacage::isEnabled(Gigacage::Primitive) ? 1 : 0;849 846 850 847 patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 851 RELEASE_ASSERT(!Gigacage::isEnabled(Gigacage::Primitive) || !isARM64());852 AllowMacroScratchRegisterUsageIf allowScratch(jit, !isARM64());853 GPRReg baseMemory = pinnedRegs->baseMemoryPointer;854 GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;855 856 848 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister); 857 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 858 859 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize); 849 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), pinnedRegs->baseMemoryPointer); 860 850 }); 861 851 … … 1969 1959 patchpoint->clobber(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking)); 1970 1960 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 1971 patchpoint->numGPScratchRegisters = Gigacage::isEnabled(Gigacage::Primitive) ? 1 : 0;1972 1973 1961 patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 1974 1962 AllowMacroScratchRegisterUsage allowScratch(jit); … … 1984 1972 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 1985 1973 ASSERT(pinnedRegs.sizeRegister != newContextInstance); 1986 GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.sizeRegister;1987 1988 1974 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 1989 1975 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1990 1991 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);1992 1976 }); 1993 1977 -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r246240 r246322 48 48 #include "B3WasmAddressValue.h" 49 49 #include "B3WasmBoundsCheckValue.h" 50 #include "DisallowMacroScratchRegisterUsage.h"51 50 #include "JSCInlines.h" 52 51 #include "JSWebAssemblyInstance.h" … … 479 478 clobbers.set(pinnedRegs->baseMemoryPointer); 480 479 clobbers.set(pinnedRegs->sizeRegister); 481 if (!isARM64())482 clobbers.set(RegisterSet::macroScratchRegisters());483 480 484 481 B3::PatchpointValue* patchpoint = block->appendNew<B3::PatchpointValue>(proc, B3::Void, origin()); … … 488 485 patchpoint->effects = effects; 489 486 patchpoint->clobber(clobbers); 490 patchpoint->numGPScratchRegisters = Gigacage::isEnabled(Gigacage::Primitive) ? 1 : 0;491 487 492 488 patchpoint->append(instance, ValueRep::SomeRegister); 489 493 490 patchpoint->setGenerator([pinnedRegs] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 494 RELEASE_ASSERT(!Gigacage::isEnabled(Gigacage::Primitive) || !isARM64());495 AllowMacroScratchRegisterUsageIf allowScratch(jit, !isARM64());496 491 GPRReg baseMemory = pinnedRegs->baseMemoryPointer; 497 GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;498 499 492 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister); 500 493 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 501 502 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);503 494 }); 504 495 } … … 1381 1372 patchpoint->append(newContextInstance, ValueRep::SomeRegister); 1382 1373 patchpoint->append(instanceValue(), ValueRep::SomeRegister); 1383 patchpoint->numGPScratchRegisters = Gigacage::isEnabled(Gigacage::Primitive) ? 1 : 0;1384 1385 1374 patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 1386 1375 AllowMacroScratchRegisterUsage allowScratch(jit); … … 1397 1386 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 1398 1387 ASSERT(pinnedRegs.sizeRegister != newContextInstance); 1399 GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.sizeRegister;1400 1401 1388 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 1402 1389 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1403 1404 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);1405 1390 }); 1406 1391 doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation); -
trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp
r246034 r246322 315 315 316 316 m_wasmInternalFunctions[functionIndex]->entrypoint.compilation = std::make_unique<B3::Compilation>( 317 FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly BBQfunction[%i] %s", functionIndex, signature.toString().ascii().data()),317 FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly function[%i] %s", functionIndex, signature.toString().ascii().data()), 318 318 WTFMove(context.wasmEntrypointByproducts)); 319 319 } -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r246240 r246322 47 47 JIT jit; 48 48 49 GPRReg scratch = wasmCallingConventionAir().prologueScratch(0);49 GPRReg scratch = GPRInfo::nonPreservedNonArgumentGPR0; 50 50 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 51 51 ASSERT(baseMemory != scratch); … … 67 67 // FIXME the following code assumes that all Wasm::Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952 68 68 // Set up the callee's baseMemory register as well as the memory size registers. 69 { 70 GPRReg scratchOrSize = isARM64E() ? pinnedRegs.sizeRegister : wasmCallingConventionAir().prologueScratch(1); 71 72 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 73 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::TaggedArrayStoragePtr<void> (void*). 74 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize); 75 } 69 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size. 70 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::void*. 76 71 77 72 // Tail call into the callee WebAssembly function. -
trunk/Source/JavaScriptCore/wasm/WasmInstance.h
r245765 r246322 67 67 Table* table() { return m_table.get(); } 68 68 69 void* cachedMemory() const { return m_cachedMemory .getMayBeNull(cachedMemorySize()); }69 void* cachedMemory() const { return m_cachedMemory; } 70 70 size_t cachedMemorySize() const { return m_cachedMemorySize; } 71 71 … … 79 79 { 80 80 if (m_memory != nullptr) { 81 m_cachedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>(memory()->memory(), memory()->size());81 m_cachedMemory = memory()->memory(); 82 82 m_cachedMemorySize = memory()->size(); 83 83 } … … 148 148 void* m_owner { nullptr }; // In a JS embedding, this is a JSWebAssemblyInstance*. 149 149 Context* m_context { nullptr }; 150 CagedPtr<Gigacage::Primitive, void, tagCagedPtr> m_cachedMemory;150 void* m_cachedMemory { nullptr }; 151 151 size_t m_cachedMemorySize { 0 }; 152 152 Ref<Module> m_module; -
trunk/Source/JavaScriptCore/wasm/WasmMemory.cpp
r245432 r246322 254 254 ASSERT(m_mode == MemoryMode::BoundsChecking); 255 255 dataLogLnIf(verbose, "Memory::Memory allocating ", *this); 256 ASSERT(!memory());257 256 } 258 257 259 258 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) 260 : m_memory(memory , initial.bytes())259 : m_memory(memory) 261 260 , m_size(initial.bytes()) 262 261 , m_initial(initial) … … 340 339 switch (m_mode) { 341 340 case MemoryMode::Signaling: 342 if (mprotect(m emory(), Memory::fastMappedBytes(), PROT_READ | PROT_WRITE)) {341 if (mprotect(m_memory, Memory::fastMappedBytes(), PROT_READ | PROT_WRITE)) { 343 342 dataLog("mprotect failed: ", strerror(errno), "\n"); 344 343 RELEASE_ASSERT_NOT_REACHED(); 345 344 } 346 memoryManager().freeFastMemory(m emory());345 memoryManager().freeFastMemory(m_memory); 347 346 break; 348 347 case MemoryMode::BoundsChecking: 349 Gigacage::freeVirtualPages(Gigacage::Primitive, m emory(), m_size);348 Gigacage::freeVirtualPages(Gigacage::Primitive, m_memory, m_size); 350 349 break; 351 350 } … … 421 420 return makeUnexpected(GrowFailReason::OutOfMemory); 422 421 423 memcpy(newMemory, m emory(), m_size);422 memcpy(newMemory, m_memory, m_size); 424 423 if (m_memory) 425 Gigacage::freeVirtualPages(Gigacage::Primitive, m emory(), m_size);426 m_memory = CagedMemory(newMemory, desiredSize);424 Gigacage::freeVirtualPages(Gigacage::Primitive, m_memory, m_size); 425 m_memory = newMemory; 427 426 m_mappedCapacity = desiredSize; 428 427 m_size = desiredSize; 429 ASSERT(memory() == newMemory);430 428 return success(); 431 429 } 432 430 case MemoryMode::Signaling: { 433 RELEASE_ASSERT(m emory());431 RELEASE_ASSERT(m_memory); 434 432 // Signaling memory must have been pre-allocated virtually. 435 uint8_t* startAddress = static_cast<uint8_t*>(m emory()) + m_size;436 437 dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(m emory()), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")");433 uint8_t* startAddress = static_cast<uint8_t*>(m_memory) + m_size; 434 435 dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(m_memory), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")"); 438 436 if (mprotect(startAddress, extraBytes, PROT_READ | PROT_WRITE)) { 439 437 dataLog("mprotect failed: ", strerror(errno), "\n"); 440 438 RELEASE_ASSERT_NOT_REACHED(); 441 439 } 442 m_memory.recage(m_size, desiredSize);443 440 m_size = desiredSize; 444 441 return success(); … … 464 461 void Memory::dump(PrintStream& out) const 465 462 { 466 out.print("Memory at ", RawPointer(m emory()), ", size ", m_size, "B capacity ", m_mappedCapacity, "B, initial ", m_initial, " maximum ", m_maximum, " mode ", makeString(m_mode));463 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)); 467 464 } 468 465 -
trunk/Source/JavaScriptCore/wasm/WasmMemory.h
r245432 r246322 31 31 #include "WasmPageCount.h" 32 32 33 #include <wtf/CagedPtr.h>34 33 #include <wtf/Expected.h> 35 34 #include <wtf/Function.h> … … 70 69 static bool addressIsInActiveFastMemory(void*); 71 70 72 void* memory() const { ASSERT(m_memory.getMayBeNull(size()) == m_memory.getUnsafe()); return m_memory.getMayBeNull(size()); }71 void* memory() const { return m_memory; } 73 72 size_t size() const { return m_size; } 74 73 PageCount sizeInPages() const { return PageCount::fromBytes(m_size); } … … 98 97 Memory(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback); 99 98 100 using CagedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>; 101 CagedMemory m_memory; 99 void* m_memory { nullptr }; 102 100 size_t m_size { 0 }; 103 101 PageCount m_initial; -
trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp
r246240 r246322 30 30 31 31 #include "CCallHelpers.h" 32 #include "DisallowMacroScratchRegisterUsage.h"33 32 #include "JSCInlines.h" 34 33 #include "JSWebAssemblyInstance.h" … … 213 212 if (!!info.memory) { 214 213 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 215 GPRReg scratchOrSize = wasmCallingConventionAir().prologueScratch(0);216 214 217 215 if (Context::useFastTLS()) … … 219 217 220 218 GPRReg currentInstanceGPR = Context::useFastTLS() ? baseMemory : wasmContextInstanceGPR; 221 if (isARM64E()) { 222 if (mode != Wasm::MemoryMode::Signaling) 223 scratchOrSize = pinnedRegs.sizeRegister; 224 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), scratchOrSize); 225 } else { 226 if (mode != Wasm::MemoryMode::Signaling) 227 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); 228 } 219 if (mode != MemoryMode::Signaling) 220 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); 229 221 230 222 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 231 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);232 223 } 233 224 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r246240 r246322 411 411 if (!!moduleInformation.memory) { 412 412 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 413 GPRReg scratchOrSize = scratch2GPR; 414 auto mode = instance()->memoryMode(); 415 416 if (isARM64E()) { 417 if (mode != Wasm::MemoryMode::Signaling) 418 scratchOrSize = pinnedRegs.sizeRegister; 419 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), scratchOrSize); 420 } else { 421 if (mode != Wasm::MemoryMode::Signaling) 422 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); 413 414 if (instance()->memoryMode() != Wasm::MemoryMode::Signaling) { 415 ASSERT(pinnedRegs.sizeRegister != scratchGPR); 416 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); 423 417 } 424 418 425 419 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 426 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize);427 420 } 428 421 -
trunk/Source/WTF/ChangeLog
r246300 r246322 1 2019-06-11 Saam Barati <sbarati@apple.com> 2 3 Roll out PAC cage 4 https://bugs.webkit.org/show_bug.cgi?id=198726 5 6 Reviewed by Keith Miller. 7 8 * WTF.xcodeproj/project.pbxproj: 9 * wtf/CMakeLists.txt: 10 * wtf/CagedPtr.h: 11 (WTF::CagedPtr::CagedPtr): 12 (WTF::CagedPtr::get const): 13 (WTF::CagedPtr::getMayBeNull const): 14 (WTF::CagedPtr::operator=): 15 (WTF::CagedPtr::operator== const): 16 (WTF::CagedPtr::operator!= const): 17 (WTF::CagedPtr::operator bool const): 18 (WTF::CagedPtr::operator* const): 19 (WTF::CagedPtr::operator-> const): 20 (WTF::CagedPtr::operator[] const): 21 (WTF::CagedPtr::getUnsafe const): Deleted. 22 (WTF::CagedPtr::at const): Deleted. 23 (WTF::CagedPtr::recage): Deleted. 24 * wtf/CagedUniquePtr.h: 25 (WTF::CagedUniquePtr::CagedUniquePtr): 26 (WTF::CagedUniquePtr::create): 27 (WTF::CagedUniquePtr::operator=): 28 (WTF::CagedUniquePtr::~CagedUniquePtr): 29 (WTF::CagedUniquePtr::destroy): 30 * wtf/Gigacage.h: 31 (Gigacage::caged): 32 (Gigacage::cagedMayBeNull): Deleted. 33 * wtf/PtrTag.h: 34 (WTF::tagArrayPtr): Deleted. 35 (WTF::untagArrayPtr): Deleted. 36 (WTF::removeArrayPtrTag): Deleted. 37 (WTF::retagArrayPtr): Deleted. 38 * wtf/TaggedArrayStoragePtr.h: 39 (WTF::TaggedArrayStoragePtr::TaggedArrayStoragePtr): Deleted. 40 (WTF::TaggedArrayStoragePtr::get const): Deleted. 41 (WTF::TaggedArrayStoragePtr::getUnsafe const): Deleted. 42 (WTF::TaggedArrayStoragePtr::resize): Deleted. 43 (WTF::TaggedArrayStoragePtr::operator bool const): Deleted. 44 1 45 2019-06-10 Andy Estes <aestes@apple.com> 2 46 -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r245564 r246322 652 652 DCEE21FD1CEA7551000C2396 /* BlockObjCExceptions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockObjCExceptions.mm; sourceTree = "<group>"; }; 653 653 DCEE22041CEB9869000C2396 /* BackwardsGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackwardsGraph.h; sourceTree = "<group>"; }; 654 DEF7FE5F22581AC800C15129 /* TaggedArrayStoragePtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaggedArrayStoragePtr.h; sourceTree = "<group>"; };655 654 E15556F318A0CC18006F48FB /* CryptographicUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptographicUtilities.cpp; sourceTree = "<group>"; }; 656 655 E15556F418A0CC18006F48FB /* CryptographicUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptographicUtilities.h; sourceTree = "<group>"; }; … … 1159 1158 E3E158251EADA53C004A079D /* SystemFree.h */, 1160 1159 0FB317C31C488001007E395A /* SystemTracing.h */, 1161 DEF7FE5F22581AC800C15129 /* TaggedArrayStoragePtr.h */,1162 1160 E311FB151F0A568B003C08DE /* ThreadGroup.cpp */, 1163 1161 E311FB161F0A568B003C08DE /* ThreadGroup.h */, -
trunk/Source/WTF/wtf/CMakeLists.txt
r245968 r246322 231 231 SystemFree.h 232 232 SystemTracing.h 233 TaggedArrayStoragePtr.h234 233 ThreadGroup.h 235 234 ThreadMessage.h -
trunk/Source/WTF/wtf/CagedPtr.h
r246038 r246322 28 28 #include <wtf/DumbPtrTraits.h> 29 29 #include <wtf/Gigacage.h> 30 #include <wtf/PtrTag.h>31 30 32 31 namespace WTF { 33 32 34 constexpr bool tagCagedPtr = true; 35 36 template<Gigacage::Kind passedKind, typename T, bool shouldTag = false, typename PtrTraits = DumbPtrTraits<T>> 33 template<Gigacage::Kind passedKind, typename T, typename PtrTraits = DumbPtrTraits<T>> 37 34 class CagedPtr { 38 35 public: … … 40 37 41 38 CagedPtr() : CagedPtr(nullptr) { } 42 CagedPtr(std::nullptr_t) 43 : m_ptr(shouldTag ? tagArrayPtr<T>(nullptr, 0) : nullptr) 44 { } 39 CagedPtr(std::nullptr_t) : m_ptr(nullptr) { } 45 40 46 CagedPtr(T* ptr, unsigned size)47 : m_ptr( shouldTag ? tagArrayPtr(ptr, size) :ptr)48 { }49 50 51 T* get( unsigned size) const41 explicit CagedPtr(T* ptr) 42 : m_ptr(ptr) 43 { 44 } 45 46 T* get() const 52 47 { 53 48 ASSERT(m_ptr); 54 T* ptr = PtrTraits::unwrap(m_ptr); 55 if (shouldTag) 56 ptr = untagArrayPtr(ptr, size); 57 return Gigacage::caged(kind, ptr); 49 return Gigacage::caged(kind, PtrTraits::unwrap(m_ptr)); 50 } 51 52 T* getMayBeNull() const 53 { 54 if (!m_ptr) 55 return nullptr; 56 return get(); 58 57 } 59 58 60 T* getMayBeNull(unsigned size) const59 CagedPtr& operator=(T* ptr) 61 60 { 62 T* ptr = PtrTraits::unwrap(m_ptr); 63 if (shouldTag) 64 ptr = untagArrayPtr(ptr, size); 65 return Gigacage::cagedMayBeNull(kind, ptr); 66 } 67 68 T* getUnsafe() const 69 { 70 T* ptr = PtrTraits::unwrap(m_ptr); 71 if (shouldTag) 72 ptr = removeArrayPtrTag(ptr); 73 return Gigacage::cagedMayBeNull(kind, ptr); 74 } 75 76 // 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. 77 template<typename U = T> 78 typename std::enable_if<!std::is_same<void, U>::value, T>::type& 79 /* T& */ at(unsigned index, unsigned size) const { return get(size)[index]; } 80 81 void recage(unsigned oldSize, unsigned newSize) 82 { 83 auto ptr = get(oldSize); 84 ASSERT(ptr == getUnsafe()); 85 *this = CagedPtr(ptr, newSize); 86 } 87 88 CagedPtr(CagedPtr& other) 89 : m_ptr(other.m_ptr) 90 { 91 } 92 93 CagedPtr& operator=(const CagedPtr& ptr) 94 { 95 m_ptr = ptr.m_ptr; 61 m_ptr = ptr; 96 62 return *this; 97 63 } 98 64 99 CagedPtr(CagedPtr&& other) 100 : m_ptr(PtrTraits::exchange(other.m_ptr, nullptr)) 65 CagedPtr& operator=(T*&& ptr) 101 66 { 102 } 103 104 CagedPtr& operator=(CagedPtr&& ptr) 105 { 106 m_ptr = PtrTraits::exchange(ptr.m_ptr, nullptr); 67 m_ptr = WTFMove(ptr); 107 68 return *this; 108 69 } … … 110 71 bool operator==(const CagedPtr& other) const 111 72 { 112 bool result = m_ptr == other.m_ptr; 113 ASSERT(result == (getUnsafe() == other.getUnsafe())); 114 return result; 73 return getMayBeNull() == other.getMayBeNull(); 115 74 } 116 75 … … 122 81 explicit operator bool() const 123 82 { 124 return getUnsafe() != nullptr; 83 return *this != CagedPtr(); 84 } 85 86 T& operator*() const { return *get(); } 87 T* operator->() const { return get(); } 88 89 template<typename IndexType> 90 T& operator[](IndexType index) const { return get()[index]; } 91 92 protected: 93 typename PtrTraits::StorageType m_ptr; 94 }; 95 96 template<Gigacage::Kind passedKind, typename PtrTraits> 97 class CagedPtr<passedKind, void, PtrTraits> { 98 public: 99 static constexpr Gigacage::Kind kind = passedKind; 100 101 CagedPtr() : CagedPtr(nullptr) { } 102 CagedPtr(std::nullptr_t) : m_ptr(nullptr) { } 103 104 explicit CagedPtr(void* ptr) 105 : m_ptr(ptr) 106 { 107 } 108 109 void* get() const 110 { 111 ASSERT(m_ptr); 112 return Gigacage::caged(kind, PtrTraits::unwrap(m_ptr)); 113 } 114 115 void* getMayBeNull() const 116 { 117 if (!m_ptr) 118 return nullptr; 119 return get(); 120 } 121 122 CagedPtr& operator=(void* ptr) 123 { 124 m_ptr = ptr; 125 return *this; 126 } 127 128 bool operator==(const CagedPtr& other) const 129 { 130 return getMayBeNull() == other.getMayBeNull(); 131 } 132 133 bool operator!=(const CagedPtr& other) const 134 { 135 return !(*this == other); 136 } 137 138 explicit operator bool() const 139 { 140 return *this != CagedPtr(); 125 141 } 126 142 … … 132 148 133 149 using WTF::CagedPtr; 134 using WTF::tagCagedPtr;135 150 -
trunk/Source/WTF/wtf/CagedUniquePtr.h
r245064 r246322 30 30 namespace WTF { 31 31 32 template<Gigacage::Kind kind, typename T, bool shouldTag = false> 33 class CagedUniquePtr : public CagedPtr<kind, T, shouldTag> { 34 static_assert(std::is_trivially_destructible<T>::value, "We expect the contents of a caged pointer to be trivially destructable."); 32 template<Gigacage::Kind kind, typename T, typename Enable = void> 33 class CagedUniquePtr : public CagedPtr<kind, T> { 35 34 public: 36 using Base = CagedPtr<kind, T, shouldTag>; 37 CagedUniquePtr() = default; 38 39 CagedUniquePtr(T* ptr, unsigned size) 40 : Base(ptr, size) 41 { } 42 35 CagedUniquePtr(T* ptr = nullptr) 36 : CagedPtr<kind, T>(ptr) 37 { 38 } 39 43 40 CagedUniquePtr(CagedUniquePtr&& ptr) 44 : Base(std::forward<CagedUniquePtr&&>(ptr)) 45 { } 41 : CagedPtr<kind, T>(ptr.m_ptr) 42 { 43 ptr.m_ptr = nullptr; 44 } 46 45 47 46 CagedUniquePtr(const CagedUniquePtr&) = delete; 48 47 49 48 template<typename... Arguments> 50 static CagedUniquePtr create(unsigned length, Arguments&&... arguments) 51 { 52 T* result = static_cast<T*>(Gigacage::malloc(kind, sizeof(T) * length)); 53 while (length--) 54 new (result + length) T(arguments...); 55 return CagedUniquePtr(result, length); 49 static CagedUniquePtr create(Arguments&&... arguments) 50 { 51 T* result = static_cast<T*>(Gigacage::malloc(kind, sizeof(T))); 52 new (result) T(std::forward<Arguments>(arguments)...); 53 return CagedUniquePtr(result); 56 54 } 57 55 … … 70 68 destroy(); 71 69 } 72 70 73 71 private: 74 72 void destroy() 75 73 { 76 T* ptr = Base::getUnsafe(); 77 if (!ptr) 74 if (!this->m_ptr) 78 75 return; 79 ptr->~T();80 Gigacage::free(kind, ptr);76 this->m_ptr->~T(); 77 Gigacage::free(kind, this->m_ptr); 81 78 } 82 79 }; 83 80 81 template<Gigacage::Kind kind, typename T> 82 class CagedUniquePtr<kind, T[], typename std::enable_if<std::is_trivially_destructible<T>::value>::type> : public CagedPtr<kind, T> { 83 public: 84 CagedUniquePtr() : CagedPtr<kind, T>() { } 85 86 CagedUniquePtr(T* ptr) 87 : CagedPtr<kind, T>(ptr) 88 { 89 } 90 91 CagedUniquePtr(CagedUniquePtr&& ptr) 92 : CagedPtr<kind, T>(ptr.m_ptr) 93 { 94 ptr.m_ptr = nullptr; 95 } 96 97 CagedUniquePtr(const CagedUniquePtr&) = delete; 98 99 template<typename... Arguments> 100 static CagedUniquePtr create(size_t count, Arguments&&... arguments) 101 { 102 T* result = static_cast<T*>(Gigacage::mallocArray(kind, count, sizeof(T))); 103 while (count--) 104 new (result + count) T(std::forward<Arguments>(arguments)...); 105 return CagedUniquePtr(result); 106 } 107 108 CagedUniquePtr& operator=(CagedUniquePtr&& ptr) 109 { 110 destroy(); 111 this->m_ptr = ptr.m_ptr; 112 ptr.m_ptr = nullptr; 113 return *this; 114 } 115 116 CagedUniquePtr& operator=(const CagedUniquePtr&) = delete; 117 118 ~CagedUniquePtr() 119 { 120 destroy(); 121 } 122 123 private: 124 void destroy() 125 { 126 if (!this->m_ptr) 127 return; 128 Gigacage::free(kind, this->m_ptr); 129 } 130 }; 131 132 template<Gigacage::Kind kind, typename T> 133 class CagedUniquePtr<kind, T[], typename std::enable_if<!std::is_trivially_destructible<T>::value>::type> : public CagedPtr<kind, T> { 134 public: 135 CagedUniquePtr() : CagedPtr<kind, T>() { } 136 137 CagedUniquePtr(T* ptr, size_t count) 138 : CagedPtr<kind, T>(ptr) 139 , m_count(count) 140 { 141 } 142 143 CagedUniquePtr(CagedUniquePtr&& ptr) 144 : CagedPtr<kind, T>(ptr.m_ptr) 145 , m_count(ptr.m_count) 146 { 147 ptr.clear(); 148 } 149 150 CagedUniquePtr(const CagedUniquePtr&) = delete; 151 152 template<typename... Arguments> 153 static CagedUniquePtr create(size_t count, Arguments&&... arguments) 154 { 155 T* result = static_cast<T*>(Gigacage::mallocArray(kind, count, sizeof(T))); 156 while (count--) 157 new (result + count) T(std::forward<Arguments>(arguments)...); 158 return CagedUniquePtr(result, count); 159 } 160 161 CagedUniquePtr& operator=(CagedUniquePtr&& ptr) 162 { 163 destroy(); 164 this->m_ptr = ptr.m_ptr; 165 m_count = ptr.m_count; 166 ptr.clear(); 167 return *this; 168 } 169 170 CagedUniquePtr& operator=(const CagedUniquePtr&) = delete; 171 172 ~CagedUniquePtr() 173 { 174 destroy(); 175 } 176 177 // FIXME: It's weird that we inherit CagedPtr::operator== and friends, which don't do anything 178 // about m_count. It "works" because pointer equality is enough so long as everything is sane, but 179 // it seems like a missed opportunity to assert things. 180 // https://bugs.webkit.org/show_bug.cgi?id=175541 181 182 private: 183 void destroy() 184 { 185 if (!this->m_ptr) 186 return; 187 while (m_count--) 188 this->m_ptr[m_count].~T(); 189 Gigacage::free(kind, this->m_ptr); 190 } 191 192 void clear() 193 { 194 this->m_ptr = nullptr; 195 m_count = 0; 196 } 197 198 size_t m_count { 0 }; 199 }; 200 84 201 } // namespace WTF 85 202 -
trunk/Source/WTF/wtf/Gigacage.h
r245064 r246322 115 115 template<typename T> 116 116 inline T* caged(Kind, T* ptr) { return ptr; } 117 template<typename T>118 inline T* cagedMayBeNull(Kind, T* ptr) { return ptr; }119 117 120 118 inline bool isCaged(Kind, const void*) { return false; } -
trunk/Source/WTF/wtf/PtrTag.h
r245325 r246322 123 123 124 124 125 template<typename T>126 inline T* tagArrayPtr(std::nullptr_t ptr, size_t length)127 {128 ASSERT(!length);129 return ptrauth_sign_unauthenticated(static_cast<T*>(ptr), ptrauth_key_process_dependent_data, length);130 }131 132 133 template<typename T>134 inline T* tagArrayPtr(T* ptr, size_t length)135 {136 return ptrauth_sign_unauthenticated(ptr, ptrauth_key_process_dependent_data, length);137 }138 139 template<typename T>140 inline T* untagArrayPtr(T* ptr, size_t length)141 {142 return ptrauth_auth_data(ptr, ptrauth_key_process_dependent_data, length);143 }144 145 template<typename T>146 inline T* removeArrayPtrTag(T* ptr)147 {148 return ptrauth_strip(ptr, ptrauth_key_process_dependent_data);149 }150 151 template<typename T>152 inline T* retagArrayPtr(T* ptr, size_t oldLength, size_t newLength)153 {154 return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_data, oldLength, ptrauth_key_process_dependent_data, newLength);155 }156 157 125 template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>> 158 126 inline constexpr T removeCodePtrTag(PtrType ptr) … … 428 396 inline void reportBadTag(const void*, PtrTag) { } 429 397 430 template<typename T>431 inline T* tagArrayPtr(std::nullptr_t, size_t size)432 {433 ASSERT_UNUSED(size, !size);434 return nullptr;435 }436 437 template<typename T>438 inline T* tagArrayPtr(T* ptr, size_t)439 {440 return ptr;441 }442 443 template<typename T>444 inline T* untagArrayPtr(T* ptr, size_t)445 {446 return ptr;447 }448 449 template<typename T>450 inline T* removeArrayPtrTag(T* ptr)451 {452 return ptr;453 }454 455 template<typename T>456 inline T* retagArrayPtr(T* ptr, size_t, size_t)457 {458 return ptr;459 }460 461 462 398 template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>> 463 399 constexpr T tagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); } … … 558 494 559 495 using WTF::reportBadTag; 560 561 using WTF::tagArrayPtr;562 using WTF::untagArrayPtr;563 using WTF::retagArrayPtr;564 using WTF::removeArrayPtrTag;565 496 566 497 using WTF::tagCodePtr; -
trunk/Source/bmalloc/ChangeLog
r246240 r246322 1 2019-06-11 Saam Barati <sbarati@apple.com> 2 3 Roll out PAC cage 4 https://bugs.webkit.org/show_bug.cgi?id=198726 5 6 Reviewed by Keith Miller. 7 8 * bmalloc/Gigacage.h: 9 (Gigacage::isEnabled): 10 (Gigacage::caged): 11 (Gigacage::cagedMayBeNull): Deleted. 12 1 13 2019-06-09 Commit Queue <commit-queue@webkit.org> 2 14 -
trunk/Source/bmalloc/bmalloc/Gigacage.h
r246240 r246322 35 35 #include <inttypes.h> 36 36 37 #if ((BOS(DARWIN) || BOS(LINUX)) && BCPU(X86_64)) 37 #if ((BOS(DARWIN) || BOS(LINUX)) && \ 38 (BCPU(X86_64) || (BCPU(ARM64) && !defined(__ILP32__) && (!BPLATFORM(IOS_FAMILY) || BPLATFORM(IOS))))) 38 39 #define GIGACAGE_ENABLED 1 39 40 #else … … 200 201 } 201 202 202 template<typename T>203 BINLINE T* cagedMayBeNull(Kind kind, T* ptr)204 {205 if (!ptr)206 return ptr;207 return caged(kind, ptr);208 }209 210 203 BINLINE bool isCaged(Kind kind, const void* ptr) 211 204 { … … 227 220 BINLINE bool wasEnabled() { return false; } 228 221 BINLINE bool isCaged(Kind, const void*) { return true; } 229 BINLINE bool isEnabled( Kind) { return false; }222 BINLINE bool isEnabled() { return false; } 230 223 template<typename T> BINLINE T* caged(Kind, T* ptr) { return ptr; } 231 template<typename T> BINLINE T* cagedMayBeNull(Kind, T* ptr) { return ptr; }232 224 BINLINE void disableDisablingPrimitiveGigacageIfShouldBeEnabled() { } 233 225 BINLINE bool canPrimitiveGigacageBeDisabled() { return false; }
Note: See TracChangeset
for help on using the changeset viewer.