Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(417)

Side by Side Diff: src/arm/assembler-arm.h

Issue 356393003: [Arm]: Enable use of extended out-of-line constant pool for Arm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix issue with inline-constant pool. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm/assembler-arm.cc » ('j') | src/arm/assembler-arm.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); 511 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2);
512 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); 512 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize);
513 } 513 }
514 514
515 // rm <shift_op> rs 515 // rm <shift_op> rs
516 explicit Operand(Register rm, ShiftOp shift_op, Register rs); 516 explicit Operand(Register rm, ShiftOp shift_op, Register rs);
517 517
518 // Return true if this is a register operand. 518 // Return true if this is a register operand.
519 INLINE(bool is_reg() const); 519 INLINE(bool is_reg() const);
520 520
521 // Return true if this operand fits in one instruction so that no 521 // Return the number of actual instructions required to implement the given
522 // 2-instruction solution with a load into the ip register is necessary. If 522 // instruction for this particular operand. This can be a single instruction,
523 // if no load into the ip register is necessary, or anything between 2 and 4
524 // instructions when we need to load from the constant pool (depending upon
525 // whether the constant pool entry is in the small or extended section). If
523 // the instruction this operand is used for is a MOV or MVN instruction the 526 // the instruction this operand is used for is a MOV or MVN instruction the
524 // actual instruction to use is required for this calculation. For other 527 // actual instruction to use is required for this calculation. For other
525 // instructions instr is ignored. 528 // instructions instr is ignored.
526 bool is_single_instruction(const Assembler* assembler, 529 int instructions_required(const Assembler* assembler, Instr instr = 0) const;
527 Instr instr = 0) const;
528 bool must_output_reloc_info(const Assembler* assembler) const; 530 bool must_output_reloc_info(const Assembler* assembler) const;
529 531
530 inline int32_t immediate() const { 532 inline int32_t immediate() const {
531 ASSERT(!rm_.is_valid()); 533 ASSERT(!rm_.is_valid());
532 return imm32_; 534 return imm32_;
533 } 535 }
534 536
535 Register rm() const { return rm_; } 537 Register rm() const { return rm_; }
536 Register rs() const { return rs_; } 538 Register rs() const { return rs_; }
537 ShiftOp shift_op() const { return shift_op_; } 539 ShiftOp shift_op() const { return shift_op_; }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 private: 640 private:
639 DoubleRegister base_; 641 DoubleRegister base_;
640 NeonListType type_; 642 NeonListType type_;
641 }; 643 };
642 644
643 645
644 // Class used to build a constant pool. 646 // Class used to build a constant pool.
645 class ConstantPoolBuilder BASE_EMBEDDED { 647 class ConstantPoolBuilder BASE_EMBEDDED {
646 public: 648 public:
647 explicit ConstantPoolBuilder(); 649 explicit ConstantPoolBuilder();
648 void AddEntry(Assembler* assm, const RelocInfo& rinfo); 650 ConstantPoolArray::LayoutSection AddEntry(Assembler* assm,
651 const RelocInfo& rinfo);
649 void Relocate(int pc_delta); 652 void Relocate(int pc_delta);
650 bool IsEmpty(); 653 bool IsEmpty();
651 Handle<ConstantPoolArray> New(Isolate* isolate); 654 Handle<ConstantPoolArray> New(Isolate* isolate);
652 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); 655 void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
653 656
654 inline int count_of_64bit() const { return count_of_64bit_; } 657 inline ConstantPoolArray::LayoutSection current_section() const {
655 inline int count_of_code_ptr() const { return count_of_code_ptr_; } 658 return current_section_;
656 inline int count_of_heap_ptr() const { return count_of_heap_ptr_; } 659 }
657 inline int count_of_32bit() const { return count_of_32bit_; } 660
661 inline ConstantPoolArray::NumberOfEntries* number_of_entries(
662 ConstantPoolArray::LayoutSection section) {
663 return &number_of_entries_[section];
664 }
665
666 inline ConstantPoolArray::NumberOfEntries* small_entries() {
667 return number_of_entries(ConstantPoolArray::SMALL_SECTION);
668 }
669
670 inline ConstantPoolArray::NumberOfEntries* extended_entries() {
671 return number_of_entries(ConstantPoolArray::EXTENDED_SECTION);
672 }
658 673
659 private: 674 private:
660 bool Is64BitEntry(RelocInfo::Mode rmode); 675 struct ConstantPoolEntry {
661 bool Is32BitEntry(RelocInfo::Mode rmode); 676 ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section,
662 bool IsCodePtrEntry(RelocInfo::Mode rmode); 677 int merged_index)
663 bool IsHeapPtrEntry(RelocInfo::Mode rmode); 678 : rinfo_(rinfo), section_(section), merged_index_(merged_index) { }
664 679
665 // TODO(rmcilroy): This should ideally be a ZoneList, however that would mean 680 RelocInfo rinfo_;
666 // RelocInfo would need to subclass ZoneObject which it currently doesn't. 681 ConstantPoolArray::LayoutSection section_;
667 std::vector<RelocInfo> entries_; 682 int merged_index_;
668 std::vector<int> merged_indexes_; 683 };
669 int count_of_64bit_; 684
670 int count_of_code_ptr_; 685 ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode);
671 int count_of_heap_ptr_; 686
672 int count_of_32bit_; 687 std::vector<ConstantPoolEntry> entries_;
688 ConstantPoolArray::LayoutSection current_section_;
689 ConstantPoolArray::NumberOfEntries number_of_entries_[2];
673 }; 690 };
674 691
675 struct VmovIndex { 692 struct VmovIndex {
676 unsigned char index; 693 unsigned char index;
677 }; 694 };
678 const VmovIndex VmovIndexLo = { 0 }; 695 const VmovIndex VmovIndexLo = { 0 };
679 const VmovIndex VmovIndexHi = { 1 }; 696 const VmovIndex VmovIndexHi = { 1 };
680 697
681 class Assembler : public AssemblerBase { 698 class Assembler : public AssemblerBase {
682 public: 699 public:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 // Note: The same Label can be used for forward and backward branches 733 // Note: The same Label can be used for forward and backward branches
717 // but it may be bound only once. 734 // but it may be bound only once.
718 735
719 void bind(Label* L); // binds an unbound label L to the current code position 736 void bind(Label* L); // binds an unbound label L to the current code position
720 737
721 // Returns the branch offset to the given label from the current code position 738 // Returns the branch offset to the given label from the current code position
722 // Links the label to the current position if it is still unbound 739 // Links the label to the current position if it is still unbound
723 // Manages the jump elimination optimization if the second parameter is true. 740 // Manages the jump elimination optimization if the second parameter is true.
724 int branch_offset(Label* L, bool jump_elimination_allowed); 741 int branch_offset(Label* L, bool jump_elimination_allowed);
725 742
743 // Returns true if the given pc address is the start of a constant pool load
744 // instruction sequence.
745 INLINE(static bool is_constant_pool_load(Address pc));
746
726 // Return the address in the constant pool of the code target address used by 747 // Return the address in the constant pool of the code target address used by
727 // the branch/call instruction at pc, or the object in a mov. 748 // the branch/call instruction at pc, or the object in a mov.
728 INLINE(static Address constant_pool_entry_address( 749 INLINE(static Address constant_pool_entry_address(
729 Address pc, ConstantPoolArray* constant_pool)); 750 Address pc, ConstantPoolArray* constant_pool));
730 751
731 // Read/Modify the code target address in the branch/call instruction at pc. 752 // Read/Modify the code target address in the branch/call instruction at pc.
732 INLINE(static Address target_address_at(Address pc, 753 INLINE(static Address target_address_at(Address pc,
733 ConstantPoolArray* constant_pool)); 754 ConstantPoolArray* constant_pool));
734 INLINE(static void set_target_address_at(Address pc, 755 INLINE(static void set_target_address_at(Address pc,
735 ConstantPoolArray* constant_pool, 756 ConstantPoolArray* constant_pool,
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 1373 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1353 static void instr_at_put(byte* pc, Instr instr) { 1374 static void instr_at_put(byte* pc, Instr instr) {
1354 *reinterpret_cast<Instr*>(pc) = instr; 1375 *reinterpret_cast<Instr*>(pc) = instr;
1355 } 1376 }
1356 static Condition GetCondition(Instr instr); 1377 static Condition GetCondition(Instr instr);
1357 static bool IsBranch(Instr instr); 1378 static bool IsBranch(Instr instr);
1358 static int GetBranchOffset(Instr instr); 1379 static int GetBranchOffset(Instr instr);
1359 static bool IsLdrRegisterImmediate(Instr instr); 1380 static bool IsLdrRegisterImmediate(Instr instr);
1360 static bool IsVldrDRegisterImmediate(Instr instr); 1381 static bool IsVldrDRegisterImmediate(Instr instr);
1361 static Instr GetConsantPoolLoadPattern(); 1382 static Instr GetConsantPoolLoadPattern();
1383 static Instr GetConsantPoolLoadMask();
1384 static bool IsLdrPpRegOffset(Instr instr);
1385 static Instr GetLdrPpRegOffsetPattern();
1362 static bool IsLdrPpImmediateOffset(Instr instr); 1386 static bool IsLdrPpImmediateOffset(Instr instr);
1363 static bool IsVldrDPpImmediateOffset(Instr instr); 1387 static bool IsVldrDPpImmediateOffset(Instr instr);
1364 static int GetLdrRegisterImmediateOffset(Instr instr); 1388 static int GetLdrRegisterImmediateOffset(Instr instr);
1365 static int GetVldrDRegisterImmediateOffset(Instr instr); 1389 static int GetVldrDRegisterImmediateOffset(Instr instr);
1366 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); 1390 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset);
1367 static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset); 1391 static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset);
1368 static bool IsStrRegisterImmediate(Instr instr); 1392 static bool IsStrRegisterImmediate(Instr instr);
1369 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); 1393 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset);
1370 static bool IsAddRegisterImmediate(Instr instr); 1394 static bool IsAddRegisterImmediate(Instr instr);
1371 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); 1395 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset);
(...skipping 10 matching lines...) Expand all
1382 static bool IsVldrDPcImmediateOffset(Instr instr); 1406 static bool IsVldrDPcImmediateOffset(Instr instr);
1383 static bool IsBlxReg(Instr instr); 1407 static bool IsBlxReg(Instr instr);
1384 static bool IsBlxIp(Instr instr); 1408 static bool IsBlxIp(Instr instr);
1385 static bool IsTstImmediate(Instr instr); 1409 static bool IsTstImmediate(Instr instr);
1386 static bool IsCmpRegister(Instr instr); 1410 static bool IsCmpRegister(Instr instr);
1387 static bool IsCmpImmediate(Instr instr); 1411 static bool IsCmpImmediate(Instr instr);
1388 static Register GetCmpImmediateRegister(Instr instr); 1412 static Register GetCmpImmediateRegister(Instr instr);
1389 static int GetCmpImmediateRawImmediate(Instr instr); 1413 static int GetCmpImmediateRawImmediate(Instr instr);
1390 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 1414 static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1391 static bool IsMovT(Instr instr); 1415 static bool IsMovT(Instr instr);
1416 static Instr GetMovTPattern();
1392 static bool IsMovW(Instr instr); 1417 static bool IsMovW(Instr instr);
1418 static Instr GetMovWPattern();
1419 static Instr EncodeMovwImmediate(uint32_t immediate);
1420 static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate);
1393 1421
1394 // Constants in pools are accessed via pc relative addressing, which can 1422 // Constants in pools are accessed via pc relative addressing, which can
1395 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point 1423 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
1396 // PC-relative loads, thereby defining a maximum distance between the 1424 // PC-relative loads, thereby defining a maximum distance between the
1397 // instruction and the accessed constant. 1425 // instruction and the accessed constant.
1398 static const int kMaxDistToIntPool = 4*KB; 1426 static const int kMaxDistToIntPool = 4*KB;
1399 static const int kMaxDistToFPPool = 1*KB; 1427 static const int kMaxDistToFPPool = 1*KB;
1400 // All relocations could be integer, it therefore acts as the limit. 1428 // All relocations could be integer, it therefore acts as the limit.
1401 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; 1429 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize;
1402 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; 1430 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize;
1403 1431
1404 // Postpone the generation of the constant pool for the specified number of 1432 // Postpone the generation of the constant pool for the specified number of
1405 // instructions. 1433 // instructions.
1406 void BlockConstPoolFor(int instructions); 1434 void BlockConstPoolFor(int instructions);
1407 1435
1408 // Check if is time to emit a constant pool. 1436 // Check if is time to emit a constant pool.
1409 void CheckConstPool(bool force_emit, bool require_jump); 1437 void CheckConstPool(bool force_emit, bool require_jump);
1410 1438
1411 // Allocate a constant pool of the correct size for the generated code. 1439 // Allocate a constant pool of the correct size for the generated code.
1412 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); 1440 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
1413 1441
1414 // Generate the constant pool for the generated code. 1442 // Generate the constant pool for the generated code.
1415 void PopulateConstantPool(ConstantPoolArray* constant_pool); 1443 void PopulateConstantPool(ConstantPoolArray* constant_pool);
1416 1444
1417 bool can_use_constant_pool() const { 1445 bool is_constant_pool_available() const {
1418 return is_constant_pool_available() && !constant_pool_full_; 1446 return constant_pool_available_;
1419 } 1447 }
1420 1448
1421 void set_constant_pool_full() { 1449 bool use_extended_constant_pool() const {
1422 constant_pool_full_ = true; 1450 return constant_pool_builder_.current_section() ==
1451 ConstantPoolArray::EXTENDED_SECTION;
1423 } 1452 }
1424 1453
1454
1425 protected: 1455 protected:
1426 // Relocation for a type-recording IC has the AST id added to it. This 1456 // Relocation for a type-recording IC has the AST id added to it. This
1427 // member variable is a way to pass the information from the call site to 1457 // member variable is a way to pass the information from the call site to
1428 // the relocation info. 1458 // the relocation info.
1429 TypeFeedbackId recorded_ast_id_; 1459 TypeFeedbackId recorded_ast_id_;
1430 1460
1431 int buffer_space() const { return reloc_info_writer.pos() - pc_; } 1461 int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1432 1462
1433 // Decode branch instruction at pos and return branch target pos 1463 // Decode branch instruction at pos and return branch target pos
1434 int target_at(int pos); 1464 int target_at(int pos);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 // trigger a check. 1498 // trigger a check.
1469 next_buffer_check_ = no_const_pool_before_; 1499 next_buffer_check_ = no_const_pool_before_;
1470 } 1500 }
1471 } 1501 }
1472 1502
1473 bool is_const_pool_blocked() const { 1503 bool is_const_pool_blocked() const {
1474 return (const_pool_blocked_nesting_ > 0) || 1504 return (const_pool_blocked_nesting_ > 0) ||
1475 (pc_offset() < no_const_pool_before_); 1505 (pc_offset() < no_const_pool_before_);
1476 } 1506 }
1477 1507
1478 bool is_constant_pool_available() const {
1479 return constant_pool_available_;
1480 }
1481
1482 void set_constant_pool_available(bool available) { 1508 void set_constant_pool_available(bool available) {
1483 constant_pool_available_ = available; 1509 constant_pool_available_ = available;
1484 } 1510 }
1485 1511
1486 private: 1512 private:
1487 int next_buffer_check_; // pc offset of next buffer check 1513 int next_buffer_check_; // pc offset of next buffer check
1488 1514
1489 // Code generation 1515 // Code generation
1490 // The relocation writer's position is at least kGap bytes below the end of 1516 // The relocation writer's position is at least kGap bytes below the end of
1491 // the generated instructions. This is so that multi-instruction sequences do 1517 // the generated instructions. This is so that multi-instruction sequences do
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 int num_pending_64_bit_reloc_info_; 1567 int num_pending_64_bit_reloc_info_;
1542 1568
1543 ConstantPoolBuilder constant_pool_builder_; 1569 ConstantPoolBuilder constant_pool_builder_;
1544 1570
1545 // The bound position, before this we cannot do instruction elimination. 1571 // The bound position, before this we cannot do instruction elimination.
1546 int last_bound_pos_; 1572 int last_bound_pos_;
1547 1573
1548 // Indicates whether the constant pool can be accessed, which is only possible 1574 // Indicates whether the constant pool can be accessed, which is only possible
1549 // if the pp register points to the current code object's constant pool. 1575 // if the pp register points to the current code object's constant pool.
1550 bool constant_pool_available_; 1576 bool constant_pool_available_;
1551 // Indicates whether the constant pool is too full to accept new entries due
1552 // to the ldr instruction's limitted immediate offset range.
1553 bool constant_pool_full_;
1554 1577
1555 // Code emission 1578 // Code emission
1556 inline void CheckBuffer(); 1579 inline void CheckBuffer();
1557 void GrowBuffer(); 1580 void GrowBuffer();
1558 inline void emit(Instr x); 1581 inline void emit(Instr x);
1559 1582
1560 // 32-bit immediate values 1583 // 32-bit immediate values
1561 void move_32_bit_immediate(Register rd, 1584 void move_32_bit_immediate(Register rd,
1562 const Operand& x, 1585 const Operand& x,
1563 Condition cond = al); 1586 Condition cond = al);
(...skipping 11 matching lines...) Expand all
1575 void next(Label* L); 1598 void next(Label* L);
1576 1599
1577 enum UseConstantPoolMode { 1600 enum UseConstantPoolMode {
1578 USE_CONSTANT_POOL, 1601 USE_CONSTANT_POOL,
1579 DONT_USE_CONSTANT_POOL 1602 DONT_USE_CONSTANT_POOL
1580 }; 1603 };
1581 1604
1582 // Record reloc info for current pc_ 1605 // Record reloc info for current pc_
1583 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1606 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1584 void RecordRelocInfo(const RelocInfo& rinfo); 1607 void RecordRelocInfo(const RelocInfo& rinfo);
1585 void ConstantPoolAddEntry(const RelocInfo& rinfo); 1608 ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo& rinfo);
1586 1609
1587 friend class RelocInfo; 1610 friend class RelocInfo;
1588 friend class CodePatcher; 1611 friend class CodePatcher;
1589 friend class BlockConstPoolScope; 1612 friend class BlockConstPoolScope;
1590 friend class FrameAndConstantPoolScope; 1613 friend class FrameAndConstantPoolScope;
1591 friend class ConstantPoolUnavailableScope; 1614 friend class ConstantPoolUnavailableScope;
1592 1615
1593 PositionsRecorder positions_recorder_; 1616 PositionsRecorder positions_recorder_;
1594 friend class PositionsRecorder; 1617 friend class PositionsRecorder;
1595 friend class EnsureSpace; 1618 friend class EnsureSpace;
1596 }; 1619 };
1597 1620
1598 1621
1599 class EnsureSpace BASE_EMBEDDED { 1622 class EnsureSpace BASE_EMBEDDED {
1600 public: 1623 public:
1601 explicit EnsureSpace(Assembler* assembler) { 1624 explicit EnsureSpace(Assembler* assembler) {
1602 assembler->CheckBuffer(); 1625 assembler->CheckBuffer();
1603 } 1626 }
1604 }; 1627 };
1605 1628
1606 1629
1607 } } // namespace v8::internal 1630 } } // namespace v8::internal
1608 1631
1609 #endif // V8_ARM_ASSEMBLER_ARM_H_ 1632 #endif // V8_ARM_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm/assembler-arm.cc » ('j') | src/arm/assembler-arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698