| 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 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 | 773 |
| 774 // Returns the branch offset to the given label from the current code position | 774 // Returns the branch offset to the given label from the current code position |
| 775 // Links the label to the current position if it is still unbound | 775 // Links the label to the current position if it is still unbound |
| 776 // Manages the jump elimination optimization if the second parameter is true. | 776 // Manages the jump elimination optimization if the second parameter is true. |
| 777 int branch_offset(Label* L, bool jump_elimination_allowed); | 777 int branch_offset(Label* L, bool jump_elimination_allowed); |
| 778 | 778 |
| 779 // Return the address in the constant pool of the code target address used by | 779 // Return the address in the constant pool of the code target address used by |
| 780 // the branch/call instruction at pc, or the object in a mov. | 780 // the branch/call instruction at pc, or the object in a mov. |
| 781 INLINE(static Address target_pointer_address_at(Address pc)); | 781 INLINE(static Address target_pointer_address_at(Address pc)); |
| 782 | 782 |
| 783 // Return the address in the constant pool of the code target address used by |
| 784 // the branch/call instruction at pc, or the object in a mov. |
| 785 INLINE(static Address target_constant_pool_address_at( |
| 786 Address pc, ConstantPoolArray* constant_pool)); |
| 787 |
| 783 // Read/Modify the code target address in the branch/call instruction at pc. | 788 // Read/Modify the code target address in the branch/call instruction at pc. |
| 784 INLINE(static Address target_address_at(Address pc)); | 789 INLINE(static Address target_address_at(Address pc, |
| 785 INLINE(static void set_target_address_at(Address pc, Address target)); | 790 ConstantPoolArray* constant_pool)); |
| 791 INLINE(static void set_target_address_at(Address pc, |
| 792 ConstantPoolArray* constant_pool, |
| 793 Address target)); |
| 794 INLINE(static Address target_address_at(Address pc, Code* code)) { |
| 795 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; |
| 796 return target_address_at(pc, constant_pool); |
| 797 } |
| 798 INLINE(static void set_target_address_at(Address pc, |
| 799 Code* code, |
| 800 Address target)) { |
| 801 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; |
| 802 set_target_address_at(pc, constant_pool, target); |
| 803 } |
| 786 | 804 |
| 787 // Return the code target address at a call site from the return address | 805 // Return the code target address at a call site from the return address |
| 788 // of that call in the instruction stream. | 806 // of that call in the instruction stream. |
| 789 INLINE(static Address target_address_from_return_address(Address pc)); | 807 INLINE(static Address target_address_from_return_address(Address pc)); |
| 790 | 808 |
| 791 // Given the address of the beginning of a call, return the address | 809 // Given the address of the beginning of a call, return the address |
| 792 // in the instruction stream that the call will return from. | 810 // in the instruction stream that the call will return from. |
| 793 INLINE(static Address return_address_from_call_start(Address pc)); | 811 INLINE(static Address return_address_from_call_start(Address pc)); |
| 794 | 812 |
| 795 // This sets the branch destination (which is in the constant pool on ARM). | 813 // This sets the branch destination (which is in the constant pool on ARM). |
| 796 // This is for calls and branches within generated code. | 814 // This is for calls and branches within generated code. |
| 797 inline static void deserialization_set_special_target_at( | 815 inline static void deserialization_set_special_target_at( |
| 798 Address constant_pool_entry, Address target); | 816 Address constant_pool_entry, Code* code, Address target); |
| 799 | 817 |
| 800 // Here we are patching the address in the constant pool, not the actual call | 818 // Here we are patching the address in the constant pool, not the actual call |
| 801 // instruction. The address in the constant pool is the same size as a | 819 // instruction. The address in the constant pool is the same size as a |
| 802 // pointer. | 820 // pointer. |
| 803 static const int kSpecialTargetSize = kPointerSize; | 821 static const int kSpecialTargetSize = kPointerSize; |
| 804 | 822 |
| 805 // Size of an instruction. | 823 // Size of an instruction. |
| 806 static const int kInstrSize = sizeof(Instr); | 824 static const int kInstrSize = sizeof(Instr); |
| 807 | 825 |
| 808 // Distance between start of patched return sequence and the emitted address | 826 // Distance between start of patched return sequence and the emitted address |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 ldr(dst, MemOperand(sp, 4, PostIndex), cond); | 1303 ldr(dst, MemOperand(sp, 4, PostIndex), cond); |
| 1286 } | 1304 } |
| 1287 | 1305 |
| 1288 void pop() { | 1306 void pop() { |
| 1289 add(sp, sp, Operand(kPointerSize)); | 1307 add(sp, sp, Operand(kPointerSize)); |
| 1290 } | 1308 } |
| 1291 | 1309 |
| 1292 // Jump unconditionally to given label. | 1310 // Jump unconditionally to given label. |
| 1293 void jmp(Label* L) { b(L, al); } | 1311 void jmp(Label* L) { b(L, al); } |
| 1294 | 1312 |
| 1295 static bool use_immediate_embedded_pointer_loads( | |
| 1296 const Assembler* assembler) { | |
| 1297 return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) && | |
| 1298 (assembler == NULL || !assembler->predictable_code_size()); | |
| 1299 } | |
| 1300 | |
| 1301 // Check the code size generated from label to here. | 1313 // Check the code size generated from label to here. |
| 1302 int SizeOfCodeGeneratedSince(Label* label) { | 1314 int SizeOfCodeGeneratedSince(Label* label) { |
| 1303 return pc_offset() - label->pos(); | 1315 return pc_offset() - label->pos(); |
| 1304 } | 1316 } |
| 1305 | 1317 |
| 1306 // Check the number of instructions generated from label to here. | 1318 // Check the number of instructions generated from label to here. |
| 1307 int InstructionsGeneratedSince(Label* label) { | 1319 int InstructionsGeneratedSince(Label* label) { |
| 1308 return SizeOfCodeGeneratedSince(label) / kInstrSize; | 1320 return SizeOfCodeGeneratedSince(label) / kInstrSize; |
| 1309 } | 1321 } |
| 1310 | 1322 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; | 1451 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; |
| 1440 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; | 1452 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; |
| 1441 | 1453 |
| 1442 // Postpone the generation of the constant pool for the specified number of | 1454 // Postpone the generation of the constant pool for the specified number of |
| 1443 // instructions. | 1455 // instructions. |
| 1444 void BlockConstPoolFor(int instructions); | 1456 void BlockConstPoolFor(int instructions); |
| 1445 | 1457 |
| 1446 // Check if is time to emit a constant pool. | 1458 // Check if is time to emit a constant pool. |
| 1447 void CheckConstPool(bool force_emit, bool require_jump); | 1459 void CheckConstPool(bool force_emit, bool require_jump); |
| 1448 | 1460 |
| 1461 bool can_use_constant_pool() const { |
| 1462 return is_constant_pool_available() && !constant_pool_full_; |
| 1463 } |
| 1464 |
| 1465 void set_constant_pool_full() { |
| 1466 constant_pool_full_ = true; |
| 1467 } |
| 1468 |
| 1449 protected: | 1469 protected: |
| 1450 // Relocation for a type-recording IC has the AST id added to it. This | 1470 // Relocation for a type-recording IC has the AST id added to it. This |
| 1451 // member variable is a way to pass the information from the call site to | 1471 // member variable is a way to pass the information from the call site to |
| 1452 // the relocation info. | 1472 // the relocation info. |
| 1453 TypeFeedbackId recorded_ast_id_; | 1473 TypeFeedbackId recorded_ast_id_; |
| 1454 | 1474 |
| 1455 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1475 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
| 1456 | 1476 |
| 1457 // Decode branch instruction at pos and return branch target pos | 1477 // Decode branch instruction at pos and return branch target pos |
| 1458 int target_at(int pos); | 1478 int target_at(int pos); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 // trigger a check. | 1512 // trigger a check. |
| 1493 next_buffer_check_ = no_const_pool_before_; | 1513 next_buffer_check_ = no_const_pool_before_; |
| 1494 } | 1514 } |
| 1495 } | 1515 } |
| 1496 | 1516 |
| 1497 bool is_const_pool_blocked() const { | 1517 bool is_const_pool_blocked() const { |
| 1498 return (const_pool_blocked_nesting_ > 0) || | 1518 return (const_pool_blocked_nesting_ > 0) || |
| 1499 (pc_offset() < no_const_pool_before_); | 1519 (pc_offset() < no_const_pool_before_); |
| 1500 } | 1520 } |
| 1501 | 1521 |
| 1522 bool is_constant_pool_available() const { |
| 1523 return constant_pool_available_; |
| 1524 } |
| 1525 |
| 1526 void set_constant_pool_available(bool available) { |
| 1527 constant_pool_available_ = available; |
| 1528 } |
| 1529 |
| 1502 private: | 1530 private: |
| 1503 int next_buffer_check_; // pc offset of next buffer check | 1531 int next_buffer_check_; // pc offset of next buffer check |
| 1504 | 1532 |
| 1505 // Code generation | 1533 // Code generation |
| 1506 // The relocation writer's position is at least kGap bytes below the end of | 1534 // The relocation writer's position is at least kGap bytes below the end of |
| 1507 // the generated instructions. This is so that multi-instruction sequences do | 1535 // the generated instructions. This is so that multi-instruction sequences do |
| 1508 // not have to check for overflow. The same is true for writes of large | 1536 // not have to check for overflow. The same is true for writes of large |
| 1509 // relocation info entries. | 1537 // relocation info entries. |
| 1510 static const int kGap = 32; | 1538 static const int kGap = 32; |
| 1511 | 1539 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo]; | 1580 RelocInfo pending_32_bit_reloc_info_[kMaxNumPending32RelocInfo]; |
| 1553 RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo]; | 1581 RelocInfo pending_64_bit_reloc_info_[kMaxNumPending64RelocInfo]; |
| 1554 // Number of pending reloc info entries in the 32 bits buffer. | 1582 // Number of pending reloc info entries in the 32 bits buffer. |
| 1555 int num_pending_32_bit_reloc_info_; | 1583 int num_pending_32_bit_reloc_info_; |
| 1556 // Number of pending reloc info entries in the 64 bits buffer. | 1584 // Number of pending reloc info entries in the 64 bits buffer. |
| 1557 int num_pending_64_bit_reloc_info_; | 1585 int num_pending_64_bit_reloc_info_; |
| 1558 | 1586 |
| 1559 // The bound position, before this we cannot do instruction elimination. | 1587 // The bound position, before this we cannot do instruction elimination. |
| 1560 int last_bound_pos_; | 1588 int last_bound_pos_; |
| 1561 | 1589 |
| 1590 // Indicates whether the constant pool can be accessed, which is only possible |
| 1591 // if the pp register points to the current code object's constant pool. |
| 1592 bool constant_pool_available_; |
| 1593 // Indicates whether the constant pool is too full to accept new entries due |
| 1594 // to the ldr instruction's limitted immediate offset range. |
| 1595 bool constant_pool_full_; |
| 1596 |
| 1562 // Code emission | 1597 // Code emission |
| 1563 inline void CheckBuffer(); | 1598 inline void CheckBuffer(); |
| 1564 void GrowBuffer(); | 1599 void GrowBuffer(); |
| 1565 inline void emit(Instr x); | 1600 inline void emit(Instr x); |
| 1566 | 1601 |
| 1567 // 32-bit immediate values | 1602 // 32-bit immediate values |
| 1568 void move_32_bit_immediate(Condition cond, | 1603 void move_32_bit_immediate(Register rd, |
| 1569 Register rd, | 1604 const Operand& x, |
| 1570 SBit s, | 1605 Condition cond = al); |
| 1571 const Operand& x); | |
| 1572 | 1606 |
| 1573 // Instruction generation | 1607 // Instruction generation |
| 1574 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); | 1608 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); |
| 1575 void addrmod2(Instr instr, Register rd, const MemOperand& x); | 1609 void addrmod2(Instr instr, Register rd, const MemOperand& x); |
| 1576 void addrmod3(Instr instr, Register rd, const MemOperand& x); | 1610 void addrmod3(Instr instr, Register rd, const MemOperand& x); |
| 1577 void addrmod4(Instr instr, Register rn, RegList rl); | 1611 void addrmod4(Instr instr, Register rn, RegList rl); |
| 1578 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); | 1612 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); |
| 1579 | 1613 |
| 1580 // Labels | 1614 // Labels |
| 1581 void print(Label* L); | 1615 void print(Label* L); |
| 1582 void bind_to(Label* L, int pos); | 1616 void bind_to(Label* L, int pos); |
| 1583 void next(Label* L); | 1617 void next(Label* L); |
| 1584 | 1618 |
| 1585 enum UseConstantPoolMode { | 1619 enum UseConstantPoolMode { |
| 1586 USE_CONSTANT_POOL, | 1620 USE_CONSTANT_POOL, |
| 1587 DONT_USE_CONSTANT_POOL | 1621 DONT_USE_CONSTANT_POOL |
| 1588 }; | 1622 }; |
| 1589 | 1623 |
| 1590 // Record reloc info for current pc_ | 1624 // Record reloc info for current pc_ |
| 1591 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0, | 1625 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0, |
| 1592 UseConstantPoolMode mode = USE_CONSTANT_POOL); | 1626 UseConstantPoolMode mode = USE_CONSTANT_POOL); |
| 1593 void RecordRelocInfo(double data); | 1627 void RecordRelocInfo(double data); |
| 1594 void RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo); | 1628 void RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo); |
| 1595 | 1629 |
| 1596 friend class RelocInfo; | 1630 friend class RelocInfo; |
| 1597 friend class CodePatcher; | 1631 friend class CodePatcher; |
| 1598 friend class BlockConstPoolScope; | 1632 friend class BlockConstPoolScope; |
| 1633 friend class FrameAndConstantPoolScope; |
| 1634 friend class ConstantPoolUnavailableScope; |
| 1599 | 1635 |
| 1600 PositionsRecorder positions_recorder_; | 1636 PositionsRecorder positions_recorder_; |
| 1601 friend class PositionsRecorder; | 1637 friend class PositionsRecorder; |
| 1602 friend class EnsureSpace; | 1638 friend class EnsureSpace; |
| 1603 }; | 1639 }; |
| 1604 | 1640 |
| 1605 | 1641 |
| 1606 class EnsureSpace BASE_EMBEDDED { | 1642 class EnsureSpace BASE_EMBEDDED { |
| 1607 public: | 1643 public: |
| 1608 explicit EnsureSpace(Assembler* assembler) { | 1644 explicit EnsureSpace(Assembler* assembler) { |
| 1609 assembler->CheckBuffer(); | 1645 assembler->CheckBuffer(); |
| 1610 } | 1646 } |
| 1611 }; | 1647 }; |
| 1612 | 1648 |
| 1613 | 1649 |
| 1614 } } // namespace v8::internal | 1650 } } // namespace v8::internal |
| 1615 | 1651 |
| 1616 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1652 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |