Chromium Code Reviews| Index: src/arm/assembler-arm.cc |
| diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc |
| index da1ab68a76d0ae1bf47d35444df3f51524ad314a..ceb5adf283d9af7cd467292992233a3fd91d266d 100644 |
| --- a/src/arm/assembler-arm.cc |
| +++ b/src/arm/assembler-arm.cc |
| @@ -234,9 +234,9 @@ const int RelocInfo::kApplyMask = 0; |
| bool RelocInfo::IsCodedSpecially() { |
| // The deserializer needs to know whether a pointer is specially coded. Being |
| // specially coded on ARM means that it is a movw/movt instruction, or is an |
| - // out of line constant pool entry. These only occur if |
| - // FLAG_enable_ool_constant_pool is true. |
| - return FLAG_enable_ool_constant_pool; |
| + // embedded constant pool entry. These only occur if |
| + // FLAG_enable_embedded_constant_pool is true. |
| + return FLAG_enable_embedded_constant_pool; |
| } |
| @@ -449,11 +449,11 @@ const Instr kLdrStrInstrTypeMask = 0xffff0000; |
| Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) |
| : AssemblerBase(isolate, buffer, buffer_size), |
| recorded_ast_id_(TypeFeedbackId::None()), |
| - constant_pool_builder_(), |
| + constant_pool_builder_(12, 10), |
|
rmcilroy
2015/05/20 14:32:10
make the '12' and '10' constants defined in const
MTBrandyberry
2015/05/20 22:28:21
Done.
|
| positions_recorder_(this) { |
| reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
| - num_pending_32_bit_reloc_info_ = 0; |
| - num_pending_64_bit_reloc_info_ = 0; |
| + num_pending_32_bit_constants_ = 0; |
| + num_pending_64_bit_constants_ = 0; |
| next_buffer_check_ = 0; |
| const_pool_blocked_nesting_ = 0; |
| no_const_pool_before_ = 0; |
| @@ -471,17 +471,22 @@ Assembler::~Assembler() { |
| void Assembler::GetCode(CodeDesc* desc) { |
| reloc_info_writer.Finish(); |
| - if (!FLAG_enable_ool_constant_pool) { |
| - // Emit constant pool if necessary. |
| + |
| + // Emit constant pool if necessary. |
| + int offset = 0; |
| + if (FLAG_enable_embedded_constant_pool) { |
| + offset = EmitConstantPool(); |
| + } else { |
| CheckConstPool(true, false); |
| - DCHECK(num_pending_32_bit_reloc_info_ == 0); |
| - DCHECK(num_pending_64_bit_reloc_info_ == 0); |
| + DCHECK(num_pending_32_bit_constants_ == 0); |
| + DCHECK(num_pending_64_bit_constants_ == 0); |
| } |
| // Set up code descriptor. |
| desc->buffer = buffer_; |
| desc->buffer_size = buffer_size_; |
| desc->instr_size = pc_offset(); |
| desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); |
| + desc->constant_pool_size = (offset ? desc->instr_size - offset : 0); |
| desc->origin = this; |
| } |
| @@ -623,7 +628,7 @@ Register Assembler::GetRm(Instr instr) { |
| Instr Assembler::GetConsantPoolLoadPattern() { |
| - if (FLAG_enable_ool_constant_pool) { |
| + if (FLAG_enable_embedded_constant_pool) { |
| return kLdrPpImmedPattern; |
| } else { |
| return kLdrPCImmedPattern; |
| @@ -632,7 +637,7 @@ Instr Assembler::GetConsantPoolLoadPattern() { |
| Instr Assembler::GetConsantPoolLoadMask() { |
| - if (FLAG_enable_ool_constant_pool) { |
| + if (FLAG_enable_embedded_constant_pool) { |
| return kLdrPpImmedMask; |
| } else { |
| return kLdrPCImmedMask; |
| @@ -1044,8 +1049,8 @@ bool Operand::must_output_reloc_info(const Assembler* assembler) const { |
| static bool use_mov_immediate_load(const Operand& x, |
| const Assembler* assembler) { |
| - if (FLAG_enable_ool_constant_pool && assembler != NULL && |
| - !assembler->is_ool_constant_pool_available()) { |
| + if (FLAG_enable_embedded_constant_pool && assembler != NULL && |
| + !assembler->is_constant_pool_available()) { |
| return true; |
| } else if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) && |
| (assembler == NULL || !assembler->predictable_code_size())) { |
| @@ -1074,7 +1079,7 @@ int Operand::instructions_required(const Assembler* assembler, |
| if (use_mov_immediate_load(*this, assembler)) { |
| // A movw / movt or mov / orr immediate load. |
| instructions = CpuFeatures::IsSupported(ARMv7) ? 2 : 4; |
| - } else if (assembler != NULL && assembler->use_extended_constant_pool()) { |
| + } else if (assembler != NULL && assembler->ConstantPoolOverflow()) { |
| // An extended constant pool load. |
|
rmcilroy
2015/05/20 14:32:10
update comment.
MTBrandyberry
2015/05/20 22:28:21
Done.
|
| instructions = CpuFeatures::IsSupported(ARMv7) ? 3 : 5; |
| } else { |
| @@ -1100,23 +1105,23 @@ int Operand::instructions_required(const Assembler* assembler, |
| void Assembler::move_32_bit_immediate(Register rd, |
| const Operand& x, |
| Condition cond) { |
| - RelocInfo rinfo(pc_, x.rmode_, x.imm32_, NULL); |
| uint32_t imm32 = static_cast<uint32_t>(x.imm32_); |
| if (x.must_output_reloc_info(this)) { |
| - RecordRelocInfo(rinfo); |
| + RecordRelocInfo(x.rmode_); |
| } |
| if (use_mov_immediate_load(x, this)) { |
| Register target = rd.code() == pc.code() ? ip : rd; |
| if (CpuFeatures::IsSupported(ARMv7)) { |
| - if (!FLAG_enable_ool_constant_pool && x.must_output_reloc_info(this)) { |
| + if (!FLAG_enable_embedded_constant_pool && |
| + x.must_output_reloc_info(this)) { |
| // Make sure the movw/movt doesn't get separated. |
| BlockConstPoolFor(2); |
| } |
| movw(target, imm32 & 0xffff, cond); |
| movt(target, imm32 >> 16, cond); |
| } else { |
| - DCHECK(FLAG_enable_ool_constant_pool); |
| + DCHECK(FLAG_enable_embedded_constant_pool); |
| mov(target, Operand(imm32 & kImm8Mask), LeaveCC, cond); |
| orr(target, target, Operand(imm32 & (kImm8Mask << 8)), LeaveCC, cond); |
| orr(target, target, Operand(imm32 & (kImm8Mask << 16)), LeaveCC, cond); |
| @@ -1126,10 +1131,11 @@ void Assembler::move_32_bit_immediate(Register rd, |
| mov(rd, target, LeaveCC, cond); |
| } |
| } else { |
| - DCHECK(!FLAG_enable_ool_constant_pool || is_ool_constant_pool_available()); |
| - ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo); |
| - if (section == ConstantPoolArray::EXTENDED_SECTION) { |
| - DCHECK(FLAG_enable_ool_constant_pool); |
| + DCHECK(!FLAG_enable_embedded_constant_pool || is_constant_pool_available()); |
| + ConstantPoolEntry::Access access = |
| + ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_); |
| + if (access == ConstantPoolEntry::OVERFLOWED) { |
| + DCHECK(FLAG_enable_embedded_constant_pool); |
| Register target = rd.code() == pc.code() ? ip : rd; |
| // Emit instructions to load constant pool offset. |
| if (CpuFeatures::IsSupported(ARMv7)) { |
| @@ -1144,8 +1150,9 @@ void Assembler::move_32_bit_immediate(Register rd, |
| // Load from constant pool at offset. |
| ldr(rd, MemOperand(pp, target), cond); |
| } else { |
| - DCHECK(section == ConstantPoolArray::SMALL_SECTION); |
| - ldr(rd, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0), cond); |
| + DCHECK(access == ConstantPoolEntry::REGULAR); |
| + ldr(rd, MemOperand(FLAG_enable_embedded_constant_pool ? pp : pc, 0), |
| + cond); |
| } |
| } |
| } |
| @@ -2554,7 +2561,7 @@ void Assembler::vmov(const DwVfpRegister dst, |
| int vd, d; |
| dst.split_code(&vd, &d); |
| emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); |
| - } else if (FLAG_enable_vldr_imm && is_ool_constant_pool_available()) { |
| + } else if (FLAG_enable_vldr_imm && is_constant_pool_available()) { |
| // TODO(jfb) Temporarily turned off until we have constant blinding or |
| // some equivalent mitigation: an attacker can otherwise control |
| // generated data which also happens to be executable, a Very Bad |
| @@ -2570,18 +2577,17 @@ 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. |
| - RelocInfo rinfo(pc_, imm); |
| - ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo); |
| - if (section == ConstantPoolArray::EXTENDED_SECTION) { |
| - DCHECK(FLAG_enable_ool_constant_pool); |
| + ConstantPoolEntry::Access access = ConstantPoolAddEntry(pc_offset(), imm); |
| + if (access == ConstantPoolEntry::OVERFLOWED) { |
| + DCHECK(FLAG_enable_embedded_constant_pool); |
| // Emit instructions to load constant pool offset. |
| movw(ip, 0); |
| movt(ip, 0); |
| // Load from constant pool at offset. |
| vldr(dst, MemOperand(pp, ip)); |
| } else { |
| - DCHECK(section == ConstantPoolArray::SMALL_SECTION); |
| - vldr(dst, MemOperand(FLAG_enable_ool_constant_pool ? pp : pc, 0)); |
| + DCHECK(access == ConstantPoolEntry::REGULAR); |
| + vldr(dst, MemOperand(FLAG_enable_embedded_constant_pool ? pp : pc, 0)); |
| } |
| } else { |
| // Synthesise the double from ARM immediates. |
| @@ -3555,22 +3561,6 @@ void Assembler::GrowBuffer() { |
| // None of our relocation types are pc relative pointing outside the code |
| // buffer nor pc absolute pointing inside the code buffer, so there is no need |
| // to relocate any emitted relocation entries. |
| - |
| - // Relocate pending relocation entries. |
| - for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { |
| - RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; |
| - DCHECK(rinfo.rmode() != RelocInfo::COMMENT && |
| - rinfo.rmode() != RelocInfo::POSITION); |
| - if (rinfo.rmode() != RelocInfo::JS_RETURN) { |
| - rinfo.set_pc(rinfo.pc() + pc_delta); |
| - } |
| - } |
| - for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) { |
| - RelocInfo& rinfo = pending_64_bit_reloc_info_[i]; |
| - DCHECK(rinfo.rmode() == RelocInfo::NONE64); |
| - rinfo.set_pc(rinfo.pc() + pc_delta); |
| - } |
| - constant_pool_builder_.Relocate(pc_delta); |
| } |
| @@ -3578,8 +3568,8 @@ void Assembler::db(uint8_t data) { |
| // No relocation info should be pending while using db. db is used |
| // to write pure data with no pointers and the constant pool should |
| // be emitted before using db. |
| - DCHECK(num_pending_32_bit_reloc_info_ == 0); |
| - DCHECK(num_pending_64_bit_reloc_info_ == 0); |
| + DCHECK(num_pending_32_bit_constants_ == 0); |
| + DCHECK(num_pending_64_bit_constants_ == 0); |
| CheckBuffer(); |
| *reinterpret_cast<uint8_t*>(pc_) = data; |
| pc_ += sizeof(uint8_t); |
| @@ -3590,14 +3580,21 @@ void Assembler::dd(uint32_t data) { |
| // No relocation info should be pending while using dd. dd is used |
| // to write pure data with no pointers and the constant pool should |
| // be emitted before using dd. |
| - DCHECK(num_pending_32_bit_reloc_info_ == 0); |
| - DCHECK(num_pending_64_bit_reloc_info_ == 0); |
| + DCHECK(num_pending_32_bit_constants_ == 0); |
| + DCHECK(num_pending_64_bit_constants_ == 0); |
| CheckBuffer(); |
| *reinterpret_cast<uint32_t*>(pc_) = data; |
| pc_ += sizeof(uint32_t); |
| } |
| +void Assembler::dq(uint64_t value) { |
| + CheckBuffer(); |
|
rmcilroy
2015/05/20 14:32:10
Please add the num_pending_xx_bit_constants_ == 0
MTBrandyberry
2015/05/20 22:28:21
Done.
|
| + *reinterpret_cast<uint64_t*>(pc_) = value; |
| + pc_ += sizeof(uint64_t); |
| +} |
| + |
| + |
| void Assembler::emit_code_stub_address(Code* stub) { |
| CheckBuffer(); |
| *reinterpret_cast<uint32_t*>(pc_) = |
| @@ -3607,64 +3604,73 @@ void Assembler::emit_code_stub_address(Code* stub) { |
| void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| + if (RelocInfo::IsNone(rmode) || |
| + // Don't record external references unless the heap will be serialized. |
| + (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() && |
| + !emit_debug_code())) { |
| + return; |
| + } |
| + DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here |
| + if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { |
| + data = RecordedAstId().ToInt(); |
| + ClearRecordedAstId(); |
| + } |
| RelocInfo rinfo(pc_, rmode, data, NULL); |
| - RecordRelocInfo(rinfo); |
| + reloc_info_writer.Write(&rinfo); |
| } |
| -void Assembler::RecordRelocInfo(const RelocInfo& rinfo) { |
| - if (!RelocInfo::IsNone(rinfo.rmode())) { |
| - // Don't record external references unless the heap will be serialized. |
| - if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE && |
| - !serializer_enabled() && !emit_debug_code()) { |
| - return; |
| - } |
| - DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here |
| - if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) { |
| - RelocInfo reloc_info_with_ast_id(rinfo.pc(), |
| - rinfo.rmode(), |
| - RecordedAstId().ToInt(), |
| - NULL); |
| - ClearRecordedAstId(); |
| - reloc_info_writer.Write(&reloc_info_with_ast_id); |
| - } else { |
| - reloc_info_writer.Write(&rinfo); |
| +ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, |
| + RelocInfo::Mode rmode, |
| + intptr_t value) { |
| + DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::POSITION && |
| + rmode != RelocInfo::STATEMENT_POSITION && |
| + rmode != RelocInfo::CONST_POOL && rmode != RelocInfo::NONE64); |
| + bool sharing_ok = RelocInfo::IsNone(rmode) || |
| + !(serializer_enabled() || rmode < RelocInfo::CELL); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + return constant_pool_builder_.AddEntry(position, value, sharing_ok); |
| + } else { |
| + DCHECK(num_pending_32_bit_constants_ < kMaxNumPending32Constants); |
| + if (num_pending_32_bit_constants_ == 0) { |
| + first_const_pool_32_use_ = position; |
| } |
| + ConstantPoolEntry entry(position, value, sharing_ok); |
| + pending_32_bit_constants_[num_pending_32_bit_constants_++] = 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; |
| } |
| } |
| -ConstantPoolArray::LayoutSection Assembler::ConstantPoolAddEntry( |
| - const RelocInfo& rinfo) { |
| - if (FLAG_enable_ool_constant_pool) { |
| - return constant_pool_builder_.AddEntry(this, rinfo); |
| +ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, |
| + double value) { |
| + if (FLAG_enable_embedded_constant_pool) { |
| + return constant_pool_builder_.AddEntry(position, value); |
| } else { |
| - if (rinfo.rmode() == RelocInfo::NONE64) { |
| - DCHECK(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo); |
| - if (num_pending_64_bit_reloc_info_ == 0) { |
| - first_const_pool_64_use_ = pc_offset(); |
| - } |
| - pending_64_bit_reloc_info_[num_pending_64_bit_reloc_info_++] = rinfo; |
| - } else { |
| - DCHECK(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo); |
| - if (num_pending_32_bit_reloc_info_ == 0) { |
| - first_const_pool_32_use_ = pc_offset(); |
| - } |
| - pending_32_bit_reloc_info_[num_pending_32_bit_reloc_info_++] = rinfo; |
| + DCHECK(num_pending_64_bit_constants_ < kMaxNumPending64Constants); |
| + if (num_pending_64_bit_constants_ == 0) { |
| + first_const_pool_64_use_ = position; |
| } |
| + ConstantPoolEntry entry(position, value); |
| + pending_64_bit_constants_[num_pending_64_bit_constants_++] = 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 ConstantPoolArray::SMALL_SECTION; |
| + return ConstantPoolEntry::REGULAR; |
| } |
| } |
| void Assembler::BlockConstPoolFor(int instructions) { |
| - if (FLAG_enable_ool_constant_pool) { |
| - // Should be a no-op if using an out-of-line constant pool. |
| - DCHECK(num_pending_32_bit_reloc_info_ == 0); |
| - DCHECK(num_pending_64_bit_reloc_info_ == 0); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + // Should be a no-op if using an embedded constant pool. |
| + DCHECK(num_pending_32_bit_constants_ == 0); |
| + DCHECK(num_pending_64_bit_constants_ == 0); |
| return; |
| } |
| @@ -3673,10 +3679,11 @@ void Assembler::BlockConstPoolFor(int instructions) { |
| // Max pool start (if we need a jump and an alignment). |
| #ifdef DEBUG |
| int start = pc_limit + kInstrSize + 2 * kPointerSize; |
| - DCHECK((num_pending_32_bit_reloc_info_ == 0) || |
| + DCHECK((num_pending_32_bit_constants_ == 0) || |
| (start - first_const_pool_32_use_ + |
| - num_pending_64_bit_reloc_info_ * kDoubleSize < kMaxDistToIntPool)); |
| - DCHECK((num_pending_64_bit_reloc_info_ == 0) || |
| + num_pending_64_bit_constants_ * kDoubleSize < |
| + kMaxDistToIntPool)); |
| + DCHECK((num_pending_64_bit_constants_ == 0) || |
| (start - first_const_pool_64_use_ < kMaxDistToFPPool)); |
| #endif |
| no_const_pool_before_ = pc_limit; |
| @@ -3689,10 +3696,10 @@ void Assembler::BlockConstPoolFor(int instructions) { |
| void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| - if (FLAG_enable_ool_constant_pool) { |
| - // Should be a no-op if using an out-of-line constant pool. |
| - DCHECK(num_pending_32_bit_reloc_info_ == 0); |
| - DCHECK(num_pending_64_bit_reloc_info_ == 0); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + // Should be a no-op if using an embedded constant pool. |
| + DCHECK(num_pending_32_bit_constants_ == 0); |
| + DCHECK(num_pending_64_bit_constants_ == 0); |
| return; |
| } |
| @@ -3706,8 +3713,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| } |
| // There is nothing to do if there are no pending constant pool entries. |
| - if ((num_pending_32_bit_reloc_info_ == 0) && |
| - (num_pending_64_bit_reloc_info_ == 0)) { |
| + if ((num_pending_32_bit_constants_ == 0) && |
| + (num_pending_64_bit_constants_ == 0)) { |
| // Calculate the offset of the next check. |
| next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
| return; |
| @@ -3718,15 +3725,15 @@ 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_reloc_info_ * kPointerSize; |
| - bool has_fp_values = (num_pending_64_bit_reloc_info_ > 0); |
| + int 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); |
| if (require_64_bit_align) { |
| size_after_marker += kInstrSize; |
| } |
| - size_after_marker += num_pending_64_bit_reloc_info_ * kDoubleSize; |
| + size_after_marker += num_pending_64_bit_constants_ * kDoubleSize; |
| } |
| int size = size_up_to_marker + size_after_marker; |
| @@ -3743,9 +3750,8 @@ 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 - |
| - num_pending_32_bit_reloc_info_ * kPointerSize - |
| + int dist64 = pc_offset() + size - |
| + num_pending_32_bit_constants_ * kPointerSize - |
| first_const_pool_64_use_; |
| if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) || |
| (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) { |
| @@ -3787,60 +3793,52 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| // Emit 64-bit constant pool entries first: their range is smaller than |
| // 32-bit entries. |
| - for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) { |
| - RelocInfo& rinfo = pending_64_bit_reloc_info_[i]; |
| + 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(rinfo.pc()); |
| + 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_ - rinfo.pc() - kPcLoadDelta; |
| + int delta = pc_offset() - entry.position() - kPcLoadDelta; |
| DCHECK(is_uint10(delta)); |
| bool found = false; |
| - uint64_t value = rinfo.raw_data64(); |
| + uint64_t value = entry.value64(); |
| for (int j = 0; j < i; j++) { |
| - RelocInfo& rinfo2 = pending_64_bit_reloc_info_[j]; |
| - if (value == rinfo2.raw_data64()) { |
| + ConstantPoolEntry& entry2 = pending_64_bit_constants_[j]; |
| + if (value == entry2.value64()) { |
| found = true; |
| - DCHECK(rinfo2.rmode() == RelocInfo::NONE64); |
| - Instr instr2 = instr_at(rinfo2.pc()); |
| + Instr instr2 = instr_at(entry2.position()); |
| DCHECK(IsVldrDPcImmediateOffset(instr2)); |
| delta = GetVldrDRegisterImmediateOffset(instr2); |
| - delta += rinfo2.pc() - rinfo.pc(); |
| + delta += entry2.position() - entry.position(); |
| break; |
| } |
| } |
| - instr_at_put(rinfo.pc(), SetVldrDRegisterImmediateOffset(instr, delta)); |
| + instr_at_put(entry.position(), |
| + SetVldrDRegisterImmediateOffset(instr, delta)); |
| if (!found) { |
| - uint64_t uint_data = rinfo.raw_data64(); |
| - emit(uint_data & 0xFFFFFFFF); |
| - emit(uint_data >> 32); |
| + dq(entry.value64()); |
| } |
| } |
| // Emit 32-bit constant pool entries. |
| - for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { |
| - RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; |
| - DCHECK(rinfo.rmode() != RelocInfo::COMMENT && |
| - rinfo.rmode() != RelocInfo::POSITION && |
| - rinfo.rmode() != RelocInfo::STATEMENT_POSITION && |
| - rinfo.rmode() != RelocInfo::CONST_POOL && |
| - rinfo.rmode() != RelocInfo::NONE64); |
| - |
| - Instr instr = instr_at(rinfo.pc()); |
| + for (int i = 0; i < num_pending_32_bit_constants_; i++) { |
| + ConstantPoolEntry& entry = pending_32_bit_constants_[i]; |
| + Instr instr = instr_at(entry.position()); |
| // 64-bit loads shouldn't get here. |
| DCHECK(!IsVldrDPcImmediateOffset(instr)); |
| if (IsLdrPcImmediateOffset(instr) && |
| GetLdrRegisterImmediateOffset(instr) == 0) { |
| - int delta = pc_ - rinfo.pc() - kPcLoadDelta; |
| + int delta = pc_offset() - entry.position() - kPcLoadDelta; |
| DCHECK(is_uint12(delta)); |
| // 0 is the smallest delta: |
| // ldr rd, [pc, #0] |
| @@ -3848,16 +3846,15 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| // data |
| bool found = false; |
| - if (!serializer_enabled() && rinfo.rmode() >= RelocInfo::CELL) { |
| + if (entry.sharing_ok()) { |
| for (int j = 0; j < i; j++) { |
| - RelocInfo& rinfo2 = pending_32_bit_reloc_info_[j]; |
| + ConstantPoolEntry& entry2 = pending_32_bit_constants_[j]; |
| - if ((rinfo2.data() == rinfo.data()) && |
| - (rinfo2.rmode() == rinfo.rmode())) { |
| - Instr instr2 = instr_at(rinfo2.pc()); |
| + if (entry2.value() == entry.value()) { |
| + Instr instr2 = instr_at(entry2.position()); |
| if (IsLdrPcImmediateOffset(instr2)) { |
| delta = GetLdrRegisterImmediateOffset(instr2); |
| - delta += rinfo2.pc() - rinfo.pc(); |
| + delta += entry2.position() - entry.position(); |
| found = true; |
| break; |
| } |
| @@ -3865,18 +3862,19 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| } |
| } |
| - instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta)); |
| + instr_at_put(entry.position(), |
| + SetLdrRegisterImmediateOffset(instr, delta)); |
| if (!found) { |
| - emit(rinfo.data()); |
| + dp(entry.value()); |
| } |
| } else { |
| DCHECK(IsMovW(instr)); |
| } |
| } |
| - num_pending_32_bit_reloc_info_ = 0; |
| - num_pending_64_bit_reloc_info_ = 0; |
| + num_pending_32_bit_constants_ = 0; |
| + num_pending_64_bit_constants_ = 0; |
| first_const_pool_32_use_ = -1; |
| first_const_pool_64_use_ = -1; |
| @@ -3893,225 +3891,56 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| } |
| -Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) { |
| - if (!FLAG_enable_ool_constant_pool) { |
| - return isolate->factory()->empty_constant_pool_array(); |
| - } |
| - return constant_pool_builder_.New(isolate); |
| -} |
| - |
| - |
| -void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
| - constant_pool_builder_.Populate(this, constant_pool); |
| -} |
| - |
| - |
| -ConstantPoolBuilder::ConstantPoolBuilder() |
| - : entries_(), current_section_(ConstantPoolArray::SMALL_SECTION) {} |
| - |
| - |
| -bool ConstantPoolBuilder::IsEmpty() { |
| - return entries_.size() == 0; |
| -} |
| - |
| - |
| -ConstantPoolArray::Type ConstantPoolBuilder::GetConstantPoolType( |
| - RelocInfo::Mode rmode) { |
| - if (rmode == RelocInfo::NONE64) { |
| - return ConstantPoolArray::INT64; |
| - } else if (!RelocInfo::IsGCRelocMode(rmode)) { |
| - return ConstantPoolArray::INT32; |
| - } else if (RelocInfo::IsCodeTarget(rmode)) { |
| - return ConstantPoolArray::CODE_PTR; |
| - } else { |
| - DCHECK(RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode)); |
| - return ConstantPoolArray::HEAP_PTR; |
| - } |
| -} |
| - |
| - |
| -ConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry( |
| - Assembler* assm, const RelocInfo& rinfo) { |
| - RelocInfo::Mode rmode = rinfo.rmode(); |
| - DCHECK(rmode != RelocInfo::COMMENT && |
| - rmode != RelocInfo::POSITION && |
| - rmode != RelocInfo::STATEMENT_POSITION && |
| - rmode != RelocInfo::CONST_POOL); |
| +void Assembler::SetConstantPoolOffset(int pos, int offset, |
|
rmcilroy
2015/05/20 14:32:10
I think this would be clearer as something like Pa
MTBrandyberry
2015/05/20 22:28:21
Done.
|
| + ConstantPoolEntry::Access access, |
| + ConstantPoolEntry::Type type) { |
| + DCHECK(FLAG_enable_embedded_constant_pool); |
| + Address pc = buffer_ + pos; |
| - // Try to merge entries which won't be patched. |
| - int merged_index = -1; |
| - ConstantPoolArray::LayoutSection entry_section = current_section_; |
| - if (RelocInfo::IsNone(rmode) || |
| - (!assm->serializer_enabled() && (rmode >= RelocInfo::CELL))) { |
| - size_t i; |
| - std::vector<ConstantPoolEntry>::const_iterator it; |
| - for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) { |
| - if (RelocInfo::IsEqual(rinfo, it->rinfo_)) { |
| - // Merge with found entry. |
| - merged_index = i; |
| - entry_section = entries_[i].section_; |
| - break; |
| - } |
| - } |
| - } |
| - DCHECK(entry_section <= current_section_); |
| - entries_.push_back(ConstantPoolEntry(rinfo, entry_section, merged_index)); |
| - |
| - if (merged_index == -1) { |
| - // Not merged, so update the appropriate count. |
| - number_of_entries_[entry_section].increment(GetConstantPoolType(rmode)); |
| - } |
| - |
| - // Check if we still have room for another entry in the small section |
| - // given Arm's ldr and vldr immediate offset range. |
| - if (current_section_ == ConstantPoolArray::SMALL_SECTION && |
| - !(is_uint12(ConstantPoolArray::SizeFor(*small_entries())) && |
| - is_uint10(ConstantPoolArray::MaxInt64Offset( |
| - small_entries()->count_of(ConstantPoolArray::INT64))))) { |
| - current_section_ = ConstantPoolArray::EXTENDED_SECTION; |
| - } |
| - return entry_section; |
| -} |
| - |
| - |
| -void ConstantPoolBuilder::Relocate(int pc_delta) { |
| - for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin(); |
| - entry != entries_.end(); entry++) { |
| - DCHECK(entry->rinfo_.rmode() != RelocInfo::JS_RETURN); |
| - entry->rinfo_.set_pc(entry->rinfo_.pc() + pc_delta); |
| - } |
| -} |
| - |
| - |
| -Handle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) { |
| - if (IsEmpty()) { |
| - return isolate->factory()->empty_constant_pool_array(); |
| - } else if (extended_entries()->is_empty()) { |
| - return isolate->factory()->NewConstantPoolArray(*small_entries()); |
| - } else { |
| - DCHECK(current_section_ == ConstantPoolArray::EXTENDED_SECTION); |
| - return isolate->factory()->NewExtendedConstantPoolArray( |
| - *small_entries(), *extended_entries()); |
| - } |
| -} |
| - |
| - |
| -void ConstantPoolBuilder::Populate(Assembler* assm, |
| - ConstantPoolArray* constant_pool) { |
| - DCHECK_EQ(extended_entries()->is_empty(), |
| - !constant_pool->is_extended_layout()); |
| - DCHECK(small_entries()->equals(ConstantPoolArray::NumberOfEntries( |
| - constant_pool, ConstantPoolArray::SMALL_SECTION))); |
| - if (constant_pool->is_extended_layout()) { |
| - DCHECK(extended_entries()->equals(ConstantPoolArray::NumberOfEntries( |
| - constant_pool, ConstantPoolArray::EXTENDED_SECTION))); |
| - } |
| - |
| - // Set up initial offsets. |
| - int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS] |
| - [ConstantPoolArray::NUMBER_OF_TYPES]; |
| - for (int section = 0; section <= constant_pool->final_section(); section++) { |
| - int section_start = (section == ConstantPoolArray::EXTENDED_SECTION) |
| - ? small_entries()->total_count() |
| - : 0; |
| - for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) { |
| - ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i); |
| - if (number_of_entries_[section].count_of(type) != 0) { |
| - offsets[section][type] = constant_pool->OffsetOfElementAt( |
| - number_of_entries_[section].base_of(type) + section_start); |
| - } |
| - } |
| - } |
| - |
| - for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin(); |
| - entry != entries_.end(); entry++) { |
| - RelocInfo rinfo = entry->rinfo_; |
| - RelocInfo::Mode rmode = entry->rinfo_.rmode(); |
| - ConstantPoolArray::Type type = GetConstantPoolType(rmode); |
| - |
| - // Update constant pool if necessary and get the entry's offset. |
| - int offset; |
| - if (entry->merged_index_ == -1) { |
| - offset = offsets[entry->section_][type]; |
| - offsets[entry->section_][type] += ConstantPoolArray::entry_size(type); |
| - if (type == ConstantPoolArray::INT64) { |
| - constant_pool->set_at_offset(offset, rinfo.data64()); |
| - } else if (type == ConstantPoolArray::INT32) { |
| - constant_pool->set_at_offset(offset, |
| - static_cast<int32_t>(rinfo.data())); |
| - } else if (type == ConstantPoolArray::CODE_PTR) { |
| - constant_pool->set_at_offset(offset, |
| - reinterpret_cast<Address>(rinfo.data())); |
| - } else { |
| - DCHECK(type == ConstantPoolArray::HEAP_PTR); |
| - constant_pool->set_at_offset(offset, |
| - reinterpret_cast<Object*>(rinfo.data())); |
| - } |
| - offset -= kHeapObjectTag; |
| - entry->merged_index_ = offset; // Stash offset for merged entries. |
| - } else { |
| - DCHECK(entry->merged_index_ < (entry - entries_.begin())); |
| - offset = entries_[entry->merged_index_].merged_index_; |
| - } |
| - |
| - // Patch vldr/ldr instruction with correct offset. |
| - Instr instr = assm->instr_at(rinfo.pc()); |
| - if (entry->section_ == ConstantPoolArray::EXTENDED_SECTION) { |
| - if (CpuFeatures::IsSupported(ARMv7)) { |
| - // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0]. |
| - Instr next_instr = assm->instr_at(rinfo.pc() + Assembler::kInstrSize); |
| - DCHECK((Assembler::IsMovW(instr) && |
| - Instruction::ImmedMovwMovtValue(instr) == 0)); |
| - DCHECK((Assembler::IsMovT(next_instr) && |
| - Instruction::ImmedMovwMovtValue(next_instr) == 0)); |
| - assm->instr_at_put( |
| - rinfo.pc(), Assembler::PatchMovwImmediate(instr, offset & 0xffff)); |
| - assm->instr_at_put( |
| - rinfo.pc() + Assembler::kInstrSize, |
| - Assembler::PatchMovwImmediate(next_instr, offset >> 16)); |
| - } else { |
| - // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0]. |
| - Instr instr_2 = assm->instr_at(rinfo.pc() + Assembler::kInstrSize); |
| - Instr instr_3 = assm->instr_at(rinfo.pc() + 2 * Assembler::kInstrSize); |
| - Instr instr_4 = assm->instr_at(rinfo.pc() + 3 * Assembler::kInstrSize); |
| - DCHECK((Assembler::IsMovImmed(instr) && |
| - Instruction::Immed8Value(instr) == 0)); |
| - DCHECK((Assembler::IsOrrImmed(instr_2) && |
| - Instruction::Immed8Value(instr_2) == 0) && |
| - Assembler::GetRn(instr_2).is(Assembler::GetRd(instr_2))); |
| - DCHECK((Assembler::IsOrrImmed(instr_3) && |
| - Instruction::Immed8Value(instr_3) == 0) && |
| - Assembler::GetRn(instr_3).is(Assembler::GetRd(instr_3))); |
| - DCHECK((Assembler::IsOrrImmed(instr_4) && |
| - Instruction::Immed8Value(instr_4) == 0) && |
| - Assembler::GetRn(instr_4).is(Assembler::GetRd(instr_4))); |
| - assm->instr_at_put( |
| - rinfo.pc(), Assembler::PatchShiftImm(instr, (offset & kImm8Mask))); |
| - assm->instr_at_put( |
| - rinfo.pc() + Assembler::kInstrSize, |
| - Assembler::PatchShiftImm(instr_2, (offset & (kImm8Mask << 8)))); |
| - assm->instr_at_put( |
| - rinfo.pc() + 2 * Assembler::kInstrSize, |
| - Assembler::PatchShiftImm(instr_3, (offset & (kImm8Mask << 16)))); |
| - assm->instr_at_put( |
| - rinfo.pc() + 3 * Assembler::kInstrSize, |
| - Assembler::PatchShiftImm(instr_4, (offset & (kImm8Mask << 24)))); |
| - } |
| - } else if (type == ConstantPoolArray::INT64) { |
| - // Instruction to patch must be 'vldr rd, [pp, #0]'. |
| - DCHECK((Assembler::IsVldrDPpImmediateOffset(instr) && |
| - Assembler::GetVldrDRegisterImmediateOffset(instr) == 0)); |
| - DCHECK(is_uint10(offset)); |
| - assm->instr_at_put(rinfo.pc(), Assembler::SetVldrDRegisterImmediateOffset( |
| - instr, offset)); |
| + // Patch vldr/ldr instruction with correct offset. |
| + Instr instr = instr_at(pc); |
| + if (access == ConstantPoolEntry::OVERFLOWED) { |
| + if (CpuFeatures::IsSupported(ARMv7)) { |
| + // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0]. |
| + Instr next_instr = instr_at(pc + kInstrSize); |
| + DCHECK((IsMovW(instr) && Instruction::ImmedMovwMovtValue(instr) == 0)); |
| + DCHECK((IsMovT(next_instr) && |
| + Instruction::ImmedMovwMovtValue(next_instr) == 0)); |
| + instr_at_put(pc, PatchMovwImmediate(instr, offset & 0xffff)); |
| + instr_at_put(pc + kInstrSize, |
| + PatchMovwImmediate(next_instr, offset >> 16)); |
| } else { |
| - // Instruction to patch must be 'ldr rd, [pp, #0]'. |
| - DCHECK((Assembler::IsLdrPpImmediateOffset(instr) && |
| - Assembler::GetLdrRegisterImmediateOffset(instr) == 0)); |
| - DCHECK(is_uint12(offset)); |
| - assm->instr_at_put( |
| - rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset)); |
| + // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0]. |
| + Instr instr_2 = instr_at(pc + kInstrSize); |
| + Instr instr_3 = instr_at(pc + 2 * kInstrSize); |
| + Instr instr_4 = instr_at(pc + 3 * kInstrSize); |
| + DCHECK((IsMovImmed(instr) && Instruction::Immed8Value(instr) == 0)); |
| + DCHECK((IsOrrImmed(instr_2) && Instruction::Immed8Value(instr_2) == 0) && |
| + GetRn(instr_2).is(GetRd(instr_2))); |
| + DCHECK((IsOrrImmed(instr_3) && Instruction::Immed8Value(instr_3) == 0) && |
| + GetRn(instr_3).is(GetRd(instr_3))); |
| + DCHECK((IsOrrImmed(instr_4) && Instruction::Immed8Value(instr_4) == 0) && |
| + GetRn(instr_4).is(GetRd(instr_4))); |
| + instr_at_put(pc, PatchShiftImm(instr, (offset & kImm8Mask))); |
| + instr_at_put(pc + kInstrSize, |
| + PatchShiftImm(instr_2, (offset & (kImm8Mask << 8)))); |
| + instr_at_put(pc + 2 * kInstrSize, |
| + PatchShiftImm(instr_3, (offset & (kImm8Mask << 16)))); |
| + instr_at_put(pc + 3 * kInstrSize, |
| + PatchShiftImm(instr_4, (offset & (kImm8Mask << 24)))); |
| } |
| + } else if (type == ConstantPoolEntry::DOUBLE) { |
| + // Instruction to patch must be 'vldr rd, [pp, #0]'. |
| + DCHECK((IsVldrDPpImmediateOffset(instr) && |
| + GetVldrDRegisterImmediateOffset(instr) == 0)); |
| + DCHECK(is_uint10(offset)); |
| + instr_at_put(pc, SetVldrDRegisterImmediateOffset(instr, offset)); |
| + } else { |
| + // Instruction to patch must be 'ldr rd, [pp, #0]'. |
| + DCHECK((IsLdrPpImmediateOffset(instr) && |
| + GetLdrRegisterImmediateOffset(instr) == 0)); |
| + DCHECK(is_uint12(offset)); |
| + instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
| } |
| } |