mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 846531 - Add optimized stub for Compare(Boolean x Int32). r=bhackett
This commit is contained in:
parent
574d0b6833
commit
5a5f242200
@ -1509,6 +1509,9 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
|||||||
if ((lhs.isNumber() && rhs.isUndefined()) ||
|
if ((lhs.isNumber() && rhs.isUndefined()) ||
|
||||||
(lhs.isUndefined() && rhs.isNumber()))
|
(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());
|
ICCompare_NumberWithUndefined::Compiler compiler(cx, op, lhs.isUndefined());
|
||||||
ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
|
ICStub *doubleStub = compiler.getStub(compiler.getStubSpace(script));
|
||||||
if (!stub)
|
if (!stub)
|
||||||
@ -1519,6 +1522,7 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lhs.isBoolean() && rhs.isBoolean()) {
|
if (lhs.isBoolean() && rhs.isBoolean()) {
|
||||||
|
IonSpew(IonSpew_BaselineIC, " Generating %s(Boolean, Boolean) stub", js_CodeName[op]);
|
||||||
ICCompare_Boolean::Compiler compiler(cx, op);
|
ICCompare_Boolean::Compiler compiler(cx, op);
|
||||||
ICStub *booleanStub = compiler.getStub(compiler.getStubSpace(script));
|
ICStub *booleanStub = compiler.getStub(compiler.getStubSpace(script));
|
||||||
if (!booleanStub)
|
if (!booleanStub)
|
||||||
@ -1528,6 +1532,19 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
|||||||
return true;
|
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 (IsEqualityOp(op)) {
|
||||||
if (lhs.isString() && rhs.isString() && !stub->hasStub(ICStub::Compare_String)) {
|
if (lhs.isString() && rhs.isString() && !stub->hasStub(ICStub::Compare_String)) {
|
||||||
IonSpew(IonSpew_BaselineIC, " Generating %s(String, String) stub", js_CodeName[op]);
|
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()) {
|
if (lhs.isObject() && rhs.isObject()) {
|
||||||
JS_ASSERT(!stub->hasStub(ICStub::Compare_Object));
|
JS_ASSERT(!stub->hasStub(ICStub::Compare_Object));
|
||||||
|
IonSpew(IonSpew_BaselineIC, " Generating %s(Object, Object) stub", js_CodeName[op]);
|
||||||
ICCompare_Object::Compiler compiler(cx, op);
|
ICCompare_Object::Compiler compiler(cx, op);
|
||||||
ICStub *objectStub = compiler.getStub(compiler.getStubSpace(script));
|
ICStub *objectStub = compiler.getStub(compiler.getStubSpace(script));
|
||||||
if (!objectStub)
|
if (!objectStub)
|
||||||
@ -1555,6 +1573,8 @@ DoCompareFallback(JSContext *cx, ICCompare_Fallback *stub, HandleValue lhs, Hand
|
|||||||
(rhs.isObject() || rhs.isNull() || rhs.isUndefined()) &&
|
(rhs.isObject() || rhs.isNull() || rhs.isUndefined()) &&
|
||||||
!stub->hasStub(ICStub::Compare_ObjectWithUndefined))
|
!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 lhsIsUndefined = lhs.isNull() || lhs.isUndefined();
|
||||||
bool compareWithNull = lhs.isNull() || rhs.isNull();
|
bool compareWithNull = lhs.isNull() || rhs.isNull();
|
||||||
ICCompare_ObjectWithUndefined::Compiler compiler(cx, op,
|
ICCompare_ObjectWithUndefined::Compiler compiler(cx, op,
|
||||||
@ -1797,6 +1817,51 @@ ICCompare_ObjectWithUndefined::Compiler::generateStubCode(MacroAssembler &masm)
|
|||||||
return true;
|
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
|
// ToBool_Fallback
|
||||||
//
|
//
|
||||||
|
@ -296,6 +296,7 @@ class ICEntry
|
|||||||
_(Compare_Boolean) \
|
_(Compare_Boolean) \
|
||||||
_(Compare_Object) \
|
_(Compare_Object) \
|
||||||
_(Compare_ObjectWithUndefined) \
|
_(Compare_ObjectWithUndefined) \
|
||||||
|
_(Compare_Int32WithBoolean) \
|
||||||
\
|
\
|
||||||
_(ToBool_Fallback) \
|
_(ToBool_Fallback) \
|
||||||
_(ToBool_Int32) \
|
_(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
|
// ToBool
|
||||||
// JSOP_IFNE
|
// JSOP_IFNE
|
||||||
|
|
||||||
|
@ -644,6 +644,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||||||
Register extractInt32(const ValueOperand &value, Register scratch) {
|
Register extractInt32(const ValueOperand &value, Register scratch) {
|
||||||
return value.payloadReg();
|
return value.payloadReg();
|
||||||
}
|
}
|
||||||
|
Register extractBoolean(const ValueOperand &value, Register scratch) {
|
||||||
|
return value.payloadReg();
|
||||||
|
}
|
||||||
Register extractTag(const Address &address, Register scratch);
|
Register extractTag(const Address &address, Register scratch);
|
||||||
Register extractTag(const BaseIndex &address, Register scratch);
|
Register extractTag(const BaseIndex &address, Register scratch);
|
||||||
Register extractTag(const ValueOperand &value, Register scratch) {
|
Register extractTag(const ValueOperand &value, Register scratch) {
|
||||||
|
@ -803,6 +803,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||||||
unboxInt32(value, scratch);
|
unboxInt32(value, scratch);
|
||||||
return 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) {
|
Register extractTag(const Address &address, Register scratch) {
|
||||||
JS_ASSERT(scratch != ScratchReg);
|
JS_ASSERT(scratch != ScratchReg);
|
||||||
loadPtr(address, scratch);
|
loadPtr(address, scratch);
|
||||||
|
@ -685,6 +685,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
|||||||
Register extractInt32(const ValueOperand &value, Register scratch) {
|
Register extractInt32(const ValueOperand &value, Register scratch) {
|
||||||
return value.payloadReg();
|
return value.payloadReg();
|
||||||
}
|
}
|
||||||
|
Register extractBoolean(const ValueOperand &value, Register scratch) {
|
||||||
|
return value.payloadReg();
|
||||||
|
}
|
||||||
Register extractTag(const Address &address, Register scratch) {
|
Register extractTag(const Address &address, Register scratch) {
|
||||||
movl(tagOf(address), scratch);
|
movl(tagOf(address), scratch);
|
||||||
return scratch;
|
return scratch;
|
||||||
|
Loading…
Reference in New Issue
Block a user