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/object_xray.h" 21 #include "ecmascript/mem/remembered_set.h" 22 #include "ecmascript/mem/slots.h" 23 #include "libpandabase/utils/logger.h" 24 25 namespace panda::ecmascript { 26 class Heap; 27 class TaggedObject; 28 class Region; 29 30 class Marker { 31 public: 32 Marker(Heap *heap); 33 virtual ~Marker() = default; 34 Initialized()35 virtual void Initialized() 36 { 37 ECMA_GC_LOG() << "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 ProcessOldToNew(uint32_t threadId, Region *region); // for SemiGC 43 void ProcessSnapshotRSet(uint32_t threadId); // for SemiGC 44 ProcessMarkStack(uint32_t threadId)45 virtual void ProcessMarkStack(uint32_t threadId) 46 { 47 LOG(FATAL, ECMASCRIPT) << "can not call this method"; 48 } 49 50 protected: MarkObject(uint32_t threadId,TaggedObject * object)51 virtual inline void MarkObject(uint32_t threadId, TaggedObject *object) // non move 52 { 53 LOG(FATAL, ECMASCRIPT) << "can not call this method"; 54 } 55 MarkObject(uint32_t threadId,TaggedObject * object,ObjectSlot slot)56 virtual inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) // move 57 { 58 LOG(FATAL, ECMASCRIPT) << "can not call this method"; 59 return SlotStatus::KEEP_SLOT; 60 } 61 62 virtual inline void HandleOldToNewRSet(uint32_t threadId, Region *region) = 0; 63 virtual inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) = 0; 64 virtual inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 65 ObjectSlot end) = 0; RecordWeakReference(uint32_t threadId,JSTaggedType * ref,Region * objectRegion)66 virtual inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, 67 [[maybe_unused]] Region *objectRegion) 68 { 69 LOG(FATAL, ECMASCRIPT) << "can not call this method"; 70 } 71 72 Heap *heap_; 73 ObjectXRay objXRay_; 74 }; 75 76 class NonMovableMarker : public Marker { 77 public: NonMovableMarker(Heap * heap)78 NonMovableMarker(Heap *heap) : Marker(heap) {} 79 80 protected: 81 void ProcessMarkStack(uint32_t threadId) override; 82 inline void MarkObject(uint32_t threadId, TaggedObject *object) override; 83 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; 84 inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 85 ObjectSlot end) override; 86 87 inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override; 88 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion) override; 89 }; 90 91 class MovableMarker : public Marker { 92 public: MovableMarker(Heap * heap)93 MovableMarker(Heap *heap) : Marker(heap) {} 94 95 protected: 96 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; 97 inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 98 ObjectSlot end) override; 99 virtual inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 100 ObjectSlot slot) = 0; 101 102 inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override; 103 104 inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size, bool &shouldPromote); 105 inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, 106 uintptr_t toAddress, size_t size, const MarkWord &markWord, 107 ObjectSlot slot); 108 inline bool UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); 109 }; 110 111 class SemiGcMarker : public MovableMarker { 112 public: SemiGcMarker(Heap * heap)113 SemiGcMarker(Heap *heap) : MovableMarker(heap) {} 114 115 void Initialized() override; 116 117 protected: 118 void ProcessMarkStack(uint32_t threadId) override; 119 inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; 120 inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 121 ObjectSlot slot) override; 122 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override; 123 124 private: 125 inline bool ShouldBePromoted(TaggedObject *object); 126 127 uintptr_t waterLine_ {0}; 128 }; 129 130 class CompressGcMarker : public MovableMarker { 131 public: CompressGcMarker(Heap * heap)132 CompressGcMarker(Heap *heap) : MovableMarker(heap) {} 133 134 protected: 135 void ProcessMarkStack(uint32_t threadId) override; 136 inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; 137 138 inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, 139 ObjectSlot slot) override; 140 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override; 141 }; 142 } // namespace panda::ecmascript 143 #endif // ECMASCRIPT_MEM_PARALLEL_MARKER_H 144