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 * object_allocator,const GCSettings & settings)24 GCLang<LanguageConfig>::GCLang(ObjectAllocatorBase *object_allocator, const GCSettings &settings)
25 : GC(object_allocator, 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 // NOLINTNEXTLINE(readability-braces-around-statements)
52 if constexpr (LanguageConfig::MT_MODE == MT_MODE_MULTI) {
53 GetPandaVm()->GetThreadManager()->EnumerateThreads(cleaner);
54 } else { // NOLINT(readability-misleading-indentation)
55 cleaner(GetPandaVm()->GetAssociatedThread());
56 }
57 }
58
59 template <class LanguageConfig>
VerifyHeap()60 size_t GCLang<LanguageConfig>::VerifyHeap()
61 {
62 if (GetSettings()->EnableFastHeapVerifier()) {
63 return FastHeapVerifier<LanguageConfig>(GetPandaVm()->GetHeapManager()).VerifyAll();
64 }
65 return HeapVerifier<LanguageConfig>(GetPandaVm()->GetHeapManager()).VerifyAll();
66 }
67
68 template <class LanguageConfig>
UpdateRefsToMovedObjectsInPygoteSpace()69 void GCLang<LanguageConfig>::UpdateRefsToMovedObjectsInPygoteSpace()
70 {
71 GetObjectAllocator()->IterateNonRegularSizeObjects(
72 [](ObjectHeader *obj) { ObjectHelpers<LanguageConfig::LANG_TYPE>::UpdateRefsToMovedObjects(obj); });
73 }
74
75 template <class LanguageConfig>
CommonUpdateRefsToMovedObjects()76 void GCLang<LanguageConfig>::CommonUpdateRefsToMovedObjects()
77 {
78 trace::ScopedTrace scoped_trace(__FUNCTION__);
79
80 // Update refs in vregs
81 if constexpr (LanguageConfig::MT_MODE == MT_MODE_SINGLE) { // NOLINT
82 UpdateRefsInVRegs(GetPandaVm()->GetAssociatedThread());
83 } else { // NOLINT
84 GetPandaVm()->GetThreadManager()->EnumerateThreads([this](ManagedThread *thread) {
85 UpdateRefsInVRegs(thread);
86 return true;
87 });
88 // Update refs inside monitors
89 GetPandaVm()->GetMonitorPool()->EnumerateMonitors([this](Monitor *monitor) {
90 ObjectHeader *object_header = monitor->GetObject();
91 if (object_header != nullptr) {
92 MarkWord mark_word = object_header->AtomicGetMark();
93 if (mark_word.GetState() == MarkWord::ObjectState::STATE_GC) {
94 MarkWord::markWordSize addr = mark_word.GetForwardingAddress();
95 LOG_DEBUG_GC << "Update monitor " << std::hex << monitor << " object, old val = 0x" << std::hex
96 << object_header << ", new val = 0x" << addr;
97 monitor->SetObject(reinterpret_cast<ObjectHeader *>(addr));
98 }
99 }
100 return true;
101 });
102 }
103 // Update string table
104 if (GetPandaVm()->UpdateMovedStrings()) {
105 // AOT string slots are pointing to strings from the StringTable,
106 // so we should update it only if StringTable's pointers were updated.
107 root_manager_.UpdateAotStringRoots();
108 }
109
110 // Update thread locals
111 UpdateThreadLocals();
112 // Update refs in vm
113 UpdateVmRefs();
114 // Update refs in class linker contexts
115 UpdateClassLinkerContextRoots();
116 // Update global refs
117 UpdateGlobalObjectStorage();
118 }
119
120 template <class LanguageConfig>
PreRunPhasesImpl()121 void GCLang<LanguageConfig>::PreRunPhasesImpl()
122 {
123 // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
124 if constexpr (LanguageConfig::MT_MODE == MT_MODE_MULTI) {
125 // Run monitor deflation first
126 GetPandaVm()->GetMonitorPool()->DeflateMonitors();
127 }
128 }
129
130 TEMPLATE_GC_IS_MUTATOR_ALLOWED()
131 TEMPLATE_CLASS_LANGUAGE_CONFIG(GCLang);
132
133 } // namespace panda::mem
134