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