From 66b794cbce25439bf583b79edab37f2f94f6ff90 Mon Sep 17 00:00:00 2001 From: "plind44@gmail.com" Date: Tue, 4 Mar 2014 20:16:24 +0000 Subject: [PATCH] MIPS: Push safepoint registers in deferred number-to-i/u only on-demand. Port r19649 (49f8c2d) BUG= R=plind44@gmail.com Review URL: https://codereview.chromium.org/186673004 Patch from Balazs Kilvady . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19662 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 75 ++++++++++++++++++-------------- src/mips/lithium-codegen-mips.h | 8 ++-- src/mips/lithium-mips.cc | 8 +++- src/mips/lithium-mips.h | 16 +++++-- 4 files changed, 65 insertions(+), 42 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 30d7efd1b0..20d27c6a03 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -4553,9 +4553,11 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) { DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) : LDeferredCode(codegen), instr_(instr) { } virtual void Generate() V8_OVERRIDE { - codegen()->DoDeferredNumberTagI(instr_, - instr_->value(), - SIGNED_INT32); + codegen()->DoDeferredNumberTagIU(instr_, + instr_->value(), + instr_->temp1(), + instr_->temp2(), + SIGNED_INT32); } virtual LInstruction* instr() V8_OVERRIDE { return instr_; } private: @@ -4579,9 +4581,11 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) : LDeferredCode(codegen), instr_(instr) { } virtual void Generate() V8_OVERRIDE { - codegen()->DoDeferredNumberTagI(instr_, - instr_->value(), - UNSIGNED_INT32); + codegen()->DoDeferredNumberTagIU(instr_, + instr_->value(), + instr_->temp1(), + instr_->temp2(), + UNSIGNED_INT32); } virtual LInstruction* instr() V8_OVERRIDE { return instr_; } private: @@ -4598,18 +4602,19 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { } -void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, - LOperand* value, - IntegerSignedness signedness) { - Label slow; +void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, + LOperand* value, + LOperand* temp1, + LOperand* temp2, + IntegerSignedness signedness) { + Label done, slow; Register src = ToRegister(value); Register dst = ToRegister(instr->result()); + Register tmp1 = scratch0(); + Register tmp2 = ToRegister(temp1); + Register tmp3 = ToRegister(temp2); DoubleRegister dbl_scratch = double_scratch0(); - // Preserve the value of all registers. - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); - - Label done; if (signedness == SIGNED_INT32) { // There was overflow, so bits 30 and 31 of the original integer // disagree. Try to allocate a heap number in new space and store @@ -4626,37 +4631,41 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, } if (FLAG_inline_new) { - __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); - __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT); - __ Move(dst, t1); + __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); + __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow, DONT_TAG_RESULT); __ Branch(&done); } // Slow case: Call the runtime system to do the number allocation. __ bind(&slow); + { + // TODO(3095996): Put a valid pointer value in the stack slot where the + // result register is stored, as this register is in the pointer map, but + // contains an integer value. + __ mov(dst, zero_reg); + + // Preserve the value of all registers. + PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + + // NumberTagI and NumberTagD use the context from the frame, rather than + // the environment's HContext or HInlinedContext value. + // They only call Runtime::kAllocateHeapNumber. + // The corresponding HChange instructions are added in a phase that does + // not have easy access to the local context. + __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); + RecordSafepointWithRegisters( + instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); + __ Subu(v0, v0, kHeapObjectTag); + __ StoreToSafepointRegisterSlot(v0, dst); + } - // TODO(3095996): Put a valid pointer value in the stack slot where the result - // register is stored, as this register is in the pointer map, but contains an - // integer value. - __ StoreToSafepointRegisterSlot(zero_reg, dst); - // NumberTagI and NumberTagD use the context from the frame, rather than - // the environment's HContext or HInlinedContext value. - // They only call Runtime::kAllocateHeapNumber. - // The corresponding HChange instructions are added in a phase that does - // not have easy access to the local context. - __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); - RecordSafepointWithRegisters( - instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); - __ Move(dst, v0); - __ Subu(dst, dst, kHeapObjectTag); // Done. Put the value in dbl_scratch into the value of the allocated heap // number. __ bind(&done); __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); __ Addu(dst, dst, kHeapObjectTag); - __ StoreToSafepointRegisterSlot(dst, dst); } diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index b4651702e0..28782cc778 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -124,9 +124,11 @@ class LCodeGen: public LCodeGenBase { void DoDeferredNumberTagD(LNumberTagD* instr); enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; - void DoDeferredNumberTagI(LInstruction* instr, - LOperand* value, - IntegerSignedness signedness); + void DoDeferredNumberTagIU(LInstruction* instr, + LOperand* value, + LOperand* temp1, + LOperand* temp2, + IntegerSignedness signedness); void DoDeferredTaggedToI(LTaggedToI* instr); void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 1539deb9c3..c87066a50b 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1771,12 +1771,16 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { HValue* val = instr->value(); LOperand* value = UseRegisterAtStart(val); if (val->CheckFlag(HInstruction::kUint32)) { - LNumberTagU* result = new(zone()) LNumberTagU(value); + LOperand* temp1 = TempRegister(); + LOperand* temp2 = TempRegister(); + LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); } else if (val->HasRange() && val->range()->IsInSmiRange()) { return DefineAsRegister(new(zone()) LSmiTag(value)); } else { - LNumberTagI* result = new(zone()) LNumberTagI(value); + LOperand* temp1 = TempRegister(); + LOperand* temp2 = TempRegister(); + LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); } } else if (to.IsSmi()) { diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 67836cf7b3..54ce825be4 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -1914,25 +1914,33 @@ class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> { }; -class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 2> { public: - explicit LNumberTagI(LOperand* value) { + LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) { inputs_[0] = value; + temps_[0] = temp1; + temps_[1] = temp2; } LOperand* value() { return inputs_[0]; } + LOperand* temp1() { return temps_[0]; } + LOperand* temp2() { return temps_[1]; } DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") }; -class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 2> { public: - explicit LNumberTagU(LOperand* value) { + LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) { inputs_[0] = value; + temps_[0] = temp1; + temps_[1] = temp2; } LOperand* value() { return inputs_[0]; } + LOperand* temp1() { return temps_[0]; } + LOperand* temp2() { return temps_[1]; } DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u") };