Commit 750461ce authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: Trace on-stack intermediate results of compression|decompression

The compiler is free to spill intermediate results of
compression|decompression on stack. With our scheme, the only
intermediate result can be a truncated but non-shifted pointer.

Bug: chromium:1325007
Change-Id: Ibec1f80b9d214d1c1e7cb8368c094fc262237642
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3793615Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82236}
parent 3c7f2747
...@@ -94,22 +94,32 @@ void ConservativeTracingVisitor::TraceConservativelyIfNeeded( ...@@ -94,22 +94,32 @@ void ConservativeTracingVisitor::TraceConservativelyIfNeeded(
auto pointer = reinterpret_cast<Address>(const_cast<void*>(address)); auto pointer = reinterpret_cast<Address>(const_cast<void*>(address));
TryTracePointerConservatively(pointer); TryTracePointerConservatively(pointer);
#if defined(CPPGC_POINTER_COMPRESSION) #if defined(CPPGC_POINTER_COMPRESSION)
auto try_trace = [this](Address ptr) {
if (ptr > reinterpret_cast<Address>(SentinelPointer::kSentinelValue))
TryTracePointerConservatively(ptr);
};
// If pointer compression enabled, we may have random compressed pointers on // If pointer compression enabled, we may have random compressed pointers on
// stack (e.g. due to inlined collections). Extract, decompress and trace both // stack (e.g. due to inlined collections). Extract, decompress and trace both
// halfwords. // halfwords.
auto decompressed_low = auto decompressed_low = static_cast<Address>(CompressedPointer::Decompress(
reinterpret_cast<Address>(CompressedPointer::Decompress(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer)))); static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer))));
if (decompressed_low > try_trace(decompressed_low);
reinterpret_cast<void*>(SentinelPointer::kSentinelValue)) auto decompressed_high = static_cast<Address>(CompressedPointer::Decompress(
TryTracePointerConservatively(decompressed_low);
auto decompressed_high =
reinterpret_cast<Address>(CompressedPointer::Decompress(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer) >> static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer) >>
(sizeof(uint32_t) * CHAR_BIT)))); (sizeof(uint32_t) * CHAR_BIT))));
if (decompressed_high > try_trace(decompressed_high);
reinterpret_cast<void*>(SentinelPointer::kSentinelValue)) // In addition, check half-compressed haldwords, since the compiler is free to
TryTracePointerConservatively(decompressed_high); // spill intermediate results of compression/decompression onto the stack.
const uintptr_t base = CagedHeapBase::GetBase();
DCHECK(base);
auto intermediate_decompressed_low = reinterpret_cast<Address>(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer)) | base);
try_trace(intermediate_decompressed_low);
auto intermediate_decompressed_high = reinterpret_cast<Address>(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pointer) >>
(sizeof(uint32_t) * CHAR_BIT)) |
base);
try_trace(intermediate_decompressed_high);
#endif // defined(CPPGC_POINTER_COMPRESSION) #endif // defined(CPPGC_POINTER_COMPRESSION)
} }
......
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