diff --git a/ecmascript/dfx/hprof/heap_root_visitor.cpp b/ecmascript/dfx/hprof/heap_root_visitor.cpp index 5119fdc914..bed4662ca6 100644 --- a/ecmascript/dfx/hprof/heap_root_visitor.cpp +++ b/ecmascript/dfx/hprof/heap_root_visitor.cpp @@ -25,7 +25,7 @@ void HeapRootVisitor::VisitHeapRoots(JSThread *thread, const RootVisitor &visito const RootBaseAndDerivedVisitor &derivedVisitor) { auto ecmaVm = GetVMInstance(thread); - ecmaVm->Iterate(visitor, rangeVisitor); + ecmaVm->Iterate(visitor, rangeVisitor, VMRootVisitType::HEAP_SNAPSHOT); thread->Iterate(visitor, rangeVisitor, derivedVisitor); // SerializeRoot from shared heap diff --git a/ecmascript/dfx/hprof/tests/heap_dump_test.cpp b/ecmascript/dfx/hprof/tests/heap_dump_test.cpp index 8863dd034d..ca4fa492f7 100644 --- a/ecmascript/dfx/hprof/tests/heap_dump_test.cpp +++ b/ecmascript/dfx/hprof/tests/heap_dump_test.cpp @@ -349,7 +349,7 @@ HWTEST_F_L0(HeapDumpTest, TestAllocationEvent) RootBaseAndDerivedVisitor derivedVisitor = [] ([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived, [[maybe_unused]] uintptr_t baseOldObject) {}; - ecmaVm_->Iterate(rootVisitor, rangeVisitor); + ecmaVm_->Iterate(rootVisitor, rangeVisitor, VMRootVisitType::HEAP_SNAPSHOT); thread_->Iterate(rootVisitor, rangeVisitor, derivedVisitor); bool result = JSNApi::Execute(ecmaVm_, abcFileName, "heapdump"); @@ -358,7 +358,7 @@ HWTEST_F_L0(HeapDumpTest, TestAllocationEvent) std::unordered_map ObjAfterExecute; ObjMap = &ObjAfterExecute; heap->IterateOverObjects(countCb); - ecmaVm_->Iterate(rootVisitor, rangeVisitor); + ecmaVm_->Iterate(rootVisitor, rangeVisitor, VMRootVisitType::HEAP_SNAPSHOT); thread_->Iterate(rootVisitor, rangeVisitor, derivedVisitor); ecmaVm_->SetHeapProfile(mockHeapProfiler.profiler_); diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index 701cd966e5..bdb8dd6d66 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -708,12 +708,12 @@ void EcmaVM::CollectGarbage(TriggerGCType gcType, GCReason reason) const heap_->CollectGarbage(gcType, reason); } -void EcmaVM::Iterate(const RootVisitor &v, const RootRangeVisitor &rv) +void EcmaVM::Iterate(const RootVisitor &v, const RootRangeVisitor &rv, VMRootVisitType type) { rv(Root::ROOT_VM, ObjectSlot(ToUintPtr(&internalNativeMethods_.front())), ObjectSlot(ToUintPtr(&internalNativeMethods_.back()) + JSTaggedValue::TaggedTypeSize())); if (!WIN_OR_MAC_OR_IOS_PLATFORM && snapshotEnv_!= nullptr) { - snapshotEnv_->Iterate(v); + snapshotEnv_->Iterate(v, type); } if (pgoProfiler_ != nullptr) { pgoProfiler_->Iterate(v); diff --git a/ecmascript/ecma_vm.h b/ecmascript/ecma_vm.h index 752ea3bc42..5d40fbec10 100644 --- a/ecmascript/ecma_vm.h +++ b/ecmascript/ecma_vm.h @@ -267,7 +267,7 @@ public: return optionalLogEnabled_; } - void Iterate(const RootVisitor &v, const RootRangeVisitor &rv); + void Iterate(const RootVisitor &v, const RootRangeVisitor &rv, VMRootVisitType type); const Heap *GetHeap() const { diff --git a/ecmascript/mem/full_gc.cpp b/ecmascript/mem/full_gc.cpp index 64728280c2..a759e7c084 100644 --- a/ecmascript/mem/full_gc.cpp +++ b/ecmascript/mem/full_gc.cpp @@ -111,7 +111,7 @@ void FullGC::Mark() { ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "FullGC::Mark"); TRACE_GC(GCStats::Scope::ScopeId::Mark, heap_->GetEcmaVM()->GetEcmaGCStats()); - heap_->GetCompressGCMarker()->MarkRoots(MAIN_THREAD_INDEX); + heap_->GetCompressGCMarker()->MarkRoots(MAIN_THREAD_INDEX, VMRootVisitType::UPDATE_ROOT); heap_->GetCompressGCMarker()->ProcessMarkStack(MAIN_THREAD_INDEX); heap_->WaitRunningTaskFinished(); // MarkJitCodeMap must be call after other mark work finish to make sure which jserror object js alive. diff --git a/ecmascript/mem/object_xray.h b/ecmascript/mem/object_xray.h index c0696173d7..7864f1c0d0 100644 --- a/ecmascript/mem/object_xray.h +++ b/ecmascript/mem/object_xray.h @@ -129,9 +129,9 @@ public: ~ObjectXRay() = default; static inline void VisitVMRoots(EcmaVM *vm, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor, - const RootBaseAndDerivedVisitor &derivedVisitor) + const RootBaseAndDerivedVisitor &derivedVisitor, VMRootVisitType type) { - vm->Iterate(visitor, rangeVisitor); + vm->Iterate(visitor, rangeVisitor, type); vm->GetAssociatedJSThread()->Iterate(visitor, rangeVisitor, derivedVisitor); } diff --git a/ecmascript/mem/parallel_evacuator.cpp b/ecmascript/mem/parallel_evacuator.cpp index 9771dd3b29..7103c280af 100644 --- a/ecmascript/mem/parallel_evacuator.cpp +++ b/ecmascript/mem/parallel_evacuator.cpp @@ -332,7 +332,8 @@ void ParallelEvacuator::UpdateRoot() } }; - ObjectXRay::VisitVMRoots(heap_->GetEcmaVM(), gcUpdateYoung, gcUpdateRangeYoung, gcUpdateDerived); + ObjectXRay::VisitVMRoots(heap_->GetEcmaVM(), gcUpdateYoung, gcUpdateRangeYoung, gcUpdateDerived, + VMRootVisitType::UPDATE_ROOT); } void ParallelEvacuator::UpdateRecordWeakReference() diff --git a/ecmascript/mem/parallel_marker.cpp b/ecmascript/mem/parallel_marker.cpp index 3d1856c441..33354e8855 100644 --- a/ecmascript/mem/parallel_marker.cpp +++ b/ecmascript/mem/parallel_marker.cpp @@ -21,7 +21,7 @@ namespace panda::ecmascript { Marker::Marker(Heap *heap) : heap_(heap), workManager_(heap->GetWorkManager()) {} -void Marker::MarkRoots(uint32_t threadId) +void Marker::MarkRoots(uint32_t threadId, VMRootVisitType type) { TRACE_GC(GCStats::Scope::ScopeId::MarkRoots, heap_->GetEcmaVM()->GetEcmaGCStats()); ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "GC::MarkRoots"); @@ -33,7 +33,7 @@ void Marker::MarkRoots(uint32_t threadId) }, [this](Root type, ObjectSlot base, ObjectSlot derived, uintptr_t baseOldObject) { this->HandleDerivedRoots(type, base, derived, baseOldObject); - }); + }, type); workManager_->PushWorkNodeToGlobal(threadId, false); } diff --git a/ecmascript/mem/parallel_marker.h b/ecmascript/mem/parallel_marker.h index ea66633613..689d71a4ff 100644 --- a/ecmascript/mem/parallel_marker.h +++ b/ecmascript/mem/parallel_marker.h @@ -37,7 +37,7 @@ public: LOG_GC(DEBUG) << "Marker::Initialize do nothing"; } - void MarkRoots(uint32_t threadId); + void MarkRoots(uint32_t threadId, VMRootVisitType type = VMRootVisitType::MARK); void ProcessNewToEden(uint32_t threadId); // for HPPGC only sticky mode void ProcessNewToEdenNoMarkStack(uint32_t threadId); void ProcessOldToNew(uint32_t threadId); // for HPPGC only semi mode diff --git a/ecmascript/mem/shared_heap/shared_gc_marker.cpp b/ecmascript/mem/shared_heap/shared_gc_marker.cpp index 679362dd96..da63723dab 100644 --- a/ecmascript/mem/shared_heap/shared_gc_marker.cpp +++ b/ecmascript/mem/shared_heap/shared_gc_marker.cpp @@ -59,7 +59,7 @@ void SharedGCMarker::MarkLocalVMRoots(uint32_t threadId, EcmaVM *localVm) }, [this](Root type, ObjectSlot base, ObjectSlot derived, uintptr_t baseOldObject) { this->HandleLocalDerivedRoots(type, base, derived, baseOldObject); - }); + }, VMRootVisitType::MARK); heap->ProcessSharedGCMarkingLocalBuffer(); } diff --git a/ecmascript/mem/stw_young_gc.cpp b/ecmascript/mem/stw_young_gc.cpp index 4e11db0de1..6494cdae28 100644 --- a/ecmascript/mem/stw_young_gc.cpp +++ b/ecmascript/mem/stw_young_gc.cpp @@ -77,7 +77,7 @@ void STWYoungGC::Mark() } else { heap_->GetSemiGCMarker()->ProcessOldToNew(0, region); heap_->GetSemiGCMarker()->ProcessSnapshotRSet(MAIN_THREAD_INDEX); - heap_->GetSemiGCMarker()->MarkRoots(MAIN_THREAD_INDEX); + heap_->GetSemiGCMarker()->MarkRoots(MAIN_THREAD_INDEX, VMRootVisitType::UPDATE_ROOT); heap_->GetSemiGCMarker()->ProcessMarkStack(MAIN_THREAD_INDEX); } heap_->WaitRunningTaskFinished(); diff --git a/ecmascript/mem/verification.cpp b/ecmascript/mem/verification.cpp index 01054438a4..029365d3e9 100644 --- a/ecmascript/mem/verification.cpp +++ b/ecmascript/mem/verification.cpp @@ -467,7 +467,7 @@ size_t Verification::VerifyRoot() const []([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived, [[maybe_unused]] uintptr_t baseOldObject) { }; - ObjectXRay::VisitVMRoots(heap_->GetEcmaVM(), visitor, rangeVisitor, derivedVisitor); + ObjectXRay::VisitVMRoots(heap_->GetEcmaVM(), visitor, rangeVisitor, derivedVisitor, VMRootVisitType::VERIFY); if (failCount > 0) { LOG_GC(ERROR) << "VerifyRoot detects deadObject count is " << failCount; } @@ -795,7 +795,7 @@ size_t SharedHeapVerification::VerifyRoot() const auto vm = thread->GetEcmaVM(); auto localHeap = const_cast(vm->GetHeap()); localHeap->GetSweeper()->EnsureAllTaskFinished(); - ObjectXRay::VisitVMRoots(vm, visitor, rangeVisitor, derivedVisitor); + ObjectXRay::VisitVMRoots(vm, visitor, rangeVisitor, derivedVisitor, VMRootVisitType::VERIFY); if (failCount > 0) { LOG_GC(ERROR) << "SharedHeap VerifyRoot detects deadObject count is " << failCount; } diff --git a/ecmascript/mem/visitor.h b/ecmascript/mem/visitor.h index cef87110d3..6454ad8fd9 100644 --- a/ecmascript/mem/visitor.h +++ b/ecmascript/mem/visitor.h @@ -38,6 +38,7 @@ enum class VisitObjectArea { }; enum class VisitType : size_t { SEMI_GC_VISIT, OLD_GC_VISIT, SNAPSHOT_VISIT, ALL_VISIT }; +enum class VMRootVisitType : uint8_t { MARK, UPDATE_ROOT, VERIFY, HEAP_SNAPSHOT }; using RootVisitor = std::function; using RootRangeVisitor = std::function; diff --git a/ecmascript/snapshot/mem/snapshot_env.cpp b/ecmascript/snapshot/mem/snapshot_env.cpp index ffe9c59c8d..dac262adc2 100644 --- a/ecmascript/snapshot/mem/snapshot_env.cpp +++ b/ecmascript/snapshot/mem/snapshot_env.cpp @@ -43,26 +43,24 @@ JSTaggedType SnapshotEnv::RelocateRootObjectAddr(uint32_t index) return value->GetRawData(); } -void SnapshotEnv::Iterate(const RootVisitor &v) +void SnapshotEnv::Iterate(const RootVisitor &v, VMRootVisitType type) { - std::vector> updatedObjPair; - for (auto &it : rootObjectMap_) { - auto objectAddr = it.first; - ObjectSlot slot(reinterpret_cast(&objectAddr)); - v(Root::ROOT_VM, slot); - // Record updated obj addr after gc - if (slot.GetTaggedType() != it.first) { - updatedObjPair.emplace_back(std::make_pair(it.first, slot.GetTaggedType())); + if (type == VMRootVisitType::UPDATE_ROOT) { + // during update root, rootObjectMap_ key need update + std::unordered_map rootObjectMap(rootObjectMap_.size()); + for (auto &it : rootObjectMap_) { + auto objectAddr = it.first; + ObjectSlot slot(reinterpret_cast(&objectAddr)); + v(Root::ROOT_VM, slot); + rootObjectMap.emplace(slot.GetTaggedType(), it.second); + } + std::swap(rootObjectMap_, rootObjectMap); + rootObjectMap.clear(); + } else { + for (auto &it : rootObjectMap_) { + ObjectSlot slot(reinterpret_cast(&it)); + v(Root::ROOT_VM, slot); } - } - // Update hashmap, erase old objAddr, emplace updated objAddr - while (!updatedObjPair.empty()) { - auto pair = updatedObjPair.back(); - ASSERT(rootObjectMap_.find(pair.first) != rootObjectMap_.end()); - uint32_t index = rootObjectMap_.find(pair.first)->second; - rootObjectMap_.erase(pair.first); - rootObjectMap_.emplace(pair.second, index); - updatedObjPair.pop_back(); } } } // namespace panda::ecmascript diff --git a/ecmascript/snapshot/mem/snapshot_env.h b/ecmascript/snapshot/mem/snapshot_env.h index 0d23242b60..a0d7886b89 100644 --- a/ecmascript/snapshot/mem/snapshot_env.h +++ b/ecmascript/snapshot/mem/snapshot_env.h @@ -35,7 +35,7 @@ public: rootObjectMap_.clear(); } - void Iterate(const RootVisitor &v); + void Iterate(const RootVisitor &v, VMRootVisitType type); void Push(JSTaggedType objectAddr, uint32_t index) {