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

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

This is still incomplete, but already able to pass all tests on x64.
Sparkplug (on pointer compression) only generates two relocation types:
FULL_EMBEDDED_OBJECT and RUNTIME_ENTRY.

Bug: v8:11872
Change-Id: I6aefbbc9690511a06b2a4a942c48fef85d536bef
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3009221
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75605}
parent 819c3ae2
......@@ -409,6 +409,10 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
CodeCommentsWriter code_comments_writer_;
// Relocation information when code allocated directly on heap.
std::vector<std::pair<uint32_t, Address>> saved_handles_for_raw_object_ptr_;
std::vector<std::pair<uint32_t, uint32_t>> saved_offsets_for_runtime_entries_;
private:
// Before we copy code into the code space, we sometimes cannot encode
// call/jump code targets as we normally would, as the difference between the
......
......@@ -40,7 +40,14 @@ void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) {
DCHECK(RelocInfo::IsRuntimeEntry(rmode));
DCHECK_NE(options().code_range_start, 0);
RecordRelocInfo(rmode);
emitl(static_cast<uint32_t>(entry - options().code_range_start));
uint32_t offset = static_cast<uint32_t>(entry - options().code_range_start);
if (IsOnHeap()) {
saved_offsets_for_runtime_entries_.push_back(
std::make_pair(pc_offset(), offset));
emitl(relative_target_offset(entry, reinterpret_cast<Address>(pc_)));
} else {
emitl(offset);
}
}
void Assembler::emit(Immediate x) {
......@@ -53,6 +60,15 @@ void Assembler::emit(Immediate x) {
void Assembler::emit(Immediate64 x) {
if (!RelocInfo::IsNone(x.rmode_)) {
RecordRelocInfo(x.rmode_);
if (x.rmode_ == RelocInfo::FULL_EMBEDDED_OBJECT && IsOnHeap()) {
Address handle_address = reinterpret_cast<Address>(&x.value_);
Handle<HeapObject> object = Handle<HeapObject>::cast(
ReadUnalignedValue<Handle<Object>>(handle_address));
saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x.value_));
emitq(static_cast<uint64_t>(object->ptr()));
return;
}
}
emitq(static_cast<uint64_t>(x.value_));
}
......@@ -234,13 +250,18 @@ Address Assembler::target_address_at(Address pc, Address constant_pool) {
void Assembler::set_target_address_at(Address pc, Address constant_pool,
Address target,
ICacheFlushMode icache_flush_mode) {
DCHECK(is_int32(target - pc - 4));
WriteUnalignedValue(pc, static_cast<int32_t>(target - pc - 4));
WriteUnalignedValue(pc, relative_target_offset(target, pc));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
FlushInstructionCache(pc, sizeof(int32_t));
}
}
int32_t Assembler::relative_target_offset(Address target, Address pc) {
Address offset = target - pc - 4;
DCHECK(is_int32(offset));
return static_cast<int32_t>(offset);
}
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target, RelocInfo::Mode mode) {
WriteUnalignedValue(pc, target);
......
......@@ -536,6 +536,8 @@ bool Assembler::is_optimizable_farjmp(int idx) {
void Assembler::GrowBuffer() {
DCHECK(buffer_overflow());
bool previously_on_heap = buffer_->IsOnHeap();
// Compute new buffer size.
DCHECK_EQ(buffer_start_, buffer_->start());
int old_size = buffer_->size();
......@@ -573,6 +575,17 @@ void Assembler::GrowBuffer() {
WriteUnalignedValue(p, ReadUnalignedValue<intptr_t>(p) + pc_delta);
}
// 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);
}
for (auto p : saved_offsets_for_runtime_entries_) {
WriteUnalignedValue<uint32_t>(base + p.first, p.second);
}
}
DCHECK(!buffer_overflow());
}
......
......@@ -438,6 +438,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
static inline void set_target_address_at(
Address pc, Address constant_pool, Address target,
ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
static inline int32_t relative_target_offset(Address target, Address pc);
// This sets the branch destination (which is in the instruction on x64).
// This is for calls and branches within generated code.
......
......@@ -296,7 +296,6 @@ void Factory::CodeBuilder::FinalizeOnHeapCode(Handle<Code> code,
DCHECK(!heap->code_lo_space()->Contains(*code));
code->CopyRelocInfoToByteArray(reloc_info, code_desc_);
code->RelocateFromDesc(reloc_info, heap, code_desc_);
int old_object_size = Code::SizeFor(code_desc_.origin->buffer_size());
int new_object_size =
......
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