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