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