diff --git a/include/v8.h b/include/v8.h
index d7e6760d60..56fe98d404 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -6955,7 +6955,7 @@ class Internals {
static const int kNodeIsIndependentShift = 3;
static const int kNodeIsPartiallyDependentShift = 4;
- static const int kJSObjectType = 0xbf;
+ static const int kJSObjectType = 0xbe;
static const int kFirstNonstringType = 0x80;
static const int kOddballType = 0x83;
static const int kForeignType = 0x87;
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h
index 0b5ced5159..5e590a7d03 100644
--- a/src/arm/assembler-arm-inl.h
+++ b/src/arm/assembler-arm-inl.h
@@ -118,7 +118,7 @@ Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE);
- if (FLAG_enable_ool_constant_pool ||
+ if (FLAG_enable_embedded_constant_pool ||
Assembler::IsMovW(Memory::int32_at(pc_))) {
// We return the PC for ool constant pool since this function is used by the
// serializer and expects the address to reside within the code object.
@@ -545,7 +545,7 @@ Address Assembler::return_address_from_call_start(Address pc) {
void Assembler::deserialization_set_special_target_at(
Address constant_pool_entry, Code* code, Address target) {
- if (FLAG_enable_ool_constant_pool) {
+ if (FLAG_enable_embedded_constant_pool) {
set_target_address_at(constant_pool_entry, code, target);
} else {
Memory::Address_at(constant_pool_entry) = target;
@@ -562,21 +562,21 @@ void Assembler::deserialization_set_target_internal_reference_at(
bool Assembler::is_constant_pool_load(Address pc) {
if (CpuFeatures::IsSupported(ARMv7)) {
return !Assembler::IsMovW(Memory::int32_at(pc)) ||
- (FLAG_enable_ool_constant_pool &&
+ (FLAG_enable_embedded_constant_pool &&
Assembler::IsLdrPpRegOffset(
Memory::int32_at(pc + 2 * Assembler::kInstrSize)));
} else {
return !Assembler::IsMovImmed(Memory::int32_at(pc)) ||
- (FLAG_enable_ool_constant_pool &&
+ (FLAG_enable_embedded_constant_pool &&
Assembler::IsLdrPpRegOffset(
Memory::int32_at(pc + 4 * Assembler::kInstrSize)));
}
}
-Address Assembler::constant_pool_entry_address(
- Address pc, ConstantPoolArray* constant_pool) {
- if (FLAG_enable_ool_constant_pool) {
+Address Assembler::constant_pool_entry_address(Address pc,
+ Address constant_pool) {
+ if (FLAG_enable_embedded_constant_pool) {
DCHECK(constant_pool != NULL);
int cp_offset;
if (!CpuFeatures::IsSupported(ARMv7) && IsMovImmed(Memory::int32_at(pc))) {
@@ -604,7 +604,7 @@ Address Assembler::constant_pool_entry_address(
DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc)));
cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc));
}
- return reinterpret_cast
(constant_pool) + cp_offset;
+ return constant_pool + cp_offset;
} else {
DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc)));
Instr instr = Memory::int32_at(pc);
@@ -613,8 +613,7 @@ Address Assembler::constant_pool_entry_address(
}
-Address Assembler::target_address_at(Address pc,
- ConstantPoolArray* constant_pool) {
+Address Assembler::target_address_at(Address pc, Address constant_pool) {
if (is_constant_pool_load(pc)) {
// This is a constant pool lookup. Return the value in the constant pool.
return Memory::Address_at(constant_pool_entry_address(pc, constant_pool));
@@ -645,8 +644,7 @@ Address Assembler::target_address_at(Address pc,
}
-void Assembler::set_target_address_at(Address pc,
- ConstantPoolArray* constant_pool,
+void Assembler::set_target_address_at(Address pc, Address constant_pool,
Address target,
ICacheFlushMode icache_flush_mode) {
if (is_constant_pool_load(pc)) {
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 315eeb1b66..ed8664a9c5 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_(kLdrMaxReachBits, kVldrMaxReachBits),
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,23 @@ 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 constant_pool_offset = 0;
+ if (FLAG_enable_embedded_constant_pool) {
+ constant_pool_offset = EmitEmbeddedConstantPool();
+ } 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 =
+ (constant_pool_offset ? desc->instr_size - constant_pool_offset : 0);
desc->origin = this;
}
@@ -623,7 +629,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 +638,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 +1050,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,8 +1080,9 @@ 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()) {
- // An extended constant pool load.
+ } else if (assembler != NULL &&
+ assembler->ConstantPoolAccessIsInOverflow()) {
+ // An overflowed constant pool load.
instructions = CpuFeatures::IsSupported(ARMv7) ? 3 : 5;
} else {
// A small constant pool load.
@@ -1100,23 +1107,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(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 +1133,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 +1152,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 +2563,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 +2579,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.
@@ -3556,22 +3564,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);
}
@@ -3579,8 +3571,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(pc_) = data;
pc_ += sizeof(uint8_t);
@@ -3591,14 +3583,26 @@ 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(pc_) = data;
pc_ += sizeof(uint32_t);
}
+void Assembler::dq(uint64_t value) {
+ // No relocation info should be pending while using dq. dq is used
+ // to write pure data with no pointers and the constant pool should
+ // be emitted before using dd.
+ DCHECK(num_pending_32_bit_constants_ == 0);
+ DCHECK(num_pending_64_bit_constants_ == 0);
+ CheckBuffer();
+ *reinterpret_cast(pc_) = value;
+ pc_ += sizeof(uint64_t);
+}
+
+
void Assembler::emit_code_stub_address(Code* stub) {
CheckBuffer();
*reinterpret_cast(pc_) =
@@ -3608,64 +3612,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;
}
@@ -3674,10 +3687,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;
@@ -3690,10 +3704,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;
}
@@ -3707,8 +3721,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;
@@ -3719,15 +3733,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;
@@ -3744,9 +3758,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))) {
@@ -3788,60 +3801,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]
@@ -3849,16 +3854,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;
}
@@ -3866,18 +3870,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());
+ emit(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;
@@ -3894,225 +3899,56 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
}
-Handle 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::PatchConstantPoolAccessInstruction(
+ int pc_offset, int offset, ConstantPoolEntry::Access access,
+ ConstantPoolEntry::Type type) {
+ DCHECK(FLAG_enable_embedded_constant_pool);
+ Address pc = buffer_ + pc_offset;
-
-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);
-
- // 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::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::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 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(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::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(rinfo.data()));
- } else if (type == ConstantPoolArray::CODE_PTR) {
- constant_pool->set_at_offset(offset,
- reinterpret_cast(rinfo.data()));
- } else {
- DCHECK(type == ConstantPoolArray::HEAP_PTR);
- constant_pool->set_at_offset(offset,
- reinterpret_cast