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

Unified Diff: src/arm/assembler-arm.cc

Issue 2869683004: [arm] Share constant pool entries in snapshot. (Closed)
Patch Set: Update tools/v8heapconst.py Created 3 years, 7 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
Index: src/arm/assembler-arm.cc
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 6932e973796b2c6d995f08ffb5b3d0214cc7dc73..f2afa52eef6268ec64b9b8d5b40c15ec12bc5764 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -1093,24 +1093,23 @@ static bool fits_shifter(uint32_t imm32,
return false;
}
+namespace {
// We have to use the temporary register for things that can be relocated even
// if they can be encoded in the ARM's 12 bits of immediate-offset instruction
// space. There is no guarantee that the relocated location can be similarly
// encoded.
-bool Operand::must_output_reloc_info(const Assembler* assembler) const {
- if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
+bool must_output_reloc_info(RelocInfo::Mode rmode, const Assembler* assembler) {
+ if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
if (assembler != NULL && assembler->predictable_code_size()) return true;
return assembler->serializer_enabled();
- } else if (RelocInfo::IsNone(rmode_)) {
+ } else if (RelocInfo::IsNone(rmode)) {
return false;
}
return true;
}
-
-static bool use_mov_immediate_load(const Operand& x,
- const Assembler* assembler) {
+bool use_mov_immediate_load(const Operand& x, const Assembler* assembler) {
DCHECK(assembler != nullptr);
if (x.must_output_reloc_info(assembler)) {
// Prefer constant pool if data is likely to be patched.
@@ -1121,6 +1120,11 @@ static bool use_mov_immediate_load(const Operand& x,
}
}
+} // namespace
+
+bool Operand::must_output_reloc_info(const Assembler* assembler) const {
+ return v8::internal::must_output_reloc_info(rmode_, assembler);
+}
int Operand::instructions_required(const Assembler* assembler,
Instr instr) const {
@@ -1134,8 +1138,9 @@ int Operand::instructions_required(const Assembler* assembler,
// for the constant pool or immediate load
int instructions;
if (use_mov_immediate_load(*this, assembler)) {
- // A movw / movt or mov / orr immediate load.
- instructions = CpuFeatures::IsSupported(ARMv7) ? 2 : 4;
+ DCHECK(CpuFeatures::IsSupported(ARMv7));
+ // A movw / movt immediate load.
+ instructions = 2;
} else {
// A small constant pool load.
instructions = 1;
@@ -1158,11 +1163,6 @@ int Operand::instructions_required(const Assembler* assembler,
void Assembler::move_32_bit_immediate(Register rd,
const Operand& x,
Condition cond) {
- uint32_t imm32 = static_cast<uint32_t>(x.imm32_);
- if (x.must_output_reloc_info(this)) {
- RecordRelocInfo(x.rmode_);
- }
-
if (use_mov_immediate_load(x, this)) {
// use_mov_immediate_load should return false when we need to output
// relocation info, since we prefer the constant pool for values that
@@ -1170,6 +1170,7 @@ void Assembler::move_32_bit_immediate(Register rd,
DCHECK(!x.must_output_reloc_info(this));
Register target = rd.code() == pc.code() ? ip : rd;
if (CpuFeatures::IsSupported(ARMv7)) {
+ uint32_t imm32 = static_cast<uint32_t>(x.imm32_);
CpuFeatureScope scope(this, ARMv7);
movw(target, imm32 & 0xffff, cond);
movt(target, imm32 >> 16, cond);
@@ -1178,10 +1179,7 @@ void Assembler::move_32_bit_immediate(Register rd,
mov(rd, target, LeaveCC, cond);
}
} else {
- ConstantPoolEntry::Access access =
- ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_);
- DCHECK(access == ConstantPoolEntry::REGULAR);
- USE(access);
+ ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_);
ldr(rd, MemOperand(pc, 0), cond);
}
}
@@ -2725,9 +2723,7 @@ void Assembler::vmov(const DwVfpRegister dst,
// The code could also randomize the order of values, though
// that's tricky because vldr has a limited reach. Furthermore
// it breaks load locality.
- ConstantPoolEntry::Access access = ConstantPoolAddEntry(pc_offset(), imm);
- DCHECK(access == ConstantPoolEntry::REGULAR);
- USE(access);
+ ConstantPoolAddEntry(pc_offset(), imm);
vldr(dst, MemOperand(pc, 0));
} else {
// Synthesise the double from ARM immediates.
@@ -5019,7 +5015,6 @@ void Assembler::emit_code_stub_address(Code* stub) {
pc_ += sizeof(uint32_t);
}
-
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
if (RelocInfo::IsNone(rmode) ||
// Don't record external references unless the heap will be serialized.
@@ -5036,41 +5031,86 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
reloc_info_writer.Write(&rinfo);
}
-
-ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position,
- RelocInfo::Mode rmode,
- intptr_t value) {
+void Assembler::ConstantPoolAddEntry(int position, RelocInfo::Mode rmode,
+ intptr_t value) {
DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::CONST_POOL &&
rmode != RelocInfo::NONE64);
bool sharing_ok = RelocInfo::IsNone(rmode) ||
- !(serializer_enabled() || rmode < RelocInfo::CELL);
+ (rmode >= RelocInfo::FIRST_SHAREABLE_RELOC_MODE);
DCHECK(pending_32_bit_constants_.size() < kMaxNumPending32Constants);
if (pending_32_bit_constants_.empty()) {
first_const_pool_32_use_ = position;
}
- ConstantPoolEntry entry(position, value, sharing_ok);
+ ConstantPoolEntry entry(
+ position, value,
+ sharing_ok || (rmode == RelocInfo::CODE_TARGET && serializer_enabled()));
+
+ bool shared = false;
+ if (sharing_ok) {
+ // Merge the constant, if possible.
+ for (size_t i = 0; i < pending_32_bit_constants_.size(); i++) {
+ ConstantPoolEntry& current_entry = pending_32_bit_constants_[i];
+ if (!current_entry.sharing_ok()) continue;
+ if (entry.value() == current_entry.value()) {
+ entry.set_merged_index(i);
+ shared = true;
+ break;
+ }
+ }
+ }
+
+ if (rmode == RelocInfo::CODE_TARGET && serializer_enabled()) {
+ // TODO(all): We only do this in the serializer, for now, because
+ // full-codegen relies on RelocInfo for translating PCs between full-codegen
+ // normal and debug code.
+ // Sharing entries here relies on canonicalized handles - without them, we
+ // will miss the optimisation opportunity.
+ Address handle_address = reinterpret_cast<Address>(value);
+ auto existing = handle_to_index_map_.find(handle_address);
+ if (existing != handle_to_index_map_.end()) {
+ int index = existing->second;
+ entry.set_merged_index(index);
+ shared = true;
+ } else {
+ // Keep track of this code handle.
+ handle_to_index_map_[handle_address] =
+ static_cast<int>(pending_32_bit_constants_.size());
+ }
+ }
+
pending_32_bit_constants_.push_back(entry);
// Make sure the constant pool is not emitted in place of the next
// instruction for which we just recorded relocation info.
BlockConstPoolFor(1);
- return ConstantPoolEntry::REGULAR;
-}
+ // Emit relocation info.
+ if (must_output_reloc_info(rmode, this) && !shared) {
+ RecordRelocInfo(rmode);
+ }
+}
-ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position,
- double value) {
+void Assembler::ConstantPoolAddEntry(int position, double value) {
DCHECK(pending_64_bit_constants_.size() < kMaxNumPending64Constants);
if (pending_64_bit_constants_.empty()) {
first_const_pool_64_use_ = position;
}
ConstantPoolEntry entry(position, value);
+
+ // Merge the constant, if possible.
+ for (size_t i = 0; i < pending_64_bit_constants_.size(); i++) {
+ ConstantPoolEntry& current_entry = pending_64_bit_constants_[i];
+ DCHECK(current_entry.sharing_ok());
+ if (entry.value() == current_entry.value()) {
+ entry.set_merged_index(i);
+ break;
+ }
+ }
pending_64_bit_constants_.push_back(entry);
// Make sure the constant pool is not emitted in place of the next
// instruction for which we just recorded relocation info.
BlockConstPoolFor(1);
- return ConstantPoolEntry::REGULAR;
}
@@ -5171,29 +5211,12 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
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];
- DCHECK(!entry.is_merged());
- for (size_t 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;
- }
- }
+ 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];
- DCHECK(!entry.is_merged());
- if (!entry.sharing_ok()) continue;
- for (size_t 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;
- }
- }
+ if (entry.is_merged()) size_after_marker -= kPointerSize;
}
int size = size_up_to_marker + size_after_marker;
@@ -5292,6 +5315,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
pending_32_bit_constants_.clear();
pending_64_bit_constants_.clear();
+ handle_to_index_map_.clear();
+
first_const_pool_32_use_ = -1;
first_const_pool_64_use_ = -1;
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-arm-inl.h » ('j') | src/disassembler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698