Commit 3fe40a3f authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

cppgc: Support conservatively tracing large objects

We would use a payload size of 0 and end up walking up the stack till
we crash.

Bug: chromium:1056170
Change-Id: I12a69ada24697faaf05e2f4ab210045d54cf34e5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2891657Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74537}
parent 3abb253d
......@@ -30,8 +30,11 @@ 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) {
const size_t object_size =
header.IsLargeObject()
? LargePage::From(BasePage::FromPayload(&header))->ObjectSize()
: header.ObjectSize();
for (size_t i = 0; i < (object_size / sizeof(Address)); ++i) {
Address maybe_ptr = payload[i];
#if defined(MEMORY_SANITIZER)
// |payload| may be uninitialized by design or just contain padding bytes.
......
......@@ -89,6 +89,46 @@ TEST_F(GCHeapTest, ConservativeGCRetainsObjectOnStack) {
EXPECT_EQ(1u, Foo::destructor_callcount);
}
namespace {
class GCedWithFinalizer final : public GarbageCollected<GCedWithFinalizer> {
public:
static size_t destructor_counter;
GCedWithFinalizer() { destructor_counter = 0; }
~GCedWithFinalizer() { destructor_counter++; }
void Trace(Visitor* visitor) const {}
};
// static
size_t GCedWithFinalizer::destructor_counter = 0;
class LargeObjectGCDuringCtor final
: public GarbageCollected<LargeObjectGCDuringCtor> {
public:
static constexpr size_t kDataSize = kLargeObjectSizeThreshold + 1;
explicit LargeObjectGCDuringCtor(cppgc::Heap* heap)
: child_(MakeGarbageCollected<GCedWithFinalizer>(
heap->GetAllocationHandle())) {
internal::Heap::From(heap)->CollectGarbage(
Heap::Config::ConservativeAtomicConfig());
}
void Trace(Visitor* visitor) const { visitor->Trace(child_); }
char data[kDataSize];
Member<GCedWithFinalizer> child_;
};
} // namespace
TEST_F(GCHeapTest, ConservativeGCFromLargeObjectCtorFindsObject) {
GCedWithFinalizer::destructor_counter = 0;
MakeGarbageCollected<LargeObjectGCDuringCtor>(GetAllocationHandle(),
GetHeap());
EXPECT_EQ(0u, GCedWithFinalizer::destructor_counter);
}
TEST_F(GCHeapTest, ObjectPayloadSize) {
static constexpr size_t kNumberOfObjectsPerArena = 16;
static constexpr size_t kObjectSizes[] = {1, 32, 64, 128,
......
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