• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 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 
16 #include "runtime/mem/gc/gc_adaptive_marking_stack.h"
17 #include "runtime/mem/gc/gc.h"
18 #include "runtime/mem/gc/workers/gc_workers_task_pool.h"
19 #include "runtime/mem/gc/gc_adaptive_stack_inl.h"
20 
21 namespace ark::mem {
22 
PushToStack(const ObjectHeader * fromObject,ObjectHeader * object)23 void GCAdaptiveMarkingStack::PushToStack(const ObjectHeader *fromObject, ObjectHeader *object)
24 {
25     LOG(DEBUG, GC) << "Add object to stack: " << GetDebugInfoAboutObject(object)
26                    << " accessed from object: " << fromObject;
27     ValidateObject(fromObject, object);
28     GCAdaptiveStack<ObjectHeader *>::PushToStack(object);
29 }
30 
PushToStack(RootType rootType,ObjectHeader * object)31 void GCAdaptiveMarkingStack::PushToStack(RootType rootType, ObjectHeader *object)
32 {
33     LOG(DEBUG, GC) << "Add object to stack: " << GetDebugInfoAboutObject(object) << " accessed as a root: " << rootType;
34     ValidateObject(rootType, object);
35     GCAdaptiveStack<ObjectHeader *>::PushToStack(object);
36 }
37 
CreateStack()38 GCAdaptiveMarkingStack *GCAdaptiveMarkingStack::CreateStack()
39 {
40     auto *gc = GetGC();
41     auto allocator = gc->GetInternalAllocator();
42     // New tasks will be created with the same new_task_stack_size_limit_ and stack_size_limit_
43     return allocator->New<GCAdaptiveMarkingStack>(gc, GetNewTaskStackSizeLimit(), GetNewTaskStackSizeLimit(),
44                                                   GetTaskType(), GetTimeLimitForNewTaskCreation(), GetStackDst());
45 }
46 
CreateTask(GCAdaptiveStack<ObjectHeader * > * stack)47 GCWorkersTask GCAdaptiveMarkingStack::CreateTask(GCAdaptiveStack<ObjectHeader *> *stack)
48 {
49     return GCMarkWorkersTask(GetTaskType(), static_cast<GCAdaptiveMarkingStack *>(stack));
50 }
51 
MarkObjects(const GCAdaptiveMarkingStack::ObjectVisitor & visitor)52 GCAdaptiveMarkingStack::MarkedObjects GCAdaptiveMarkingStack::MarkObjects(
53     const GCAdaptiveMarkingStack::ObjectVisitor &visitor)
54 {
55     // We need this to avoid allocation of new stack and fragmentation
56     static constexpr size_t BUCKET_SIZE = 16;
57     auto *gc = GetGC();
58     auto allocator = gc->GetInternalAllocator();
59     MarkedObjects markedObjects;
60     PandaDeque<ObjectHeader *> *tailMarkedObjects =
61         allocator->template New<PandaDeque<ObjectHeader *>>(allocator->Adapter());
62     if (GetStackSrc()->empty()) {
63         std::swap(GetStackSrc(), GetStackDst());
64     }
65     while (!Empty()) {
66         [[maybe_unused]] auto stackSrcSize = GetStackSrc()->size();
67         for (auto *object : *GetStackSrc()) {
68             visitor(object);
69             // visitor mustn't pop from stack
70             ASSERT(stackSrcSize == GetStackSrc()->size());
71         }
72         if (LIKELY(GetStackSrc()->size() > BUCKET_SIZE)) {
73             markedObjects.push_back(GetStackSrc());
74             GetStackSrc() = allocator->template New<PandaDeque<ObjectHeader *>>(allocator->Adapter());
75         } else {
76             tailMarkedObjects->insert(tailMarkedObjects->end(), GetStackSrc()->begin(), GetStackSrc()->end());
77             GetStackSrc()->clear();
78         }
79         std::swap(GetStackSrc(), GetStackDst());
80     }
81     if (!tailMarkedObjects->empty()) {
82         markedObjects.push_back(tailMarkedObjects);
83     } else {
84         allocator->Delete(tailMarkedObjects);
85     }
86     return markedObjects;
87 }
88 }  // namespace ark::mem
89