Commit 288b545a authored by Omer Katz's avatar Omer Katz Committed by Commit Bot

cppgc: Add TraceCallback to GCInfo

This is needed to trace objects found durinbg stack scanning.

Bug: chromium:1056170
Change-Id: I1280d98f2fe69281c514b3a7d4a57f909a2eed96
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2190425
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67788}
parent 795246c4
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include "cppgc/internal/finalizer-trait.h" #include "cppgc/internal/finalizer-trait.h"
#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory) #include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc { namespace cppgc {
...@@ -18,7 +19,7 @@ using GCInfoIndex = uint16_t; ...@@ -18,7 +19,7 @@ using GCInfoIndex = uint16_t;
class V8_EXPORT RegisteredGCInfoIndex final { class V8_EXPORT RegisteredGCInfoIndex final {
public: public:
RegisteredGCInfoIndex(FinalizationCallback finalization_callback, RegisteredGCInfoIndex(FinalizationCallback finalization_callback,
bool has_v_table); TraceCallback trace_callback, bool has_v_table);
GCInfoIndex GetIndex() const { return index_; } GCInfoIndex GetIndex() const { return index_; }
private: private:
...@@ -32,7 +33,8 @@ struct GCInfoTrait { ...@@ -32,7 +33,8 @@ struct GCInfoTrait {
static GCInfoIndex Index() { static GCInfoIndex Index() {
static_assert(sizeof(T), "T must be fully defined"); static_assert(sizeof(T), "T must be fully defined");
static const RegisteredGCInfoIndex registered_index( static const RegisteredGCInfoIndex registered_index(
FinalizerTrait<T>::kCallback, std::is_polymorphic<T>::value); FinalizerTrait<T>::kCallback, TraceTrait<T>::Trace,
std::is_polymorphic<T>::value);
return registered_index.GetIndex(); return registered_index.GetIndex();
} }
}; };
......
...@@ -18,6 +18,11 @@ namespace internal { ...@@ -18,6 +18,11 @@ namespace internal {
namespace { namespace {
// GCInfoTable::table_, the table which holds GCInfos, is maintained as a
// contiguous array reserved upfront. Subparts of the array are (re-)committed
// as read/write or read-only in OS pages, whose size is a power of 2. To avoid
// having GCInfos that cross the boundaries between these subparts we force the
// size of GCInfo to be a power of 2 as well.
constexpr size_t kEntrySize = sizeof(GCInfo); constexpr size_t kEntrySize = sizeof(GCInfo);
static_assert(v8::base::bits::IsPowerOfTwo(kEntrySize), static_assert(v8::base::bits::IsPowerOfTwo(kEntrySize),
"GCInfoTable entries size must be power of " "GCInfoTable entries size must be power of "
......
...@@ -22,7 +22,10 @@ namespace internal { ...@@ -22,7 +22,10 @@ namespace internal {
// inherit from GarbageCollected. // inherit from GarbageCollected.
struct GCInfo final { struct GCInfo final {
FinalizationCallback finalize; FinalizationCallback finalize;
TraceCallback trace;
bool has_v_table; bool has_v_table;
// Keep sizeof(GCInfo) a power of 2.
size_t padding = 0;
}; };
class V8_EXPORT GCInfoTable final { class V8_EXPORT GCInfoTable final {
......
...@@ -10,9 +10,10 @@ namespace cppgc { ...@@ -10,9 +10,10 @@ namespace cppgc {
namespace internal { namespace internal {
RegisteredGCInfoIndex::RegisteredGCInfoIndex( RegisteredGCInfoIndex::RegisteredGCInfoIndex(
FinalizationCallback finalization_callback, bool has_v_table) FinalizationCallback finalization_callback, TraceCallback trace_callback,
bool has_v_table)
: index_(GlobalGCInfoTable::GetMutable().RegisterNewGCInfo( : index_(GlobalGCInfoTable::GetMutable().RegisterNewGCInfo(
{finalization_callback, has_v_table})) {} {finalization_callback, trace_callback, has_v_table})) {}
} // namespace internal } // namespace internal
} // namespace cppgc } // namespace cppgc
...@@ -61,8 +61,7 @@ const HeapObjectHeader* BasePage::ObjectHeaderFromInnerAddress( ...@@ -61,8 +61,7 @@ const HeapObjectHeader* BasePage::ObjectHeaderFromInnerAddress(
DCHECK_LT(address, DCHECK_LT(address,
reinterpret_cast<ConstAddress>(header) + reinterpret_cast<ConstAddress>(header) +
header->GetSize<HeapObjectHeader::AccessMode::kAtomic>()); header->GetSize<HeapObjectHeader::AccessMode::kAtomic>());
DCHECK_NE(kFreeListGCInfoIndex, DCHECK_NE(kFreeListGCInfoIndex, header->GetGCInfoIndex());
header->GetGCInfoIndex<HeapObjectHeader::AccessMode::kAtomic>());
return header; return header;
} }
......
...@@ -48,18 +48,26 @@ class TestWithHeapWithCustomSpaces : public testing::TestWithPlatform { ...@@ -48,18 +48,26 @@ class TestWithHeapWithCustomSpaces : public testing::TestWithPlatform {
std::unique_ptr<cppgc::Heap> heap_; std::unique_ptr<cppgc::Heap> heap_;
}; };
class RegularGCed final : public GarbageCollected<RegularGCed> {}; class RegularGCed final : public GarbageCollected<RegularGCed> {
public:
void Trace(Visitor*) const {}
};
class CustomGCed1 final : public GarbageCollected<CustomGCed1> { class CustomGCed1 final : public GarbageCollected<CustomGCed1> {
public: public:
~CustomGCed1() { g_destructor_callcount++; } ~CustomGCed1() { g_destructor_callcount++; }
void Trace(Visitor*) const {}
}; };
class CustomGCed2 final : public GarbageCollected<CustomGCed2> { class CustomGCed2 final : public GarbageCollected<CustomGCed2> {
public: public:
~CustomGCed2() { g_destructor_callcount++; } ~CustomGCed2() { g_destructor_callcount++; }
void Trace(Visitor*) const {}
}; };
class CustomGCedBase : public GarbageCollected<CustomGCedBase> {}; class CustomGCedBase : public GarbageCollected<CustomGCedBase> {
public:
void Trace(Visitor*) const {}
};
class CustomGCedFinal1 final : public CustomGCedBase { class CustomGCedFinal1 final : public CustomGCedBase {
public: public:
~CustomGCedFinal1() { g_destructor_callcount++; } ~CustomGCedFinal1() { g_destructor_callcount++; }
......
...@@ -16,7 +16,10 @@ namespace internal { ...@@ -16,7 +16,10 @@ namespace internal {
namespace { namespace {
class GCed : public GarbageCollected<GCed> {}; class GCed : public GarbageCollected<GCed> {
public:
void Trace(Visitor*) const {}
};
class NotGCed {}; class NotGCed {};
class Mixin : public GarbageCollectedMixin {}; class Mixin : public GarbageCollectedMixin {};
class GCedWithMixin : public GarbageCollected<GCedWithMixin>, public Mixin { class GCedWithMixin : public GarbageCollected<GCedWithMixin>, public Mixin {
......
...@@ -23,7 +23,7 @@ TEST(GCInfoTableTest, InitialEmpty) { ...@@ -23,7 +23,7 @@ TEST(GCInfoTableTest, InitialEmpty) {
TEST(GCInfoTableTest, ResizeToMaxIndex) { TEST(GCInfoTableTest, ResizeToMaxIndex) {
v8::base::PageAllocator page_allocator; v8::base::PageAllocator page_allocator;
GCInfoTable table(&page_allocator); GCInfoTable table(&page_allocator);
GCInfo info = {nullptr, false}; GCInfo info = {nullptr, nullptr, false};
for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex; for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
i++) { i++) {
GCInfoIndex index = table.RegisterNewGCInfo(info); GCInfoIndex index = table.RegisterNewGCInfo(info);
...@@ -34,7 +34,7 @@ TEST(GCInfoTableTest, ResizeToMaxIndex) { ...@@ -34,7 +34,7 @@ TEST(GCInfoTableTest, ResizeToMaxIndex) {
TEST(GCInfoTableDeathTest, MoreThanMaxIndexInfos) { TEST(GCInfoTableDeathTest, MoreThanMaxIndexInfos) {
v8::base::PageAllocator page_allocator; v8::base::PageAllocator page_allocator;
GCInfoTable table(&page_allocator); GCInfoTable table(&page_allocator);
GCInfo info = {nullptr, false}; GCInfo info = {nullptr, nullptr, false};
// Create GCInfoTable::kMaxIndex entries. // Create GCInfoTable::kMaxIndex entries.
for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex; for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
i++) { i++) {
...@@ -46,7 +46,7 @@ TEST(GCInfoTableDeathTest, MoreThanMaxIndexInfos) { ...@@ -46,7 +46,7 @@ TEST(GCInfoTableDeathTest, MoreThanMaxIndexInfos) {
TEST(GCInfoTableDeathTest, OldTableAreaIsReadOnly) { TEST(GCInfoTableDeathTest, OldTableAreaIsReadOnly) {
v8::base::PageAllocator page_allocator; v8::base::PageAllocator page_allocator;
GCInfoTable table(&page_allocator); GCInfoTable table(&page_allocator);
GCInfo info = {nullptr, false}; GCInfo info = {nullptr, nullptr, false};
// Use up all slots until limit. // Use up all slots until limit.
GCInfoIndex limit = table.LimitForTesting(); GCInfoIndex limit = table.LimitForTesting();
// Bail out if initial limit is already the maximum because of large committed // Bail out if initial limit is already the maximum because of large committed
...@@ -76,7 +76,7 @@ class ThreadRegisteringGCInfoObjects final : public v8::base::Thread { ...@@ -76,7 +76,7 @@ class ThreadRegisteringGCInfoObjects final : public v8::base::Thread {
num_registrations_(num_registrations) {} num_registrations_(num_registrations) {}
void Run() final { void Run() final {
GCInfo info = {nullptr, false}; GCInfo info = {nullptr, nullptr, false};
for (GCInfoIndex i = 0; i < num_registrations_; i++) { for (GCInfoIndex i = 0; i < num_registrations_; i++) {
table_->RegisterNewGCInfo(info); table_->RegisterNewGCInfo(info);
} }
...@@ -101,7 +101,7 @@ TEST(GCInfoTableTest, MultiThreadedResizeToMaxIndex) { ...@@ -101,7 +101,7 @@ TEST(GCInfoTableTest, MultiThreadedResizeToMaxIndex) {
v8::base::PageAllocator page_allocator; v8::base::PageAllocator page_allocator;
GCInfoTable table(&page_allocator); GCInfoTable table(&page_allocator);
GCInfo info = {nullptr, false}; GCInfo info = {nullptr, nullptr, false};
for (size_t i = 0; i < main_thread_initialized; i++) { for (size_t i = 0; i < main_thread_initialized; i++) {
table.RegisterNewGCInfo(info); table.RegisterNewGCInfo(info);
} }
...@@ -126,8 +126,14 @@ namespace { ...@@ -126,8 +126,14 @@ namespace {
class GCInfoTraitTest : public testing::TestWithPlatform {}; class GCInfoTraitTest : public testing::TestWithPlatform {};
class BasicType final {}; class BasicType final {
class OtherBasicType final {}; public:
void Trace(Visitor*) const {}
};
class OtherBasicType final {
public:
void Trace(Visitor*) const {}
};
} // namespace } // namespace
......
...@@ -36,6 +36,8 @@ class Foo : public GarbageCollected<Foo> { ...@@ -36,6 +36,8 @@ class Foo : public GarbageCollected<Foo> {
Foo() { destructor_callcount = 0; } Foo() { destructor_callcount = 0; }
~Foo() { destructor_callcount++; } ~Foo() { destructor_callcount++; }
void Trace(cppgc::Visitor*) const {}
}; };
size_t Foo::destructor_callcount; size_t Foo::destructor_callcount;
...@@ -43,7 +45,7 @@ size_t Foo::destructor_callcount; ...@@ -43,7 +45,7 @@ size_t Foo::destructor_callcount;
template <size_t Size> template <size_t Size>
class GCed : public GarbageCollected<Foo> { class GCed : public GarbageCollected<Foo> {
public: public:
void Visit(cppgc::Visitor*) {} void Trace(cppgc::Visitor*) const {}
char buf[Size]; char buf[Size];
}; };
......
...@@ -211,6 +211,7 @@ class GCInDestructor final : public GarbageCollected<GCInDestructor> { ...@@ -211,6 +211,7 @@ class GCInDestructor final : public GarbageCollected<GCInDestructor> {
// well. // well.
heap_->CollectGarbage(internal::Heap::GCConfig::Default()); heap_->CollectGarbage(internal::Heap::GCConfig::Default());
} }
void Trace(Visitor*) const {}
private: private:
Heap* heap_; Heap* heap_;
......
...@@ -202,7 +202,7 @@ class GCedWithCustomWeakCallback final ...@@ -202,7 +202,7 @@ class GCedWithCustomWeakCallback final
WeakCallbackDispatcher::Call(broker, this); WeakCallbackDispatcher::Call(broker, this);
} }
void Trace(cppgc::Visitor* visitor) { void Trace(cppgc::Visitor* visitor) const {
visitor->RegisterWeakCallbackMethod< visitor->RegisterWeakCallbackMethod<
GCedWithCustomWeakCallback, GCedWithCustomWeakCallback,
&GCedWithCustomWeakCallback::CustomWeakCallbackMethod>(this); &GCedWithCustomWeakCallback::CustomWeakCallbackMethod>(this);
......
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