%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/heap-write-barrier.cc |
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/heap/heap-write-barrier.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"
#include "src/objects/maybe-object.h"
#include "src/objects/slots-inl.h"
namespace v8 {
namespace internal {
namespace {
thread_local MarkingBarrier* current_marking_barrier = nullptr;
} // namespace
MarkingBarrier* WriteBarrier::CurrentMarkingBarrier(
Tagged<HeapObject> verification_candidate) {
MarkingBarrier* marking_barrier = current_marking_barrier;
DCHECK_NOT_NULL(marking_barrier);
#if DEBUG
if (!verification_candidate.is_null() &&
!verification_candidate.InAnySharedSpace()) {
Heap* host_heap =
MemoryChunk::FromHeapObject(verification_candidate)->heap();
LocalHeap* local_heap = LocalHeap::Current();
if (!local_heap) local_heap = host_heap->main_thread_local_heap();
DCHECK_EQ(marking_barrier, local_heap->marking_barrier());
}
#endif // DEBUG
return marking_barrier;
}
MarkingBarrier* WriteBarrier::SetForThread(MarkingBarrier* marking_barrier) {
MarkingBarrier* existing = current_marking_barrier;
current_marking_barrier = marking_barrier;
return existing;
}
void WriteBarrier::MarkingSlow(Tagged<HeapObject> host, HeapObjectSlot slot,
Tagged<HeapObject> value) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
marking_barrier->Write(host, slot, value);
}
// static
void WriteBarrier::MarkingSlowFromGlobalHandle(Tagged<HeapObject> value) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(value);
marking_barrier->WriteWithoutHost(value);
}
// static
void WriteBarrier::MarkingSlowFromInternalFields(Heap* heap,
Tagged<JSObject> host) {
if (auto* cpp_heap = heap->cpp_heap()) {
CppHeap::From(cpp_heap)->WriteBarrier(host);
}
}
void WriteBarrier::MarkingSlow(Tagged<InstructionStream> host,
RelocInfo* reloc_info,
Tagged<HeapObject> value) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
marking_barrier->Write(host, reloc_info, value);
}
void WriteBarrier::SharedSlow(Tagged<InstructionStream> host,
RelocInfo* reloc_info, Tagged<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(Tagged<JSArrayBuffer> host,
ArrayBufferExtension* extension) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
marking_barrier->Write(host, extension);
}
void WriteBarrier::MarkingSlow(Tagged<DescriptorArray> descriptor_array,
int number_of_own_descriptors) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(descriptor_array);
marking_barrier->Write(descriptor_array, number_of_own_descriptors);
}
void WriteBarrier::MarkingSlow(Tagged<HeapObject> host,
IndirectPointerSlot slot) {
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
marking_barrier->Write(host, slot);
}
int WriteBarrier::MarkingFromCode(Address raw_host, Address raw_slot) {
Tagged<HeapObject> host = HeapObject::cast(Tagged<Object>(raw_host));
MaybeObjectSlot slot(raw_slot);
Address value = (*slot).ptr();
#ifdef V8_MAP_PACKING
if (slot.address() == host.address()) {
// Clear metadata bits and fix object tag.
value = (value & ~Internals::kMapWordMetadataMask &
~Internals::kMapWordXorMask) |
(uint64_t)kHeapObjectTag;
}
#endif
#if DEBUG
Heap* heap = MemoryChunk::FromHeapObject(host)->heap();
DCHECK(heap->incremental_marking()->IsMarking());
// We will only reach local objects here while incremental marking in the
// current isolate is enabled. However, we might still reach objects in the
// shared space but only from the shared space isolate (= the main isolate).
MarkingBarrier* barrier = CurrentMarkingBarrier(host);
DCHECK_IMPLIES(host.InWritableSharedSpace(),
barrier->heap()->isolate()->is_shared_space_isolate());
barrier->AssertMarkingIsActivated();
#endif // DEBUG
WriteBarrier::Marking(host, slot, MaybeObject(value));
// Called by WriteBarrierCodeStubAssembler, which doesn't accept void type
return 0;
}
int WriteBarrier::IndirectPointerMarkingFromCode(Address raw_host,
Address raw_slot,
Address raw_tag) {
Tagged<HeapObject> host = HeapObject::cast(Tagged<Object>(raw_host));
IndirectPointerTag tag = static_cast<IndirectPointerTag>(raw_tag);
DCHECK(IsValidIndirectPointerTag(tag));
IndirectPointerSlot slot(raw_slot, tag);
#if DEBUG
Heap* heap = MemoryChunk::FromHeapObject(host)->heap();
DCHECK(heap->incremental_marking()->IsMarking());
// We will only reach local objects here while incremental marking in the
// current isolate is enabled. However, we might still reach objects in the
// shared space but only from the shared space isolate (= the main isolate).
MarkingBarrier* barrier = CurrentMarkingBarrier(host);
DCHECK_IMPLIES(host.InWritableSharedSpace(),
barrier->heap()->isolate()->is_shared_space_isolate());
barrier->AssertMarkingIsActivated();
#endif // DEBUG
WriteBarrier::Marking(host, slot);
// Called by WriteBarrierCodeStubAssembler, which doesn't accept void type
return 0;
}
int WriteBarrier::SharedMarkingFromCode(Address raw_host, Address raw_slot) {
Tagged<HeapObject> host = HeapObject::cast(Tagged<Object>(raw_host));
MaybeObjectSlot slot(raw_slot);
Address raw_value = (*slot).ptr();
MaybeObject value(raw_value);
DCHECK(host.InWritableSharedSpace());
#if DEBUG
Heap* heap = MemoryChunk::FromHeapObject(host)->heap();
DCHECK(heap->incremental_marking()->IsMajorMarking());
Isolate* isolate = heap->isolate();
DCHECK(isolate->is_shared_space_isolate());
// The shared marking barrier will only be reached from client isolates (=
// worker isolates).
MarkingBarrier* barrier = CurrentMarkingBarrier(host);
DCHECK(!barrier->heap()->isolate()->is_shared_space_isolate());
barrier->AssertSharedMarkingIsActivated();
#endif // DEBUG
WriteBarrier::Marking(host, slot, MaybeObject(value));
// Called by WriteBarrierCodeStubAssembler, which doesn't accept void type
return 0;
}
int WriteBarrier::SharedFromCode(Address raw_host, Address raw_slot) {
Tagged<HeapObject> host = HeapObject::cast(Tagged<Object>(raw_host));
if (!host.InWritableSharedSpace()) {
Heap::SharedHeapBarrierSlow(host, raw_slot);
}
// Called by WriteBarrierCodeStubAssembler, which doesn't accept void type
return 0;
}
#ifdef ENABLE_SLOW_DCHECKS
bool WriteBarrier::IsImmortalImmovableHeapObject(Tagged<HeapObject> object) {
BasicMemoryChunk* basic_chunk = BasicMemoryChunk::FromHeapObject(object);
// All objects in readonly space are immortal and immovable.
return basic_chunk->InReadOnlySpace();
}
#endif
} // namespace internal
} // namespace v8