Commit 15b4fc63 authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: Trace full pointers in in-construction objects.

On-heap objects may have TracedReferences, which are uncompressed
pointers that still need to be conservatively scanned (another CL).

Bug: chromium:1325007
Change-Id: If05add36191978486f315dc1ef142a7ed8d4a7bb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3804808
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Auto-Submit: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82152}
parent 84c2c7cf
......@@ -35,33 +35,34 @@ namespace {
void TraceConservatively(ConservativeTracingVisitor* conservative_visitor,
const HeapObjectHeader& header) {
#if defined(CPPGC_POINTER_COMPRESSION)
using PointerType = uint32_t;
#else // !defined(CPPGC_POINTER_COMPRESSION)
using PointerType = uintptr_t;
#endif // !defined(CPPGC_POINTER_COMPRESSION)
const auto object_view = ObjectView<>(header);
PointerType* object = reinterpret_cast<PointerType*>(object_view.Start());
for (size_t i = 0; i < (object_view.Size() / sizeof(PointerType)); ++i) {
PointerType maybe_ptr = object[i];
uintptr_t* word = reinterpret_cast<uintptr_t*>(object_view.Start());
for (size_t i = 0; i < (object_view.Size() / sizeof(uintptr_t)); ++i) {
uintptr_t maybe_full_ptr = word[i];
#if defined(MEMORY_SANITIZER)
// |object| 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_MEMORY_IS_INITIALIZED(&maybe_ptr, sizeof(maybe_ptr));
MSAN_MEMORY_IS_INITIALIZED(&maybe_full_ptr, sizeof(maybe_full_ptr));
#endif
if (maybe_ptr > SentinelPointer::kSentinelValue) {
// First, check the full pointer.
if (maybe_full_ptr > SentinelPointer::kSentinelValue)
conservative_visitor->TraceConservativelyIfNeeded(
reinterpret_cast<Address>(maybe_full_ptr));
#if defined(CPPGC_POINTER_COMPRESSION)
// We know that all on-heap pointers are compressed, so don't check full
// pointers.
Address decompressed_ptr =
static_cast<Address>(CompressedPointer::Decompress(maybe_ptr));
#else // !defined(CPPGC_POINTER_COMPRESSION)
Address decompressed_ptr = reinterpret_cast<Address>(maybe_ptr);
// Then, check for compressed pointers.
auto decompressed_low = reinterpret_cast<Address>(
CompressedPointer::Decompress(static_cast<uint32_t>(maybe_full_ptr)));
if (decompressed_low >
reinterpret_cast<void*>(SentinelPointer::kSentinelValue))
conservative_visitor->TraceConservativelyIfNeeded(decompressed_low);
auto decompressed_high = reinterpret_cast<Address>(
CompressedPointer::Decompress(static_cast<uint32_t>(
maybe_full_ptr >> (sizeof(uint32_t) * CHAR_BIT))));
if (decompressed_high >
reinterpret_cast<void*>(SentinelPointer::kSentinelValue))
conservative_visitor->TraceConservativelyIfNeeded(decompressed_high);
#endif // !defined(CPPGC_POINTER_COMPRESSION)
conservative_visitor->TraceConservativelyIfNeeded(decompressed_ptr);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment