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