1 /**
2 * Copyright (c) 2021-2022 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 panda::mem {
26
CreateHeapManager(InternalAllocatorPtr internal_allocator,const MemoryManager::HeapOptions & options,GCType gc_type,MemStatsType * mem_stats)27 static HeapManager *CreateHeapManager(InternalAllocatorPtr internal_allocator,
28 const MemoryManager::HeapOptions &options, GCType gc_type,
29 MemStatsType *mem_stats)
30 {
31 auto *heap_manager = new HeapManager();
32 if (heap_manager == nullptr) {
33 LOG(ERROR, RUNTIME) << "Failed to allocate HeapManager";
34 return nullptr;
35 }
36
37 if (!heap_manager->Initialize(gc_type, options.is_single_thread, options.is_use_tlab_for_allocations, mem_stats,
38 internal_allocator, options.is_start_as_zygote)) {
39 LOG(ERROR, RUNTIME) << "Failed to initialize HeapManager";
40 return nullptr;
41 }
42 heap_manager->SetIsFinalizableFunc(options.is_object_finalizeble_func);
43 heap_manager->SetRegisterFinalizeReferenceFunc(options.register_finalize_reference_func);
44
45 return heap_manager;
46 }
47
48 /* static */
Create(const LanguageContext & ctx,InternalAllocatorPtr internal_allocator,GCType gc_type,const GCSettings & gc_settings,const GCTriggerConfig & gc_trigger_config,const HeapOptions & heap_options)49 MemoryManager *MemoryManager::Create(const LanguageContext &ctx, InternalAllocatorPtr internal_allocator,
50 GCType gc_type, const GCSettings &gc_settings,
51 const GCTriggerConfig &gc_trigger_config, const HeapOptions &heap_options)
52 {
53 std::unique_ptr<MemStatsType> mem_stats = std::make_unique<MemStatsType>();
54
55 HeapManager *heap_manager = CreateHeapManager(internal_allocator, heap_options, gc_type, mem_stats.get());
56 if (heap_manager == nullptr) {
57 return nullptr;
58 }
59
60 InternalAllocatorPtr allocator = heap_manager->GetInternalAllocator();
61 GCStats *gc_stats = allocator->New<GCStats>(mem_stats.get(), gc_type, allocator);
62 GC *gc = ctx.CreateGC(gc_type, heap_manager->GetObjectAllocator().AsObjectAllocator(), gc_settings);
63 GCTrigger *gc_trigger =
64 CreateGCTrigger(mem_stats.get(), heap_manager->GetObjectAllocator().AsObjectAllocator()->GetHeapSpace(),
65 gc_trigger_config, allocator);
66
67 GlobalObjectStorage *global_object_storage = internal_allocator->New<GlobalObjectStorage>(
68 internal_allocator, heap_options.max_global_ref_size, heap_options.is_global_reference_size_check_enabled);
69 if (global_object_storage == nullptr) {
70 LOG(ERROR, RUNTIME) << "Failed to allocate GlobalObjectStorage";
71 return nullptr;
72 }
73
74 return new MemoryManager(internal_allocator, heap_manager, gc, gc_trigger, gc_stats, mem_stats.release(),
75 global_object_storage);
76 }
77
78 /* static */
Destroy(MemoryManager * mm)79 void MemoryManager::Destroy(MemoryManager *mm)
80 {
81 delete mm;
82 }
83
~MemoryManager()84 MemoryManager::~MemoryManager()
85 {
86 heap_manager_->GetInternalAllocator()->Delete(gc_);
87 heap_manager_->GetInternalAllocator()->Delete(gc_trigger_);
88 heap_manager_->GetInternalAllocator()->Delete(gc_stats_);
89 heap_manager_->GetInternalAllocator()->Delete(global_object_storage_);
90
91 delete heap_manager_;
92
93 // One more check that we don't have memory leak in internal allocator.
94 ASSERT(mem_stats_->GetFootprint(SpaceType::SPACE_TYPE_INTERNAL) == 0);
95 delete mem_stats_;
96 }
97
Finalize()98 void MemoryManager::Finalize()
99 {
100 heap_manager_->Finalize();
101 }
102
InitializeGC(PandaVM * vm)103 void MemoryManager::InitializeGC(PandaVM *vm)
104 {
105 heap_manager_->SetPandaVM(vm);
106 gc_->Initialize(vm);
107 gc_->AddListener(gc_trigger_);
108 }
109
PreStartup()110 void MemoryManager::PreStartup()
111 {
112 gc_->PreStartup();
113 }
114
PreZygoteFork()115 void MemoryManager::PreZygoteFork()
116 {
117 gc_->PreZygoteFork();
118 heap_manager_->PreZygoteFork();
119 }
120
PostZygoteFork()121 void MemoryManager::PostZygoteFork()
122 {
123 gc_->PostZygoteFork();
124 }
125
StartGC()126 void MemoryManager::StartGC()
127 {
128 gc_->StartGC();
129 }
130
StopGC()131 void MemoryManager::StopGC()
132 {
133 gc_->StopGC();
134 }
135
136 } // namespace panda::mem
137