author | Brian Hackett <bhackett1024@gmail.com> |
Fri, 12 Aug 2011 09:18:48 -0700 | |
changeset 77431 | 409b62513ac6ad4a1c2287376fb59ead21fe7550 |
parent 77430 | 0a8195cb7590cc4c803adced8fea4c1f99b34c03 |
child 77432 | 07361922fd67f3678cd65f29e9369c54f552a2f7 |
push id | 78 |
push user | clegnitto@mozilla.com |
push date | Fri, 16 Dec 2011 17:32:24 +0000 |
treeherder | mozilla-release@79d24e644fdd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 678141 |
milestone | 8.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/jaeger/bug678141.js @@ -0,0 +1,10 @@ + +c = {}.__proto__[1] = 3; +(function() { + function b(a) { + return a + } + for each(let z in [{}]) { + print(new b(z)) + } +})()
--- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -779,39 +779,39 @@ mjit::Compiler::generatePrologue() StackFrame::OVERFLOW_ARGS | StackFrame::HAS_ARGS_OBJ)); masm.storePtr(ImmPtr((void *) script->function()->nargs), Address(JSFrameReg, StackFrame::offsetOfArgs())); hasArgs.linkTo(masm.label(), &masm); } } + if (cx->typeInferenceEnabled()) { +#ifdef DEBUG + if (script->hasFunction) { + prepareStubCall(Uses(0)); + INLINE_STUBCALL(stubs::AssertArgumentTypes, REJOIN_NONE); + } +#endif + ensureDoubleArguments(); + } + if (isConstructing) { if (!constructThis()) return Compile_Error; } if (debugMode()) { prepareStubCall(Uses(0)); INLINE_STUBCALL(stubs::ScriptDebugPrologue, REJOIN_RESUME); } else if (Probes::callTrackingActive(cx)) { prepareStubCall(Uses(0)); INLINE_STUBCALL(stubs::ScriptProbeOnlyPrologue, REJOIN_RESUME); } - if (cx->typeInferenceEnabled()) { -#ifdef DEBUG - if (script->hasFunction) { - prepareStubCall(Uses(0)); - INLINE_STUBCALL(stubs::AssertArgumentTypes, REJOIN_NONE); - } -#endif - ensureDoubleArguments(); - } - recompileCheckHelper(); if (outerScript->pcCounters) { size_t length = ssa.frameLength(ssa.numFrames() - 1); pcLengths = (PCLengthEntry *) cx->calloc_(sizeof(pcLengths[0]) * length); if (!pcLengths) return Compile_Error; } @@ -2943,17 +2943,19 @@ mjit::Compiler::fixPrimitiveReturn(Assem // If the type is known to be an object, just load the return value as normal. if (fe && fe->isTypeKnown() && fe->getKnownType() == JSVAL_TYPE_OBJECT) { loadReturnValue(masm, fe); return; } // There's a return value, and its type is unknown. Test the type and load - // |thisv| if necessary. + // |thisv| if necessary. Sync the 'this' entry before doing so, as it may + // be stored in registers if we constructed it inline. + frame.syncThis(); loadReturnValue(masm, fe); Jump j = masm->testObject(Assembler::Equal, JSReturnReg_Type); masm->loadValueAsComponents(thisv, JSReturnReg_Type, JSReturnReg_Data); j.linkTo(masm->label(), masm); } // Loads the return value into the scripted ABI register pair, such that JS // semantics in constructors are preserved.
--- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -1310,34 +1310,37 @@ FrameState::pushThis() } void FrameState::learnThisIsObject(bool unsync) { // If the 'this' object is a copy, this must be an inline frame, in which // case we will trigger recompilation if the 'this' entry isn't actually // an object (thus, it is OK to modify the backing directly). - FrameEntry *fe = a->this_; - if (!fe->isTracked()) - addToTracker(fe); + FrameEntry *fe = getThis(); if (fe->isCopy()) fe = fe->copyOf(); learnType(fe, JSVAL_TYPE_OBJECT, unsync); } void FrameState::setThis(RegisterID reg) { - FrameEntry *fe = a->this_; - if (!fe->isTracked()) - addToTracker(fe); + FrameEntry *fe = getThis(); JS_ASSERT(!fe->isCopy()); learnType(fe, JSVAL_TYPE_OBJECT, reg); } +void +FrameState::syncThis() +{ + FrameEntry *fe = getThis(); + syncFe(fe); +} + inline void FrameState::leaveBlock(uint32 n) { popn(n); } inline void FrameState::enterBlock(uint32 n)
--- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -388,16 +388,17 @@ class FrameState // Pushes a copy of a slot (formal argument, local variable, or stack slot) // onto the operation stack. void pushLocal(uint32 n); void pushArg(uint32 n); void pushCallee(); void pushThis(); void pushCopyOf(FrameEntry *fe); inline void setThis(RegisterID reg); + inline void syncThis(); inline void learnThisIsObject(bool unsync = true); inline FrameEntry *getStack(uint32 slot); inline FrameEntry *getLocal(uint32 slot); inline FrameEntry *getArg(uint32 slot); inline FrameEntry *getSlotEntry(uint32 slot); /*