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