1 /* 2 * Copyright (c) 2021 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 16 #ifndef PANDA_RUNTIME_MEM_GC_G1_G1_GC_H_ 17 #define PANDA_RUNTIME_MEM_GC_G1_G1_GC_H_ 18 19 #include "runtime/include/mem/panda_smart_pointers.h" 20 #include "runtime/mem/gc/card_table.h" 21 #include "runtime/mem/gc/gc.h" 22 #include "runtime/mem/gc/lang/gc_lang.h" 23 #include "runtime/mem/gc/g1/g1-allocator.h" 24 #include "runtime/mem/gc/generational-gc-base.h" 25 26 namespace panda { 27 class ManagedThread; 28 } // namespace panda 29 namespace panda::mem { 30 31 /** 32 * \brief G1 alike GC 33 */ 34 template <class LanguageConfig> 35 class G1GC : public GenerationalGC<LanguageConfig> { 36 public: 37 explicit G1GC(ObjectAllocatorBase *object_allocator, const GCSettings &settings); 38 ~G1GC() override = default; 39 DEFAULT_MOVE_SEMANTIC(G1GC); 40 DEFAULT_COPY_SEMANTIC(G1GC); 41 42 void InitGCBits(panda::ObjectHeader *obj_header) override; 43 44 void InitGCBitsForAllocationInTLAB(panda::ObjectHeader *object) override; 45 46 void Trigger() override; 47 48 void MarkReferences(PandaStackTL<ObjectHeader *> *references, GCPhase gc_phase) override; 49 50 void MarkObject(ObjectHeader *object_header) override; 51 52 bool MarkObjectIfNotMarked(ObjectHeader *object_header) override; 53 54 void UnMarkObject(ObjectHeader *object_header) override; 55 56 private: 57 using RefUpdateInfo = std::pair<const void *, const void *>; 58 59 void InitializeImpl() override; 60 61 void RunPhasesImpl(const GCTask &task) override; 62 63 void PreStartupImp() override; 64 65 /** 66 * Check if object can be in collectible set 67 * @return true if object in region which is currently processed by GC for collection 68 */ 69 bool IsInCollectibleSet(ObjectHeader *obj_header) const; 70 71 /** 72 * GC for young generation. Runs with STW. 73 */ 74 void RunYoungGC(GCTask task); 75 76 /** 77 * GC for tenured generation. 78 */ 79 void RunTenuredGC(GCTask task); 80 81 /** 82 * Marks objects in young generation 83 */ 84 void MarkYoung(GCTask task); 85 86 void MarkYoungStack(PandaStackTL<ObjectHeader *> *objects_stack); 87 88 /** 89 * Marks roots and add them to the stack 90 * @param objects_stack 91 * @param visit_class_roots 92 * @param visit_card_table_roots 93 */ 94 void MarkRoots(PandaStackTL<ObjectHeader *> *objects_stack, CardTableVisitFlag visit_card_table_roots, 95 VisitGCRootFlags flags = VisitGCRootFlags::ACCESS_ROOT_ALL); 96 97 /** 98 * Initial marks roots and fill in 1st level from roots into stack. 99 * STW 100 * @param objects_stack 101 */ 102 void InitialMark(PandaStackTL<ObjectHeader *> *objects_stack); 103 104 /** 105 * Concurrently marking all objects 106 * @param objects_stack 107 */ 108 NO_THREAD_SAFETY_ANALYSIS void ConcurrentMark(PandaStackTL<ObjectHeader *> *objects_stack); 109 110 /** 111 * ReMarks objects after Concurrent marking 112 * @param objects_stack 113 */ 114 void ReMark(PandaStackTL<ObjectHeader *> *objects_stack, GCTask task); 115 116 /** 117 * Mark all objects in stack recursively for Full GC. 118 */ 119 void MarkStack(PandaStackTL<ObjectHeader *> *stack); 120 121 /** 122 * Collect dead objects in young generation and move survivors 123 * @return 124 */ 125 void CollectYoungAndMove(); 126 127 /** 128 * Sweeps string table from about to become dangled pointers to young generation 129 */ 130 void SweepStringTableYoung(); 131 132 /** 133 * Remove dead strings from string table 134 */ 135 void SweepStringTable(); 136 137 /** 138 * Update all refs to moved objects 139 */ 140 void UpdateRefsToMovedObjects(PandaVector<ObjectHeader *> *moved_objects); 141 142 void Sweep(); 143 144 bool IsMarked(const ObjectHeader *object) const override; 145 GetG1ObjectAllocator()146 ALWAYS_INLINE ObjectAllocatorG1<MT_MODE_MULTI> *GetG1ObjectAllocator() 147 { 148 return static_cast<ObjectAllocatorG1<MT_MODE_MULTI> *>(this->GetObjectAllocator()); 149 } 150 151 bool concurrent_marking_flag_ {false}; // flag indicates if we are currently in concurrent marking phase 152 PandaUniquePtr<CardTable> card_table_ {nullptr}; 153 std::function<void(const void *, const void *)> post_queue_func_ {nullptr}; //! funciton called in the post WRB 154 PandaVector<RefUpdateInfo> updated_refs_queue_ {}; //! queue with updated refs info 155 os::memory::Mutex queue_lock_; 156 }; 157 158 template <MTModeT MTMode> 159 class AllocConfig<GCType::G1_GC, MTMode> { 160 public: 161 using ObjectAllocatorType = ObjectAllocatorG1<MTMode>; 162 using CodeAllocatorType = CodeAllocator; 163 }; 164 165 } // namespace panda::mem 166 167 #endif // PANDA_RUNTIME_MEM_GC_G1_G1_GC_H_ 168