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 ECMASCRIPT_MEM_PARALLEL_MARKER_H 17 #define ECMASCRIPT_MEM_PARALLEL_MARKER_H 18 19 #include "ecmascript/js_hclass.h" 20 #include "ecmascript/mem/gc_bitset.h" 21 #include "ecmascript/mem/object_xray.h" 22 #include "ecmascript/mem/slots.h" 23 #include "ecmascript/mem/work_manager.h" 24 25 namespace panda::ecmascript { 26 class Heap; 27 class Region; 28 class TaggedObject; 29 30 static constexpr uint32_t MAIN_THREAD_INDEX = 0; 31 32 class Marker { 33 public: 34 explicit Marker(Heap *heap); 35 virtual ~Marker() = default; 36 Initialize()37 virtual void Initialize() 38 { 39 LOG_GC(DEBUG) << "Marker::Initialize do nothing"; 40 } 41 42 void MarkRoots(uint32_t threadId); 43 void ProcessOldToNew(uint32_t threadId); // for HPPGC only semi mode 44 void ProcessOldToNew(uint32_t threadId, Region *region); // for SemiGC 45 void ProcessSnapshotRSet(uint32_t threadId); // for SemiGC 46 ProcessMarkStack(uint32_t threadId)47 virtual void ProcessMarkStack([[maybe_unused]] uint32_t threadId) 48 { 49 LOG_GC(FATAL) << "can not call this method"; 50 } 51 52 protected: 53 // non move MarkObject(uint32_t threadId,TaggedObject * object)54 virtual inline void MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object) 55 { 56 LOG_GC(FATAL) << "can not call this method"; 57 } 58 MarkObject(uint32_t threadId,TaggedObject * object,ObjectSlot slot)59 virtual inline SlotStatus MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object, 60 [[maybe_unused]] ObjectSlot slot) // move 61 { 62 LOG_GC(FATAL) << "can not call this method"; 63 return SlotStatus::KEEP_SLOT; 64 } 65 66 virtual inline void HandleOldToNewRSet(uint32_t threadId, Region *region) = 0; 67 virtual inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) = 0; 68 virtual inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 69 ObjectSlot end) = 0; 70 virtual inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 71 uintptr_t baseOldObject) = 0; RecordWeakReference(uint32_t threadId,JSTaggedType * ref,Region * objectRegion)72 virtual inline void RecordWeakReference([[maybe_unused]] uint32_t threadId, [[maybe_unused]] JSTaggedType *ref, 73 [[maybe_unused]] Region *objectRegion) 74 { 75 LOG_GC(FATAL) << "can not call this method"; 76 } 77 78 Heap *heap_ {nullptr}; 79 ObjectXRay objXRay_ {nullptr}; 80 WorkManager *workManager_ {nullptr}; 81 }; 82 83 class NonMovableMarker : public Marker { 84 public: NonMovableMarker(Heap * heap)85 explicit NonMovableMarker(Heap *heap) : Marker(heap) {} 86 ~NonMovableMarker() = default; 87 88 protected: 89 void ProcessMarkStack(uint32_t threadId) override; 90 inline void MarkObject(uint32_t threadId, TaggedObject *object) override; 91 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; 92 inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 93 ObjectSlot end) override; 94 inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 95 uintptr_t baseOldObject) override; 96 97 inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override; 98 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion) override; 99 }; 100 101 class MovableMarker : public Marker { 102 public: MovableMarker(Heap * heap)103 explicit MovableMarker(Heap *heap) : Marker(heap) {} 104 ~MovableMarker() = default; 105 106 protected: 107 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; 108 inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 109 ObjectSlot end) override; 110 inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 111 uintptr_t baseOldObject) override; 112 virtual inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 113 ObjectSlot slot) = 0; 114 115 inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override; 116 117 inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size, bool &shouldPromote); 118 inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, 119 uintptr_t toAddress, size_t size, const MarkWord &markWord, 120 ObjectSlot slot, bool isPromoted = false); 121 inline bool UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); 122 }; 123 124 class SemiGCMarker : public MovableMarker { 125 public: SemiGCMarker(Heap * heap)126 explicit SemiGCMarker(Heap *heap) : MovableMarker(heap) {} 127 ~SemiGCMarker() = default; 128 129 void Initialize() override; 130 131 protected: 132 void ProcessMarkStack(uint32_t threadId) override; 133 inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; 134 inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 135 ObjectSlot slot) override; 136 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override; 137 138 private: 139 inline bool ShouldBePromoted(TaggedObject *object); 140 141 uintptr_t waterLine_ {0}; 142 }; 143 144 class CompressGCMarker : public MovableMarker { 145 public: CompressGCMarker(Heap * heap)146 explicit CompressGCMarker(Heap *heap) : MovableMarker(heap) {} 147 ~CompressGCMarker() = default; 148 149 inline bool NeedEvacuate(Region *region); SetAppSpawn(bool flag)150 void SetAppSpawn(bool flag) 151 { 152 isAppSpawn_ = flag; 153 } 154 155 protected: 156 void ProcessMarkStack(uint32_t threadId) override; 157 inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; 158 159 inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 160 ObjectSlot slot) override; 161 uintptr_t AllocateForwardAddress(uint32_t threadId, size_t size, JSHClass *hclass, TaggedObject *object); 162 inline uintptr_t AllocateAppSpawnSpace(size_t size); 163 inline uintptr_t AllocateReadOnlySpace(size_t size); 164 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override; 165 166 private: 167 bool isAppSpawn_ {false}; 168 os::memory::Mutex mutex_; 169 }; 170 } // namespace panda::ecmascript 171 #endif // ECMASCRIPT_MEM_PARALLEL_MARKER_H 172