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 ProcessOldToNewNoMarkStack(uint32_t threadId); 45 void ProcessOldToNew(uint32_t threadId, Region *region); // for SemiGC 46 void ProcessSnapshotRSet(uint32_t threadId); // for SemiGC 47 void ProcessSnapshotRSetNoMarkStack(uint32_t threadId); 48 ProcessMarkStack(uint32_t threadId)49 virtual void ProcessMarkStack([[maybe_unused]] uint32_t threadId) 50 { 51 LOG_GC(FATAL) << "can not call this method"; 52 } 53 ProcessIncrementalMarkStack(uint32_t threadId,uint32_t markStepSize)54 virtual void ProcessIncrementalMarkStack([[maybe_unused]] uint32_t threadId, 55 [[maybe_unused]] uint32_t markStepSize) 56 { 57 LOG_GC(FATAL) << "can not call this method"; 58 } 59 60 protected: 61 // non move MarkObject(uint32_t threadId,TaggedObject * object)62 virtual inline void MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object) 63 { 64 LOG_GC(FATAL) << "can not call this method"; 65 } 66 MarkObject(uint32_t threadId,TaggedObject * object,ObjectSlot slot)67 virtual inline SlotStatus MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object, 68 [[maybe_unused]] ObjectSlot slot) // move 69 { 70 LOG_GC(FATAL) << "can not call this method"; 71 return SlotStatus::KEEP_SLOT; 72 } 73 74 virtual inline void HandleOldToNewRSet(uint32_t threadId, Region *region) = 0; 75 virtual inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) = 0; 76 virtual inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 77 ObjectSlot end) = 0; 78 virtual inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 79 uintptr_t baseOldObject) = 0; RecordWeakReference(uint32_t threadId,JSTaggedType * ref,Region * objectRegion)80 virtual inline void RecordWeakReference([[maybe_unused]] uint32_t threadId, [[maybe_unused]] JSTaggedType *ref, 81 [[maybe_unused]] Region *objectRegion) 82 { 83 LOG_GC(FATAL) << "can not call this method"; 84 } 85 86 Heap *heap_ {nullptr}; 87 ObjectXRay objXRay_ {nullptr}; 88 WorkManager *workManager_ {nullptr}; 89 }; 90 91 class NonMovableMarker : public Marker { 92 public: NonMovableMarker(Heap * heap)93 explicit NonMovableMarker(Heap *heap) : Marker(heap) {} 94 ~NonMovableMarker() override = default; 95 96 protected: 97 void ProcessMarkStack(uint32_t threadId) override; 98 template <typename Callback> 99 inline bool VisitBodyInObj(TaggedObject *root, ObjectSlot start, ObjectSlot end, Callback callback); 100 inline void MarkValue(uint32_t threadId, ObjectSlot &slot, Region *rootRegion, bool needBarrier); 101 inline void MarkObject(uint32_t threadId, TaggedObject *object) override; 102 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; 103 inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 104 ObjectSlot end) override; 105 inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 106 uintptr_t baseOldObject) override; 107 108 inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override; 109 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion) override; 110 void ProcessIncrementalMarkStack(uint32_t threadId, uint32_t markStepSize) override; 111 }; 112 113 class MovableMarker : public Marker { 114 public: MovableMarker(Heap * heap)115 explicit MovableMarker(Heap *heap) : Marker(heap) {} 116 ~MovableMarker() override = default; 117 118 protected: 119 template <typename Callback> 120 inline bool VisitBodyInObj(TaggedObject *root, ObjectSlot start, ObjectSlot end, Callback callback); 121 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; 122 inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 123 ObjectSlot end) override; 124 inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 125 uintptr_t baseOldObject) override; 126 virtual inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 127 ObjectSlot slot) = 0; 128 129 inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override; 130 131 inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size, bool &shouldPromote); 132 inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, 133 uintptr_t toAddress, size_t size, const MarkWord &markWord, 134 ObjectSlot slot, bool isPromoted = false); 135 inline bool UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); 136 }; 137 138 class SemiGCMarker : public MovableMarker { 139 public: SemiGCMarker(Heap * heap)140 explicit SemiGCMarker(Heap *heap) : MovableMarker(heap) {} 141 ~SemiGCMarker() override = default; 142 143 void Initialize() override; 144 145 protected: 146 void ProcessMarkStack(uint32_t threadId) override; 147 inline void MarkValue(uint32_t threadId, TaggedObject *root, ObjectSlot slot); 148 inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; 149 inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 150 ObjectSlot slot) override; 151 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override; 152 153 private: 154 inline bool ShouldBePromoted(TaggedObject *object); 155 156 uintptr_t waterLine_ {0}; 157 }; 158 159 class CompressGCMarker : public MovableMarker { 160 public: CompressGCMarker(Heap * heap)161 explicit CompressGCMarker(Heap *heap) : MovableMarker(heap) {} 162 ~CompressGCMarker() override = default; 163 164 inline bool NeedEvacuate(Region *region); SetAppSpawn(bool flag)165 void SetAppSpawn(bool flag) 166 { 167 isAppSpawn_ = flag; 168 } 169 170 protected: 171 void ProcessMarkStack(uint32_t threadId) override; 172 inline void MarkValue(uint32_t threadId, ObjectSlot slot); 173 inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; 174 175 inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 176 ObjectSlot slot) override; 177 uintptr_t AllocateForwardAddress(uint32_t threadId, size_t size, JSHClass *hclass, TaggedObject *object); 178 inline uintptr_t AllocateAppSpawnSpace(size_t size); 179 inline uintptr_t AllocateReadOnlySpace(size_t size); 180 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override; 181 182 private: 183 bool isAppSpawn_ {false}; 184 os::memory::Mutex mutex_; 185 }; 186 } // namespace panda::ecmascript 187 #endif // ECMASCRIPT_MEM_PARALLEL_MARKER_H 188