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
27namespace 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.
31enum class EnableConcurrentSweepType : uint8_t {
32    ENABLE,
33    CONFIG_DISABLE,
34    DISABLE,
35    REQUEST_DISABLE
36};
37
38class ConcurrentSweeper {
39public:
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
61    bool IsSweeping()
62    {
63        return isSweeping_;
64    }
65
66    bool ConcurrentSweepEnabled()
67    {
68        return !IsDisabled();
69    }
70
71    void ConfigConcurrentSweep(bool enabled)
72    {
73        enableType_ = enabled ? EnableConcurrentSweepType::ENABLE :
74                      EnableConcurrentSweepType::CONFIG_DISABLE;
75    }
76
77    bool IsDisabled() const
78    {
79        return enableType_ == EnableConcurrentSweepType::DISABLE ||
80            enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE;
81    }
82
83    bool IsRequestDisabled() const
84    {
85        return enableType_ == EnableConcurrentSweepType::REQUEST_DISABLE;
86    }
87
88    bool IsConfigDisabled() const
89    {
90        return enableType_ == EnableConcurrentSweepType::CONFIG_DISABLE;
91    }
92private:
93    class SweeperTask : public Task {
94    public:
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