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_RSET_WORKLIST_HANDLER_H 17 #define ECMASCRIPT_MEM_RSET_WORKLIST_HANDLER_H 18 19 #include "ecmascript/platform/mutex.h" 20 21 namespace panda::ecmascript { 22 class Heap; 23 class Region; 24 class RememberedSet; 25 26 class RSetItem { 27 public: RSetItem(Region * region,RememberedSet * rSet)28 explicit RSetItem(Region *region, RememberedSet *rSet) : region_(region), rSet_(rSet) {} 29 ~RSetItem() = default; 30 31 template<class Visitor> 32 inline void Process(const Visitor &visitor); 33 34 inline void MergeBack(); 35 36 private: 37 Region *region_ {nullptr}; 38 RememberedSet *rSet_ {nullptr}; 39 }; 40 41 class RSetWorkListHandler { 42 public: 43 explicit RSetWorkListHandler(Heap *heap, JSThread *thread); 44 ~RSetWorkListHandler() = default; 45 46 inline void Initialize(); 47 48 template<class Visitor> 49 inline void ProcessAll(const Visitor &visitor); 50 51 // Only called from the bound js thread in RUNNING state. 52 inline void WaitFinishedThenMergeBack(); 53 54 inline bool MergeBack(); 55 56 inline Heap *GetHeap(); 57 58 inline void EnumerateRegions(const Heap *heap); 59 60 template<class Visitor> 61 inline void ProcessAllVisitor(const Visitor &visitor, int done); 62 63 inline void MergeBackForAllItem(); 64 GetOwnerThreadUnsafe()65 JSThread *GetOwnerThreadUnsafe() const 66 { 67 return ownerThread_; 68 } 69 70 private: 71 inline void CollectRSetItemsInHeap(const Heap *heap); 72 73 template<class Visitor> 74 inline bool ProcessNext(const Visitor &visitor); 75 76 inline bool TryMergeBack(); 77 78 Heap *heap_ {nullptr}; 79 // The thread is not guaranteed to be alive. The caller must ensure that the thread is alive. 80 JSThread *ownerThread_ {nullptr}; 81 /** 82 * This value represent whether there are some items to process, this is set to true in Initialize when collecting 83 * the RSet in heap(call from daemon thread in SuspendAll), and use CAS to set to false when try to merge back and 84 * clear(call maybe from daemon thread in SuspendAll, or from bound js thread in RUNNING state). 85 * Only two ways to modify this value: 86 * 1. Initialzie, from daemon thread in SuspendAll, and the modification must be visible to the bound js thread. 87 * 2. MergeBackAndReset, maybe from daemon thread when SuspendAll, or from js thread which region 88 * belonged to in RUNNING state. 89 * So the bound js thread can always see the lastest value without using atomic. 90 * And thus WaitFinishedThenMergeBack should ONLY be called from the bound js thread in RUNNING state. 91 */ 92 bool initialized_ {false}; 93 std::vector<RSetItem> items_; 94 std::atomic<int> nextItemIndex_ {-1}; 95 int remainItems_ {0}; 96 Mutex mutex_; 97 ConditionVariable cv_; 98 }; 99 } // namespace panda::ecmascript 100 101 #endif // ECMASCRIPT_MEM_RSET_WORKLIST_HANDLER_H 102