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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 static const int kMantissaOffset = 0; | 101 static const int kMantissaOffset = 0; |
102 static const int kExponentOffset = 4; | 102 static const int kExponentOffset = 4; |
103 #else | 103 #else |
104 static const int kMantissaOffset = 4; | 104 static const int kMantissaOffset = 4; |
105 static const int kExponentOffset = 0; | 105 static const int kExponentOffset = 0; |
106 #endif | 106 #endif |
107 | 107 |
108 static const int kAllocatableLowRangeBegin = 3; | 108 static const int kAllocatableLowRangeBegin = 3; |
109 static const int kAllocatableLowRangeEnd = 10; | 109 static const int kAllocatableLowRangeEnd = 10; |
110 static const int kAllocatableHighRangeBegin = 14; | 110 static const int kAllocatableHighRangeBegin = 14; |
111 static const int kAllocatableHighRangeEnd = 28; | 111 static const int kAllocatableHighRangeEnd = |
| 112 FLAG_enable_embedded_constant_pool ? 27 : 28; |
112 static const int kAllocatableContext = 30; | 113 static const int kAllocatableContext = 30; |
113 | 114 |
114 static const int kNumAllocatableLow = | 115 static const int kNumAllocatableLow = |
115 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; | 116 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; |
116 static const int kNumAllocatableHigh = | 117 static const int kNumAllocatableHigh = |
117 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; | 118 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; |
118 static const int kMaxNumAllocatableRegisters = | 119 static const int kMaxNumAllocatableRegisters = |
119 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp | 120 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp |
120 | 121 |
121 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | 122 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 "r21", | 171 "r21", |
171 "r22", | 172 "r22", |
172 "r23", | 173 "r23", |
173 "r24", | 174 "r24", |
174 "r25", | 175 "r25", |
175 "r26", | 176 "r26", |
176 "r27", | 177 "r27", |
177 "r28", | 178 "r28", |
178 "cp", | 179 "cp", |
179 }; | 180 }; |
| 181 if (FLAG_enable_embedded_constant_pool && |
| 182 (index == kMaxNumAllocatableRegisters - 2)) { |
| 183 return names[index + 1]; |
| 184 } |
180 return names[index]; | 185 return names[index]; |
181 } | 186 } |
182 | 187 |
183 static const RegList kAllocatable = | 188 static const RegList kAllocatable = |
184 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | | 189 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | |
185 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | | 190 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | |
186 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 | | 191 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 | |
187 1 << 28 | 1 << 30; | 192 (FLAG_enable_embedded_constant_pool ? 0 : 1 << 28) | 1 << 30; |
188 | 193 |
189 static Register from_code(int code) { | 194 static Register from_code(int code) { |
190 Register r = {code}; | 195 Register r = {code}; |
191 return r; | 196 return r; |
192 } | 197 } |
193 | 198 |
194 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 199 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
195 bool is(Register reg) const { return code_ == reg.code_; } | 200 bool is(Register reg) const { return code_ == reg.code_; } |
196 int code() const { | 201 int code() const { |
197 DCHECK(is_valid()); | 202 DCHECK(is_valid()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 const int kRegister_r18_Code = 18; | 240 const int kRegister_r18_Code = 18; |
236 const int kRegister_r19_Code = 19; | 241 const int kRegister_r19_Code = 19; |
237 const int kRegister_r20_Code = 20; | 242 const int kRegister_r20_Code = 20; |
238 const int kRegister_r21_Code = 21; | 243 const int kRegister_r21_Code = 21; |
239 const int kRegister_r22_Code = 22; | 244 const int kRegister_r22_Code = 22; |
240 const int kRegister_r23_Code = 23; | 245 const int kRegister_r23_Code = 23; |
241 const int kRegister_r24_Code = 24; | 246 const int kRegister_r24_Code = 24; |
242 const int kRegister_r25_Code = 25; | 247 const int kRegister_r25_Code = 25; |
243 const int kRegister_r26_Code = 26; | 248 const int kRegister_r26_Code = 26; |
244 const int kRegister_r27_Code = 27; | 249 const int kRegister_r27_Code = 27; |
245 const int kRegister_r28_Code = 28; | 250 const int kRegister_r28_Code = 28; // constant pool pointer |
246 const int kRegister_r29_Code = 29; // roots array pointer | 251 const int kRegister_r29_Code = 29; // roots array pointer |
247 const int kRegister_r30_Code = 30; // context pointer | 252 const int kRegister_r30_Code = 30; // context pointer |
248 const int kRegister_fp_Code = 31; // frame pointer | 253 const int kRegister_fp_Code = 31; // frame pointer |
249 | 254 |
250 const Register no_reg = {kRegister_no_reg_Code}; | 255 const Register no_reg = {kRegister_no_reg_Code}; |
251 | 256 |
252 const Register r0 = {kRegister_r0_Code}; | 257 const Register r0 = {kRegister_r0_Code}; |
253 const Register sp = {kRegister_sp_Code}; | 258 const Register sp = {kRegister_sp_Code}; |
254 const Register r2 = {kRegister_r2_Code}; | 259 const Register r2 = {kRegister_r2_Code}; |
255 const Register r3 = {kRegister_r3_Code}; | 260 const Register r3 = {kRegister_r3_Code}; |
(...skipping 23 matching lines...) Expand all Loading... |
279 const Register r26 = {kRegister_r26_Code}; | 284 const Register r26 = {kRegister_r26_Code}; |
280 const Register r27 = {kRegister_r27_Code}; | 285 const Register r27 = {kRegister_r27_Code}; |
281 const Register r28 = {kRegister_r28_Code}; | 286 const Register r28 = {kRegister_r28_Code}; |
282 const Register r29 = {kRegister_r29_Code}; | 287 const Register r29 = {kRegister_r29_Code}; |
283 const Register r30 = {kRegister_r30_Code}; | 288 const Register r30 = {kRegister_r30_Code}; |
284 const Register fp = {kRegister_fp_Code}; | 289 const Register fp = {kRegister_fp_Code}; |
285 | 290 |
286 // Give alias names to registers | 291 // Give alias names to registers |
287 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer | 292 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer |
288 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. | 293 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. |
| 294 const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool |
289 | 295 |
290 // Double word FP register. | 296 // Double word FP register. |
291 struct DoubleRegister { | 297 struct DoubleRegister { |
292 static const int kNumRegisters = 32; | 298 static const int kNumRegisters = 32; |
293 static const int kMaxNumRegisters = kNumRegisters; | 299 static const int kMaxNumRegisters = kNumRegisters; |
294 static const int kNumVolatileRegisters = 14; // d0-d13 | 300 static const int kNumVolatileRegisters = 14; // d0-d13 |
295 static const int kSizeInBytes = 8; | 301 static const int kSizeInBytes = 8; |
296 | 302 |
297 static const int kAllocatableLowRangeBegin = 1; | 303 static const int kAllocatableLowRangeBegin = 1; |
298 static const int kAllocatableLowRangeEnd = 12; | 304 static const int kAllocatableLowRangeEnd = 12; |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 // Manages the jump elimination optimization if the second parameter is true. | 594 // Manages the jump elimination optimization if the second parameter is true. |
589 int branch_offset(Label* L, bool jump_elimination_allowed) { | 595 int branch_offset(Label* L, bool jump_elimination_allowed) { |
590 int position = link(L); | 596 int position = link(L); |
591 return position - pc_offset(); | 597 return position - pc_offset(); |
592 } | 598 } |
593 | 599 |
594 // Puts a labels target address at the given position. | 600 // Puts a labels target address at the given position. |
595 // The high 8 bits are set to zero. | 601 // The high 8 bits are set to zero. |
596 void label_at_put(Label* L, int at_offset); | 602 void label_at_put(Label* L, int at_offset); |
597 | 603 |
| 604 INLINE(static bool IsConstantPoolLoadStart( |
| 605 Address pc, ConstantPoolEntry::Access* access = nullptr)); |
| 606 INLINE(static bool IsConstantPoolLoadEnd( |
| 607 Address pc, ConstantPoolEntry::Access* access = nullptr)); |
| 608 INLINE(static int GetConstantPoolOffset(Address pc, |
| 609 ConstantPoolEntry::Access access, |
| 610 ConstantPoolEntry::Type type)); |
| 611 INLINE(void PatchConstantPoolAccessInstruction( |
| 612 int pc_offset, int offset, ConstantPoolEntry::Access access, |
| 613 ConstantPoolEntry::Type type)); |
| 614 |
| 615 // Return the address in the constant pool of the code target address used by |
| 616 // the branch/call instruction at pc, or the object in a mov. |
| 617 INLINE(static Address target_constant_pool_address_at( |
| 618 Address pc, Address constant_pool, ConstantPoolEntry::Access access, |
| 619 ConstantPoolEntry::Type type)); |
| 620 |
598 // Read/Modify the code target address in the branch/call instruction at pc. | 621 // Read/Modify the code target address in the branch/call instruction at pc. |
599 INLINE(static Address target_address_at(Address pc, | 622 INLINE(static Address target_address_at(Address pc, Address constant_pool)); |
600 ConstantPoolArray* constant_pool)); | |
601 INLINE(static void set_target_address_at( | 623 INLINE(static void set_target_address_at( |
602 Address pc, ConstantPoolArray* constant_pool, Address target, | 624 Address pc, Address constant_pool, Address target, |
603 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); | 625 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); |
604 INLINE(static Address target_address_at(Address pc, Code* code)) { | 626 INLINE(static Address target_address_at(Address pc, Code* code)) { |
605 ConstantPoolArray* constant_pool = NULL; | 627 Address constant_pool = code ? code->constant_pool() : NULL; |
606 return target_address_at(pc, constant_pool); | 628 return target_address_at(pc, constant_pool); |
607 } | 629 } |
608 INLINE(static void set_target_address_at( | 630 INLINE(static void set_target_address_at( |
609 Address pc, Code* code, Address target, | 631 Address pc, Code* code, Address target, |
610 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { | 632 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { |
611 ConstantPoolArray* constant_pool = NULL; | 633 Address constant_pool = code ? code->constant_pool() : NULL; |
612 set_target_address_at(pc, constant_pool, target, icache_flush_mode); | 634 set_target_address_at(pc, constant_pool, target, icache_flush_mode); |
613 } | 635 } |
614 | 636 |
615 // Return the code target address at a call site from the return address | 637 // Return the code target address at a call site from the return address |
616 // of that call in the instruction stream. | 638 // of that call in the instruction stream. |
617 inline static Address target_address_from_return_address(Address pc); | 639 inline static Address target_address_from_return_address(Address pc); |
618 | 640 |
619 // Given the address of the beginning of a call, return the address | 641 // Given the address of the beginning of a call, return the address |
620 // in the instruction stream that the call will return to. | 642 // in the instruction stream that the call will return to. |
621 INLINE(static Address return_address_from_call_start(Address pc)); | 643 INLINE(static Address return_address_from_call_start(Address pc)); |
(...skipping 17 matching lines...) Expand all Loading... |
639 // Here we are patching the address in the LUI/ORI instruction pair. | 661 // Here we are patching the address in the LUI/ORI instruction pair. |
640 // These values are used in the serialization process and must be zero for | 662 // These values are used in the serialization process and must be zero for |
641 // PPC platform, as Code, Embedded Object or External-reference pointers | 663 // PPC platform, as Code, Embedded Object or External-reference pointers |
642 // are split across two consecutive instructions and don't exist separately | 664 // are split across two consecutive instructions and don't exist separately |
643 // in the code, so the serializer should not step forwards in memory after | 665 // in the code, so the serializer should not step forwards in memory after |
644 // a target is resolved and written. | 666 // a target is resolved and written. |
645 static const int kSpecialTargetSize = 0; | 667 static const int kSpecialTargetSize = 0; |
646 | 668 |
647 // Number of instructions to load an address via a mov sequence. | 669 // Number of instructions to load an address via a mov sequence. |
648 #if V8_TARGET_ARCH_PPC64 | 670 #if V8_TARGET_ARCH_PPC64 |
649 static const int kMovInstructions = 5; | 671 static const int kMovInstructionsConstantPool = 1; |
| 672 static const int kMovInstructionsNoConstantPool = 5; |
| 673 #if defined(V8_PPC_TAGGING_OPT) |
| 674 static const int kTaggedLoadInstructions = 1; |
| 675 #else |
650 static const int kTaggedLoadInstructions = 2; | 676 static const int kTaggedLoadInstructions = 2; |
| 677 #endif |
651 #else | 678 #else |
652 static const int kMovInstructions = 2; | 679 static const int kMovInstructionsConstantPool = 1; |
| 680 static const int kMovInstructionsNoConstantPool = 2; |
653 static const int kTaggedLoadInstructions = 1; | 681 static const int kTaggedLoadInstructions = 1; |
654 #endif | 682 #endif |
| 683 static const int kMovInstructions = FLAG_enable_embedded_constant_pool |
| 684 ? kMovInstructionsConstantPool |
| 685 : kMovInstructionsNoConstantPool; |
655 | 686 |
656 // Distance between the instruction referring to the address of the call | 687 // Distance between the instruction referring to the address of the call |
657 // target and the return address. | 688 // target and the return address. |
658 | 689 |
659 // Call sequence is a FIXED_SEQUENCE: | 690 // Call sequence is a FIXED_SEQUENCE: |
660 // mov r8, @ call address | 691 // mov r8, @ call address |
661 // mtlr r8 | 692 // mtlr r8 |
662 // blrl | 693 // blrl |
663 // @ return address | 694 // @ return address |
664 static const int kCallTargetAddressOffset = | 695 static const int kCallTargetAddressOffset = |
(...skipping 10 matching lines...) Expand all Loading... |
675 // Distance between start of patched debug break slot and the emitted address | 706 // Distance between start of patched debug break slot and the emitted address |
676 // to jump to. | 707 // to jump to. |
677 // Patched debug break slot code is a FIXED_SEQUENCE: | 708 // Patched debug break slot code is a FIXED_SEQUENCE: |
678 // mov r0, <address> | 709 // mov r0, <address> |
679 // mtlr r0 | 710 // mtlr r0 |
680 // blrl | 711 // blrl |
681 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; | 712 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; |
682 | 713 |
683 // This is the length of the BreakLocation::SetDebugBreakAtReturn() | 714 // This is the length of the BreakLocation::SetDebugBreakAtReturn() |
684 // code patch FIXED_SEQUENCE | 715 // code patch FIXED_SEQUENCE |
685 static const int kJSReturnSequenceInstructions = kMovInstructions + 3; | 716 static const int kJSReturnSequenceInstructions = |
| 717 kMovInstructionsNoConstantPool + 3; |
686 static const int kJSReturnSequenceLength = | 718 static const int kJSReturnSequenceLength = |
687 kJSReturnSequenceInstructions * kInstrSize; | 719 kJSReturnSequenceInstructions * kInstrSize; |
688 | 720 |
689 // This is the length of the code sequence from SetDebugBreakAtSlot() | 721 // This is the length of the code sequence from SetDebugBreakAtSlot() |
690 // FIXED_SEQUENCE | 722 // FIXED_SEQUENCE |
691 static const int kDebugBreakSlotInstructions = kMovInstructions + 2; | 723 static const int kDebugBreakSlotInstructions = |
| 724 kMovInstructionsNoConstantPool + 2; |
692 static const int kDebugBreakSlotLength = | 725 static const int kDebugBreakSlotLength = |
693 kDebugBreakSlotInstructions * kInstrSize; | 726 kDebugBreakSlotInstructions * kInstrSize; |
694 | 727 |
695 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { | 728 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { |
696 return ((cr.code() * CRWIDTH) + crbit); | 729 return ((cr.code() * CRWIDTH) + crbit); |
697 } | 730 } |
698 | 731 |
699 // --------------------------------------------------------------------------- | 732 // --------------------------------------------------------------------------- |
700 // Code generation | 733 // Code generation |
701 | 734 |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 assem_->StartBlockTrampolinePool(); | 1227 assem_->StartBlockTrampolinePool(); |
1195 } | 1228 } |
1196 ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); } | 1229 ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); } |
1197 | 1230 |
1198 private: | 1231 private: |
1199 Assembler* assem_; | 1232 Assembler* assem_; |
1200 | 1233 |
1201 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); | 1234 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope); |
1202 }; | 1235 }; |
1203 | 1236 |
| 1237 // Class for scoping disabling constant pool entry merging |
| 1238 class BlockConstantPoolEntrySharingScope { |
| 1239 public: |
| 1240 explicit BlockConstantPoolEntrySharingScope(Assembler* assem) |
| 1241 : assem_(assem) { |
| 1242 assem_->StartBlockConstantPoolEntrySharing(); |
| 1243 } |
| 1244 ~BlockConstantPoolEntrySharingScope() { |
| 1245 assem_->EndBlockConstantPoolEntrySharing(); |
| 1246 } |
| 1247 |
| 1248 private: |
| 1249 Assembler* assem_; |
| 1250 |
| 1251 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope); |
| 1252 }; |
| 1253 |
1204 // Debugging | 1254 // Debugging |
1205 | 1255 |
1206 // Mark address of the ExitJSFrame code. | 1256 // Mark address of the ExitJSFrame code. |
1207 void RecordJSReturn(); | 1257 void RecordJSReturn(); |
1208 | 1258 |
1209 // Mark address of a debug break slot. | 1259 // Mark address of a debug break slot. |
1210 void RecordDebugBreakSlot(); | 1260 void RecordDebugBreakSlot(); |
1211 | 1261 |
1212 // Record the AST id of the CallIC being compiled, so that it can be placed | 1262 // Record the AST id of the CallIC being compiled, so that it can be placed |
1213 // in the relocation information. | 1263 // in the relocation information. |
(...skipping 16 matching lines...) Expand all Loading... |
1230 void RecordComment(const char* msg); | 1280 void RecordComment(const char* msg); |
1231 | 1281 |
1232 // Record a deoptimization reason that can be used by a log or cpu profiler. | 1282 // Record a deoptimization reason that can be used by a log or cpu profiler. |
1233 // Use --trace-deopt to enable. | 1283 // Use --trace-deopt to enable. |
1234 void RecordDeoptReason(const int reason, const SourcePosition position); | 1284 void RecordDeoptReason(const int reason, const SourcePosition position); |
1235 | 1285 |
1236 // Writes a single byte or word of data in the code stream. Used | 1286 // Writes a single byte or word of data in the code stream. Used |
1237 // for inline tables, e.g., jump-tables. | 1287 // for inline tables, e.g., jump-tables. |
1238 void db(uint8_t data); | 1288 void db(uint8_t data); |
1239 void dd(uint32_t data); | 1289 void dd(uint32_t data); |
1240 void emit_ptr(intptr_t data); | 1290 void dq(uint64_t data); |
1241 void emit_double(double data); | 1291 void dp(uintptr_t data); |
1242 | 1292 |
1243 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1293 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
1244 | 1294 |
1245 // Read/patch instructions | 1295 // Read/patch instructions |
1246 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 1296 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
1247 void instr_at_put(int pos, Instr instr) { | 1297 void instr_at_put(int pos, Instr instr) { |
1248 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 1298 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
1249 } | 1299 } |
1250 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } | 1300 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } |
1251 static void instr_at_put(byte* pc, Instr instr) { | 1301 static void instr_at_put(byte* pc, Instr instr) { |
(...skipping 25 matching lines...) Expand all Loading... |
1277 static bool IsCrSet(Instr instr); | 1327 static bool IsCrSet(Instr instr); |
1278 static Register GetCmpImmediateRegister(Instr instr); | 1328 static Register GetCmpImmediateRegister(Instr instr); |
1279 static int GetCmpImmediateRawImmediate(Instr instr); | 1329 static int GetCmpImmediateRawImmediate(Instr instr); |
1280 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1330 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
1281 | 1331 |
1282 // Postpone the generation of the trampoline pool for the specified number of | 1332 // Postpone the generation of the trampoline pool for the specified number of |
1283 // instructions. | 1333 // instructions. |
1284 void BlockTrampolinePoolFor(int instructions); | 1334 void BlockTrampolinePoolFor(int instructions); |
1285 void CheckTrampolinePool(); | 1335 void CheckTrampolinePool(); |
1286 | 1336 |
| 1337 // For mov. Return the number of actual instructions required to |
| 1338 // load the operand into a register. This can be anywhere from |
| 1339 // one (constant pool small section) to five instructions (full |
| 1340 // 64-bit sequence). |
| 1341 // |
| 1342 // The value returned is only valid as long as no entries are added to the |
| 1343 // constant pool between this call and the actual instruction being emitted. |
| 1344 int instructions_required_for_mov(Register dst, const Operand& src) const; |
| 1345 |
| 1346 // Decide between using the constant pool vs. a mov immediate sequence. |
| 1347 bool use_constant_pool_for_mov(Register dst, const Operand& src, |
| 1348 bool canOptimize) const; |
| 1349 |
1287 // The code currently calls CheckBuffer() too often. This has the side | 1350 // The code currently calls CheckBuffer() too often. This has the side |
1288 // effect of randomly growing the buffer in the middle of multi-instruction | 1351 // effect of randomly growing the buffer in the middle of multi-instruction |
1289 // sequences. | 1352 // sequences. |
1290 // | 1353 // |
1291 // This function allows outside callers to check and grow the buffer | 1354 // This function allows outside callers to check and grow the buffer |
1292 void EnsureSpaceFor(int space_needed); | 1355 void EnsureSpaceFor(int space_needed); |
1293 | 1356 |
1294 // Allocate a constant pool of the correct size for the generated code. | 1357 int EmitConstantPool() { return constant_pool_builder_.Emit(this); } |
1295 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); | |
1296 | 1358 |
1297 // Generate the constant pool for the generated code. | 1359 bool ConstantPoolAccessIsInOverflow() const { |
1298 void PopulateConstantPool(ConstantPoolArray* constant_pool); | 1360 return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) == |
| 1361 ConstantPoolEntry::OVERFLOWED; |
| 1362 } |
| 1363 |
| 1364 Label* ConstantPoolPosition() { |
| 1365 return constant_pool_builder_.EmittedPosition(); |
| 1366 } |
1299 | 1367 |
1300 void EmitRelocations(); | 1368 void EmitRelocations(); |
1301 | 1369 |
1302 protected: | 1370 protected: |
1303 // Relocation for a type-recording IC has the AST id added to it. This | 1371 // Relocation for a type-recording IC has the AST id added to it. This |
1304 // member variable is a way to pass the information from the call site to | 1372 // member variable is a way to pass the information from the call site to |
1305 // the relocation info. | 1373 // the relocation info. |
1306 TypeFeedbackId recorded_ast_id_; | 1374 TypeFeedbackId recorded_ast_id_; |
1307 | 1375 |
1308 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1376 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
1309 | 1377 |
1310 // Decode branch instruction at pos and return branch target pos | 1378 // Decode branch instruction at pos and return branch target pos |
1311 int target_at(int pos); | 1379 int target_at(int pos); |
1312 | 1380 |
1313 // Patch branch instruction at pos to branch to given branch target pos | 1381 // Patch branch instruction at pos to branch to given branch target pos |
1314 void target_at_put(int pos, int target_pos); | 1382 void target_at_put(int pos, int target_pos); |
1315 | 1383 |
1316 // Record reloc info for current pc_ | 1384 // Record reloc info for current pc_ |
1317 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1385 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1318 void RecordRelocInfo(const DeferredRelocInfo& rinfo); | 1386 ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode, |
| 1387 intptr_t value) { |
| 1388 bool sharing_ok = RelocInfo::IsNone(rmode) || |
| 1389 !(serializer_enabled() || rmode < RelocInfo::CELL || |
| 1390 is_constant_pool_entry_sharing_blocked()); |
| 1391 return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok); |
| 1392 } |
| 1393 ConstantPoolEntry::Access ConstantPoolAddEntry(double value) { |
| 1394 return constant_pool_builder_.AddEntry(pc_offset(), value); |
| 1395 } |
1319 | 1396 |
1320 // Block the emission of the trampoline pool before pc_offset. | 1397 // Block the emission of the trampoline pool before pc_offset. |
1321 void BlockTrampolinePoolBefore(int pc_offset) { | 1398 void BlockTrampolinePoolBefore(int pc_offset) { |
1322 if (no_trampoline_pool_before_ < pc_offset) | 1399 if (no_trampoline_pool_before_ < pc_offset) |
1323 no_trampoline_pool_before_ = pc_offset; | 1400 no_trampoline_pool_before_ = pc_offset; |
1324 } | 1401 } |
1325 | 1402 |
1326 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } | 1403 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } |
1327 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } | 1404 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } |
1328 bool is_trampoline_pool_blocked() const { | 1405 bool is_trampoline_pool_blocked() const { |
1329 return trampoline_pool_blocked_nesting_ > 0; | 1406 return trampoline_pool_blocked_nesting_ > 0; |
1330 } | 1407 } |
1331 | 1408 |
| 1409 void StartBlockConstantPoolEntrySharing() { |
| 1410 constant_pool_entry_sharing_blocked_nesting_++; |
| 1411 } |
| 1412 void EndBlockConstantPoolEntrySharing() { |
| 1413 constant_pool_entry_sharing_blocked_nesting_--; |
| 1414 } |
| 1415 bool is_constant_pool_entry_sharing_blocked() const { |
| 1416 return constant_pool_entry_sharing_blocked_nesting_ > 0; |
| 1417 } |
| 1418 |
1332 bool has_exception() const { return internal_trampoline_exception_; } | 1419 bool has_exception() const { return internal_trampoline_exception_; } |
1333 | 1420 |
1334 bool is_trampoline_emitted() const { return trampoline_emitted_; } | 1421 bool is_trampoline_emitted() const { return trampoline_emitted_; } |
1335 | 1422 |
1336 private: | 1423 private: |
1337 // Code generation | 1424 // Code generation |
1338 // The relocation writer's position is at least kGap bytes below the end of | 1425 // The relocation writer's position is at least kGap bytes below the end of |
1339 // the generated instructions. This is so that multi-instruction sequences do | 1426 // the generated instructions. This is so that multi-instruction sequences do |
1340 // not have to check for overflow. The same is true for writes of large | 1427 // not have to check for overflow. The same is true for writes of large |
1341 // relocation info entries. | 1428 // relocation info entries. |
1342 static const int kGap = 32; | 1429 static const int kGap = 32; |
1343 | 1430 |
1344 // Repeated checking whether the trampoline pool should be emitted is rather | 1431 // Repeated checking whether the trampoline pool should be emitted is rather |
1345 // expensive. By default we only check again once a number of instructions | 1432 // expensive. By default we only check again once a number of instructions |
1346 // has been generated. | 1433 // has been generated. |
1347 int next_buffer_check_; // pc offset of next buffer check. | 1434 int next_buffer_check_; // pc offset of next buffer check. |
1348 | 1435 |
1349 // Emission of the trampoline pool may be blocked in some code sequences. | 1436 // Emission of the trampoline pool may be blocked in some code sequences. |
1350 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. | 1437 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. |
1351 int no_trampoline_pool_before_; // Block emission before this pc offset. | 1438 int no_trampoline_pool_before_; // Block emission before this pc offset. |
1352 | 1439 |
| 1440 // Do not share constant pool entries. |
| 1441 int constant_pool_entry_sharing_blocked_nesting_; |
| 1442 |
1353 // Relocation info generation | 1443 // Relocation info generation |
1354 // Each relocation is encoded as a variable size value | 1444 // Each relocation is encoded as a variable size value |
1355 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1445 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
1356 RelocInfoWriter reloc_info_writer; | 1446 RelocInfoWriter reloc_info_writer; |
1357 std::vector<DeferredRelocInfo> relocations_; | 1447 std::vector<DeferredRelocInfo> relocations_; |
1358 | 1448 |
1359 // The bound position, before this we cannot do instruction elimination. | 1449 // The bound position, before this we cannot do instruction elimination. |
1360 int last_bound_pos_; | 1450 int last_bound_pos_; |
1361 | 1451 |
| 1452 ConstantPoolBuilder constant_pool_builder_; |
| 1453 |
1362 // Code emission | 1454 // Code emission |
1363 inline void CheckBuffer(); | 1455 inline void CheckBuffer(); |
1364 void GrowBuffer(int needed = 0); | 1456 void GrowBuffer(int needed = 0); |
1365 inline void emit(Instr x); | 1457 inline void emit(Instr x); |
1366 inline void CheckTrampolinePoolQuick(); | 1458 inline void CheckTrampolinePoolQuick(); |
1367 | 1459 |
1368 // Instruction generation | 1460 // Instruction generation |
1369 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, | 1461 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, |
1370 DoubleRegister frb, RCBit r); | 1462 DoubleRegister frb, RCBit r); |
1371 void d_form(Instr instr, Register rt, Register ra, const intptr_t val, | 1463 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 Loading... |
1442 | 1534 |
1443 | 1535 |
1444 class EnsureSpace BASE_EMBEDDED { | 1536 class EnsureSpace BASE_EMBEDDED { |
1445 public: | 1537 public: |
1446 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 1538 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } |
1447 }; | 1539 }; |
1448 } | 1540 } |
1449 } // namespace v8::internal | 1541 } // namespace v8::internal |
1450 | 1542 |
1451 #endif // V8_PPC_ASSEMBLER_PPC_H_ | 1543 #endif // V8_PPC_ASSEMBLER_PPC_H_ |
OLD | NEW |