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(uint32_t threadId,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(uint32_t threadId,TaggedObject * object,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(Root type,ObjectSlot base,ObjectSlot derived,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(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 // This method is called within the GCIterateThreadList method, 95 // so the thread lock problem does not need to be considered. 96 inline void NotifyThreadProcessRsetStart(JSThread *localThread); 97 inline void NotifyThreadProcessRsetFinished(JSThread *localThread); 98 99 template<SharedMarkType markType> 100 inline auto GenerateRSetVisitor(uint32_t threadId); 101 inline void RecordObject(JSTaggedValue value, uint32_t threadId, void *mem); 102 template<SharedMarkType markType> 103 inline bool GetVisitor(JSTaggedValue value, uint32_t threadId, void *mem); 104 105 std::vector<RSetWorkListHandler*> rSetHandlers_; 106 }; 107 108 class SharedGCMarker : public SharedGCMarkerBase { 109 public: 110 explicit SharedGCMarker(SharedGCWorkManager *workManger); 111 ~SharedGCMarker() override = default; 112 void ProcessMarkStack(uint32_t threadId) override; 113 114 protected: 115 inline void MarkValue(uint32_t threadId, ObjectSlot &slot) override; 116 inline void MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot &slot) override; 117 inline void HandleLocalDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 118 uintptr_t baseOldObject) override; 119 }; 120 121 class SharedGCMovableMarker : public SharedGCMarkerBase { 122 public: 123 explicit SharedGCMovableMarker(SharedGCWorkManager *workManger, SharedHeap *sHeap); 124 ~SharedGCMovableMarker() override = default; 125 inline bool NeedEvacuate(Region *region); 126 void ProcessMarkStack(uint32_t threadId) override; 127 128 protected: 129 inline void HandleLocalDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived, 130 uintptr_t baseOldObject) override; 131 inline void MarkValue(uint32_t threadId, ObjectSlot &slot) override; 132 inline void MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot &slot) override; 133 inline uintptr_t AllocateForwardAddress(uint32_t threadId, size_t size); 134 inline void EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, ObjectSlot slot); 135 inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size); 136 inline void RawCopyObject(uintptr_t fromAddress, uintptr_t toAddress, size_t size, const MarkWord &markWord); 137 inline void UpdateForwardAddressIfSuccess(uint32_t threadId, JSHClass *klass, uintptr_t toAddress, size_t size, 138 ObjectSlot slot); 139 inline void UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); 140 141 private: 142 SharedHeap *sHeap_; 143 }; 144 } // namespace panda::ecmascript 145 #endif // ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_MARKER_H