• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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 ark {
32 class PandaVM;
33 class ManagedThread;
34 }  // namespace ark
35 
36 namespace ark::mem {
37 
38 class GCAdaptiveMarkingStack;
39 
40 using GCMarkingStackType = GCAdaptiveMarkingStack;
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 PANDA_PUBLIC_API uint32_t operator&(VisitGCRootFlags left, VisitGCRootFlags right);
54 
55 PANDA_PUBLIC_API VisitGCRootFlags operator|(VisitGCRootFlags left, VisitGCRootFlags right);
56 
57 /// @brief I am groot
58 class GCRoot {
59 public:
60     GCRoot(RootType type, ObjectHeader *obj);
61     GCRoot(RootType type, ObjectHeader *fromObject, ObjectHeader *obj);
62 
63     RootType GetType() const;
64     ObjectHeader *GetObjectHeader() const;
65     ObjectHeader *GetFromObjectHeader() const;
66     friend std::ostream &operator<<(std::ostream &os, const GCRoot &root);
67 
68     virtual ~GCRoot() = default;
69 
70     NO_COPY_SEMANTIC(GCRoot);
71     NO_MOVE_SEMANTIC(GCRoot);
72 
73 private:
74     RootType type_;
75     /**
76      * From which object current root was found by reference. Usually from_object is nullptr, except when object was
77      * found from card_table
78      */
79     ObjectHeader *fromObject_;
80     ObjectHeader *object_;
81 };
82 
83 template <class LanguageConfig>
84 class RootManager final {
85 public:
RootManager(PandaVM * vm)86     explicit RootManager(PandaVM *vm) : vm_(vm) {};
87     /// Visit all non-heap roots(registers, thread locals, etc)
88     void VisitNonHeapRoots(const GCRootVisitor &gcRootVisitor,
89                            VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL) const;
90 
91     /// Visit local roots for frame
92     void VisitLocalRoots(const GCRootVisitor &gcRootVisitor) const;
93 
94     /**
95      * Visit card table roots
96      * @param card_table - card table for scan
97      * @param allocator - object allocator
98      * @param root_visitor
99      * @param range_checker - return true if we need to check mem range for current card
100      * @param range_object_checker - return true if we should apply root_visitor to the object obtained during
101      * traversing
102      * @param from_object_checker - return true if we need to traverse objects approved by range_checker
103      */
104     void VisitCardTableRoots(CardTable *cardTable, ObjectAllocatorBase *allocator, GCRootVisitor rootVisitor,
105                              MemRangeChecker rangeChecker, ObjectChecker rangeObjectChecker,
106                              ObjectChecker fromObjectChecker, uint32_t processedFlag) const;
107 
108     /// Visit roots in class linker
109     void VisitClassRoots(const GCRootVisitor &gcRootVisitor,
110                          VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL) const;
111 
112     void VisitAotStringRoots(const GCRootVisitor &gcRootVisitor, VisitGCRootFlags flags) const;
113 
114     void UpdateRefsToMovedObjects(const GCRootUpdater &gcRootUpdater);
115 
116 private:
117     /// Visit VM-specific roots
118     void VisitVmRoots(const GCRootVisitor &gcRootVisitor) const;
119 
120     template <class VRegRef>
121     void VisitRegisterRoot(const VRegRef &vRegister, const GCRootVisitor &gcRootVisitor) const;
122 
123     void VisitClassLinkerContextRoots(const GCRootVisitor &gcRootVisitor) const;
124 
125     /**
126      * Visit roots for @param thread
127      * @param thread
128      */
129     void VisitRootsForThread(ManagedThread *thread, const GCRootVisitor &gcRootVisitor) const;
130 
131     void UpdateRefsInVRegs(ManagedThread *thread, const GCRootUpdater &gcRootUpdater);
132 
133     /// Updates references to moved objects in TLS
134     void UpdateThreadLocals(const GCRootUpdater &gcRootUpdater);
135 
136     void UpdateVmRefs(const GCRootUpdater &gcRootUpdater);
137 
138     void UpdateGlobalObjectStorage(const GCRootUpdater &gcRootUpdater);
139 
140     void UpdateClassLinkerContextRoots(const GCRootUpdater &gcRootUpdater);
141 
142     void UpdateAotStringRoots(const GCRootUpdater &gcRootUpdater);
143 
144     PandaVM *vm_ {nullptr};
145 };
146 
147 }  // namespace ark::mem
148 
149 #endif  // PANDA_RUNTIME_MEM_GC_GC_ROOT_H
150