[heap] Improve verification for code write barrier

Pass WriteBarrierMode to the code object write barrier and DCHECK WriteBarrier::IsRequired when using SKIP_WRITE_BARRIER.

Bug: v8:11708
Change-Id: I457d0fa07e830d6831fb95a4ae9311f6066215e8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3810171
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82201}
This commit is contained in:
Dominik Inführ 2022-08-04 11:06:35 +02:00 committed by V8 LUCI CQ
parent 368b1e2fde
commit dc2d69d815
10 changed files with 36 additions and 22 deletions

View File

@ -124,9 +124,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
icache_flush_mode);
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() &&
!FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target);
if (!host().is_null() && !FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target, write_barrier_mode);
}
}

View File

@ -702,9 +702,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
icache_flush_mode);
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() &&
!FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target);
if (!host().is_null() && !FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target, write_barrier_mode);
}
}

View File

@ -101,9 +101,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
FlushInstructionCache(pc_, sizeof(Address));
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() &&
!FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target);
if (!host().is_null() && !FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target, write_barrier_mode);
}
}

View File

@ -356,6 +356,13 @@ void RelocInfo::set_target_address(Address target,
}
}
void RelocInfo::set_off_heap_target_address(Address target,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTargetMode(rmode_));
Assembler::set_target_address_at(pc_, constant_pool_, target,
icache_flush_mode);
}
bool RelocInfo::HasTargetAddressAddress() const {
// TODO(jgruber): Investigate whether WASM_CALL is still appropriate on
// non-intel platforms now that wasm code is no longer on the heap.

View File

@ -249,6 +249,10 @@ class RelocInfo {
WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER,
ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
void set_off_heap_target_address(
Address target,
ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
// this relocation applies to;
// can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
V8_INLINE Address target_address();

View File

@ -382,9 +382,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
FlushInstructionCache(pc_, sizeof(Address));
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() &&
!FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target);
if (!host().is_null() && !FLAG_disable_write_barriers) {
WriteBarrierForCode(host(), this, target, write_barrier_mode);
}
}

View File

@ -132,13 +132,21 @@ inline void CombinedWriteBarrierInternal(HeapObject host, HeapObjectSlot slot,
} // namespace heap_internals
inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value) {
inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value,
WriteBarrierMode mode) {
DCHECK(!HasWeakHeapObjectTag(value));
if (!value.IsHeapObject()) return;
WriteBarrierForCode(host, rinfo, HeapObject::cast(value));
}
inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value) {
inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value,
WriteBarrierMode mode) {
if (mode == SKIP_WRITE_BARRIER) {
SLOW_DCHECK(!WriteBarrier::IsRequired(host, value));
return;
}
DCHECK_EQ(mode, UPDATE_WRITE_BARRIER);
GenerationalBarrierForCode(host, rinfo, value);
WriteBarrier::Shared(host, rinfo, value);
WriteBarrier::Marking(host, rinfo, value);

View File

@ -29,8 +29,10 @@ class RelocInfo;
// object-macros.h.
// Combined write barriers.
void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value);
void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value);
void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
void WriteBarrierForCode(Code host);
void CombinedWriteBarrier(HeapObject object, ObjectSlot slot, Object value,

View File

@ -7256,9 +7256,7 @@ void Heap::WriteBarrierForCodeSlow(Code code) {
for (RelocIterator it(code, RelocInfo::EmbeddedObjectModeMask()); !it.done();
it.next()) {
HeapObject target_object = it.rinfo()->target_object(cage_base);
GenerationalBarrierForCode(code, it.rinfo(), target_object);
WriteBarrier::Shared(code, it.rinfo(), target_object);
WriteBarrier::Marking(code, it.rinfo(), target_object);
WriteBarrierForCode(code, it.rinfo(), target_object);
}
}

View File

@ -241,9 +241,8 @@ void FinalizeEmbeddedCodeTargets(Isolate* isolate, EmbeddedData* blob) {
CHECK(Builtins::IsIsolateIndependentBuiltin(target));
// Do not emit write-barrier for off-heap writes.
off_heap_it.rinfo()->set_target_address(
blob->InstructionStartOfBuiltin(target.builtin_id()),
SKIP_WRITE_BARRIER);
off_heap_it.rinfo()->set_off_heap_target_address(
blob->InstructionStartOfBuiltin(target.builtin_id()));
on_heap_it.next();
off_heap_it.next();