1 /**
2 * Copyright (c) 2021-2024 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 return nullptr;
40 }
41 heapManager->SetIsFinalizableFunc(options.isObjectFinalizebleFunc);
42 heapManager->SetRegisterFinalizeReferenceFunc(options.registerFinalizeReferenceFunc);
43
44 return heapManager;
45 }
46
47 /* static */
48 // 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)49 MemoryManager *MemoryManager::Create(const LanguageContext &ctx, InternalAllocatorPtr internalAllocator, GCType gcType,
50 const GCSettings &gcSettings, const GCTriggerConfig &gcTriggerConfig,
51 const HeapOptions &heapOptions)
52 {
53 std::unique_ptr<MemStatsType> memStats = std::make_unique<MemStatsType>();
54
55 HeapManager *heapManager = CreateHeapManager(internalAllocator, heapOptions, gcType, memStats.get());
56 if (heapManager == nullptr) {
57 return nullptr;
58 }
59
60 InternalAllocatorPtr allocator = heapManager->GetInternalAllocator();
61 GCStats *gcStats = allocator->New<GCStats>(memStats.get(), gcType, allocator);
62 GC *gc = ctx.CreateGC(gcType, heapManager->GetObjectAllocator().AsObjectAllocator(), gcSettings);
63 GCTrigger *gcTrigger =
64 CreateGCTrigger(memStats.get(), heapManager->GetObjectAllocator().AsObjectAllocator()->GetHeapSpace(),
65 gcTriggerConfig, allocator);
66 if (gcSettings.G1EnablePauseTimeGoal() &&
67 (gcType != GCType::G1_GC || gcTrigger->GetType() != GCTriggerType::PAUSE_TIME_GOAL_TRIGGER)) {
68 LOG(FATAL, RUNTIME) << "Pause time goal is supported with G1 GC and pause-time-goal trigger only";
69 return nullptr;
70 }
71
72 GlobalObjectStorage *globalObjectStorage = internalAllocator->New<GlobalObjectStorage>(
73 internalAllocator, heapOptions.maxGlobalRefSize, heapOptions.isGlobalReferenceSizeCheckEnabled);
74 if (globalObjectStorage == nullptr) {
75 LOG(ERROR, RUNTIME) << "Failed to allocate GlobalObjectStorage";
76 return nullptr;
77 }
78
79 return new MemoryManager(internalAllocator, heapManager, gc, gcTrigger, gcStats, memStats.release(),
80 globalObjectStorage);
81 }
82
83 /* static */
Destroy(MemoryManager * mm)84 void MemoryManager::Destroy(MemoryManager *mm)
85 {
86 delete mm;
87 }
88
~MemoryManager()89 MemoryManager::~MemoryManager()
90 {
91 heapManager_->GetInternalAllocator()->Delete(gc_);
92 heapManager_->GetInternalAllocator()->Delete(gcTrigger_);
93 heapManager_->GetInternalAllocator()->Delete(gcStats_);
94 heapManager_->GetInternalAllocator()->Delete(globalObjectStorage_);
95
96 delete heapManager_;
97
98 // One more check that we don't have memory leak in internal allocator.
99 ASSERT(memStats_->GetFootprint(SpaceType::SPACE_TYPE_INTERNAL) == 0);
100 delete memStats_;
101 }
102
Finalize()103 void MemoryManager::Finalize()
104 {
105 heapManager_->Finalize();
106 }
107
InitializeGC(PandaVM * vm)108 void MemoryManager::InitializeGC(PandaVM *vm)
109 {
110 heapManager_->SetPandaVM(vm);
111 gc_->Initialize(vm);
112 gc_->AddListener(gcTrigger_);
113 }
114
PreStartup()115 void MemoryManager::PreStartup()
116 {
117 gc_->PreStartup();
118 }
119
PreZygoteFork()120 void MemoryManager::PreZygoteFork()
121 {
122 gc_->PreZygoteFork();
123 heapManager_->PreZygoteFork();
124 }
125
PostZygoteFork()126 void MemoryManager::PostZygoteFork()
127 {
128 gc_->PostZygoteFork();
129 }
130
StartGC()131 void MemoryManager::StartGC()
132 {
133 gc_->StartGC();
134 }
135
StopGC()136 void MemoryManager::StopGC()
137 {
138 gc_->StopGC();
139 }
140
141 } // namespace ark::mem
142