[heap] Add thread-safe shared barrier for code objects
In order to make the shared code write barrier thread-safe, we simply lock the page mutex when appending to the typed_slot_set. We can later improve this when performance isn't good enough. Bug: v8:13018 Change-Id: I5e12f83f459f8976c22ec488cfa9b6f16d4a8a8e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3763867 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/main@{#81855}
This commit is contained in:
parent
b3179fe760
commit
aee4f59521
@ -140,7 +140,7 @@ inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value) {
|
||||
|
||||
inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value) {
|
||||
GenerationalBarrierForCode(host, rinfo, value);
|
||||
SharedHeapBarrierForCode(host, rinfo, value);
|
||||
WriteBarrier::Shared(host, rinfo, value);
|
||||
WriteBarrier::Marking(host, rinfo, value);
|
||||
}
|
||||
|
||||
@ -218,18 +218,6 @@ inline void GenerationalBarrierForCode(Code host, RelocInfo* rinfo,
|
||||
Heap_GenerationalBarrierForCodeSlow(host, rinfo, object);
|
||||
}
|
||||
|
||||
inline void SharedHeapBarrierForCode(Code host, RelocInfo* rinfo,
|
||||
HeapObject object) {
|
||||
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) return;
|
||||
|
||||
heap_internals::MemoryChunk* object_chunk =
|
||||
heap_internals::MemoryChunk::FromHeapObject(object);
|
||||
if (!object_chunk->InSharedHeap()) return;
|
||||
|
||||
// TODO(v8:11708): Implement a thread-safe shared heap barrier. The barrier is
|
||||
// executed from the main thread as well from concurrent compilation threads.
|
||||
}
|
||||
|
||||
inline WriteBarrierMode GetWriteBarrierModeForObject(
|
||||
HeapObject object, const DisallowGarbageCollection* promise) {
|
||||
if (FLAG_disable_write_barriers) return SKIP_WRITE_BARRIER;
|
||||
@ -271,6 +259,14 @@ base::Optional<Heap*> WriteBarrier::GetHeapIfMarking(HeapObject object) {
|
||||
return chunk->GetHeap();
|
||||
}
|
||||
|
||||
Heap* WriteBarrier::GetHeap(HeapObject object) {
|
||||
DCHECK(!V8_ENABLE_THIRD_PARTY_HEAP_BOOL);
|
||||
heap_internals::MemoryChunk* chunk =
|
||||
heap_internals::MemoryChunk::FromHeapObject(object);
|
||||
DCHECK(!chunk->InReadOnlySpace());
|
||||
return chunk->GetHeap();
|
||||
}
|
||||
|
||||
void WriteBarrier::Marking(HeapObject host, ObjectSlot slot, Object value) {
|
||||
DCHECK(!HasWeakHeapObjectTag(value));
|
||||
if (!value.IsHeapObject()) return;
|
||||
@ -310,6 +306,21 @@ void WriteBarrier::Marking(Code host, RelocInfo* reloc_info, HeapObject value) {
|
||||
MarkingSlow(*heap, host, reloc_info, value);
|
||||
}
|
||||
|
||||
void WriteBarrier::Shared(Code host, RelocInfo* reloc_info, HeapObject value) {
|
||||
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) return;
|
||||
|
||||
// There are no code objects in the shared heap.
|
||||
DCHECK(!MemoryChunk::FromHeapObject(host)->InSharedHeap());
|
||||
|
||||
heap_internals::MemoryChunk* value_chunk =
|
||||
heap_internals::MemoryChunk::FromHeapObject(value);
|
||||
if (!value_chunk->InSharedHeap()) return;
|
||||
|
||||
Heap* heap = GetHeap(host);
|
||||
DCHECK_NOT_NULL(heap);
|
||||
SharedSlow(heap, host, reloc_info, value);
|
||||
}
|
||||
|
||||
void WriteBarrier::Marking(JSArrayBuffer host,
|
||||
ArrayBufferExtension* extension) {
|
||||
if (!extension) return;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/heap/embedder-tracing.h"
|
||||
#include "src/heap/heap-write-barrier-inl.h"
|
||||
#include "src/heap/marking-barrier.h"
|
||||
#include "src/heap/remembered-set.h"
|
||||
#include "src/objects/code-inl.h"
|
||||
#include "src/objects/descriptor-array.h"
|
||||
#include "src/objects/js-objects.h"
|
||||
@ -61,6 +62,16 @@ void WriteBarrier::MarkingSlow(Heap* heap, Code host, RelocInfo* reloc_info,
|
||||
marking_barrier->Write(host, reloc_info, value);
|
||||
}
|
||||
|
||||
void WriteBarrier::SharedSlow(Heap* heap, Code host, RelocInfo* reloc_info,
|
||||
HeapObject value) {
|
||||
MarkCompactCollector::RecordRelocSlotInfo info =
|
||||
MarkCompactCollector::ProcessRelocInfo(host, reloc_info, value);
|
||||
|
||||
base::MutexGuard write_scope(info.memory_chunk->mutex());
|
||||
RememberedSet<OLD_TO_SHARED>::InsertTyped(info.memory_chunk, info.slot_type,
|
||||
info.offset);
|
||||
}
|
||||
|
||||
void WriteBarrier::MarkingSlow(Heap* heap, JSArrayBuffer host,
|
||||
ArrayBufferExtension* extension) {
|
||||
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(heap);
|
||||
|
@ -44,9 +44,6 @@ void CombinedEphemeronWriteBarrier(EphemeronHashTable object, ObjectSlot slot,
|
||||
// Generational write barrier.
|
||||
void GenerationalBarrierForCode(Code host, RelocInfo* rinfo, HeapObject object);
|
||||
|
||||
// Shared heap write barrier.
|
||||
void SharedHeapBarrierForCode(Code host, RelocInfo* rinfo, HeapObject object);
|
||||
|
||||
inline bool IsReadOnlyHeapObject(HeapObject object);
|
||||
|
||||
class V8_EXPORT_PRIVATE WriteBarrier {
|
||||
@ -59,6 +56,8 @@ class V8_EXPORT_PRIVATE WriteBarrier {
|
||||
static inline void Marking(JSArrayBuffer host, ArrayBufferExtension*);
|
||||
static inline void Marking(DescriptorArray, int number_of_own_descriptors);
|
||||
|
||||
static inline void Shared(Code host, RelocInfo*, HeapObject value);
|
||||
|
||||
// It is invoked from generated code and has to take raw addresses.
|
||||
static int MarkingFromCode(Address raw_host, Address raw_slot);
|
||||
// Invoked from global handles where no host object is available.
|
||||
@ -81,6 +80,7 @@ class V8_EXPORT_PRIVATE WriteBarrier {
|
||||
|
||||
private:
|
||||
static inline base::Optional<Heap*> GetHeapIfMarking(HeapObject object);
|
||||
static inline Heap* GetHeap(HeapObject object);
|
||||
|
||||
static void MarkingSlow(Heap* heap, Code host, RelocInfo*, HeapObject value);
|
||||
static void MarkingSlow(Heap* heap, JSArrayBuffer host,
|
||||
@ -89,6 +89,10 @@ class V8_EXPORT_PRIVATE WriteBarrier {
|
||||
int number_of_own_descriptors);
|
||||
static void MarkingSlowFromGlobalHandle(Heap* heap, HeapObject value);
|
||||
static void MarkingSlowFromInternalFields(Heap* heap, JSObject host);
|
||||
|
||||
static void SharedSlow(Heap* heap, Code host, RelocInfo*, HeapObject value);
|
||||
|
||||
friend class Heap;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -7276,6 +7276,7 @@ void Heap::WriteBarrierForCodeSlow(Code code) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Flags: --shared-string-table --harmony-struct --allow-natives-syntax
|
||||
// Flags: --verify-heapo
|
||||
// Flags: --verify-heap
|
||||
|
||||
"use strict";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user