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