From a6723bde01e17da3056b727e7c9f5070674676bf Mon Sep 17 00:00:00 2001 From: Artem Udovichenko Date: Thu, 11 Aug 2022 19:24:22 +0300 Subject: [PATCH] Add a test for G1GC Change-Id: I486ab50acc1fd892025e8e15c080c7ebf11e81bf Signed-off-by: Artem Udovichenko --- tests/runtime/mem/g1gc_barrier_test.cpp | 78 +++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/runtime/mem/g1gc_barrier_test.cpp b/tests/runtime/mem/g1gc_barrier_test.cpp index 8cda01f84..27cb4481e 100644 --- a/tests/runtime/mem/g1gc_barrier_test.cpp +++ b/tests/runtime/mem/g1gc_barrier_test.cpp @@ -7,6 +7,7 @@ #include "runtime/mem/gc/gc.h" #include "runtime/include/runtime.h" #include "runtime/mem/heap_manager.h" +#include "runtime/mem/gc/g1/g1-allocator.h" #include "runtime/include/thread_scopes.h" #include "plugins/ecmascript/runtime/js_thread.h" #include "plugins/ecmascript/runtime/ecma_string.h" @@ -116,4 +117,81 @@ TEST_F(G1GCBarrierTest, TestPreBarrier) task.Run(*gc); ASSERT_TRUE(listener.has_concurrent_mark); } + +class G1GCClassCollectionTest : public testing::TestWithParam { +public: + G1GCClassCollectionTest() + { + RuntimeOptions options; + options.SetBootClassSpaces({"ecmascript"}); + options.SetRuntimeType("ecmascript"); + options.SetGcType("g1-gc"); + options.SetRunGcInPlace(true); + options.SetG1TrackFreedObjects(GetParam() ? "true" : "false"); + options.SetCompilerEnableJit(false); + options.SetGcWorkersCount(0); + options.SetGcTriggerType("debug-never"); + options.SetShouldLoadBootPandaFiles(false); + options.SetShouldInitializeIntrinsics(false); + + Runtime::Create(options); + + thread_ = JSThread::GetCurrent(); + } + + ~G1GCClassCollectionTest() + { + Runtime::Destroy(); + } + + JSHandle AllocClass() + { + const GlobalEnvConstants *global_const = thread_->GlobalConstants(); + ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory(); + JSHClass *root_hclass = JSHClass::Cast(global_const->GetHClassClass().GetTaggedObject()); + return factory->NewEcmaDynClass(root_hclass, 0, JSType::JS_OBJECT); + } + + mem::ObjectAllocatorG1<> *GetAllocator() + { + Runtime *runtime = Runtime::GetCurrent(); + mem::GC *gc = runtime->GetPandaVM()->GetGC(); + return static_cast *>(gc->GetObjectAllocator()); + } + + JSThread *thread_; +}; + +TEST_P(G1GCClassCollectionTest, TestCollectClasses) +{ + JSHClass *hclass = nullptr; + { + [[maybe_unused]] EcmaHandleScope scope(thread_); + JSHandle hclass_handle = AllocClass(); + // JSHClass is allocated in the non-movable space so we can use raw pointer safe + hclass = hclass_handle.GetObject(); + } + ASSERT_NE(nullptr, hclass); + mem::Region *region = mem::ObjectToRegion(hclass); + ASSERT_TRUE(region->HasFlag(mem::IS_NONMOVABLE)); + mem::GC *gc = thread_->GetVM()->GetGC(); + + GCTask task(GCTaskCause::HEAP_USAGE_THRESHOLD_CAUSE); // trigger concurrent marking + task.Run(*gc); + bool found = false; + GetAllocator()->IterateRegularSizeObjects([hclass, &found](ObjectHeader *obj) { + if (obj == hclass) { + found = true; + } + }); + if (GetParam()) { + // Tracking freed objects is enabled. We cannot delete the class. + ASSERT_TRUE(found); + } else { + // Tracking freed objects is disabled. We should delete the class. + ASSERT_FALSE(found); + } +} + +INSTANTIATE_TEST_SUITE_P(G1GCClassCollectionTestSuite, G1GCClassCollectionTest, testing::Values(true, false)); } // namespace panda::ecmascript -- Gitee