[JAEGER] Bug 580114: fix constant-type optimization of JSOP_INSTANCEOF in the method jit, r=dvander

--HG--
extra : rebase_source : c98b6a8d1e40cc5597afcefffdb1a3091813d381
This commit is contained in:
David Mandelin 2010-07-19 18:34:08 -07:00
parent 3c92cb6c14
commit d5a8633709
4 changed files with 37 additions and 13 deletions

View File

@ -2961,14 +2961,11 @@ mjit::Compiler::jsop_unbrand()
void
mjit::Compiler::jsop_instanceof()
{
FrameEntry *lhs = frame.peek(-2);
FrameEntry *rhs = frame.peek(-1);
/*
* Optimize only function objects, as these will have js_FunctionClass and
* thus have fun_instanceOf, which we're inlining.
*/
if (rhs->isTypeKnown() && rhs->getKnownType() != JSVAL_TYPE_OBJECT) {
// The fast path applies only when both operands are objects.
if (rhs->isNotType(JSVAL_TYPE_OBJECT) || lhs->isNotType(JSVAL_TYPE_OBJECT)) {
prepareStubCall(Uses(2));
stubCall(stubs::InstanceOf);
frame.popn(2);
@ -2977,9 +2974,8 @@ mjit::Compiler::jsop_instanceof()
return;
}
Jump firstSlow;
bool typeKnown = rhs->isTypeKnown();
if (!typeKnown) {
MaybeJump firstSlow;
if (!rhs->isTypeKnown()) {
Jump j = frame.testObject(Assembler::NotEqual, rhs);
stubcc.linkExit(j, Uses(2));
RegisterID reg = frame.tempRegForData(rhs);
@ -3001,12 +2997,13 @@ mjit::Compiler::jsop_instanceof()
stubcc.linkExit(j, Uses(3));
/* Allocate registers up front, because of branchiness. */
FrameEntry *lhs = frame.peek(-3);
RegisterID obj = frame.copyDataIntoReg(lhs);
RegisterID proto = frame.copyDataIntoReg(rhs);
RegisterID temp = frame.allocReg();
Jump isFalse = frame.testPrimitive(Assembler::Equal, lhs);
MaybeJump isFalse;
if (!lhs->isTypeKnown())
isFalse = frame.testPrimitive(Assembler::Equal, lhs);
/* Quick test to avoid wrapped objects. */
masm.loadPtr(Address(obj, offsetof(JSObject, clasp)), temp);
@ -3026,7 +3023,8 @@ mjit::Compiler::jsop_instanceof()
masm.move(Imm32(1), temp);
isTrue = masm.jump();
isFalse.linkTo(masm.label(), &masm);
if (isFalse.isSet())
isFalse.getJump().linkTo(masm.label(), &masm);
isFalse2.linkTo(masm.label(), &masm);
masm.move(Imm32(0), temp);
isTrue.linkTo(masm.label(), &masm);
@ -3040,7 +3038,8 @@ mjit::Compiler::jsop_instanceof()
frame.popn(3);
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, temp);
firstSlow.linkTo(stubcc.masm.label(), &stubcc.masm);
if (firstSlow.isSet())
firstSlow.getJump().linkTo(stubcc.masm.label(), &stubcc.masm);
stubcc.rejoin(Changes(1));
}

View File

@ -143,6 +143,8 @@ class Compiler
inline void setJump(const Jump &j) { jump = j; set = true; }
inline bool isSet() const { return set; }
inline MaybeJump &operator=(Jump j) { setJump(j); return *this; }
private:
Jump jump;
bool set;

View File

@ -81,6 +81,16 @@ class FrameEntry
return knownType;
}
// Return true iff the type of this value is definitely known to be type_.
bool isType(JSValueType type_) const {
return isTypeKnown() && getKnownType() == type_;
}
// Return true iff the type of this value is definitely known not to be type_.
bool isNotType(JSValueType type_) const {
return isTypeKnown() && getKnownType() != type_;
}
uint32 getPayload32() const {
//JS_ASSERT(!Valueify(v_.asBits).isDouble() || type.synced());
return v_.s.payload.u32;

View File

@ -0,0 +1,13 @@
// |trace-test| error: TypeError
// Verify that the compiler doesn't assert.
function f() {
var o = {}, p = {};
z = o instanceof p;
z = 3 instanceof p;
z = p instanceof 3;
z = 3 instanceof 4;
}
f();