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

Side by Side Diff: src/arm/assembler-arm.cc

Issue 1217673003: Make sure the constant pool size is as promised. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: keep deduplication Created 5 years, 5 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/assembler.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 (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 3716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 // Calculate the offset of the next check. 3727 // Calculate the offset of the next check.
3728 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3728 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3729 return; 3729 return;
3730 } 3730 }
3731 3731
3732 // Check that the code buffer is large enough before emitting the constant 3732 // Check that the code buffer is large enough before emitting the constant
3733 // pool (include the jump over the pool and the constant pool marker and 3733 // pool (include the jump over the pool and the constant pool marker and
3734 // the gap to the relocation information). 3734 // the gap to the relocation information).
3735 int jump_instr = require_jump ? kInstrSize : 0; 3735 int jump_instr = require_jump ? kInstrSize : 0;
3736 int size_up_to_marker = jump_instr + kInstrSize; 3736 int size_up_to_marker = jump_instr + kInstrSize;
3737 int size_after_marker = num_pending_32_bit_constants_ * kPointerSize; 3737 int estimated_size_after_marker =
3738 num_pending_32_bit_constants_ * kPointerSize;
3738 bool has_fp_values = (num_pending_64_bit_constants_ > 0); 3739 bool has_fp_values = (num_pending_64_bit_constants_ > 0);
3739 bool require_64_bit_align = false; 3740 bool require_64_bit_align = false;
3740 if (has_fp_values) { 3741 if (has_fp_values) {
3741 require_64_bit_align = (((uintptr_t)pc_ + size_up_to_marker) & 0x7); 3742 require_64_bit_align = IsAligned(
3743 reinterpret_cast<intptr_t>(pc_ + size_up_to_marker), kDoubleAlignment);
3742 if (require_64_bit_align) { 3744 if (require_64_bit_align) {
3743 size_after_marker += kInstrSize; 3745 estimated_size_after_marker += kInstrSize;
3744 } 3746 }
3745 size_after_marker += num_pending_64_bit_constants_ * kDoubleSize; 3747 estimated_size_after_marker += num_pending_64_bit_constants_ * kDoubleSize;
3746 } 3748 }
3747 3749 int estimated_size = size_up_to_marker + estimated_size_after_marker;
3748 int size = size_up_to_marker + size_after_marker;
3749 3750
3750 // We emit a constant pool when: 3751 // We emit a constant pool when:
3751 // * requested to do so by parameter force_emit (e.g. after each function). 3752 // * requested to do so by parameter force_emit (e.g. after each function).
3752 // * the distance from the first instruction accessing the constant pool to 3753 // * the distance from the first instruction accessing the constant pool to
3753 // any of the constant pool entries will exceed its limit the next 3754 // any of the constant pool entries will exceed its limit the next
3754 // time the pool is checked. This is overly restrictive, but we don't emit 3755 // time the pool is checked. This is overly restrictive, but we don't emit
3755 // constant pool entries in-order so it's conservatively correct. 3756 // constant pool entries in-order so it's conservatively correct.
3756 // * the instruction doesn't require a jump after itself to jump over the 3757 // * the instruction doesn't require a jump after itself to jump over the
3757 // constant pool, and we're getting close to running out of range. 3758 // constant pool, and we're getting close to running out of range.
3758 if (!force_emit) { 3759 if (!force_emit) {
3759 DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0)); 3760 DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
3760 bool need_emit = false; 3761 bool need_emit = false;
3761 if (has_fp_values) { 3762 if (has_fp_values) {
3762 int dist64 = pc_offset() + size - 3763 int dist64 = pc_offset() + estimated_size -
3763 num_pending_32_bit_constants_ * kPointerSize - 3764 num_pending_32_bit_constants_ * kPointerSize -
3764 first_const_pool_64_use_; 3765 first_const_pool_64_use_;
3765 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) || 3766 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
3766 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) { 3767 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) {
3767 need_emit = true; 3768 need_emit = true;
3768 } 3769 }
3769 } 3770 }
3770 int dist32 = 3771 int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_;
3771 pc_offset() + size - first_const_pool_32_use_;
3772 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) || 3772 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) ||
3773 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) { 3773 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) {
3774 need_emit = true; 3774 need_emit = true;
3775 } 3775 }
3776 if (!need_emit) return; 3776 if (!need_emit) return;
3777 } 3777 }
3778 3778
3779 // Deduplicate constants.
3780 int size_after_marker = estimated_size_after_marker;
3781 for (int i = 0; i < num_pending_64_bit_constants_; i++) {
3782 ConstantPoolEntry& entry = pending_64_bit_constants_[i];
3783 DCHECK(!entry.is_merged());
3784 for (int j = 0; j < i; j++) {
3785 if (entry.value64() == pending_64_bit_constants_[j].value64()) {
3786 DCHECK(!pending_64_bit_constants_[j].is_merged());
3787 entry.set_merged_index(j);
3788 size_after_marker -= kDoubleSize;
3789 break;
3790 }
3791 }
3792 }
3793
3794 for (int i = 0; i < num_pending_32_bit_constants_; i++) {
3795 ConstantPoolEntry& entry = pending_32_bit_constants_[i];
3796 DCHECK(!entry.is_merged());
3797 if (!entry.sharing_ok()) continue;
3798 for (int j = 0; j < i; j++) {
3799 if (entry.value() == pending_32_bit_constants_[j].value()) {
3800 DCHECK(!pending_32_bit_constants_[j].is_merged());
3801 entry.set_merged_index(j);
rmcilroy 2015/07/03 08:58:04 I think this the wrong way round, you should be se
Yang 2015/07/03 09:07:33 I haven't changed the merge loop at all. j is neve
rmcilroy 2015/07/03 09:45:14 You're right, oops. I didn't look at the for loop
3802 size_after_marker -= kPointerSize;
3803 break;
3804 }
3805 }
3806 }
3807
3808 int size = size_up_to_marker + size_after_marker;
3809
3779 int needed_space = size + kGap; 3810 int needed_space = size + kGap;
3780 while (buffer_space() <= needed_space) GrowBuffer(); 3811 while (buffer_space() <= needed_space) GrowBuffer();
3781 3812
3782 { 3813 {
3783 // Block recursive calls to CheckConstPool. 3814 // Block recursive calls to CheckConstPool.
3784 BlockConstPoolScope block_const_pool(this); 3815 BlockConstPoolScope block_const_pool(this);
3785 RecordComment("[ Constant Pool"); 3816 RecordComment("[ Constant Pool");
3786 RecordConstPool(size); 3817 RecordConstPool(size);
3787 3818
3819 Label size_check;
3820 bind(&size_check);
3821
3788 // Emit jump over constant pool if necessary. 3822 // Emit jump over constant pool if necessary.
3789 Label after_pool; 3823 Label after_pool;
3790 if (require_jump) { 3824 if (require_jump) {
3791 b(&after_pool); 3825 b(&after_pool);
3792 } 3826 }
3793 3827
3794 // Put down constant pool marker "Undefined instruction". 3828 // Put down constant pool marker "Undefined instruction".
3795 // The data size helps disassembly know what to print. 3829 // The data size helps disassembly know what to print.
3796 emit(kConstantPoolMarker | 3830 emit(kConstantPoolMarker |
3797 EncodeConstantPoolLength(size_after_marker / kPointerSize)); 3831 EncodeConstantPoolLength(size_after_marker / kPointerSize));
3798 3832
3799 if (require_64_bit_align) { 3833 if (require_64_bit_align) {
3800 emit(kConstantPoolMarker); 3834 emit(kConstantPoolMarker);
3801 } 3835 }
3802 3836
3803 // Emit 64-bit constant pool entries first: their range is smaller than 3837 // Emit 64-bit constant pool entries first: their range is smaller than
3804 // 32-bit entries. 3838 // 32-bit entries.
3805 for (int i = 0; i < num_pending_64_bit_constants_; i++) { 3839 for (int i = 0; i < num_pending_64_bit_constants_; i++) {
3806 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; 3840 ConstantPoolEntry& entry = pending_64_bit_constants_[i];
3807 3841
3808 DCHECK(!((uintptr_t)pc_ & 0x7)); // Check 64-bit alignment.
3809
3810 Instr instr = instr_at(entry.position()); 3842 Instr instr = instr_at(entry.position());
3811 // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0. 3843 // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
3812 DCHECK((IsVldrDPcImmediateOffset(instr) && 3844 DCHECK((IsVldrDPcImmediateOffset(instr) &&
3813 GetVldrDRegisterImmediateOffset(instr) == 0)); 3845 GetVldrDRegisterImmediateOffset(instr) == 0));
3814 3846
3815 int delta = pc_offset() - entry.position() - kPcLoadDelta; 3847 int delta = pc_offset() - entry.position() - kPcLoadDelta;
3816 DCHECK(is_uint10(delta)); 3848 DCHECK(is_uint10(delta));
3817 3849
3818 bool found = false; 3850 if (entry.is_merged()) {
3819 uint64_t value = entry.value64(); 3851 ConstantPoolEntry& merged =
3820 for (int j = 0; j < i; j++) { 3852 pending_64_bit_constants_[entry.merged_index()];
3821 ConstantPoolEntry& entry2 = pending_64_bit_constants_[j]; 3853 DCHECK(entry.value64() == merged.value64());
3822 if (value == entry2.value64()) { 3854 Instr merged_instr = instr_at(merged.position());
3823 found = true; 3855 DCHECK(IsVldrDPcImmediateOffset(merged_instr));
3824 Instr instr2 = instr_at(entry2.position()); 3856 delta = GetVldrDRegisterImmediateOffset(merged_instr);
3825 DCHECK(IsVldrDPcImmediateOffset(instr2)); 3857 delta += merged.position() - entry.position();
3826 delta = GetVldrDRegisterImmediateOffset(instr2);
3827 delta += entry2.position() - entry.position();
3828 break;
3829 }
3830 } 3858 }
3831
3832 instr_at_put(entry.position(), 3859 instr_at_put(entry.position(),
3833 SetVldrDRegisterImmediateOffset(instr, delta)); 3860 SetVldrDRegisterImmediateOffset(instr, delta));
3834 3861 if (!entry.is_merged()) {
3835 if (!found) { 3862 DCHECK(IsAligned(reinterpret_cast<intptr_t>(pc_), kDoubleAlignment));
3836 dq(entry.value64()); 3863 dq(entry.value64());
3837 } 3864 }
3838 } 3865 }
3839 3866
3840 // Emit 32-bit constant pool entries. 3867 // Emit 32-bit constant pool entries.
3841 for (int i = 0; i < num_pending_32_bit_constants_; i++) { 3868 for (int i = 0; i < num_pending_32_bit_constants_; i++) {
3842 ConstantPoolEntry& entry = pending_32_bit_constants_[i]; 3869 ConstantPoolEntry& entry = pending_32_bit_constants_[i];
3843 Instr instr = instr_at(entry.position()); 3870 Instr instr = instr_at(entry.position());
3844 3871
3845 // 64-bit loads shouldn't get here. 3872 // 64-bit loads shouldn't get here.
3846 DCHECK(!IsVldrDPcImmediateOffset(instr)); 3873 DCHECK(!IsVldrDPcImmediateOffset(instr));
3874 DCHECK(!IsMovW(instr));
3875 DCHECK(IsLdrPcImmediateOffset(instr) &&
3876 GetLdrRegisterImmediateOffset(instr) == 0);
3847 3877
3848 if (IsLdrPcImmediateOffset(instr) && 3878 int delta = pc_offset() - entry.position() - kPcLoadDelta;
3849 GetLdrRegisterImmediateOffset(instr) == 0) { 3879 DCHECK(is_uint12(delta));
3850 int delta = pc_offset() - entry.position() - kPcLoadDelta; 3880 // 0 is the smallest delta:
3851 DCHECK(is_uint12(delta)); 3881 // ldr rd, [pc, #0]
3852 // 0 is the smallest delta: 3882 // constant pool marker
3853 // ldr rd, [pc, #0] 3883 // data
3854 // constant pool marker
3855 // data
3856 3884
3857 bool found = false; 3885 if (entry.is_merged()) {
3858 if (entry.sharing_ok()) { 3886 DCHECK(entry.sharing_ok());
3859 for (int j = 0; j < i; j++) { 3887 ConstantPoolEntry& merged =
3860 ConstantPoolEntry& entry2 = pending_32_bit_constants_[j]; 3888 pending_32_bit_constants_[entry.merged_index()];
3861 3889 DCHECK(entry.value() == merged.value());
3862 if (entry2.value() == entry.value()) { 3890 Instr merged_instr = instr_at(merged.position());
3863 Instr instr2 = instr_at(entry2.position()); 3891 DCHECK(IsLdrPcImmediateOffset(merged_instr));
3864 if (IsLdrPcImmediateOffset(instr2)) { 3892 delta = GetLdrRegisterImmediateOffset(merged_instr);
3865 delta = GetLdrRegisterImmediateOffset(instr2); 3893 delta += merged.position() - entry.position();
3866 delta += entry2.position() - entry.position(); 3894 }
3867 found = true; 3895 instr_at_put(entry.position(),
3868 break; 3896 SetLdrRegisterImmediateOffset(instr, delta));
3869 } 3897 if (!entry.is_merged()) {
3870 } 3898 emit(entry.value());
3871 }
3872 }
3873
3874 instr_at_put(entry.position(),
3875 SetLdrRegisterImmediateOffset(instr, delta));
3876
3877 if (!found) {
3878 emit(entry.value());
3879 }
3880 } else {
3881 DCHECK(IsMovW(instr));
3882 } 3899 }
3883 } 3900 }
3884 3901
3885 num_pending_32_bit_constants_ = 0; 3902 num_pending_32_bit_constants_ = 0;
3886 num_pending_64_bit_constants_ = 0; 3903 num_pending_64_bit_constants_ = 0;
3887 first_const_pool_32_use_ = -1; 3904 first_const_pool_32_use_ = -1;
3888 first_const_pool_64_use_ = -1; 3905 first_const_pool_64_use_ = -1;
3889 3906
3890 RecordComment("]"); 3907 RecordComment("]");
3891 3908
3909 DCHECK_EQ(size, SizeOfCodeGeneratedSince(&size_check));
3910
3892 if (after_pool.is_linked()) { 3911 if (after_pool.is_linked()) {
3893 bind(&after_pool); 3912 bind(&after_pool);
3894 } 3913 }
3895 } 3914 }
3896 3915
3897 // Since a constant pool was just emitted, move the check offset forward by 3916 // Since a constant pool was just emitted, move the check offset forward by
3898 // the standard interval. 3917 // the standard interval.
3899 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3918 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3900 } 3919 }
3901 3920
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3951 DCHECK(is_uint12(offset)); 3970 DCHECK(is_uint12(offset));
3952 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); 3971 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset));
3953 } 3972 }
3954 } 3973 }
3955 3974
3956 3975
3957 } // namespace internal 3976 } // namespace internal
3958 } // namespace v8 3977 } // namespace v8
3959 3978
3960 #endif // V8_TARGET_ARCH_ARM 3979 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698