Index: src/x64/virtual-frame-x64.cc |
=================================================================== |
--- src/x64/virtual-frame-x64.cc (revision 3859) |
+++ src/x64/virtual-frame-x64.cc (working copy) |
@@ -45,7 +45,7 @@ |
: elements_(parameter_count() + local_count() + kPreallocatedElements), |
stack_pointer_(parameter_count() + 1) { // 0-based index of TOS. |
for (int i = 0; i <= stack_pointer_; i++) { |
- elements_.Add(FrameElement::MemoryElement()); |
+ elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown)); |
} |
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { |
register_locations_[i] = kIllegalIndex; |
@@ -193,25 +193,25 @@ |
} |
-void VirtualFrame::EmitPush(Register reg) { |
+void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) { |
ASSERT(stack_pointer_ == element_count() - 1); |
- elements_.Add(FrameElement::MemoryElement()); |
+ elements_.Add(FrameElement::MemoryElement(info)); |
stack_pointer_++; |
__ push(reg); |
} |
-void VirtualFrame::EmitPush(const Operand& operand) { |
+void VirtualFrame::EmitPush(const Operand& operand, NumberInfo::Type info) { |
ASSERT(stack_pointer_ == element_count() - 1); |
- elements_.Add(FrameElement::MemoryElement()); |
+ elements_.Add(FrameElement::MemoryElement(info)); |
stack_pointer_++; |
__ push(operand); |
} |
-void VirtualFrame::EmitPush(Immediate immediate) { |
+void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) { |
ASSERT(stack_pointer_ == element_count() - 1); |
- elements_.Add(FrameElement::MemoryElement()); |
+ elements_.Add(FrameElement::MemoryElement(info)); |
stack_pointer_++; |
__ push(immediate); |
} |
@@ -219,7 +219,7 @@ |
void VirtualFrame::EmitPush(Smi* smi_value) { |
ASSERT(stack_pointer_ == element_count() - 1); |
- elements_.Add(FrameElement::MemoryElement()); |
+ elements_.Add(FrameElement::MemoryElement(NumberInfo::kSmi)); |
stack_pointer_++; |
__ Push(smi_value); |
} |
@@ -227,15 +227,21 @@ |
void VirtualFrame::EmitPush(Handle<Object> value) { |
ASSERT(stack_pointer_ == element_count() - 1); |
- elements_.Add(FrameElement::MemoryElement()); |
+ NumberInfo::Type info = NumberInfo::kUnknown; |
+ if (value->IsSmi()) { |
+ info = NumberInfo::kSmi; |
+ } else if (value->IsHeapNumber()) { |
+ info = NumberInfo::kHeapNumber; |
+ } |
+ elements_.Add(FrameElement::MemoryElement(info)); |
stack_pointer_++; |
__ Push(value); |
} |
-void VirtualFrame::EmitPush(Heap::RootListIndex index) { |
+void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo::Type info) { |
ASSERT(stack_pointer_ == element_count() - 1); |
- elements_.Add(FrameElement::MemoryElement()); |
+ elements_.Add(FrameElement::MemoryElement(info)); |
stack_pointer_++; |
__ PushRoot(index); |
} |
@@ -305,10 +311,14 @@ |
// Set the new backing element. |
if (elements_[new_backing_index].is_synced()) { |
elements_[new_backing_index] = |
- FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); |
+ FrameElement::RegisterElement(backing_reg, |
+ FrameElement::SYNCED, |
+ original.number_info()); |
} else { |
elements_[new_backing_index] = |
- FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); |
+ FrameElement::RegisterElement(backing_reg, |
+ FrameElement::NOT_SYNCED, |
+ original.number_info()); |
} |
// Update the other copies. |
for (int i = new_backing_index + 1; i < element_count(); i++) { |
@@ -339,7 +349,8 @@ |
ASSERT(fresh.is_valid()); |
FrameElement new_element = |
FrameElement::RegisterElement(fresh.reg(), |
- FrameElement::NOT_SYNCED); |
+ FrameElement::NOT_SYNCED, |
+ original.number_info()); |
Use(fresh.reg(), element_count()); |
elements_.Add(new_element); |
__ movq(fresh.reg(), Operand(rbp, fp_relative(index))); |
@@ -480,10 +491,12 @@ |
for (int i = 0; i < element_count(); i++) { |
FrameElement element = elements_[i]; |
+ // In all cases we have to reset the number type information |
+ // to unknown for a mergable frame because of incoming back edges. |
if (element.is_constant() || element.is_copy()) { |
if (element.is_synced()) { |
// Just spill. |
- elements_[i] = FrameElement::MemoryElement(); |
+ elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown); |
} else { |
// Allocate to a register. |
FrameElement backing_element; // Invalid if not a copy. |
@@ -494,7 +507,8 @@ |
ASSERT(fresh.is_valid()); // A register was spilled if all were in use. |
elements_[i] = |
FrameElement::RegisterElement(fresh.reg(), |
- FrameElement::NOT_SYNCED); |
+ FrameElement::NOT_SYNCED, |
+ NumberInfo::kUnknown); |
Use(fresh.reg(), i); |
// Emit a move. |
@@ -523,6 +537,7 @@ |
// The copy flag is not relied on before the end of this loop, |
// including when registers are spilled. |
elements_[i].clear_copied(); |
+ elements_[i].set_number_info(NumberInfo::kUnknown); |
} |
} |
} |
@@ -728,6 +743,14 @@ |
int index = element_count(); |
ASSERT(element.is_valid()); |
+ // Get number type information of the result. |
+ NumberInfo::Type info; |
+ if (!element.is_copy()) { |
+ info = element.number_info(); |
+ } else { |
+ info = elements_[element.index()].number_info(); |
+ } |
+ |
bool pop_needed = (stack_pointer_ == index); |
if (pop_needed) { |
stack_pointer_--; |
@@ -735,6 +758,7 @@ |
Result temp = cgen()->allocator()->Allocate(); |
ASSERT(temp.is_valid()); |
__ pop(temp.reg()); |
+ temp.set_number_info(info); |
return temp; |
} |
@@ -762,14 +786,16 @@ |
ASSERT(temp.is_valid()); |
Use(temp.reg(), index); |
FrameElement new_element = |
- FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); |
+ FrameElement::RegisterElement(temp.reg(), |
+ FrameElement::SYNCED, |
+ element.number_info()); |
// Preserve the copy flag on the element. |
if (element.is_copied()) new_element.set_copied(); |
elements_[index] = new_element; |
__ movq(temp.reg(), Operand(rbp, fp_relative(index))); |
- return Result(temp.reg()); |
+ return Result(temp.reg(), info); |
} else if (element.is_register()) { |
- return Result(element.reg()); |
+ return Result(element.reg(), info); |
} else { |
ASSERT(element.is_constant()); |
return Result(element.handle()); |