• 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 
16 #ifndef PANDA_RUNTIME_MEM_GC_STATIC_GC_MARKER_STATIC_INL_H
17 #define PANDA_RUNTIME_MEM_GC_STATIC_GC_MARKER_STATIC_INL_H
18 
19 #include "runtime/mem/gc/gc_marker.h"
20 
21 namespace ark::mem {
22 
23 template <typename Marker>
HandleObject(GCMarkingStackType * objectsStack,const ObjectHeader * object,const Class * cls)24 void GCMarker<Marker, LANG_TYPE_STATIC>::HandleObject(GCMarkingStackType *objectsStack, const ObjectHeader *object,
25                                                       const Class *cls)
26 {
27     while (cls != nullptr) {
28         // Iterate over instance fields
29         uint32_t refNum = cls->GetRefFieldsNum<false>();
30         if (refNum == 0) {
31             cls = cls->GetBase();
32             continue;
33         }
34         uint32_t offset = cls->GetRefFieldsOffset<false>();
35         uint32_t refVolatileNum = cls->GetVolatileRefFieldsNum<false>();
36         for (uint32_t i = 0; i < refVolatileNum; i++, offset += ClassHelper::OBJECT_POINTER_SIZE) {
37             auto *fieldObject = object->GetFieldObject<true>(offset);
38             ValidateObject(object, fieldObject);
39             if (fieldObject != nullptr && AsMarker()->MarkIfNotMarked(fieldObject)) {
40                 objectsStack->PushToStack(object, fieldObject);
41             }
42         }
43         for (uint32_t i = refVolatileNum; i < refNum; i++, offset += ClassHelper::OBJECT_POINTER_SIZE) {
44             auto *fieldObject = object->GetFieldObject<false>(offset);
45             ValidateObject(object, fieldObject);
46             if (fieldObject != nullptr && AsMarker()->MarkIfNotMarked(fieldObject)) {
47                 objectsStack->PushToStack(object, fieldObject);
48             }
49         }
50         cls = cls->GetBase();
51     }
52 }
53 template <typename Marker>
HandleClass(GCMarkingStackType * objectsStack,const Class * cls)54 void GCMarker<Marker, LANG_TYPE_STATIC>::HandleClass(GCMarkingStackType *objectsStack, const Class *cls)
55 {
56     // Iterate over static fields
57     uint32_t refNum = cls->GetRefFieldsNum<true>();
58     if (refNum > 0) {
59         uint32_t offset = cls->GetRefFieldsOffset<true>();
60         uint32_t refVolatileNum = cls->GetVolatileRefFieldsNum<true>();
61         for (uint32_t i = 0; i < refVolatileNum; i++, offset += ClassHelper::OBJECT_POINTER_SIZE) {
62             auto *fieldObject = cls->GetFieldObject<true>(offset);
63             if (fieldObject != nullptr && AsMarker()->MarkIfNotMarked(fieldObject)) {
64                 objectsStack->PushToStack(cls->GetManagedObject(), fieldObject);
65             }
66         }
67         for (uint32_t i = refVolatileNum; i < refNum; i++, offset += ClassHelper::OBJECT_POINTER_SIZE) {
68             auto *fieldObject = cls->GetFieldObject<false>(offset);
69             if (fieldObject != nullptr && AsMarker()->MarkIfNotMarked(fieldObject)) {
70                 objectsStack->PushToStack(cls->GetManagedObject(), fieldObject);
71             }
72         }
73     }
74 }
75 
76 template <typename Marker>
HandleArrayClass(GCMarkingStackType * objectsStack,const coretypes::Array * arrayObject,const Class * cls)77 void GCMarker<Marker, LANG_TYPE_STATIC>::HandleArrayClass(GCMarkingStackType *objectsStack,
78                                                           const coretypes::Array *arrayObject,
79                                                           [[maybe_unused]] const Class *cls)
80 {
81     LOG(DEBUG, GC) << "Array object: " << GetDebugInfoAboutObject(arrayObject);
82     ArraySizeT arrayLength = arrayObject->GetLength();
83 
84     ASSERT(cls->IsObjectArrayClass());
85 
86     LOG(DEBUG, GC) << "Iterate over: " << arrayLength << " elements in array";
87     for (coretypes::ArraySizeT i = 0; i < arrayLength; i++) {
88         auto *arrayElement = arrayObject->Get<ObjectHeader *>(i);
89         if (arrayElement == nullptr) {
90             continue;
91         }
92 #ifndef NDEBUG
93         auto arrayElementCls = arrayElement->ClassAddr<Class>();
94         LOG_IF(arrayElementCls == nullptr, ERROR, GC)
95             << " object's class is nullptr: " << arrayElement << " from array: " << arrayObject;
96         ASSERT(arrayElementCls != nullptr);
97 #endif
98         if (AsMarker()->MarkIfNotMarked(arrayElement)) {
99             objectsStack->PushToStack(arrayObject, arrayElement);
100         }
101     }
102 }
103 
104 template <typename Marker>
MarkInstance(GCMarkingStackType * objectsStack,const ObjectHeader * object,const BaseClass * baseCls,const ReferenceCheckPredicateT & refPred)105 void GCMarker<Marker, LANG_TYPE_STATIC>::MarkInstance(GCMarkingStackType *objectsStack, const ObjectHeader *object,
106                                                       const BaseClass *baseCls, const ReferenceCheckPredicateT &refPred)
107 {
108     ASSERT(!baseCls->IsDynamicClass());
109     auto cls = static_cast<const Class *>(baseCls);
110     if (GetGC()->IsReference(cls, object, refPred)) {
111         GetGC()->ProcessReference(objectsStack, cls, object, GC::EmptyReferenceProcessPredicate);
112     } else {
113         MarkInstance(objectsStack, object, baseCls);
114     }
115 }
116 
117 template <typename Marker>
MarkInstance(GCMarkingStackType * objectsStack,const ObjectHeader * object,const BaseClass * baseCls)118 void GCMarker<Marker, LANG_TYPE_STATIC>::MarkInstance(GCMarkingStackType *objectsStack, const ObjectHeader *object,
119                                                       const BaseClass *baseCls)
120 {
121     ASSERT(!baseCls->IsDynamicClass());
122     const auto *cls = static_cast<const Class *>(baseCls);
123     if (cls->IsObjectArrayClass()) {
124         auto *arrayObject = static_cast<const ark::coretypes::Array *>(object);
125         HandleArrayClass(objectsStack, arrayObject, cls);
126     } else if (cls->IsClassClass()) {
127         // Handle Class handles static fields only, so we need to Handle regular fields explicitly too
128         auto objectCls = ark::Class::FromClassObject(object);
129         if (objectCls->IsInitializing() || objectCls->IsInitialized()) {
130             HandleClass(objectsStack, objectCls);
131         }
132         HandleObject(objectsStack, object, cls);
133     } else if (cls->IsInstantiable()) {
134         HandleObject(objectsStack, object, cls);
135     } else {
136         if (!cls->IsPrimitive()) {
137             LOG(FATAL, GC) << "Wrong handling, missed type: " << cls->GetDescriptor();
138         }
139     }
140 }
141 
142 }  // namespace ark::mem
143 
144 #endif  // PANDA_RUNTIME_MEM_GC_STATIC_GC_MARKER_STATIC_INL_H
145