diff --git a/js/src/assembler/assembler/MacroAssemblerARM.h b/js/src/assembler/assembler/MacroAssemblerARM.h index c2ab0122ec5..16c57b8ff08 100644 --- a/js/src/assembler/assembler/MacroAssemblerARM.h +++ b/js/src/assembler/assembler/MacroAssemblerARM.h @@ -496,6 +496,11 @@ public: return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool)); } + Jump branch32_force32(Condition cond, RegisterID left, Imm32 right, int useConstantPool = 0) + { + return branch32(cond, left, right, useConstantPool); + } + // As branch32, but allow the value ('right') to be patched. Jump branch32WithPatch(Condition cond, RegisterID left, Imm32 right, DataLabel32 &dataLabel) { diff --git a/js/src/configure.in b/js/src/configure.in index a7b208756a9..1e03e41ec5f 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -2918,6 +2918,8 @@ i?86-*) ENABLE_POLYIC_CALLPROP=1 ENABLE_POLYIC_BIND=1 ENABLE_POLYIC_NAME=1 + ENABLE_POLYIC_GETELEM=1 + ENABLE_POLYIC_SETELEM=1 AC_DEFINE(JS_CPU_X86) AC_DEFINE(JS_NUNBOX32) ;; @@ -2932,6 +2934,8 @@ x86_64*-*) ENABLE_POLYIC_CALLPROP=1 ENABLE_POLYIC_BIND=1 ENABLE_POLYIC_NAME=1 + ENABLE_POLYIC_GETELEM=1 + ENABLE_POLYIC_SETELEM=1 AC_DEFINE(JS_CPU_X64) AC_DEFINE(JS_PUNBOX64) ;; @@ -2946,6 +2950,8 @@ arm*-*) ENABLE_POLYIC_CALLPROP=1 ENABLE_POLYIC_BIND=1 ENABLE_POLYIC_NAME=1 + ENABLE_POLYIC_GETELEM=1 + ENABLE_POLYIC_SETELEM=1 AC_DEFINE(JS_CPU_ARM) AC_DEFINE(JS_NUNBOX32) ;; @@ -3011,8 +3017,12 @@ if test "$ENABLE_POLYIC_BIND"; then AC_DEFINE(JS_POLYIC_BIND) fi -if test "$ENABLE_POLYIC_ELEM"; then - AC_DEFINE(JS_POLYIC_ELEM) +if test "$ENABLE_POLYIC_GETELEM"; then + AC_DEFINE(JS_POLYIC_GETELEM) +fi + +if test "$ENABLE_POLYIC_SETELEM"; then + AC_DEFINE(JS_POLYIC_SETELEM) fi if test "$ENABLE_METHODJIT_SPEW"; then diff --git a/js/src/methodjit/BaseCompiler.h b/js/src/methodjit/BaseCompiler.h index 3cc10a8673f..43bffef12f5 100644 --- a/js/src/methodjit/BaseCompiler.h +++ b/js/src/methodjit/BaseCompiler.h @@ -266,7 +266,7 @@ class AutoReserveICSpace { } }; -# define RESERVE_IC_SPACE(__masm) AutoReserveICSpace<80> arics(__masm) +# define RESERVE_IC_SPACE(__masm) AutoReserveICSpace<96> arics(__masm) /* 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 diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 072dd2ef4ce..4f1d160d71c 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -48,6 +48,7 @@ #include "StubCalls.h" #include "MonoIC.h" #include "PolyIC.h" +#include "ICChecker.h" #include "Retcon.h" #include "assembler/jit/ExecutableAllocator.h" #include "assembler/assembler/LinkBuffer.h" @@ -642,7 +643,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp) stubCode.patch(patch.slowNcodePatch, fullCode.locationOf(patch.joinPoint)); } -#if defined JS_POLYIC +#if defined JS_POLYIC_GETELEM jit->nGetElems = getElemICs.length(); if (getElemICs.length()) { jit->getElems = (ic::GetElementIC *)cursor; @@ -675,7 +676,9 @@ mjit::Compiler::finishThisUp(JITScript **jitp) stubCode.patch(from.paramAddr, &to); } +#endif /* JS_POLYIC_GETELEM */ +#if defined JS_POLYIC_SETELEM jit->nSetElems = setElemICs.length(); if (setElemICs.length()) { jit->setElems = (ic::SetElementIC *)cursor; @@ -713,12 +716,16 @@ mjit::Compiler::finishThisUp(JITScript **jitp) to.inlineHoleGuard = inlineHoleGuard; JS_ASSERT(to.inlineHoleGuard == inlineHoleGuard); + CheckIsStubCall(to.slowPathCall.labelAtOffset(0)); + to.volatileMask = from.volatileMask; JS_ASSERT(to.volatileMask == from.volatileMask); stubCode.patch(from.paramAddr, &to); } +#endif /* JS_POLYIC_SETELEM */ +#if defined JS_POLYIC jit->nPICs = pics.length(); if (pics.length()) { jit->pics = (ic::PICInfo *)cursor; @@ -754,7 +761,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp) stubCode.patch(pics[i].paramAddr, &scriptPICs[i]); } } -#endif /* JS_POLYIC */ +#endif /* Link fast and slow paths together. */ stubcc.fixCrossJumps(result, masm.size(), masm.size() + stubcc.size()); diff --git a/js/src/methodjit/FastOps.cpp b/js/src/methodjit/FastOps.cpp index 95b54d03798..bc60a71c1e3 100644 --- a/js/src/methodjit/FastOps.cpp +++ b/js/src/methodjit/FastOps.cpp @@ -1256,10 +1256,12 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed) ic.objRemat = frame.dataRematInfo(obj); // All patchable guards must occur after this point. + RESERVE_IC_SPACE(masm); ic.fastPathStart = masm.label(); // Create the common out-of-line sync block, taking care to link previous // guards here after. + RESERVE_OOL_SPACE(stubcc.masm); ic.slowPathStart = stubcc.syncExit(Uses(3)); // Guard obj is a dense array. @@ -1427,9 +1429,11 @@ mjit::Compiler::jsop_getelem(bool isCall) ic.id = ValueRemat::FromRegisters(ic.typeReg, dataReg); } + RESERVE_IC_SPACE(masm); ic.fastPathStart = masm.label(); // Note: slow path here is safe, since the frame will not be modified. + RESERVE_OOL_SPACE(stubcc.masm); ic.slowPathStart = stubcc.masm.label(); frame.sync(stubcc.masm, Uses(2)); diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index d47d13c7a72..0db15191127 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -1038,7 +1038,6 @@ class GetPropCompiler : public PICStubCompiler Label start; Jump shapeGuardJump; - DataLabel32 shapeGuardData; Jump argsLenGuard; bool setStubShapeOffset = true; @@ -1060,8 +1059,8 @@ class GetPropCompiler : public PICStubCompiler } start = masm.label(); - shapeGuardJump = masm.branch32WithPatch(Assembler::NotEqual, pic.shapeReg, - Imm32(obj->shape()), shapeGuardData); + shapeGuardJump = masm.branch32_force32(Assembler::NotEqual, pic.shapeReg, + Imm32(obj->shape())); } Label stubShapeJumpLabel = masm.label(); @@ -1995,7 +1994,7 @@ BaseIC::shouldUpdate(JSContext *cx) return true; } -#if defined JS_POLYIC_ELEM +#if defined JS_POLYIC_GETELEM static void JS_FASTCALL DisabledGetElem(VMFrame &f, ic::GetElementIC *ic) { @@ -2048,10 +2047,13 @@ GetElementIC::purge(Repatcher &repatcher) repatcher.relink(fastPathStart.jumpAtOffset(inlineClaspGuard), slowPathStart); if (slowCallPatched) { - if (op == JSOP_GETELEM) - repatcher.relink(slowPathCall, FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, ic::GetElement))); - else if (op == JSOP_CALLELEM) - repatcher.relink(slowPathCall, FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, ic::CallElement))); + if (op == JSOP_GETELEM) { + repatcher.relink(slowPathCall, + FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, ic::GetElement))); + } else if (op == JSOP_CALLELEM) { + repatcher.relink(slowPathCall, + FunctionPtr(JS_FUNC_TO_DATA_PTR(void *, ic::CallElement))); + } } reset(); @@ -2444,7 +2446,9 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic) if (!obj->getProperty(cx, id, &f.regs.sp[-2])) THROW(); } +#endif /* JS_POLYIC_GETELEM */ +#ifdef JS_POLYIC_SETELEM #define APPLY_STRICTNESS(f, s) \ (FunctionTemplateConditional(s, f, f)) @@ -2703,7 +2707,7 @@ ic::SetElement(VMFrame &f, ic::SetElementIC *ic) template void JS_FASTCALL ic::SetElement(VMFrame &f, SetElementIC *ic); template void JS_FASTCALL ic::SetElement(VMFrame &f, SetElementIC *ic); -#endif /* JS_POLYIC_ELEM */ +#endif /* JS_POLYIC_SETELEM */ void JITScript::purgePICs() @@ -2746,9 +2750,11 @@ JITScript::purgePICs() pic.reset(); } -#if defined JS_POLYIC_ELEM +#if defined JS_POLYIC_GETELEM for (uint32 i = 0; i < nGetElems; i++) getElems[i].purge(repatcher); +#endif +#if defined JS_POLYIC_SETELEM for (uint32 i = 0; i < nSetElems; i++) setElems[i].purge(repatcher); #endif