1 /*
2 * Copyright (c) 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 #ifndef COMMON_INTERFACES_BASE_RUNTIME_H
17 #define COMMON_INTERFACES_BASE_RUNTIME_H
18
19 #include <atomic>
20 #include <functional>
21 #include <mutex>
22
23 #include "base/runtime_param.h"
24
25 namespace common {
26 class BaseStringTableImpl;
27 template <typename Impl>
28 class BaseStringTableInterface;
29 class BaseObject;
30 class HeapManager;
31 class MutatorManager;
32 class ThreadHolderManager;
33 class ThreadHolder;
34 class BaseClassRoots;
35
36 // Used by Collector::RequestGC.
37 // It tells why GC is triggered.
38 //
39 // sync: Caller of Collector::RequestGC will wait until GC completes.
40 // async: Collector::RequestGC returns immediately and caller continues to run.
41 enum GCReason : uint32_t {
42 GC_REASON_BEGIN = 0,
43 GC_REASON_USER = GC_REASON_BEGIN, // Triggered by user explicitly.
44 GC_REASON_OOM, // Out of memory. Failed to allocate object.
45 GC_REASON_BACKUP, // backup gc is triggered if no other reason triggers gc for a long time.
46 GC_REASON_HEU, // Statistics show it is worth doing GC. Does not have to be immediate.
47 GC_REASON_YOUNG, // Statistics show it is worth doing Young GC. Does not have to be immediate.
48 GC_REASON_NATIVE, // Native-Allocation-Registry shows it's worth doing GC.
49 GC_REASON_HEU_SYNC, // Just wait one gc request to reduce heap fragmentation.
50 GC_REASON_NATIVE_SYNC, // Just wait one gc request to reduce native heap consumption.
51 GC_REASON_FORCE, // force gc is triggered when runtime triggers gc actively.
52 GC_REASON_APPSPAWN, // appspawn gc is triggered when prefork.
53 GC_REASON_BACKGROUND, // trigger gc caused by switching to background.
54 GC_REASON_HINT, // trigger gc caused by hint gc.
55 GC_REASON_IDLE, // When in a low activity state, trigger gc to reduce resicdent memory.
56 GC_REASON_END = GC_REASON_IDLE,
57 GC_REASON_INVALID = std::numeric_limits<uint32_t>::max(),
58 };
59
60 inline const char* GCREASON_STRING[] = {
61 "user",
62 "oom",
63 "backup",
64 "heuristic",
65 "young",
66 "native_alloc",
67 "heuristic_sync",
68 "native_alloc_sync",
69 "force",
70 "appspawn",
71 "backgound",
72 "hint",
73 "idle",
74 };
75
GCReasonToString(GCReason reason)76 inline const char* GCReasonToString(GCReason reason)
77 {
78 if (reason >= GC_REASON_BEGIN && reason <= GC_REASON_END) {
79 return GCREASON_STRING[reason];
80 }
81 return "UNKNOW_GC_REASON";
82 }
83
84 enum GCType : uint32_t {
85 GC_TYPE_BEGIN = 0,
86 GC_TYPE_FULL = GC_TYPE_BEGIN,
87 GC_TYPE_YOUNG,
88 GC_TYPE_STW,
89 GC_TYPE_END = GC_TYPE_STW,
90 };
91
92 inline const char* GCTYPE_STRING[] = {
93 "FULL",
94 "YOUNG",
95 "STW",
96 };
97
GCTypeToString(GCType gcType)98 inline const char* GCTypeToString(GCType gcType)
99 {
100 if (gcType >= GC_TYPE_BEGIN && gcType <= GC_TYPE_END) {
101 return GCTYPE_STRING[gcType];
102 }
103 return "UNKNOW_GC_TYPE";
104 }
105
106 enum class MemoryReduceDegree : uint8_t {
107 LOW = 0,
108 HIGH,
109 };
110
111 using HeapVisitor = const std::function<void(BaseObject*)>;
112
113 class PUBLIC_API BaseRuntime {
114 public:
115 BaseRuntime() = default;
116 ~BaseRuntime() = default;
117
118 static BaseRuntime *GetInstance();
119 static void DestroyInstance();
120
121 void PreFork(ThreadHolder *holder);
122 void PostFork();
123
124 void Init(const RuntimeParam ¶m); // Support setting custom parameters
125 void Init(); // Use default parameters
126 void Fini();
127
128 // Need refactor, move to other file
129 static void WriteRoot(void* obj);
130 static void WriteBarrier(void* obj, void* field, void* ref);
131 static void* ReadBarrier(void* obj, void* field);
132 static void* ReadBarrier(void* field);
133 static void* AtomicReadBarrier(void* obj, void* field, std::memory_order order);
134 static void RequestGC(GCReason reason, bool async, GCType gcType);
135 static void WaitForGCFinish();
136 static void EnterGCCriticalSection();
137 static void ExitGCCriticalSection();
138 static bool ForEachObj(HeapVisitor& visitor, bool safe);
139 static void NotifyNativeAllocation(size_t bytes);
140 static void NotifyNativeFree(size_t bytes);
141 static void NotifyNativeReset(size_t oldBytes, size_t newBytes);
142 static size_t GetNotifiedNativeSize();
143 static void ChangeGCParams(bool isBackground);
144 static bool CheckAndTriggerHintGC(MemoryReduceDegree degree);
145 static void NotifyHighSensitive(bool isStart);
146
GetHeapParam()147 HeapParam &GetHeapParam()
148 {
149 return param_.heapParam;
150 }
151
GetGCParam()152 GCParam &GetGCParam()
153 {
154 return param_.gcParam;
155 }
156
GetMutatorManager()157 MutatorManager &GetMutatorManager()
158 {
159 return *mutatorManager_;
160 }
161
GetThreadHolderManager()162 ThreadHolderManager &GetThreadHolderManager()
163 {
164 return *threadHolderManager_;
165 }
166
GetHeapManager()167 HeapManager &GetHeapManager()
168 {
169 return *heapManager_;
170 }
171
GetBaseClassRoots()172 BaseClassRoots &GetBaseClassRoots()
173 {
174 return *baseClassRoots_;
175 }
176
GetStringTable()177 BaseStringTableInterface<BaseStringTableImpl> &GetStringTable()
178 {
179 return *stringTable_;
180 }
181 private:
182 RuntimeParam param_ {};
183
184 HeapManager* heapManager_ = nullptr;
185 MutatorManager* mutatorManager_ = nullptr;
186 ThreadHolderManager* threadHolderManager_ = nullptr;
187 BaseClassRoots* baseClassRoots_ = nullptr;
188 BaseStringTableInterface<BaseStringTableImpl>* stringTable_ = nullptr;
189 static std::mutex vmCreationLock_;
190 static BaseRuntime *baseRuntimeInstance_;
191 static bool initialized_;
192 };
193 } // namespace common
194 #endif // COMMON_INTERFACES_BASE_RUNTIME_H
195