Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 5256) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -202,105 +202,92 @@ |
// esi: callee's context |
allocator_->Initialize(); |
- if (info->mode() == CompilationInfo::PRIMARY) { |
- frame_->Enter(); |
+ frame_->Enter(); |
- // Allocate space for locals and initialize them. |
- frame_->AllocateStackSlots(); |
+ // Allocate space for locals and initialize them. |
+ frame_->AllocateStackSlots(); |
- // Allocate the local context if needed. |
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
- if (heap_slots > 0) { |
- Comment cmnt(masm_, "[ allocate local context"); |
- // Allocate local context. |
- // Get outer context and create a new context based on it. |
- frame_->PushFunction(); |
- Result context; |
- if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
- FastNewContextStub stub(heap_slots); |
- context = frame_->CallStub(&stub, 1); |
- } else { |
- context = frame_->CallRuntime(Runtime::kNewContext, 1); |
- } |
+ // Allocate the local context if needed. |
+ int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
+ if (heap_slots > 0) { |
+ Comment cmnt(masm_, "[ allocate local context"); |
+ // Allocate local context. |
+ // Get outer context and create a new context based on it. |
+ frame_->PushFunction(); |
+ Result context; |
+ if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
+ FastNewContextStub stub(heap_slots); |
+ context = frame_->CallStub(&stub, 1); |
+ } else { |
+ context = frame_->CallRuntime(Runtime::kNewContext, 1); |
+ } |
- // Update context local. |
- frame_->SaveContextRegister(); |
+ // Update context local. |
+ frame_->SaveContextRegister(); |
- // Verify that the runtime call result and esi agree. |
- if (FLAG_debug_code) { |
- __ cmp(context.reg(), Operand(esi)); |
- __ Assert(equal, "Runtime::NewContext should end up in esi"); |
- } |
+ // Verify that the runtime call result and esi agree. |
+ if (FLAG_debug_code) { |
+ __ cmp(context.reg(), Operand(esi)); |
+ __ Assert(equal, "Runtime::NewContext should end up in esi"); |
} |
+ } |
- // TODO(1241774): Improve this code: |
- // 1) only needed if we have a context |
- // 2) no need to recompute context ptr every single time |
- // 3) don't copy parameter operand code from SlotOperand! |
- { |
- Comment cmnt2(masm_, "[ copy context parameters into .context"); |
- // Note that iteration order is relevant here! If we have the same |
- // parameter twice (e.g., function (x, y, x)), and that parameter |
- // needs to be copied into the context, it must be the last argument |
- // passed to the parameter that needs to be copied. This is a rare |
- // case so we don't check for it, instead we rely on the copying |
- // order: such a parameter is copied repeatedly into the same |
- // context location and thus the last value is what is seen inside |
- // the function. |
- for (int i = 0; i < scope()->num_parameters(); i++) { |
- Variable* par = scope()->parameter(i); |
- Slot* slot = par->slot(); |
- if (slot != NULL && slot->type() == Slot::CONTEXT) { |
- // The use of SlotOperand below is safe in unspilled code |
- // because the slot is guaranteed to be a context slot. |
- // |
- // There are no parameters in the global scope. |
- ASSERT(!scope()->is_global_scope()); |
- frame_->PushParameterAt(i); |
- Result value = frame_->Pop(); |
- value.ToRegister(); |
+ // TODO(1241774): Improve this code: |
+ // 1) only needed if we have a context |
+ // 2) no need to recompute context ptr every single time |
+ // 3) don't copy parameter operand code from SlotOperand! |
+ { |
+ Comment cmnt2(masm_, "[ copy context parameters into .context"); |
+ // Note that iteration order is relevant here! If we have the same |
+ // parameter twice (e.g., function (x, y, x)), and that parameter |
+ // needs to be copied into the context, it must be the last argument |
+ // passed to the parameter that needs to be copied. This is a rare |
+ // case so we don't check for it, instead we rely on the copying |
+ // order: such a parameter is copied repeatedly into the same |
+ // context location and thus the last value is what is seen inside |
+ // the function. |
+ for (int i = 0; i < scope()->num_parameters(); i++) { |
+ Variable* par = scope()->parameter(i); |
+ Slot* slot = par->slot(); |
+ if (slot != NULL && slot->type() == Slot::CONTEXT) { |
+ // The use of SlotOperand below is safe in unspilled code |
+ // because the slot is guaranteed to be a context slot. |
+ // |
+ // There are no parameters in the global scope. |
+ ASSERT(!scope()->is_global_scope()); |
+ frame_->PushParameterAt(i); |
+ Result value = frame_->Pop(); |
+ value.ToRegister(); |
- // SlotOperand loads context.reg() with the context object |
- // stored to, used below in RecordWrite. |
- Result context = allocator_->Allocate(); |
- ASSERT(context.is_valid()); |
- __ mov(SlotOperand(slot, context.reg()), value.reg()); |
- int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
- Result scratch = allocator_->Allocate(); |
- ASSERT(scratch.is_valid()); |
- frame_->Spill(context.reg()); |
- frame_->Spill(value.reg()); |
- __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); |
- } |
+ // SlotOperand loads context.reg() with the context object |
+ // stored to, used below in RecordWrite. |
+ Result context = allocator_->Allocate(); |
+ ASSERT(context.is_valid()); |
+ __ mov(SlotOperand(slot, context.reg()), value.reg()); |
+ int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
+ Result scratch = allocator_->Allocate(); |
+ ASSERT(scratch.is_valid()); |
+ frame_->Spill(context.reg()); |
+ frame_->Spill(value.reg()); |
+ __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg()); |
} |
} |
+ } |
- // Store the arguments object. This must happen after context |
- // initialization because the arguments object may be stored in |
- // the context. |
- if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { |
- StoreArgumentsObject(true); |
- } |
+ // Store the arguments object. This must happen after context |
+ // initialization because the arguments object may be stored in |
+ // the context. |
+ if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { |
+ StoreArgumentsObject(true); |
+ } |
- // Initialize ThisFunction reference if present. |
- if (scope()->is_function_scope() && scope()->function() != NULL) { |
- frame_->Push(Factory::the_hole_value()); |
- StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); |
- } |
- } else { |
- // When used as the secondary compiler for splitting, ebp, esi, |
- // and edi have been pushed on the stack. Adjust the virtual |
- // frame to match this state. |
- frame_->Adjust(3); |
- allocator_->Unuse(edi); |
- |
- // Bind all the bailout labels to the beginning of the function. |
- List<CompilationInfo::Bailout*>* bailouts = info->bailouts(); |
- for (int i = 0; i < bailouts->length(); i++) { |
- __ bind(bailouts->at(i)->label()); |
- } |
+ // Initialize ThisFunction reference if present. |
+ if (scope()->is_function_scope() && scope()->function() != NULL) { |
+ frame_->Push(Factory::the_hole_value()); |
+ StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); |
} |
+ |
// Initialize the function return target after the locals are set |
// up, because it needs the expected frame height from the frame. |
function_return_.set_direction(JumpTarget::BIDIRECTIONAL); |