diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 5352718694e..9cc152f51e5 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -464,7 +464,7 @@ mjit::Compiler::generateMethod() BEGIN_CASE(JSOP_FORLOCAL) iterNext(); - frame.storeLocal(GET_SLOTNO(PC)); + frame.storeLocal(GET_SLOTNO(PC), true); frame.pop(); END_CASE(JSOP_FORLOCAL) @@ -2477,38 +2477,39 @@ mjit::Compiler::iterNext() Address privSlot(reg, offsetof(JSObject, fslots) + sizeof(Value) * JSSLOT_PRIVATE); masm.loadData32(privSlot, T1); - RegisterID T2 = frame.allocReg(); RegisterID T3 = frame.allocReg(); - - /* Get cursor. */ - masm.loadPtr(Address(T1, offsetof(NativeIterator, props_cursor)), T2); - - /* Test type. */ - Jump isString = masm.branch32(Assembler::Equal, - masm.payloadOf(Address(T2, 0)), - Imm32(int32(JSVAL_TAG_STRING))); + RegisterID T4 = frame.allocReg(); /* Test if for-each. */ masm.load32(Address(T1, offsetof(NativeIterator, flags)), T3); masm.and32(Imm32(JSITER_FOREACH), T3); - notFast = masm.branchTest32(Assembler::Zero, T3, T3); + notFast = masm.branchTest32(Assembler::NonZero, T3, T3); + stubcc.linkExit(notFast); + + RegisterID T2 = frame.allocReg(); + + /* Get cursor. */ + masm.loadPtr(Address(T1, offsetof(NativeIterator, props_cursor)), T2); + + /* Test if the jsid is a string. */ + masm.loadPtr(T2, T3); + masm.move(T3, T4); + masm.andPtr(Imm32(JSID_TYPE_MASK), T4); + notFast = masm.branchTestPtr(Assembler::NonZero, T4, T4); stubcc.linkExit(notFast); - isString.linkTo(masm.label(), &masm); /* It's safe to increase the cursor now. */ - masm.addPtr(Imm32(sizeof(Value)), T2, T3); - masm.storePtr(T3, Address(T1, offsetof(NativeIterator, props_cursor))); + masm.addPtr(Imm32(sizeof(jsid)), T2, T4); + masm.storePtr(T4, Address(T1, offsetof(NativeIterator, props_cursor))); - /* Done with T1 and T3! */ + frame.freeReg(T4); frame.freeReg(T1); - frame.freeReg(T3); + frame.freeReg(T2); stubcc.leave(); stubcc.call(stubs::IterNext); - /* Now... */ - frame.freeReg(T2); - frame.push(Address(T2, 0)); + frame.pushUntypedPayload(JSVAL_TAG_STRING, T3); /* Join with the stub call. */ stubcc.rejoin(1); diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index f5dd12293c5..18e23de31ea 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -292,7 +292,7 @@ FrameState::pushTypedPayload(JSValueTag tag, RegisterID payload) inline void FrameState::pushUntypedPayload(JSValueTag tag, RegisterID payload, - bool popGuaranteed) + bool popGuaranteed, bool fastType) { JS_ASSERT(!freeRegs.hasReg(payload)); @@ -310,7 +310,7 @@ FrameState::pushUntypedPayload(JSValueTag tag, RegisterID payload, if (popGuaranteed) { fe->setTypeTag(tag); } else { - if (!fe->type.synced()) + if (!fastType || !fe->type.synced()) masm.storeTypeTag(ImmTag(tag), addressOf(fe)); /* The forceful type sync will assert otherwise. */ @@ -640,9 +640,13 @@ FrameState::pushLocal(uint32 n) if (!eval && !escaping[n]) { pushCopyOf(indexOfFe(getLocal(n))); } else { - JS_ASSERT_IF(base[localIndex(n)], - entries[localIndex(n)].type.inMemory() && - entries[localIndex(n)].data.inMemory()); + if (FrameEntry *fe = base[localIndex(n)]) { + /* :TODO: we could do better here. */ + if (!fe->type.synced()) + syncType(fe, addressOf(fe), masm); + if (!fe->data.synced()) + syncData(fe, addressOf(fe), masm); + } push(Address(JSFrameReg, sizeof(JSStackFrame) + n * sizeof(Value))); } } diff --git a/js/src/methodjit/FrameState.h b/js/src/methodjit/FrameState.h index f939ed1a5b0..80bd784588f 100644 --- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -200,7 +200,8 @@ class FrameState * was taken. */ inline void pushUntypedPayload(JSValueTag tag, RegisterID payload, - bool popGuaranteed = false); + bool popGuaranteed = false, + bool fastTyped = false); /* * Pops a value off the operation stack, freeing any of its resources. diff --git a/js/src/methodjit/nunbox/FastOps.cpp b/js/src/methodjit/nunbox/FastOps.cpp index d3a6078a167..b223f1a55db 100644 --- a/js/src/methodjit/nunbox/FastOps.cpp +++ b/js/src/methodjit/nunbox/FastOps.cpp @@ -835,7 +835,7 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped) Registers::ArgReg1); stubcc.vpInc(op, depth); - frame.pushUntypedPayload(JSVAL_TAG_INT32, reg, true); + frame.pushUntypedPayload(JSVAL_TAG_INT32, reg, true, true); frame.storeLocal(slot, post || popped, false); if (post || popped)