Commit aee4f595 authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[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/+/3763867Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81855}
parent b3179fe7
...@@ -140,7 +140,7 @@ inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value) { ...@@ -140,7 +140,7 @@ inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value) {
inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value) { inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, HeapObject value) {
GenerationalBarrierForCode(host, rinfo, value); GenerationalBarrierForCode(host, rinfo, value);
SharedHeapBarrierForCode(host, rinfo, value); WriteBarrier::Shared(host, rinfo, value);
WriteBarrier::Marking(host, rinfo, value); WriteBarrier::Marking(host, rinfo, value);
} }
...@@ -218,18 +218,6 @@ inline void GenerationalBarrierForCode(Code host, RelocInfo* rinfo, ...@@ -218,18 +218,6 @@ inline void GenerationalBarrierForCode(Code host, RelocInfo* rinfo,
Heap_GenerationalBarrierForCodeSlow(host, rinfo, object); 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( inline WriteBarrierMode GetWriteBarrierModeForObject(
HeapObject object, const DisallowGarbageCollection* promise) { HeapObject object, const DisallowGarbageCollection* promise) {
if (FLAG_disable_write_barriers) return SKIP_WRITE_BARRIER; if (FLAG_disable_write_barriers) return SKIP_WRITE_BARRIER;
...@@ -271,6 +259,14 @@ base::Optional<Heap*> WriteBarrier::GetHeapIfMarking(HeapObject object) { ...@@ -271,6 +259,14 @@ base::Optional<Heap*> WriteBarrier::GetHeapIfMarking(HeapObject object) {
return chunk->GetHeap(); 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) { void WriteBarrier::Marking(HeapObject host, ObjectSlot slot, Object value) {
DCHECK(!HasWeakHeapObjectTag(value)); DCHECK(!HasWeakHeapObjectTag(value));
if (!value.IsHeapObject()) return; if (!value.IsHeapObject()) return;
...@@ -310,6 +306,21 @@ void WriteBarrier::Marking(Code host, RelocInfo* reloc_info, HeapObject value) { ...@@ -310,6 +306,21 @@ void WriteBarrier::Marking(Code host, RelocInfo* reloc_info, HeapObject value) {
MarkingSlow(*heap, host, reloc_info, 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, void WriteBarrier::Marking(JSArrayBuffer host,
ArrayBufferExtension* extension) { ArrayBufferExtension* extension) {
if (!extension) return; if (!extension) return;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/heap/embedder-tracing.h" #include "src/heap/embedder-tracing.h"
#include "src/heap/heap-write-barrier-inl.h" #include "src/heap/heap-write-barrier-inl.h"
#include "src/heap/marking-barrier.h" #include "src/heap/marking-barrier.h"
#include "src/heap/remembered-set.h"
#include "src/objects/code-inl.h" #include "src/objects/code-inl.h"
#include "src/objects/descriptor-array.h" #include "src/objects/descriptor-array.h"
#include "src/objects/js-objects.h" #include "src/objects/js-objects.h"
...@@ -61,6 +62,16 @@ void WriteBarrier::MarkingSlow(Heap* heap, Code host, RelocInfo* reloc_info, ...@@ -61,6 +62,16 @@ void WriteBarrier::MarkingSlow(Heap* heap, Code host, RelocInfo* reloc_info,
marking_barrier->Write(host, reloc_info, value); 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, void WriteBarrier::MarkingSlow(Heap* heap, JSArrayBuffer host,
ArrayBufferExtension* extension) { ArrayBufferExtension* extension) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(heap); MarkingBarrier* marking_barrier = CurrentMarkingBarrier(heap);
......
...@@ -44,9 +44,6 @@ void CombinedEphemeronWriteBarrier(EphemeronHashTable object, ObjectSlot slot, ...@@ -44,9 +44,6 @@ void CombinedEphemeronWriteBarrier(EphemeronHashTable object, ObjectSlot slot,
// Generational write barrier. // Generational write barrier.
void GenerationalBarrierForCode(Code host, RelocInfo* rinfo, HeapObject object); 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); inline bool IsReadOnlyHeapObject(HeapObject object);
class V8_EXPORT_PRIVATE WriteBarrier { class V8_EXPORT_PRIVATE WriteBarrier {
...@@ -59,6 +56,8 @@ 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(JSArrayBuffer host, ArrayBufferExtension*);
static inline void Marking(DescriptorArray, int number_of_own_descriptors); 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. // It is invoked from generated code and has to take raw addresses.
static int MarkingFromCode(Address raw_host, Address raw_slot); static int MarkingFromCode(Address raw_host, Address raw_slot);
// Invoked from global handles where no host object is available. // Invoked from global handles where no host object is available.
...@@ -81,6 +80,7 @@ class V8_EXPORT_PRIVATE WriteBarrier { ...@@ -81,6 +80,7 @@ class V8_EXPORT_PRIVATE WriteBarrier {
private: private:
static inline base::Optional<Heap*> GetHeapIfMarking(HeapObject object); 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, Code host, RelocInfo*, HeapObject value);
static void MarkingSlow(Heap* heap, JSArrayBuffer host, static void MarkingSlow(Heap* heap, JSArrayBuffer host,
...@@ -89,6 +89,10 @@ class V8_EXPORT_PRIVATE WriteBarrier { ...@@ -89,6 +89,10 @@ class V8_EXPORT_PRIVATE WriteBarrier {
int number_of_own_descriptors); int number_of_own_descriptors);
static void MarkingSlowFromGlobalHandle(Heap* heap, HeapObject value); static void MarkingSlowFromGlobalHandle(Heap* heap, HeapObject value);
static void MarkingSlowFromInternalFields(Heap* heap, JSObject host); static void MarkingSlowFromInternalFields(Heap* heap, JSObject host);
static void SharedSlow(Heap* heap, Code host, RelocInfo*, HeapObject value);
friend class Heap;
}; };
} // namespace internal } // namespace internal
......
...@@ -7276,6 +7276,7 @@ void Heap::WriteBarrierForCodeSlow(Code code) { ...@@ -7276,6 +7276,7 @@ void Heap::WriteBarrierForCodeSlow(Code code) {
it.next()) { it.next()) {
HeapObject target_object = it.rinfo()->target_object(cage_base); HeapObject target_object = it.rinfo()->target_object(cage_base);
GenerationalBarrierForCode(code, it.rinfo(), target_object); GenerationalBarrierForCode(code, it.rinfo(), target_object);
WriteBarrier::Shared(code, it.rinfo(), target_object);
WriteBarrier::Marking(code, it.rinfo(), target_object); WriteBarrier::Marking(code, it.rinfo(), target_object);
} }
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// Flags: --shared-string-table --harmony-struct --allow-natives-syntax // Flags: --shared-string-table --harmony-struct --allow-natives-syntax
// Flags: --verify-heapo // Flags: --verify-heap
"use strict"; "use strict";
......
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