author | Lars T Hansen <lhansen@mozilla.com> |
Fri, 06 Oct 2017 11:01:08 +0200 | |
changeset 385365 | 8dd2fefd471b508a6233042abc5d2ed5b7b754a4 |
parent 385364 | 2ffd7a34aa10f072615044c0c84929358b11f318 |
child 385366 | 813d4e250712d296eb4b11b0b89e10ed6a94e3d4 |
push id | 32653 |
push user | archaeopteryx@coole-files.de |
push date | Tue, 10 Oct 2017 21:56:30 +0000 |
treeherder | mozilla-central@e897e367d3bd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 1406336 |
milestone | 58.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/Registers.h +++ b/js/src/jit/Registers.h @@ -130,17 +130,18 @@ Register::LiveAsIndexableSet<RegTypeName } template <> inline Register::SetType Register::AllocatableAsIndexableSet<RegTypeName::GPR>(SetType set) { return set; } -#if defined(JS_NUNBOX32) +#if JS_BITS_PER_WORD == 32 +// Note, some platform code depends on INT64LOW_OFFSET being zero. static const uint32_t INT64LOW_OFFSET = 0 * sizeof(int32_t); static const uint32_t INT64HIGH_OFFSET = 1 * sizeof(int32_t); #endif struct Register64 { #ifdef JS_PUNBOX64 Register reg;
--- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1003,19 +1003,18 @@ class MacroAssemblerARMCompat : public M void load16ZeroExtend(const Address& address, Register dest); void load16ZeroExtend(const BaseIndex& src, Register dest); void load32(const Address& address, Register dest); void load32(const BaseIndex& address, Register dest); void load32(AbsoluteAddress address, Register dest); void load64(const Address& address, Register64 dest) { - load32(Address(address.base, address.offset + INT64LOW_OFFSET), dest.low); - int32_t highOffset = (address.offset < 0) ? -int32_t(INT64HIGH_OFFSET) : INT64HIGH_OFFSET; - load32(Address(address.base, address.offset + highOffset), dest.high); + load32(LowWord(address), dest.low); + load32(HighWord(address), dest.high); } void loadPtr(const Address& address, Register dest); void loadPtr(const BaseIndex& src, Register dest); void loadPtr(AbsoluteAddress address, Register dest); void loadPtr(wasm::SymbolicAddress address, Register dest); void loadPrivate(const Address& address, Register dest); @@ -1075,23 +1074,23 @@ class MacroAssemblerARMCompat : public M void store32(Register src, AbsoluteAddress address); void store32(Register src, const Address& address); void store32(Register src, const BaseIndex& address); void store32(Imm32 src, const Address& address); void store32(Imm32 src, const BaseIndex& address); void store64(Register64 src, Address address) { - store32(src.low, Address(address.base, address.offset + INT64LOW_OFFSET)); - store32(src.high, Address(address.base, address.offset + INT64HIGH_OFFSET)); + store32(src.low, LowWord(address)); + store32(src.high, HighWord(address)); } void store64(Imm64 imm, Address address) { - store32(imm.low(), Address(address.base, address.offset + INT64LOW_OFFSET)); - store32(imm.hi(), Address(address.base, address.offset + INT64HIGH_OFFSET)); + store32(imm.low(), LowWord(address)); + store32(imm.hi(), HighWord(address)); } void storePtr(ImmWord imm, const Address& address); void storePtr(ImmWord imm, const BaseIndex& address); void storePtr(ImmPtr imm, const Address& address); void storePtr(ImmPtr imm, const BaseIndex& address); void storePtr(ImmGCPtr imm, const Address& address); void storePtr(ImmGCPtr imm, const BaseIndex& address);
--- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -853,19 +853,18 @@ class MacroAssemblerMIPSCompat : public void load16ZeroExtend(const Address& address, Register dest); void load16ZeroExtend(const BaseIndex& src, Register dest); void load32(const Address& address, Register dest); void load32(const BaseIndex& address, Register dest); void load32(AbsoluteAddress address, Register dest); void load32(wasm::SymbolicAddress address, Register dest); void load64(const Address& address, Register64 dest) { - load32(Address(address.base, address.offset + INT64LOW_OFFSET), dest.low); - int32_t highOffset = (address.offset < 0) ? -int32_t(INT64HIGH_OFFSET) : INT64HIGH_OFFSET; - load32(Address(address.base, address.offset + highOffset), dest.high); + load32(LowWord(address), dest.low); + load32(HighWord(address), dest.high); } void loadPtr(const Address& address, Register dest); void loadPtr(const BaseIndex& src, Register dest); void loadPtr(AbsoluteAddress address, Register dest); void loadPtr(wasm::SymbolicAddress address, Register dest); void loadPrivate(const Address& address, Register dest);
--- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -2,16 +2,17 @@ * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef jit_shared_Assembler_shared_h #define jit_shared_Assembler_shared_h +#include "mozilla/CheckedInt.h" #include "mozilla/PodOperations.h" #include <limits.h> #include "jit/AtomicOp.h" #include "jit/JitAllocPolicy.h" #include "jit/Label.h" #include "jit/Registers.h" @@ -29,16 +30,18 @@ // JS_SMALL_BRANCH means the range on a branch instruction // is smaller than the whole address space # define JS_SMALL_BRANCH #endif namespace js { namespace jit { +using mozilla::CheckedInt; + namespace Disassembler { class HeapAccess; } // namespace Disassembler static const uint32_t Simd128DataSize = 4 * sizeof(int32_t); static_assert(Simd128DataSize == 4 * sizeof(int32_t), "SIMD data should be able to contain int32x4"); static_assert(Simd128DataSize == 4 * sizeof(float), "SIMD data should be able to contain float32x4"); static_assert(Simd128DataSize == 2 * sizeof(double), "SIMD data should be able to contain float64x2"); @@ -293,32 +296,68 @@ struct Address int32_t offset; Address(Register base, int32_t offset) : base(base), offset(offset) { } Address() { mozilla::PodZero(this); } }; +#if JS_BITS_PER_WORD == 32 + +static inline Address +LowWord(const Address& address) { + CheckedInt<int32_t> offset = CheckedInt<int32_t>(address.offset) + INT64LOW_OFFSET; + MOZ_ALWAYS_TRUE(offset.isValid()); + return Address(address.base, offset.value()); +} + +static inline Address +HighWord(const Address& address) { + CheckedInt<int32_t> offset = CheckedInt<int32_t>(address.offset) + INT64HIGH_OFFSET; + MOZ_ALWAYS_TRUE(offset.isValid()); + return Address(address.base, offset.value()); +} + +#endif + // Specifies an address computed in the form of a register base, a register // index with a scale, and a constant, 32-bit offset. struct BaseIndex { Register base; Register index; Scale scale; int32_t offset; BaseIndex(Register base, Register index, Scale scale, int32_t offset = 0) : base(base), index(index), scale(scale), offset(offset) { } BaseIndex() { mozilla::PodZero(this); } }; +#if JS_BITS_PER_WORD == 32 + +static inline BaseIndex +LowWord(const BaseIndex& address) { + CheckedInt<int32_t> offset = CheckedInt<int32_t>(address.offset) + INT64LOW_OFFSET; + MOZ_ALWAYS_TRUE(offset.isValid()); + return BaseIndex(address.base, address.index, address.scale, offset.value()); +} + +static inline BaseIndex +HighWord(const BaseIndex& address) { + CheckedInt<int32_t> offset = CheckedInt<int32_t>(address.offset) + INT64HIGH_OFFSET; + MOZ_ALWAYS_TRUE(offset.isValid()); + return BaseIndex(address.base, address.index, address.scale, offset.value()); +} + +#endif + // A BaseIndex used to access Values. Note that |offset| is *not* scaled by // sizeof(Value). Use this *only* if you're indexing into a series of Values // that aren't object elements or object slots (for example, values on the // stack, values in an arguments object, &c.). If you're indexing into an // object's elements or slots, don't use this directly! Use // BaseObject{Element,Slot}Index instead. struct BaseValueIndex : BaseIndex {
--- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -203,16 +203,34 @@ PatchJump(CodeLocationJump jump, CodeLoc X86Encoding::SetRel32(jump.raw(), label.raw()); } static inline void PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitZoneGroup::BackedgeTarget target) { PatchJump(jump_, label); } +static inline Operand +LowWord(const Operand& op) { + switch (op.kind()) { + case Operand::MEM_REG_DISP: return Operand(LowWord(op.toAddress())); + case Operand::MEM_SCALE: return Operand(LowWord(op.toBaseIndex())); + default: MOZ_CRASH("Invalid operand type"); + } +} + +static inline Operand +HighWord(const Operand& op) { + switch (op.kind()) { + case Operand::MEM_REG_DISP: return Operand(HighWord(op.toAddress())); + case Operand::MEM_SCALE: return Operand(HighWord(op.toBaseIndex())); + default: MOZ_CRASH("Invalid operand type"); + } +} + // Return operand from a JS -> JS call. static const ValueOperand JSReturnOperand = ValueOperand(JSReturnReg_Type, JSReturnReg_Data); class Assembler : public AssemblerX86Shared { void writeRelocation(JmpSrc src) { jumpRelocations_.writeUnsigned(src.offset()); } @@ -763,34 +781,30 @@ class Assembler : public AssemblerX86Sha default: MOZ_CRASH("unexpected operand kind"); } return CodeOffset(masm.currentOffset()); } CodeOffset movlWithPatchLow(Register regLow, const Operand& dest) { switch (dest.kind()) { case Operand::MEM_REG_DISP: { - Address addr = dest.toAddress(); - Operand low(addr.base, addr.offset + INT64LOW_OFFSET); - return movlWithPatch(regLow, low); + return movlWithPatch(regLow, LowWord(dest)); } case Operand::MEM_ADDRESS32: { Operand low(PatchedAbsoluteAddress(uint32_t(dest.address()) + INT64LOW_OFFSET)); return movlWithPatch(regLow, low); } default: MOZ_CRASH("unexpected operand kind"); } } CodeOffset movlWithPatchHigh(Register regHigh, const Operand& dest) { switch (dest.kind()) { case Operand::MEM_REG_DISP: { - Address addr = dest.toAddress(); - Operand high(addr.base, addr.offset + INT64HIGH_OFFSET); - return movlWithPatch(regHigh, high); + return movlWithPatch(regHigh, HighWord(dest)); } case Operand::MEM_ADDRESS32: { Operand high(PatchedAbsoluteAddress(uint32_t(dest.address()) + INT64HIGH_OFFSET)); return movlWithPatch(regHigh, high); } default: MOZ_CRASH("unexpected operand kind"); }
--- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -945,57 +945,57 @@ MacroAssembler::truncateFloat32ToUInt64( { Label done; loadFloat32(src, floatTemp); truncateFloat32ToInt64(src, dest, temp); // For unsigned conversion the case of [INT64, UINT64] needs to get handle seperately. - load32(Address(dest.base, dest.offset + INT64HIGH_OFFSET), temp); + load32(HighWord(dest), temp); branch32(Assembler::Condition::NotSigned, temp, Imm32(0), &done); // Move the value inside INT64 range. storeFloat32(floatTemp, dest); loadConstantFloat32(double(int64_t(0x8000000000000000)), floatTemp); vaddss(Operand(dest), floatTemp, floatTemp); storeFloat32(floatTemp, dest); truncateFloat32ToInt64(dest, dest, temp); - load32(Address(dest.base, dest.offset + INT64HIGH_OFFSET), temp); + load32(HighWord(dest), temp); orl(Imm32(0x80000000), temp); - store32(temp, Address(dest.base, dest.offset + INT64HIGH_OFFSET)); + store32(temp, HighWord(dest)); bind(&done); } void MacroAssembler::truncateDoubleToUInt64(Address src, Address dest, Register temp, FloatRegister floatTemp) { Label done; loadDouble(src, floatTemp); truncateDoubleToInt64(src, dest, temp); // For unsigned conversion the case of [INT64, UINT64] needs to get handle seperately. - load32(Address(dest.base, dest.offset + INT64HIGH_OFFSET), temp); + load32(HighWord(dest), temp); branch32(Assembler::Condition::NotSigned, temp, Imm32(0), &done); // Move the value inside INT64 range. storeDouble(floatTemp, dest); loadConstantDouble(double(int64_t(0x8000000000000000)), floatTemp); vaddsd(Operand(dest), floatTemp, floatTemp); storeDouble(floatTemp, dest); truncateDoubleToInt64(dest, dest, temp); - load32(Address(dest.base, dest.offset + INT64HIGH_OFFSET), temp); + load32(HighWord(dest), temp); orl(Imm32(0x80000000), temp); - store32(temp, Address(dest.base, dest.offset + INT64HIGH_OFFSET)); + store32(temp, HighWord(dest)); bind(&done); } // ======================================================================== // wasm support template <class L>
--- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -763,40 +763,28 @@ MacroAssembler::wasmLoadI64(const wasm:: break; case Scalar::Uint32: movl(srcAddr, out.low); append(access, loadOffset, framePushed()); xorl(out.high, out.high); break; case Scalar::Int64: { - Operand low(eax); - Operand high(eax); - if (srcAddr.kind() == Operand::MEM_SCALE) { - BaseIndex addr = srcAddr.toBaseIndex(); - - MOZ_RELEASE_ASSERT(addr.base != out.low && addr.index != out.low); + MOZ_RELEASE_ASSERT(srcAddr.toBaseIndex().base != out.low && + srcAddr.toBaseIndex().index != out.low); + } + if (srcAddr.kind() == Operand::MEM_REG_DISP) + MOZ_RELEASE_ASSERT(srcAddr.toAddress().base != out.low); - low = Operand(addr.base, addr.index, addr.scale, addr.offset + INT64LOW_OFFSET); - high = Operand(addr.base, addr.index, addr.scale, addr.offset + INT64HIGH_OFFSET); - } else { - Address addr = srcAddr.toAddress(); - - MOZ_RELEASE_ASSERT(addr.base != out.low); - - low = Operand(addr.base, addr.offset + INT64LOW_OFFSET); - high = Operand(addr.base, addr.offset + INT64HIGH_OFFSET); - } - - movl(low, out.low); + movl(LowWord(srcAddr), out.low); append(access, loadOffset, framePushed()); loadOffset = size(); - movl(high, out.high); + movl(HighWord(srcAddr), out.high); append(access, loadOffset, framePushed()); break; } case Scalar::Float32: case Scalar::Float64: case Scalar::Float32x4: case Scalar::Int8x16: @@ -877,34 +865,22 @@ MacroAssembler::wasmStore(const wasm::Me void MacroAssembler::wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value, Operand dstAddr) { MOZ_ASSERT(!access.isAtomic()); MOZ_ASSERT(!access.isSimd()); MOZ_ASSERT(dstAddr.kind() == Operand::MEM_REG_DISP || dstAddr.kind() == Operand::MEM_SCALE); - Operand low(eax); - Operand high(eax); - if (dstAddr.kind() == Operand::MEM_SCALE) { - BaseIndex addr = dstAddr.toBaseIndex(); - low = Operand(addr.base, addr.index, addr.scale, addr.offset + INT64LOW_OFFSET); - high = Operand(addr.base, addr.index, addr.scale, addr.offset + INT64HIGH_OFFSET); - } else { - Address addr = dstAddr.toAddress(); - low = Operand(addr.base, addr.offset + INT64LOW_OFFSET); - high = Operand(addr.base, addr.offset + INT64HIGH_OFFSET); - } - size_t storeOffset = size(); - movl(value.low, low); + movl(value.low, LowWord(dstAddr)); append(access, storeOffset, framePushed()); storeOffset = size(); - movl(value.high, high); + movl(value.high, HighWord(dstAddr)); append(access, storeOffset, framePushed()); } void MacroAssembler::wasmTruncateDoubleToUInt32(FloatRegister input, Register output, Label* oolEntry) { Label done; vcvttsd2si(input, output);
--- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -582,20 +582,20 @@ class MacroAssemblerX86 : public MacroAs movl(Operand(address), dest); } void loadPrivate(const Address& src, Register dest) { movl(payloadOf(src), dest); } void load32(AbsoluteAddress address, Register dest) { movl(Operand(address), dest); } - void load64(const Address& address, Register64 dest) { - movl(Operand(Address(address.base, address.offset + INT64LOW_OFFSET)), dest.low); - int32_t highOffset = (address.offset < 0) ? -int32_t(INT64HIGH_OFFSET) : INT64HIGH_OFFSET; - movl(Operand(Address(address.base, address.offset + highOffset)), dest.high); + template <typename T> + void load64(const T& address, Register64 dest) { + movl(Operand(LowWord(address)), dest.low); + movl(Operand(HighWord(address)), dest.high); } template <typename T> void storePtr(ImmWord imm, T address) { movl(Imm32(imm.value), Operand(address)); } template <typename T> void storePtr(ImmPtr imm, T address) { storePtr(ImmWord(uintptr_t(imm.value)), address); @@ -617,23 +617,24 @@ class MacroAssemblerX86 : public MacroAs movl(src, Operand(address)); } void store32(Register src, AbsoluteAddress address) { movl(src, Operand(address)); } void store16(Register src, AbsoluteAddress address) { movw(src, Operand(address)); } - void store64(Register64 src, Address address) { - movl(src.low, Operand(Address(address.base, address.offset + INT64LOW_OFFSET))); - movl(src.high, Operand(Address(address.base, address.offset + INT64HIGH_OFFSET))); + template <typename T> + void store64(Register64 src, const T& address) { + movl(src.low, Operand(LowWord(address))); + movl(src.high, Operand(HighWord(address))); } void store64(Imm64 imm, Address address) { - movl(imm.low(), Operand(Address(address.base, address.offset + INT64LOW_OFFSET))); - movl(imm.hi(), Operand(Address(address.base, address.offset + INT64HIGH_OFFSET))); + movl(imm.low(), Operand(LowWord(address))); + movl(imm.hi(), Operand(HighWord(address))); } void setStackArg(Register reg, uint32_t arg) { movl(reg, Operand(esp, arg * sizeof(intptr_t))); } void boxDouble(FloatRegister src, const ValueOperand& dest, FloatRegister temp) { if (Assembler::HasSSE41()) {
--- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -2516,19 +2516,19 @@ class BaseCompiler ABIArg argLoc = call.abi.next(MIRType::Int64); if (argLoc.kind() == ABIArg::Stack) { ScratchI32 scratch(*this); #if defined(JS_CODEGEN_X64) loadI64(Register64(scratch), arg); masm.movq(scratch, Operand(StackPointer, argLoc.offsetFromArgBase())); #elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM) loadI64Low(scratch, arg); - masm.store32(scratch, Address(StackPointer, argLoc.offsetFromArgBase() + INT64LOW_OFFSET)); + masm.store32(scratch, LowWord(Address(StackPointer, argLoc.offsetFromArgBase()))); loadI64High(scratch, arg); - masm.store32(scratch, Address(StackPointer, argLoc.offsetFromArgBase() + INT64HIGH_OFFSET)); + masm.store32(scratch, HighWord(Address(StackPointer, argLoc.offsetFromArgBase()))); #else MOZ_CRASH("BaseCompiler platform hook: passArg I64"); #endif } else { loadI64(argLoc.gpr64(), arg); } break; }
--- a/js/src/wasm/WasmStubs.cpp +++ b/js/src/wasm/WasmStubs.cpp @@ -134,20 +134,20 @@ SetupABIArguments(MacroAssembler& masm, switch (type) { case MIRType::Int32: masm.load32(src, scratch); masm.storePtr(scratch, Address(masm.getStackPointer(), iter->offsetFromArgBase())); break; case MIRType::Int64: { Register sp = masm.getStackPointer(); #if JS_BITS_PER_WORD == 32 - masm.load32(Address(src.base, src.offset + INT64LOW_OFFSET), scratch); - masm.store32(scratch, Address(sp, iter->offsetFromArgBase() + INT64LOW_OFFSET)); - masm.load32(Address(src.base, src.offset + INT64HIGH_OFFSET), scratch); - masm.store32(scratch, Address(sp, iter->offsetFromArgBase() + INT64HIGH_OFFSET)); + masm.load32(LowWord(src), scratch); + masm.store32(scratch, LowWord(Address(sp, iter->offsetFromArgBase()))); + masm.load32(HighWord(src), scratch); + masm.store32(scratch, HighWord(Address(sp, iter->offsetFromArgBase()))); #else Register64 scratch64(scratch); masm.load64(src, scratch64); masm.store64(scratch64, Address(sp, iter->offsetFromArgBase())); #endif break; } case MIRType::Double: @@ -379,20 +379,20 @@ GenerateEntry(MacroAssembler& masm, cons static void StackCopy(MacroAssembler& masm, MIRType type, Register scratch, Address src, Address dst) { if (type == MIRType::Int32) { masm.load32(src, scratch); masm.store32(scratch, dst); } else if (type == MIRType::Int64) { #if JS_BITS_PER_WORD == 32 - masm.load32(Address(src.base, src.offset + INT64LOW_OFFSET), scratch); - masm.store32(scratch, Address(dst.base, dst.offset + INT64LOW_OFFSET)); - masm.load32(Address(src.base, src.offset + INT64HIGH_OFFSET), scratch); - masm.store32(scratch, Address(dst.base, dst.offset + INT64HIGH_OFFSET)); + masm.load32(LowWord(src), scratch); + masm.store32(scratch, LowWord(dst)); + masm.load32(HighWord(src), scratch); + masm.store32(scratch, HighWord(dst)); #else Register64 scratch64(scratch); masm.load64(src, scratch64); masm.store64(scratch64, dst); #endif } else if (type == MIRType::Float32) { masm.loadFloat32(src, ScratchFloat32Reg); masm.storeFloat32(ScratchFloat32Reg, dst);