• 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/base/sanitizer/msan.h"
8 #include "src/heap/cppgc/caged-heap.h"
9 #include "src/heap/cppgc/gc-info-table.h"
10 #include "src/heap/cppgc/heap-base.h"
11 #include "src/heap/cppgc/heap-object-header.h"
12 #include "src/heap/cppgc/heap-page.h"
13 #include "src/heap/cppgc/object-view.h"
14 #include "src/heap/cppgc/page-memory.h"
15 
16 namespace cppgc {
17 
18 #ifdef V8_ENABLE_CHECKS
CheckObjectNotInConstruction(const void * address)19 void Visitor::CheckObjectNotInConstruction(const void* address) {
20   // TODO(chromium:1056170): |address| is an inner pointer of an object. Check
21   // that the object is not in construction.
22 }
23 #endif  // V8_ENABLE_CHECKS
24 
25 namespace internal {
26 
ConservativeTracingVisitor(HeapBase & heap,PageBackend & page_backend,cppgc::Visitor & visitor)27 ConservativeTracingVisitor::ConservativeTracingVisitor(
28     HeapBase& heap, PageBackend& page_backend, cppgc::Visitor& visitor)
29     : heap_(heap), page_backend_(page_backend), visitor_(visitor) {}
30 
31 namespace {
32 
TraceConservatively(ConservativeTracingVisitor * conservative_visitor,const HeapObjectHeader & header)33 void TraceConservatively(ConservativeTracingVisitor* conservative_visitor,
34                          const HeapObjectHeader& header) {
35   const auto object_view = ObjectView<>(header);
36   Address* object = reinterpret_cast<Address*>(object_view.Start());
37   for (size_t i = 0; i < (object_view.Size() / sizeof(Address)); ++i) {
38     Address maybe_ptr = object[i];
39 #if defined(MEMORY_SANITIZER)
40     // |object| may be uninitialized by design or just contain padding bytes.
41     // Copy into a local variable that is not poisoned for conservative marking.
42     // Copy into a temporary variable to maintain the original MSAN state.
43     MSAN_MEMORY_IS_INITIALIZED(&maybe_ptr, sizeof(maybe_ptr));
44 #endif
45     if (maybe_ptr) {
46       conservative_visitor->TraceConservativelyIfNeeded(maybe_ptr);
47     }
48   }
49 }
50 
51 }  // namespace
52 
TraceConservativelyIfNeeded(const void * address)53 void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
54     const void* address) {
55 #if defined(CPPGC_CAGED_HEAP)
56   // TODO(chromium:1056170): Add support for SIMD in stack scanning.
57   if (V8_LIKELY(!heap_.caged_heap().IsOnHeap(address))) return;
58 #endif
59 
60   const BasePage* page = reinterpret_cast<const BasePage*>(
61       page_backend_.Lookup(static_cast<ConstAddress>(address)));
62 
63   if (!page) return;
64 
65   DCHECK_EQ(&heap_, &page->heap());
66 
67   auto* header = page->TryObjectHeaderFromInnerAddress(
68       const_cast<Address>(reinterpret_cast<ConstAddress>(address)));
69 
70   if (!header) return;
71 
72   TraceConservativelyIfNeeded(*header);
73 }
74 
TraceConservativelyIfNeeded(HeapObjectHeader & header)75 void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
76     HeapObjectHeader& header) {
77   if (!header.IsInConstruction<AccessMode::kNonAtomic>()) {
78     VisitFullyConstructedConservatively(header);
79   } else {
80     VisitInConstructionConservatively(header, TraceConservatively);
81   }
82 }
83 
VisitFullyConstructedConservatively(HeapObjectHeader & header)84 void ConservativeTracingVisitor::VisitFullyConstructedConservatively(
85     HeapObjectHeader& header) {
86   visitor_.Visit(
87       header.ObjectStart(),
88       {header.ObjectStart(),
89        GlobalGCInfoTable::GCInfoFromIndex(header.GetGCInfoIndex()).trace});
90 }
91 
92 }  // namespace internal
93 }  // namespace cppgc
94