| 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 |