| Index: src/ia32/virtual-frame-ia32.cc
|
| ===================================================================
|
| --- src/ia32/virtual-frame-ia32.cc (revision 4147)
|
| +++ src/ia32/virtual-frame-ia32.cc (working copy)
|
| @@ -775,6 +775,89 @@
|
| }
|
|
|
|
|
| +void VirtualFrame::UntaggedPushFrameSlotAt(int index) {
|
| + ASSERT(index >= 0);
|
| + ASSERT(index <= element_count());
|
| + FrameElement original = elements_[index];
|
| + if (original.is_copy()) {
|
| + original = elements_[original.index()];
|
| + index = original.index();
|
| + }
|
| +
|
| + switch (original.type()) {
|
| + case FrameElement::MEMORY:
|
| + case FrameElement::REGISTER: {
|
| + Label done;
|
| + // Emit code to load the original element's data into a register.
|
| + // Push that register as a FrameElement on top of the frame.
|
| + Result fresh = cgen()->allocator()->Allocate();
|
| + ASSERT(fresh.is_valid());
|
| + Register fresh_reg = fresh.reg();
|
| + FrameElement new_element =
|
| + FrameElement::RegisterElement(fresh_reg,
|
| + FrameElement::NOT_SYNCED,
|
| + original.number_info());
|
| + new_element.set_untagged_int32(true);
|
| + Use(fresh_reg, element_count());
|
| + fresh.Unuse(); // BreakTarget does not handle a live Result well.
|
| + elements_.Add(new_element);
|
| + if (original.is_register()) {
|
| + __ mov(fresh_reg, original.reg());
|
| + } else {
|
| + ASSERT(original.is_memory());
|
| + __ mov(fresh_reg, Operand(ebp, fp_relative(index)));
|
| + }
|
| + // Now convert the value to int32, or bail out.
|
| + if (original.number_info().IsSmi()) {
|
| + __ SmiUntag(fresh_reg);
|
| + // Pushing the element is completely done.
|
| + } else {
|
| + __ test(fresh_reg, Immediate(kSmiTagMask));
|
| + Label not_smi;
|
| + __ j(not_zero, ¬_smi);
|
| + __ SmiUntag(fresh_reg);
|
| + __ jmp(&done);
|
| +
|
| + __ bind(¬_smi);
|
| + if (!original.number_info().IsNumber()) {
|
| + __ cmp(FieldOperand(fresh_reg, HeapObject::kMapOffset),
|
| + Factory::heap_number_map());
|
| + cgen()->unsafe_bailout_->Branch(not_equal);
|
| + }
|
| +
|
| + if (!CpuFeatures::IsSupported(SSE2)) {
|
| + UNREACHABLE();
|
| + } else {
|
| + CpuFeatures::Scope use_sse2(SSE2);
|
| + __ movdbl(xmm0, FieldOperand(fresh_reg, HeapNumber::kValueOffset));
|
| + __ cvttsd2si(fresh_reg, Operand(xmm0));
|
| + __ cvtsi2sd(xmm1, Operand(fresh_reg));
|
| + __ ucomisd(xmm0, xmm1);
|
| + cgen()->unsafe_bailout_->Branch(not_equal);
|
| + cgen()->unsafe_bailout_->Branch(parity_even); // NaN.
|
| + // Test for negative zero.
|
| + __ test(fresh_reg, Operand(fresh_reg));
|
| + __ j(not_zero, &done);
|
| + __ movmskpd(fresh_reg, xmm0);
|
| + __ and_(fresh_reg, 0x1);
|
| + cgen()->unsafe_bailout_->Branch(not_equal);
|
| + }
|
| + __ bind(&done);
|
| + }
|
| + break;
|
| + }
|
| + case FrameElement::CONSTANT:
|
| + elements_.Add(CopyElementAt(index));
|
| + elements_[element_count() - 1].set_untagged_int32(true);
|
| + break;
|
| + case FrameElement::COPY:
|
| + case FrameElement::INVALID:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| void VirtualFrame::PushTryHandler(HandlerType type) {
|
| ASSERT(cgen()->HasValidEntryRegisters());
|
| // Grow the expression stack by handler size less one (the return
|
| @@ -1060,6 +1143,7 @@
|
| FrameElement element = elements_.RemoveLast();
|
| int index = element_count();
|
| ASSERT(element.is_valid());
|
| + ASSERT(element.is_untagged_int32() == cgen()->in_safe_int32_mode());
|
|
|
| // Get number type information of the result.
|
| NumberInfo info;
|
| @@ -1077,6 +1161,7 @@
|
| ASSERT(temp.is_valid());
|
| __ pop(temp.reg());
|
| temp.set_number_info(info);
|
| + temp.set_untagged_int32(element.is_untagged_int32());
|
| return temp;
|
| }
|
|
|
| @@ -1089,6 +1174,7 @@
|
| if (element.is_register()) {
|
| Unuse(element.reg());
|
| } else if (element.is_copy()) {
|
| + ASSERT(!element.is_untagged_int32());
|
| ASSERT(element.index() < index);
|
| index = element.index();
|
| element = elements_[index];
|
| @@ -1100,6 +1186,7 @@
|
| // Memory elements could only be the backing store of a copy.
|
| // Allocate the original to a register.
|
| ASSERT(index <= stack_pointer_);
|
| + ASSERT(!element.is_untagged_int32());
|
| Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| Use(temp.reg(), index);
|
| @@ -1113,10 +1200,14 @@
|
| __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
|
| return Result(temp.reg(), info);
|
| } else if (element.is_register()) {
|
| - return Result(element.reg(), info);
|
| + Result return_value(element.reg(), info);
|
| + return_value.set_untagged_int32(element.is_untagged_int32());
|
| + return return_value;
|
| } else {
|
| ASSERT(element.is_constant());
|
| - return Result(element.handle());
|
| + Result return_value(element.handle());
|
| + return_value.set_untagged_int32(element.is_untagged_int32());
|
| + return return_value;
|
| }
|
| }
|
|
|
| @@ -1161,6 +1252,12 @@
|
| }
|
|
|
|
|
| +void VirtualFrame::PushUntaggedElement(Handle<Object> value) {
|
| + elements_.Add(FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED));
|
| + elements_[element_count() - 1].set_untagged_int32(true);
|
| +}
|
| +
|
| +
|
| void VirtualFrame::Push(Expression* expr) {
|
| ASSERT(expr->IsTrivial());
|
|
|
|
|