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

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

Issue 2937413002: [arm64] Share constant pool entries in snapshot. (Closed)
Patch Set: [arm64] Share constant pool entries in snapshot. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/arm64/assembler-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_
6 #define V8_ARM64_ASSEMBLER_ARM64_H_ 6 #define V8_ARM64_ASSEMBLER_ARM64_H_
7 7
8 #include <deque> 8 #include <deque>
9 #include <list> 9 #include <list>
10 #include <map> 10 #include <map>
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 int64_t offset_; 795 int64_t offset_;
796 AddrMode addrmode_; 796 AddrMode addrmode_;
797 Shift shift_; 797 Shift shift_;
798 Extend extend_; 798 Extend extend_;
799 unsigned shift_amount_; 799 unsigned shift_amount_;
800 }; 800 };
801 801
802 802
803 class ConstPool { 803 class ConstPool {
804 public: 804 public:
805 explicit ConstPool(Assembler* assm) 805 explicit ConstPool(Assembler* assm) : assm_(assm), first_use_(-1) {}
806 : assm_(assm), 806 // Returns true when we need to write RelocInfo and false when we do not.
807 first_use_(-1), 807 bool RecordEntry(intptr_t data, RelocInfo::Mode mode);
808 shared_entries_count(0) {} 808 int EntryCount() const { return static_cast<int>(entries_.size()); }
809 void RecordEntry(intptr_t data, RelocInfo::Mode mode); 809 bool IsEmpty() const { return entries_.empty(); }
810 int EntryCount() const {
811 return shared_entries_count + static_cast<int>(unique_entries_.size());
812 }
813 bool IsEmpty() const {
814 return shared_entries_.empty() && unique_entries_.empty();
815 }
816 // Distance in bytes between the current pc and the first instruction 810 // Distance in bytes between the current pc and the first instruction
817 // using the pool. If there are no pending entries return kMaxInt. 811 // using the pool. If there are no pending entries return kMaxInt.
818 int DistanceToFirstUse(); 812 int DistanceToFirstUse();
819 // Offset after which instructions using the pool will be out of range. 813 // Offset after which instructions using the pool will be out of range.
820 int MaxPcOffset(); 814 int MaxPcOffset();
821 // Maximum size the constant pool can be with current entries. It always 815 // Maximum size the constant pool can be with current entries. It always
822 // includes alignment padding and branch over. 816 // includes alignment padding and branch over.
823 int WorstCaseSize(); 817 int WorstCaseSize();
824 // Size in bytes of the literal pool *if* it is emitted at the current 818 // Size in bytes of the literal pool *if* it is emitted at the current
825 // pc. The size will include the branch over the pool if it was requested. 819 // pc. The size will include the branch over the pool if it was requested.
826 int SizeIfEmittedAtCurrentPc(bool require_jump); 820 int SizeIfEmittedAtCurrentPc(bool require_jump);
827 // Emit the literal pool at the current pc with a branch over the pool if 821 // Emit the literal pool at the current pc with a branch over the pool if
828 // requested. 822 // requested.
829 void Emit(bool require_jump); 823 void Emit(bool require_jump);
830 // Discard any pending pool entries. 824 // Discard any pending pool entries.
831 void Clear(); 825 void Clear();
832 826
833 private: 827 private:
834 bool CanBeShared(RelocInfo::Mode mode); 828 bool CanBeShared(RelocInfo::Mode mode);
835 void EmitMarker(); 829 void EmitMarker();
836 void EmitGuard(); 830 void EmitGuard();
837 void EmitEntries(); 831 void EmitEntries();
838 832
833 typedef std::map<uint64_t, int> SharedEntryMap;
834 // Adds a shared entry to entries_, using 'entry_map' to determine whether we
835 // already track this entry. Returns true if this is the first time we add
836 // this entry, false otherwise.
837 bool AddSharedEntry(SharedEntryMap& entry_map, uint64_t data, int offset);
838
839 Assembler* assm_; 839 Assembler* assm_;
840 // Keep track of the first instruction requiring a constant pool entry 840 // Keep track of the first instruction requiring a constant pool entry
841 // since the previous constant pool was emitted. 841 // since the previous constant pool was emitted.
842 int first_use_; 842 int first_use_;
843 // values, pc offset(s) of entries which can be shared. 843
844 std::multimap<uint64_t, int> shared_entries_; 844 // Map of data to index in entries_ for shared entries.
845 // Number of distinct literal in shared entries. 845 SharedEntryMap shared_entries_;
846 int shared_entries_count; 846
847 // values, pc offset of entries which cannot be shared. 847 // Map of address of handle to index in entries_. We need to keep track of
848 std::vector<std::pair<uint64_t, int> > unique_entries_; 848 // code targets separately from other shared entries, as they can be
849 // relocated.
850 SharedEntryMap handle_to_index_map_;
851
852 // Values, pc offset(s) of entries. Use a vector to preserve the order of
853 // insertion, as the serializer expects code target RelocInfo to point to
854 // constant pool addresses in an ascending order.
855 std::vector<std::pair<uint64_t, std::vector<int> > > entries_;
849 }; 856 };
850 857
851 858
852 // ----------------------------------------------------------------------------- 859 // -----------------------------------------------------------------------------
853 // Assembler. 860 // Assembler.
854 861
855 class Assembler : public AssemblerBase { 862 class Assembler : public AssemblerBase {
856 public: 863 public:
857 // Create an assembler. Instructions and relocation information are emitted 864 // Create an assembler. Instructions and relocation information are emitted
858 // into a buffer, with the instructions starting from the beginning and the 865 // into a buffer, with the instructions starting from the beginning and the
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 1007
1001 static constexpr int kPatchDebugBreakSlotAddressOffset = 0; 1008 static constexpr int kPatchDebugBreakSlotAddressOffset = 0;
1002 1009
1003 // Number of instructions necessary to be able to later patch it to a call. 1010 // Number of instructions necessary to be able to later patch it to a call.
1004 static constexpr int kDebugBreakSlotInstructions = 5; 1011 static constexpr int kDebugBreakSlotInstructions = 5;
1005 static constexpr int kDebugBreakSlotLength = 1012 static constexpr int kDebugBreakSlotLength =
1006 kDebugBreakSlotInstructions * kInstructionSize; 1013 kDebugBreakSlotInstructions * kInstructionSize;
1007 1014
1008 // Prevent contant pool emission until EndBlockConstPool is called. 1015 // Prevent contant pool emission until EndBlockConstPool is called.
1009 // Call to this function can be nested but must be followed by an equal 1016 // Call to this function can be nested but must be followed by an equal
1010 // number of call to EndBlockConstpool. 1017 // number of calls to EndBlockConstpool.
1011 void StartBlockConstPool(); 1018 void StartBlockConstPool();
1012 1019
1013 // Resume constant pool emission. Need to be called as many time as 1020 // Resume constant pool emission. Need to be called as many time as
1014 // StartBlockConstPool to have an effect. 1021 // StartBlockConstPool to have an effect.
1015 void EndBlockConstPool(); 1022 void EndBlockConstPool();
1016 1023
1017 bool is_const_pool_blocked() const; 1024 bool is_const_pool_blocked() const;
1018 static bool IsConstantPoolAt(Instruction* instr); 1025 static bool IsConstantPoolAt(Instruction* instr);
1019 static int ConstantPoolSizeAt(Instruction* instr); 1026 static int ConstantPoolSizeAt(Instruction* instr);
1020 // See Assembler::CheckConstPool for more info. 1027 // See Assembler::CheckConstPool for more info.
1021 void EmitPoolGuard(); 1028 void EmitPoolGuard();
1022 1029
1023 // Prevent veneer pool emission until EndBlockVeneerPool is called. 1030 // Prevent veneer pool emission until EndBlockVeneerPool is called.
1024 // Call to this function can be nested but must be followed by an equal 1031 // Call to this function can be nested but must be followed by an equal
1025 // number of call to EndBlockConstpool. 1032 // number of calls to EndBlockConstpool.
1026 void StartBlockVeneerPool(); 1033 void StartBlockVeneerPool();
1027 1034
1028 // Resume constant pool emission. Need to be called as many time as 1035 // Resume constant pool emission. Need to be called as many time as
1029 // StartBlockVeneerPool to have an effect. 1036 // StartBlockVeneerPool to have an effect.
1030 void EndBlockVeneerPool(); 1037 void EndBlockVeneerPool();
1031 1038
1032 bool is_veneer_pool_blocked() const { 1039 bool is_veneer_pool_blocked() const {
1033 return veneer_pool_blocked_nesting_ > 0; 1040 return veneer_pool_blocked_nesting_ > 0;
1034 } 1041 }
1035 1042
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 ~BlockPoolsScope() { 3183 ~BlockPoolsScope() {
3177 assem_->EndBlockPools(); 3184 assem_->EndBlockPools();
3178 } 3185 }
3179 3186
3180 private: 3187 private:
3181 Assembler* assem_; 3188 Assembler* assem_;
3182 3189
3183 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope); 3190 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope);
3184 }; 3191 };
3185 3192
3193 // Class for blocking sharing of code targets in constant pool.
3194 class BlockCodeTargetSharingScope {
3195 public:
3196 explicit BlockCodeTargetSharingScope(Assembler* assem) : assem_(nullptr) {
3197 Open(assem);
3198 }
3199 // This constructor does not initialize the scope. The user needs to
3200 // explicitly call Open() before using it.
3201 BlockCodeTargetSharingScope() : assem_(nullptr) {}
3202 ~BlockCodeTargetSharingScope() { Close(); }
3203 void Open(Assembler* assem) {
3204 DCHECK_NULL(assem_);
3205 DCHECK_NOT_NULL(assem);
3206 assem_ = assem;
3207 assem_->StartBlockCodeTargetSharing();
3208 }
3209
3210 private:
3211 void Close() {
3212 if (assem_ != nullptr) {
3213 assem_->EndBlockCodeTargetSharing();
3214 }
3215 }
3216 Assembler* assem_;
3217
3218 DISALLOW_COPY_AND_ASSIGN(BlockCodeTargetSharingScope);
3219 };
3220
3186 protected: 3221 protected:
3187 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const; 3222 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const;
3188 3223
3189 void LoadStore(const CPURegister& rt, 3224 void LoadStore(const CPURegister& rt,
3190 const MemOperand& addr, 3225 const MemOperand& addr,
3191 LoadStoreOp op); 3226 LoadStoreOp op);
3192 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2, 3227 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2,
3193 const MemOperand& addr, LoadStorePairOp op); 3228 const MemOperand& addr, LoadStorePairOp op);
3194 void LoadStoreStruct(const VRegister& vt, const MemOperand& addr, 3229 void LoadStoreStruct(const VRegister& vt, const MemOperand& addr,
3195 NEONLoadStoreMultiStructOp op); 3230 NEONLoadStoreMultiStructOp op);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3261 const CPURegister& rt2); 3296 const CPURegister& rt2);
3262 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt); 3297 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt);
3263 3298
3264 // Remove the specified branch from the unbound label link chain. 3299 // Remove the specified branch from the unbound label link chain.
3265 // If available, a veneer for this label can be used for other branches in the 3300 // If available, a veneer for this label can be used for other branches in the
3266 // chain if the link chain cannot be fixed up without this branch. 3301 // chain if the link chain cannot be fixed up without this branch.
3267 void RemoveBranchFromLabelLinkChain(Instruction* branch, 3302 void RemoveBranchFromLabelLinkChain(Instruction* branch,
3268 Label* label, 3303 Label* label,
3269 Instruction* label_veneer = NULL); 3304 Instruction* label_veneer = NULL);
3270 3305
3306 // Prevent sharing of code target constant pool entries until
3307 // EndBlockCodeTargetSharing is called. Calls to this function can be nested
3308 // but must be followed by an equal number of call to
3309 // EndBlockCodeTargetSharing.
3310 void StartBlockCodeTargetSharing() { ++code_target_sharing_blocked_nesting_; }
3311
3312 // Resume sharing of constant pool code target entries. Needs to be called
3313 // as many times as StartBlockCodeTargetSharing to have an effect.
3314 void EndBlockCodeTargetSharing() { --code_target_sharing_blocked_nesting_; }
3315
3271 private: 3316 private:
3272 static uint32_t FPToImm8(double imm); 3317 static uint32_t FPToImm8(double imm);
3273 3318
3274 // Instruction helpers. 3319 // Instruction helpers.
3275 void MoveWide(const Register& rd, 3320 void MoveWide(const Register& rd,
3276 uint64_t imm, 3321 uint64_t imm,
3277 int shift, 3322 int shift,
3278 MoveWideImmediateOp mov_op); 3323 MoveWideImmediateOp mov_op);
3279 void DataProcShiftedRegister(const Register& rd, 3324 void DataProcShiftedRegister(const Register& rd,
3280 const Register& rn, 3325 const Register& rn,
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3442 // pool emission checks are interval based this value is an approximation. 3487 // pool emission checks are interval based this value is an approximation.
3443 static constexpr int kApproxMaxPoolEntryCount = 512; 3488 static constexpr int kApproxMaxPoolEntryCount = 512;
3444 3489
3445 // Emission of the constant pool may be blocked in some code sequences. 3490 // Emission of the constant pool may be blocked in some code sequences.
3446 int const_pool_blocked_nesting_; // Block emission if this is not zero. 3491 int const_pool_blocked_nesting_; // Block emission if this is not zero.
3447 int no_const_pool_before_; // Block emission before this pc offset. 3492 int no_const_pool_before_; // Block emission before this pc offset.
3448 3493
3449 // Emission of the veneer pools may be blocked in some code sequences. 3494 // Emission of the veneer pools may be blocked in some code sequences.
3450 int veneer_pool_blocked_nesting_; // Block emission if this is not zero. 3495 int veneer_pool_blocked_nesting_; // Block emission if this is not zero.
3451 3496
3497 // Sharing of code target entries may be blocked in some code sequences.
3498 int code_target_sharing_blocked_nesting_;
3499 bool IsCodeTargetSharingAllowed() const {
3500 return code_target_sharing_blocked_nesting_ == 0;
3501 }
3502
3452 // Relocation info generation 3503 // Relocation info generation
3453 // Each relocation is encoded as a variable size value 3504 // Each relocation is encoded as a variable size value
3454 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; 3505 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
3455 RelocInfoWriter reloc_info_writer; 3506 RelocInfoWriter reloc_info_writer;
3456 3507
3457 // Internal reference positions, required for (potential) patching in 3508 // Internal reference positions, required for (potential) patching in
3458 // GrowBuffer(); contains only those internal references whose labels 3509 // GrowBuffer(); contains only those internal references whose labels
3459 // are already bound. 3510 // are already bound.
3460 std::deque<int> internal_reference_positions_; 3511 std::deque<int> internal_reference_positions_;
3461 3512
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
3627 public: 3678 public:
3628 explicit EnsureSpace(Assembler* assembler) { 3679 explicit EnsureSpace(Assembler* assembler) {
3629 assembler->CheckBufferSpace(); 3680 assembler->CheckBufferSpace();
3630 } 3681 }
3631 }; 3682 };
3632 3683
3633 } // namespace internal 3684 } // namespace internal
3634 } // namespace v8 3685 } // namespace v8
3635 3686
3636 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ 3687 #endif // V8_ARM64_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « no previous file | src/arm64/assembler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698