Chromium Code Reviews| 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/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
| 8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 if (instr->InputAt(4)->IsRegister()) { \ | 520 if (instr->InputAt(4)->IsRegister()) { \ |
| 521 Register value = i.InputRegister(4); \ | 521 Register value = i.InputRegister(4); \ |
| 522 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ | 522 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ |
| 523 } else { \ | 523 } else { \ |
| 524 Immediate value = i.InputImmediate(4); \ | 524 Immediate value = i.InputImmediate(4); \ |
| 525 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ | 525 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ |
| 526 } \ | 526 } \ |
| 527 } while (false) | 527 } while (false) |
| 528 | 528 |
| 529 | 529 |
| 530 void CodeGenerator::FixFrameForTailCall() { | |
|
Benedikt Meurer
2015/04/29 04:06:05
Hm, FixFrameForTailCall is not an appropriate name
Sven Panne
2015/04/29 10:24:18
Done.
| |
| 531 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | |
| 532 int stack_slots = frame()->GetSpillSlotCount(); | |
| 533 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | |
| 534 __ movq(rsp, rbp); | |
| 535 __ popq(rbp); | |
| 536 int32_t bytes_to_pop = | |
| 537 descriptor->IsJSFunctionCall() | |
| 538 ? static_cast<int32_t>(descriptor->JSParameterCount() * | |
| 539 kPointerSize) | |
| 540 : 0; | |
| 541 __ popq(Operand(rsp, bytes_to_pop)); | |
|
Benedikt Meurer
2015/04/29 04:06:05
Had to close my eyes to review these lines of code
Sven Panne
2015/04/29 10:24:18
... and I had to close my eyes to write them. :-D
| |
| 542 __ addq(rsp, Immediate(bytes_to_pop)); | |
| 543 } | |
| 544 } | |
| 545 | |
| 546 | |
| 530 // Assembles an instruction after register allocation, producing machine code. | 547 // Assembles an instruction after register allocation, producing machine code. |
| 531 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 548 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 532 X64OperandConverter i(this, instr); | 549 X64OperandConverter i(this, instr); |
| 533 | 550 |
| 534 switch (ArchOpcodeField::decode(instr->opcode())) { | 551 switch (ArchOpcodeField::decode(instr->opcode())) { |
| 535 case kArchCallCodeObject: { | 552 case kArchCallCodeObject: { |
| 536 EnsureSpaceForLazyDeopt(); | 553 EnsureSpaceForLazyDeopt(); |
| 537 if (HasImmediateInput(instr, 0)) { | 554 if (HasImmediateInput(instr, 0)) { |
| 538 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 555 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
| 539 __ Call(code, RelocInfo::CODE_TARGET); | 556 __ Call(code, RelocInfo::CODE_TARGET); |
| 540 } else { | 557 } else { |
| 541 Register reg = i.InputRegister(0); | 558 Register reg = i.InputRegister(0); |
| 542 int entry = Code::kHeaderSize - kHeapObjectTag; | 559 int entry = Code::kHeaderSize - kHeapObjectTag; |
| 543 __ Call(Operand(reg, entry)); | 560 __ Call(Operand(reg, entry)); |
| 544 } | 561 } |
| 545 RecordCallPosition(instr); | 562 RecordCallPosition(instr); |
| 546 break; | 563 break; |
| 547 } | 564 } |
| 565 case kArchTailCallCodeObject: { | |
| 566 FixFrameForTailCall(); | |
| 567 if (HasImmediateInput(instr, 0)) { | |
| 568 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | |
| 569 __ jmp(code, RelocInfo::CODE_TARGET); | |
| 570 } else { | |
| 571 Register reg = i.InputRegister(0); | |
| 572 int entry = Code::kHeaderSize - kHeapObjectTag; | |
| 573 __ jmp(Operand(reg, entry)); | |
| 574 } | |
| 575 break; | |
| 576 } | |
| 548 case kArchCallJSFunction: { | 577 case kArchCallJSFunction: { |
| 549 EnsureSpaceForLazyDeopt(); | 578 EnsureSpaceForLazyDeopt(); |
| 550 Register func = i.InputRegister(0); | 579 Register func = i.InputRegister(0); |
| 551 if (FLAG_debug_code) { | 580 if (FLAG_debug_code) { |
| 552 // Check the function's context matches the context argument. | 581 // Check the function's context matches the context argument. |
| 553 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 582 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
| 554 __ Assert(equal, kWrongFunctionContext); | 583 __ Assert(equal, kWrongFunctionContext); |
| 555 } | 584 } |
| 556 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 585 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
| 557 RecordCallPosition(instr); | 586 RecordCallPosition(instr); |
| 558 break; | 587 break; |
| 559 } | 588 } |
| 589 case kArchTailCallJSFunction: { | |
| 590 Register func = i.InputRegister(0); | |
| 591 if (FLAG_debug_code) { | |
| 592 // Check the function's context matches the context argument. | |
| 593 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | |
| 594 __ Assert(equal, kWrongFunctionContext); | |
| 595 } | |
| 596 FixFrameForTailCall(); | |
| 597 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); | |
| 598 break; | |
| 599 } | |
| 560 case kArchJmp: | 600 case kArchJmp: |
| 561 AssembleArchJump(i.InputRpo(0)); | 601 AssembleArchJump(i.InputRpo(0)); |
| 562 break; | 602 break; |
| 563 case kArchLookupSwitch: | 603 case kArchLookupSwitch: |
| 564 AssembleArchLookupSwitch(instr); | 604 AssembleArchLookupSwitch(instr); |
| 565 break; | 605 break; |
| 566 case kArchTableSwitch: | 606 case kArchTableSwitch: |
| 567 AssembleArchTableSwitch(instr); | 607 AssembleArchTableSwitch(instr); |
| 568 break; | 608 break; |
| 569 case kArchNop: | 609 case kArchNop: |
| (...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1665 } | 1705 } |
| 1666 } | 1706 } |
| 1667 MarkLazyDeoptSite(); | 1707 MarkLazyDeoptSite(); |
| 1668 } | 1708 } |
| 1669 | 1709 |
| 1670 #undef __ | 1710 #undef __ |
| 1671 | 1711 |
| 1672 } // namespace internal | 1712 } // namespace internal |
| 1673 } // namespace compiler | 1713 } // namespace compiler |
| 1674 } // namespace v8 | 1714 } // namespace v8 |
| OLD | NEW |