1 /* 2 * Copyright (c) 2024 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_SHARED_HEAP_SHARED_GC_MARKER_H 17 #define ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_MARKER_H 18 19 #include "ecmascript/js_hclass.h" 20 #include "ecmascript/mem/rset_worklist_handler-inl.h" 21 #include "ecmascript/mem/slots.h" 22 #include "ecmascript/mem/work_manager.h" 23 24 namespace panda::ecmascript { 25 class Region; 26 class TaggedObject; 27 class SharedGCMarker; 28 class JSHClass; 29 enum class Root; 30 31 enum class SharedMarkType : uint8_t { 32 NOT_CONCURRENT_MARK, 33 CONCURRENT_MARK_INITIAL_MARK, 34 CONCURRENT_MARK_REMARK, 35 }; 36 37 class SharedGCMarkerBase { 38 public: SharedGCMarkerBase(SharedGCWorkManager *workManger)39 explicit SharedGCMarkerBase(SharedGCWorkManager *workManger) : sWorkManager_(workManger) {} 40 virtual ~SharedGCMarkerBase() = default; 41 42 void ResetWorkManager(SharedGCWorkManager *workManager); 43 void MarkRoots(uint32_t threadId, SharedMarkType markType, VMRootVisitType type = VMRootVisitType::MARK); 44 void MarkLocalVMRoots(uint32_t threadId, EcmaVM *localVm, SharedMarkType markType, 45 VMRootVisitType type = VMRootVisitType::MARK); 46 void CollectLocalVMRSet(EcmaVM *localVm); 47 void MarkStringCache(uint32_t threadId); 48 void MarkSerializeRoots(uint32_t threadId); 49 void MarkSharedModule(uint32_t threadId); 50 inline void ProcessThenMergeBackRSetFromBoundJSThread(RSetWorkListHandler *handler); 51 template<SharedMarkType markType> 52 inline void DoMark(uint32_t threadId); 53 template <typename Callback> 54 inline bool VisitBodyInObj(TaggedObject *root, ObjectSlot start, ObjectSlot end, Callback callback); 55 inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot); 56 inline void HandleLocalRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot); 57 inline void HandleLocalRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 58 ObjectSlot end); 59 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref); 60 void MergeBackAndResetRSetWorkListHandler(); 61 template<SharedMarkType markType> 62 inline void ProcessVisitorOfDoMark(uint32_t threadId); 63 inline void ProcessVisitor(RSetWorkListHandler *handler); 64 inline bool MarkObjectOfProcessVisitor(void *mem, WorkNode *&localBuffer); 65 66 inline void MarkObjectFromJSThread(WorkNode *&localBuffer, TaggedObject *object); 67 MarkValue([[maybe_unused]] uint32_t threadId, [[maybe_unused]] ObjectSlot &slot)68 virtual inline void MarkValue([[maybe_unused]] uint32_t threadId, [[maybe_unused]] ObjectSlot &slot) 69 { 70 LOG_GC(FATAL) << " can not call this method"; 71 } 72 MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object, [[maybe_unused]] ObjectSlot &slot)73 virtual inline void MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object, 74 [[maybe_unused]] ObjectSlot &slot) 75 { 76 LOG_GC(FATAL) << " can not call this method"; 77 } 78 HandleLocalDerivedRoots([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived, [[maybe_unused]] uintptr_t baseOldObject)79 virtual inline void HandleLocalDerivedRoots([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, 80 [[maybe_unused]] ObjectSlot derived, 81 [[maybe_unused]] uintptr_t baseOldObject) 82 { 83 LOG_GC(FATAL) << " can not call this method"; 84 } ProcessMarkStack([[maybe_unused]] uint32_t threadId)85 virtual void ProcessMarkStack([[maybe_unused]] uint32_t threadId) 86 { 87 LOG_GC(FATAL) << " can not call this method"; 88 } 89 90 protected: 91 SharedGCWorkManager *sWorkManager_ {nullptr}; 92 93 private: 94 template<SharedMarkType markType> 95 inline auto GenerateRSetVisitor(uint32_t threadId); 96 inline void RecordObject(JSTaggedValue value, uint32_t threadId, void *mem); 97 template<SharedMarkType markType> 98 inline bool GetVisitor(JSTaggedValue value, uint32_t threadId, void *mem); 99 100 std::vector<RSetWorkListHandler*> rSetHandlers_; 101 }; 102 103 class SharedGCMarker : public SharedGCMarkerBase { 104 public: 105 explicit SharedGCMarker(SharedGCWorkManager *workManger); 106 ~SharedGCMarker() override = default; 107 void ProcessMarkStack(uint32_t threadId) override; 108 109 protected: 110 inline void MarkValue(uint32_t threadId, ObjectSlot &slot) override; 111 inline void MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot &slot) override; 112 inline void HandleLocalDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 113 uintptr_t baseOldObject) override; 114 }; 115 116 class SharedGCMovableMarker : public SharedGCMarkerBase { 117 public: 118 explicit SharedGCMovableMarker(SharedGCWorkManager *workManger, SharedHeap *sHeap); 119 ~SharedGCMovableMarker() override = default; 120 inline bool NeedEvacuate(Region *region); 121 void ProcessMarkStack(uint32_t threadId) override; 122 123 protected: 124 inline void HandleLocalDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 125 uintptr_t baseOldObject) override; 126 inline void MarkValue(uint32_t threadId, ObjectSlot &slot) override; 127 inline void MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot &slot) override; 128 inline uintptr_t AllocateForwardAddress(uint32_t threadId, size_t size); 129 inline void EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, ObjectSlot slot); 130 inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size); 131 inline void RawCopyObject(uintptr_t fromAddress, uintptr_t toAddress, size_t size, const MarkWord &markWord); 132 inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, 133 uintptr_t toAddress, size_t size, ObjectSlot slot); 134 inline void UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); 135 136 private: 137 SharedHeap *sHeap_; 138 }; 139 } // namespace panda::ecmascript 140 #endif // ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_MARKER_H