1 /** 2 * Copyright (c) 2023-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_G1_G1_MARKER_H 16 #define PANDA_RUNTIME_MEM_GC_G1_G1_MARKER_H 17 18 #include "runtime/mem/gc/gc_marker.h" 19 20 namespace ark::mem { 21 template <class LanguageConfig, bool ATOMIC> 22 class G1GCMarker : public GCMarker<G1GCMarker<LanguageConfig, ATOMIC>, LanguageConfig::LANG_TYPE> { 23 public: G1GCMarker(GC * gc)24 explicit G1GCMarker(GC *gc) : GCMarker<G1GCMarker<LanguageConfig, ATOMIC>, LanguageConfig::LANG_TYPE>(gc) {} 25 MarkIfNotMarked(ObjectHeader * object)26 ALWAYS_INLINE bool MarkIfNotMarked(ObjectHeader *object) const 27 { 28 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 29 ASSERT(bitmap != nullptr); 30 if constexpr (ATOMIC) { 31 return !bitmap->AtomicTestAndSet(object); 32 } else { 33 bool result = !bitmap->Test(object); 34 bitmap->Set(object); 35 return result; 36 } 37 } 38 IsMarked(const ObjectHeader * object)39 ALWAYS_INLINE static bool IsMarked(const ObjectHeader *object) 40 { 41 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 42 ASSERT(bitmap != nullptr); 43 if constexpr (ATOMIC) { 44 return bitmap->AtomicTest(object); 45 } else { 46 return bitmap->Test(object); 47 } 48 } 49 Mark(ObjectHeader * object)50 ALWAYS_INLINE static void Mark(ObjectHeader *object) 51 { 52 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 53 ASSERT(bitmap != nullptr); 54 if constexpr (ATOMIC) { 55 bitmap->AtomicTestAndSet(object); 56 } else { 57 bitmap->Set(object); 58 } 59 } 60 }; 61 62 template <class LanguageConfig> 63 class G1GCMixedMarker : public GCMarker<G1GCMixedMarker<LanguageConfig>, LanguageConfig::LANG_TYPE> { 64 public: G1GCMixedMarker(GC * gc)65 explicit G1GCMixedMarker(GC *gc) : GCMarker<G1GCMixedMarker<LanguageConfig>, LanguageConfig::LANG_TYPE>(gc) {} 66 MarkIfNotMarked(ObjectHeader * object)67 ALWAYS_INLINE bool MarkIfNotMarked(ObjectHeader *object) const 68 { 69 Region *objRegion = ObjectToRegion(object); 70 if (!objRegion->IsInCollectionSet()) { 71 return false; 72 } 73 MarkBitmap *bitmap = objRegion->GetMarkBitmap(); 74 ASSERT(bitmap != nullptr); 75 return !bitmap->AtomicTestAndSet(object); 76 } 77 MarkIfNotMarkedInCollectionSet(ObjectHeader * object)78 ALWAYS_INLINE bool MarkIfNotMarkedInCollectionSet(ObjectHeader *object) const 79 { 80 ASSERT(this->GetGC()->InGCSweepRange(object)); 81 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 82 ASSERT(bitmap != nullptr); 83 return !bitmap->AtomicTestAndSet(object); 84 } 85 IsMarked(const ObjectHeader * object)86 ALWAYS_INLINE bool IsMarked(const ObjectHeader *object) const 87 { 88 return G1GCMarker<LanguageConfig, true>::IsMarked(object); 89 } 90 Mark(ObjectHeader * object)91 ALWAYS_INLINE void Mark(ObjectHeader *object) const 92 { 93 G1GCMarker<LanguageConfig, true>::Mark(object); 94 } 95 }; 96 97 template <class LanguageConfig, bool ATOMIC> 98 class XGCMarker : public GCMarker<XGCMarker<LanguageConfig, ATOMIC>, LanguageConfig::LANG_TYPE> { 99 public: XGCMarker(GC * gc,std::function<void (ObjectHeader *)> callback)100 explicit XGCMarker(GC *gc, std::function<void(ObjectHeader *)> callback) 101 : GCMarker<XGCMarker<LanguageConfig, ATOMIC>, LanguageConfig::LANG_TYPE>(gc), callback_(std::move(callback)) 102 { 103 } 104 MarkIfNotMarked(ObjectHeader * object)105 ALWAYS_INLINE bool MarkIfNotMarked(ObjectHeader *object) const 106 { 107 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 108 ASSERT(bitmap != nullptr); 109 bool alreadyMarked = false; 110 if constexpr (ATOMIC) { 111 alreadyMarked = bitmap->AtomicTestAndSet(object); 112 } else { 113 alreadyMarked = bitmap->Test(object); 114 bitmap->Set(object); 115 } 116 callback_(object); 117 return !alreadyMarked; 118 } 119 IsMarked(const ObjectHeader * object)120 ALWAYS_INLINE static bool IsMarked(const ObjectHeader *object) 121 { 122 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 123 ASSERT(bitmap != nullptr); 124 if constexpr (ATOMIC) { 125 return bitmap->AtomicTest(object); 126 } else { 127 return bitmap->Test(object); 128 } 129 } 130 Mark(ObjectHeader * object)131 ALWAYS_INLINE void Mark(ObjectHeader *object) const 132 { 133 MarkBitmap *bitmap = ObjectToRegion(object)->GetMarkBitmap(); 134 ASSERT(bitmap != nullptr); 135 if constexpr (ATOMIC) { 136 bitmap->AtomicTestAndSet(object); 137 } else { 138 bitmap->Set(object); 139 } 140 callback_(object); 141 } 142 143 private: 144 std::function<void(ObjectHeader *)> callback_; 145 }; 146 } // namespace ark::mem 147 148 #endif // PANDA_RUNTIME_MEM_GC_G1_G1_MARKER_H 149