• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/heap/cppgc/visitor.h"
6 
7 #include "src/heap/cppgc/gc-info-table.h"
8 #include "src/heap/cppgc/heap-object-header.h"
9 #include "src/heap/cppgc/heap-page.h"
10 #include "src/heap/cppgc/page-memory.h"
11 #include "src/heap/cppgc/sanitizers.h"
12 
13 namespace cppgc {
14 
15 #ifdef V8_ENABLE_CHECKS
CheckObjectNotInConstruction(const void * address)16 void Visitor::CheckObjectNotInConstruction(const void* address) {
17   // TODO(chromium:1056170): |address| is an inner pointer of an object. Check
18   // that the object is not in construction.
19 }
20 #endif  // V8_ENABLE_CHECKS
21 
22 namespace internal {
23 
ConservativeTracingVisitor(HeapBase & heap,PageBackend & page_backend,cppgc::Visitor & visitor)24 ConservativeTracingVisitor::ConservativeTracingVisitor(
25     HeapBase& heap, PageBackend& page_backend, cppgc::Visitor& visitor)
26     : heap_(heap), page_backend_(page_backend), visitor_(visitor) {}
27 
28 namespace {
29 
TraceConservatively(ConservativeTracingVisitor * conservative_visitor,const HeapObjectHeader & header)30 void TraceConservatively(ConservativeTracingVisitor* conservative_visitor,
31                          const HeapObjectHeader& header) {
32   Address* payload = reinterpret_cast<Address*>(header.Payload());
33   const size_t payload_size = header.GetSize();
34   for (size_t i = 0; i < (payload_size / sizeof(Address)); ++i) {
35     Address maybe_ptr = payload[i];
36 #if defined(MEMORY_SANITIZER)
37     // |payload| may be uninitialized by design or just contain padding bytes.
38     // Copy into a local variable that is not poisoned for conservative marking.
39     // Copy into a temporary variable to maintain the original MSAN state.
40     MSAN_UNPOISON(&maybe_ptr, sizeof(maybe_ptr));
41 #endif
42     if (maybe_ptr) {
43       conservative_visitor->TraceConservativelyIfNeeded(maybe_ptr);
44     }
45   }
46 }
47 
48 }  // namespace
49 
TraceConservativelyIfNeeded(const void * address)50 void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
51     const void* address) {
52   // TODO(chromium:1056170): Add page bloom filter
53 
54   const BasePage* page = reinterpret_cast<const BasePage*>(
55       page_backend_.Lookup(static_cast<ConstAddress>(address)));
56 
57   if (!page) return;
58 
59   DCHECK_EQ(&heap_, page->heap());
60 
61   auto* header = page->TryObjectHeaderFromInnerAddress(
62       const_cast<Address>(reinterpret_cast<ConstAddress>(address)));
63 
64   if (!header) return;
65 
66   TraceConservativelyIfNeeded(*header);
67 }
68 
TraceConservativelyIfNeeded(HeapObjectHeader & header)69 void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
70     HeapObjectHeader& header) {
71   if (!header.IsInConstruction<AccessMode::kNonAtomic>()) {
72     VisitFullyConstructedConservatively(header);
73   } else {
74     VisitInConstructionConservatively(header, TraceConservatively);
75   }
76 }
77 
VisitFullyConstructedConservatively(HeapObjectHeader & header)78 void ConservativeTracingVisitor::VisitFullyConstructedConservatively(
79     HeapObjectHeader& header) {
80   visitor_.Visit(
81       header.Payload(),
82       {header.Payload(),
83        GlobalGCInfoTable::GCInfoFromIndex(header.GetGCInfoIndex()).trace});
84 }
85 
86 }  // namespace internal
87 }  // namespace cppgc
88