From d6862b085c33972a2dd24d5d7f1699b363856f02 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 26 Jun 2023 19:40:22 +0200 Subject: [PATCH] deps: V8: cherry-pick 93275031284c Original commit message: [cppgc] expose wrapper descriptor on CppHeap This makes it possible for embedders to: 1. Avoid creating wrapper objects that happen to have a layout that leads V8 to consider the object cppgc-managed while it's not. Refs: https://github.com/nodejs/node/pull/43521 2. Create cppgc-managed wrapper objects when they do not own the CppHeap. Refs: https://github.com/nodejs/node/pull/45704 Bug: v8:13960 Change-Id: If31f4d56c5ead59dc0d56f937494d23d631f7438 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4598833 Reviewed-by: Michael Lippautz Commit-Queue: Michael Lippautz Cr-Commit-Position: refs/heads/main@{#88490} Refs: https://github.com/v8/v8/commit/93275031284c66be7852b13f1b18a8bbe7f3a0a9 PR-URL: https://github.com/nodejs/node/pull/48660 Backport-PR-URL: https://github.com/nodejs/node/pull/49187 Reviewed-By: Chengzhong Wu Reviewed-By: Jiawen Geng Refs: https://github.com/nodejs/node/issues/40786 Refs: https://docs.google.com/document/d/1ny2Qz_EsUnXGKJRGxoA-FXIE2xpLgaMAN6jD7eAkqFQ/edit --- common.gypi | 2 +- deps/v8/include/v8-cppgc.h | 5 +++ deps/v8/src/heap/cppgc-js/cpp-heap.cc | 4 ++ .../heap/cppgc-js/unified-heap-unittest.cc | 41 +++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/common.gypi b/common.gypi index 87e9d4ebfc0ab2..6b170a52c37725 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.13', + 'v8_embedder_string': '-node.14', ##### V8 defaults for Node.js ##### 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