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/compiler/osr.h" | |
| 10 #include "src/scopes.h" | 11 #include "src/scopes.h" |
| 11 #include "src/x64/assembler-x64.h" | 12 #include "src/x64/assembler-x64.h" |
| 12 #include "src/x64/macro-assembler-x64.h" | 13 #include "src/x64/macro-assembler-x64.h" |
| 13 | 14 |
| 14 namespace v8 { | 15 namespace v8 { |
| 15 namespace internal { | 16 namespace internal { |
| 16 namespace compiler { | 17 namespace compiler { |
| 17 | 18 |
| 18 #define __ masm()-> | 19 #define __ masm()-> |
| 19 | 20 |
| (...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1452 } | 1453 } |
| 1453 | 1454 |
| 1454 | 1455 |
| 1455 void CodeGenerator::AssembleDeoptimizerCall( | 1456 void CodeGenerator::AssembleDeoptimizerCall( |
| 1456 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1457 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
| 1457 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1458 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
| 1458 isolate(), deoptimization_id, bailout_type); | 1459 isolate(), deoptimization_id, bailout_type); |
| 1459 __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1460 __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
| 1460 } | 1461 } |
| 1461 | 1462 |
| 1463 namespace { | |
| 1464 | |
| 1465 static const int kQuadWordSize = 16; | |
| 1466 } | |
|
Benedikt Meurer
2015/08/16 07:04:35
Nit: add // namespace after } to make clang-format
danno
2015/08/18 13:23:10
Done
| |
| 1467 | |
| 1462 | 1468 |
| 1463 void CodeGenerator::AssemblePrologue() { | 1469 void CodeGenerator::AssemblePrologue() { |
| 1464 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1470 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1465 int stack_slots = frame()->GetSpillSlotCount(); | |
| 1466 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1471 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
| 1467 __ pushq(rbp); | 1472 __ pushq(rbp); |
| 1468 __ movq(rbp, rsp); | 1473 __ movq(rbp, rsp); |
| 1469 int register_save_area_size = 0; | |
| 1470 const RegList saves = descriptor->CalleeSavedRegisters(); | |
| 1471 if (saves != 0) { // Save callee-saved registers. | |
| 1472 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | |
| 1473 if (!((1 << i) & saves)) continue; | |
| 1474 __ pushq(Register::from_code(i)); | |
| 1475 register_save_area_size += kPointerSize; | |
| 1476 } | |
| 1477 } | |
| 1478 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); | |
| 1479 if (saves_fp != 0) { // Save callee-saved XMM registers. | |
| 1480 const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); | |
| 1481 const int stack_size = saves_fp_count * 16; | |
| 1482 // Adjust the stack pointer. | |
| 1483 __ subp(rsp, Immediate(stack_size)); | |
| 1484 // Store the registers on the stack. | |
| 1485 int slot_idx = 0; | |
| 1486 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | |
| 1487 if (!((1 << i) & saves_fp)) continue; | |
| 1488 __ movdqu(Operand(rsp, 16 * slot_idx), XMMRegister::from_code(i)); | |
| 1489 slot_idx++; | |
| 1490 } | |
| 1491 register_save_area_size += stack_size; | |
| 1492 } | |
| 1493 if (register_save_area_size > 0) { | |
| 1494 frame()->SetRegisterSaveAreaSize(register_save_area_size); | |
| 1495 } | |
| 1496 } else if (descriptor->IsJSFunctionCall()) { | 1474 } else if (descriptor->IsJSFunctionCall()) { |
| 1497 CompilationInfo* info = this->info(); | 1475 CompilationInfo* info = this->info(); |
| 1498 __ Prologue(info->IsCodePreAgingActive()); | 1476 __ Prologue(info->IsCodePreAgingActive()); |
| 1499 frame()->SetRegisterSaveAreaSize( | |
| 1500 StandardFrameConstants::kFixedFrameSizeFromFp); | |
| 1501 } else if (needs_frame_) { | 1477 } else if (needs_frame_) { |
| 1502 __ StubPrologue(); | 1478 __ StubPrologue(); |
| 1503 frame()->SetRegisterSaveAreaSize( | 1479 } else { |
| 1504 StandardFrameConstants::kFixedFrameSizeFromFp); | 1480 frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize); |
| 1505 } | 1481 } |
| 1506 | 1482 |
| 1483 int stack_shrink_slots = frame()->GetSpillSlotCount(); | |
| 1507 if (info()->is_osr()) { | 1484 if (info()->is_osr()) { |
| 1508 // TurboFan OSR-compiled functions cannot be entered directly. | 1485 // TurboFan OSR-compiled functions cannot be entered directly. |
| 1509 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1486 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
| 1510 | 1487 |
| 1511 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1488 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
| 1512 // frame is still on the stack. Optimized code uses OSR values directly from | 1489 // frame is still on the stack. Optimized code uses OSR values directly from |
| 1513 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1490 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
| 1514 // remaining stack slots. | 1491 // remaining stack slots. |
| 1515 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1492 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
| 1516 osr_pc_offset_ = __ pc_offset(); | 1493 osr_pc_offset_ = __ pc_offset(); |
| 1517 // TODO(titzer): cannot address target function == local #-1 | 1494 // TODO(titzer): cannot address target function == local #-1 |
| 1518 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1495 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1519 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); | 1496 stack_shrink_slots -= |
| 1520 stack_slots -= frame()->GetOsrStackSlotCount(); | 1497 static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); |
| 1521 } | 1498 } |
| 1522 | 1499 |
| 1523 if (stack_slots > 0) { | 1500 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); |
| 1524 __ subq(rsp, Immediate(stack_slots * kPointerSize)); | 1501 if (saves_fp != 0) { |
| 1502 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); | |
| 1503 } | |
| 1504 if (stack_shrink_slots > 0) { | |
| 1505 __ subq(rsp, Immediate(stack_shrink_slots * kPointerSize)); | |
| 1506 } | |
| 1507 | |
| 1508 if (saves_fp != 0) { // Save callee-saved XMM registers. | |
| 1509 const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); | |
| 1510 const int stack_size = saves_fp_count * kQuadWordSize; | |
| 1511 // Adjust the stack pointer. | |
| 1512 __ subp(rsp, Immediate(stack_size)); | |
| 1513 // Store the registers on the stack. | |
| 1514 int slot_idx = 0; | |
| 1515 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | |
| 1516 if (!((1 << i) & saves_fp)) continue; | |
| 1517 __ movdqu(Operand(rsp, kQuadWordSize * slot_idx), | |
| 1518 XMMRegister::from_code(i)); | |
| 1519 slot_idx++; | |
| 1520 } | |
| 1521 frame()->AllocateSavedCalleeRegisterSlots(saves_fp_count * | |
| 1522 (kQuadWordSize / kPointerSize)); | |
| 1523 } | |
| 1524 | |
| 1525 const RegList saves = descriptor->CalleeSavedRegisters(); | |
| 1526 if (saves != 0) { // Save callee-saved registers. | |
| 1527 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | |
| 1528 if (!((1 << i) & saves)) continue; | |
| 1529 __ pushq(Register::from_code(i)); | |
| 1530 frame()->AllocateSavedCalleeRegisterSlots(1); | |
| 1531 } | |
| 1525 } | 1532 } |
| 1526 } | 1533 } |
| 1527 | 1534 |
| 1528 | 1535 |
| 1529 void CodeGenerator::AssembleReturn() { | 1536 void CodeGenerator::AssembleReturn() { |
| 1530 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1537 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1531 int stack_slots = frame()->GetSpillSlotCount(); | 1538 |
| 1539 // Restore registers. | |
| 1540 const RegList saves = descriptor->CalleeSavedRegisters(); | |
| 1541 if (saves != 0) { | |
| 1542 for (int i = 0; i < Register::kNumRegisters; i++) { | |
| 1543 if (!((1 << i) & saves)) continue; | |
| 1544 __ popq(Register::from_code(i)); | |
| 1545 } | |
| 1546 } | |
| 1547 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); | |
| 1548 if (saves_fp != 0) { | |
| 1549 const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); | |
| 1550 const int stack_size = saves_fp_count * kQuadWordSize; | |
| 1551 // Load the registers from the stack. | |
| 1552 int slot_idx = 0; | |
| 1553 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | |
| 1554 if (!((1 << i) & saves_fp)) continue; | |
| 1555 __ movdqu(XMMRegister::from_code(i), | |
| 1556 Operand(rsp, kQuadWordSize * slot_idx)); | |
| 1557 slot_idx++; | |
| 1558 } | |
| 1559 // Adjust the stack pointer. | |
| 1560 __ addp(rsp, Immediate(stack_size)); | |
| 1561 } | |
| 1562 | |
| 1532 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1563 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
| 1533 if (frame()->GetRegisterSaveAreaSize() > 0) { | 1564 __ movq(rsp, rbp); // Move stack pointer back to frame pointer. |
| 1534 // Remove this frame's spill slots first. | 1565 __ popq(rbp); // Pop caller's frame pointer. |
| 1535 if (stack_slots > 0) { | |
| 1536 __ addq(rsp, Immediate(stack_slots * kPointerSize)); | |
| 1537 } | |
| 1538 // Restore registers. | |
| 1539 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); | |
| 1540 if (saves_fp != 0) { | |
| 1541 const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); | |
| 1542 const int stack_size = saves_fp_count * 16; | |
| 1543 // Load the registers from the stack. | |
| 1544 int slot_idx = 0; | |
| 1545 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | |
| 1546 if (!((1 << i) & saves_fp)) continue; | |
| 1547 __ movdqu(XMMRegister::from_code(i), Operand(rsp, 16 * slot_idx)); | |
| 1548 slot_idx++; | |
| 1549 } | |
| 1550 // Adjust the stack pointer. | |
| 1551 __ addp(rsp, Immediate(stack_size)); | |
| 1552 } | |
| 1553 const RegList saves = descriptor->CalleeSavedRegisters(); | |
| 1554 if (saves != 0) { | |
| 1555 for (int i = 0; i < Register::kNumRegisters; i++) { | |
| 1556 if (!((1 << i) & saves)) continue; | |
| 1557 __ popq(Register::from_code(i)); | |
| 1558 } | |
| 1559 } | |
| 1560 __ popq(rbp); // Pop caller's frame pointer. | |
| 1561 } else { | |
| 1562 // No saved registers. | |
| 1563 __ movq(rsp, rbp); // Move stack pointer back to frame pointer. | |
| 1564 __ popq(rbp); // Pop caller's frame pointer. | |
| 1565 } | |
| 1566 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { | 1566 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { |
| 1567 // Canonicalize JSFunction return sites for now. | 1567 // Canonicalize JSFunction return sites for now. |
| 1568 if (return_label_.is_bound()) { | 1568 if (return_label_.is_bound()) { |
| 1569 __ jmp(&return_label_); | 1569 __ jmp(&return_label_); |
| 1570 return; | 1570 return; |
| 1571 } else { | 1571 } else { |
| 1572 __ bind(&return_label_); | 1572 __ bind(&return_label_); |
| 1573 __ movq(rsp, rbp); // Move stack pointer back to frame pointer. | 1573 __ movq(rsp, rbp); // Move stack pointer back to frame pointer. |
| 1574 __ popq(rbp); // Pop caller's frame pointer. | 1574 __ popq(rbp); // Pop caller's frame pointer. |
| 1575 } | 1575 } |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1768 __ Nop(padding_size); | 1768 __ Nop(padding_size); |
| 1769 } | 1769 } |
| 1770 } | 1770 } |
| 1771 } | 1771 } |
| 1772 | 1772 |
| 1773 #undef __ | 1773 #undef __ |
| 1774 | 1774 |
| 1775 } // namespace internal | 1775 } // namespace internal |
| 1776 } // namespace compiler | 1776 } // namespace compiler |
| 1777 } // namespace v8 | 1777 } // namespace v8 |
| OLD | NEW |