diff --git a/deps/v8/include/v8-cppgc.h b/deps/v8/include/v8-cppgc.h index 4a457027c9f76b..e0d76f45016e87 100644 --- a/deps/v8/include/v8-cppgc.h +++ b/deps/v8/include/v8-cppgc.h @@ -177,6 +177,11 @@ class V8_EXPORT CppHeap { void CollectGarbageInYoungGenerationForTesting( cppgc::EmbedderStackState stack_state); + /** + * \returns the wrapper descriptor of this CppHeap. + */ + v8::WrapperDescriptor wrapper_descriptor() const; + private: CppHeap() = default; diff --git a/deps/v8/src/heap/cppgc-js/cpp-heap.cc b/deps/v8/src/heap/cppgc-js/cpp-heap.cc index 7481a81c4a832e..81fe3fb4497d89 100644 --- a/deps/v8/src/heap/cppgc-js/cpp-heap.cc +++ b/deps/v8/src/heap/cppgc-js/cpp-heap.cc @@ -147,6 +147,10 @@ void CppHeap::CollectGarbageInYoungGenerationForTesting( internal::CppHeap::CollectionType::kMinor, stack_state); } +v8::WrapperDescriptor CppHeap::wrapper_descriptor() const { + return internal::CppHeap::From(this)->wrapper_descriptor(); +} + namespace internal { namespace { diff --git a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc index 3934eb8b008515..31b0ee07aac74d 100644 --- a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc +++ b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc @@ -706,4 +706,45 @@ TEST_F(UnifiedHeapTest, TracedReferenceHandlesDoNotLeak) { EXPECT_EQ(initial_count, final_count + 1); } +namespace { +class Wrappable2 final : public cppgc::GarbageCollected { + public: + static size_t destructor_call_count; + void Trace(cppgc::Visitor* visitor) const {} + ~Wrappable2() { destructor_call_count++; } +}; + +size_t Wrappable2::destructor_call_count = 0; +} // namespace + +TEST_F(UnifiedHeapTest, WrapperDescriptorGetter) { + v8::Isolate* isolate = v8_isolate(); + v8::HandleScope scope(isolate); + auto* wrappable_object = + cppgc::MakeGarbageCollected(allocation_handle()); + v8::WrapperDescriptor descriptor = + isolate->GetCppHeap()->wrapper_descriptor(); + v8::Local tmpl = v8::ObjectTemplate::New(isolate); + int size = std::max(descriptor.wrappable_type_index, + descriptor.wrappable_instance_index) + + 1; + tmpl->SetInternalFieldCount(size); + v8::Local api_object = + tmpl->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); + api_object->SetAlignedPointerInInternalField( + descriptor.wrappable_type_index, + &descriptor.embedder_id_for_garbage_collected); + api_object->SetAlignedPointerInInternalField( + descriptor.wrappable_instance_index, wrappable_object); + + Wrappable2::destructor_call_count = 0; + EXPECT_EQ(0u, Wrappable2::destructor_call_count); + CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic); + EXPECT_EQ(0u, Wrappable2::destructor_call_count); + api_object->SetAlignedPointerInInternalField( + descriptor.wrappable_instance_index, nullptr); + CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic); + EXPECT_EQ(1u, Wrappable2::destructor_call_count); +} + } // namespace v8::internal