Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 1ccc3a6..9633a63 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -57,7 +57,7 @@
answer |= 1u << ARMv8;
// ARMv8 always features VFP and NEON.
answer |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS;
- answer |= 1u << SUDIV | 1u << MLS;
+ answer |= 1u << SUDIV;
}
#endif // CAN_USE_ARMV8_INSTRUCTIONS
#ifdef CAN_USE_ARMV7_INSTRUCTIONS
@@ -93,7 +93,7 @@
supported_ |= 1u << ARMv8;
// ARMv8 always features VFP and NEON.
supported_ |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS;
- supported_ |= 1u << SUDIV | 1u << MLS;
+ supported_ |= 1u << SUDIV;
if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
}
if (FLAG_enable_armv7) {
@@ -104,7 +104,6 @@
if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS;
}
- if (FLAG_enable_mls) supported_ |= 1u << MLS;
if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
#else // __arm__
@@ -119,7 +118,6 @@
if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON;
if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV;
- if (FLAG_enable_mls && cpu.has_thumb2()) supported_ |= 1u << MLS;
if (cpu.architecture() >= 7) {
if (FLAG_enable_armv7) supported_ |= 1u << ARMv7;
@@ -203,12 +201,11 @@
void CpuFeatures::PrintFeatures() {
printf(
- "ARMv8=%d ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d MLS=%d"
+ "ARMv8=%d ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d "
"UNALIGNED_ACCESSES=%d MOVW_MOVT_IMMEDIATE_LOADS=%d",
CpuFeatures::IsSupported(ARMv8), CpuFeatures::IsSupported(ARMv7),
CpuFeatures::IsSupported(VFP3), CpuFeatures::IsSupported(VFP32DREGS),
CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV),
- CpuFeatures::IsSupported(MLS),
CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
#ifdef __arm__
@@ -252,31 +249,20 @@
return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_));
}
-void RelocInfo::update_wasm_memory_reference(
- Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
- ICacheFlushMode icache_flush_mode) {
- DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
- if (IsWasmMemoryReference(rmode_)) {
- Address updated_memory_reference;
- DCHECK(old_base <= wasm_memory_reference() &&
- wasm_memory_reference() < old_base + old_size);
- updated_memory_reference = new_base + (wasm_memory_reference() - old_base);
- DCHECK(new_base <= updated_memory_reference &&
- updated_memory_reference < new_base + new_size);
- Assembler::set_target_address_at(
- isolate_, pc_, host_, updated_memory_reference, icache_flush_mode);
- } else if (IsWasmMemorySizeReference(rmode_)) {
- uint32_t updated_size_reference;
- DCHECK(wasm_memory_size_reference() <= old_size);
- updated_size_reference =
- new_size + (wasm_memory_size_reference() - old_size);
- DCHECK(updated_size_reference <= new_size);
- Assembler::set_target_address_at(
- isolate_, pc_, host_, reinterpret_cast<Address>(updated_size_reference),
- icache_flush_mode);
- } else {
- UNREACHABLE();
- }
+Address RelocInfo::wasm_global_reference() {
+ DCHECK(IsWasmGlobalReference(rmode_));
+ return Assembler::target_address_at(pc_, host_);
+}
+
+void RelocInfo::unchecked_update_wasm_memory_reference(
+ Address address, ICacheFlushMode flush_mode) {
+ Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode);
+}
+
+void RelocInfo::unchecked_update_wasm_memory_size(uint32_t size,
+ ICacheFlushMode flush_mode) {
+ Assembler::set_target_address_at(isolate_, pc_, host_,
+ reinterpret_cast<Address>(size), flush_mode);
}
// -----------------------------------------------------------------------------
@@ -486,17 +472,16 @@
al | B26 | NegOffset | Register::kCode_fp * B16;
const Instr kLdrStrInstrTypeMask = 0xffff0000;
-
Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
: AssemblerBase(isolate, buffer, buffer_size),
recorded_ast_id_(TypeFeedbackId::None()),
- pending_32_bit_constants_(&pending_32_bit_constants_buffer_[0]),
- pending_64_bit_constants_(&pending_64_bit_constants_buffer_[0]),
+ pending_32_bit_constants_(),
+ pending_64_bit_constants_(),
constant_pool_builder_(kLdrMaxReachBits, kVldrMaxReachBits),
positions_recorder_(this) {
+ pending_32_bit_constants_.reserve(kMinNumPendingConstants);
+ pending_64_bit_constants_.reserve(kMinNumPendingConstants);
reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
- 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;
@@ -509,12 +494,6 @@
Assembler::~Assembler() {
DCHECK(const_pool_blocked_nesting_ == 0);
- if (pending_32_bit_constants_ != &pending_32_bit_constants_buffer_[0]) {
- delete[] pending_32_bit_constants_;
- }
- if (pending_64_bit_constants_ != &pending_64_bit_constants_buffer_[0]) {
- delete[] pending_64_bit_constants_;
- }
}
@@ -527,8 +506,8 @@
constant_pool_offset = EmitEmbeddedConstantPool();
} else {
CheckConstPool(true, false);
- DCHECK(num_pending_32_bit_constants_ == 0);
- DCHECK(num_pending_64_bit_constants_ == 0);
+ DCHECK(pending_32_bit_constants_.empty());
+ DCHECK(pending_64_bit_constants_.empty());
}
// Set up code descriptor.
desc->buffer = buffer_;
@@ -538,6 +517,8 @@
desc->constant_pool_size =
(constant_pool_offset ? desc->instr_size - constant_pool_offset : 0);
desc->origin = this;
+ desc->unwinding_info_size = 0;
+ desc->unwinding_info = nullptr;
}
@@ -851,6 +832,19 @@
// Load the position of the label relative to the generated code object
// pointer in a register.
+ // The existing code must be a single 24-bit label chain link, followed by
+ // nops encoding the destination register. See mov_label_offset.
+
+ // Extract the destination register from the first nop instructions.
+ Register dst =
+ Register::from_code(Instruction::RmValue(instr_at(pos + kInstrSize)));
+ // In addition to the 24-bit label chain link, we expect to find one nop for
+ // ARMv7 and above, or two nops for ARMv6. See mov_label_offset.
+ DCHECK(IsNop(instr_at(pos + kInstrSize), dst.code()));
+ if (!CpuFeatures::IsSupported(ARMv7)) {
+ DCHECK(IsNop(instr_at(pos + 2 * kInstrSize), dst.code()));
+ }
+
// Here are the instructions we need to emit:
// For ARMv7: target24 => target16_1:target16_0
// movw dst, #target16_0
@@ -860,10 +854,6 @@
// orr dst, dst, #target8_1 << 8
// orr dst, dst, #target8_2 << 16
- // We extract the destination register from the emitted nop instruction.
- Register dst = Register::from_code(
- Instruction::RmValue(instr_at(pos + kInstrSize)));
- DCHECK(IsNop(instr_at(pos + kInstrSize), dst.code()));
uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
DCHECK(is_uint24(target24));
if (is_uint8(target24)) {
@@ -1390,7 +1380,6 @@
void Assembler::bl(int branch_offset, Condition cond) {
- positions_recorder()->WriteRecordedPositions();
DCHECK((branch_offset & 3) == 0);
int imm24 = branch_offset >> 2;
CHECK(is_int24(imm24));
@@ -1399,7 +1388,6 @@
void Assembler::blx(int branch_offset) { // v5 and above
- positions_recorder()->WriteRecordedPositions();
DCHECK((branch_offset & 1) == 0);
int h = ((branch_offset & 2) >> 1)*B24;
int imm24 = branch_offset >> 2;
@@ -1409,14 +1397,12 @@
void Assembler::blx(Register target, Condition cond) { // v5 and above
- positions_recorder()->WriteRecordedPositions();
DCHECK(!target.is(pc));
emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
}
void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t
- positions_recorder()->WriteRecordedPositions();
DCHECK(!target.is(pc)); // use of pc is actually allowed, but discouraged
emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
}
@@ -1524,9 +1510,6 @@
void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
- if (dst.is(pc)) {
- positions_recorder()->WriteRecordedPositions();
- }
// Don't allow nop instructions in the form mov rn, rn to be generated using
// the mov instruction. They must be generated using nop(int/NopMarkerTypes)
// or MarkCode(int/NopMarkerTypes) pseudo instructions.
@@ -1609,7 +1592,7 @@
void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
Condition cond) {
DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
- DCHECK(IsEnabled(MLS));
+ DCHECK(IsEnabled(ARMv7));
emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -2015,9 +1998,6 @@
// Load/Store instructions.
void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
- if (dst.is(pc)) {
- positions_recorder()->WriteRecordedPositions();
- }
addrmod2(cond | B26 | L, dst, src);
}
@@ -2076,6 +2056,53 @@
addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
}
+// Load/Store exclusive instructions.
+void Assembler::ldrex(Register dst, Register src, Condition cond) {
+ // Instruction details available in ARM DDI 0406C.b, A8.8.75.
+ // cond(31-28) | 00011001(27-20) | Rn(19-16) | Rt(15-12) | 111110011111(11-0)
+ emit(cond | B24 | B23 | B20 | src.code() * B16 | dst.code() * B12 | 0xf9f);
+}
+
+void Assembler::strex(Register src1, Register src2, Register dst,
+ Condition cond) {
+ // Instruction details available in ARM DDI 0406C.b, A8.8.212.
+ // cond(31-28) | 00011000(27-20) | Rn(19-16) | Rd(15-12) | 11111001(11-4) |
+ // Rt(3-0)
+ emit(cond | B24 | B23 | dst.code() * B16 | src1.code() * B12 | 0xf9 * B4 |
+ src2.code());
+}
+
+void Assembler::ldrexb(Register dst, Register src, Condition cond) {
+ // Instruction details available in ARM DDI 0406C.b, A8.8.76.
+ // cond(31-28) | 00011101(27-20) | Rn(19-16) | Rt(15-12) | 111110011111(11-0)
+ emit(cond | B24 | B23 | B22 | B20 | src.code() * B16 | dst.code() * B12 |
+ 0xf9f);
+}
+
+void Assembler::strexb(Register src1, Register src2, Register dst,
+ Condition cond) {
+ // Instruction details available in ARM DDI 0406C.b, A8.8.213.
+ // cond(31-28) | 00011100(27-20) | Rn(19-16) | Rd(15-12) | 11111001(11-4) |
+ // Rt(3-0)
+ emit(cond | B24 | B23 | B22 | dst.code() * B16 | src1.code() * B12 |
+ 0xf9 * B4 | src2.code());
+}
+
+void Assembler::ldrexh(Register dst, Register src, Condition cond) {
+ // Instruction details available in ARM DDI 0406C.b, A8.8.78.
+ // cond(31-28) | 00011111(27-20) | Rn(19-16) | Rt(15-12) | 111110011111(11-0)
+ emit(cond | B24 | B23 | B22 | B21 | B20 | src.code() * B16 |
+ dst.code() * B12 | 0xf9f);
+}
+
+void Assembler::strexh(Register src1, Register src2, Register dst,
+ Condition cond) {
+ // Instruction details available in ARM DDI 0406C.b, A8.8.215.
+ // cond(31-28) | 00011110(27-20) | Rn(19-16) | Rd(15-12) | 11111001(11-4) |
+ // Rt(3-0)
+ emit(cond | B24 | B23 | B22 | B21 | dst.code() * B16 | src1.code() * B12 |
+ 0xf9 * B4 | src2.code());
+}
// Preload instructions.
void Assembler::pld(const MemOperand& address) {
@@ -3827,8 +3854,8 @@
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() || (num_pending_32_bit_constants_ == 0));
- DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0));
+ 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);
@@ -3838,8 +3865,8 @@
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() || (num_pending_32_bit_constants_ == 0));
- DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0));
+ 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);
@@ -3849,8 +3876,8 @@
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() || (num_pending_32_bit_constants_ == 0));
- DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0));
+ 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);
@@ -3893,21 +3920,12 @@
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) {
+ DCHECK(pending_32_bit_constants_.size() < kMaxNumPending32Constants);
+ if (pending_32_bit_constants_.empty()) {
first_const_pool_32_use_ = position;
- } else if (num_pending_32_bit_constants_ == kMinNumPendingConstants &&
- pending_32_bit_constants_ ==
- &pending_32_bit_constants_buffer_[0]) {
- // Inline buffer is full, switch to dynamically allocated buffer.
- pending_32_bit_constants_ =
- new ConstantPoolEntry[kMaxNumPending32Constants];
- std::copy(&pending_32_bit_constants_buffer_[0],
- &pending_32_bit_constants_buffer_[kMinNumPendingConstants],
- &pending_32_bit_constants_[0]);
}
ConstantPoolEntry entry(position, value, sharing_ok);
- pending_32_bit_constants_[num_pending_32_bit_constants_++] = entry;
+ 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.
@@ -3922,21 +3940,12 @@
if (FLAG_enable_embedded_constant_pool) {
return constant_pool_builder_.AddEntry(position, value);
} else {
- DCHECK(num_pending_64_bit_constants_ < kMaxNumPending64Constants);
- if (num_pending_64_bit_constants_ == 0) {
+ DCHECK(pending_64_bit_constants_.size() < kMaxNumPending64Constants);
+ if (pending_64_bit_constants_.empty()) {
first_const_pool_64_use_ = position;
- } else if (num_pending_64_bit_constants_ == kMinNumPendingConstants &&
- pending_64_bit_constants_ ==
- &pending_64_bit_constants_buffer_[0]) {
- // Inline buffer is full, switch to dynamically allocated buffer.
- pending_64_bit_constants_ =
- new ConstantPoolEntry[kMaxNumPending64Constants];
- std::copy(&pending_64_bit_constants_buffer_[0],
- &pending_64_bit_constants_buffer_[kMinNumPendingConstants],
- &pending_64_bit_constants_[0]);
}
ConstantPoolEntry entry(position, value);
- pending_64_bit_constants_[num_pending_64_bit_constants_++] = entry;
+ 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.
@@ -3949,8 +3958,8 @@
void Assembler::BlockConstPoolFor(int instructions) {
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);
+ DCHECK(pending_32_bit_constants_.empty());
+ DCHECK(pending_64_bit_constants_.empty());
return;
}
@@ -3959,11 +3968,11 @@
// 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_constants_ == 0) ||
+ DCHECK(pending_32_bit_constants_.empty() ||
(start - first_const_pool_32_use_ +
- num_pending_64_bit_constants_ * kDoubleSize <
+ pending_64_bit_constants_.size() * kDoubleSize <
kMaxDistToIntPool));
- DCHECK((num_pending_64_bit_constants_ == 0) ||
+ DCHECK(pending_64_bit_constants_.empty() ||
(start - first_const_pool_64_use_ < kMaxDistToFPPool));
#endif
no_const_pool_before_ = pc_limit;
@@ -3978,8 +3987,8 @@
void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
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);
+ DCHECK(pending_32_bit_constants_.empty());
+ DCHECK(pending_64_bit_constants_.empty());
return;
}
@@ -3993,8 +4002,7 @@
}
// There is nothing to do if there are no pending constant pool entries.
- if ((num_pending_32_bit_constants_ == 0) &&
- (num_pending_64_bit_constants_ == 0)) {
+ if (pending_32_bit_constants_.empty() && pending_64_bit_constants_.empty()) {
// Calculate the offset of the next check.
next_buffer_check_ = pc_offset() + kCheckPoolInterval;
return;
@@ -4006,9 +4014,9 @@
int jump_instr = require_jump ? kInstrSize : 0;
int size_up_to_marker = jump_instr + kInstrSize;
int estimated_size_after_marker =
- num_pending_32_bit_constants_ * kPointerSize;
- bool has_int_values = (num_pending_32_bit_constants_ > 0);
- bool has_fp_values = (num_pending_64_bit_constants_ > 0);
+ 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 =
@@ -4017,7 +4025,8 @@
if (require_64_bit_align) {
estimated_size_after_marker += kInstrSize;
}
- estimated_size_after_marker += num_pending_64_bit_constants_ * kDoubleSize;
+ estimated_size_after_marker +=
+ pending_64_bit_constants_.size() * kDoubleSize;
}
int estimated_size = size_up_to_marker + estimated_size_after_marker;
@@ -4036,7 +4045,7 @@
// 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 -
- num_pending_32_bit_constants_ * kPointerSize -
+ pending_32_bit_constants_.size() * kPointerSize -
first_const_pool_64_use_;
if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
(!require_jump && (dist64 >= kMaxDistToFPPool / 2))) {
@@ -4055,7 +4064,7 @@
// Deduplicate constants.
int size_after_marker = estimated_size_after_marker;
- for (int i = 0; i < num_pending_64_bit_constants_; i++) {
+ for (int i = 0; i < pending_64_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_64_bit_constants_[i];
DCHECK(!entry.is_merged());
for (int j = 0; j < i; j++) {
@@ -4068,7 +4077,7 @@
}
}
- for (int i = 0; i < num_pending_32_bit_constants_; i++) {
+ for (int 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;
@@ -4113,7 +4122,7 @@
// Emit 64-bit constant pool entries first: their range is smaller than
// 32-bit entries.
- for (int i = 0; i < num_pending_64_bit_constants_; i++) {
+ for (int i = 0; i < pending_64_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_64_bit_constants_[i];
Instr instr = instr_at(entry.position());
@@ -4142,7 +4151,7 @@
}
// Emit 32-bit constant pool entries.
- for (int i = 0; i < num_pending_32_bit_constants_; i++) {
+ for (int i = 0; i < pending_32_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_32_bit_constants_[i];
Instr instr = instr_at(entry.position());
@@ -4176,8 +4185,8 @@
}
}
- num_pending_32_bit_constants_ = 0;
- num_pending_64_bit_constants_ = 0;
+ pending_32_bit_constants_.clear();
+ pending_64_bit_constants_.clear();
first_const_pool_32_use_ = -1;
first_const_pool_64_use_ = -1;