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