From 8c2c641e80fe6df04c150488fb59f5f0cd074c66 Mon Sep 17 00:00:00 2001 From: Branislav Rankov Date: Thu, 24 Apr 2014 17:39:20 +0200 Subject: [PATCH] Bug 994716 - IonMonkey MIPS: Add changes to MIPS code during upload process, part 2. r=jandem --- js/src/jit/mips/Bailouts-mips.cpp | 4 +-- js/src/jit/mips/Lowering-mips.h | 2 ++ js/src/jit/mips/MacroAssembler-mips.cpp | 33 ++++++++++++++++--------- js/src/jit/mips/MacroAssembler-mips.h | 33 ++++++++++++++++++++----- 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/js/src/jit/mips/Bailouts-mips.cpp b/js/src/jit/mips/Bailouts-mips.cpp index 4cde9d7a9ccd..2e12628b4f9d 100644 --- a/js/src/jit/mips/Bailouts-mips.cpp +++ b/js/src/jit/mips/Bailouts-mips.cpp @@ -14,7 +14,7 @@ using namespace js::jit; IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, BailoutStack *bailout) - : IonFrameIterator(activations), + : JitFrameIterator(activations), machine_(bailout->machine()) { uint8_t *sp = bailout->parentStackPointer(); @@ -49,7 +49,7 @@ IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, InvalidationBailoutStack *bailout) - : IonFrameIterator(activations), + : JitFrameIterator(activations), machine_(bailout->machine()) { returnAddressToFp_ = bailout->osiPointReturnAddress(); diff --git a/js/src/jit/mips/Lowering-mips.h b/js/src/jit/mips/Lowering-mips.h index 0deab804d4c8..dbd464b5d8db 100644 --- a/js/src/jit/mips/Lowering-mips.h +++ b/js/src/jit/mips/Lowering-mips.h @@ -35,6 +35,8 @@ class LIRGeneratorMIPS : public LIRGeneratorShared return LDefinition::BogusTemp(); } + bool needTempForPostBarrier() { return false; } + // MIPS has a scratch register, so no need for another temp for dispatch // ICs. LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) { diff --git a/js/src/jit/mips/MacroAssembler-mips.cpp b/js/src/jit/mips/MacroAssembler-mips.cpp index 3ae24a5b8e3b..de34c65a644f 100644 --- a/js/src/jit/mips/MacroAssembler-mips.cpp +++ b/js/src/jit/mips/MacroAssembler-mips.cpp @@ -3328,20 +3328,29 @@ MacroAssemblerMIPSCompat::toggledCall(JitCode *target, bool enabled) return offset; } +#ifdef JSGC_GENERATIONAL + void MacroAssemblerMIPSCompat::branchPtrInNurseryRange(Register ptr, Register temp, Label *label) { - JS_ASSERT(temp != InvalidReg); - const Nursery &nursery = GetIonContext()->runtime->gcNursery(); + JS_ASSERT(ptr != temp); + JS_ASSERT(ptr != SecondScratchReg); - // ptr and temp may be the same register, in which case we mustn't trash it - // before we use its contents. - if (ptr == temp) { - addPtr(ImmWord(-ptrdiff_t(nursery.start())), ptr); - branchPtr(Assembler::Below, ptr, Imm32(Nursery::NurserySize), label); - } else { - movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp); - addPtr(ptr, temp); - branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), label); - } + const Nursery &nursery = GetIonContext()->runtime->gcNursery(); + movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg); + addPtr(ptr, SecondScratchReg); + branchPtr(Assembler::Below, SecondScratchReg, Imm32(Nursery::NurserySize), label); } + +void +MacroAssemblerMIPSCompat::branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label) +{ + Label done; + + branchTestObject(Assembler::NotEqual, value, &done); + branchPtrInNurseryRange(value.payloadReg(), temp, label); + + bind(&done); +} + +#endif diff --git a/js/src/jit/mips/MacroAssembler-mips.h b/js/src/jit/mips/MacroAssembler-mips.h index 1c156cd05054..d9c8af6eb41f 100644 --- a/js/src/jit/mips/MacroAssembler-mips.h +++ b/js/src/jit/mips/MacroAssembler-mips.h @@ -817,12 +817,30 @@ public: void moveValue(const Value &val, const ValueOperand &dest); void moveValue(const ValueOperand &src, const ValueOperand &dest) { - MOZ_ASSERT(src.typeReg() != dest.payloadReg()); - MOZ_ASSERT(src.payloadReg() != dest.typeReg()); - if (src.typeReg() != dest.typeReg()) - ma_move(dest.typeReg(), src.typeReg()); - if (src.payloadReg() != dest.payloadReg()) - ma_move(dest.payloadReg(), src.payloadReg()); + Register s0 = src.typeReg(), d0 = dest.typeReg(), + s1 = src.payloadReg(), d1 = dest.payloadReg(); + + // Either one or both of the source registers could be the same as a + // destination register. + if (s1 == d0) { + if (s0 == d1) { + // If both are, this is just a swap of two registers. + JS_ASSERT(d1 != ScratchRegister); + JS_ASSERT(d0 != ScratchRegister); + move32(d1, ScratchRegister); + move32(d0, d1); + move32(ScratchRegister, d0); + return; + } + // If only one is, copy that source first. + mozilla::Swap(s0, s1); + mozilla::Swap(d0, d1); + } + + if (s0 != d0) + move32(s0, d0); + if (s1 != d1) + move32(s1, d1); } void storeValue(ValueOperand val, Operand dst); @@ -1221,7 +1239,10 @@ public: as_movs(dest, src); } +#ifdef JSGC_GENERATIONAL void branchPtrInNurseryRange(Register ptr, Register temp, Label *label); + void branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label); +#endif }; typedef MacroAssemblerMIPSCompat MacroAssemblerSpecific;