[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:
parent
368b1e2fde
commit
dc2d69d815
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user