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_PARALLEL_EVACUATOR_VISITOR_INL_H
17 #define ECMASCRIPT_MEM_PARALLEL_EVACUATOR_VISITOR_INL_H
18
19 #include "ecmascript/mem/parallel_evacuator_visitor.h"
20
21 namespace panda::ecmascript {
22
23 template<TriggerGCType gcType>
SlotUpdateRangeVisitor(ParallelEvacuator * evacuator)24 SlotUpdateRangeVisitor<gcType>::SlotUpdateRangeVisitor(ParallelEvacuator *evacuator) : evacuator_(evacuator) {}
25
26 template<TriggerGCType gcType>
VisitObjectRangeImpl(BaseObject * root,uintptr_t startAddr,uintptr_t endAddr,VisitObjectArea area)27 void SlotUpdateRangeVisitor<gcType>::VisitObjectRangeImpl(BaseObject *root, uintptr_t startAddr, uintptr_t endAddr,
28 VisitObjectArea area)
29 {
30 JSThread *thread = evacuator_->heap_->GetJSThread();
31 Region *rootRegion = Region::ObjectAddressToRange(root);
32 ObjectSlot start(startAddr);
33 ObjectSlot end(endAddr);
34 if (UNLIKELY(area == VisitObjectArea::IN_OBJECT)) {
35 JSHClass *hclass = TaggedObject::Cast(root)->SynchronizedGetClass();
36 ASSERT(!hclass->IsAllTaggedProp());
37 int index = 0;
38 LayoutInfo *layout = LayoutInfo::UncheckCast(hclass->GetLayout(thread).GetTaggedObject());
39 ObjectSlot realEnd = start;
40 realEnd += layout->GetPropertiesCapacity();
41 end = end > realEnd ? realEnd : end;
42 for (ObjectSlot slot = start; slot < end; slot++) {
43 PropertyAttributes attr = layout->GetAttr(thread, index++);
44 if (attr.IsTaggedRep()) {
45 UpdateSlot(slot, rootRegion);
46 }
47 }
48 return;
49 }
50 for (ObjectSlot slot = start; slot < end; slot++) {
51 UpdateSlot(slot, rootRegion);
52 }
53 }
54
55 template<TriggerGCType gcType>
UpdateSlot(ObjectSlot slot,Region * rootRegion)56 void SlotUpdateRangeVisitor<gcType>::UpdateSlot(ObjectSlot slot, Region *rootRegion)
57 {
58 evacuator_->UpdateNewObjectSlot<gcType, false>(slot);
59 JSTaggedValue value(slot.GetTaggedType());
60 if (!value.IsHeapObject()) {
61 return;
62 }
63 Region *valueRegion = Region::ObjectAddressToRange(slot.GetTaggedObject());
64 if (valueRegion->InYoungSpace()) {
65 rootRegion->InsertOldToNewRSet(slot.SlotAddress());
66 }
67 }
68
69 template <TriggerGCType gcType>
NewToOldEvacuationVisitor(Heap * heap,std::unordered_set<JSTaggedType> * set,ParallelEvacuator * evacuator)70 NewToOldEvacuationVisitor<gcType>::NewToOldEvacuationVisitor(Heap *heap, std::unordered_set<JSTaggedType> *set,
71 ParallelEvacuator *evacuator)
72 : pgoEnabled_(heap->GetJSThread()->IsPGOProfilerEnable()),
73 thread_(heap->GetJSThread()),
74 pgoProfiler_(heap->GetEcmaVM()->GetPGOProfiler()),
75 trackSet_(set),
76 slotUpdateRangeVisitor_(evacuator)
77 {
78 }
79
80 template<TriggerGCType gcType>
operator()81 void NewToOldEvacuationVisitor<gcType>::operator()(void *mem)
82 {
83 auto object = reinterpret_cast<TaggedObject *>(mem);
84 JSHClass *klass = object->GetClass();
85 ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(object, klass, slotUpdateRangeVisitor_);
86 if (pgoEnabled_) {
87 UpdateTrackInfo(object, klass);
88 }
89 }
90
91 template<TriggerGCType gcType>
UpdateTrackInfo(TaggedObject * header,JSHClass * klass)92 void NewToOldEvacuationVisitor<gcType>::UpdateTrackInfo(TaggedObject *header, JSHClass *klass)
93 {
94 if (klass->IsJSArray()) {
95 auto trackInfo = JSArray::Cast(header)->GetTrackInfo(thread_);
96 trackSet_->emplace(trackInfo.GetRawData());
97 }
98 }
99 } // namespace panda::ecmascript
100 #endif // ECMASCRIPT_MEM_PARALLEL_EVACUATOR_VISITOR_INL_H
101