[arm] Remove 64bit constant pool support

We haven't put 64bit constants in the constant pool for a while. This
CL removes the support, simplifying the implementation.

Change-Id: I2c8972ea74dc71ccd5c9d333947d681dad2ea6c0
Bug: v8:8054
Reviewed-on: https://chromium-review.googlesource.com/c/1346109
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57701}
This commit is contained in:
Sigurd Schneider 2018-11-21 16:49:54 +01:00 committed by Commit Bot
parent 039d408101
commit a119ed63f6
2 changed files with 8 additions and 96 deletions

View File

@ -544,16 +544,13 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
int buffer_size)
: AssemblerBase(options, buffer, buffer_size),
pending_32_bit_constants_(),
pending_64_bit_constants_(),
scratch_register_list_(ip.bit()) {
pending_32_bit_constants_.reserve(kMinNumPendingConstants);
pending_64_bit_constants_.reserve(kMinNumPendingConstants);
reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
next_buffer_check_ = 0;
const_pool_blocked_nesting_ = 0;
no_const_pool_before_ = 0;
first_const_pool_32_use_ = -1;
first_const_pool_64_use_ = -1;
last_bound_pos_ = 0;
if (CpuFeatures::IsSupported(VFP32DREGS)) {
// Register objects tend to be abstracted and survive between scopes, so
@ -579,7 +576,6 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
int constant_pool_offset = 0;
CheckConstPool(true, false);
DCHECK(pending_32_bit_constants_.empty());
DCHECK(pending_64_bit_constants_.empty());
AllocateAndInstallRequestedHeapObjects(isolate);
@ -5080,7 +5076,6 @@ void Assembler::db(uint8_t data) {
// db is used to write raw data. The constant pool should be emitted or
// blocked before using db.
DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty());
DCHECK(is_const_pool_blocked() || pending_64_bit_constants_.empty());
CheckBuffer();
*reinterpret_cast<uint8_t*>(pc_) = data;
pc_ += sizeof(uint8_t);
@ -5091,7 +5086,6 @@ void Assembler::dd(uint32_t data) {
// dd is used to write raw data. The constant pool should be emitted or
// blocked before using dd.
DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty());
DCHECK(is_const_pool_blocked() || pending_64_bit_constants_.empty());
CheckBuffer();
*reinterpret_cast<uint32_t*>(pc_) = data;
pc_ += sizeof(uint32_t);
@ -5102,7 +5096,6 @@ void Assembler::dq(uint64_t value) {
// dq is used to write raw data. The constant pool should be emitted or
// blocked before using dq.
DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty());
DCHECK(is_const_pool_blocked() || pending_64_bit_constants_.empty());
CheckBuffer();
*reinterpret_cast<uint64_t*>(pc_) = value;
pc_ += sizeof(uint64_t);
@ -5164,11 +5157,7 @@ void Assembler::BlockConstPoolFor(int instructions) {
#ifdef DEBUG
int start = pc_limit + kInstrSize + 2 * kPointerSize;
DCHECK(pending_32_bit_constants_.empty() ||
(start - first_const_pool_32_use_ +
pending_64_bit_constants_.size() * kDoubleSize <
kMaxDistToIntPool));
DCHECK(pending_64_bit_constants_.empty() ||
(start - first_const_pool_64_use_ < kMaxDistToFPPool));
(start < first_const_pool_32_use_ + kMaxDistToIntPool));
#endif
no_const_pool_before_ = pc_limit;
}
@ -5190,7 +5179,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
}
// There is nothing to do if there are no pending constant pool entries.
if (pending_32_bit_constants_.empty() && pending_64_bit_constants_.empty()) {
if (pending_32_bit_constants_.empty()) {
// Calculate the offset of the next check.
next_buffer_check_ = pc_offset() + kCheckPoolInterval;
return;
@ -5203,19 +5192,6 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
int size_up_to_marker = jump_instr + kInstrSize;
int estimated_size_after_marker =
pending_32_bit_constants_.size() * kPointerSize;
bool has_int_values = !pending_32_bit_constants_.empty();
bool has_fp_values = !pending_64_bit_constants_.empty();
bool require_64_bit_align = false;
if (has_fp_values) {
require_64_bit_align =
!IsAligned(reinterpret_cast<intptr_t>(pc_ + size_up_to_marker),
kDoubleAlignment);
if (require_64_bit_align) {
estimated_size_after_marker += kInstrSize;
}
estimated_size_after_marker +=
pending_64_bit_constants_.size() * kDoubleSize;
}
int estimated_size = size_up_to_marker + estimated_size_after_marker;
// We emit a constant pool when:
@ -5227,35 +5203,18 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// * the instruction doesn't require a jump after itself to jump over the
// constant pool, and we're getting close to running out of range.
if (!force_emit) {
DCHECK(has_fp_values || has_int_values);
DCHECK(!pending_32_bit_constants_.empty());
bool need_emit = false;
if (has_fp_values) {
// The 64-bit constants are always emitted before the 32-bit constants, so
// we can ignore the effect of the 32-bit constants on estimated_size.
int dist64 = pc_offset() + estimated_size -
pending_32_bit_constants_.size() * kPointerSize -
first_const_pool_64_use_;
if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
(!require_jump && (dist64 >= kMaxDistToFPPool / 2))) {
need_emit = true;
}
}
if (has_int_values) {
int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_;
if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) ||
(!require_jump && (dist32 >= kMaxDistToIntPool / 2))) {
need_emit = true;
}
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 (size_t i = 0; i < pending_64_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_64_bit_constants_[i];
if (entry.is_merged()) size_after_marker -= kDoubleSize;
}
for (size_t i = 0; i < pending_32_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_32_bit_constants_[i];
@ -5287,40 +5246,6 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
emit(kConstantPoolMarker |
EncodeConstantPoolLength(size_after_marker / kPointerSize));
if (require_64_bit_align) {
emit(kConstantPoolMarker);
}
// Emit 64-bit constant pool entries first: their range is smaller than
// 32-bit entries.
for (size_t i = 0; i < pending_64_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_64_bit_constants_[i];
Instr instr = instr_at(entry.position());
// Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
DCHECK((IsVldrDPcImmediateOffset(instr) &&
GetVldrDRegisterImmediateOffset(instr) == 0));
int delta = pc_offset() - entry.position() - Instruction::kPcLoadDelta;
DCHECK(is_uint10(delta));
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 (!entry.is_merged()) {
DCHECK(IsAligned(reinterpret_cast<intptr_t>(pc_), kDoubleAlignment));
dq(entry.value64());
}
}
// Emit 32-bit constant pool entries.
for (size_t i = 0; i < pending_32_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_32_bit_constants_[i];
@ -5357,10 +5282,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
}
pending_32_bit_constants_.clear();
pending_64_bit_constants_.clear();
first_const_pool_32_use_ = -1;
first_const_pool_64_use_ = -1;
RecordComment("]");
@ -5385,7 +5308,6 @@ PatchingAssembler::PatchingAssembler(const AssemblerOptions& options,
PatchingAssembler::~PatchingAssembler() {
// Check that we don't have any pending constant pools.
DCHECK(pending_32_bit_constants_.empty());
DCHECK(pending_64_bit_constants_.empty());
// Check that the code was patched as expected.
DCHECK_EQ(pc_, buffer_ + buffer_size_ - kGap);

View File

@ -627,7 +627,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
virtual void AbortedCodeGeneration() {
pending_32_bit_constants_.clear();
pending_64_bit_constants_.clear();
}
// GetCode emits any pending (non-emitted) code and fills the descriptor
@ -1506,13 +1505,10 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// PC-relative loads, thereby defining a maximum distance between the
// instruction and the accessed constant.
static constexpr int kMaxDistToIntPool = 4 * KB;
static constexpr int kMaxDistToFPPool = 1 * KB;
// All relocations could be integer, it therefore acts as the limit.
static constexpr int kMinNumPendingConstants = 4;
static constexpr int kMaxNumPending32Constants =
kMaxDistToIntPool / kInstrSize;
static constexpr int kMaxNumPending64Constants =
kMaxDistToFPPool / kInstrSize;
// Postpone the generation of the constant pool for the specified number of
// instructions.
@ -1563,11 +1559,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
int start = pc_offset() + kInstrSize + 2 * kPointerSize;
// Check the constant pool hasn't been blocked for too long.
DCHECK(pending_32_bit_constants_.empty() ||
(start + pending_64_bit_constants_.size() * kDoubleSize <
static_cast<size_t>(first_const_pool_32_use_ +
kMaxDistToIntPool)));
DCHECK(pending_64_bit_constants_.empty() ||
(start < (first_const_pool_64_use_ + kMaxDistToFPPool)));
(start < first_const_pool_32_use_ + kMaxDistToIntPool));
#endif
// Two cases:
// * no_const_pool_before_ >= next_buffer_check_ and the emission is
@ -1618,7 +1610,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// The buffers of pending constant pool entries.
std::vector<ConstantPoolEntry> pending_32_bit_constants_;
std::vector<ConstantPoolEntry> pending_64_bit_constants_;
// Scratch registers available for use by the Assembler.
RegList scratch_register_list_;
@ -1654,7 +1645,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// Keep track of the first instruction requiring a constant pool entry
// since the previous constant pool was emitted.
int first_const_pool_32_use_;
int first_const_pool_64_use_;
// The bound position, before this we cannot do instruction elimination.
int last_bound_pos_;