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