1 /** 2 * Copyright (c) 2021-2022 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_LIBPANDABASE_MEM_STWGC_H 16 #define PANDA_LIBPANDABASE_MEM_STWGC_H 17 18 #include "runtime/include/coretypes/array-inl.h" 19 #include "runtime/include/mem/panda_containers.h" 20 #include "runtime/mem/gc/lang/gc_lang.h" 21 #include "runtime/mem/gc/gc_marker.h" 22 #include "runtime/mem/gc/gc_root.h" 23 24 namespace panda::mem { 25 26 template <LangTypeT LANG_TYPE, bool HAS_VALUE_OBJECT_TYPES> 27 class StwGCMarker 28 : public DefaultGCMarker<StwGCMarker<LANG_TYPE, HAS_VALUE_OBJECT_TYPES>, LANG_TYPE, HAS_VALUE_OBJECT_TYPES> { 29 using Base = DefaultGCMarker<StwGCMarker<LANG_TYPE, HAS_VALUE_OBJECT_TYPES>, LANG_TYPE, HAS_VALUE_OBJECT_TYPES>; 30 31 public: StwGCMarker(GC * gc)32 explicit StwGCMarker(GC *gc) : Base(gc) {} 33 MarkIfNotMarked(ObjectHeader * object)34 bool MarkIfNotMarked(ObjectHeader *object) const 35 { 36 if (!reverse_mark_) { 37 return Base::template MarkIfNotMarked<false>(object); 38 } 39 return Base::template MarkIfNotMarked<true>(object); 40 } 41 Mark(ObjectHeader * object)42 void Mark(ObjectHeader *object) const 43 { 44 if (!reverse_mark_) { 45 LOG(DEBUG, GC) << "Set mark for GC " << GetDebugInfoAboutObject(object); 46 Base::template Mark<false>(object); 47 } else { 48 LOG(DEBUG, GC) << "Set unmark for GC " << GetDebugInfoAboutObject(object); 49 Base::template Mark<true>(object); 50 } 51 } 52 IsMarked(const ObjectHeader * object)53 bool IsMarked(const ObjectHeader *object) const 54 { 55 if (!reverse_mark_) { 56 LOG(DEBUG, GC) << "Get marked for GC " << GetDebugInfoAboutObject(object); 57 return Base::template IsMarked<false>(object); 58 } 59 LOG(DEBUG, GC) << "Get unmarked for GC " << GetDebugInfoAboutObject(object); 60 return Base::template IsMarked<true>(object); 61 } 62 ReverseMark()63 void ReverseMark() 64 { 65 reverse_mark_ = !reverse_mark_; 66 } 67 IsReverseMark()68 bool IsReverseMark() const 69 { 70 return reverse_mark_; 71 } 72 73 private: 74 bool reverse_mark_ = false; 75 }; 76 77 /** 78 * \brief Stop the world, non-concurrent GC 79 */ 80 template <class LanguageConfig> 81 class StwGC final : public GCLang<LanguageConfig> { 82 public: 83 explicit StwGC(ObjectAllocatorBase *object_allocator, const GCSettings &settings); 84 85 NO_COPY_SEMANTIC(StwGC); 86 NO_MOVE_SEMANTIC(StwGC); 87 ~StwGC() override = default; 88 89 void WaitForGC(GCTask task) override; 90 91 void InitGCBits(panda::ObjectHeader *object) override; 92 93 void InitGCBitsForAllocationInTLAB(panda::ObjectHeader *obj_header) override; 94 95 void Trigger() override; 96 97 void WorkerTaskProcessing(GCWorkersTask *task, void *worker_data) override; 98 99 private: 100 void InitializeImpl() override; 101 void RunPhasesImpl(GCTask &task) override; 102 void Mark(const GCTask &task); 103 void MarkStack(GCMarkingStackType *stack, const GC::MarkPredicate &markPredicate); 104 void SweepStringTable(); 105 void Sweep(); 106 107 void MarkObject(ObjectHeader *object) override; 108 bool IsMarked(const ObjectHeader *object) const override; 109 void UnMarkObject(ObjectHeader *object_header); 110 void MarkReferences(GCMarkingStackType *references, GCPhase gc_phase) override; 111 112 StwGCMarker<LanguageConfig::LANG_TYPE, LanguageConfig::HAS_VALUE_OBJECT_TYPES> marker_; 113 }; 114 115 } // namespace panda::mem 116 117 #endif // PANDA_LIBPANDABASE_MEM_STWGC_H 118