• 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 "memory_manager.h"
17 #include "runtime/include/runtime_options.h"
18 #include "runtime/mem/refstorage/global_object_storage.h"
19 
20 #include <runtime/mem/gc/gc.h>
21 #include <runtime/mem/gc/gc_trigger.h>
22 #include <runtime/mem/gc/gc_stats.h>
23 #include <runtime/mem/heap_manager.h>
24 
25 namespace ark::mem {
26 
CreateHeapManager(InternalAllocatorPtr internalAllocator,const MemoryManager::HeapOptions & options,GCType gcType,MemStatsType * memStats)27 static HeapManager *CreateHeapManager(InternalAllocatorPtr internalAllocator, const MemoryManager::HeapOptions &options,
28                                       GCType gcType, MemStatsType *memStats)
29 {
30     auto *heapManager = new HeapManager();
31     if (heapManager == nullptr) {
32         LOG(ERROR, RUNTIME) << "Failed to allocate HeapManager";
33         return nullptr;
34     }
35 
36     if (!heapManager->Initialize(gcType, options.multithreadingMode, options.isUseTlabForAllocations, memStats,
37                                  internalAllocator, options.isStartAsZygote)) {
38         LOG(ERROR, RUNTIME) << "Failed to initialize HeapManager";
39         delete heapManager;
40         return nullptr;
41     }
42     heapManager->SetIsFinalizableFunc(options.isObjectFinalizebleFunc);
43     heapManager->SetRegisterFinalizeReferenceFunc(options.registerFinalizeReferenceFunc);
44 
45     return heapManager;
46 }
47 
48 /* static */
49 // CC-OFFNXT(G.FUN.01-CPP) solid logic, the fix will degrade the readability and maintenance of the code
Create(const LanguageContext & ctx,InternalAllocatorPtr internalAllocator,GCType gcType,const GCSettings & gcSettings,const GCTriggerConfig & gcTriggerConfig,const HeapOptions & heapOptions)50 MemoryManager *MemoryManager::Create(const LanguageContext &ctx, InternalAllocatorPtr internalAllocator, GCType gcType,
51                                      const GCSettings &gcSettings, const GCTriggerConfig &gcTriggerConfig,
52                                      const HeapOptions &heapOptions)
53 {
54     std::unique_ptr<MemStatsType> memStats = std::make_unique<MemStatsType>();
55 
56     HeapManager *heapManager = CreateHeapManager(internalAllocator, heapOptions, gcType, memStats.get());
57     if (heapManager == nullptr) {
58         return nullptr;
59     }
60 
61     InternalAllocatorPtr allocator = heapManager->GetInternalAllocator();
62     GCStats *gcStats = allocator->New<GCStats>(memStats.get(), gcType, allocator);
63     GC *gc = ctx.CreateGC(gcType, heapManager->GetObjectAllocator().AsObjectAllocator(), gcSettings);
64     GCTrigger *gcTrigger =
65         CreateGCTrigger(memStats.get(), heapManager->GetObjectAllocator().AsObjectAllocator()->GetHeapSpace(),
66                         gcTriggerConfig, allocator);
67     if (gcSettings.G1EnablePauseTimeGoal() &&
68         (gcType != GCType::G1_GC || gcTrigger->GetType() != GCTriggerType::PAUSE_TIME_GOAL_TRIGGER)) {
69         LOG(FATAL, RUNTIME) << "Pause time goal is supported with G1 GC and pause-time-goal trigger only";
70         return nullptr;
71     }
72 
73     GlobalObjectStorage *globalObjectStorage = internalAllocator->New<GlobalObjectStorage>(
74         internalAllocator, heapOptions.maxGlobalRefSize, heapOptions.isGlobalReferenceSizeCheckEnabled);
75     if (globalObjectStorage == nullptr) {
76         LOG(ERROR, RUNTIME) << "Failed to allocate GlobalObjectStorage";
77         return nullptr;
78     }
79 
80     return new MemoryManager(internalAllocator, heapManager, gc, gcTrigger, gcStats, memStats.release(),
81                              globalObjectStorage);
82 }
83 
84 /* static */
Destroy(MemoryManager * mm)85 void MemoryManager::Destroy(MemoryManager *mm)
86 {
87     delete mm;
88 }
89 
~MemoryManager()90 MemoryManager::~MemoryManager()
91 {
92     heapManager_->GetInternalAllocator()->Delete(gc_);
93     heapManager_->GetInternalAllocator()->Delete(gcTrigger_);
94     heapManager_->GetInternalAllocator()->Delete(gcStats_);
95     heapManager_->GetInternalAllocator()->Delete(globalObjectStorage_);
96 
97     delete heapManager_;
98 
99     // One more check that we don't have memory leak in internal allocator.
100     ASSERT(memStats_->GetFootprint(SpaceType::SPACE_TYPE_INTERNAL) == 0);
101     delete memStats_;
102 }
103 
Finalize()104 void MemoryManager::Finalize()
105 {
106     heapManager_->Finalize();
107 }
108 
InitializeGC(PandaVM * vm)109 void MemoryManager::InitializeGC(PandaVM *vm)
110 {
111     heapManager_->SetPandaVM(vm);
112     gc_->Initialize(vm);
113     gc_->AddListener(gcTrigger_);
114 }
115 
PreStartup()116 void MemoryManager::PreStartup()
117 {
118     gc_->PreStartup();
119 }
120 
PreZygoteFork()121 void MemoryManager::PreZygoteFork()
122 {
123     gc_->PreZygoteFork();
124     heapManager_->PreZygoteFork();
125 }
126 
PostZygoteFork()127 void MemoryManager::PostZygoteFork()
128 {
129     gc_->PostZygoteFork();
130 }
131 
StartGC()132 void MemoryManager::StartGC()
133 {
134     gc_->StartGC();
135 }
136 
StopGC()137 void MemoryManager::StopGC()
138 {
139     gc_->StopGC();
140 }
141 
142 }  // namespace ark::mem
143