blob: 33786f6fce3c45344c0c94bc3c4dd9f46d17e347 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
// 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<Address*>(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<const BasePage*>(
page_backend_.Lookup(static_cast<ConstAddress>(address)));
if (!page) return;
DCHECK_EQ(&heap_, page->heap());
auto* header = page->TryObjectHeaderFromInnerAddress(
const_cast<Address>(reinterpret_cast<ConstAddress>(address)));
if (!header) return;
TraceConservativelyIfNeeded(*header);
}
void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
HeapObjectHeader& header) {
if (!header.IsInConstruction<AccessMode::kNonAtomic>()) {
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
|