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 <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19662 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
plind44@gmail.com 2014-03-04 20:16:24 +00:00
parent 83c7b60293
commit 66b794cbce
4 changed files with 65 additions and 42 deletions

View File

@ -4553,8 +4553,10 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
: LDeferredCode(codegen), instr_(instr) { } : LDeferredCode(codegen), instr_(instr) { }
virtual void Generate() V8_OVERRIDE { virtual void Generate() V8_OVERRIDE {
codegen()->DoDeferredNumberTagI(instr_, codegen()->DoDeferredNumberTagIU(instr_,
instr_->value(), instr_->value(),
instr_->temp1(),
instr_->temp2(),
SIGNED_INT32); SIGNED_INT32);
} }
virtual LInstruction* instr() V8_OVERRIDE { return instr_; } virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
@ -4579,8 +4581,10 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
: LDeferredCode(codegen), instr_(instr) { } : LDeferredCode(codegen), instr_(instr) { }
virtual void Generate() V8_OVERRIDE { virtual void Generate() V8_OVERRIDE {
codegen()->DoDeferredNumberTagI(instr_, codegen()->DoDeferredNumberTagIU(instr_,
instr_->value(), instr_->value(),
instr_->temp1(),
instr_->temp2(),
UNSIGNED_INT32); UNSIGNED_INT32);
} }
virtual LInstruction* instr() V8_OVERRIDE { return instr_; } virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
@ -4598,18 +4602,19 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
} }
void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
LOperand* value, LOperand* value,
LOperand* temp1,
LOperand* temp2,
IntegerSignedness signedness) { IntegerSignedness signedness) {
Label slow; Label done, slow;
Register src = ToRegister(value); Register src = ToRegister(value);
Register dst = ToRegister(instr->result()); Register dst = ToRegister(instr->result());
Register tmp1 = scratch0();
Register tmp2 = ToRegister(temp1);
Register tmp3 = ToRegister(temp2);
DoubleRegister dbl_scratch = double_scratch0(); DoubleRegister dbl_scratch = double_scratch0();
// Preserve the value of all registers.
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
Label done;
if (signedness == SIGNED_INT32) { if (signedness == SIGNED_INT32) {
// There was overflow, so bits 30 and 31 of the original integer // There was overflow, so bits 30 and 31 of the original integer
// disagree. Try to allocate a heap number in new space and store // disagree. Try to allocate a heap number in new space and store
@ -4626,19 +4631,22 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
} }
if (FLAG_inline_new) { if (FLAG_inline_new) {
__ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex);
__ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT); __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow, DONT_TAG_RESULT);
__ Move(dst, t1);
__ Branch(&done); __ Branch(&done);
} }
// Slow case: Call the runtime system to do the number allocation. // Slow case: Call the runtime system to do the number allocation.
__ bind(&slow); __ 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);
// 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 // NumberTagI and NumberTagD use the context from the frame, rather than
// the environment's HContext or HInlinedContext value. // the environment's HContext or HInlinedContext value.
// They only call Runtime::kAllocateHeapNumber. // They only call Runtime::kAllocateHeapNumber.
@ -4648,15 +4656,16 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
__ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
RecordSafepointWithRegisters( RecordSafepointWithRegisters(
instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
__ Move(dst, v0); __ Subu(v0, v0, kHeapObjectTag);
__ Subu(dst, dst, kHeapObjectTag); __ StoreToSafepointRegisterSlot(v0, dst);
}
// Done. Put the value in dbl_scratch into the value of the allocated heap // Done. Put the value in dbl_scratch into the value of the allocated heap
// number. // number.
__ bind(&done); __ bind(&done);
__ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset));
__ Addu(dst, dst, kHeapObjectTag); __ Addu(dst, dst, kHeapObjectTag);
__ StoreToSafepointRegisterSlot(dst, dst);
} }

View File

@ -124,8 +124,10 @@ class LCodeGen: public LCodeGenBase {
void DoDeferredNumberTagD(LNumberTagD* instr); void DoDeferredNumberTagD(LNumberTagD* instr);
enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
void DoDeferredNumberTagI(LInstruction* instr, void DoDeferredNumberTagIU(LInstruction* instr,
LOperand* value, LOperand* value,
LOperand* temp1,
LOperand* temp2,
IntegerSignedness signedness); IntegerSignedness signedness);
void DoDeferredTaggedToI(LTaggedToI* instr); void DoDeferredTaggedToI(LTaggedToI* instr);

View File

@ -1771,12 +1771,16 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
HValue* val = instr->value(); HValue* val = instr->value();
LOperand* value = UseRegisterAtStart(val); LOperand* value = UseRegisterAtStart(val);
if (val->CheckFlag(HInstruction::kUint32)) { 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))); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
} else if (val->HasRange() && val->range()->IsInSmiRange()) { } else if (val->HasRange() && val->range()->IsInSmiRange()) {
return DefineAsRegister(new(zone()) LSmiTag(value)); return DefineAsRegister(new(zone()) LSmiTag(value));
} else { } 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))); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
} }
} else if (to.IsSmi()) { } else if (to.IsSmi()) {

View File

@ -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: public:
explicit LNumberTagI(LOperand* value) { LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) {
inputs_[0] = value; inputs_[0] = value;
temps_[0] = temp1;
temps_[1] = temp2;
} }
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
LOperand* temp1() { return temps_[0]; }
LOperand* temp2() { return temps_[1]; }
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") 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: public:
explicit LNumberTagU(LOperand* value) { LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) {
inputs_[0] = value; inputs_[0] = value;
temps_[0] = temp1;
temps_[1] = temp2;
} }
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
LOperand* temp1() { return temps_[0]; }
LOperand* temp2() { return temps_[1]; }
DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u") DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
}; };