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