• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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:
86     /// Visit all non-heap roots(registers, thread locals, etc)
87     void VisitNonHeapRoots(const GCRootVisitor &gcRootVisitor,
88                            VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL) const;
89 
90     /// Visit local roots for frame
91     void VisitLocalRoots(const GCRootVisitor &gcRootVisitor) const;
92 
93     /**
94      * Visit card table roots
95      * @param card_table - card table for scan
96      * @param allocator - object allocator
97      * @param root_visitor
98      * @param range_checker - return true if we need to check mem range for current card
99      * @param range_object_checker - return true if we should apply root_visitor to the object obtained during
100      * traversing
101      * @param from_object_checker - return true if we need to traverse objects approved by range_checker
102      */
103     void VisitCardTableRoots(CardTable *cardTable, ObjectAllocatorBase *allocator, GCRootVisitor rootVisitor,
104                              MemRangeChecker rangeChecker, ObjectChecker rangeObjectChecker,
105                              ObjectChecker fromObjectChecker, uint32_t processedFlag) const;
106 
107     /// Visit roots in class linker
108     void VisitClassRoots(const GCRootVisitor &gcRootVisitor,
109                          VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL) const;
110 
111     void VisitAotStringRoots(const GCRootVisitor &gcRootVisitor, VisitGCRootFlags flags) const;
112 
113     /// Updates references to moved objects in TLS
114     void UpdateThreadLocals();
115 
116     void UpdateVmRefs();
117 
118     void UpdateGlobalObjectStorage();
119 
120     void UpdateClassLinkerContextRoots();
121 
122     void UpdateAotStringRoots();
123 
SetPandaVM(PandaVM * vm)124     void SetPandaVM(PandaVM *vm)
125     {
126         vm_ = vm;
127     }
128 
129 private:
130     /// Visit VM-specific roots
131     void VisitVmRoots(const GCRootVisitor &gcRootVisitor) const;
132 
133     template <class VRegRef>
134     void VisitRegisterRoot(const VRegRef &vRegister, const GCRootVisitor &gcRootVisitor) const;
135 
136     void VisitClassLinkerContextRoots(const GCRootVisitor &gcRootVisitor) const;
137 
138     /**
139      * Visit roots for @param thread
140      * @param thread
141      */
142     void VisitRootsForThread(ManagedThread *thread, const GCRootVisitor &gcRootVisitor) const;
143 
144     PandaVM *vm_ {nullptr};
145 };
146 
147 }  // namespace ark::mem
148 
149 #endif  // PANDA_RUNTIME_MEM_GC_GC_ROOT_H
150