Commit 619570b3 authored by yangguo's avatar yangguo Committed by Commit bot

Make sure the constant pool size is as promised.

LOG=N
R=bmeurer@chromium.org
BUG=chromium:506443

Review URL: https://codereview.chromium.org/1217673003

Cr-Commit-Position: refs/heads/master@{#29463}
parent 75e67175
......@@ -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);
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);
}
......
......@@ -881,6 +881,8 @@ void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT
if (id != Deoptimizer::kNotDeoptimizationEntry) {
os << " (deoptimization bailout " << id << ")";
}
} else if (IsConstPool(rmode_)) {
os << " (size " << static_cast<int>(data_) << ")";
}
os << "\n";
......
......@@ -100,8 +100,8 @@ static int DecodeIt(Isolate* isolate, std::ostream* os,
int num_const = d.ConstantPoolSizeAt(pc);
if (num_const >= 0) {
SNPrintF(decode_buffer,
"%08x constant pool begin",
*reinterpret_cast<int32_t*>(pc));
"%08x constant pool begin (num_const = %d)",
*reinterpret_cast<int32_t*>(pc), num_const);
constants = num_const;
pc += 4;
} else if (it != NULL && !it->done() && it->rinfo()->pc() == pc &&
......
// 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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment