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