1 /* 2 * Copyright (c) 2021 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_CONCURRENT_SWEEPER_H 17 #define ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H 18 19 #include <array> 20 #include <atomic> 21 22 #include "ecmascript/mem/space.h" 23 #include "ecmascript/taskpool/task.h" 24 25 #include "ecmascript/platform/mutex.h" 26 27 namespace panda::ecmascript { 28 // CONFIG_DISABLE means concurrent sweeper is disabled by options or macros and cannot be changed. 29 // REQUEST_DISABLE means we want to disable concurrent sweeper while it is sweeping. 30 // REQUEST_DISABLE can be ragarded as enable and will be changed into disable after finishing sweeping. 31 enum class EnableConcurrentSweepType : uint8_t { 32 ENABLE, 33 CONFIG_DISABLE, 34 DISABLE, 35 REQUEST_DISABLE 36 }; 37 38 class ConcurrentSweeper { 39 public: 40 ConcurrentSweeper(Heap *heap, EnableConcurrentSweepType type); 41 ~ConcurrentSweeper() = default; 42 43 NO_COPY_SEMANTIC(ConcurrentSweeper); 44 NO_MOVE_SEMANTIC(ConcurrentSweeper); 45 46 void PostTask(bool fullGC = false); 47 void Sweep(bool fullGC = false); 48 void SweepNewToOldRegions(); 49 50 void WaitAllTaskFinished(); 51 // Help to finish sweeping task. It can be called through js thread 52 void EnsureAllTaskFinished(); 53 // Ensure task finish. It can be called through js thread 54 void EnsureTaskFinished(MemSpaceType type); 55 void EnsureTaskFinishedNoCheck(MemSpaceType type); 56 57 void TryFillSweptRegion(); 58 void ClearRSetInRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); 59 60 void EnableConcurrentSweep(EnableConcurrentSweepType type); 61 IsSweeping()62 bool IsSweeping() 63 { 64 return isSweeping_; 65 } 66 ConcurrentSweepEnabled()67 bool ConcurrentSweepEnabled() 68 { 69 return !IsDisabled(); 70 } 71 ConfigConcurrentSweep(bool enabled)72 void ConfigConcurrentSweep(bool enabled) 73 { 74 enableType_ = enabled ? EnableConcurrentSweepType::ENABLE : 75 EnableConcurrentSweepType::CONFIG_DISABLE; 76 } 77 IsDisabled()78 bool IsDisabled() const 79 { 80 return enableType_ == EnableConcurrentSweepType::DISABLE || 81 enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE; 82 } 83 IsRequestDisabled()84 bool IsRequestDisabled() const 85 { 86 return enableType_ == EnableConcurrentSweepType::REQUEST_DISABLE; 87 } 88 IsConfigDisabled()89 bool IsConfigDisabled() const 90 { 91 return enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE; 92 } 93 private: 94 class SweeperTask : public Task { 95 public: SweeperTask(int32_t id,ConcurrentSweeper * sweeper,MemSpaceType type,MemSpaceType startSpaceType)96 SweeperTask(int32_t id, ConcurrentSweeper *sweeper, MemSpaceType type, MemSpaceType startSpaceType) 97 : Task(id), sweeper_(sweeper), type_(type), startSpaceType_(startSpaceType) {}; 98 ~SweeperTask() override = default; 99 bool Run(uint32_t threadIndex) override; 100 101 NO_COPY_SEMANTIC(SweeperTask); 102 NO_MOVE_SEMANTIC(SweeperTask); 103 104 private: 105 ConcurrentSweeper *sweeper_; 106 MemSpaceType type_; 107 MemSpaceType startSpaceType_; 108 }; 109 110 void AsyncSweepSpace(MemSpaceType type, bool isMain); 111 112 void WaitingTaskFinish(MemSpaceType type); 113 114 std::array<Mutex, FREE_LIST_NUM> mutexs_; 115 std::array<ConditionVariable, FREE_LIST_NUM> cvs_; 116 std::array<std::atomic_int, FREE_LIST_NUM> remainingTaskNum_ = {0, 0, 0}; 117 118 Heap *heap_; 119 EnableConcurrentSweepType enableType_ {EnableConcurrentSweepType::CONFIG_DISABLE}; 120 bool isSweeping_ {false}; 121 MemSpaceType startSpaceType_ = MemSpaceType::OLD_SPACE; 122 }; 123 } // namespace panda::ecmascript 124 #endif // ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H 125