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

[baseline] Adds EmbeddedObjectMatches

This checks if we have emitted the correct constant. If for wherever
reason we grow the assembler buffer and fall back to off-heap
compilation, we must ensure that we have in the buffer a pointer to the
object handle (or the index in embedded_objects_ for arm64).

Bug: v8:11872
Change-Id: If989727206f8ee0fd0035307d2dadc8424676b2a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3030708
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75741}
parent 274eb226
......@@ -5450,13 +5450,12 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
SetLdrRegisterImmediateOffset(instr, delta));
if (!entry.is_merged()) {
if (IsOnHeap() && RelocInfo::IsEmbeddedObjectMode(entry.rmode())) {
int offset = pc_offset();
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());
std::make_pair(offset, entry.value()));
Handle<HeapObject> object(reinterpret_cast<Address*>(entry.value()));
emit(object->ptr());
DCHECK(EmbeddedObjectMatches(offset, object));
} else {
emit(entry.value());
}
......
......@@ -1187,6 +1187,13 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
}
}
#ifdef DEBUG
bool EmbeddedObjectMatches(int pc_offset, Handle<Object> object) {
return *reinterpret_cast<uint32_t*>(buffer_->start() + pc_offset) ==
(IsOnHeap() ? object->ptr() : object.address());
}
#endif
// Move a 32-bit immediate into a register, potentially via the constant pool.
void Move32BitImmediate(Register rd, const Operand& x, Condition cond = al);
......
......@@ -2676,6 +2676,12 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
static size_t GetApproxMaxDistToConstPoolForTesting() {
return ConstantPool::kApproxDistToPool64;
}
bool EmbeddedObjectMatches(int pc_offset, Handle<Object> object,
EmbeddedObjectIndex index) {
return *reinterpret_cast<uint64_t*>(buffer_->start() + pc_offset) ==
(IsOnHeap() ? object->ptr() : index);
}
#endif
class FarBranchInfo {
......
......@@ -354,13 +354,13 @@ void ConstantPool::Emit(const ConstantPoolKey& key) {
assm_->dd(key.value32());
} else {
if (assm_->IsOnHeap() && RelocInfo::IsEmbeddedObjectMode(key.rmode())) {
int offset = assm_->pc_offset();
Assembler::EmbeddedObjectIndex index = key.value64();
assm_->saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(assm_->pc_offset(), key.value64()));
Handle<Object> handle = assm_->GetEmbeddedObject(key.value64());
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());
std::make_pair(offset, index));
Handle<Object> object = assm_->GetEmbeddedObject(index);
assm_->dq(object->ptr());
DCHECK(assm_->EmbeddedObjectMatches(offset, object, index));
} else {
assm_->dq(key.value64());
}
......
......@@ -186,13 +186,11 @@ void Assembler::emit(uint32_t x, RelocInfo::Mode rmode) {
if (!RelocInfo::IsNone(rmode)) {
RecordRelocInfo(rmode);
if (rmode == RelocInfo::FULL_EMBEDDED_OBJECT && IsOnHeap()) {
int offset = pc_offset();
Handle<HeapObject> object(reinterpret_cast<Address*>(x));
saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x));
saved_handles_for_raw_object_ptr_.push_back(std::make_pair(offset, x));
emit(object->ptr());
// We must ensure that `emit` is not growing the assembler buffer
// and falling back to off-heap compilation.
DCHECK(IsOnHeap());
DCHECK(EmbeddedObjectMatches(offset, object));
return;
}
}
......@@ -216,12 +214,11 @@ void Assembler::emit(const Immediate& x) {
return;
}
if (x.is_embedded_object() && IsOnHeap()) {
int offset = pc_offset();
saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x.immediate()));
std::make_pair(offset, x.immediate()));
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());
DCHECK(EmbeddedObjectMatches(offset, x.embedded_object()));
return;
}
emit(x.immediate());
......
......@@ -397,6 +397,13 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// Unused on this architecture.
void MaybeEmitOutOfLineConstantPool() {}
#ifdef DEBUG
bool EmbeddedObjectMatches(int pc_offset, Handle<Object> object) {
return *reinterpret_cast<uint32_t*>(buffer_->start() + pc_offset) ==
(IsOnHeap() ? object->ptr() : object.address());
}
#endif
// Read/Modify the code target in the branch/call instruction at pc.
// The isolate argument is unused (and may be nullptr) when skipping flushing.
inline static Address target_address_at(Address pc, Address constant_pool);
......
......@@ -64,15 +64,12 @@ 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));
int offset = pc_offset();
Handle<HeapObject> object(reinterpret_cast<Address*>(x.value_));
saved_handles_for_raw_object_ptr_.push_back(
std::make_pair(pc_offset(), x.value_));
std::make_pair(offset, x.value_));
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());
DCHECK(EmbeddedObjectMatches(offset, object));
return;
}
}
......
......@@ -1867,6 +1867,13 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
}
void dq(Label* label);
#ifdef DEBUG
bool EmbeddedObjectMatches(int pc_offset, Handle<Object> object) {
return *reinterpret_cast<uint64_t*>(buffer_->start() + pc_offset) ==
(IsOnHeap() ? object->ptr() : object.address());
}
#endif
// Patch entries for partial constant pool.
void PatchConstPool();
......
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