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 "runtime/include/panda_vm.h"
17 #include "runtime/mem/gc/lang/gc_lang.h"
18 #include "runtime/mem/object_helpers-inl.h"
19 #include "runtime/mem/gc/dynamic/gc_dynamic_data.h"
20
21 namespace ark::mem {
22
23 template <class LanguageConfig>
GCLang(ObjectAllocatorBase * objectAllocator,const GCSettings & settings)24 GCLang<LanguageConfig>::GCLang(ObjectAllocatorBase *objectAllocator, const GCSettings &settings)
25 : GC(objectAllocator, settings)
26 {
27 if constexpr (LanguageConfig::LANG_TYPE == LANG_TYPE_DYNAMIC) { // NOLINT
28 auto allocator = GetInternalAllocator();
29 GCDynamicData *data = allocator->template New<GCDynamicData>(allocator);
30 SetExtensionData(data);
31 }
32 }
33
34 template <class LanguageConfig>
~GCLang()35 GCLang<LanguageConfig>::~GCLang()
36 {
37 GCExtensionData *data = GetExtensionData();
38 if (GetExtensionData() != nullptr) {
39 InternalAllocatorPtr allocator = GetInternalAllocator();
40 allocator->Delete(data);
41 }
42 }
43
44 template <class LanguageConfig>
ClearLocalInternalAllocatorPools()45 void GCLang<LanguageConfig>::ClearLocalInternalAllocatorPools()
46 {
47 auto cleaner = [](ManagedThread *thread) {
48 InternalAllocator<>::RemoveFreePoolsForLocalInternalAllocator(thread->GetLocalInternalAllocator());
49 return true;
50 };
51 GetPandaVm()->GetThreadManager()->EnumerateThreads(cleaner);
52 }
53
54 template <class LanguageConfig>
VerifyHeap()55 size_t GCLang<LanguageConfig>::VerifyHeap()
56 {
57 if (GetSettings()->EnableFastHeapVerifier()) {
58 return FastHeapVerifier<LanguageConfig>(GetPandaVm()->GetHeapManager()).VerifyAll();
59 }
60 return HeapVerifier<LanguageConfig>(GetPandaVm()->GetHeapManager()).VerifyAll();
61 }
62
63 template <class LanguageConfig>
UpdateRefsToMovedObjectsInPygoteSpace()64 void GCLang<LanguageConfig>::UpdateRefsToMovedObjectsInPygoteSpace()
65 {
66 GetObjectAllocator()->IterateNonRegularSizeObjects(
67 [](ObjectHeader *obj) { ObjectHelpers<LanguageConfig::LANG_TYPE>::UpdateRefsToMovedObjects(obj); });
68 }
69
70 template <class LanguageConfig>
CommonUpdateRefsToMovedObjects()71 void GCLang<LanguageConfig>::CommonUpdateRefsToMovedObjects()
72 {
73 trace::ScopedTrace scopedTrace(__FUNCTION__);
74
75 auto cb = [this](ManagedThread *thread) {
76 UpdateRefsInVRegs(thread);
77 return true;
78 };
79 // Update refs in vregs
80 GetPandaVm()->GetThreadManager()->EnumerateThreads(cb);
81 if constexpr (LanguageConfig::MT_MODE != MT_MODE_SINGLE) { // NOLINT
82 // Update refs inside monitors
83 GetPandaVm()->GetMonitorPool()->EnumerateMonitors([this](Monitor *monitor) {
84 ObjectHeader *objectHeader = monitor->GetObject();
85 if (objectHeader == nullptr) {
86 return true;
87 }
88 MarkWord markWord = objectHeader->AtomicGetMark();
89 if (markWord.GetState() == MarkWord::ObjectState::STATE_GC) {
90 MarkWord::MarkWordSize addr = markWord.GetForwardingAddress();
91 LOG_DEBUG_GC << "Update monitor " << std::hex << monitor << " object, old val = 0x" << std::hex
92 << objectHeader << ", new val = 0x" << addr;
93 monitor->SetObject(reinterpret_cast<ObjectHeader *>(addr));
94 }
95 return true;
96 });
97 }
98 // Update string table
99 if (GetPandaVm()->UpdateMovedStrings()) {
100 // AOT string slots are pointing to strings from the StringTable,
101 // so we should update it only if StringTable's pointers were updated.
102 rootManager_.UpdateAotStringRoots();
103 }
104 // Update thread locals
105 UpdateThreadLocals();
106 // Update refs in vm
107 UpdateVmRefs();
108 // Update refs in class linker contexts
109 UpdateClassLinkerContextRoots();
110 // Update global refs
111 UpdateGlobalObjectStorage();
112 }
113
114 template <class LanguageConfig>
PreRunPhasesImpl()115 void GCLang<LanguageConfig>::PreRunPhasesImpl()
116 {
117 // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
118 if constexpr (LanguageConfig::MT_MODE != MT_MODE_SINGLE) {
119 // Run monitor deflation first
120 GetPandaVm()->GetMonitorPool()->DeflateMonitors();
121 }
122 }
123
124 TEMPLATE_GC_IS_MUTATOR_ALLOWED()
125 TEMPLATE_CLASS_LANGUAGE_CONFIG(GCLang);
126
127 } // namespace ark::mem
128