• 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 #ifndef PANDA_RUNTIME_MEM_GC_GC_ROOT_H
16 #define PANDA_RUNTIME_MEM_GC_GC_ROOT_H
17 
18 #include <algorithm>
19 #include <ostream>
20 #include <vector>
21 
22 #include "libpandabase/mem/mem.h"
23 #include "libpandabase/mem/mem_range.h"
24 #include "runtime/include/class.h"
25 #include "runtime/include/language_config.h"
26 #include "runtime/include/mem/panda_containers.h"
27 #include "runtime/interpreter/frame.h"
28 #include "runtime/mem/gc/card_table.h"
29 #include "runtime/mem/gc/gc_root_type.h"
30 
31 namespace panda {
32 class PandaVM;
33 class ManagedThread;
34 }  // namespace panda
35 
36 namespace panda::mem {
37 
38 class GCAdaptiveStack;
39 
40 using GCMarkingStackType = GCAdaptiveStack;
41 
42 enum class VisitGCRootFlags : uint32_t {
43     ACCESS_ROOT_ALL = 1U,
44     ACCESS_ROOT_ONLY_NEW = 1U << 1U,  // used at remark to iterate over new roots only for classes and stringtable
45     ACCESS_ROOT_NONE = 1U << 2U,
46 
47     ACCESS_ROOT_AOT_STRINGS_ONLY_YOUNG = 1U << 3U,  // visit only young string roots in aot table
48 
49     START_RECORDING_NEW_ROOT = 1U << 10U,
50     END_RECORDING_NEW_ROOT = 1U << 11U,
51 };
52 
53 uint32_t operator&(VisitGCRootFlags left, VisitGCRootFlags right);
54 
55 VisitGCRootFlags operator|(VisitGCRootFlags left, VisitGCRootFlags right);
56 
57 /**
58  * \brief I am groot
59  */
60 class GCRoot {
61 public:
62     GCRoot(RootType type, ObjectHeader *obj);
63     GCRoot(RootType type, ObjectHeader *from_object, ObjectHeader *obj);
64 
65     RootType GetType() const;
66     ObjectHeader *GetObjectHeader() const;
67     ObjectHeader *GetFromObjectHeader() const;
68     friend std::ostream &operator<<(std::ostream &os, const GCRoot &root);
69 
70     virtual ~GCRoot() = default;
71 
72     NO_COPY_SEMANTIC(GCRoot);
73     NO_MOVE_SEMANTIC(GCRoot);
74 
75 private:
76     RootType type_;
77     /**
78      * From which object current root was found by reference. Usually from_object is nullptr, except when object was
79      * found from card_table
80      */
81     ObjectHeader *from_object_;
82     ObjectHeader *object_;
83 };
84 
85 template <class LanguageConfig>
86 class RootManager final {
87 public:
88     /**
89      * Visit all non-heap roots(registers, thread locals, etc)
90      */
91     void VisitNonHeapRoots(const GCRootVisitor &gc_root_visitor,
92                            VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL) const;
93 
94     /**
95      * Visit local roots for frame
96      */
97     void VisitLocalRoots(const GCRootVisitor &gc_root_visitor) const;
98 
99     /**
100      * Visit card table roots
101      * @param card_table - card table for scan
102      * @param allocator - object allocator
103      * @param root_visitor
104      * @param range_checker - return true if we need to check mem range for current card
105      * @param range_object_checker - return true if we should apply root_visitor to the object obtained during
106      * traversing
107      * @param from_object_checker - return true if we need to traverse objects approved by range_checker
108      */
109     void VisitCardTableRoots(CardTable *card_table, ObjectAllocatorBase *allocator, GCRootVisitor root_visitor,
110                              MemRangeChecker range_checker, ObjectChecker range_object_checker,
111                              ObjectChecker from_object_checker, uint32_t processed_flag) const;
112 
113     /**
114      * Visit roots in class linker
115      */
116     void VisitClassRoots(const GCRootVisitor &gc_root_visitor,
117                          VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL) const;
118 
119     void VisitAotStringRoots(const GCRootVisitor &gc_root_visitor, VisitGCRootFlags flags) const;
120 
121     /**
122      * Updates references to moved objects in TLS
123      */
124     void UpdateThreadLocals();
125 
126     void UpdateVmRefs();
127 
128     void UpdateGlobalObjectStorage();
129 
130     void UpdateClassLinkerContextRoots();
131 
132     void UpdateAotStringRoots();
133 
SetPandaVM(PandaVM * vm)134     void SetPandaVM(PandaVM *vm)
135     {
136         vm_ = vm;
137     }
138 
139 private:
140     /**
141      * Visit VM-specific roots
142      */
143     void VisitVmRoots(const GCRootVisitor &gc_root_visitor) const;
144 
145     template <class VRegRef>
146     void VisitRegisterRoot(const VRegRef &v_register, const GCRootVisitor &gc_root_visitor) const;
147 
148     void VisitClassLinkerContextRoots(const GCRootVisitor &gc_root_visitor) const;
149 
150     /**
151      * Visit roots for \param thread
152      * @param thread
153      */
154     void VisitRootsForThread(ManagedThread *thread, const GCRootVisitor &gc_root_visitor) const;
155 
156     PandaVM *vm_ {nullptr};
157 };
158 
159 }  // namespace panda::mem
160 
161 #endif  // PANDA_RUNTIME_MEM_GC_GC_ROOT_H
162