• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/tests/ecma_test_common.h"
17 
18 using namespace panda;
19 
20 using namespace panda::ecmascript;
21 
22 namespace panda::test {
23 class SharedTestSpace;
24 class SharedPartialGCTest : public BaseTestWithScope<false> {
25 public:
26     JSHandle<TaggedObject> CreateSharedObjectsInOneRegion(std::shared_ptr<SharedTestSpace> space, double aliveRate);
27     void InitTaggedArray(TaggedObject *obj, size_t arrayLen);
28     void CreateTaggedArray();
29 };
30 
31 class SharedTestSpace : public Space {
32 public:
33     static constexpr size_t CAP = 10 * 1024 * 1024;
SharedTestSpace(SharedHeap * heap)34     explicit SharedTestSpace(SharedHeap *heap)
35         : Space(heap, heap->GetHeapRegionAllocator(), MemSpaceType::SHARED_OLD_SPACE, CAP, CAP), sHeap_(heap) {}
36     ~SharedTestSpace() override = default;
37     NO_COPY_SEMANTIC(SharedTestSpace);
38     NO_MOVE_SEMANTIC(SharedTestSpace);
39 
Expand(JSThread * thread)40     void Expand(JSThread *thread)
41     {
42         Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE, thread, sHeap_);
43         FillBumpPointer();
44         allocator_.Reset(region->GetBegin(), region->GetEnd());
45     }
46 
Allocate(size_t size)47     uintptr_t Allocate(size_t size)
48     {
49         return allocator_.Allocate(size);
50     }
51 
GetTop()52     uintptr_t GetTop()
53     {
54         return allocator_.GetTop();
55     }
56 
FillBumpPointer()57     void FillBumpPointer()
58     {
59         auto begin = allocator_.GetTop();
60         auto size = allocator_.Available();
61         FreeObject::FillFreeObject(sHeap_, begin, size);
62     }
63 
GetEnd()64     uintptr_t GetEnd()
65     {
66         return allocator_.GetEnd();
67     }
68 private:
69     SharedHeap *sHeap_ {nullptr};
70     BumpPointerAllocator allocator_;
71 };
72 
InitTaggedArray(TaggedObject * obj,size_t arrayLen)73 void SharedPartialGCTest::InitTaggedArray(TaggedObject *obj, size_t arrayLen)
74 {
75     JSHClass *arrayClass = JSHClass::Cast(thread->GlobalConstants()->GetTaggedArrayClass().GetTaggedObject());
76     obj->SetClassWithoutBarrier(arrayClass);
77     TaggedArray::Cast(obj)->InitializeWithSpecialValue(JSTaggedValue::Undefined(), arrayLen);
78 }
79 
CreateSharedObjectsInOneRegion(std::shared_ptr<SharedTestSpace> space,double aliveRate)80 JSHandle<TaggedObject> SharedPartialGCTest::CreateSharedObjectsInOneRegion(std::shared_ptr<SharedTestSpace> space,
81     double aliveRate)
82 {
83     constexpr size_t TAGGED_TYPE_SIZE = 8;
84     space->Expand(thread);
85     size_t totalSize = space->GetEnd() - space->GetTop();
86     size_t alive = totalSize * aliveRate;
87     size_t arrayLen = alive / TAGGED_TYPE_SIZE;
88     size_t size = TaggedArray::ComputeSize(TAGGED_TYPE_SIZE, arrayLen);
89     TaggedObject *obj = reinterpret_cast<TaggedObject *>(space->Allocate(size));
90     EXPECT_TRUE(obj != nullptr);
91     InitTaggedArray(obj, arrayLen);
92     return JSHandle<TaggedObject>(thread, obj);
93 }
94 
HWTEST_F_L0(SharedPartialGCTest,PartialGCTest)95 HWTEST_F_L0(SharedPartialGCTest, PartialGCTest)
96 {
97     constexpr double ALIVE_RATE = 0.1;
98     constexpr size_t ARRAY_SIZE = SharedOldSpace::MIN_COLLECT_REGION_SIZE;
99     instance->GetJSOptions().SetEnableForceGC(false);
100     Heap *heap = const_cast<Heap *>(instance->GetHeap());
101     SharedHeap *sHeap = SharedHeap::GetInstance();
102     ObjectFactory *factory = heap->GetEcmaVM()->GetFactory();
103     JSHandle<TaggedArray> localObj = factory->NewTaggedArray(ARRAY_SIZE, JSTaggedValue::Undefined(), false);
104     heap->CollectGarbage(TriggerGCType::FULL_GC);
105     sHeap->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread);
106     heap->GetHeapPrepare();
107     SharedOldSpace *sOldSpace = sHeap->GetOldSpace();
108     std::shared_ptr<SharedTestSpace> space= std::make_shared<SharedTestSpace>(sHeap);
109     std::vector<std::pair<Region*, JSHandle<TaggedObject>>> checkObjList;
110     for (size_t i = 0; i < SharedOldSpace::MIN_COLLECT_REGION_SIZE; i++) {
111         auto obj = CreateSharedObjectsInOneRegion(space, ALIVE_RATE);
112         Region *region = Region::ObjectAddressToRange(*obj);
113         checkObjList.emplace_back(region, obj);
114         sOldSpace->AddRegion(region);
115     }
116     space->FillBumpPointer();
117     EXPECT_TRUE(sHeap->CheckCanTriggerConcurrentMarking(thread));
118     sHeap->TriggerConcurrentMarking<TriggerGCType::SHARED_PARTIAL_GC, MarkReason::OTHER>(thread);
119     while (!thread->HasSuspendRequest());
120     thread->CheckSafepointIfSuspended();
121     if (thread->IsSharedConcurrentMarkingOrFinished()) {
122         EXPECT_TRUE(sOldSpace->GetCollectSetRegionCount() > 0);
123         Region *localRegion = Region::ObjectAddressToRange(*localObj);
124         for (uint32_t i = 0; i < SharedOldSpace::MIN_COLLECT_REGION_SIZE; i++) {
125             auto each = checkObjList[i];
126             Region *checkRegion = each.first;
127             JSHandle<TaggedObject> checkObj = each.second;
128             EXPECT_TRUE(checkRegion->InSCollectSet());
129             localObj->Set(thread, i, checkObj);
130             JSTaggedType *localSlot = localObj->GetData() + i;
131             EXPECT_TRUE(localRegion->TestLocalToShare(reinterpret_cast<uintptr_t>(localSlot)));
132         }
133     }
134     sHeap->WaitGCFinished(thread);
135 }
136 } // namespace panda::test
137