mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
Bug 846531 - Add optimized stub for Compare(Boolean x Int32). r=bhackett
This commit is contained in:
parent
cb5ae90745
commit
02c6091256
@ -1509,6 +1509,9 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
||||
if ((lhs.isNumber() && rhs.isUndefined()) ||
|
||||
(lhs.isUndefined() && rhs.isNumber()))
|
||||
{
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(%s, %s) stub", js_CodeName[op],
|
||||
rhs.isUndefined() ? "Number" : "Undefined",
|
||||
rhs.isUndefined() ? "Undefined" : "Number");
|
||||
ICCompare_NumberWithUndefined::Compiler compiler(cx, op, lhs.isUndefined());
|
||||
ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!stub)
|
||||
@ -1519,6 +1522,7 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
||||
}
|
||||
|
||||
if (lhs.isBoolean() && rhs.isBoolean()) {
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(Boolean, Boolean) stub", js_CodeName[op]);
|
||||
ICCompare_Boolean::Compiler compiler(cx, op);
|
||||
ICStub *booleanStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!booleanStub)
|
||||
@ -1528,6 +1532,19 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((lhs.isBoolean() && rhs.isInt32()) || (lhs.isInt32() && rhs.isBoolean())) {
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(%s, %s) stub", js_CodeName[op],
|
||||
rhs.isInt32() ? "Boolean" : "Int32",
|
||||
rhs.isInt32() ? "Int32" : "Boolean");
|
||||
ICCompare_Int32WithBoolean::Compiler compiler(cx, op, lhs.isInt32());
|
||||
ICStub *optStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!optStub)
|
||||
return false;
|
||||
|
||||
stub->addNewStub(optStub);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsEqualityOp(op)) {
|
||||
if (lhs.isString() && rhs.isString() && !stub->hasStub(ICStub::Compare_String)) {
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(String, String) stub", js_CodeName[op]);
|
||||
@ -1542,6 +1559,7 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
||||
|
||||
if (lhs.isObject() && rhs.isObject()) {
|
||||
JS_ASSERT(!stub->hasStub(ICStub::Compare_Object));
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(Object, Object) stub", js_CodeName[op]);
|
||||
ICCompare_Object::Compiler compiler(cx, op);
|
||||
ICStub *objectStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!objectStub)
|
||||
@ -1555,6 +1573,8 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
||||
(rhs.isObject() || rhs.isNull() || rhs.isUndefined()) &&
|
||||
!stub->hasStub(ICStub::Compare_ObjectWithUndefined))
|
||||
{
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(Obj/Null/Undef, Obj/Null/Undef) stub",
|
||||
js_CodeName[op]);
|
||||
bool lhsIsUndefined = lhs.isNull() || lhs.isUndefined();
|
||||
bool compareWithNull = lhs.isNull() || rhs.isNull();
|
||||
ICCompare_ObjectWithUndefined::Compiler compiler(cx, op,
|
||||
@ -1797,6 +1817,51 @@ ICCompare_ObjectWithUndefined::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Compare_Int32WithBoolean
|
||||
//
|
||||
|
||||
bool
|
||||
ICCompare_Int32WithBoolean::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
ValueOperand int32Val;
|
||||
ValueOperand boolVal;
|
||||
if (lhsIsInt32_) {
|
||||
int32Val = R0;
|
||||
boolVal = R1;
|
||||
} else {
|
||||
boolVal = R0;
|
||||
int32Val = R1;
|
||||
}
|
||||
masm.branchTestBoolean(Assembler::NotEqual, boolVal, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, int32Val, &failure);
|
||||
|
||||
if (op_ == JSOP_STRICTEQ || op_ == JSOP_STRICTNE) {
|
||||
// Ints and booleans are never strictly equal, always strictly not equal.
|
||||
masm.moveValue(BooleanValue(op_ == JSOP_STRICTNE), R0);
|
||||
EmitReturnFromIC(masm);
|
||||
} else {
|
||||
Register boolReg = masm.extractBoolean(boolVal, ExtractTemp0);
|
||||
Register int32Reg = masm.extractInt32(int32Val, ExtractTemp1);
|
||||
|
||||
// Compare payload regs of R0 and R1.
|
||||
Assembler::Condition cond = JSOpToCondition(op_);
|
||||
masm.cmp32(lhsIsInt32_ ? int32Reg : boolReg,
|
||||
lhsIsInt32_ ? boolReg : int32Reg);
|
||||
masm.emitSet(cond, R0.scratchReg());
|
||||
|
||||
// Box the result and return
|
||||
masm.tagValue(JSVAL_TYPE_BOOLEAN, R0.scratchReg(), R0);
|
||||
EmitReturnFromIC(masm);
|
||||
}
|
||||
|
||||
// Failure case - jump to next stub
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// ToBool_Fallback
|
||||
//
|
||||
|
@ -296,6 +296,7 @@ class ICEntry
|
||||
_(Compare_Boolean) \
|
||||
_(Compare_Object) \
|
||||
_(Compare_ObjectWithUndefined) \
|
||||
_(Compare_Int32WithBoolean) \
|
||||
\
|
||||
_(ToBool_Fallback) \
|
||||
_(ToBool_Int32) \
|
||||
@ -1881,6 +1882,54 @@ class ICCompare_ObjectWithUndefined : public ICStub
|
||||
};
|
||||
};
|
||||
|
||||
class ICCompare_Int32WithBoolean : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
ICCompare_Int32WithBoolean(IonCode *stubCode, bool lhsIsInt32)
|
||||
: ICStub(ICStub::Compare_Int32WithBoolean, stubCode)
|
||||
{
|
||||
extra_ = lhsIsInt32;
|
||||
}
|
||||
|
||||
public:
|
||||
static inline ICCompare_Int32WithBoolean *New(ICStubSpace *space, IonCode *code,
|
||||
bool lhsIsInt32)
|
||||
{
|
||||
if (!code)
|
||||
return NULL;
|
||||
return space->allocate<ICCompare_Int32WithBoolean>(code, lhsIsInt32);
|
||||
}
|
||||
|
||||
bool lhsIsInt32() const {
|
||||
return extra_;
|
||||
}
|
||||
|
||||
// Compiler for this stub kind.
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
JSOp op_;
|
||||
bool lhsIsInt32_;
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
return (static_cast<int32_t>(kind) | (static_cast<int32_t>(op_) << 16) |
|
||||
(static_cast<int32_t>(lhsIsInt32_) << 24));
|
||||
}
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx, JSOp op, bool lhsIsInt32)
|
||||
: ICStubCompiler(cx, ICStub::Compare_Int32WithBoolean),
|
||||
op_(op),
|
||||
lhsIsInt32_(lhsIsInt32)
|
||||
{}
|
||||
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
return ICCompare_Int32WithBoolean::New(space, getStubCode(), lhsIsInt32_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// ToBool
|
||||
// JSOP_IFNE
|
||||
|
||||
|
@ -644,6 +644,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
Register extractInt32(const ValueOperand &value, Register scratch) {
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractBoolean(const ValueOperand &value, Register scratch) {
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractTag(const Address &address, Register scratch);
|
||||
Register extractTag(const BaseIndex &address, Register scratch);
|
||||
Register extractTag(const ValueOperand &value, Register scratch) {
|
||||
|
@ -803,6 +803,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
unboxInt32(value, scratch);
|
||||
return scratch;
|
||||
}
|
||||
Register extractBoolean(const ValueOperand &value, Register scratch) {
|
||||
JS_ASSERT(scratch != ScratchReg);
|
||||
unboxBoolean(value, scratch);
|
||||
return scratch;
|
||||
}
|
||||
Register extractTag(const Address &address, Register scratch) {
|
||||
JS_ASSERT(scratch != ScratchReg);
|
||||
loadPtr(address, scratch);
|
||||
|
@ -685,6 +685,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
Register extractInt32(const ValueOperand &value, Register scratch) {
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractBoolean(const ValueOperand &value, Register scratch) {
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractTag(const Address &address, Register scratch) {
|
||||
movl(tagOf(address), scratch);
|
||||
return scratch;
|
||||
|
Loading…
Reference in New Issue
Block a user