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