OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 // Otherwise, returns the current pc_offset(). | 585 // Otherwise, returns the current pc_offset(). |
586 int link(Label* L); | 586 int link(Label* L); |
587 | 587 |
588 // Determines if Label is bound and near enough so that a single | 588 // Determines if Label is bound and near enough so that a single |
589 // branch instruction can be used to reach it. | 589 // branch instruction can be used to reach it. |
590 bool is_near(Label* L, Condition cond); | 590 bool is_near(Label* L, Condition cond); |
591 | 591 |
592 // Returns the branch offset to the given label from the current code position | 592 // Returns the branch offset to the given label from the current code position |
593 // Links the label to the current position if it is still unbound | 593 // Links the label to the current position if it is still unbound |
594 int branch_offset(Label* L) { | 594 int branch_offset(Label* L) { |
595 int position = link(L); | 595 if (L->is_unused() && !trampoline_emitted_) { |
596 return position - pc_offset(); | 596 TrackBranch(); |
| 597 } |
| 598 return link(L) - pc_offset(); |
597 } | 599 } |
598 | 600 |
599 // Puts a labels target address at the given position. | 601 // Puts a labels target address at the given position. |
600 // The high 8 bits are set to zero. | 602 // The high 8 bits are set to zero. |
601 void label_at_put(Label* L, int at_offset); | 603 void label_at_put(Label* L, int at_offset); |
602 | 604 |
603 INLINE(static bool IsConstantPoolLoadStart( | 605 INLINE(static bool IsConstantPoolLoadStart( |
604 Address pc, ConstantPoolEntry::Access* access = nullptr)); | 606 Address pc, ConstantPoolEntry::Access* access = nullptr)); |
605 INLINE(static bool IsConstantPoolLoadEnd( | 607 INLINE(static bool IsConstantPoolLoadEnd( |
606 Address pc, ConstantPoolEntry::Access* access = nullptr)); | 608 Address pc, ConstantPoolEntry::Access* access = nullptr)); |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 void EmitRelocations(); | 1418 void EmitRelocations(); |
1417 | 1419 |
1418 protected: | 1420 protected: |
1419 // Relocation for a type-recording IC has the AST id added to it. This | 1421 // Relocation for a type-recording IC has the AST id added to it. This |
1420 // member variable is a way to pass the information from the call site to | 1422 // member variable is a way to pass the information from the call site to |
1421 // the relocation info. | 1423 // the relocation info. |
1422 TypeFeedbackId recorded_ast_id_; | 1424 TypeFeedbackId recorded_ast_id_; |
1423 | 1425 |
1424 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1426 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
1425 | 1427 |
1426 // Decode branch instruction at pos and return branch target pos | 1428 // Decode instruction(s) at pos and return backchain to previous |
| 1429 // label reference or kEndOfChain. |
1427 int target_at(int pos); | 1430 int target_at(int pos); |
1428 | 1431 |
1429 // Patch branch instruction at pos to branch to given branch target pos | 1432 // Patch instruction(s) at pos to target target_pos (e.g. branch) |
1430 void target_at_put(int pos, int target_pos); | 1433 void target_at_put(int pos, int target_pos, bool* is_branch = nullptr); |
1431 | 1434 |
1432 // Record reloc info for current pc_ | 1435 // Record reloc info for current pc_ |
1433 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1436 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1434 ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode, | 1437 ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode, |
1435 intptr_t value) { | 1438 intptr_t value) { |
1436 bool sharing_ok = RelocInfo::IsNone(rmode) || | 1439 bool sharing_ok = RelocInfo::IsNone(rmode) || |
1437 !(serializer_enabled() || rmode < RelocInfo::CELL || | 1440 !(serializer_enabled() || rmode < RelocInfo::CELL || |
1438 is_constant_pool_entry_sharing_blocked()); | 1441 is_constant_pool_entry_sharing_blocked()); |
1439 return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok); | 1442 return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok); |
1440 } | 1443 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1472 // Code generation | 1475 // Code generation |
1473 // The relocation writer's position is at least kGap bytes below the end of | 1476 // The relocation writer's position is at least kGap bytes below the end of |
1474 // the generated instructions. This is so that multi-instruction sequences do | 1477 // the generated instructions. This is so that multi-instruction sequences do |
1475 // not have to check for overflow. The same is true for writes of large | 1478 // not have to check for overflow. The same is true for writes of large |
1476 // relocation info entries. | 1479 // relocation info entries. |
1477 static const int kGap = 32; | 1480 static const int kGap = 32; |
1478 | 1481 |
1479 // Repeated checking whether the trampoline pool should be emitted is rather | 1482 // Repeated checking whether the trampoline pool should be emitted is rather |
1480 // expensive. By default we only check again once a number of instructions | 1483 // expensive. By default we only check again once a number of instructions |
1481 // has been generated. | 1484 // has been generated. |
1482 int next_buffer_check_; // pc offset of next buffer check. | 1485 int next_trampoline_check_; // pc offset of next buffer check. |
1483 | 1486 |
1484 // Emission of the trampoline pool may be blocked in some code sequences. | 1487 // Emission of the trampoline pool may be blocked in some code sequences. |
1485 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. | 1488 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. |
1486 int no_trampoline_pool_before_; // Block emission before this pc offset. | 1489 int no_trampoline_pool_before_; // Block emission before this pc offset. |
1487 | 1490 |
1488 // Do not share constant pool entries. | 1491 // Do not share constant pool entries. |
1489 int constant_pool_entry_sharing_blocked_nesting_; | 1492 int constant_pool_entry_sharing_blocked_nesting_; |
1490 | 1493 |
1491 // Relocation info generation | 1494 // Relocation info generation |
1492 // Each relocation is encoded as a variable size value | 1495 // Each relocation is encoded as a variable size value |
1493 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1496 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
1494 RelocInfoWriter reloc_info_writer; | 1497 RelocInfoWriter reloc_info_writer; |
1495 std::vector<DeferredRelocInfo> relocations_; | 1498 std::vector<DeferredRelocInfo> relocations_; |
1496 | 1499 |
1497 // The bound position, before this we cannot do instruction elimination. | 1500 // The bound position, before this we cannot do instruction elimination. |
1498 int last_bound_pos_; | 1501 int last_bound_pos_; |
1499 // Optimizable cmpi information. | 1502 // Optimizable cmpi information. |
1500 int optimizable_cmpi_pos_; | 1503 int optimizable_cmpi_pos_; |
1501 CRegister cmpi_cr_; | 1504 CRegister cmpi_cr_; |
1502 | 1505 |
1503 ConstantPoolBuilder constant_pool_builder_; | 1506 ConstantPoolBuilder constant_pool_builder_; |
1504 | 1507 |
1505 // Code emission | 1508 // Code emission |
1506 inline void CheckBuffer(); | 1509 inline void CheckBuffer(); |
1507 void GrowBuffer(int needed = 0); | 1510 void GrowBuffer(int needed = 0); |
1508 inline void emit(Instr x); | 1511 inline void emit(Instr x); |
| 1512 inline void TrackBranch(); |
| 1513 inline void UntrackBranch(); |
1509 inline void CheckTrampolinePoolQuick(); | 1514 inline void CheckTrampolinePoolQuick(); |
1510 | 1515 |
1511 // Instruction generation | 1516 // Instruction generation |
1512 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, | 1517 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, |
1513 DoubleRegister frb, RCBit r); | 1518 DoubleRegister frb, RCBit r); |
1514 void d_form(Instr instr, Register rt, Register ra, const intptr_t val, | 1519 void d_form(Instr instr, Register rt, Register ra, const intptr_t val, |
1515 bool signed_disp); | 1520 bool signed_disp); |
1516 void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r); | 1521 void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r); |
1517 void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o, | 1522 void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o, |
1518 RCBit r); | 1523 RCBit r); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 } | 1557 } |
1553 return trampoline_slot; | 1558 return trampoline_slot; |
1554 } | 1559 } |
1555 | 1560 |
1556 private: | 1561 private: |
1557 int next_slot_; | 1562 int next_slot_; |
1558 int free_slot_count_; | 1563 int free_slot_count_; |
1559 }; | 1564 }; |
1560 | 1565 |
1561 int32_t get_trampoline_entry(); | 1566 int32_t get_trampoline_entry(); |
1562 int unbound_labels_count_; | 1567 int tracked_branch_count_; |
1563 // If trampoline is emitted, generated code is becoming large. As | 1568 // If trampoline is emitted, generated code is becoming large. As |
1564 // this is already a slow case which can possibly break our code | 1569 // this is already a slow case which can possibly break our code |
1565 // generation for the extreme case, we use this information to | 1570 // generation for the extreme case, we use this information to |
1566 // trigger different mode of branch instruction generation, where we | 1571 // trigger different mode of branch instruction generation, where we |
1567 // no longer use a single branch instruction. | 1572 // no longer use a single branch instruction. |
1568 bool trampoline_emitted_; | 1573 bool trampoline_emitted_; |
1569 static const int kTrampolineSlotsSize = kInstrSize; | 1574 static const int kTrampolineSlotsSize = kInstrSize; |
1570 static const int kMaxCondBranchReach = (1 << (16 - 1)) - 1; | 1575 static const int kMaxCondBranchReach = (1 << (16 - 1)) - 1; |
1571 static const int kMaxBlockTrampolineSectionSize = 64 * kInstrSize; | 1576 static const int kMaxBlockTrampolineSectionSize = 64 * kInstrSize; |
1572 static const int kInvalidSlotPos = -1; | 1577 static const int kInvalidSlotPos = -1; |
(...skipping 12 matching lines...) Expand all Loading... |
1585 | 1590 |
1586 | 1591 |
1587 class EnsureSpace BASE_EMBEDDED { | 1592 class EnsureSpace BASE_EMBEDDED { |
1588 public: | 1593 public: |
1589 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 1594 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } |
1590 }; | 1595 }; |
1591 } | 1596 } |
1592 } // namespace v8::internal | 1597 } // namespace v8::internal |
1593 | 1598 |
1594 #endif // V8_PPC_ASSEMBLER_PPC_H_ | 1599 #endif // V8_PPC_ASSEMBLER_PPC_H_ |
OLD | NEW |