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:
parent
83c7b60293
commit
66b794cbce
@ -4553,9 +4553,11 @@ 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(),
|
||||||
SIGNED_INT32);
|
instr_->temp1(),
|
||||||
|
instr_->temp2(),
|
||||||
|
SIGNED_INT32);
|
||||||
}
|
}
|
||||||
virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
|
virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
|
||||||
private:
|
private:
|
||||||
@ -4579,9 +4581,11 @@ 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(),
|
||||||
UNSIGNED_INT32);
|
instr_->temp1(),
|
||||||
|
instr_->temp2(),
|
||||||
|
UNSIGNED_INT32);
|
||||||
}
|
}
|
||||||
virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
|
virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
|
||||||
private:
|
private:
|
||||||
@ -4598,18 +4602,19 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
|
void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
|
||||||
LOperand* value,
|
LOperand* value,
|
||||||
IntegerSignedness signedness) {
|
LOperand* temp1,
|
||||||
Label slow;
|
LOperand* temp2,
|
||||||
|
IntegerSignedness signedness) {
|
||||||
|
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,37 +4631,41 @@ 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);
|
||||||
|
|
||||||
|
// 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
|
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,9 +124,11 @@ 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,
|
||||||
IntegerSignedness signedness);
|
LOperand* temp1,
|
||||||
|
LOperand* temp2,
|
||||||
|
IntegerSignedness signedness);
|
||||||
|
|
||||||
void DoDeferredTaggedToI(LTaggedToI* instr);
|
void DoDeferredTaggedToI(LTaggedToI* instr);
|
||||||
void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
|
void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
|
||||||
|
@ -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()) {
|
||||||
|
@ -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")
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user