| 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 |