• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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