diff --git a/test/cctest/BUILD.gn b/test/cctest/BUILD.gn index 73191fa71e..e250c36056 100644 --- a/test/cctest/BUILD.gn +++ b/test/cctest/BUILD.gn @@ -182,7 +182,6 @@ v8_source_set("cctest_sources") { "test-disasm-regex-helper.h", "test-field-type-tracking.cc", "test-func-name-inference.cc", - "test-global-handles.cc", "test-heap-profiler.cc", "test-icache.cc", "test-ignition-statistics-extension.cc", diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status index 91e4935ac2..86c5f56694 100644 --- a/test/cctest/cctest.status +++ b/test/cctest/cctest.status @@ -522,7 +522,6 @@ 'test-bignum-dtoa/*': [SKIP], 'test-cpu-profiler/*': [SKIP], 'test-debug/*': [SKIP], - 'test-global-handles/*': [SKIP], 'test-heap-profiler/*': [SKIP], 'test-heap/*': [SKIP], 'test-inobject-slack-tracking/*': [SKIP], @@ -977,13 +976,6 @@ 'test-embedder-tracing/V8RegisteringEmbedderReference': [SKIP], 'test-external-string-tracker/ExternalString_ExternalBackingStoreSizeIncreasesAfterExternalization': [SKIP], 'test-external-string-tracker/ExternalString_ExternalBackingStoreSizeIncreasesMarkCompact': [SKIP], - 'test-global-handles/FinalizerDiesAndKeepsPhantomAliveOnMarkCompact': [SKIP], - 'test-global-handles/FinalizerWeakness': [SKIP], - 'test-global-handles/GCFromWeakCallbacks': [SKIP], - 'test-global-handles/PhantomHandlesWithoutCallbacks': [SKIP], - 'test-global-handles/SecondPassPhantomCallbacks': [SKIP], - 'test-global-handles/WeakHandleToUnmodifiedJSApiObjectDiesOnMarkCompact': [SKIP], - 'test-global-handles/WeakHandleToUnmodifiedJSObjectDiesOnMarkCompact': [SKIP], 'test-heap-profiler/HeapSnapshotDeleteDuringTakeSnapshot': [SKIP], 'test-heap-profiler/HeapSnapshotObjectsStats': [SKIP], 'test-heap-profiler/SamplingHeapProfilerPretenuredInlineAllocations': [SKIP], diff --git a/test/unittests/BUILD.gn b/test/unittests/BUILD.gn index 703bfaf57f..dbf6bc45c2 100644 --- a/test/unittests/BUILD.gn +++ b/test/unittests/BUILD.gn @@ -378,6 +378,7 @@ v8_source_set("unittests_sources") { "heap/embedder-tracing-unittest.cc", "heap/gc-idle-time-handler-unittest.cc", "heap/gc-tracer-unittest.cc", + "heap/global-handles-unittest.cc", "heap/global-safepoint-unittest.cc", "heap/heap-controller-unittest.cc", "heap/heap-unittest.cc", diff --git a/test/unittests/api/api-wasm-unittest.cc b/test/unittests/api/api-wasm-unittest.cc index a205fab24f..269bfab640 100644 --- a/test/unittests/api/api-wasm-unittest.cc +++ b/test/unittests/api/api-wasm-unittest.cc @@ -39,9 +39,7 @@ class ApiWasmTest : public TestWithIsolate { // value is irrelevant. Local promise = Local::Cast(RunJS("WebAssembly.compileStreaming(null)")); - - while (platform::PumpMessageLoop(platform(), isolate())) { - } + EmptyMessageQueues(); CHECK_EQ(expected_state, promise->State()); } }; diff --git a/test/unittests/heap/embedder-tracing-unittest.cc b/test/unittests/heap/embedder-tracing-unittest.cc index 373976e891..3602018c27 100644 --- a/test/unittests/heap/embedder-tracing-unittest.cc +++ b/test/unittests/heap/embedder-tracing-unittest.cc @@ -498,23 +498,6 @@ void ConstructJSApiObject(v8::Isolate* isolate, v8::Local context, EXPECT_FALSE(global->IsEmpty()); } -namespace { - -bool InCorrectGeneration(HeapObject object) { - return FLAG_single_generation ? !i::Heap::InYoungGeneration(object) - : i::Heap::InYoungGeneration(object); -} - -template -bool InCorrectGeneration(v8::Isolate* isolate, - const GlobalOrPersistent& global) { - v8::HandleScope scope(isolate); - auto tmp = global.Get(isolate); - return InCorrectGeneration(*v8::Utils::OpenHandle(*tmp)); -} - -} // namespace - enum class SurvivalMode { kSurvives, kDies }; template handles_count(); auto handle = std::make_unique>(); construct_function(isolate, context, handle.get()); - ASSERT_TRUE(InCorrectGeneration(isolate, *handle)); + ASSERT_TRUE(IsNewObjectInCorrectGeneration(isolate, *handle)); modifier_function(*handle); const size_t after_modification_count = global_handles->handles_count(); gc_function(); @@ -983,7 +966,8 @@ V8_NOINLINE void StackToHeapTest(v8::Isolate* v8_isolate, v8::HandleScope scope(v8_isolate); v8::Local to_object(ConstructTraceableJSApiObject( v8_isolate->GetCurrentContext(), nullptr, nullptr)); - EXPECT_TRUE(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); + EXPECT_TRUE( + IsNewObjectInCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); if (!FLAG_single_generation && target_handling == TargetHandling::kInitializedOldGen) { FullGC(v8_isolate); @@ -1034,7 +1018,8 @@ V8_NOINLINE void HeapToStackTest(v8::Isolate* v8_isolate, v8::HandleScope scope(v8_isolate); v8::Local to_object(ConstructTraceableJSApiObject( v8_isolate->GetCurrentContext(), nullptr, nullptr)); - EXPECT_TRUE(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); + EXPECT_TRUE( + IsNewObjectInCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); if (!FLAG_single_generation && target_handling == TargetHandling::kInitializedOldGen) { FullGC(v8_isolate); @@ -1074,7 +1059,8 @@ V8_NOINLINE void StackToStackTest(v8::Isolate* v8_isolate, v8::HandleScope scope(v8_isolate); v8::Local to_object(ConstructTraceableJSApiObject( v8_isolate->GetCurrentContext(), nullptr, nullptr)); - EXPECT_TRUE(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); + EXPECT_TRUE( + IsNewObjectInCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); if (!FLAG_single_generation && target_handling == TargetHandling::kInitializedOldGen) { FullGC(v8_isolate); diff --git a/test/cctest/test-global-handles.cc b/test/unittests/heap/global-handles-unittest.cc similarity index 65% rename from test/cctest/test-global-handles.cc rename to test/unittests/heap/global-handles-unittest.cc index fb17b2046a..3ce85c90f7 100644 --- a/test/cctest/test-global-handles.cc +++ b/test/unittests/heap/global-handles-unittest.cc @@ -25,16 +25,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "src/handles/global-handles.h" + #include "include/v8-function.h" -#include "include/v8-locker.h" #include "src/api/api-inl.h" #include "src/execution/isolate.h" -#include "src/handles/global-handles.h" #include "src/heap/factory.h" #include "src/heap/heap-inl.h" #include "src/objects/objects-inl.h" -#include "test/cctest/cctest.h" -#include "test/cctest/heap/heap-utils.h" +#include "test/unittests/heap/heap-utils.h" +#include "test/unittests/test-utils.h" +#include "testing/gtest/include/gtest/gtest.h" namespace v8 { namespace internal { @@ -81,12 +82,9 @@ class NonRootingEmbedderHeapTracer final : public v8::EmbedderHeapTracer { std::vector wrappers_; }; -void InvokeScavenge() { CcTest::CollectGarbage(i::NEW_SPACE); } - -void InvokeMarkSweep() { CcTest::CollectAllGarbage(); } - void SimpleCallback(const v8::FunctionCallbackInfo& info) { - info.GetReturnValue().Set(v8_num(0)); + v8::Isolate* isolate = info.GetIsolate(); + info.GetReturnValue().Set(v8::Number::New(isolate, 0)); } struct FlagAndGlobal { @@ -154,7 +152,7 @@ void WeakHandleTest(v8::Isolate* isolate, ConstructFunction construct_function, FlagAndGlobal fp; construct_function(isolate, context, &fp); - CHECK(heap::InCorrectGeneration(isolate, fp.handle)); + CHECK(IsNewObjectInCorrectGeneration(isolate, fp.handle)); fp.handle.SetWeak(&fp, &ResetHandleAndSetFlag, v8::WeakCallbackType::kParameter); fp.flag = false; @@ -164,42 +162,44 @@ void WeakHandleTest(v8::Isolate* isolate, ConstructFunction construct_function, CHECK_IMPLIES(survives == SurvivalMode::kDies, fp.flag); } -template -void TracedReferenceTestWithScavenge(v8::Isolate* isolate, - ConstructFunction construct_function, - ModifierFunction modifier_function, - SurvivalMode survives) { - v8::HandleScope scope(isolate); - v8::Local context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - NonRootingEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - - auto fp = std::make_unique(); - tracer.Register(fp.get()); - construct_function(isolate, context, fp.get()); - CHECK(heap::InCorrectGeneration(isolate, fp->handle)); - modifier_function(fp.get()); - InvokeScavenge(); - // Scavenge clear properly resets the original handle, so we can check the - // handle directly here. - CHECK_IMPLIES(survives == SurvivalMode::kSurvives, !fp->handle.IsEmpty()); - CHECK_IMPLIES(survives == SurvivalMode::kDies, fp->handle.IsEmpty()); -} - void EmptyWeakCallback(const v8::WeakCallbackInfo& data) {} +class GlobalHandlesTest : public TestWithContext { + protected: + template + void TracedReferenceTestWithScavenge(ConstructFunction construct_function, + ModifierFunction modifier_function, + SurvivalMode survives) { + v8::Isolate* isolate = v8_isolate(); + v8::HandleScope scope(isolate); + v8::Local context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + + NonRootingEmbedderHeapTracer tracer; + TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); + + auto fp = std::make_unique(); + tracer.Register(fp.get()); + construct_function(isolate, context, fp.get()); + CHECK(IsNewObjectInCorrectGeneration(isolate, fp->handle)); + modifier_function(fp.get()); + CollectGarbage(i::NEW_SPACE); + // Scavenge clear properly resets the original handle, so we can check the + // handle directly here. + CHECK_IMPLIES(survives == SurvivalMode::kSurvives, !fp->handle.IsEmpty()); + CHECK_IMPLIES(survives == SurvivalMode::kDies, fp->handle.IsEmpty()); + } +}; + } // namespace -TEST(EternalHandles) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); +TEST_F(GlobalHandlesTest, EternalHandles) { + Isolate* isolate = i_isolate(); v8::Isolate* v8_isolate = reinterpret_cast(isolate); EternalHandles* eternal_handles = isolate->eternal_handles(); // Create a number of handles that will not be on a block boundary - const int kArrayLength = 2048-1; + const int kArrayLength = 2048 - 1; int indices[kArrayLength]; v8::Eternal eternals[kArrayLength]; @@ -208,19 +208,20 @@ TEST(EternalHandles) { indices[i] = -1; HandleScope scope(isolate); v8::Local object = v8::Object::New(v8_isolate); - object->Set(v8_isolate->GetCurrentContext(), i, - v8::Integer::New(v8_isolate, i)) + object + ->Set(v8_isolate->GetCurrentContext(), i, + v8::Integer::New(v8_isolate, i)) .FromJust(); // Create with internal api - eternal_handles->Create( - isolate, *v8::Utils::OpenHandle(*object), &indices[i]); + eternal_handles->Create(isolate, *v8::Utils::OpenHandle(*object), + &indices[i]); // Create with external api CHECK(eternals[i].IsEmpty()); eternals[i].Set(v8_isolate, object); CHECK(!eternals[i].IsEmpty()); } - CcTest::CollectAllAvailableGarbage(); + CollectAllAvailableGarbage(); for (int i = 0; i < kArrayLength; i++) { for (int j = 0; j < 2; j++) { @@ -256,10 +257,8 @@ TEST(EternalHandles) { CHECK_EQ(2 * kArrayLength + 1, eternal_handles->handles_count()); } - -TEST(PersistentBaseGetLocal) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); +TEST_F(GlobalHandlesTest, PersistentBaseGetLocal) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Local o = v8::Object::New(isolate); @@ -273,9 +272,8 @@ TEST(PersistentBaseGetLocal) { CHECK(v8::Local::New(isolate, g) == g.Get(isolate)); } -TEST(WeakPersistentSmi) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); +TEST_F(GlobalHandlesTest, WeakPersistentSmi) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Local n = v8::Number::New(isolate, 0); @@ -288,9 +286,8 @@ TEST(WeakPersistentSmi) { START_ALLOW_USE_DEPRECATED() -TEST(PhantomHandlesWithoutCallbacks) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); +TEST_F(GlobalHandlesTest, PhantomHandlesWithoutCallbacks) { + v8::Isolate* isolate = v8_isolate(); v8::Global g1, g2; { @@ -302,129 +299,127 @@ TEST(PhantomHandlesWithoutCallbacks) { } CHECK(!g1.IsEmpty()); CHECK(!g2.IsEmpty()); - CcTest::CollectAllAvailableGarbage(); + CollectAllAvailableGarbage(); CHECK(g1.IsEmpty()); CHECK(g2.IsEmpty()); } END_ALLOW_USE_DEPRECATED() -TEST(WeakHandleToUnmodifiedJSObjectDiesOnScavenge) { +TEST_F(GlobalHandlesTest, WeakHandleToUnmodifiedJSObjectDiesOnScavenge) { if (FLAG_single_generation) return; - CcTest::InitializeVM(); + WeakHandleTest( - CcTest::isolate(), &ConstructJSObject, - [](FlagAndGlobal* fp) {}, []() { InvokeScavenge(); }, - SurvivalMode::kDies); + v8_isolate(), &ConstructJSObject, [](FlagAndGlobal* fp) {}, + [this]() { CollectGarbage(i::NEW_SPACE); }, SurvivalMode::kDies); } -TEST(TracedReferenceToUnmodifiedJSObjectSurvivesScavenge) { +TEST_F(GlobalHandlesTest, TracedReferenceToUnmodifiedJSObjectSurvivesScavenge) { if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); + + ManualGCScope manual_gc(i_isolate()); TracedReferenceTestWithScavenge( - CcTest::isolate(), &ConstructJSObject, + &ConstructJSObject, [](TracedReferenceWrapper* fp) {}, SurvivalMode::kSurvives); } -TEST(WeakHandleToUnmodifiedJSObjectDiesOnMarkCompact) { - CcTest::InitializeVM(); +TEST_F(GlobalHandlesTest, WeakHandleToUnmodifiedJSObjectDiesOnMarkCompact) { WeakHandleTest( - CcTest::isolate(), &ConstructJSObject, - [](FlagAndGlobal* fp) {}, []() { InvokeMarkSweep(); }, - SurvivalMode::kDies); + v8_isolate(), &ConstructJSObject, [](FlagAndGlobal* fp) {}, + [this]() { CollectAllGarbage(); }, SurvivalMode::kDies); } -TEST(WeakHandleToUnmodifiedJSObjectSurvivesMarkCompactWhenInHandle) { - CcTest::InitializeVM(); +TEST_F(GlobalHandlesTest, + WeakHandleToUnmodifiedJSObjectSurvivesMarkCompactWhenInHandle) { WeakHandleTest( - CcTest::isolate(), &ConstructJSObject, - [](FlagAndGlobal* fp) { + v8_isolate(), &ConstructJSObject, + [this](FlagAndGlobal* fp) { v8::Local handle = - v8::Local::New(CcTest::isolate(), fp->handle); + v8::Local::New(v8_isolate(), fp->handle); USE(handle); }, - []() { InvokeMarkSweep(); }, SurvivalMode::kSurvives); + [this]() { CollectAllGarbage(); }, SurvivalMode::kSurvives); } -TEST(WeakHandleToUnmodifiedJSApiObjectDiesOnScavenge) { +TEST_F(GlobalHandlesTest, WeakHandleToUnmodifiedJSApiObjectDiesOnScavenge) { if (FLAG_single_generation) return; - CcTest::InitializeVM(); + WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndGlobal* fp) {}, []() { InvokeScavenge(); }, + v8_isolate(), &ConstructJSApiObject, + [](FlagAndGlobal* fp) {}, [this]() { CollectGarbage(i::NEW_SPACE); }, SurvivalMode::kDies); } -TEST(TracedReferenceToUnmodifiedJSApiObjectDiesOnScavenge) { +TEST_F(GlobalHandlesTest, + TracedReferenceToUnmodifiedJSApiObjectDiesOnScavenge) { if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); + + ManualGCScope manual_gc(i_isolate()); TracedReferenceTestWithScavenge( - CcTest::isolate(), &ConstructJSApiObject, + &ConstructJSApiObject, [](TracedReferenceWrapper* fp) {}, SurvivalMode::kDies); } -TEST(TracedReferenceToJSApiObjectWithIdentityHashSurvivesScavenge) { +TEST_F(GlobalHandlesTest, + TracedReferenceToJSApiObjectWithIdentityHashSurvivesScavenge) { if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - Isolate* i_isolate = CcTest::i_isolate(); - HandleScope scope(i_isolate); - Handle weakmap = i_isolate->factory()->NewJSWeakMap(); + ManualGCScope manual_gc(i_isolate()); + Isolate* isolate = i_isolate(); + HandleScope scope(isolate); + Handle weakmap = isolate->factory()->NewJSWeakMap(); TracedReferenceTestWithScavenge( - CcTest::isolate(), &ConstructJSApiObject, - [&weakmap, i_isolate](TracedReferenceWrapper* fp) { - v8::HandleScope scope(CcTest::isolate()); + &ConstructJSApiObject, + [this, &weakmap, isolate](TracedReferenceWrapper* fp) { + v8::HandleScope scope(v8_isolate()); Handle key = - Utils::OpenHandle(*fp->handle.Get(CcTest::isolate())); - Handle smi(Smi::FromInt(23), i_isolate); - int32_t hash = key->GetOrCreateHash(i_isolate).value(); + Utils::OpenHandle(*fp->handle.Get(v8_isolate())); + Handle smi(Smi::FromInt(23), isolate); + int32_t hash = key->GetOrCreateHash(isolate).value(); JSWeakCollection::Set(weakmap, key, smi, hash); }, SurvivalMode::kSurvives); } -TEST(WeakHandleToUnmodifiedJSApiObjectSurvivesScavengeWhenInHandle) { +TEST_F(GlobalHandlesTest, + WeakHandleToUnmodifiedJSApiObjectSurvivesScavengeWhenInHandle) { if (FLAG_single_generation) return; - CcTest::InitializeVM(); + WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndGlobal* fp) { + v8_isolate(), &ConstructJSApiObject, + [this](FlagAndGlobal* fp) { v8::Local handle = - v8::Local::New(CcTest::isolate(), fp->handle); + v8::Local::New(v8_isolate(), fp->handle); USE(handle); }, - []() { InvokeScavenge(); }, SurvivalMode::kSurvives); + [this]() { CollectGarbage(i::NEW_SPACE); }, SurvivalMode::kSurvives); } -TEST(WeakHandleToUnmodifiedJSApiObjectDiesOnMarkCompact) { - CcTest::InitializeVM(); +TEST_F(GlobalHandlesTest, WeakHandleToUnmodifiedJSApiObjectDiesOnMarkCompact) { WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndGlobal* fp) {}, []() { InvokeMarkSweep(); }, + v8_isolate(), &ConstructJSApiObject, + [](FlagAndGlobal* fp) {}, [this]() { CollectAllGarbage(); }, SurvivalMode::kDies); } -TEST(WeakHandleToUnmodifiedJSApiObjectSurvivesMarkCompactWhenInHandle) { - CcTest::InitializeVM(); +TEST_F(GlobalHandlesTest, + WeakHandleToUnmodifiedJSApiObjectSurvivesMarkCompactWhenInHandle) { WeakHandleTest( - CcTest::isolate(), &ConstructJSApiObject, - [](FlagAndGlobal* fp) { + v8_isolate(), &ConstructJSApiObject, + [this](FlagAndGlobal* fp) { v8::Local handle = - v8::Local::New(CcTest::isolate(), fp->handle); + v8::Local::New(v8_isolate(), fp->handle); USE(handle); }, - []() { InvokeMarkSweep(); }, SurvivalMode::kSurvives); + [this]() { CollectAllGarbage(); }, SurvivalMode::kSurvives); } -TEST(TracedReferenceToJSApiObjectWithModifiedMapSurvivesScavenge) { +TEST_F(GlobalHandlesTest, + TracedReferenceToJSApiObjectWithModifiedMapSurvivesScavenge) { if (FLAG_single_generation) return; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - LocalContext context; + + v8::Isolate* isolate = v8_isolate(); TracedReference handle; { @@ -434,19 +429,19 @@ TEST(TracedReferenceToJSApiObjectWithModifiedMapSurvivesScavenge) { auto instance_t = function_template->InstanceTemplate(); instance_t->Set(isolate, "a", v8::Number::New(isolate, 10)); auto function = - function_template->GetFunction(context.local()).ToLocalChecked(); - auto i = function->NewInstance(context.local()).ToLocalChecked(); + function_template->GetFunction(v8_context()).ToLocalChecked(); + auto i = function->NewInstance(v8_context()).ToLocalChecked(); handle.Reset(isolate, i); } - InvokeScavenge(); + CollectGarbage(i::NEW_SPACE); CHECK(!handle.IsEmpty()); } -TEST(TracedReferenceTOJsApiObjectWithElementsSurvivesScavenge) { +TEST_F(GlobalHandlesTest, + TracedReferenceTOJsApiObjectWithElementsSurvivesScavenge) { if (FLAG_single_generation) return; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - LocalContext context; + + v8::Isolate* isolate = v8_isolate(); TracedReference handle; { @@ -458,11 +453,11 @@ TEST(TracedReferenceTOJsApiObjectWithElementsSurvivesScavenge) { instance_t->Set(isolate, "1", v8::Number::New(isolate, 10)); instance_t->Set(isolate, "2", v8::Number::New(isolate, 10)); auto function = - function_template->GetFunction(context.local()).ToLocalChecked(); - auto i = function->NewInstance(context.local()).ToLocalChecked(); + function_template->GetFunction(v8_context()).ToLocalChecked(); + auto i = function->NewInstance(v8_context()).ToLocalChecked(); handle.Reset(isolate, i); } - InvokeScavenge(); + CollectGarbage(i::NEW_SPACE); CHECK(!handle.IsEmpty()); } @@ -470,7 +465,7 @@ namespace { void ForceScavenge2(const v8::WeakCallbackInfo& data) { data.GetParameter()->flag = true; - InvokeScavenge(); + YoungGC(data.GetIsolate()); } void ForceScavenge1(const v8::WeakCallbackInfo& data) { @@ -480,7 +475,7 @@ void ForceScavenge1(const v8::WeakCallbackInfo& data) { void ForceMarkSweep2(const v8::WeakCallbackInfo& data) { data.GetParameter()->flag = true; - InvokeMarkSweep(); + FullGC(data.GetIsolate()); } void ForceMarkSweep1(const v8::WeakCallbackInfo& data) { @@ -490,9 +485,8 @@ void ForceMarkSweep1(const v8::WeakCallbackInfo& data) { } // namespace -TEST(GCFromWeakCallbacks) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Locker locker(CcTest::isolate()); +TEST_F(GlobalHandlesTest, GCFromWeakCallbacks) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -500,11 +494,11 @@ TEST(GCFromWeakCallbacks) { if (FLAG_single_generation) { FlagAndGlobal fp; ConstructJSApiObject(isolate, context, &fp); - CHECK(!heap::InYoungGeneration(isolate, fp.handle)); + CHECK(!InYoungGeneration(isolate, fp.handle)); fp.flag = false; fp.handle.SetWeak(&fp, &ForceMarkSweep1, v8::WeakCallbackType::kParameter); - InvokeMarkSweep(); - EmptyMessageQueues(isolate); + CollectAllGarbage(); + EmptyMessageQueues(); CHECK(fp.flag); return; } @@ -514,19 +508,21 @@ TEST(GCFromWeakCallbacks) { Callback gc_forcing_callback[kNumberOfGCTypes] = {&ForceScavenge1, &ForceMarkSweep1}; - using GCInvoker = void (*)(); - GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; + using GCInvoker = std::function; + GCInvoker invoke_gc[kNumberOfGCTypes] = { + [this]() { CollectGarbage(i::NEW_SPACE); }, + [this]() { CollectAllGarbage(); }}; for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { FlagAndGlobal fp; ConstructJSApiObject(isolate, context, &fp); - CHECK(heap::InYoungGeneration(isolate, fp.handle)); + CHECK(InYoungGeneration(isolate, fp.handle)); fp.flag = false; fp.handle.SetWeak(&fp, gc_forcing_callback[inner_gc], v8::WeakCallbackType::kParameter); invoke_gc[outer_gc](); - EmptyMessageQueues(isolate); + EmptyMessageQueues(); CHECK(fp.flag); } } @@ -545,9 +541,8 @@ void FirstPassCallback(const v8::WeakCallbackInfo& data) { } // namespace -TEST(SecondPassPhantomCallbacks) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Locker locker(CcTest::isolate()); +TEST_F(GlobalHandlesTest, SecondPassPhantomCallbacks) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); @@ -556,72 +551,65 @@ TEST(SecondPassPhantomCallbacks) { fp.flag = false; fp.handle.SetWeak(&fp, FirstPassCallback, v8::WeakCallbackType::kParameter); CHECK(!fp.flag); - InvokeMarkSweep(); - InvokeMarkSweep(); + CollectAllGarbage(); + CollectAllGarbage(); CHECK(fp.flag); } -TEST(MoveStrongGlobal) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); +TEST_F(GlobalHandlesTest, MoveStrongGlobal) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Global* global = new Global(); ConstructJSObject(isolate, global); - InvokeMarkSweep(); + CollectAllGarbage(); v8::Global global2(std::move(*global)); delete global; - InvokeMarkSweep(); + CollectAllGarbage(); } -TEST(MoveWeakGlobal) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); +TEST_F(GlobalHandlesTest, MoveWeakGlobal) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Global* global = new Global(); ConstructJSObject(isolate, global); - InvokeMarkSweep(); + CollectAllGarbage(); global->SetWeak(); v8::Global global2(std::move(*global)); delete global; - InvokeMarkSweep(); + CollectAllGarbage(); } -TEST(TotalSizeRegularNode) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - Isolate* i_isolate = CcTest::i_isolate(); +TEST_F(GlobalHandlesTest, TotalSizeRegularNode) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::Global* global = new Global(); - CHECK_EQ(i_isolate->global_handles()->TotalSize(), 0); - CHECK_EQ(i_isolate->global_handles()->UsedSize(), 0); + CHECK_EQ(i_isolate()->global_handles()->TotalSize(), 0); + CHECK_EQ(i_isolate()->global_handles()->UsedSize(), 0); ConstructJSObject(isolate, global); - CHECK_GT(i_isolate->global_handles()->TotalSize(), 0); - CHECK_GT(i_isolate->global_handles()->UsedSize(), 0); + CHECK_GT(i_isolate()->global_handles()->TotalSize(), 0); + CHECK_GT(i_isolate()->global_handles()->UsedSize(), 0); delete global; - CHECK_GT(i_isolate->global_handles()->TotalSize(), 0); - CHECK_EQ(i_isolate->global_handles()->UsedSize(), 0); + CHECK_GT(i_isolate()->global_handles()->TotalSize(), 0); + CHECK_EQ(i_isolate()->global_handles()->UsedSize(), 0); } -TEST(TotalSizeTracedNode) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - Isolate* i_isolate = CcTest::i_isolate(); +TEST_F(GlobalHandlesTest, TotalSizeTracedNode) { + v8::Isolate* isolate = v8_isolate(); v8::HandleScope scope(isolate); v8::TracedReference* handle = new TracedReference(); - CHECK_EQ(i_isolate->global_handles()->TotalSize(), 0); - CHECK_EQ(i_isolate->global_handles()->UsedSize(), 0); + CHECK_EQ(i_isolate()->global_handles()->TotalSize(), 0); + CHECK_EQ(i_isolate()->global_handles()->UsedSize(), 0); ConstructJSObject(isolate, handle); - CHECK_GT(i_isolate->global_handles()->TotalSize(), 0); - CHECK_GT(i_isolate->global_handles()->UsedSize(), 0); + CHECK_GT(i_isolate()->global_handles()->TotalSize(), 0); + CHECK_GT(i_isolate()->global_handles()->UsedSize(), 0); delete handle; - InvokeMarkSweep(); - CHECK_GT(i_isolate->global_handles()->TotalSize(), 0); - CHECK_EQ(i_isolate->global_handles()->UsedSize(), 0); + CollectAllGarbage(); + CHECK_GT(i_isolate()->global_handles()->TotalSize(), 0); + CHECK_EQ(i_isolate()->global_handles()->UsedSize(), 0); } } // namespace internal diff --git a/test/unittests/heap/heap-utils.cc b/test/unittests/heap/heap-utils.cc index 91ee7206d2..9d8f8a62d9 100644 --- a/test/unittests/heap/heap-utils.cc +++ b/test/unittests/heap/heap-utils.cc @@ -220,5 +220,10 @@ std::vector> HeapInternalsBase::CreatePadding( return handles; } +bool IsNewObjectInCorrectGeneration(HeapObject object) { + return FLAG_single_generation ? !i::Heap::InYoungGeneration(object) + : i::Heap::InYoungGeneration(object); +} + } // namespace internal } // namespace v8 diff --git a/test/unittests/heap/heap-utils.h b/test/unittests/heap/heap-utils.h index fa1de178de..8375d7ddeb 100644 --- a/test/unittests/heap/heap-utils.h +++ b/test/unittests/heap/heap-utils.h @@ -99,6 +99,22 @@ class WithHeapInternals : public TMixin, HeapInternalsBase { } }; +class V8_NODISCARD TemporaryEmbedderHeapTracerScope { + public: + TemporaryEmbedderHeapTracerScope(v8::Isolate* isolate, + v8::EmbedderHeapTracer* tracer) + : isolate_(isolate) { + isolate_->SetEmbedderHeapTracer(tracer); + } + + ~TemporaryEmbedderHeapTracerScope() { + isolate_->SetEmbedderHeapTracer(nullptr); + } + + private: + v8::Isolate* const isolate_; +}; + using TestWithHeapInternals = // WithHeapInternals< // WithInternalIsolateMixin< // @@ -121,6 +137,24 @@ inline void YoungGC(v8::Isolate* isolate) { i::NEW_SPACE, i::GarbageCollectionReason::kTesting); } +template +bool InYoungGeneration(v8::Isolate* isolate, const GlobalOrPersistent& global) { + CHECK(!FLAG_single_generation); + v8::HandleScope scope(isolate); + auto tmp = global.Get(isolate); + return i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*tmp)); +} + +bool IsNewObjectInCorrectGeneration(HeapObject object); + +template +bool IsNewObjectInCorrectGeneration(v8::Isolate* isolate, + const GlobalOrPersistent& global) { + v8::HandleScope scope(isolate); + auto tmp = global.Get(isolate); + return IsNewObjectInCorrectGeneration(*v8::Utils::OpenHandle(*tmp)); +} + } // namespace internal } // namespace v8 diff --git a/test/unittests/test-utils.h b/test/unittests/test-utils.h index 0a6a48da11..4dce8c91f2 100644 --- a/test/unittests/test-utils.h +++ b/test/unittests/test-utils.h @@ -211,6 +211,12 @@ class WithIsolateScopeMixin : public TMixin { return v8::String::NewFromUtf8(this->v8_isolate(), string).ToLocalChecked(); } + void EmptyMessageQueues() { + while (v8::platform::PumpMessageLoop(internal::V8::GetCurrentPlatform(), + this->v8_isolate())) { + } + } + private: Local RunJS(Local source) { return TryRunJS(source).ToLocalChecked(); diff --git a/test/unittests/unittests.status b/test/unittests/unittests.status index ecfbe39afb..58319b7bd8 100644 --- a/test/unittests/unittests.status +++ b/test/unittests/unittests.status @@ -203,6 +203,13 @@ # Performs GC 'APIExceptionTest.ExceptionMessageDoesNotKeepContextAlive': [SKIP], + 'GlobalHandlesTest.FinalizerDiesAndKeepsPhantomAliveOnMarkCompact': [SKIP], + 'GlobalHandlesTest.FinalizerWeakness': [SKIP], + 'GlobalHandlesTest.GCFromWeakCallbacks': [SKIP], + 'GlobalHandlesTest.PhantomHandlesWithoutCallbacks': [SKIP], + 'GlobalHandlesTest.SecondPassPhantomCallbacks': [SKIP], + 'GlobalHandlesTest.WeakHandleToUnmodifiedJSApiObjectDiesOnMarkCompact': [SKIP], + 'GlobalHandlesTest.WeakHandleToUnmodifiedJSObjectDiesOnMarkCompact': [SKIP], 'LocalHeapTest.GCEpilogue': [SKIP], 'UnifiedHeapDetachedTest.AllocationBeforeConfigureHeap': [SKIP], 'UnifiedHeapTest.FindingV8ToBlinkReference': [SKIP], @@ -283,6 +290,7 @@ 'BignumDtoaTest.*': [SKIP], 'DtoaTest.*': [SKIP], 'DeclsTest.*': [SKIP], + 'GlobalHandlesTest.*': [SKIP], }], # variant == no_wasm_traps ##############################################################################