mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 664824 - JM+TI: Make JSOP_IN fast for dense arrays. r=jandem
This commit is contained in:
parent
a71396ead0
commit
3352dc9370
21
js/src/jit-test/tests/jaeger/in.js
Normal file
21
js/src/jit-test/tests/jaeger/in.js
Normal file
@ -0,0 +1,21 @@
|
||||
function f(arr, b) {
|
||||
var res = "";
|
||||
var a;
|
||||
if (b)
|
||||
a = arr;
|
||||
for (var i=100; i>-200; i--) {
|
||||
if (i in a) {
|
||||
res += i;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
assertEq(f([1, , 2, 3], true), "320");
|
||||
|
||||
try {
|
||||
f([1, , 2, 3], false);
|
||||
assertEq(0, 1);
|
||||
} catch(e) {
|
||||
assertEq(e instanceof TypeError, true);
|
||||
}
|
@ -791,6 +791,20 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
|
||||
return branch32(cond, extent, key.reg());
|
||||
}
|
||||
|
||||
Jump guardElementNotHole(RegisterID elements, const Int32Key &key) {
|
||||
Jump jmp;
|
||||
|
||||
if (key.isConstant()) {
|
||||
Address slot(elements, key.index() * sizeof(Value));
|
||||
jmp = guardNotHole(slot);
|
||||
} else {
|
||||
BaseIndex slot(elements, key.reg(), JSVAL_SCALE);
|
||||
jmp = guardNotHole(slot);
|
||||
}
|
||||
|
||||
return jmp;
|
||||
}
|
||||
|
||||
// Load a jsval from an array slot, given a key. |objReg| is clobbered.
|
||||
FastArrayLoadFails fastArrayLoad(RegisterID objReg, const Int32Key &key,
|
||||
RegisterID typeReg, RegisterID dataReg) {
|
||||
|
@ -2966,11 +2966,7 @@ mjit::Compiler::generateMethod()
|
||||
|
||||
BEGIN_CASE(JSOP_IN)
|
||||
{
|
||||
prepareStubCall(Uses(2));
|
||||
INLINE_STUBCALL(stubs::In, REJOIN_PUSH_BOOLEAN);
|
||||
frame.popn(2);
|
||||
frame.takeReg(Registers::ReturnReg);
|
||||
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
|
||||
jsop_in();
|
||||
}
|
||||
END_CASE(JSOP_IN)
|
||||
|
||||
@ -7448,6 +7444,76 @@ mjit::Compiler::jsop_toid()
|
||||
stubcc.rejoin(Changes(1));
|
||||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::jsop_in()
|
||||
{
|
||||
FrameEntry *obj = frame.peek(-1);
|
||||
FrameEntry *id = frame.peek(-2);
|
||||
|
||||
if (cx->typeInferenceEnabled() && id->isType(JSVAL_TYPE_INT32)) {
|
||||
types::TypeSet *types = analysis->poppedTypes(PC, 0);
|
||||
|
||||
if (obj->mightBeType(JSVAL_TYPE_OBJECT) &&
|
||||
!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY) &&
|
||||
!types::ArrayPrototypeHasIndexedProperty(cx, outerScript))
|
||||
{
|
||||
bool isPacked = !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY);
|
||||
|
||||
if (!obj->isTypeKnown()) {
|
||||
Jump guard = frame.testObject(Assembler::NotEqual, obj);
|
||||
stubcc.linkExit(guard, Uses(2));
|
||||
}
|
||||
|
||||
RegisterID dataReg = frame.copyDataIntoReg(obj);
|
||||
|
||||
Int32Key key = id->isConstant()
|
||||
? Int32Key::FromConstant(id->getValue().toInt32())
|
||||
: Int32Key::FromRegister(frame.tempRegForData(id));
|
||||
|
||||
masm.loadPtr(Address(dataReg, JSObject::offsetOfElements()), dataReg);
|
||||
|
||||
// Guard on the array's initialized length.
|
||||
Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
|
||||
dataReg, key, Assembler::BelowOrEqual);
|
||||
|
||||
// Guard to make sure we don't have a hole. Skip it if the array is packed.
|
||||
MaybeJump holeCheck;
|
||||
if (!isPacked)
|
||||
holeCheck = masm.guardElementNotHole(dataReg, key);
|
||||
|
||||
masm.move(Imm32(1), dataReg);
|
||||
Jump done = masm.jump();
|
||||
|
||||
Label falseBranch = masm.label();
|
||||
initlenGuard.linkTo(falseBranch, &masm);
|
||||
if (!isPacked)
|
||||
holeCheck.getJump().linkTo(falseBranch, &masm);
|
||||
masm.move(Imm32(0), dataReg);
|
||||
|
||||
done.linkTo(masm.label(), &masm);
|
||||
|
||||
stubcc.leave();
|
||||
OOL_STUBCALL_USES(stubs::In, REJOIN_PUSH_BOOLEAN, Uses(2));
|
||||
|
||||
frame.popn(2);
|
||||
if (dataReg != Registers::ReturnReg)
|
||||
stubcc.masm.move(Registers::ReturnReg, dataReg);
|
||||
|
||||
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, dataReg);
|
||||
|
||||
stubcc.rejoin(Changes(2));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
prepareStubCall(Uses(2));
|
||||
INLINE_STUBCALL(stubs::In, REJOIN_PUSH_BOOLEAN);
|
||||
frame.popn(2);
|
||||
frame.takeReg(Registers::ReturnReg);
|
||||
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* For any locals or args which we know to be integers but are treated as
|
||||
* doubles by the type inference, convert to double. These will be assumed to be
|
||||
|
@ -753,6 +753,7 @@ private:
|
||||
CompileStatus jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused);
|
||||
bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
|
||||
void jsop_pos();
|
||||
void jsop_in();
|
||||
|
||||
static inline Assembler::Condition
|
||||
GetCompareCondition(JSOp op, JSOp fused)
|
||||
|
Loading…
Reference in New Issue
Block a user