• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 panda::mem {
22 
23 template <typename Marker>
HandleObject(GCMarkingStackType * objects_stack,const ObjectHeader * object,const Class * cls)24 void GCMarker<Marker, LANG_TYPE_STATIC, false>::HandleObject(GCMarkingStackType *objects_stack,
25                                                              const ObjectHeader *object, const Class *cls)
26 {
27     while (cls != nullptr) {
28         // Iterate over instance fields
29         uint32_t ref_num = cls->GetRefFieldsNum<false>();
30         if (ref_num > 0) {
31             uint32_t offset = cls->GetRefFieldsOffset<false>();
32             uint32_t ref_volatile_num = cls->GetVolatileRefFieldsNum<false>();
33             for (uint32_t i = 0; i < ref_num; i++, offset += ClassHelper::OBJECT_POINTER_SIZE) {
34                 auto *field_object = (i < ref_volatile_num) ? object->GetFieldObject<true>(offset)
35                                                             : object->GetFieldObject<false>(offset);
36                 ValidateObject(object, field_object);
37                 if (field_object != nullptr && AsMarker()->MarkIfNotMarked(field_object)) {
38                     objects_stack->PushToStack(object, field_object);
39                 }
40             }
41         }
42         cls = cls->GetBase();
43     }
44 }
45 template <typename Marker>
HandleClass(GCMarkingStackType * objects_stack,const Class * cls)46 void GCMarker<Marker, LANG_TYPE_STATIC, false>::HandleClass(GCMarkingStackType *objects_stack, const Class *cls)
47 {
48     // Iterate over static fields
49     uint32_t ref_num = cls->GetRefFieldsNum<true>();
50     if (ref_num > 0) {
51         uint32_t offset = cls->GetRefFieldsOffset<true>();
52         uint32_t ref_volatile_num = cls->GetVolatileRefFieldsNum<true>();
53         for (uint32_t i = 0; i < ref_num; i++, offset += ClassHelper::OBJECT_POINTER_SIZE) {
54             auto *field_object =
55                 (i < ref_volatile_num) ? cls->GetFieldObject<true>(offset) : cls->GetFieldObject<false>(offset);
56             if (field_object != nullptr && AsMarker()->MarkIfNotMarked(field_object)) {
57                 objects_stack->PushToStack(cls->GetManagedObject(), field_object);
58             }
59         }
60     }
61 }
62 
63 template <typename Marker>
HandleArrayClass(GCMarkingStackType * objects_stack,const coretypes::Array * array_object,const Class * cls)64 void GCMarker<Marker, LANG_TYPE_STATIC, false>::HandleArrayClass(GCMarkingStackType *objects_stack,
65                                                                  const coretypes::Array *array_object,
66                                                                  [[maybe_unused]] const Class *cls)
67 {
68     LOG(DEBUG, GC) << "Array object: " << GetDebugInfoAboutObject(array_object);
69     auto array_length = array_object->GetLength();
70 
71     ASSERT(cls->IsObjectArrayClass());
72 
73     LOG(DEBUG, GC) << "Iterate over: " << array_length << " elements in array";
74     for (coretypes::array_size_t i = 0; i < array_length; i++) {
75         auto *array_element = array_object->Get<ObjectHeader *>(i);
76         if (array_element == nullptr) {
77             continue;
78         }
79 #ifndef NDEBUG
80         auto array_element_cls = array_element->ClassAddr<Class>();
81         LOG_IF(array_element_cls == nullptr, DEBUG, GC)
82             << " object's class is nullptr: " << array_element << " from array: " << array_object;
83         ASSERT(array_element_cls != nullptr);
84 #endif
85         if (AsMarker()->MarkIfNotMarked(array_element)) {
86             objects_stack->PushToStack(array_object, array_element);
87         }
88     }
89 }
90 
91 template <typename Marker>
MarkInstance(GCMarkingStackType * objects_stack,const ReferenceCheckPredicateT & ref_pred,const ObjectHeader * object,const BaseClass * base_cls)92 void GCMarker<Marker, LANG_TYPE_STATIC, false>::MarkInstance(GCMarkingStackType *objects_stack,
93                                                              const ReferenceCheckPredicateT &ref_pred,
94                                                              const ObjectHeader *object, const BaseClass *base_cls)
95 {
96     ASSERT(!base_cls->IsDynamicClass());
97     auto cls = static_cast<const Class *>(base_cls);
98     if (GetGC()->IsReference(cls, object, ref_pred)) {
99         GetGC()->ProcessReference(objects_stack, cls, object, GC::EmptyReferenceProcessPredicate);
100     } else if (cls->IsObjectArrayClass()) {
101         auto *array_object = static_cast<const panda::coretypes::Array *>(object);
102         HandleArrayClass(objects_stack, array_object, cls);
103     } else if (cls->IsClassClass()) {
104         // Handle Class handles static fields only, so we need to Handle regular fields explicitly too
105         auto object_cls = panda::Class::FromClassObject(object);
106         if (object_cls->IsInitializing() || object_cls->IsInitialized()) {
107             HandleClass(objects_stack, object_cls);
108         }
109         HandleObject(objects_stack, object, cls);
110     } else if (cls->IsInstantiable()) {
111         HandleObject(objects_stack, object, cls);
112     } else {
113         if (!cls->IsPrimitive()) {
114             LOG(FATAL, GC) << "Wrong handling, missed type: " << cls->GetDescriptor();
115         }
116     }
117 }
118 
119 }  // namespace panda::mem
120 
121 #endif  // PANDA_RUNTIME_MEM_GC_STATIC_GC_MARKER_STATIC_INL_H
122