• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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 #ifndef PANDA_RUNTIME_MEM_GC_GC_ADAPTIVE_STACK_H
16 #define PANDA_RUNTIME_MEM_GC_GC_ADAPTIVE_STACK_H
17 
18 #include "runtime/mem/gc/gc_root_type.h"
19 #include "runtime/mem/gc/workers/gc_workers_tasks.h"
20 #include "runtime/include/mem/panda_containers.h"
21 #include "runtime/mem/gc/g1/object_ref.h"
22 
23 namespace ark::mem {
24 
25 class GC;
26 
27 /*
28  * Adaptive stack with GC workers support.
29  * It will try to pop objects from the source stack and push
30  * it to the destination stack. if the destination stack reaches the limit,
31  * we will create a new task for worker.
32  * If stack limit is equal to zero, it means that the destination stack is unlimited.
33  */
34 template <typename Ref>
35 class GCAdaptiveStack {
36 public:
37     explicit GCAdaptiveStack(GC *gc, size_t stackSizeLimit = 0, size_t newTaskStackSizeLimit = 0,
38                              GCWorkersTaskTypes task = GCWorkersTaskTypes::TASK_EMPTY,
39                              uint64_t timeLimitForNewTaskCreation = 0, PandaDeque<Ref> *stackSrc = nullptr);
40 
41     virtual ~GCAdaptiveStack();
42     NO_COPY_SEMANTIC(GCAdaptiveStack);
43     NO_MOVE_SEMANTIC(GCAdaptiveStack);
44 
45     /**
46      * @brief Add new object into destination stack.
47      * If we set the limit for stack, we will create a new task for
48      * GC workers with it.
49      */
50     void PushToStack(Ref element);
51 
52     /**
53      * @brief Pop an object from source stack.
54      * If the source stack is empty, we will swap it with destination stack
55      * and return an object from it.
56      */
57     Ref PopFromStack();
58 
59     /**
60      * @brief Travers objects in stack via visitor and return marked objects.
61      * Visitor can push in stack, but mustn't pop from it.
62      */
63     template <typename Handler>
64     void TraverseObjects(Handler &handler);
65 
66     /// @brief Check that destination or source stack has at least one object.
67     bool Empty() const;
68     /// @brief Returns the sum of destination and source stacks sizes.
69     size_t Size() const;
70 
71     /**
72      * @brief Set the src stack pointer to nullptr.
73      * Should be used if we decide to free it not on destructor of this instance.
74      */
75     PandaDeque<Ref> *MoveStacksPointers();
76 
77     /// @brief Returns true if stack supports parallel workers, false otherwise
78     bool IsWorkersTaskSupported() const;
79 
80     /// @brief Remove all elements from stack
81     void Clear();
82 
83 protected:
84     virtual GCAdaptiveStack<Ref> *CreateStack() = 0;
85     virtual GCWorkersTask CreateTask(GCAdaptiveStack<Ref> *stack) = 0;
86 
GetStackSrc()87     PandaDeque<Ref> *&GetStackSrc()
88     {
89         return stackSrc_;
90     }
91 
GetStackDst()92     PandaDeque<Ref> *&GetStackDst()
93     {
94         return stackDst_;
95     }
96 
GetTaskType()97     GCWorkersTaskTypes GetTaskType() const
98     {
99         return taskType_;
100     }
101 
GetGC()102     GC *GetGC()
103     {
104         return gc_;
105     }
106 
GetNewTaskStackSizeLimit()107     size_t GetNewTaskStackSizeLimit() const
108     {
109         return newTaskStackSizeLimit_;
110     }
111 
GetTimeLimitForNewTaskCreation()112     uint64_t GetTimeLimitForNewTaskCreation() const
113     {
114         return timeLimitForNewTaskCreation_;
115     }
116 
117 private:
118     static constexpr size_t DEFAULT_TASKS_FOR_TIME_CHECK = 10;
119 
120     /**
121      * @brief Check tasks creation rate.
122      * If we create tasks too frequently, return true.
123      */
124     bool IsHighTaskCreationRate();
125 
126 private:
127     PandaDeque<Ref> *stackSrc_;
128     PandaDeque<Ref> *stackDst_;
129     size_t stackSizeLimit_ {0};
130     size_t initialStackSizeLimit_ {0};
131     size_t newTaskStackSizeLimit_ {0};
132     uint64_t startTime_ {0};
133     uint64_t timeLimitForNewTaskCreation_ {0};
134     size_t tasksForTimeCheck_ {DEFAULT_TASKS_FOR_TIME_CHECK};
135     size_t createdTasks_ {0};
136     GCWorkersTaskTypes taskType_;
137     GC *gc_;
138 };
139 }  // namespace ark::mem
140 
141 #endif  // PANDA_RUNTIME_MEM_GC_GC_ADAPTIVE_STACK_H
142