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