author | Shu-yu Guo <shu@rfrn.org> |
Fri, 02 Aug 2013 08:24:57 -0700 | |
changeset 153426 | 699c21af878da8539a77b1b7b232e156c9d08bea |
parent 153425 | 4e12ba2df6a6cf16721c337217e2470dbe2d0745 |
child 153427 | aba98905fc13482fa3c649f9ea54138185b9b517 |
push id | 2859 |
push user | akeybl@mozilla.com |
push date | Mon, 16 Sep 2013 19:14:59 +0000 |
treeherder | mozilla-beta@87d3c51cd2bf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 895950 |
milestone | 25.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/ion/IonMacroAssembler.h +++ b/js/src/ion/IonMacroAssembler.h @@ -288,16 +288,21 @@ class MacroAssembler : public MacroAssem storeTypedOrValue(src.reg(), dest); } void storeCallResult(Register reg) { if (reg != ReturnReg) mov(ReturnReg, reg); } + void storeCallFloatResult(const FloatRegister ®) { + if (reg != ReturnFloatReg) + moveDouble(ReturnFloatReg, reg); + } + void storeCallResultValue(AnyRegister dest) { #if defined(JS_NUNBOX32) unboxValue(ValueOperand(JSReturnReg_Type, JSReturnReg_Data), dest); #elif defined(JS_PUNBOX64) unboxValue(ValueOperand(JSReturnReg), dest); #else #error "Bad architecture" #endif
--- a/js/src/ion/VMFunctions.h +++ b/js/src/ion/VMFunctions.h @@ -19,16 +19,17 @@ class DeclEnvObject; class ForkJoinSlice; namespace ion { enum DataType { Type_Void, Type_Bool, Type_Int32, + Type_Double, Type_Pointer, Type_Object, Type_Value, Type_Handle, Type_ParallelResult }; struct PopValues @@ -359,16 +360,17 @@ template <> struct TypeToRootType<Handle }; template <class> struct OutParamToDataType { static const DataType result = Type_Void; }; template <> struct OutParamToDataType<Value *> { static const DataType result = Type_Value; }; template <> struct OutParamToDataType<int *> { static const DataType result = Type_Int32; }; template <> struct OutParamToDataType<uint32_t *> { static const DataType result = Type_Int32; }; template <> struct OutParamToDataType<uint8_t **> { static const DataType result = Type_Pointer; }; template <> struct OutParamToDataType<bool *> { static const DataType result = Type_Bool; }; +template <> struct OutParamToDataType<double *> { static const DataType result = Type_Double; }; template <> struct OutParamToDataType<MutableHandleValue> { static const DataType result = Type_Handle; }; template <> struct OutParamToDataType<MutableHandleObject> { static const DataType result = Type_Handle; }; template <> struct OutParamToDataType<MutableHandleString> { static const DataType result = Type_Handle; }; template <class> struct OutParamToRootType { static const VMFunction::RootType result = VMFunction::RootNone; }; template <> struct OutParamToRootType<MutableHandleValue> {
--- a/js/src/ion/arm/MacroAssembler-arm.h +++ b/js/src/ion/arm/MacroAssembler-arm.h @@ -1193,16 +1193,19 @@ class MacroAssemblerARMCompat : public M ma_vstr(src, Operand(addr)); } void storeDouble(FloatRegister src, BaseIndex addr) { // Harder cases not handled yet. JS_ASSERT(addr.offset == 0); uint32_t scale = Imm32::ShiftOf(addr.scale).value; ma_vstr(src, addr.base, addr.index, scale); } + void moveDouble(FloatRegister src, FloatRegister dest) { + ma_vstr(src, Operand(dest)); + } void storeFloat(FloatRegister src, Address addr) { ma_vstr(VFPRegister(src).singleOverlay(), Operand(addr)); } void storeFloat(FloatRegister src, BaseIndex addr) { // Harder cases not handled yet. JS_ASSERT(addr.offset == 0); uint32_t scale = Imm32::ShiftOf(addr.scale).value;
--- a/js/src/ion/arm/Trampoline-arm.cpp +++ b/js/src/ion/arm/Trampoline-arm.cpp @@ -641,16 +641,23 @@ IonRuntime::generateVMWrapper(JSContext case Type_Pointer: case Type_Bool: outReg = r4; regs.take(outReg); masm.reserveStack(sizeof(int32_t)); masm.ma_mov(sp, outReg); break; + case Type_Double: + outReg = r4; + regs.take(outReg); + masm.reserveStack(sizeof(double)); + masm.ma_mov(sp, outReg); + break; + default: JS_ASSERT(f.outParam == Type_Void); break; } masm.setupUnalignedABICall(f.argc(), regs.getAny()); masm.passABIArg(cxreg); @@ -720,16 +727,21 @@ IonRuntime::generateVMWrapper(JSContext masm.freeStack(sizeof(int32_t)); break; case Type_Bool: masm.load8ZeroExtend(Address(sp, 0), ReturnReg); masm.freeStack(sizeof(int32_t)); break; + case Type_Double: + masm.loadDouble(Address(sp, 0), ReturnFloatReg); + masm.freeStack(sizeof(double)); + break; + default: JS_ASSERT(f.outParam == Type_Void); break; } masm.leaveExitFrame(); masm.retn(Imm32(sizeof(IonExitFrameLayout) + f.explicitStackSlots() * sizeof(void *) + f.extraValuesToPop * sizeof(Value)));
--- a/js/src/ion/shared/CodeGenerator-shared.h +++ b/js/src/ion/shared/CodeGenerator-shared.h @@ -307,16 +307,20 @@ class CodeGeneratorShared : public LInst pushedArgs_++; #endif } void storeResultTo(const Register ®) { masm.storeCallResult(reg); } + void storeFloatResultTo(const FloatRegister ®) { + masm.storeCallFloatResult(reg); + } + template <typename T> void storeResultValueTo(const T &t) { masm.storeCallResultValue(t); } bool callVM(const VMFunction &f, LInstruction *ins, const Register *dynStack = NULL); template <class ArgSeq, class StoreOutputTo> @@ -528,16 +532,36 @@ class StoreRegisterTo } inline RegisterSet clobbered() const { RegisterSet set = RegisterSet(); set.add(out_); return set; } }; +class StoreFloatRegisterTo +{ + private: + FloatRegister out_; + + public: + StoreFloatRegisterTo(const FloatRegister &out) + : out_(out) + { } + + inline void generate(CodeGeneratorShared *codegen) const { + codegen->storeFloatResultTo(out_); + } + inline RegisterSet clobbered() const { + RegisterSet set = RegisterSet(); + set.add(out_); + return set; + } +}; + template <typename Output> class StoreValueTo_ { private: Output out_; public: StoreValueTo_(const Output &out)
--- a/js/src/ion/shared/MacroAssembler-x86-shared.h +++ b/js/src/ion/shared/MacroAssembler-x86-shared.h @@ -278,16 +278,19 @@ class MacroAssemblerX86Shared : public A movsd(src, Operand(dest)); } void storeDouble(FloatRegister src, const BaseIndex &dest) { movsd(src, Operand(dest)); } void storeDouble(FloatRegister src, const Operand &dest) { movsd(src, dest); } + void moveDouble(FloatRegister src, FloatRegister dest) { + movsd(src, dest); + } void zeroDouble(FloatRegister reg) { xorpd(reg, reg); } void negateDouble(FloatRegister reg) { // From MacroAssemblerX86Shared::maybeInlineDouble pcmpeqw(ScratchFloatReg, ScratchFloatReg); psllq(Imm32(63), ScratchFloatReg);
--- a/js/src/ion/x64/Trampoline-x64.cpp +++ b/js/src/ion/x64/Trampoline-x64.cpp @@ -526,16 +526,22 @@ IonRuntime::generateVMWrapper(JSContext case Type_Int32: case Type_Bool: outReg = regs.takeAny(); masm.reserveStack(sizeof(int32_t)); masm.movq(esp, outReg); break; + case Type_Double: + outReg = regs.takeAny(); + masm.reserveStack(sizeof(double)); + masm.movq(esp, outReg); + break; + case Type_Pointer: outReg = regs.takeAny(); masm.reserveStack(sizeof(uintptr_t)); masm.movq(esp, outReg); break; default: JS_ASSERT(f.outParam == Type_Void); @@ -609,16 +615,21 @@ IonRuntime::generateVMWrapper(JSContext masm.freeStack(sizeof(int32_t)); break; case Type_Bool: masm.load8ZeroExtend(Address(esp, 0), ReturnReg); masm.freeStack(sizeof(int32_t)); break; + case Type_Double: + masm.loadDouble(Address(esp, 0), ReturnFloatReg); + masm.freeStack(sizeof(double)); + break; + case Type_Pointer: masm.loadPtr(Address(esp, 0), ReturnReg); masm.freeStack(sizeof(uintptr_t)); break; default: JS_ASSERT(f.outParam == Type_Void); break;
--- a/js/src/ion/x86/Trampoline-x86.cpp +++ b/js/src/ion/x86/Trampoline-x86.cpp @@ -551,16 +551,22 @@ IonRuntime::generateVMWrapper(JSContext case Type_Int32: case Type_Pointer: case Type_Bool: outReg = regs.takeAny(); masm.reserveStack(sizeof(int32_t)); masm.movl(esp, outReg); break; + case Type_Double: + outReg = regs.takeAny(); + masm.reserveStack(sizeof(double)); + masm.movl(esp, outReg); + break; + default: JS_ASSERT(f.outParam == Type_Void); break; } masm.setupUnalignedABICall(f.argc(), regs.getAny()); masm.passABIArg(cxreg); @@ -633,16 +639,20 @@ IonRuntime::generateVMWrapper(JSContext masm.Pop(ReturnReg); break; case Type_Bool: masm.Pop(ReturnReg); masm.movzxbl(ReturnReg, ReturnReg); break; + case Type_Double: + masm.Pop(ReturnFloatReg); + break; + default: JS_ASSERT(f.outParam == Type_Void); break; } masm.leaveExitFrame(); masm.retn(Imm32(sizeof(IonExitFrameLayout) + f.explicitStackSlots() * sizeof(void *) + f.extraValuesToPop * sizeof(Value)));