author | Shu-yu Guo <shu@rfrn.org> |
Mon, 14 Apr 2014 22:00:07 -0700 | |
changeset 178447 | a71e790f9652157844c03f9c700ff1cdcfdc3f8b |
parent 178446 | 0ff06ac4a4349a4ca72d709274b291c4498c4bd5 |
child 178448 | 5f65bfd35342939845d341d4ea5861a7c56feec6 |
push id | 42283 |
push user | shu@rfrn.org |
push date | Tue, 15 Apr 2014 04:56:37 +0000 |
treeherder | mozilla-inbound@6c2aaabb1f35 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 994444 |
milestone | 31.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
|
--- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -387,16 +387,27 @@ GetStubReturnAddress(JSContext *cx, jsby return cx->compartment()->jitCompartment()->baselineGetPropReturnAddr(); if (IsSetPropPC(pc)) return cx->compartment()->jitCompartment()->baselineSetPropReturnAddr(); // This should be a call op of some kind, now. JS_ASSERT(IsCallPC(pc)); return cx->compartment()->jitCompartment()->baselineCallReturnAddr(); } +static inline jsbytecode * +GetNextNonLoopEntryPc(jsbytecode *pc) +{ + JSOp op = JSOp(*pc); + if (op == JSOP_GOTO) + return pc + GET_JUMP_OFFSET(pc); + if (op == JSOP_LOOPENTRY || op == JSOP_NOP || op == JSOP_LOOPHEAD) + return GetNextPc(pc); + return pc; +} + // For every inline frame, we write out the following data: // // | ... | // +---------------+ // | Descr(???) | --- Descr size here is (PREV_FRAME_SIZE) // +---------------+ // | ReturnAddr | // -- +===============+ --- OVERWRITE STARTS HERE (START_STACK_ADDR) @@ -778,26 +789,28 @@ InitFromBailout(JSContext *cx, HandleScr return false; } size_t endOfBaselineJSFrameStack = builder.framePushed(); // If we are resuming at a LOOPENTRY op, resume at the next op to avoid // a bailout -> enter Ion -> bailout loop with --ion-eager. See also // ThunkToInterpreter. + // + // The algorithm below is the "tortoise and the hare" algorithm. See bug + // 994444 for more explanation. if (!resumeAfter) { + jsbytecode *fasterPc = pc; while (true) { - op = JSOp(*pc); - if (op == JSOP_GOTO) - pc += GET_JUMP_OFFSET(pc); - else if (op == JSOP_LOOPENTRY || op == JSOP_NOP || op == JSOP_LOOPHEAD) - pc = GetNextPc(pc); - else + pc = GetNextNonLoopEntryPc(pc); + fasterPc = GetNextNonLoopEntryPc(GetNextNonLoopEntryPc(fasterPc)); + if (fasterPc == pc) break; } + op = JSOp(*pc); } uint32_t pcOff = script->pcToOffset(pc); bool isCall = IsCallPC(pc); BaselineScript *baselineScript = script->baselineScript(); #ifdef DEBUG uint32_t expectedDepth;