• 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 * 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