// 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/cppgc/visitor.h" #include "src/heap/cppgc/gc-info-table.h" #include "src/heap/cppgc/heap-object-header.h" #include "src/heap/cppgc/heap-page.h" #include "src/heap/cppgc/page-memory.h" #include "src/heap/cppgc/sanitizers.h" namespace cppgc { #ifdef V8_ENABLE_CHECKS void Visitor::CheckObjectNotInConstruction(const void* address) { // TODO(chromium:1056170): |address| is an inner pointer of an object. Check // that the object is not in construction. } #endif // V8_ENABLE_CHECKS namespace internal { ConservativeTracingVisitor::ConservativeTracingVisitor( HeapBase& heap, PageBackend& page_backend, cppgc::Visitor& visitor) : heap_(heap), page_backend_(page_backend), visitor_(visitor) {} namespace { void TraceConservatively(ConservativeTracingVisitor* conservative_visitor, const HeapObjectHeader& header) { Address* payload = reinterpret_cast(header.Payload()); const size_t payload_size = header.GetSize(); for (size_t i = 0; i < (payload_size / sizeof(Address)); ++i) { Address maybe_ptr = payload[i]; #if defined(MEMORY_SANITIZER) // |payload| may be uninitialized by design or just contain padding bytes. // Copy into a local variable that is not poisoned for conservative marking. // Copy into a temporary variable to maintain the original MSAN state. MSAN_UNPOISON(&maybe_ptr, sizeof(maybe_ptr)); #endif if (maybe_ptr) { conservative_visitor->TraceConservativelyIfNeeded(maybe_ptr); } } } } // namespace void ConservativeTracingVisitor::TraceConservativelyIfNeeded( const void* address) { // TODO(chromium:1056170): Add page bloom filter const BasePage* page = reinterpret_cast( page_backend_.Lookup(static_cast(address))); if (!page) return; DCHECK_EQ(&heap_, page->heap()); auto* header = page->TryObjectHeaderFromInnerAddress( const_cast
(reinterpret_cast(address))); if (!header) return; TraceConservativelyIfNeeded(*header); } void ConservativeTracingVisitor::TraceConservativelyIfNeeded( HeapObjectHeader& header) { if (!header.IsInConstruction()) { VisitFullyConstructedConservatively(header); } else { VisitInConstructionConservatively(header, TraceConservatively); } } void ConservativeTracingVisitor::VisitFullyConstructedConservatively( HeapObjectHeader& header) { visitor_.Visit( header.Payload(), {header.Payload(), GlobalGCInfoTable::GCInfoFromIndex(header.GetGCInfoIndex()).trace}); } } // namespace internal } // namespace cppgc