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

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

Issue 1030353003: Enable constant pool support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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
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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 static const int kMantissaOffset = 0; 102 static const int kMantissaOffset = 0;
103 static const int kExponentOffset = 4; 103 static const int kExponentOffset = 4;
104 #else 104 #else
105 static const int kMantissaOffset = 4; 105 static const int kMantissaOffset = 4;
106 static const int kExponentOffset = 0; 106 static const int kExponentOffset = 0;
107 #endif 107 #endif
108 108
109 static const int kAllocatableLowRangeBegin = 3; 109 static const int kAllocatableLowRangeBegin = 3;
110 static const int kAllocatableLowRangeEnd = 10; 110 static const int kAllocatableLowRangeEnd = 10;
111 static const int kAllocatableHighRangeBegin = 14; 111 static const int kAllocatableHighRangeBegin = 14;
112 static const int kAllocatableHighRangeEnd = 28; 112 static const int kAllocatableHighRangeEnd =
113 FLAG_enable_embedded_constant_pool ? 27 : 28;
113 static const int kAllocatableContext = 30; 114 static const int kAllocatableContext = 30;
114 115
115 static const int kNumAllocatableLow = 116 static const int kNumAllocatableLow =
116 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; 117 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1;
117 static const int kNumAllocatableHigh = 118 static const int kNumAllocatableHigh =
118 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; 119 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1;
119 static const int kMaxNumAllocatableRegisters = 120 static const int kMaxNumAllocatableRegisters =
120 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp 121 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp
121 122
122 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } 123 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 "r21", 172 "r21",
172 "r22", 173 "r22",
173 "r23", 174 "r23",
174 "r24", 175 "r24",
175 "r25", 176 "r25",
176 "r26", 177 "r26",
177 "r27", 178 "r27",
178 "r28", 179 "r28",
179 "cp", 180 "cp",
180 }; 181 };
182 if (FLAG_enable_embedded_constant_pool &&
183 (index == kMaxNumAllocatableRegisters - 2)) {
184 return names[index + 1];
185 }
181 return names[index]; 186 return names[index];
182 } 187 }
183 188
184 static const RegList kAllocatable = 189 static const RegList kAllocatable =
185 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | 190 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 |
186 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | 191 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 |
187 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 | 192 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 |
188 1 << 28 | 1 << 30; 193 (FLAG_enable_embedded_constant_pool ? 0 : 1 << 28) | 1 << 30;
189 194
190 static Register from_code(int code) { 195 static Register from_code(int code) {
191 Register r = {code}; 196 Register r = {code};
192 return r; 197 return r;
193 } 198 }
194 199
195 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 200 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
196 bool is(Register reg) const { return code_ == reg.code_; } 201 bool is(Register reg) const { return code_ == reg.code_; }
197 int code() const { 202 int code() const {
198 DCHECK(is_valid()); 203 DCHECK(is_valid());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 const int kRegister_r18_Code = 18; 241 const int kRegister_r18_Code = 18;
237 const int kRegister_r19_Code = 19; 242 const int kRegister_r19_Code = 19;
238 const int kRegister_r20_Code = 20; 243 const int kRegister_r20_Code = 20;
239 const int kRegister_r21_Code = 21; 244 const int kRegister_r21_Code = 21;
240 const int kRegister_r22_Code = 22; 245 const int kRegister_r22_Code = 22;
241 const int kRegister_r23_Code = 23; 246 const int kRegister_r23_Code = 23;
242 const int kRegister_r24_Code = 24; 247 const int kRegister_r24_Code = 24;
243 const int kRegister_r25_Code = 25; 248 const int kRegister_r25_Code = 25;
244 const int kRegister_r26_Code = 26; 249 const int kRegister_r26_Code = 26;
245 const int kRegister_r27_Code = 27; 250 const int kRegister_r27_Code = 27;
246 const int kRegister_r28_Code = 28; 251 const int kRegister_r28_Code = 28; // constant pool pointer
247 const int kRegister_r29_Code = 29; // roots array pointer 252 const int kRegister_r29_Code = 29; // roots array pointer
248 const int kRegister_r30_Code = 30; // context pointer 253 const int kRegister_r30_Code = 30; // context pointer
249 const int kRegister_fp_Code = 31; // frame pointer 254 const int kRegister_fp_Code = 31; // frame pointer
250 255
251 const Register no_reg = {kRegister_no_reg_Code}; 256 const Register no_reg = {kRegister_no_reg_Code};
252 257
253 const Register r0 = {kRegister_r0_Code}; 258 const Register r0 = {kRegister_r0_Code};
254 const Register sp = {kRegister_sp_Code}; 259 const Register sp = {kRegister_sp_Code};
255 const Register r2 = {kRegister_r2_Code}; 260 const Register r2 = {kRegister_r2_Code};
256 const Register r3 = {kRegister_r3_Code}; 261 const Register r3 = {kRegister_r3_Code};
(...skipping 23 matching lines...) Expand all
280 const Register r26 = {kRegister_r26_Code}; 285 const Register r26 = {kRegister_r26_Code};
281 const Register r27 = {kRegister_r27_Code}; 286 const Register r27 = {kRegister_r27_Code};
282 const Register r28 = {kRegister_r28_Code}; 287 const Register r28 = {kRegister_r28_Code};
283 const Register r29 = {kRegister_r29_Code}; 288 const Register r29 = {kRegister_r29_Code};
284 const Register r30 = {kRegister_r30_Code}; 289 const Register r30 = {kRegister_r30_Code};
285 const Register fp = {kRegister_fp_Code}; 290 const Register fp = {kRegister_fp_Code};
286 291
287 // Give alias names to registers 292 // Give alias names to registers
288 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer 293 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer
289 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. 294 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer.
295 const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool
290 296
291 // Double word FP register. 297 // Double word FP register.
292 struct DoubleRegister { 298 struct DoubleRegister {
293 static const int kNumRegisters = 32; 299 static const int kNumRegisters = 32;
294 static const int kMaxNumRegisters = kNumRegisters; 300 static const int kMaxNumRegisters = kNumRegisters;
295 static const int kNumVolatileRegisters = 14; // d0-d13 301 static const int kNumVolatileRegisters = 14; // d0-d13
296 static const int kSizeInBytes = 8; 302 static const int kSizeInBytes = 8;
297 303
298 static const int kAllocatableLowRangeBegin = 1; 304 static const int kAllocatableLowRangeBegin = 1;
299 static const int kAllocatableLowRangeEnd = 12; 305 static const int kAllocatableLowRangeEnd = 12;
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 RelocInfo::Mode rmode() const { return rmode_; } 534 RelocInfo::Mode rmode() const { return rmode_; }
529 intptr_t data() const { return data_; } 535 intptr_t data() const { return data_; }
530 536
531 private: 537 private:
532 int position_; 538 int position_;
533 RelocInfo::Mode rmode_; 539 RelocInfo::Mode rmode_;
534 intptr_t data_; 540 intptr_t data_;
535 }; 541 };
536 542
537 543
544 // Class used to build a constant pool.
545 class ConstantPoolBuilder BASE_EMBEDDED {
546 public:
547 ConstantPoolBuilder();
548 void AddEntry(int position, RelocInfo::Mode rmode, intptr_t value,
549 bool sharing_ok) {
550 DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::POSITION &&
551 rmode != RelocInfo::STATEMENT_POSITION);
552 ConstantPoolEntry entry(position, rmode, value);
553 AddEntry(entry, sharing_ok);
554 }
555 void AddEntry(int position, double value) {
556 ConstantPoolEntry entry(position, RelocInfo::NONE64, value);
557 AddEntry(entry, true);
558 }
559 int Emit(Assembler* assm);
560 inline Label* Position() { return &label_; }
561
562 // This implementation does not currently support an unlimited constant
563 // pool size (which would require a multi-instruction sequence).
564 inline bool IsFull() const { return !is_int16(size_); }
565 inline bool IsEmpty() const { return entries_.size() == 0; }
566 inline bool IsEmitted() const { return label_.is_bound(); }
567
568 private:
569 enum Type {
570 #if !V8_TARGET_ARCH_PPC64
571 INT64,
572 #endif
573 PTR,
574 NUMBER_OF_TYPES,
575 };
576
577 struct ConstantPoolEntry {
578 ConstantPoolEntry(int position, RelocInfo::Mode rmode, intptr_t value)
579 : position_(position),
580 merged_index_(-1),
581 rmode_(rmode),
582 value_(value) {}
583 ConstantPoolEntry(int position, RelocInfo::Mode rmode, double value)
584 : position_(position),
585 merged_index_(-1),
586 rmode_(rmode),
587 value64_(value) {}
588
589 bool IsEqual(const ConstantPoolEntry& entry) const {
590 return rmode_ == entry.rmode_ &&
591 #if V8_TARGET_ARCH_PPC64
592 value_ == entry.value_;
593 #else
594 ((rmode_ == RelocInfo::NONE64) ? raw_value64_ == entry.raw_value64_
595 : value_ == entry.value_);
596 #endif
597 }
598
599 Type type() {
600 #if !V8_TARGET_ARCH_PPC64
601 if (rmode_ == RelocInfo::NONE64) {
602 return INT64;
603 }
604 #endif
605 return PTR;
606 }
607
608 int size() {
609 #if !V8_TARGET_ARCH_PPC64
610 if (rmode_ == RelocInfo::NONE64) {
611 return kInt64Size;
612 }
613 #endif
614 return kPointerSize;
615 }
616
617 int position_;
618 int merged_index_;
619 RelocInfo::Mode rmode_;
620 union {
621 intptr_t value_;
622 double value64_;
623 #if !V8_TARGET_ARCH_PPC64
624 int64_t raw_value64_;
625 #endif
626 };
627 };
628
629 class NumberOfEntries {
630 public:
631 inline NumberOfEntries() {
632 for (int i = 0; i < NUMBER_OF_TYPES; i++) {
633 element_counts_[i] = 0;
634 }
635 }
636
637 inline void increment(Type type) {
638 DCHECK(type < NUMBER_OF_TYPES);
639 element_counts_[type]++;
640 }
641
642 inline int count_of(Type type) const { return element_counts_[type]; }
643
644 inline int size() {
645 int size = count_of(PTR) * kPointerSize;
646 #if !V8_TARGET_ARCH_PPC64
647 size += count_of(INT64) * kInt64Size;
648 #endif
649 return size;
650 }
651
652 private:
653 int element_counts_[NUMBER_OF_TYPES];
654 };
655
656 void AddEntry(ConstantPoolEntry& entry, bool sharing_ok);
657 void EmitGroup(Assembler* assm, int entrySize);
658
659 int size_;
660 std::vector<ConstantPoolEntry> entries_;
661 NumberOfEntries number_of_entries_;
662 Label label_;
663 };
664
665
538 class Assembler : public AssemblerBase { 666 class Assembler : public AssemblerBase {
539 public: 667 public:
540 // Create an assembler. Instructions and relocation information are emitted 668 // Create an assembler. Instructions and relocation information are emitted
541 // into a buffer, with the instructions starting from the beginning and the 669 // into a buffer, with the instructions starting from the beginning and the
542 // relocation information starting from the end of the buffer. See CodeDesc 670 // relocation information starting from the end of the buffer. See CodeDesc
543 // for a detailed comment on the layout (globals.h). 671 // for a detailed comment on the layout (globals.h).
544 // 672 //
545 // If the provided buffer is NULL, the assembler allocates and grows its own 673 // If the provided buffer is NULL, the assembler allocates and grows its own
546 // buffer, and buffer_size determines the initial buffer size. The buffer is 674 // buffer, and buffer_size determines the initial buffer size. The buffer is
547 // owned by the assembler and deallocated upon destruction of the assembler. 675 // owned by the assembler and deallocated upon destruction of the assembler.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 // Manages the jump elimination optimization if the second parameter is true. 717 // Manages the jump elimination optimization if the second parameter is true.
590 int branch_offset(Label* L, bool jump_elimination_allowed) { 718 int branch_offset(Label* L, bool jump_elimination_allowed) {
591 int position = link(L); 719 int position = link(L);
592 return position - pc_offset(); 720 return position - pc_offset();
593 } 721 }
594 722
595 // Puts a labels target address at the given position. 723 // Puts a labels target address at the given position.
596 // The high 8 bits are set to zero. 724 // The high 8 bits are set to zero.
597 void label_at_put(Label* L, int at_offset); 725 void label_at_put(Label* L, int at_offset);
598 726
727 INLINE(static bool IsConstantPoolLoadStart(Address pc));
728 INLINE(static bool IsConstantPoolLoadEnd(Address pc));
729 INLINE(static int GetConstantPoolOffset(Address pc));
730 INLINE(void SetConstantPoolOffset(int pos, int offset));
731
732 // Return the address in the constant pool of the code target address used by
733 // the branch/call instruction at pc, or the object in a mov.
734 INLINE(static Address target_constant_pool_address_at(Address pc,
735 Address constant_pool));
736
599 // Read/Modify the code target address in the branch/call instruction at pc. 737 // Read/Modify the code target address in the branch/call instruction at pc.
600 INLINE(static Address target_address_at(Address pc, 738 INLINE(static Address target_address_at(Address pc, Address constant_pool));
601 ConstantPoolArray* constant_pool));
602 INLINE(static void set_target_address_at( 739 INLINE(static void set_target_address_at(
603 Address pc, ConstantPoolArray* constant_pool, Address target, 740 Address pc, Address constant_pool, Address target,
604 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); 741 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
605 INLINE(static Address target_address_at(Address pc, Code* code)) { 742 INLINE(static Address target_address_at(Address pc, Code* code)) {
606 ConstantPoolArray* constant_pool = NULL; 743 Address constant_pool = code ? code->constant_pool() : NULL;
607 return target_address_at(pc, constant_pool); 744 return target_address_at(pc, constant_pool);
608 } 745 }
609 INLINE(static void set_target_address_at( 746 INLINE(static void set_target_address_at(
610 Address pc, Code* code, Address target, 747 Address pc, Code* code, Address target,
611 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { 748 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
612 ConstantPoolArray* constant_pool = NULL; 749 Address constant_pool = code ? code->constant_pool() : NULL;
613 set_target_address_at(pc, constant_pool, target, icache_flush_mode); 750 set_target_address_at(pc, constant_pool, target, icache_flush_mode);
614 } 751 }
615 752
616 // Return the code target address at a call site from the return address 753 // Return the code target address at a call site from the return address
617 // of that call in the instruction stream. 754 // of that call in the instruction stream.
618 inline static Address target_address_from_return_address(Address pc); 755 inline static Address target_address_from_return_address(Address pc);
619 756
620 // Given the address of the beginning of a call, return the address 757 // Given the address of the beginning of a call, return the address
621 // in the instruction stream that the call will return to. 758 // in the instruction stream that the call will return to.
622 INLINE(static Address return_address_from_call_start(Address pc)); 759 INLINE(static Address return_address_from_call_start(Address pc));
(...skipping 17 matching lines...) Expand all
640 // Here we are patching the address in the LUI/ORI instruction pair. 777 // Here we are patching the address in the LUI/ORI instruction pair.
641 // These values are used in the serialization process and must be zero for 778 // These values are used in the serialization process and must be zero for
642 // PPC platform, as Code, Embedded Object or External-reference pointers 779 // PPC platform, as Code, Embedded Object or External-reference pointers
643 // are split across two consecutive instructions and don't exist separately 780 // are split across two consecutive instructions and don't exist separately
644 // in the code, so the serializer should not step forwards in memory after 781 // in the code, so the serializer should not step forwards in memory after
645 // a target is resolved and written. 782 // a target is resolved and written.
646 static const int kSpecialTargetSize = 0; 783 static const int kSpecialTargetSize = 0;
647 784
648 // Number of instructions to load an address via a mov sequence. 785 // Number of instructions to load an address via a mov sequence.
649 #if V8_TARGET_ARCH_PPC64 786 #if V8_TARGET_ARCH_PPC64
650 static const int kMovInstructions = 5; 787 static const int kMovInstructionsConstantPool = 1;
788 static const int kMovInstructionsNoConstantPool = 5;
651 static const int kTaggedLoadInstructions = 2; 789 static const int kTaggedLoadInstructions = 2;
652 #else 790 #else
653 static const int kMovInstructions = 2; 791 static const int kMovInstructionsConstantPool = 1;
792 static const int kMovInstructionsNoConstantPool = 2;
654 static const int kTaggedLoadInstructions = 1; 793 static const int kTaggedLoadInstructions = 1;
655 #endif 794 #endif
795 static const int kMovInstructions = FLAG_enable_embedded_constant_pool
796 ? kMovInstructionsConstantPool
797 : kMovInstructionsNoConstantPool;
656 798
657 // Distance between the instruction referring to the address of the call 799 // Distance between the instruction referring to the address of the call
658 // target and the return address. 800 // target and the return address.
659 801
660 // Call sequence is a FIXED_SEQUENCE: 802 // Call sequence is a FIXED_SEQUENCE:
661 // mov r8, @ call address 803 // mov r8, @ call address
662 // mtlr r8 804 // mtlr r8
663 // blrl 805 // blrl
664 // @ return address 806 // @ return address
665 static const int kCallTargetAddressOffset = 807 static const int kCallTargetAddressOffset =
(...skipping 10 matching lines...) Expand all
676 // Distance between start of patched debug break slot and the emitted address 818 // Distance between start of patched debug break slot and the emitted address
677 // to jump to. 819 // to jump to.
678 // Patched debug break slot code is a FIXED_SEQUENCE: 820 // Patched debug break slot code is a FIXED_SEQUENCE:
679 // mov r0, <address> 821 // mov r0, <address>
680 // mtlr r0 822 // mtlr r0
681 // blrl 823 // blrl
682 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 824 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize;
683 825
684 // This is the length of the BreakLocation::SetDebugBreakAtReturn() 826 // This is the length of the BreakLocation::SetDebugBreakAtReturn()
685 // code patch FIXED_SEQUENCE 827 // code patch FIXED_SEQUENCE
686 static const int kJSReturnSequenceInstructions = kMovInstructions + 3; 828 static const int kJSReturnSequenceInstructions =
829 kMovInstructionsNoConstantPool + 3;
687 static const int kJSReturnSequenceLength = 830 static const int kJSReturnSequenceLength =
688 kJSReturnSequenceInstructions * kInstrSize; 831 kJSReturnSequenceInstructions * kInstrSize;
689 832
690 // This is the length of the code sequence from SetDebugBreakAtSlot() 833 // This is the length of the code sequence from SetDebugBreakAtSlot()
691 // FIXED_SEQUENCE 834 // FIXED_SEQUENCE
692 static const int kDebugBreakSlotInstructions = kMovInstructions + 2; 835 static const int kDebugBreakSlotInstructions =
836 kMovInstructionsNoConstantPool + 2;
693 static const int kDebugBreakSlotLength = 837 static const int kDebugBreakSlotLength =
694 kDebugBreakSlotInstructions * kInstrSize; 838 kDebugBreakSlotInstructions * kInstrSize;
695 839
696 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { 840 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
697 return ((cr.code() * CRWIDTH) + crbit); 841 return ((cr.code() * CRWIDTH) + crbit);
698 } 842 }
699 843
700 // --------------------------------------------------------------------------- 844 // ---------------------------------------------------------------------------
701 // Code generation 845 // Code generation
702 846
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 assem_->StartBlockTrampolinePool(); 1339 assem_->StartBlockTrampolinePool();
1196 } 1340 }
1197 ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); } 1341 ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); }
1198 1342
1199 private: 1343 private:
1200 Assembler* assem_; 1344 Assembler* assem_;
1201 1345
1202 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); 1346 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
1203 }; 1347 };
1204 1348
1349 // Class for scoping disabling constant pool entry merging
1350 class BlockConstantPoolEntrySharingScope {
1351 public:
1352 explicit BlockConstantPoolEntrySharingScope(Assembler* assem)
1353 : assem_(assem) {
1354 assem_->StartBlockConstantPoolEntrySharing();
1355 }
1356 ~BlockConstantPoolEntrySharingScope() {
1357 assem_->EndBlockConstantPoolEntrySharing();
1358 }
1359
1360 private:
1361 Assembler* assem_;
1362
1363 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope);
1364 };
1365
1205 // Debugging 1366 // Debugging
1206 1367
1207 // Mark address of the ExitJSFrame code. 1368 // Mark address of the ExitJSFrame code.
1208 void RecordJSReturn(); 1369 void RecordJSReturn();
1209 1370
1210 // Mark address of a debug break slot. 1371 // Mark address of a debug break slot.
1211 void RecordDebugBreakSlot(); 1372 void RecordDebugBreakSlot();
1212 1373
1213 // Record the AST id of the CallIC being compiled, so that it can be placed 1374 // Record the AST id of the CallIC being compiled, so that it can be placed
1214 // in the relocation information. 1375 // in the relocation information.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 static bool IsCrSet(Instr instr); 1439 static bool IsCrSet(Instr instr);
1279 static Register GetCmpImmediateRegister(Instr instr); 1440 static Register GetCmpImmediateRegister(Instr instr);
1280 static int GetCmpImmediateRawImmediate(Instr instr); 1441 static int GetCmpImmediateRawImmediate(Instr instr);
1281 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 1442 static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
1282 1443
1283 // Postpone the generation of the trampoline pool for the specified number of 1444 // Postpone the generation of the trampoline pool for the specified number of
1284 // instructions. 1445 // instructions.
1285 void BlockTrampolinePoolFor(int instructions); 1446 void BlockTrampolinePoolFor(int instructions);
1286 void CheckTrampolinePool(); 1447 void CheckTrampolinePool();
1287 1448
1449 // For mov. Return the number of actual instructions required to
1450 // load the operand into a register. This can be anywhere from
1451 // one (constant pool small section) to five instructions (full
1452 // 64-bit sequence).
1453 //
1454 // The value returned is only valid as long as no entries are added to the
1455 // constant pool between this call and the actual instruction being emitted.
1456 int instructions_required_for_mov(const Operand& x) const;
1457
1458 // Decide between using the constant pool vs. a mov immediate sequence.
1459 bool use_constant_pool_for_mov(const Operand& x, bool canOptimize) const;
1460
1288 // The code currently calls CheckBuffer() too often. This has the side 1461 // The code currently calls CheckBuffer() too often. This has the side
1289 // effect of randomly growing the buffer in the middle of multi-instruction 1462 // effect of randomly growing the buffer in the middle of multi-instruction
1290 // sequences. 1463 // sequences.
1291 // 1464 //
1292 // This function allows outside callers to check and grow the buffer 1465 // This function allows outside callers to check and grow the buffer
1293 void EnsureSpaceFor(int space_needed); 1466 void EnsureSpaceFor(int space_needed);
1294 1467
1295 // Allocate a constant pool of the correct size for the generated code. 1468 // Allocate a constant pool of the correct size for the generated code.
1296 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); 1469 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
1297 1470
1298 // Generate the constant pool for the generated code. 1471 // Generate the constant pool for the generated code.
1299 void PopulateConstantPool(ConstantPoolArray* constant_pool); 1472 void PopulateConstantPool(ConstantPoolArray* constant_pool);
1300 1473
1474 int EmitConstantPool() { return constant_pool_builder_.Emit(this); }
1475
1476 bool is_constant_pool_full() const { return constant_pool_builder_.IsFull(); }
1477
1478 Label* ConstantPoolPosition() { return constant_pool_builder_.Position(); }
1479
1301 void EmitRelocations(); 1480 void EmitRelocations();
1302 1481
1303 protected: 1482 protected:
1304 // Relocation for a type-recording IC has the AST id added to it. This 1483 // Relocation for a type-recording IC has the AST id added to it. This
1305 // member variable is a way to pass the information from the call site to 1484 // member variable is a way to pass the information from the call site to
1306 // the relocation info. 1485 // the relocation info.
1307 TypeFeedbackId recorded_ast_id_; 1486 TypeFeedbackId recorded_ast_id_;
1308 1487
1309 int buffer_space() const { return reloc_info_writer.pos() - pc_; } 1488 int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1310 1489
1311 // Decode branch instruction at pos and return branch target pos 1490 // Decode branch instruction at pos and return branch target pos
1312 int target_at(int pos); 1491 int target_at(int pos);
1313 1492
1314 // Patch branch instruction at pos to branch to given branch target pos 1493 // Patch branch instruction at pos to branch to given branch target pos
1315 void target_at_put(int pos, int target_pos); 1494 void target_at_put(int pos, int target_pos);
1316 1495
1317 // Record reloc info for current pc_ 1496 // Record reloc info for current pc_
1318 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1497 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1319 void RecordRelocInfo(const DeferredRelocInfo& rinfo); 1498 void RecordRelocInfo(const DeferredRelocInfo& rinfo);
1499 void ConstantPoolAddEntry(RelocInfo::Mode rmode, intptr_t value) {
1500 bool sharing_ok = RelocInfo::IsNone(rmode) ||
1501 !(serializer_enabled() || rmode < RelocInfo::CELL ||
1502 is_constant_pool_entry_sharing_blocked());
1503 constant_pool_builder_.AddEntry(pc_offset(), rmode, value, sharing_ok);
1504 }
1505 void ConstantPoolAddEntry(double value) {
1506 constant_pool_builder_.AddEntry(pc_offset(), value);
1507 }
1320 1508
1321 // Block the emission of the trampoline pool before pc_offset. 1509 // Block the emission of the trampoline pool before pc_offset.
1322 void BlockTrampolinePoolBefore(int pc_offset) { 1510 void BlockTrampolinePoolBefore(int pc_offset) {
1323 if (no_trampoline_pool_before_ < pc_offset) 1511 if (no_trampoline_pool_before_ < pc_offset)
1324 no_trampoline_pool_before_ = pc_offset; 1512 no_trampoline_pool_before_ = pc_offset;
1325 } 1513 }
1326 1514
1327 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } 1515 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; }
1328 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } 1516 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; }
1329 bool is_trampoline_pool_blocked() const { 1517 bool is_trampoline_pool_blocked() const {
1330 return trampoline_pool_blocked_nesting_ > 0; 1518 return trampoline_pool_blocked_nesting_ > 0;
1331 } 1519 }
1332 1520
1521 void StartBlockConstantPoolEntrySharing() {
1522 constant_pool_entry_sharing_blocked_nesting_++;
1523 }
1524 void EndBlockConstantPoolEntrySharing() {
1525 constant_pool_entry_sharing_blocked_nesting_--;
1526 }
1527 bool is_constant_pool_entry_sharing_blocked() const {
1528 return constant_pool_entry_sharing_blocked_nesting_ > 0;
1529 }
1530
1333 bool has_exception() const { return internal_trampoline_exception_; } 1531 bool has_exception() const { return internal_trampoline_exception_; }
1334 1532
1335 bool is_trampoline_emitted() const { return trampoline_emitted_; } 1533 bool is_trampoline_emitted() const { return trampoline_emitted_; }
1336 1534
1337 private: 1535 private:
1338 // Code generation 1536 // Code generation
1339 // The relocation writer's position is at least kGap bytes below the end of 1537 // The relocation writer's position is at least kGap bytes below the end of
1340 // the generated instructions. This is so that multi-instruction sequences do 1538 // the generated instructions. This is so that multi-instruction sequences do
1341 // not have to check for overflow. The same is true for writes of large 1539 // not have to check for overflow. The same is true for writes of large
1342 // relocation info entries. 1540 // relocation info entries.
1343 static const int kGap = 32; 1541 static const int kGap = 32;
1344 1542
1345 // Repeated checking whether the trampoline pool should be emitted is rather 1543 // Repeated checking whether the trampoline pool should be emitted is rather
1346 // expensive. By default we only check again once a number of instructions 1544 // expensive. By default we only check again once a number of instructions
1347 // has been generated. 1545 // has been generated.
1348 int next_buffer_check_; // pc offset of next buffer check. 1546 int next_buffer_check_; // pc offset of next buffer check.
1349 1547
1350 // Emission of the trampoline pool may be blocked in some code sequences. 1548 // Emission of the trampoline pool may be blocked in some code sequences.
1351 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. 1549 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero.
1352 int no_trampoline_pool_before_; // Block emission before this pc offset. 1550 int no_trampoline_pool_before_; // Block emission before this pc offset.
1353 1551
1552 // Do not share constant pool entries.
1553 int constant_pool_entry_sharing_blocked_nesting_;
1554
1354 // Relocation info generation 1555 // Relocation info generation
1355 // Each relocation is encoded as a variable size value 1556 // Each relocation is encoded as a variable size value
1356 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1557 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1357 RelocInfoWriter reloc_info_writer; 1558 RelocInfoWriter reloc_info_writer;
1358 std::vector<DeferredRelocInfo> relocations_; 1559 std::vector<DeferredRelocInfo> relocations_;
1359 1560
1360 // The bound position, before this we cannot do instruction elimination. 1561 // The bound position, before this we cannot do instruction elimination.
1361 int last_bound_pos_; 1562 int last_bound_pos_;
1362 1563
1564 ConstantPoolBuilder constant_pool_builder_;
1565
1363 // Code emission 1566 // Code emission
1364 inline void CheckBuffer(); 1567 inline void CheckBuffer();
1365 void GrowBuffer(int needed = 0); 1568 void GrowBuffer(int needed = 0);
1366 inline void emit(Instr x); 1569 inline void emit(Instr x);
1367 inline void CheckTrampolinePoolQuick(); 1570 inline void CheckTrampolinePoolQuick();
1368 1571
1369 // Instruction generation 1572 // Instruction generation
1370 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, 1573 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
1371 DoubleRegister frb, RCBit r); 1574 DoubleRegister frb, RCBit r);
1372 void d_form(Instr instr, Register rt, Register ra, const intptr_t val, 1575 void d_form(Instr instr, Register rt, Register ra, const intptr_t val,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 1646
1444 1647
1445 class EnsureSpace BASE_EMBEDDED { 1648 class EnsureSpace BASE_EMBEDDED {
1446 public: 1649 public:
1447 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } 1650 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1448 }; 1651 };
1449 } 1652 }
1450 } // namespace v8::internal 1653 } // namespace v8::internal
1451 1654
1452 #endif // V8_PPC_ASSEMBLER_PPC_H_ 1655 #endif // V8_PPC_ASSEMBLER_PPC_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698