Commit a3b24ecc authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[baseline][arm] Remove initial relocation when compiling on heap

Port of https://chromium-review.googlesource.com/c/v8/v8/+/3024146 to arm.

Adds DCHECKs after emitting any code on the heap.

Bug: v8:11872
Change-Id: Ia8186143e3caca17a25f8fb23c378e64cc248095
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3024158Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75721}
parent 72c8f3fb
...@@ -5175,6 +5175,8 @@ void Assembler::RecordConstPool(int size) { ...@@ -5175,6 +5175,8 @@ void Assembler::RecordConstPool(int size) {
void Assembler::GrowBuffer() { void Assembler::GrowBuffer() {
DCHECK_EQ(buffer_start_, buffer_->start()); DCHECK_EQ(buffer_start_, buffer_->start());
bool previously_on_heap = buffer_->IsOnHeap();
// Compute new buffer size. // Compute new buffer size.
int old_size = buffer_->size(); int old_size = buffer_->size();
int new_size = std::min(2 * old_size, old_size + 1 * MB); int new_size = std::min(2 * old_size, old_size + 1 * MB);
...@@ -5207,6 +5209,14 @@ void Assembler::GrowBuffer() { ...@@ -5207,6 +5209,14 @@ void Assembler::GrowBuffer() {
reinterpret_cast<Address>(reloc_info_writer.last_pc()) + pc_delta); reinterpret_cast<Address>(reloc_info_writer.last_pc()) + pc_delta);
reloc_info_writer.Reposition(new_reloc_start, new_last_pc); reloc_info_writer.Reposition(new_reloc_start, new_last_pc);
// Patch on-heap references to handles.
if (previously_on_heap && !buffer_->IsOnHeap()) {
Address base = reinterpret_cast<Address>(buffer_->start());
for (auto p : saved_handles_for_raw_object_ptr_) {
WriteUnalignedValue(base + p.first, p.second);
}
}
// None of our relocation types are pc relative pointing outside the code // 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 // buffer nor pc absolute pointing inside the code buffer, so there is no need
// to relocate any emitted relocation entries. // to relocate any emitted relocation entries.
...@@ -5400,6 +5410,13 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { ...@@ -5400,6 +5410,13 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
CHECK_LE(pc_offset(), CHECK_LE(pc_offset(),
first_const_pool_32_use_ + kMaxDistToPcRelativeConstant); first_const_pool_32_use_ + kMaxDistToPcRelativeConstant);
// Check that the code buffer is large enough before emitting the constant
// pool (this includes the gap to the relocation information).
int needed_space = pending_32_bit_constants_.size() * kPointerSize + kGap;
while (buffer_space() <= needed_space) {
GrowBuffer();
}
// Emit 32-bit constant pool entries. // Emit 32-bit constant pool entries.
for (size_t i = 0; i < pending_32_bit_constants_.size(); i++) { for (size_t i = 0; i < pending_32_bit_constants_.size(); i++) {
ConstantPoolEntry& entry = pending_32_bit_constants_[i]; ConstantPoolEntry& entry = pending_32_bit_constants_[i];
...@@ -5432,7 +5449,17 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { ...@@ -5432,7 +5449,17 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
instr_at_put(entry.position(), instr_at_put(entry.position(),
SetLdrRegisterImmediateOffset(instr, delta)); SetLdrRegisterImmediateOffset(instr, delta));
if (!entry.is_merged()) { if (!entry.is_merged()) {
emit(entry.value()); if (IsOnHeap() && RelocInfo::IsEmbeddedObjectMode(entry.rmode())) {
saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), entry.value()));
Handle<HeapObject> handle(reinterpret_cast<Address*>(entry.value()));
emit(handle->ptr());
// We must ensure that `emit` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(IsOnHeap());
} else {
emit(entry.value());
}
} }
} }
......
...@@ -358,6 +358,9 @@ void ConstantPool::Emit(const ConstantPoolKey& key) { ...@@ -358,6 +358,9 @@ void ConstantPool::Emit(const ConstantPoolKey& key) {
std::make_pair(assm_->pc_offset(), key.value64())); std::make_pair(assm_->pc_offset(), key.value64()));
Handle<Object> handle = assm_->GetEmbeddedObject(key.value64()); Handle<Object> handle = assm_->GetEmbeddedObject(key.value64());
assm_->dq(handle->ptr()); assm_->dq(handle->ptr());
// We must ensure that `dq` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(assm_->IsOnHeap());
} else { } else {
assm_->dq(key.value64()); assm_->dq(key.value64());
} }
......
...@@ -190,6 +190,9 @@ void Assembler::emit(uint32_t x, RelocInfo::Mode rmode) { ...@@ -190,6 +190,9 @@ void Assembler::emit(uint32_t x, RelocInfo::Mode rmode) {
saved_handles_for_raw_object_ptr_.push_back( saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x)); std::make_pair(pc_offset(), x));
emit(object->ptr()); emit(object->ptr());
// We must ensure that `emit` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(IsOnHeap());
return; return;
} }
} }
...@@ -216,6 +219,9 @@ void Assembler::emit(const Immediate& x) { ...@@ -216,6 +219,9 @@ void Assembler::emit(const Immediate& x) {
saved_handles_for_raw_object_ptr_.push_back( saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x.immediate())); std::make_pair(pc_offset(), x.immediate()));
emit(x.embedded_object()->ptr()); emit(x.embedded_object()->ptr());
// We must ensure that `emit` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(IsOnHeap());
return; return;
} }
emit(x.immediate()); emit(x.immediate());
......
...@@ -45,6 +45,9 @@ void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { ...@@ -45,6 +45,9 @@ void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) {
saved_offsets_for_runtime_entries_.push_back( saved_offsets_for_runtime_entries_.push_back(
std::make_pair(pc_offset(), offset)); std::make_pair(pc_offset(), offset));
emitl(relative_target_offset(entry, reinterpret_cast<Address>(pc_))); emitl(relative_target_offset(entry, reinterpret_cast<Address>(pc_)));
// We must ensure that `emitl` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(IsOnHeap());
} else { } else {
emitl(offset); emitl(offset);
} }
...@@ -67,6 +70,9 @@ void Assembler::emit(Immediate64 x) { ...@@ -67,6 +70,9 @@ void Assembler::emit(Immediate64 x) {
saved_handles_for_raw_object_ptr_.push_back( saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x.value_)); std::make_pair(pc_offset(), x.value_));
emitq(static_cast<uint64_t>(object->ptr())); emitq(static_cast<uint64_t>(object->ptr()));
// We must ensure that `emitq` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(IsOnHeap());
return; return;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment