// 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).
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) ||
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;
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);
+ 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();
RecordComment("[ Constant Pool");
RecordConstPool(size);
+ Label size_check;
+ bind(&size_check);
+
// Emit jump over constant pool if necessary.
Label after_pool;
if (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) &&
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());
}
}
// 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());
}
}
RecordComment("]");
+ DCHECK_EQ(size, SizeOfCodeGeneratedSince(&size_check));
+
if (after_pool.is_linked()) {
bind(&after_pool);
}
--- /dev/null
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+assertSame = function assertSame() {
+ if (found === expected) {
+ if (1 / expected) return;
+ } else if ((expected !== expected) && (found !== found)) {
+ return;
+ };
+};
+assertEquals = function assertEquals() {
+ if (expected) {;
+ }
+};
+assertArrayEquals = function assertArrayEquals() {
+ var start = "";
+ if (name_opt) {
+ start = name_opt + " - ";
+ };
+ if (expected.length == found.length) {
+ for (var i = 0; i < expected.length; ++i) {;
+ }
+ }
+};
+assertPropertiesEqual = function assertPropertiesEqual() {
+ if (found) {;
+ }
+};
+assertToStringEquals = function assertToStringEquals() {
+ if (found) {;
+ }
+};
+assertTrue = function assertTrue() {;
+};
+assertFalse = function assertFalse() {;
+};
+assertUnreachable = function assertUnreachable() {
+ var message = "Fail" + "ure: unreachable";
+ if (name_opt) {
+ message += " - " + name_opt;
+ }
+};
+OptimizationStatus = function() {}
+assertUnoptimized = function assertUnoptimized() {;
+}
+assertOptimized = function assertOptimized() {;
+}
+triggerAssertFalse = function() {}
+var __v_2 = {};
+var __v_3 = {};
+var __v_4 = {};
+var __v_5 = {};
+var __v_6 = 1073741823;
+var __v_7 = {};
+var __v_8 = {};
+var __v_9 = {};
+var __v_10 = {};
+var __v_11 = 2147483648;
+var __v_12 = 1073741823;
+var __v_13 = {};
+var __v_14 = {};
+var __v_15 = -2147483648;
+var __v_16 = {};
+var __v_17 = {};
+var __v_19 = {};
+var __v_20 = {};
+var __v_21 = {};
+var __v_22 = {};
+var __v_23 = {};
+var __v_24 = {};
+try {
+ (function() {
+ var Debug = %GetDebugContext().Debug;
+
+ function __f_0() {}
+ for (var __v_0 = 0; __v_0 < 3; __v_0++) {
+ var __v_2 = function() {
+ a = 1;
+ }
+ Debug.setListener(__f_0);
+ if (__v_0 < 2) Debug.setBreakPoint(__v_2);
+ }
+ })();
+} catch (e) {
+ print();
+}