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 class SharedFullGCMarkRootVisitor; 30 class SharedFullGCMarkObjectVisitor; 31 enum class Root; 32 33 enum class SharedMarkType : uint8_t { 34 NOT_CONCURRENT_MARK, 35 CONCURRENT_MARK_INITIAL_MARK, 36 CONCURRENT_MARK_REMARK, 37 }; 38 39 class SharedGCMarkerBase { 40 public: SharedGCMarkerBase(SharedGCWorkManager * workManger)41 explicit SharedGCMarkerBase(SharedGCWorkManager *workManger) : sWorkManager_(workManger) {} 42 virtual ~SharedGCMarkerBase() = default; 43 44 void ResetWorkManager(SharedGCWorkManager *workManager); 45 void MarkRoots(RootVisitor &visitor, SharedMarkType markType, VMRootVisitType type = VMRootVisitType::MARK); 46 void MarkLocalVMRoots(RootVisitor &visitor, EcmaVM *localVm, SharedMarkType markType, 47 VMRootVisitType type = VMRootVisitType::MARK); 48 void CollectLocalVMRSet(EcmaVM *localVm); 49 void MarkStringCache(RootVisitor &visitor); 50 void MarkSerializeRoots(RootVisitor &visitor); 51 void MarkSharedModule(RootVisitor &visitor); 52 inline void ProcessThenMergeBackRSetFromBoundJSThread(RSetWorkListHandler *handler); 53 template<SharedMarkType markType> 54 inline void DoMark(uint32_t threadId); 55 inline void HandleLocalRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot); 56 inline void HandleLocalRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, 57 ObjectSlot end); 58 inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref); 59 void MergeBackAndResetRSetWorkListHandler(); 60 template<SharedMarkType markType> 61 inline void ProcessVisitorOfDoMark(uint32_t threadId); 62 inline void ProcessVisitor(RSetWorkListHandler *handler); 63 inline bool MarkObjectOfProcessVisitor(void *mem, WorkNode *&localBuffer); 64 65 inline void MarkObjectFromJSThread(WorkNode *&localBuffer, TaggedObject *object); 66 MarkObject(uint32_t threadId,TaggedObject * object,ObjectSlot & slot)67 virtual inline void MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object, 68 [[maybe_unused]] ObjectSlot &slot) 69 { 70 LOG_GC(FATAL) << " can not call this method"; 71 } 72 ProcessMarkStack(uint32_t threadId)73 virtual void ProcessMarkStack([[maybe_unused]] uint32_t threadId) 74 { 75 LOG_GC(FATAL) << " can not call this method"; 76 } 77 78 protected: 79 SharedGCWorkManager *sWorkManager_ {nullptr}; 80 81 private: 82 // This method is called within the GCIterateThreadList method, 83 // so the thread lock problem does not need to be considered. 84 inline void NotifyThreadProcessRsetStart(JSThread *localThread); 85 inline void NotifyThreadProcessRsetFinished(JSThread *localThread); 86 87 template<SharedMarkType markType> 88 inline auto GenerateRSetVisitor(uint32_t threadId); 89 inline void RecordObject(JSTaggedValue value, uint32_t threadId, void *mem); 90 template<SharedMarkType markType> 91 inline bool GetVisitor(JSTaggedValue value, uint32_t threadId, void *mem); 92 93 std::vector<RSetWorkListHandler*> rSetHandlers_; 94 }; 95 96 class SharedGCMarker final : public SharedGCMarkerBase { 97 public: 98 explicit SharedGCMarker(SharedGCWorkManager *workManger); 99 ~SharedGCMarker() override = default; 100 void ProcessMarkStack(uint32_t threadId) override; 101 102 protected: 103 inline void MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot &slot) override; 104 }; 105 106 class SharedGCMovableMarker final : public SharedGCMarkerBase { 107 public: 108 explicit SharedGCMovableMarker(SharedGCWorkManager *workManger, SharedHeap *sHeap); 109 ~SharedGCMovableMarker() override = default; 110 inline bool NeedEvacuate(Region *region); 111 void ProcessMarkStack(uint32_t threadId) override; 112 113 protected: 114 inline void MarkValue(uint32_t threadId, ObjectSlot &slot); 115 inline void MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot &slot) override; 116 inline uintptr_t AllocateForwardAddress(uint32_t threadId, size_t size); 117 inline void EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, ObjectSlot slot); 118 inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size); 119 inline void RawCopyObject(uintptr_t fromAddress, uintptr_t toAddress, size_t size, const MarkWord &markWord); 120 inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, 121 uintptr_t toAddress, size_t size, ObjectSlot slot); 122 inline void UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); 123 124 private: 125 SharedHeap *sHeap_; 126 127 friend class SharedFullGCMarkRootVisitor; 128 friend class SharedFullGCMarkObjectVisitor; 129 }; 130 } // namespace panda::ecmascript 131 #endif // ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_MARKER_H