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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/assembler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/assembler-arm.cc
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index b90ff1e05b6a383cbf40276af1e762b20ebd2635..74c682a47f60799b4fecc7cbf56a7f99bddb0dce 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -3734,18 +3734,19 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// the gap to the relocation information).
int jump_instr = require_jump ? kInstrSize : 0;
int size_up_to_marker = jump_instr + kInstrSize;
- int size_after_marker = num_pending_32_bit_constants_ * kPointerSize;
+ int estimated_size_after_marker =
+ num_pending_32_bit_constants_ * kPointerSize;
bool has_fp_values = (num_pending_64_bit_constants_ > 0);
bool require_64_bit_align = false;
if (has_fp_values) {
- require_64_bit_align = (((uintptr_t)pc_ + size_up_to_marker) & 0x7);
+ require_64_bit_align = IsAligned(
+ reinterpret_cast<intptr_t>(pc_ + size_up_to_marker), kDoubleAlignment);
if (require_64_bit_align) {
- size_after_marker += kInstrSize;
+ estimated_size_after_marker += kInstrSize;
}
- size_after_marker += num_pending_64_bit_constants_ * kDoubleSize;
+ estimated_size_after_marker += num_pending_64_bit_constants_ * kDoubleSize;
}
-
- int size = size_up_to_marker + size_after_marker;
+ int estimated_size = size_up_to_marker + estimated_size_after_marker;
// We emit a constant pool when:
// * requested to do so by parameter force_emit (e.g. after each function).
@@ -3759,7 +3760,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
bool need_emit = false;
if (has_fp_values) {
- int dist64 = pc_offset() + size -
+ int dist64 = pc_offset() + estimated_size -
num_pending_32_bit_constants_ * kPointerSize -
first_const_pool_64_use_;
if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
@@ -3767,8 +3768,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
need_emit = true;
}
}
- int dist32 =
- pc_offset() + size - first_const_pool_32_use_;
+ int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_;
if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) ||
(!require_jump && (dist32 >= kMaxDistToIntPool / 2))) {
need_emit = true;
@@ -3776,6 +3776,37 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
if (!need_emit) return;
}
+ // Deduplicate constants.
+ int size_after_marker = estimated_size_after_marker;
+ for (int i = 0; i < num_pending_64_bit_constants_; i++) {
+ ConstantPoolEntry& entry = pending_64_bit_constants_[i];
+ DCHECK(!entry.is_merged());
+ for (int j = 0; j < i; j++) {
+ if (entry.value64() == pending_64_bit_constants_[j].value64()) {
+ DCHECK(!pending_64_bit_constants_[j].is_merged());
+ entry.set_merged_index(j);
+ size_after_marker -= kDoubleSize;
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < num_pending_32_bit_constants_; i++) {
+ ConstantPoolEntry& entry = pending_32_bit_constants_[i];
+ DCHECK(!entry.is_merged());
+ if (!entry.sharing_ok()) continue;
+ for (int j = 0; j < i; j++) {
+ if (entry.value() == pending_32_bit_constants_[j].value()) {
+ DCHECK(!pending_32_bit_constants_[j].is_merged());
+ 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
+ size_after_marker -= kPointerSize;
+ break;
+ }
+ }
+ }
+
+ int size = size_up_to_marker + size_after_marker;
+
int needed_space = size + kGap;
while (buffer_space() <= needed_space) GrowBuffer();
@@ -3785,6 +3816,9 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
RecordComment("[ Constant Pool");
RecordConstPool(size);
+ Label size_check;
+ bind(&size_check);
+
// Emit jump over constant pool if necessary.
Label after_pool;
if (require_jump) {
@@ -3805,8 +3839,6 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
for (int i = 0; i < num_pending_64_bit_constants_; i++) {
ConstantPoolEntry& entry = pending_64_bit_constants_[i];
- DCHECK(!((uintptr_t)pc_ & 0x7)); // Check 64-bit alignment.
-
Instr instr = instr_at(entry.position());
// Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
DCHECK((IsVldrDPcImmediateOffset(instr) &&
@@ -3815,24 +3847,19 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
int delta = pc_offset() - entry.position() - kPcLoadDelta;
DCHECK(is_uint10(delta));
- bool found = false;
- uint64_t value = entry.value64();
- for (int j = 0; j < i; j++) {
- ConstantPoolEntry& entry2 = pending_64_bit_constants_[j];
- if (value == entry2.value64()) {
- found = true;
- Instr instr2 = instr_at(entry2.position());
- DCHECK(IsVldrDPcImmediateOffset(instr2));
- delta = GetVldrDRegisterImmediateOffset(instr2);
- delta += entry2.position() - entry.position();
- break;
- }
+ if (entry.is_merged()) {
+ ConstantPoolEntry& merged =
+ pending_64_bit_constants_[entry.merged_index()];
+ DCHECK(entry.value64() == merged.value64());
+ Instr merged_instr = instr_at(merged.position());
+ DCHECK(IsVldrDPcImmediateOffset(merged_instr));
+ delta = GetVldrDRegisterImmediateOffset(merged_instr);
+ delta += merged.position() - entry.position();
}
-
instr_at_put(entry.position(),
SetVldrDRegisterImmediateOffset(instr, delta));
-
- if (!found) {
+ if (!entry.is_merged()) {
+ DCHECK(IsAligned(reinterpret_cast<intptr_t>(pc_), kDoubleAlignment));
dq(entry.value64());
}
}
@@ -3844,41 +3871,31 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// 64-bit loads shouldn't get here.
DCHECK(!IsVldrDPcImmediateOffset(instr));
+ DCHECK(!IsMovW(instr));
+ DCHECK(IsLdrPcImmediateOffset(instr) &&
+ GetLdrRegisterImmediateOffset(instr) == 0);
- if (IsLdrPcImmediateOffset(instr) &&
- GetLdrRegisterImmediateOffset(instr) == 0) {
- int delta = pc_offset() - entry.position() - kPcLoadDelta;
- DCHECK(is_uint12(delta));
- // 0 is the smallest delta:
- // ldr rd, [pc, #0]
- // constant pool marker
- // data
-
- bool found = false;
- if (entry.sharing_ok()) {
- for (int j = 0; j < i; j++) {
- ConstantPoolEntry& entry2 = pending_32_bit_constants_[j];
-
- if (entry2.value() == entry.value()) {
- Instr instr2 = instr_at(entry2.position());
- if (IsLdrPcImmediateOffset(instr2)) {
- delta = GetLdrRegisterImmediateOffset(instr2);
- delta += entry2.position() - entry.position();
- found = true;
- break;
- }
- }
- }
- }
-
- instr_at_put(entry.position(),
- SetLdrRegisterImmediateOffset(instr, delta));
-
- if (!found) {
- emit(entry.value());
- }
- } else {
- DCHECK(IsMovW(instr));
+ int delta = pc_offset() - entry.position() - kPcLoadDelta;
+ DCHECK(is_uint12(delta));
+ // 0 is the smallest delta:
+ // ldr rd, [pc, #0]
+ // constant pool marker
+ // data
+
+ if (entry.is_merged()) {
+ DCHECK(entry.sharing_ok());
+ ConstantPoolEntry& merged =
+ pending_32_bit_constants_[entry.merged_index()];
+ DCHECK(entry.value() == merged.value());
+ Instr merged_instr = instr_at(merged.position());
+ DCHECK(IsLdrPcImmediateOffset(merged_instr));
+ delta = GetLdrRegisterImmediateOffset(merged_instr);
+ delta += merged.position() - entry.position();
+ }
+ instr_at_put(entry.position(),
+ SetLdrRegisterImmediateOffset(instr, delta));
+ if (!entry.is_merged()) {
+ emit(entry.value());
}
}
@@ -3889,6 +3906,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
RecordComment("]");
+ DCHECK_EQ(size, SizeOfCodeGeneratedSince(&size_check));
+
if (after_pool.is_linked()) {
bind(&after_pool);
}
« 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