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 #ifndef ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_VISITOR_INL_H
17 #define ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_VISITOR_INL_H
18
19 #include "ecmascript/mem/shared_heap/shared_gc_visitor.h"
20
21 #include "ecmascript/mem/region-inl.h"
22 #include "ecmascript/mem/work_manager-inl.h"
23
24 namespace panda::ecmascript {
SharedGCMarkRootVisitor(SharedGCWorkManager * sWorkManager,uint32_t threadId)25 SharedGCMarkRootVisitor::SharedGCMarkRootVisitor(SharedGCWorkManager *sWorkManager, uint32_t threadId)
26 : sWorkManager_(sWorkManager), threadId_(threadId) {}
27
VisitRoot(Root type,ObjectSlot slot)28 void SharedGCMarkRootVisitor::VisitRoot([[maybe_unused]] Root type, ObjectSlot slot)
29 {
30 JSTaggedValue value(slot.GetTaggedType());
31 if (value.IsHeapObject()) {
32 ASSERT(!value.IsWeak());
33 MarkObject(value.GetTaggedObject());
34 }
35 }
36
VisitRangeRoot(Root type,ObjectSlot start,ObjectSlot end)37 void SharedGCMarkRootVisitor::VisitRangeRoot([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end)
38 {
39 for (ObjectSlot slot = start; slot < end; slot++) {
40 JSTaggedValue value(slot.GetTaggedType());
41 if (value.IsHeapObject()) {
42 ASSERT(!value.IsWeak());
43 MarkObject(value.GetTaggedObject());
44 }
45 }
46 }
47
VisitBaseAndDerivedRoot(Root type,ObjectSlot base,ObjectSlot derived,uintptr_t baseOldObject)48 void SharedGCMarkRootVisitor::VisitBaseAndDerivedRoot([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base,
49 [[maybe_unused]] ObjectSlot derived,
50 [[maybe_unused]] uintptr_t baseOldObject)
51 {
52 // It is only used to update the derived value. The mark of SharedGC does not need to update slot
53 }
54
MarkObject(TaggedObject * object)55 void SharedGCMarkRootVisitor::MarkObject(TaggedObject *object)
56 {
57 Region *objectRegion = Region::ObjectAddressToRange(object);
58 if (!objectRegion->InSharedSweepableSpace()) {
59 return;
60 }
61 if (objectRegion->AtomicMark(object)) {
62 sWorkManager_->Push(threadId_, object);
63 }
64 }
65
SharedGCMarkObjectVisitor(SharedGCWorkManager * sWorkManager,uint32_t threadId)66 SharedGCMarkObjectVisitor::SharedGCMarkObjectVisitor(SharedGCWorkManager *sWorkManager, uint32_t threadId)
67 : sWorkManager_(sWorkManager), threadId_(threadId) {}
68
VisitObjectRangeImpl(TaggedObject * root,ObjectSlot start,ObjectSlot end,VisitObjectArea area)69 void SharedGCMarkObjectVisitor::VisitObjectRangeImpl(TaggedObject *root, ObjectSlot start, ObjectSlot end,
70 VisitObjectArea area)
71 {
72 Region *rootRegion = Region::ObjectAddressToRange(root);
73 if (UNLIKELY(area == VisitObjectArea::IN_OBJECT)) {
74 JSHClass *hclass = root->SynchronizedGetClass();
75 ASSERT(!hclass->IsAllTaggedProp());
76 int index = 0;
77 LayoutInfo *layout = LayoutInfo::UncheckCast(hclass->GetLayout().GetTaggedObject());
78 ObjectSlot realEnd = start;
79 realEnd += layout->GetPropertiesCapacity();
80 end = end > realEnd ? realEnd : end;
81 for (ObjectSlot slot = start; slot < end; slot++) {
82 PropertyAttributes attr = layout->GetAttr(index++);
83 if (attr.IsTaggedRep()) {
84 HandleSlot(slot, rootRegion);
85 }
86 }
87 return;
88 }
89 for (ObjectSlot slot = start; slot < end; slot++) {
90 HandleSlot(slot, rootRegion);
91 }
92 }
93
VisitObjectHClassImpl(TaggedObject * hclass)94 void SharedGCMarkObjectVisitor::VisitObjectHClassImpl(TaggedObject *hclass)
95 {
96 ASSERT(hclass->GetClass()->IsHClass());
97 Region *hclassRegion = Region::ObjectAddressToRange(hclass);
98 if (hclassRegion->InSharedSweepableSpace()) {
99 ASSERT(hclassRegion->InSharedNonMovableSpace());
100 MarkAndPush(hclass, hclassRegion);
101 }
102 }
103
HandleSlot(ObjectSlot slot,Region * rootRegion)104 void SharedGCMarkObjectVisitor::HandleSlot(ObjectSlot slot, Region *rootRegion)
105 {
106 JSTaggedValue value(slot.GetTaggedType());
107 if (!value.IsHeapObject()) {
108 return;
109 }
110
111 Region *objectRegion = Region::ObjectAddressToRange(value.GetRawHeapObject());
112 ASSERT(objectRegion->InSharedHeap());
113
114 if (!objectRegion->InSharedSweepableSpace()) {
115 return;
116 }
117
118 if (!value.IsWeakForHeapObject()) {
119 TaggedObject *object = value.GetTaggedObject();
120 MarkAndPush(object, objectRegion);
121 if (objectRegion->InSCollectSet()) {
122 rootRegion->AtomicInsertCrossRegionRSet(slot.SlotAddress());
123 }
124 } else {
125 RecordWeakReference(reinterpret_cast<JSTaggedType*>(slot.SlotAddress()));
126 }
127 }
128
MarkAndPush(TaggedObject * object,Region * objectRegion)129 void SharedGCMarkObjectVisitor::MarkAndPush(TaggedObject *object, Region *objectRegion)
130 {
131 if (objectRegion->AtomicMark(object)) {
132 sWorkManager_->Push(threadId_, object);
133 }
134 }
135
RecordWeakReference(JSTaggedType * weak)136 void SharedGCMarkObjectVisitor::RecordWeakReference(JSTaggedType *weak)
137 {
138 sWorkManager_->PushWeakReference(threadId_, weak);
139 }
140
141 } // namespace panda::ecmascript
142 #endif // ECMASCRIPT_MEM_SHARED_HEAP_SHARED_GC_VISITOR_INL_H
143