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 "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 panda::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 MarkWord markWord = objectHeader->AtomicGetMark();
87 if (markWord.GetState() == MarkWord::ObjectState::STATE_GC) {
88 MarkWord::MarkWordSize addr = markWord.GetForwardingAddress();
89 LOG_DEBUG_GC << "Update monitor " << std::hex << monitor << " object, old val = 0x" << std::hex
90 << objectHeader << ", new val = 0x" << addr;
91 monitor->SetObject(reinterpret_cast<ObjectHeader *>(addr));
92 }
93 }
94 return true;
95 });
96 }
97 // Update string table
98 if (GetPandaVm()->UpdateMovedStrings()) {
99 // AOT string slots are pointing to strings from the StringTable,
100 // so we should update it only if StringTable's pointers were updated.
101 rootManager_.UpdateAotStringRoots();
102 }
103 // Update thread locals
104 UpdateThreadLocals();
105 // Update refs in vm
106 UpdateVmRefs();
107 // Update refs in class linker contexts
108 UpdateClassLinkerContextRoots();
109 // Update global refs
110 UpdateGlobalObjectStorage();
111 }
112
113 template <class LanguageConfig>
PreRunPhasesImpl()114 void GCLang<LanguageConfig>::PreRunPhasesImpl()
115 {
116 // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
117 if constexpr (LanguageConfig::MT_MODE == MT_MODE_MULTI) {
118 // Run monitor deflation first
119 GetPandaVm()->GetMonitorPool()->DeflateMonitors();
120 }
121 }
122
123 TEMPLATE_GC_IS_MUTATOR_ALLOWED()
124 TEMPLATE_CLASS_LANGUAGE_CONFIG(GCLang);
125
126 } // namespace panda::mem
127