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