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); 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 65 private: 66 inline void CollectRSetItemsInHeap(const Heap *heap); 67 68 template<class Visitor> 69 inline bool ProcessNext(const Visitor &visitor); 70 71 inline bool TryMergeBack(); 72 73 Heap *heap_ {nullptr}; 74 /** 75 * This value represent whether there are some items to process, this is set to true in Initialize when collecting 76 * the RSet in heap(call from daemon thread in SuspendAll), and use CAS to set to false when try to merge back and 77 * clear(call maybe from daemon thread in SuspendAll, or from bound js thread in RUNNING state). 78 * Only two ways to modify this value: 79 * 1. Initialzie, from daemon thread in SuspendAll, and the modification must be visible to the bound js thread. 80 * 2. MergeBackAndReset, maybe from daemon thread when SuspendAll, or from js thread which region 81 * belonged to in RUNNING state. 82 * So the bound js thread can always see the lastest value without using atomic. 83 * And thus WaitFinishedThenMergeBack should ONLY be called from the bound js thread in RUNNING state. 84 */ 85 bool initialized_ {false}; 86 std::vector<RSetItem> items_; 87 std::atomic<int> nextItemIndex_ {-1}; 88 int remainItems_ {0}; 89 Mutex mutex_; 90 ConditionVariable cv_; 91 }; 92 } // namespace panda::ecmascript 93 94 #endif // ECMASCRIPT_MEM_RSET_WORKLIST_HANDLER_H 95