14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <array> 204514f5e3Sopenharmony_ci#include <atomic> 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_ci#include "ecmascript/mem/space.h" 234514f5e3Sopenharmony_ci#include "ecmascript/taskpool/task.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ci#include "ecmascript/platform/mutex.h" 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_cinamespace panda::ecmascript { 284514f5e3Sopenharmony_ci// CONFIG_DISABLE means concurrent sweeper is disabled by options or macros and cannot be changed. 294514f5e3Sopenharmony_ci// REQUEST_DISABLE means we want to disable concurrent sweeper while it is sweeping. 304514f5e3Sopenharmony_ci// REQUEST_DISABLE can be ragarded as enable and will be changed into disable after finishing sweeping. 314514f5e3Sopenharmony_cienum class EnableConcurrentSweepType : uint8_t { 324514f5e3Sopenharmony_ci ENABLE, 334514f5e3Sopenharmony_ci CONFIG_DISABLE, 344514f5e3Sopenharmony_ci DISABLE, 354514f5e3Sopenharmony_ci REQUEST_DISABLE 364514f5e3Sopenharmony_ci}; 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_ciclass ConcurrentSweeper { 394514f5e3Sopenharmony_cipublic: 404514f5e3Sopenharmony_ci ConcurrentSweeper(Heap *heap, EnableConcurrentSweepType type); 414514f5e3Sopenharmony_ci ~ConcurrentSweeper() = default; 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(ConcurrentSweeper); 444514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(ConcurrentSweeper); 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ci void PostTask(bool fullGC = false); 474514f5e3Sopenharmony_ci void Sweep(bool fullGC = false); 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_ci void WaitAllTaskFinished(); 504514f5e3Sopenharmony_ci // Help to finish sweeping task. It can be called through js thread 514514f5e3Sopenharmony_ci void EnsureAllTaskFinished(); 524514f5e3Sopenharmony_ci // Ensure task finish. It can be called through js thread 534514f5e3Sopenharmony_ci void EnsureTaskFinished(MemSpaceType type); 544514f5e3Sopenharmony_ci void EnsureTaskFinishedNoCheck(MemSpaceType type); 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ci void TryFillSweptRegion(); 574514f5e3Sopenharmony_ci void ClearRSetInRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); 584514f5e3Sopenharmony_ci 594514f5e3Sopenharmony_ci void EnableConcurrentSweep(EnableConcurrentSweepType type); 604514f5e3Sopenharmony_ci 614514f5e3Sopenharmony_ci bool IsSweeping() 624514f5e3Sopenharmony_ci { 634514f5e3Sopenharmony_ci return isSweeping_; 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci 664514f5e3Sopenharmony_ci bool ConcurrentSweepEnabled() 674514f5e3Sopenharmony_ci { 684514f5e3Sopenharmony_ci return !IsDisabled(); 694514f5e3Sopenharmony_ci } 704514f5e3Sopenharmony_ci 714514f5e3Sopenharmony_ci void ConfigConcurrentSweep(bool enabled) 724514f5e3Sopenharmony_ci { 734514f5e3Sopenharmony_ci enableType_ = enabled ? EnableConcurrentSweepType::ENABLE : 744514f5e3Sopenharmony_ci EnableConcurrentSweepType::CONFIG_DISABLE; 754514f5e3Sopenharmony_ci } 764514f5e3Sopenharmony_ci 774514f5e3Sopenharmony_ci bool IsDisabled() const 784514f5e3Sopenharmony_ci { 794514f5e3Sopenharmony_ci return enableType_ == EnableConcurrentSweepType::DISABLE || 804514f5e3Sopenharmony_ci enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE; 814514f5e3Sopenharmony_ci } 824514f5e3Sopenharmony_ci 834514f5e3Sopenharmony_ci bool IsRequestDisabled() const 844514f5e3Sopenharmony_ci { 854514f5e3Sopenharmony_ci return enableType_ == EnableConcurrentSweepType::REQUEST_DISABLE; 864514f5e3Sopenharmony_ci } 874514f5e3Sopenharmony_ci 884514f5e3Sopenharmony_ci bool IsConfigDisabled() const 894514f5e3Sopenharmony_ci { 904514f5e3Sopenharmony_ci return enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE; 914514f5e3Sopenharmony_ci } 924514f5e3Sopenharmony_ciprivate: 934514f5e3Sopenharmony_ci class SweeperTask : public Task { 944514f5e3Sopenharmony_ci public: 954514f5e3Sopenharmony_ci SweeperTask(int32_t id, ConcurrentSweeper *sweeper, MemSpaceType type) 964514f5e3Sopenharmony_ci : Task(id), sweeper_(sweeper), type_(type) {}; 974514f5e3Sopenharmony_ci ~SweeperTask() override = default; 984514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(SweeperTask); 1014514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(SweeperTask); 1024514f5e3Sopenharmony_ci 1034514f5e3Sopenharmony_ci private: 1044514f5e3Sopenharmony_ci ConcurrentSweeper *sweeper_; 1054514f5e3Sopenharmony_ci MemSpaceType type_; 1064514f5e3Sopenharmony_ci }; 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci void AsyncSweepSpace(MemSpaceType type, bool isMain); 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ci void WaitingTaskFinish(MemSpaceType type); 1114514f5e3Sopenharmony_ci 1124514f5e3Sopenharmony_ci std::array<Mutex, FREE_LIST_NUM> mutexs_; 1134514f5e3Sopenharmony_ci std::array<ConditionVariable, FREE_LIST_NUM> cvs_; 1144514f5e3Sopenharmony_ci std::array<std::atomic_int, FREE_LIST_NUM> remainingTaskNum_ = {0, 0, 0}; 1154514f5e3Sopenharmony_ci 1164514f5e3Sopenharmony_ci Heap *heap_; 1174514f5e3Sopenharmony_ci EnableConcurrentSweepType enableType_ {EnableConcurrentSweepType::CONFIG_DISABLE}; 1184514f5e3Sopenharmony_ci bool isSweeping_ {false}; 1194514f5e3Sopenharmony_ci MemSpaceType startSpaceType_ = MemSpaceType::OLD_SPACE; 1204514f5e3Sopenharmony_ci}; 1214514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1224514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H 123