MIPS: DoNumberTagD performance improvement
Port r12711 (a8d45ac2) Original commit message: Allocate heap entry untagged and tag at end to avoid having to subtract off the tag offset before storing the value. BUG= TEST= Review URL: https://codereview.chromium.org/11280106 Patch from Akos Palfi <palfia@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13087 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
273b97f9b4
commit
d2fbb819a1
@ -4245,7 +4245,7 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
|
|||||||
|
|
||||||
if (FLAG_inline_new) {
|
if (FLAG_inline_new) {
|
||||||
__ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(t1, a3, t0, t2, &slow);
|
__ AllocateHeapNumber(t1, a3, t0, t2, &slow, DONT_TAG_RESULT);
|
||||||
__ Move(dst, t1);
|
__ Move(dst, t1);
|
||||||
__ Branch(&done);
|
__ Branch(&done);
|
||||||
}
|
}
|
||||||
@ -4259,11 +4259,13 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
|
|||||||
__ StoreToSafepointRegisterSlot(zero_reg, dst);
|
__ StoreToSafepointRegisterSlot(zero_reg, dst);
|
||||||
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
||||||
__ Move(dst, v0);
|
__ 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, FieldMemOperand(dst, HeapNumber::kValueOffset));
|
__ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset));
|
||||||
|
__ Addu(dst, dst, kHeapObjectTag);
|
||||||
__ StoreToSafepointRegisterSlot(dst, dst);
|
__ StoreToSafepointRegisterSlot(dst, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4288,12 +4290,16 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
|
|||||||
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
|
DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
|
||||||
if (FLAG_inline_new) {
|
if (FLAG_inline_new) {
|
||||||
__ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
|
// We want the untagged address first for performance
|
||||||
|
__ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
|
||||||
|
DONT_TAG_RESULT);
|
||||||
} else {
|
} else {
|
||||||
__ Branch(deferred->entry());
|
__ Branch(deferred->entry());
|
||||||
}
|
}
|
||||||
__ bind(deferred->exit());
|
__ bind(deferred->exit());
|
||||||
__ sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset));
|
__ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset));
|
||||||
|
// Now that we have finished with the object's real address tag it
|
||||||
|
__ Addu(reg, reg, kHeapObjectTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4306,6 +4312,7 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
|
|||||||
|
|
||||||
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
|
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
|
||||||
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
||||||
|
__ Subu(v0, v0, kHeapObjectTag);
|
||||||
__ StoreToSafepointRegisterSlot(v0, reg);
|
__ StoreToSafepointRegisterSlot(v0, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3234,7 +3234,8 @@ void MacroAssembler::AllocateHeapNumber(Register result,
|
|||||||
Register scratch1,
|
Register scratch1,
|
||||||
Register scratch2,
|
Register scratch2,
|
||||||
Register heap_number_map,
|
Register heap_number_map,
|
||||||
Label* need_gc) {
|
Label* need_gc,
|
||||||
|
TaggingMode tagging_mode) {
|
||||||
// Allocate an object in the heap for the heap number and tag it as a heap
|
// Allocate an object in the heap for the heap number and tag it as a heap
|
||||||
// object.
|
// object.
|
||||||
AllocateInNewSpace(HeapNumber::kSize,
|
AllocateInNewSpace(HeapNumber::kSize,
|
||||||
@ -3242,11 +3243,16 @@ void MacroAssembler::AllocateHeapNumber(Register result,
|
|||||||
scratch1,
|
scratch1,
|
||||||
scratch2,
|
scratch2,
|
||||||
need_gc,
|
need_gc,
|
||||||
TAG_OBJECT);
|
tagging_mode == TAG_RESULT ? TAG_OBJECT :
|
||||||
|
NO_ALLOCATION_FLAGS);
|
||||||
|
|
||||||
// Store heap number map in the allocated object.
|
// Store heap number map in the allocated object.
|
||||||
AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
||||||
|
if (tagging_mode == TAG_RESULT) {
|
||||||
sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
|
sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
|
||||||
|
} else {
|
||||||
|
sw(heap_number_map, MemOperand(result, HeapObject::kMapOffset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,14 @@ enum AllocationFlags {
|
|||||||
SIZE_IN_WORDS = 1 << 2
|
SIZE_IN_WORDS = 1 << 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags used for AllocateHeapNumber
|
||||||
|
enum TaggingMode {
|
||||||
|
// Tag the result.
|
||||||
|
TAG_RESULT,
|
||||||
|
// Don't tag
|
||||||
|
DONT_TAG_RESULT
|
||||||
|
};
|
||||||
|
|
||||||
// Flags used for the ObjectToDoubleFPURegister function.
|
// Flags used for the ObjectToDoubleFPURegister function.
|
||||||
enum ObjectToDoubleFlags {
|
enum ObjectToDoubleFlags {
|
||||||
// No special flags.
|
// No special flags.
|
||||||
@ -536,7 +544,8 @@ class MacroAssembler: public Assembler {
|
|||||||
Register scratch1,
|
Register scratch1,
|
||||||
Register scratch2,
|
Register scratch2,
|
||||||
Register heap_number_map,
|
Register heap_number_map,
|
||||||
Label* gc_required);
|
Label* gc_required,
|
||||||
|
TaggingMode tagging_mode = TAG_RESULT);
|
||||||
void AllocateHeapNumberWithValue(Register result,
|
void AllocateHeapNumberWithValue(Register result,
|
||||||
FPURegister value,
|
FPURegister value,
|
||||||
Register scratch1,
|
Register scratch1,
|
||||||
|
@ -3847,20 +3847,27 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
|||||||
__ Ret();
|
__ Ret();
|
||||||
|
|
||||||
__ bind(&box_int);
|
__ bind(&box_int);
|
||||||
|
|
||||||
|
if (CpuFeatures::IsSupported(FPU)) {
|
||||||
|
CpuFeatures::Scope scope(FPU);
|
||||||
// Allocate a HeapNumber for the result and perform int-to-double
|
// Allocate a HeapNumber for the result and perform int-to-double
|
||||||
// conversion.
|
// conversion.
|
||||||
// The arm version uses a temporary here to save r0, but we don't need to
|
// The arm version uses a temporary here to save r0, but we don't need to
|
||||||
// (a0 is not modified).
|
// (a0 is not modified).
|
||||||
__ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(v0, a3, t0, t1, &slow);
|
__ AllocateHeapNumber(v0, a3, t0, t1, &slow, DONT_TAG_RESULT);
|
||||||
|
|
||||||
if (CpuFeatures::IsSupported(FPU)) {
|
|
||||||
CpuFeatures::Scope scope(FPU);
|
|
||||||
__ mtc1(value, f0);
|
__ mtc1(value, f0);
|
||||||
__ cvt_d_w(f0, f0);
|
__ cvt_d_w(f0, f0);
|
||||||
__ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
|
__ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
|
||||||
|
__ Addu(v0, v0, kHeapObjectTag);
|
||||||
__ Ret();
|
__ Ret();
|
||||||
} else {
|
} else {
|
||||||
|
// Allocate a HeapNumber for the result and perform int-to-double
|
||||||
|
// conversion.
|
||||||
|
// The arm version uses a temporary here to save r0, but we don't need to
|
||||||
|
// (a0 is not modified).
|
||||||
|
__ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
|
||||||
|
__ AllocateHeapNumber(v0, a3, t0, t1, &slow, TAG_RESULT);
|
||||||
Register dst1 = t2;
|
Register dst1 = t2;
|
||||||
Register dst2 = t3;
|
Register dst2 = t3;
|
||||||
FloatingPointHelper::Destination dest =
|
FloatingPointHelper::Destination dest =
|
||||||
@ -3897,7 +3904,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
|||||||
// conversion. Don't use a0 and a1 as AllocateHeapNumber clobbers all
|
// conversion. Don't use a0 and a1 as AllocateHeapNumber clobbers all
|
||||||
// registers - also when jumping due to exhausted young space.
|
// registers - also when jumping due to exhausted young space.
|
||||||
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(v0, t2, t3, t6, &slow);
|
__ AllocateHeapNumber(v0, t2, t3, t6, &slow, DONT_TAG_RESULT);
|
||||||
|
|
||||||
// This is replaced by a macro:
|
// This is replaced by a macro:
|
||||||
// __ mtc1(value, f0); // LS 32-bits.
|
// __ mtc1(value, f0); // LS 32-bits.
|
||||||
@ -3906,8 +3913,9 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
|||||||
|
|
||||||
__ Cvt_d_uw(f0, value, f22);
|
__ Cvt_d_uw(f0, value, f22);
|
||||||
|
|
||||||
__ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
|
__ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
|
||||||
|
|
||||||
|
__ Addu(v0, v0, kHeapObjectTag);
|
||||||
__ Ret();
|
__ Ret();
|
||||||
} else {
|
} else {
|
||||||
// Check whether unsigned integer fits into smi.
|
// Check whether unsigned integer fits into smi.
|
||||||
@ -3940,7 +3948,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
|||||||
// clobbers all registers - also when jumping due to exhausted young
|
// clobbers all registers - also when jumping due to exhausted young
|
||||||
// space.
|
// space.
|
||||||
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(t2, t3, t5, t6, &slow);
|
__ AllocateHeapNumber(t2, t3, t5, t6, &slow, TAG_RESULT);
|
||||||
|
|
||||||
__ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset));
|
__ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset));
|
||||||
__ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset));
|
__ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset));
|
||||||
@ -3957,17 +3965,19 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
|||||||
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
||||||
// exhausted young space.
|
// exhausted young space.
|
||||||
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(v0, t3, t5, t6, &slow);
|
__ AllocateHeapNumber(v0, t3, t5, t6, &slow, DONT_TAG_RESULT);
|
||||||
// The float (single) value is already in fpu reg f0 (if we use float).
|
// The float (single) value is already in fpu reg f0 (if we use float).
|
||||||
__ cvt_d_s(f0, f0);
|
__ cvt_d_s(f0, f0);
|
||||||
__ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
|
__ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
|
||||||
|
|
||||||
|
__ Addu(v0, v0, kHeapObjectTag);
|
||||||
__ Ret();
|
__ Ret();
|
||||||
} else {
|
} else {
|
||||||
// Allocate a HeapNumber for the result. Don't use a0 and a1 as
|
// Allocate a HeapNumber for the result. Don't use a0 and a1 as
|
||||||
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
||||||
// exhausted young space.
|
// exhausted young space.
|
||||||
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(v0, t3, t5, t6, &slow);
|
__ AllocateHeapNumber(v0, t3, t5, t6, &slow, TAG_RESULT);
|
||||||
// FPU is not available, do manual single to double conversion.
|
// FPU is not available, do manual single to double conversion.
|
||||||
|
|
||||||
// a2: floating point value (binary32).
|
// a2: floating point value (binary32).
|
||||||
@ -4022,16 +4032,18 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
|||||||
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
||||||
// exhausted young space.
|
// exhausted young space.
|
||||||
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(v0, t3, t5, t6, &slow);
|
__ AllocateHeapNumber(v0, t3, t5, t6, &slow, DONT_TAG_RESULT);
|
||||||
// The double value is already in f0
|
// The double value is already in f0
|
||||||
__ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
|
__ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset));
|
||||||
|
|
||||||
|
__ Addu(v0, v0, kHeapObjectTag);
|
||||||
__ Ret();
|
__ Ret();
|
||||||
} else {
|
} else {
|
||||||
// Allocate a HeapNumber for the result. Don't use a0 and a1 as
|
// Allocate a HeapNumber for the result. Don't use a0 and a1 as
|
||||||
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
// AllocateHeapNumber clobbers all registers - also when jumping due to
|
||||||
// exhausted young space.
|
// exhausted young space.
|
||||||
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(v0, t3, t5, t6, &slow);
|
__ AllocateHeapNumber(v0, t3, t5, t6, &slow, TAG_RESULT);
|
||||||
|
|
||||||
__ sw(a2, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
|
__ sw(a2, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
|
||||||
__ sw(a3, FieldMemOperand(v0, HeapNumber::kExponentOffset));
|
__ sw(a3, FieldMemOperand(v0, HeapNumber::kExponentOffset));
|
||||||
@ -4549,7 +4561,7 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
|
|||||||
// Non-NaN. Allocate a new heap number and copy the double value into it.
|
// Non-NaN. Allocate a new heap number and copy the double value into it.
|
||||||
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
|
__ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
|
||||||
heap_number_map, &slow_allocate_heapnumber);
|
heap_number_map, &slow_allocate_heapnumber, TAG_RESULT);
|
||||||
|
|
||||||
// Don't need to reload the upper 32 bits of the double, it's already in
|
// Don't need to reload the upper 32 bits of the double, it's already in
|
||||||
// scratch.
|
// scratch.
|
||||||
|
Loading…
Reference in New Issue
Block a user