| Index: src/arm/assembler-arm.cc
|
| diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
|
| index f2afa52eef6268ec64b9b8d5b40c15ec12bc5764..6932e973796b2c6d995f08ffb5b3d0214cc7dc73 100644
|
| --- a/src/arm/assembler-arm.cc
|
| +++ b/src/arm/assembler-arm.cc
|
| @@ -1093,23 +1093,24 @@
|
| 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 must_output_reloc_info(RelocInfo::Mode rmode, const Assembler* assembler) {
|
| - if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
|
| +bool Operand::must_output_reloc_info(const Assembler* assembler) const {
|
| + 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;
|
| }
|
|
|
| -bool use_mov_immediate_load(const Operand& x, const Assembler* assembler) {
|
| +
|
| +static 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.
|
| @@ -1120,11 +1121,6 @@
|
| }
|
| }
|
|
|
| -} // 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 {
|
| @@ -1138,9 +1134,8 @@
|
| // for the constant pool or immediate load
|
| int instructions;
|
| if (use_mov_immediate_load(*this, assembler)) {
|
| - DCHECK(CpuFeatures::IsSupported(ARMv7));
|
| - // A movw / movt immediate load.
|
| - instructions = 2;
|
| + // A movw / movt or mov / orr immediate load.
|
| + instructions = CpuFeatures::IsSupported(ARMv7) ? 2 : 4;
|
| } else {
|
| // A small constant pool load.
|
| instructions = 1;
|
| @@ -1163,6 +1158,11 @@
|
| 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,7 +1170,6 @@
|
| 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);
|
| @@ -1179,7 +1178,10 @@
|
| mov(rd, target, LeaveCC, cond);
|
| }
|
| } else {
|
| - ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_);
|
| + ConstantPoolEntry::Access access =
|
| + ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_);
|
| + DCHECK(access == ConstantPoolEntry::REGULAR);
|
| + USE(access);
|
| ldr(rd, MemOperand(pc, 0), cond);
|
| }
|
| }
|
| @@ -2723,7 +2725,9 @@
|
| // The code could also randomize the order of values, though
|
| // that's tricky because vldr has a limited reach. Furthermore
|
| // it breaks load locality.
|
| - ConstantPoolAddEntry(pc_offset(), imm);
|
| + ConstantPoolEntry::Access access = ConstantPoolAddEntry(pc_offset(), imm);
|
| + DCHECK(access == ConstantPoolEntry::REGULAR);
|
| + USE(access);
|
| vldr(dst, MemOperand(pc, 0));
|
| } else {
|
| // Synthesise the double from ARM immediates.
|
| @@ -5015,6 +5019,7 @@
|
| 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.
|
| @@ -5031,86 +5036,41 @@
|
| reloc_info_writer.Write(&rinfo);
|
| }
|
|
|
| -void Assembler::ConstantPoolAddEntry(int position, RelocInfo::Mode rmode,
|
| - intptr_t value) {
|
| +
|
| +ConstantPoolEntry::Access 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) ||
|
| - (rmode >= RelocInfo::FIRST_SHAREABLE_RELOC_MODE);
|
| + !(serializer_enabled() || rmode < RelocInfo::CELL);
|
| 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 || (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());
|
| - }
|
| - }
|
| -
|
| + ConstantPoolEntry entry(position, value, sharing_ok);
|
| 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);
|
| -
|
| - // Emit relocation info.
|
| - if (must_output_reloc_info(rmode, this) && !shared) {
|
| - RecordRelocInfo(rmode);
|
| - }
|
| -}
|
| -
|
| -void Assembler::ConstantPoolAddEntry(int position, double value) {
|
| + return ConstantPoolEntry::REGULAR;
|
| +}
|
| +
|
| +
|
| +ConstantPoolEntry::Access 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;
|
| }
|
|
|
|
|
| @@ -5211,12 +5171,29 @@
|
| 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;
|
| + 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;
|
| + }
|
| + }
|
| }
|
|
|
| for (size_t i = 0; i < pending_32_bit_constants_.size(); i++) {
|
| ConstantPoolEntry& entry = pending_32_bit_constants_[i];
|
| - if (entry.is_merged()) size_after_marker -= kPointerSize;
|
| + 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;
|
| + }
|
| + }
|
| }
|
|
|
| int size = size_up_to_marker + size_after_marker;
|
| @@ -5315,8 +5292,6 @@
|
|
|
| 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;
|
|
|
|
|