OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 Label done; \ | 323 Label done; \ |
324 __ j(above_equal, &done, Label::kNear); \ | 324 __ j(above_equal, &done, Label::kNear); \ |
325 if (instr->InputAt(2)->IsRegister()) { \ | 325 if (instr->InputAt(2)->IsRegister()) { \ |
326 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ | 326 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ |
327 } else { \ | 327 } else { \ |
328 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ | 328 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ |
329 } \ | 329 } \ |
330 __ bind(&done); \ | 330 __ bind(&done); \ |
331 } while (false) | 331 } while (false) |
332 | 332 |
| 333 void CodeGenerator::AssembleDeconstructFrame() { |
| 334 __ mov(esp, ebp); |
| 335 __ pop(ebp); |
| 336 } |
| 337 |
| 338 void CodeGenerator::AssembleSetupStackPointer() {} |
333 | 339 |
334 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 340 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
335 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 341 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
336 if (sp_slot_delta > 0) { | 342 if (sp_slot_delta > 0) { |
337 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); | 343 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); |
338 } | 344 } |
339 frame_access_state()->SetFrameAccessToDefault(); | 345 frame_access_state()->SetFrameAccessToDefault(); |
340 } | 346 } |
341 | 347 |
342 | 348 |
343 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 349 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
344 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 350 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
345 if (sp_slot_delta < 0) { | 351 if (sp_slot_delta < 0) { |
346 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); | 352 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); |
347 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); | 353 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); |
348 } | 354 } |
349 if (frame()->needs_frame()) { | 355 if (frame_access_state()->has_frame()) { |
350 __ mov(ebp, MemOperand(ebp, 0)); | 356 __ mov(ebp, MemOperand(ebp, 0)); |
351 } | 357 } |
352 frame_access_state()->SetFrameAccessToSP(); | 358 frame_access_state()->SetFrameAccessToSP(); |
353 } | 359 } |
354 | 360 |
355 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, | 361 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, |
356 Register, Register, | 362 Register, Register, |
357 Register) { | 363 Register) { |
358 // There are not enough temp registers left on ia32 for a call instruction | 364 // There are not enough temp registers left on ia32 for a call instruction |
359 // so we pick some scratch registers and save/restore them manually here. | 365 // so we pick some scratch registers and save/restore them manually here. |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 case kArchRet: | 513 case kArchRet: |
508 AssembleReturn(); | 514 AssembleReturn(); |
509 break; | 515 break; |
510 case kArchStackPointer: | 516 case kArchStackPointer: |
511 __ mov(i.OutputRegister(), esp); | 517 __ mov(i.OutputRegister(), esp); |
512 break; | 518 break; |
513 case kArchFramePointer: | 519 case kArchFramePointer: |
514 __ mov(i.OutputRegister(), ebp); | 520 __ mov(i.OutputRegister(), ebp); |
515 break; | 521 break; |
516 case kArchParentFramePointer: | 522 case kArchParentFramePointer: |
517 if (frame_access_state()->frame()->needs_frame()) { | 523 if (frame_access_state()->has_frame()) { |
518 __ mov(i.OutputRegister(), Operand(ebp, 0)); | 524 __ mov(i.OutputRegister(), Operand(ebp, 0)); |
519 } else { | 525 } else { |
520 __ mov(i.OutputRegister(), ebp); | 526 __ mov(i.OutputRegister(), ebp); |
521 } | 527 } |
522 break; | 528 break; |
523 case kArchTruncateDoubleToI: { | 529 case kArchTruncateDoubleToI: { |
524 auto result = i.OutputRegister(); | 530 auto result = i.OutputRegister(); |
525 auto input = i.InputDoubleRegister(0); | 531 auto input = i.InputDoubleRegister(0); |
526 auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input); | 532 auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input); |
527 __ cvttsd2si(result, Operand(input)); | 533 __ cvttsd2si(result, Operand(input)); |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 // | FP | RET | args | caller frame | | 1594 // | FP | RET | args | caller frame | |
1589 // ^ esp,ebp | 1595 // ^ esp,ebp |
1590 | 1596 |
1591 // --{ pop ebp }---------------------------------------------------------------- | 1597 // --{ pop ebp }---------------------------------------------------------------- |
1592 // | RET | args | caller frame | | 1598 // | RET | args | caller frame | |
1593 // ^ esp ^ ebp | 1599 // ^ esp ^ ebp |
1594 | 1600 |
1595 | 1601 |
1596 void CodeGenerator::AssemblePrologue() { | 1602 void CodeGenerator::AssemblePrologue() { |
1597 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1603 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1598 if (frame()->needs_frame()) { | 1604 if (frame_access_state()->has_frame()) { |
1599 if (descriptor->IsCFunctionCall()) { | 1605 if (descriptor->IsCFunctionCall()) { |
1600 __ push(ebp); | 1606 __ push(ebp); |
1601 __ mov(ebp, esp); | 1607 __ mov(ebp, esp); |
1602 } else if (descriptor->IsJSFunctionCall()) { | 1608 } else if (descriptor->IsJSFunctionCall()) { |
1603 __ Prologue(this->info()->GeneratePreagedPrologue()); | 1609 __ Prologue(this->info()->GeneratePreagedPrologue()); |
1604 } else { | 1610 } else { |
1605 __ StubPrologue(info()->GetOutputStackFrameType()); | 1611 __ StubPrologue(info()->GetOutputStackFrameType()); |
1606 } | 1612 } |
1607 } else { | |
1608 frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize); | |
1609 } | 1613 } |
1610 frame_access_state()->SetFrameAccessToDefault(); | |
1611 | |
1612 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1614 int stack_shrink_slots = frame()->GetSpillSlotCount(); |
1613 if (info()->is_osr()) { | 1615 if (info()->is_osr()) { |
1614 // TurboFan OSR-compiled functions cannot be entered directly. | 1616 // TurboFan OSR-compiled functions cannot be entered directly. |
1615 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1617 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1616 | 1618 |
1617 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1619 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1618 // frame is still on the stack. Optimized code uses OSR values directly from | 1620 // frame is still on the stack. Optimized code uses OSR values directly from |
1619 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1621 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1620 // remaining stack slots. | 1622 // remaining stack slots. |
1621 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1623 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
(...skipping 25 matching lines...) Expand all Loading... |
1647 const RegList saves = descriptor->CalleeSavedRegisters(); | 1649 const RegList saves = descriptor->CalleeSavedRegisters(); |
1648 // Restore registers. | 1650 // Restore registers. |
1649 if (saves != 0) { | 1651 if (saves != 0) { |
1650 for (int i = 0; i < Register::kNumRegisters; i++) { | 1652 for (int i = 0; i < Register::kNumRegisters; i++) { |
1651 if (!((1 << i) & saves)) continue; | 1653 if (!((1 << i) & saves)) continue; |
1652 __ pop(Register::from_code(i)); | 1654 __ pop(Register::from_code(i)); |
1653 } | 1655 } |
1654 } | 1656 } |
1655 | 1657 |
1656 if (descriptor->IsCFunctionCall()) { | 1658 if (descriptor->IsCFunctionCall()) { |
1657 __ mov(esp, ebp); // Move stack pointer back to frame pointer. | 1659 AssembleDeconstructFrame(); |
1658 __ pop(ebp); // Pop caller's frame pointer. | 1660 } else if (frame_access_state()->has_frame()) { |
1659 } else if (frame()->needs_frame()) { | |
1660 // Canonicalize JSFunction return sites for now. | 1661 // Canonicalize JSFunction return sites for now. |
1661 if (return_label_.is_bound()) { | 1662 if (return_label_.is_bound()) { |
1662 __ jmp(&return_label_); | 1663 __ jmp(&return_label_); |
1663 return; | 1664 return; |
1664 } else { | 1665 } else { |
1665 __ bind(&return_label_); | 1666 __ bind(&return_label_); |
1666 __ mov(esp, ebp); // Move stack pointer back to frame pointer. | 1667 AssembleDeconstructFrame(); |
1667 __ pop(ebp); // Pop caller's frame pointer. | |
1668 } | 1668 } |
1669 } | 1669 } |
1670 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; | 1670 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; |
1671 // Might need ecx for scratch if pop_size is too big. | 1671 // Might need ecx for scratch if pop_size is too big. |
1672 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); | 1672 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); |
1673 __ Ret(static_cast<int>(pop_size), ecx); | 1673 __ Ret(static_cast<int>(pop_size), ecx); |
1674 } | 1674 } |
1675 | 1675 |
1676 | 1676 |
1677 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1677 void CodeGenerator::AssembleMove(InstructionOperand* source, |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 1874 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
1875 __ Nop(padding_size); | 1875 __ Nop(padding_size); |
1876 } | 1876 } |
1877 } | 1877 } |
1878 | 1878 |
1879 #undef __ | 1879 #undef __ |
1880 | 1880 |
1881 } // namespace compiler | 1881 } // namespace compiler |
1882 } // namespace internal | 1882 } // namespace internal |
1883 } // namespace v8 | 1883 } // namespace v8 |
OLD | NEW |