diff --git a/js/src/methodjit/BaseCompiler.h b/js/src/methodjit/BaseCompiler.h index 43bffef12f5a..f9d6281fef8b 100644 --- a/js/src/methodjit/BaseCompiler.h +++ b/js/src/methodjit/BaseCompiler.h @@ -266,7 +266,8 @@ class AutoReserveICSpace { } }; -# define RESERVE_IC_SPACE(__masm) AutoReserveICSpace<96> arics(__masm) +# define RESERVE_IC_SPACE(__masm) AutoReserveICSpace<128> arics(__masm) +# define CHECK_IC_SPACE() arics.check() /* The OOL path can need a lot of space because we save and restore a lot of registers. The actual * sequene varies. However, dumping the literal pool before an OOL block is probably a good idea @@ -278,6 +279,7 @@ class AutoReserveICSpace { # define CHECK_OOL_SPACE() arics_ool.check() #else # define RESERVE_IC_SPACE(__masm) /* Do nothing. */ +# define CHECK_IC_SPACE() /* Do nothing. */ # define RESERVE_OOL_SPACE(__masm) /* Do nothing. */ # define CHECK_OOL_SPACE() /* Do nothing. */ #endif diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 2b4564796689..9d32ceff86bb 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -2518,6 +2518,21 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew) RegisterID icCalleeData; /* data to call */ Address icRvalAddr; /* return slot on slow-path rejoin */ + /* + * IC space must be reserved (using RESERVE_IC_SPACE or RESERVE_OOL_SPACE) between the + * following labels (as used in finishThisUp): + * - funGuard -> hotJump + * - funGuard -> joinPoint + * - funGuard -> hotPathLabel + * - slowPathStart -> oolCall + * - slowPathStart -> oolJump + * - slowPathStart -> icCall + * - slowPathStart -> slowJoinPoint + * Because the call ICs are fairly long (compared to PICs), we don't reserve the space in each + * path until the first usage of funGuard (for the in-line path) or slowPathStart (for the + * out-of-line path). + */ + /* Initialized only on lowerFunCallOrApply branch. */ Jump uncachedCallSlowRejoin; CallPatchInfo uncachedCallPatch; @@ -2594,6 +2609,9 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew) } RegisterID funPtrReg = tempRegs.takeRegInMask(Registers::SavedRegs); + /* Reserve space just before initialization of funGuard. */ + RESERVE_IC_SPACE(masm); + /* * Guard on the callee identity. This misses on the first run. If the * callee is scripted, compiled/compilable, and argc == nargs, then this @@ -2602,6 +2620,9 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew) Jump j = masm.branchPtrWithPatch(Assembler::NotEqual, icCalleeData, callIC.funGuard); callIC.funJump = j; + /* Reserve space just before initialization of slowPathStart. */ + RESERVE_OOL_SPACE(stubcc.masm); + Jump rejoin1, rejoin2; { stubcc.linkExitDirect(j, stubcc.masm.label()); @@ -2710,6 +2731,12 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew) uncachedCallPatch.joinPoint = callIC.joinPoint; masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfPrev()), JSFrameReg); + /* + * We've placed hotJump, joinPoint and hotPathLabel, and no other labels are located by offset + * in the in-line path so we can check the IC space now. + */ + CHECK_IC_SPACE(); + frame.popn(speculatedArgc + 2); frame.takeReg(JSReturnReg_Type); frame.takeReg(JSReturnReg_Data); @@ -2729,6 +2756,8 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew) stubcc.crossJump(stubcc.masm.jump(), masm.label()); JaegerSpew(JSpew_Insns, " ---- END SLOW RESTORE CODE ---- \n"); + CHECK_OOL_SPACE(); + if (lowerFunCallOrApply) stubcc.crossJump(uncachedCallSlowRejoin, masm.label());