зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1175976: IonMonkey - Part1: Move unaryArith from baseline to shared stub, r=jandem
This commit is contained in:
Родитель
f2b116c0d6
Коммит
a6e8869a63
|
@ -1861,143 +1861,6 @@ ICToNumber_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
return tailCallVM(DoToNumberFallbackInfo, masm);
|
||||
}
|
||||
|
||||
//
|
||||
// UnaryArith_Fallback
|
||||
//
|
||||
|
||||
static bool
|
||||
DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub_,
|
||||
HandleValue val, MutableHandleValue res)
|
||||
{
|
||||
// This fallback stub may trigger debug mode toggling.
|
||||
DebugModeOSRVolatileStub<ICUnaryArith_Fallback*> stub(frame, stub_);
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||
JSOp op = JSOp(*pc);
|
||||
FallbackICSpew(cx, stub, "UnaryArith(%s)", js_CodeName[op]);
|
||||
|
||||
switch (op) {
|
||||
case JSOP_BITNOT: {
|
||||
int32_t result;
|
||||
if (!BitNot(cx, val, &result))
|
||||
return false;
|
||||
res.setInt32(result);
|
||||
break;
|
||||
}
|
||||
case JSOP_NEG:
|
||||
if (!NegOperation(cx, script, pc, val, res))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
}
|
||||
|
||||
// Check if debug mode toggling made the stub invalid.
|
||||
if (stub.invalid())
|
||||
return true;
|
||||
|
||||
if (res.isDouble())
|
||||
stub->setSawDoubleResult();
|
||||
|
||||
if (stub->numOptimizedStubs() >= ICUnaryArith_Fallback::MAX_OPTIMIZED_STUBS) {
|
||||
// TODO: Discard/replace stubs.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val.isInt32() && res.isInt32()) {
|
||||
JitSpew(JitSpew_BaselineIC, " Generating %s(Int32 => Int32) stub", js_CodeName[op]);
|
||||
ICUnaryArith_Int32::Compiler compiler(cx, op);
|
||||
ICStub* int32Stub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!int32Stub)
|
||||
return false;
|
||||
stub->addNewStub(int32Stub);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val.isNumber() && res.isNumber() && cx->runtime()->jitSupportsFloatingPoint) {
|
||||
JitSpew(JitSpew_BaselineIC, " Generating %s(Number => Number) stub", js_CodeName[op]);
|
||||
|
||||
// Unlink int32 stubs, the double stub handles both cases and TI specializes for both.
|
||||
stub->unlinkStubsWithKind(cx, ICStub::UnaryArith_Int32);
|
||||
|
||||
ICUnaryArith_Double::Compiler compiler(cx, op);
|
||||
ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!doubleStub)
|
||||
return false;
|
||||
stub->addNewStub(doubleStub);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*,
|
||||
HandleValue, MutableHandleValue);
|
||||
static const VMFunction DoUnaryArithFallbackInfo =
|
||||
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, TailCall, PopValues(1));
|
||||
|
||||
bool
|
||||
ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(engine_ == Engine::Baseline);
|
||||
MOZ_ASSERT(R0 == JSReturnOperand);
|
||||
|
||||
// Restore the tail call register.
|
||||
EmitRestoreTailCallReg(masm);
|
||||
|
||||
// Ensure stack is fully synced for the expression decompiler.
|
||||
masm.pushValue(R0);
|
||||
|
||||
// Push arguments.
|
||||
masm.pushValue(R0);
|
||||
masm.push(ICStubReg);
|
||||
pushFramePtr(masm, R0.scratchReg());
|
||||
|
||||
return tailCallVM(DoUnaryArithFallbackInfo, masm);
|
||||
}
|
||||
|
||||
bool
|
||||
ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(engine_ == Engine::Baseline);
|
||||
|
||||
Label failure;
|
||||
masm.ensureDouble(R0, FloatReg0, &failure);
|
||||
|
||||
MOZ_ASSERT(op == JSOP_NEG || op == JSOP_BITNOT);
|
||||
|
||||
if (op == JSOP_NEG) {
|
||||
masm.negateDouble(FloatReg0);
|
||||
masm.boxDouble(FloatReg0, R0);
|
||||
} else {
|
||||
// Truncate the double to an int32.
|
||||
Register scratchReg = R1.scratchReg();
|
||||
|
||||
Label doneTruncate;
|
||||
Label truncateABICall;
|
||||
masm.branchTruncateDouble(FloatReg0, scratchReg, &truncateABICall);
|
||||
masm.jump(&doneTruncate);
|
||||
|
||||
masm.bind(&truncateABICall);
|
||||
masm.setupUnalignedABICall(scratchReg);
|
||||
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
|
||||
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32));
|
||||
masm.storeCallResult(scratchReg);
|
||||
|
||||
masm.bind(&doneTruncate);
|
||||
masm.not32(scratchReg);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0);
|
||||
}
|
||||
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Failure case - jump to next stub
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// GetElem_Fallback
|
||||
//
|
||||
|
|
|
@ -1104,94 +1104,6 @@ class ICToNumber_Fallback : public ICFallbackStub
|
|||
};
|
||||
};
|
||||
|
||||
// UnaryArith
|
||||
// JSOP_BITNOT
|
||||
// JSOP_NEG
|
||||
|
||||
class ICUnaryArith_Fallback : public ICFallbackStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Fallback(JitCode* stubCode)
|
||||
: ICFallbackStub(UnaryArith_Fallback, stubCode)
|
||||
{
|
||||
extra_ = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
static const uint32_t MAX_OPTIMIZED_STUBS = 8;
|
||||
|
||||
bool sawDoubleResult() {
|
||||
return extra_;
|
||||
}
|
||||
void setSawDoubleResult() {
|
||||
extra_ = 1;
|
||||
}
|
||||
|
||||
// Compiler for this stub kind.
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
explicit Compiler(JSContext* cx)
|
||||
: ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICUnaryArith_Fallback>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ICUnaryArith_Int32 : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Int32(JitCode* stubCode)
|
||||
: ICStub(UnaryArith_Int32, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
class Compiler : public ICMultiStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, JSOp op)
|
||||
: ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICUnaryArith_Int32>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ICUnaryArith_Double : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Double(JitCode* stubCode)
|
||||
: ICStub(UnaryArith_Double, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
class Compiler : public ICMultiStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, JSOp op)
|
||||
: ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICUnaryArith_Double>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetElem
|
||||
// JSOP_GETELEM
|
||||
|
||||
|
|
|
@ -1427,7 +1427,142 @@ ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// UnaryArith_Fallback
|
||||
//
|
||||
|
||||
static bool
|
||||
DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub_,
|
||||
HandleValue val, MutableHandleValue res)
|
||||
{
|
||||
// This fallback stub may trigger debug mode toggling.
|
||||
DebugModeOSRVolatileStub<ICUnaryArith_Fallback*> stub(frame, stub_);
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||
JSOp op = JSOp(*pc);
|
||||
FallbackICSpew(cx, stub, "UnaryArith(%s)", js_CodeName[op]);
|
||||
|
||||
switch (op) {
|
||||
case JSOP_BITNOT: {
|
||||
int32_t result;
|
||||
if (!BitNot(cx, val, &result))
|
||||
return false;
|
||||
res.setInt32(result);
|
||||
break;
|
||||
}
|
||||
case JSOP_NEG:
|
||||
if (!NegOperation(cx, script, pc, val, res))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
}
|
||||
|
||||
// Check if debug mode toggling made the stub invalid.
|
||||
if (stub.invalid())
|
||||
return true;
|
||||
|
||||
if (res.isDouble())
|
||||
stub->setSawDoubleResult();
|
||||
|
||||
if (stub->numOptimizedStubs() >= ICUnaryArith_Fallback::MAX_OPTIMIZED_STUBS) {
|
||||
// TODO: Discard/replace stubs.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val.isInt32() && res.isInt32()) {
|
||||
JitSpew(JitSpew_BaselineIC, " Generating %s(Int32 => Int32) stub", js_CodeName[op]);
|
||||
ICUnaryArith_Int32::Compiler compiler(cx, op);
|
||||
ICStub* int32Stub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!int32Stub)
|
||||
return false;
|
||||
stub->addNewStub(int32Stub);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val.isNumber() && res.isNumber() && cx->runtime()->jitSupportsFloatingPoint) {
|
||||
JitSpew(JitSpew_BaselineIC, " Generating %s(Number => Number) stub", js_CodeName[op]);
|
||||
|
||||
// Unlink int32 stubs, the double stub handles both cases and TI specializes for both.
|
||||
stub->unlinkStubsWithKind(cx, ICStub::UnaryArith_Int32);
|
||||
|
||||
ICUnaryArith_Double::Compiler compiler(cx, op);
|
||||
ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!doubleStub)
|
||||
return false;
|
||||
stub->addNewStub(doubleStub);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*,
|
||||
HandleValue, MutableHandleValue);
|
||||
static const VMFunction DoUnaryArithFallbackInfo =
|
||||
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, TailCall, PopValues(1));
|
||||
|
||||
bool
|
||||
ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(engine_ == Engine::Baseline);
|
||||
MOZ_ASSERT(R0 == JSReturnOperand);
|
||||
|
||||
// Restore the tail call register.
|
||||
EmitRestoreTailCallReg(masm);
|
||||
|
||||
// Ensure stack is fully synced for the expression decompiler.
|
||||
masm.pushValue(R0);
|
||||
|
||||
// Push arguments.
|
||||
masm.pushValue(R0);
|
||||
masm.push(ICStubReg);
|
||||
pushFramePtr(masm, R0.scratchReg());
|
||||
|
||||
return tailCallVM(DoUnaryArithFallbackInfo, masm);
|
||||
}
|
||||
|
||||
bool
|
||||
ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(engine_ == Engine::Baseline);
|
||||
|
||||
Label failure;
|
||||
masm.ensureDouble(R0, FloatReg0, &failure);
|
||||
|
||||
MOZ_ASSERT(op == JSOP_NEG || op == JSOP_BITNOT);
|
||||
|
||||
if (op == JSOP_NEG) {
|
||||
masm.negateDouble(FloatReg0);
|
||||
masm.boxDouble(FloatReg0, R0);
|
||||
} else {
|
||||
// Truncate the double to an int32.
|
||||
Register scratchReg = R1.scratchReg();
|
||||
|
||||
Label doneTruncate;
|
||||
Label truncateABICall;
|
||||
masm.branchTruncateDouble(FloatReg0, scratchReg, &truncateABICall);
|
||||
masm.jump(&doneTruncate);
|
||||
|
||||
masm.bind(&truncateABICall);
|
||||
masm.setupUnalignedABICall(scratchReg);
|
||||
masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
|
||||
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32));
|
||||
masm.storeCallResult(scratchReg);
|
||||
|
||||
masm.bind(&doneTruncate);
|
||||
masm.not32(scratchReg);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0);
|
||||
}
|
||||
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Failure case - jump to next stub
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
|
|
@ -1389,6 +1389,95 @@ class ICBinaryArith_DoubleWithInt32 : public ICStub
|
|||
};
|
||||
};
|
||||
|
||||
// UnaryArith
|
||||
// JSOP_BITNOT
|
||||
// JSOP_NEG
|
||||
|
||||
class ICUnaryArith_Fallback : public ICFallbackStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Fallback(JitCode* stubCode)
|
||||
: ICFallbackStub(UnaryArith_Fallback, stubCode)
|
||||
{
|
||||
extra_ = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
static const uint32_t MAX_OPTIMIZED_STUBS = 8;
|
||||
|
||||
bool sawDoubleResult() {
|
||||
return extra_;
|
||||
}
|
||||
void setSawDoubleResult() {
|
||||
extra_ = 1;
|
||||
}
|
||||
|
||||
// Compiler for this stub kind.
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
explicit Compiler(JSContext* cx)
|
||||
: ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICUnaryArith_Fallback>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ICUnaryArith_Int32 : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Int32(JitCode* stubCode)
|
||||
: ICStub(UnaryArith_Int32, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
class Compiler : public ICMultiStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, JSOp op)
|
||||
: ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICUnaryArith_Int32>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ICUnaryArith_Double : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICUnaryArith_Double(JitCode* stubCode)
|
||||
: ICStub(UnaryArith_Double, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
class Compiler : public ICMultiStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, JSOp op)
|
||||
: ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op, Engine::Baseline)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICUnaryArith_Double>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче