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 "libpandabase/os/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 Sweep(bool fullGC = false); 47 48 void WaitAllTaskFinished(); 49 // Help to finish sweeping task. It can be called through js thread 50 void EnsureAllTaskFinished(); 51 // Ensure task finish. It can be called through js thread 52 void EnsureTaskFinished(MemSpaceType type); 53 54 void TryFillSweptRegion(); 55 void ClearRSetInRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); 56 57 void EnableConcurrentSweep(EnableConcurrentSweepType type); 58 IsSweeping()59 bool IsSweeping() 60 { 61 return isSweeping_; 62 } 63 ConcurrentSweepEnabled()64 bool ConcurrentSweepEnabled() 65 { 66 return !IsDisabled(); 67 } 68 ConfigConcurrentSweep(bool enabled)69 void ConfigConcurrentSweep(bool enabled) 70 { 71 enableType_ = enabled ? EnableConcurrentSweepType::ENABLE : 72 EnableConcurrentSweepType::CONFIG_DISABLE; 73 } 74 IsDisabled()75 bool IsDisabled() const 76 { 77 return enableType_ == EnableConcurrentSweepType::DISABLE || 78 enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE; 79 } 80 IsRequestDisabled()81 bool IsRequestDisabled() const 82 { 83 return enableType_ == EnableConcurrentSweepType::REQUEST_DISABLE; 84 } 85 IsConfigDisabled()86 bool IsConfigDisabled() const 87 { 88 return enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE; 89 } 90 private: 91 class SweeperTask : public Task { 92 public: SweeperTask(int32_t id,ConcurrentSweeper * sweeper,MemSpaceType type)93 SweeperTask(int32_t id, ConcurrentSweeper *sweeper, MemSpaceType type) 94 : Task(id), sweeper_(sweeper), type_(type) {}; 95 ~SweeperTask() override = default; 96 bool Run(uint32_t threadIndex) override; 97 98 NO_COPY_SEMANTIC(SweeperTask); 99 NO_MOVE_SEMANTIC(SweeperTask); 100 101 private: 102 ConcurrentSweeper *sweeper_; 103 MemSpaceType type_; 104 }; 105 106 void AsyncSweepSpace(MemSpaceType type, bool isMain); 107 108 void WaitingTaskFinish(MemSpaceType type); 109 110 std::array<os::memory::Mutex, FREE_LIST_NUM> mutexs_; 111 std::array<os::memory::ConditionVariable, FREE_LIST_NUM> cvs_; 112 std::array<std::atomic_int, FREE_LIST_NUM> remainingTaskNum_ = {0, 0, 0}; 113 114 Heap *heap_; 115 EnableConcurrentSweepType enableType_ {EnableConcurrentSweepType::CONFIG_DISABLE}; 116 bool isSweeping_ {false}; 117 MemSpaceType startSpaceType_ = MemSpaceType::OLD_SPACE; 118 }; 119 } // namespace panda::ecmascript 120 #endif // ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H 121