• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 "runtime/mem/gc/generational-gc-base.h"
17 #include "runtime/include/runtime.h"
18 #include "runtime/include/runtime_notification.h"
19 #include "runtime/include/panda_vm.h"
20 
21 namespace ark::mem {
22 
23 template <class LanguageConfig>
ShouldRunTenuredGC(const GCTask & task)24 bool GenerationalGC<LanguageConfig>::ShouldRunTenuredGC(const GCTask &task)
25 {
26     return this->IsOnPygoteFork() || task.reason == GCTaskCause::OOM_CAUSE ||
27            task.reason == GCTaskCause::EXPLICIT_CAUSE || task.reason == GCTaskCause::HEAP_USAGE_THRESHOLD_CAUSE ||
28            task.reason == GCTaskCause::STARTUP_COMPLETE_CAUSE;
29 }
30 
31 template <class LanguageConfig>
Dump()32 PandaString GenerationalGC<LanguageConfig>::MemStats::Dump()
33 {
34     PandaStringStream statistic;
35     statistic << "Young freed " << youngFreeObjectCount_ << " objects ("
36               << helpers::MemoryConverter(youngFreeObjectSize_) << ") Young moved " << youngMoveObjectCount_
37               << " objects, " << youngMoveObjectSize_ << " bytes (" << helpers::MemoryConverter(youngMoveObjectSize_)
38               << ")";
39     if (tenuredFreeObjectSize_ > 0U) {
40         statistic << " Tenured freed " << tenuredFreeObjectSize_ << "("
41                   << helpers::MemoryConverter(tenuredFreeObjectSize_) << ")";
42     }
43     return statistic.str();
44 }
45 
46 template <class LanguageConfig>
UpdateMemStats(size_t bytesInHeapBefore,bool updateTenuredStats,bool recordAllocationForMovedObjects)47 void GenerationalGC<LanguageConfig>::UpdateMemStats(size_t bytesInHeapBefore, bool updateTenuredStats,
48                                                     bool recordAllocationForMovedObjects)
49 {
50     size_t youngMoveSize = this->memStats_.GetSizeMovedYoung();
51     size_t youngMoveCount = this->memStats_.GetCountMovedYoung();
52     size_t youngDeleteSize = this->memStats_.GetSizeFreedYoung();
53     size_t youngDeleteCount = this->memStats_.GetCountFreedYoung();
54     size_t tenuredMoveSize = updateTenuredStats ? this->memStats_.GetSizeMovedTenured() : 0;
55     size_t tenuredMoveCount = updateTenuredStats ? this->memStats_.GetCountMovedTenured() : 0;
56     size_t tenuredDeleteSize = updateTenuredStats ? this->memStats_.GetSizeFreedTenured() : 0;
57     size_t tenuredDeleteCount = updateTenuredStats ? this->memStats_.GetCountFreedTenured() : 0;
58 
59     auto *vmMemStats = this->GetPandaVm()->GetMemStats();
60     GCInstanceStats *gcStats = this->GetStats();
61 
62     if (recordAllocationForMovedObjects) {
63         vmMemStats->RecordAllocateObjects(youngMoveCount + tenuredMoveCount, youngMoveSize + tenuredMoveSize,
64                                           SpaceType::SPACE_TYPE_OBJECT);
65     }
66     if (youngMoveSize > 0) {
67         gcStats->AddMemoryValue(youngMoveSize, MemoryTypeStats::MOVED_BYTES);
68         gcStats->AddObjectsValue(youngMoveCount, ObjectTypeStats::MOVED_OBJECTS);
69         vmMemStats->RecordYoungMovedObjects(youngMoveCount, youngMoveSize, SpaceType::SPACE_TYPE_OBJECT);
70     }
71     if (youngDeleteSize > 0) {
72         gcStats->AddMemoryValue(youngDeleteSize, MemoryTypeStats::YOUNG_FREED_BYTES);
73         gcStats->AddObjectsValue(youngDeleteCount, ObjectTypeStats::YOUNG_FREED_OBJECTS);
74     }
75 
76     if (bytesInHeapBefore > 0) {
77         gcStats->AddCopiedRatioValue(static_cast<double>(youngMoveSize + tenuredMoveSize) / bytesInHeapBefore);
78     }
79 
80     if (tenuredMoveSize > 0) {
81         gcStats->AddMemoryValue(tenuredMoveSize, MemoryTypeStats::MOVED_BYTES);
82         gcStats->AddObjectsValue(tenuredMoveCount, ObjectTypeStats::MOVED_OBJECTS);
83         vmMemStats->RecordTenuredMovedObjects(tenuredMoveCount, tenuredMoveSize, SpaceType::SPACE_TYPE_OBJECT);
84     }
85     if (tenuredDeleteSize > 0) {
86         gcStats->AddMemoryValue(tenuredDeleteSize, MemoryTypeStats::ALL_FREED_BYTES);
87         gcStats->AddObjectsValue(tenuredDeleteCount, ObjectTypeStats::ALL_FREED_OBJECTS);
88     }
89     vmMemStats->RecordFreeObjects(youngDeleteCount + tenuredDeleteCount, youngDeleteSize + tenuredDeleteSize,
90                                   SpaceType::SPACE_TYPE_OBJECT);
91 }
92 
93 template <class LanguageConfig>
CreateCardTable(InternalAllocatorPtr internalAllocatorPtr,uintptr_t minAddress,size_t size)94 void GenerationalGC<LanguageConfig>::CreateCardTable(InternalAllocatorPtr internalAllocatorPtr, uintptr_t minAddress,
95                                                      size_t size)
96 {
97     cardTable_ = MakePandaUnique<CardTable>(internalAllocatorPtr, minAddress, size);
98     ASSERT(cardTable_.get() != nullptr);
99     cardTable_->Initialize();
100 }
101 
102 template <class LanguageConfig>
Trigger(PandaUniquePtr<GCTask> task)103 bool GenerationalGC<LanguageConfig>::Trigger(PandaUniquePtr<GCTask> task)
104 {
105     // Check current heap size.
106     // Collect Young gen.
107     // If threshold for tenured gen - collect tenured gen.
108     // NOTE(dtrubenkov): change for concurrent mode
109     return this->AddGCTask(true, std::move(task));
110 }
111 
112 TEMPLATE_CLASS_LANGUAGE_CONFIG(GenerationalGC);
113 }  // namespace ark::mem
114