| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 5256)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -201,103 +201,89 @@
|
| // rsi: 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 rsi agree.
|
| - if (FLAG_debug_code) {
|
| - __ cmpq(context.reg(), rsi);
|
| - __ Assert(equal, "Runtime::NewContext should end up in rsi");
|
| - }
|
| + // Verify that the runtime call result and rsi agree.
|
| + if (FLAG_debug_code) {
|
| + __ cmpq(context.reg(), rsi);
|
| + __ Assert(equal, "Runtime::NewContext should end up in rsi");
|
| }
|
| + }
|
|
|
| - // 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());
|
| - __ movq(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());
|
| + __ movq(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, rbp, rsi,
|
| - // and rdi have been pushed on the stack. Adjust the virtual
|
| - // frame to match this state.
|
| - frame_->Adjust(3);
|
| - allocator_->Unuse(rdi);
|
| -
|
| - // 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
|
|
|