diff options
Diffstat (limited to 'js/src/jit/MacroAssembler.h')
-rw-r--r-- | js/src/jit/MacroAssembler.h | 247 |
1 files changed, 159 insertions, 88 deletions
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 43974a6ccc..361de3ac5f 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -13,6 +13,8 @@ #include "mozilla/Maybe.h" #include "mozilla/Variant.h" +#include <utility> + #if defined(JS_CODEGEN_X86) # include "jit/x86/MacroAssembler-x86.h" #elif defined(JS_CODEGEN_X64) @@ -1784,6 +1786,21 @@ class MacroAssembler : public MacroAssemblerSpecific { Register scratch, Register spectreRegToZero, Label* label); + private: + inline void branchTestClass(Condition cond, Register clasp, + std::pair<const JSClass*, const JSClass*> classes, + Label* label); + + public: + inline void branchTestObjClass( + Condition cond, Register obj, + std::pair<const JSClass*, const JSClass*> classes, Register scratch, + Register spectreRegToZero, Label* label); + inline void branchTestObjClassNoSpectreMitigations( + Condition cond, Register obj, + std::pair<const JSClass*, const JSClass*> classes, Register scratch, + Label* label); + inline void branchTestObjShape(Condition cond, Register obj, const Shape* shape, Register scratch, Register spectreRegToZero, Label* label); @@ -4191,23 +4208,23 @@ class MacroAssembler : public MacroAssemblerSpecific { // MIPS: `valueTemp`, `offsetTemp` and `maskTemp` must be defined for 8-bit // and 16-bit wide operations. - void compareExchange(Scalar::Type type, const Synchronization& sync, + void compareExchange(Scalar::Type type, Synchronization sync, const Address& mem, Register expected, Register replacement, Register output) DEFINED_ON(arm, arm64, x86_shared); - void compareExchange(Scalar::Type type, const Synchronization& sync, + void compareExchange(Scalar::Type type, Synchronization sync, const BaseIndex& mem, Register expected, Register replacement, Register output) DEFINED_ON(arm, arm64, x86_shared); - void compareExchange(Scalar::Type type, const Synchronization& sync, + void compareExchange(Scalar::Type type, Synchronization sync, const Address& mem, Register expected, Register replacement, Register valueTemp, Register offsetTemp, Register maskTemp, Register output) DEFINED_ON(mips_shared, loong64, riscv64); - void compareExchange(Scalar::Type type, const Synchronization& sync, + void compareExchange(Scalar::Type type, Synchronization sync, const BaseIndex& mem, Register expected, Register replacement, Register valueTemp, Register offsetTemp, Register maskTemp, Register output) @@ -4218,12 +4235,12 @@ class MacroAssembler : public MacroAssemblerSpecific { // ARM: Registers must be distinct; `replacement` and `output` must be // (even,odd) pairs. - void compareExchange64(const Synchronization& sync, const Address& mem, + void compareExchange64(Synchronization sync, const Address& mem, Register64 expected, Register64 replacement, Register64 output) DEFINED_ON(arm, arm64, x64, x86, mips64, loong64, riscv64); - void compareExchange64(const Synchronization& sync, const BaseIndex& mem, + void compareExchange64(Synchronization sync, const BaseIndex& mem, Register64 expected, Register64 replacement, Register64 output) DEFINED_ON(arm, arm64, x64, x86, mips64, loong64, riscv64); @@ -4232,20 +4249,20 @@ class MacroAssembler : public MacroAssemblerSpecific { // MIPS: `valueTemp`, `offsetTemp` and `maskTemp` must be defined for 8-bit // and 16-bit wide operations. - void atomicExchange(Scalar::Type type, const Synchronization& sync, + void atomicExchange(Scalar::Type type, Synchronization sync, const Address& mem, Register value, Register output) DEFINED_ON(arm, arm64, x86_shared); - void atomicExchange(Scalar::Type type, const Synchronization& sync, + void atomicExchange(Scalar::Type type, Synchronization sync, const BaseIndex& mem, Register value, Register output) DEFINED_ON(arm, arm64, x86_shared); - void atomicExchange(Scalar::Type type, const Synchronization& sync, + void atomicExchange(Scalar::Type type, Synchronization sync, const Address& mem, Register value, Register valueTemp, Register offsetTemp, Register maskTemp, Register output) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicExchange(Scalar::Type type, const Synchronization& sync, + void atomicExchange(Scalar::Type type, Synchronization sync, const BaseIndex& mem, Register value, Register valueTemp, Register offsetTemp, Register maskTemp, Register output) DEFINED_ON(mips_shared, loong64, riscv64); @@ -4254,11 +4271,11 @@ class MacroAssembler : public MacroAssemblerSpecific { // ARM: `value` and `output` must be distinct and (even,odd) pairs. // ARM64: `value` and `output` must be distinct. - void atomicExchange64(const Synchronization& sync, const Address& mem, + void atomicExchange64(Synchronization sync, const Address& mem, Register64 value, Register64 output) DEFINED_ON(arm, arm64, x64, x86, mips64, loong64, riscv64); - void atomicExchange64(const Synchronization& sync, const BaseIndex& mem, + void atomicExchange64(Synchronization sync, const BaseIndex& mem, Register64 value, Register64 output) DEFINED_ON(arm, arm64, x64, x86, mips64, loong64, riscv64); @@ -4275,33 +4292,31 @@ class MacroAssembler : public MacroAssemblerSpecific { // MIPS: `valueTemp`, `offsetTemp` and `maskTemp` must be defined for 8-bit // and 16-bit wide operations; `value` and `output` must differ. - void atomicFetchOp(Scalar::Type type, const Synchronization& sync, - AtomicOp op, Register value, const Address& mem, - Register temp, Register output) - DEFINED_ON(arm, arm64, x86_shared); + void atomicFetchOp(Scalar::Type type, Synchronization sync, AtomicOp op, + Register value, const Address& mem, Register temp, + Register output) DEFINED_ON(arm, arm64, x86_shared); - void atomicFetchOp(Scalar::Type type, const Synchronization& sync, - AtomicOp op, Imm32 value, const Address& mem, - Register temp, Register output) DEFINED_ON(x86_shared); + void atomicFetchOp(Scalar::Type type, Synchronization sync, AtomicOp op, + Imm32 value, const Address& mem, Register temp, + Register output) DEFINED_ON(x86_shared); - void atomicFetchOp(Scalar::Type type, const Synchronization& sync, - AtomicOp op, Register value, const BaseIndex& mem, - Register temp, Register output) - DEFINED_ON(arm, arm64, x86_shared); + void atomicFetchOp(Scalar::Type type, Synchronization sync, AtomicOp op, + Register value, const BaseIndex& mem, Register temp, + Register output) DEFINED_ON(arm, arm64, x86_shared); - void atomicFetchOp(Scalar::Type type, const Synchronization& sync, - AtomicOp op, Imm32 value, const BaseIndex& mem, - Register temp, Register output) DEFINED_ON(x86_shared); + void atomicFetchOp(Scalar::Type type, Synchronization sync, AtomicOp op, + Imm32 value, const BaseIndex& mem, Register temp, + Register output) DEFINED_ON(x86_shared); - void atomicFetchOp(Scalar::Type type, const Synchronization& sync, - AtomicOp op, Register value, const Address& mem, - Register valueTemp, Register offsetTemp, Register maskTemp, - Register output) DEFINED_ON(mips_shared, loong64, riscv64); + void atomicFetchOp(Scalar::Type type, Synchronization sync, AtomicOp op, + Register value, const Address& mem, Register valueTemp, + Register offsetTemp, Register maskTemp, Register output) + DEFINED_ON(mips_shared, loong64, riscv64); - void atomicFetchOp(Scalar::Type type, const Synchronization& sync, - AtomicOp op, Register value, const BaseIndex& mem, - Register valueTemp, Register offsetTemp, Register maskTemp, - Register output) DEFINED_ON(mips_shared, loong64, riscv64); + void atomicFetchOp(Scalar::Type type, Synchronization sync, AtomicOp op, + Register value, const BaseIndex& mem, Register valueTemp, + Register offsetTemp, Register maskTemp, Register output) + DEFINED_ON(mips_shared, loong64, riscv64); // x86: // `temp` must be ecx:ebx; `output` must be edx:eax. @@ -4313,23 +4328,21 @@ class MacroAssembler : public MacroAssemblerSpecific { // ARM64: // Registers `value`, `temp`, and `output` must all differ. - void atomicFetchOp64(const Synchronization& sync, AtomicOp op, - Register64 value, const Address& mem, Register64 temp, - Register64 output) + void atomicFetchOp64(Synchronization sync, AtomicOp op, Register64 value, + const Address& mem, Register64 temp, Register64 output) DEFINED_ON(arm, arm64, x64, mips64, loong64, riscv64); - void atomicFetchOp64(const Synchronization& sync, AtomicOp op, - const Address& value, const Address& mem, - Register64 temp, Register64 output) DEFINED_ON(x86); + void atomicFetchOp64(Synchronization sync, AtomicOp op, const Address& value, + const Address& mem, Register64 temp, Register64 output) + DEFINED_ON(x86); - void atomicFetchOp64(const Synchronization& sync, AtomicOp op, - Register64 value, const BaseIndex& mem, Register64 temp, - Register64 output) + void atomicFetchOp64(Synchronization sync, AtomicOp op, Register64 value, + const BaseIndex& mem, Register64 temp, Register64 output) DEFINED_ON(arm, arm64, x64, mips64, loong64, riscv64); - void atomicFetchOp64(const Synchronization& sync, AtomicOp op, - const Address& value, const BaseIndex& mem, - Register64 temp, Register64 output) DEFINED_ON(x86); + void atomicFetchOp64(Synchronization sync, AtomicOp op, const Address& value, + const BaseIndex& mem, Register64 temp, Register64 output) + DEFINED_ON(x86); // x64: // `value` can be any register. @@ -4338,18 +4351,18 @@ class MacroAssembler : public MacroAssemblerSpecific { // ARM64: // Registers `value` and `temp` must differ. - void atomicEffectOp64(const Synchronization& sync, AtomicOp op, - Register64 value, const Address& mem) DEFINED_ON(x64); + void atomicEffectOp64(Synchronization sync, AtomicOp op, Register64 value, + const Address& mem) DEFINED_ON(x64); - void atomicEffectOp64(const Synchronization& sync, AtomicOp op, - Register64 value, const Address& mem, Register64 temp) + void atomicEffectOp64(Synchronization sync, AtomicOp op, Register64 value, + const Address& mem, Register64 temp) DEFINED_ON(arm, arm64, mips64, loong64, riscv64); - void atomicEffectOp64(const Synchronization& sync, AtomicOp op, - Register64 value, const BaseIndex& mem) DEFINED_ON(x64); + void atomicEffectOp64(Synchronization sync, AtomicOp op, Register64 value, + const BaseIndex& mem) DEFINED_ON(x64); - void atomicEffectOp64(const Synchronization& sync, AtomicOp op, - Register64 value, const BaseIndex& mem, Register64 temp) + void atomicEffectOp64(Synchronization sync, AtomicOp op, Register64 value, + const BaseIndex& mem, Register64 temp) DEFINED_ON(arm, arm64, mips64, loong64, riscv64); // 64-bit atomic load. On 64-bit systems, use regular load with @@ -4358,16 +4371,16 @@ class MacroAssembler : public MacroAssemblerSpecific { // x86: `temp` must be ecx:ebx; `output` must be edx:eax. // ARM: `output` must be (even,odd) pair. - void atomicLoad64(const Synchronization& sync, const Address& mem, - Register64 temp, Register64 output) DEFINED_ON(x86); + void atomicLoad64(Synchronization sync, const Address& mem, Register64 temp, + Register64 output) DEFINED_ON(x86); - void atomicLoad64(const Synchronization& sync, const BaseIndex& mem, - Register64 temp, Register64 output) DEFINED_ON(x86); + void atomicLoad64(Synchronization sync, const BaseIndex& mem, Register64 temp, + Register64 output) DEFINED_ON(x86); - void atomicLoad64(const Synchronization& sync, const Address& mem, - Register64 output) DEFINED_ON(arm); + void atomicLoad64(Synchronization sync, const Address& mem, Register64 output) + DEFINED_ON(arm); - void atomicLoad64(const Synchronization& sync, const BaseIndex& mem, + void atomicLoad64(Synchronization sync, const BaseIndex& mem, Register64 output) DEFINED_ON(arm); // 64-bit atomic store. On 64-bit systems, use regular store with @@ -4376,10 +4389,10 @@ class MacroAssembler : public MacroAssemblerSpecific { // x86: `value` must be ecx:ebx; `temp` must be edx:eax. // ARM: `value` and `temp` must be (even,odd) pairs. - void atomicStore64(const Synchronization& sync, const Address& mem, - Register64 value, Register64 temp) DEFINED_ON(x86, arm); + void atomicStore64(Synchronization sync, const Address& mem, Register64 value, + Register64 temp) DEFINED_ON(x86, arm); - void atomicStore64(const Synchronization& sync, const BaseIndex& mem, + void atomicStore64(Synchronization sync, const BaseIndex& mem, Register64 value, Register64 temp) DEFINED_ON(x86, arm); // ======================================================================== @@ -4594,105 +4607,105 @@ class MacroAssembler : public MacroAssemblerSpecific { // For additional register constraints, see the primitive 32-bit operations // and/or wasm operations above. - void compareExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void compareExchangeJS(Scalar::Type arrayType, Synchronization sync, const Address& mem, Register expected, Register replacement, Register temp, AnyRegister output) DEFINED_ON(arm, arm64, x86_shared); - void compareExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void compareExchangeJS(Scalar::Type arrayType, Synchronization sync, const BaseIndex& mem, Register expected, Register replacement, Register temp, AnyRegister output) DEFINED_ON(arm, arm64, x86_shared); - void compareExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void compareExchangeJS(Scalar::Type arrayType, Synchronization sync, const Address& mem, Register expected, Register replacement, Register valueTemp, Register offsetTemp, Register maskTemp, Register temp, AnyRegister output) DEFINED_ON(mips_shared, loong64, riscv64); - void compareExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void compareExchangeJS(Scalar::Type arrayType, Synchronization sync, const BaseIndex& mem, Register expected, Register replacement, Register valueTemp, Register offsetTemp, Register maskTemp, Register temp, AnyRegister output) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicExchangeJS(Scalar::Type arrayType, Synchronization sync, const Address& mem, Register value, Register temp, AnyRegister output) DEFINED_ON(arm, arm64, x86_shared); - void atomicExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicExchangeJS(Scalar::Type arrayType, Synchronization sync, const BaseIndex& mem, Register value, Register temp, AnyRegister output) DEFINED_ON(arm, arm64, x86_shared); - void atomicExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicExchangeJS(Scalar::Type arrayType, Synchronization sync, const Address& mem, Register value, Register valueTemp, Register offsetTemp, Register maskTemp, Register temp, AnyRegister output) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicExchangeJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicExchangeJS(Scalar::Type arrayType, Synchronization sync, const BaseIndex& mem, Register value, Register valueTemp, Register offsetTemp, Register maskTemp, Register temp, AnyRegister output) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicFetchOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicFetchOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const Address& mem, Register temp1, Register temp2, AnyRegister output) DEFINED_ON(arm, arm64, x86_shared); - void atomicFetchOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicFetchOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const BaseIndex& mem, Register temp1, Register temp2, AnyRegister output) DEFINED_ON(arm, arm64, x86_shared); - void atomicFetchOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicFetchOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Imm32 value, const Address& mem, Register temp1, Register temp2, AnyRegister output) DEFINED_ON(x86_shared); - void atomicFetchOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicFetchOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Imm32 value, const BaseIndex& mem, Register temp1, Register temp2, AnyRegister output) DEFINED_ON(x86_shared); - void atomicFetchOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicFetchOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const Address& mem, Register valueTemp, Register offsetTemp, Register maskTemp, Register temp, AnyRegister output) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicFetchOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicFetchOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const BaseIndex& mem, Register valueTemp, Register offsetTemp, Register maskTemp, Register temp, AnyRegister output) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicEffectOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicEffectOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const Address& mem, Register temp) DEFINED_ON(arm, arm64, x86_shared); - void atomicEffectOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicEffectOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const BaseIndex& mem, Register temp) DEFINED_ON(arm, arm64, x86_shared); - void atomicEffectOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicEffectOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Imm32 value, const Address& mem, Register temp) DEFINED_ON(x86_shared); - void atomicEffectOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicEffectOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Imm32 value, const BaseIndex& mem, Register temp) DEFINED_ON(x86_shared); - void atomicEffectOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicEffectOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const Address& mem, Register valueTemp, Register offsetTemp, Register maskTemp) DEFINED_ON(mips_shared, loong64, riscv64); - void atomicEffectOpJS(Scalar::Type arrayType, const Synchronization& sync, + void atomicEffectOpJS(Scalar::Type arrayType, Synchronization sync, AtomicOp op, Register value, const BaseIndex& mem, Register valueTemp, Register offsetTemp, Register maskTemp) @@ -5245,8 +5258,8 @@ class MacroAssembler : public MacroAssemblerSpecific { void storeToTypedBigIntArray(Scalar::Type arrayType, Register64 value, const Address& dest); - void memoryBarrierBefore(const Synchronization& sync); - void memoryBarrierAfter(const Synchronization& sync); + void memoryBarrierBefore(Synchronization sync); + void memoryBarrierAfter(Synchronization sync); void debugAssertIsObject(const ValueOperand& val); void debugAssertObjHasFixedSlots(Register obj, Register scratch); @@ -5284,12 +5297,41 @@ class MacroAssembler : public MacroAssemblerSpecific { Label* label); void typedArrayElementSize(Register obj, Register output); + + private: + // Shift |output| by the element shift of the ResizableTypedArray in |obj|. + void resizableTypedArrayElementShiftBy(Register obj, Register output, + Register scratch); + + public: void branchIfClassIsNotTypedArray(Register clasp, Label* notTypedArray); void branchIfClassIsNotFixedLengthTypedArray(Register clasp, Label* notTypedArray); + void branchIfClassIsNotResizableTypedArray(Register clasp, + Label* notTypedArray); + + private: + enum class BranchIfDetached { No, Yes }; + + void branchIfHasDetachedArrayBuffer(BranchIfDetached branchIf, Register obj, + Register temp, Label* label); + public: void branchIfHasDetachedArrayBuffer(Register obj, Register temp, - Label* label); + Label* label) { + branchIfHasDetachedArrayBuffer(BranchIfDetached::Yes, obj, temp, label); + } + + void branchIfHasAttachedArrayBuffer(Register obj, Register temp, + Label* label) { + branchIfHasDetachedArrayBuffer(BranchIfDetached::No, obj, temp, label); + } + + void branchIfResizableArrayBufferViewOutOfBounds(Register obj, Register temp, + Label* label); + + void branchIfResizableArrayBufferViewInBounds(Register obj, Register temp, + Label* label); void branchIfNativeIteratorNotReusable(Register ni, Label* notReusable); void branchNativeIteratorIndices(Condition cond, Register ni, Register temp, @@ -5560,7 +5602,7 @@ class MacroAssembler : public MacroAssemblerSpecific { void loadMegamorphicCache(Register dest); void lookupStringInAtomCacheLastLookups(Register str, Register scratch, - Label* fail); + Register output, Label* fail); void loadMegamorphicSetPropCache(Register dest); void loadAtomOrSymbolAndHash(ValueOperand value, Register outId, @@ -5627,6 +5669,35 @@ class MacroAssembler : public MacroAssemblerSpecific { void loadArrayBufferViewByteOffsetIntPtr(Register obj, Register output); void loadArrayBufferViewLengthIntPtr(Register obj, Register output); + void loadGrowableSharedArrayBufferByteLengthIntPtr(Synchronization sync, + Register obj, + Register output); + + private: + enum class ResizableArrayBufferView { TypedArray, DataView }; + + void loadResizableArrayBufferViewLengthIntPtr(ResizableArrayBufferView view, + Synchronization sync, + Register obj, Register output, + Register scratch); + + public: + void loadResizableTypedArrayLengthIntPtr(Synchronization sync, Register obj, + Register output, Register scratch) { + loadResizableArrayBufferViewLengthIntPtr( + ResizableArrayBufferView::TypedArray, sync, obj, output, scratch); + } + + void loadResizableDataViewByteLengthIntPtr(Synchronization sync, Register obj, + Register output, + Register scratch) { + loadResizableArrayBufferViewLengthIntPtr(ResizableArrayBufferView::DataView, + sync, obj, output, scratch); + } + + void loadResizableTypedArrayByteOffsetMaybeOutOfBoundsIntPtr( + Register obj, Register output, Register scratch); + private: void isCallableOrConstructor(bool isCallable, Register obj, Register output, Label* isProxy); |