/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ECMASCRIPT_MEM_PARALLEL_EVACUATOR_VISITOR_INL_H #define ECMASCRIPT_MEM_PARALLEL_EVACUATOR_VISITOR_INL_H #include "ecmascript/mem/parallel_evacuator_visitor.h" namespace panda::ecmascript { template SlotUpdateRangeVisitor::SlotUpdateRangeVisitor(ParallelEvacuator *evacuator) : evacuator_(evacuator) {} template void SlotUpdateRangeVisitor::VisitObjectRangeImpl(BaseObject *root, uintptr_t startAddr, uintptr_t endAddr, VisitObjectArea area) { JSThread *thread = evacuator_->heap_->GetJSThread(); Region *rootRegion = Region::ObjectAddressToRange(root); ObjectSlot start(startAddr); ObjectSlot end(endAddr); if (UNLIKELY(area == VisitObjectArea::IN_OBJECT)) { JSHClass *hclass = TaggedObject::Cast(root)->SynchronizedGetClass(); ASSERT(!hclass->IsAllTaggedProp()); int index = 0; LayoutInfo *layout = LayoutInfo::UncheckCast(hclass->GetLayout(thread).GetTaggedObject()); ObjectSlot realEnd = start; realEnd += layout->GetPropertiesCapacity(); end = end > realEnd ? realEnd : end; for (ObjectSlot slot = start; slot < end; slot++) { PropertyAttributes attr = layout->GetAttr(thread, index++); if (attr.IsTaggedRep()) { UpdateSlot(slot, rootRegion); } } return; } for (ObjectSlot slot = start; slot < end; slot++) { UpdateSlot(slot, rootRegion); } } template void SlotUpdateRangeVisitor::UpdateSlot(ObjectSlot slot, Region *rootRegion) { evacuator_->UpdateNewObjectSlot(slot); JSTaggedValue value(slot.GetTaggedType()); if (!value.IsHeapObject()) { return; } Region *valueRegion = Region::ObjectAddressToRange(slot.GetTaggedObject()); if (valueRegion->InYoungSpace()) { rootRegion->InsertOldToNewRSet(slot.SlotAddress()); } } template NewToOldEvacuationVisitor::NewToOldEvacuationVisitor(Heap *heap, std::unordered_set *set, ParallelEvacuator *evacuator) : pgoEnabled_(heap->GetJSThread()->IsPGOProfilerEnable()), thread_(heap->GetJSThread()), pgoProfiler_(heap->GetEcmaVM()->GetPGOProfiler()), trackSet_(set), slotUpdateRangeVisitor_(evacuator) { } template void NewToOldEvacuationVisitor::operator()(void *mem) { auto object = reinterpret_cast(mem); JSHClass *klass = object->GetClass(); ObjectXRay::VisitObjectBody(object, klass, slotUpdateRangeVisitor_); if (pgoEnabled_) { UpdateTrackInfo(object, klass); } } template void NewToOldEvacuationVisitor::UpdateTrackInfo(TaggedObject *header, JSHClass *klass) { if (klass->IsJSArray()) { auto trackInfo = JSArray::Cast(header)->GetTrackInfo(thread_); trackSet_->emplace(trackInfo.GetRawData()); } } } // namespace panda::ecmascript #endif // ECMASCRIPT_MEM_PARALLEL_EVACUATOR_VISITOR_INL_H