14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/mem/verification.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/mem/shared_heap/shared_concurrent_sweeper.h"
194514f5e3Sopenharmony_ci#include "ecmascript/runtime.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_cinamespace panda::ecmascript {
224514f5e3Sopenharmony_civoid LogErrorForObjSlot(const BaseHeap *heap, const char *headerInfo, TaggedObject *obj, ObjectSlot slot,
234514f5e3Sopenharmony_ci                        TaggedObject *value)
244514f5e3Sopenharmony_ci{ // LCOV_EXCL_START
254514f5e3Sopenharmony_ci    TaggedObject *slotValue = slot.GetTaggedObject();
264514f5e3Sopenharmony_ci    Region *region = Region::ObjectAddressToRange(obj);
274514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
284514f5e3Sopenharmony_ci    Region *slotRegion = Region::ObjectAddressToRange(slotValue);
294514f5e3Sopenharmony_ci    LOG_GC(FATAL) << headerInfo
304514f5e3Sopenharmony_ci                  << ": gctype=" << heap->GetGCType()
314514f5e3Sopenharmony_ci                  << ", obj address=" << obj
324514f5e3Sopenharmony_ci                  << ", obj region=" << region
334514f5e3Sopenharmony_ci                  << ", obj space type=" << region->GetSpaceTypeName()
344514f5e3Sopenharmony_ci                  << ", obj type=" << JSHClass::DumpJSType(obj->GetClass()->GetObjectType())
354514f5e3Sopenharmony_ci                  << ", slot address=" << reinterpret_cast<void*>(slot.SlotAddress())
364514f5e3Sopenharmony_ci                  << ", slot value=" << slotValue
374514f5e3Sopenharmony_ci                  << ", slot value region=" << slotRegion
384514f5e3Sopenharmony_ci                  << ", slot value space type=" << slotRegion->GetSpaceTypeName()
394514f5e3Sopenharmony_ci                  << ", slot value type=" << JSHClass::DumpJSType(slotValue->GetClass()->GetObjectType())
404514f5e3Sopenharmony_ci                  << ", value address=" << value
414514f5e3Sopenharmony_ci                  << ", value region=" << valueRegion
424514f5e3Sopenharmony_ci                  << ", value space type=" << valueRegion->GetSpaceTypeName()
434514f5e3Sopenharmony_ci                  << ", value type=" << JSHClass::DumpJSType(value->GetClass()->GetObjectType())
444514f5e3Sopenharmony_ci                  << ", obj mark bit=" << region->Test(obj)
454514f5e3Sopenharmony_ci                  << ", obj slot oldToNew bit=" << region->TestOldToNew(slot.SlotAddress())
464514f5e3Sopenharmony_ci                  << ", obj slot newToEden bit=" << region->TestNewToEden(slot.SlotAddress())
474514f5e3Sopenharmony_ci                  << ", obj slot value mark bit=" << slotRegion->Test(slotValue)
484514f5e3Sopenharmony_ci                  << ", value mark bit=" << valueRegion->Test(value);
494514f5e3Sopenharmony_ci    UNREACHABLE();
504514f5e3Sopenharmony_ci}
514514f5e3Sopenharmony_ci
524514f5e3Sopenharmony_civoid LogErrorForObj(const BaseHeap *heap, const char *headerInfo, TaggedObject *obj)
534514f5e3Sopenharmony_ci{
544514f5e3Sopenharmony_ci    Region *region = Region::ObjectAddressToRange(obj);
554514f5e3Sopenharmony_ci    LOG_GC(FATAL) << headerInfo
564514f5e3Sopenharmony_ci                  << ": gctype=" << heap->GetGCType()
574514f5e3Sopenharmony_ci                  << ", obj address=" << obj
584514f5e3Sopenharmony_ci                  << ", obj value=" << ObjectSlot(ToUintPtr(obj)).GetTaggedObject()
594514f5e3Sopenharmony_ci                  << ", obj region=" << region
604514f5e3Sopenharmony_ci                  << ", obj space type=" << region->GetSpaceTypeName()
614514f5e3Sopenharmony_ci                  << ", obj type=" << JSHClass::DumpJSType(obj->GetClass()->GetObjectType())
624514f5e3Sopenharmony_ci                  << ", obj mark bit=" << region->Test(obj);
634514f5e3Sopenharmony_ci    UNREACHABLE();
644514f5e3Sopenharmony_ci} // LCOV_EXCL_STOP
654514f5e3Sopenharmony_ci
664514f5e3Sopenharmony_ci// Only used for verify InactiveSemiSpace
674514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyInactiveSemiSpaceMarkedObject(const BaseHeap *heap, void *addr)
684514f5e3Sopenharmony_ci{
694514f5e3Sopenharmony_ci    TaggedObject *object = reinterpret_cast<TaggedObject*>(addr);
704514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
714514f5e3Sopenharmony_ci    if (!objectRegion->InInactiveSemiSpace()) { // LCOV_EXCL_START
724514f5e3Sopenharmony_ci        LogErrorForObj(heap, "Verify InactiveSemiSpaceMarkedObject: Object is not in InactiveSemiSpace.", object);
734514f5e3Sopenharmony_ci    } else {
744514f5e3Sopenharmony_ci        MarkWord word(object);
754514f5e3Sopenharmony_ci        if (!word.IsForwardingAddress()) {
764514f5e3Sopenharmony_ci            LogErrorForObj(heap, "Verify InactiveSemiSpaceMarkedObject: not forwarding address.", object);
774514f5e3Sopenharmony_ci        } else {
784514f5e3Sopenharmony_ci            ObjectSlot slot(ToUintPtr(object));
794514f5e3Sopenharmony_ci            TaggedObject *value = word.ToForwardingAddress();
804514f5e3Sopenharmony_ci            Region *valueRegion = Region::ObjectAddressToRange(value);
814514f5e3Sopenharmony_ci            if (valueRegion->InInactiveSemiSpace()) {
824514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap, "Verify InactiveSemiSpaceMarkedObject: forwarding address, "
834514f5e3Sopenharmony_ci                    "but InactiveSemiSpace(FromSpace) Object.", object, slot, value);
844514f5e3Sopenharmony_ci            }
854514f5e3Sopenharmony_ci        }
864514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
874514f5e3Sopenharmony_ci}
884514f5e3Sopenharmony_ci
894514f5e3Sopenharmony_ci// Verify the object body
904514f5e3Sopenharmony_civoid VerifyObjectVisitor::VisitAllObjects(TaggedObject *obj)
914514f5e3Sopenharmony_ci{
924514f5e3Sopenharmony_ci    auto jsHclass = obj->GetClass();
934514f5e3Sopenharmony_ci    ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(
944514f5e3Sopenharmony_ci        obj, jsHclass, [this](TaggedObject *root, ObjectSlot start, ObjectSlot end,
954514f5e3Sopenharmony_ci                              VisitObjectArea area) {
964514f5e3Sopenharmony_ci            if (area == VisitObjectArea::IN_OBJECT) {
974514f5e3Sopenharmony_ci                auto hclass = root->GetClass();
984514f5e3Sopenharmony_ci                ASSERT(!hclass->IsAllTaggedProp());
994514f5e3Sopenharmony_ci                int index = 0;
1004514f5e3Sopenharmony_ci                for (ObjectSlot slot = start; slot < end; slot++) {
1014514f5e3Sopenharmony_ci                    auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
1024514f5e3Sopenharmony_ci                    auto attr = layout->GetAttr(index++);
1034514f5e3Sopenharmony_ci                    if (attr.IsTaggedRep()) {
1044514f5e3Sopenharmony_ci                        VerifyObjectSlotLegal(slot, root);
1054514f5e3Sopenharmony_ci                    }
1064514f5e3Sopenharmony_ci                }
1074514f5e3Sopenharmony_ci                return;
1084514f5e3Sopenharmony_ci            }
1094514f5e3Sopenharmony_ci            for (ObjectSlot slot = start; slot < end; slot++) {
1104514f5e3Sopenharmony_ci                VerifyObjectSlotLegal(slot, root);
1114514f5e3Sopenharmony_ci            }
1124514f5e3Sopenharmony_ci        });
1134514f5e3Sopenharmony_ci}
1144514f5e3Sopenharmony_ci
1154514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyObjectSlotLegal(ObjectSlot slot, TaggedObject *object) const
1164514f5e3Sopenharmony_ci{
1174514f5e3Sopenharmony_ci    JSTaggedValue value(slot.GetTaggedType());
1184514f5e3Sopenharmony_ci    if (value.IsWeak()) { // LCOV_EXCL_START
1194514f5e3Sopenharmony_ci        if (ToUintPtr(value.GetTaggedWeakRef()) < INVALID_THRESHOLD) {
1204514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Heap verify detected an invalid value.",
1214514f5e3Sopenharmony_ci                object, slot, value.GetTaggedWeakRef());
1224514f5e3Sopenharmony_ci        }
1234514f5e3Sopenharmony_ci        if (!heap_->IsAlive(value.GetTaggedWeakRef())) {
1244514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Heap verify detected a dead weak object.",
1254514f5e3Sopenharmony_ci                object, slot, value.GetTaggedWeakRef());
1264514f5e3Sopenharmony_ci            ++(*failCount_);
1274514f5e3Sopenharmony_ci        }
1284514f5e3Sopenharmony_ci    } else if (value.IsHeapObject()) {
1294514f5e3Sopenharmony_ci        VerifyHeapObjectSlotLegal(slot, value, object);
1304514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
1314514f5e3Sopenharmony_ci}
1324514f5e3Sopenharmony_ci
1334514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyHeapObjectSlotLegal(ObjectSlot slot,
1344514f5e3Sopenharmony_ci                                                    JSTaggedValue slotValue,
1354514f5e3Sopenharmony_ci                                                    TaggedObject *object) const
1364514f5e3Sopenharmony_ci{
1374514f5e3Sopenharmony_ci    ASSERT(slotValue.IsHeapObject());
1384514f5e3Sopenharmony_ci    if (ToUintPtr(slotValue.GetTaggedObject()) < INVALID_THRESHOLD) { // LCOV_EXCL_START
1394514f5e3Sopenharmony_ci        LogErrorForObjSlot(heap_, "Heap verify detected an invalid value.",
1404514f5e3Sopenharmony_ci            object, slot, slotValue.GetTaggedObject());
1414514f5e3Sopenharmony_ci    }
1424514f5e3Sopenharmony_ci    if (!heap_->IsAlive(slotValue.GetTaggedObject())) {
1434514f5e3Sopenharmony_ci        LogErrorForObjSlot(heap_, "Heap verify detected a dead object.",
1444514f5e3Sopenharmony_ci            object, slot, slotValue.GetTaggedObject());
1454514f5e3Sopenharmony_ci        ++(*failCount_);
1464514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
1474514f5e3Sopenharmony_ci    switch (verifyKind_) {
1484514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_PRE_GC:
1494514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_POST_GC:
1504514f5e3Sopenharmony_ci            break;
1514514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_MARK_EDEN:
1524514f5e3Sopenharmony_ci            VerifyMarkEden(object, slot, slotValue.GetTaggedObject());
1534514f5e3Sopenharmony_ci            break;
1544514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_EVACUATE_EDEN:
1554514f5e3Sopenharmony_ci            VerifyEvacuateEden(object, slot, slotValue.GetTaggedObject());
1564514f5e3Sopenharmony_ci            break;
1574514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_MARK_YOUNG:
1584514f5e3Sopenharmony_ci            VerifyMarkYoung(object, slot, slotValue.GetTaggedObject());
1594514f5e3Sopenharmony_ci            break;
1604514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_EVACUATE_YOUNG:
1614514f5e3Sopenharmony_ci            VerifyEvacuateYoung(object, slot, slotValue.GetTaggedObject());
1624514f5e3Sopenharmony_ci            break;
1634514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_MARK_FULL:
1644514f5e3Sopenharmony_ci            VerifyMarkFull(object, slot, slotValue.GetTaggedObject());
1654514f5e3Sopenharmony_ci            break;
1664514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_EVACUATE_OLD:
1674514f5e3Sopenharmony_ci            VerifyEvacuateOld(object, slot, slotValue.GetTaggedObject());
1684514f5e3Sopenharmony_ci            break;
1694514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_EVACUATE_FULL:
1704514f5e3Sopenharmony_ci            VerifyEvacuateFull(object, slot, slotValue.GetTaggedObject());
1714514f5e3Sopenharmony_ci            break;
1724514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_SHARED_RSET_POST_FULL_GC:
1734514f5e3Sopenharmony_ci            VerifySharedRSetPostFullGC(object, slot, slotValue.GetTaggedObject());
1744514f5e3Sopenharmony_ci            break;
1754514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_PRE_SHARED_GC:
1764514f5e3Sopenharmony_ci        case VerifyKind::VERIFY_POST_SHARED_GC:
1774514f5e3Sopenharmony_ci            VerifySharedObjectReference(object, slot, slotValue.GetTaggedObject());
1784514f5e3Sopenharmony_ci            break;
1794514f5e3Sopenharmony_ci        default: // LCOV_EXCL_START
1804514f5e3Sopenharmony_ci            LOG_GC(FATAL) << "unknown verify kind:" << static_cast<size_t>(verifyKind_);
1814514f5e3Sopenharmony_ci            UNREACHABLE(); // LCOV_EXCL_STOP
1824514f5e3Sopenharmony_ci    }
1834514f5e3Sopenharmony_ci}
1844514f5e3Sopenharmony_ci
1854514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyMarkEden(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
1864514f5e3Sopenharmony_ci{
1874514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
1884514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
1894514f5e3Sopenharmony_ci    JSTaggedValue value1(object);
1904514f5e3Sopenharmony_ci    JSTaggedValue value2(value);
1914514f5e3Sopenharmony_ci    if (objectRegion->InGeneralOldSpace() && valueRegion->InEdenSpace()) { // LCOV_EXCL_START
1924514f5e3Sopenharmony_ci        if (!objectRegion->TestOldToNew(slot.SlotAddress())) {
1934514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkEden: Old object, slot miss old_to_new bit.", object, slot, value);
1944514f5e3Sopenharmony_ci        } else if (!valueRegion->Test(value)) {
1954514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkEden: Old object, slot has old_to_new bit, miss gc_mark bit.",
1964514f5e3Sopenharmony_ci                object, slot, value);
1974514f5e3Sopenharmony_ci        }
1984514f5e3Sopenharmony_ci    }
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci    if (objectRegion->InYoungSpace() && valueRegion->InEdenSpace()) {
2014514f5e3Sopenharmony_ci        if (!objectRegion->TestNewToEden(slot.SlotAddress())) {
2024514f5e3Sopenharmony_ci            value1.D();
2034514f5e3Sopenharmony_ci            value2.D();
2044514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkEden: Young object, slot miss new_to_eden bit.", object, slot, value);
2054514f5e3Sopenharmony_ci        } else if (!valueRegion->Test(value)) {
2064514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkEden: Young object, slot has new_to_eden bit, miss gc_mark bit.",
2074514f5e3Sopenharmony_ci                object, slot, value);
2084514f5e3Sopenharmony_ci        }
2094514f5e3Sopenharmony_ci    }
2104514f5e3Sopenharmony_ci
2114514f5e3Sopenharmony_ci    if (objectRegion->Test(object)) {
2124514f5e3Sopenharmony_ci        if (!objectRegion->InEdenSpace() && !objectRegion->InAppSpawnSpace()
2134514f5e3Sopenharmony_ci                && !objectRegion->InReadOnlySpace()) {
2144514f5e3Sopenharmony_ci            LogErrorForObj(heap_, "Verify MarkYoung: Marked object, NOT in Eden Space", object);
2154514f5e3Sopenharmony_ci        }
2164514f5e3Sopenharmony_ci        if (valueRegion->InEdenSpace() && !valueRegion->Test(value)) {
2174514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkEden: Marked object, slot in EdenSpace, miss gc_mark bit.",
2184514f5e3Sopenharmony_ci                object, slot, value);
2194514f5e3Sopenharmony_ci        }
2204514f5e3Sopenharmony_ci        if (valueRegion->Test(value) && !(valueRegion->InEdenSpace() || valueRegion->InAppSpawnSpace()
2214514f5e3Sopenharmony_ci                || valueRegion->InReadOnlySpace() || valueRegion->InSharedHeap())) {
2224514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkEden: Marked object, slot marked, but NOT in Eden Space.",
2234514f5e3Sopenharmony_ci                object, slot, value);
2244514f5e3Sopenharmony_ci        }
2254514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
2264514f5e3Sopenharmony_ci}
2274514f5e3Sopenharmony_ci
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyMarkYoung(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
2304514f5e3Sopenharmony_ci{
2314514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
2324514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
2334514f5e3Sopenharmony_ci    ASSERT(!objectRegion->InSharedHeap());
2344514f5e3Sopenharmony_ci    if (objectRegion->InGeneralOldSpace() && valueRegion->InGeneralNewSpace()) { // LCOV_EXCL_START
2354514f5e3Sopenharmony_ci        if (!objectRegion->TestOldToNew(slot.SlotAddress())) {
2364514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkYoung: Old object, slot miss old_to_new bit.", object, slot, value);
2374514f5e3Sopenharmony_ci        } else if (!valueRegion->Test(value)) {
2384514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkYoung: Old object, slot has old_to_new bit, miss gc_mark bit.",
2394514f5e3Sopenharmony_ci                object, slot, value);
2404514f5e3Sopenharmony_ci        }
2414514f5e3Sopenharmony_ci    }
2424514f5e3Sopenharmony_ci    if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
2434514f5e3Sopenharmony_ci        if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
2444514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkYoung: Local object, slot local_to_share bit = 0, "
2454514f5e3Sopenharmony_ci                "but SharedHeap object.", object, slot, value);
2464514f5e3Sopenharmony_ci        }
2474514f5e3Sopenharmony_ci    }
2484514f5e3Sopenharmony_ci    if (objectRegion->Test(object)) {
2494514f5e3Sopenharmony_ci        if (!objectRegion->InGeneralNewSpace() && !objectRegion->InAppSpawnSpace() &&
2504514f5e3Sopenharmony_ci            !objectRegion->InReadOnlySpace()) {
2514514f5e3Sopenharmony_ci            LogErrorForObj(heap_, "Verify MarkYoung: Marked object, NOT in Young/AppSpawn/ReadOnly Space", object);
2524514f5e3Sopenharmony_ci        }
2534514f5e3Sopenharmony_ci        if (valueRegion->InGeneralNewSpace() && !valueRegion->Test(value)) {
2544514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkYoung: Marked object, slot in YoungSpace, miss gc_mark bit.",
2554514f5e3Sopenharmony_ci                object, slot, value);
2564514f5e3Sopenharmony_ci        }
2574514f5e3Sopenharmony_ci        if (valueRegion->Test(value) &&
2584514f5e3Sopenharmony_ci            !(valueRegion->InYoungSpace() || valueRegion->InAppSpawnSpace() || valueRegion->InReadOnlySpace() ||
2594514f5e3Sopenharmony_ci              valueRegion->InSharedHeap() || valueRegion->InEdenSpace())) {
2604514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkYoung: Marked object, slot marked, but NOT in "
2614514f5e3Sopenharmony_ci                "Young/AppSpawn/ReadOnly Space.", object, slot, value);
2624514f5e3Sopenharmony_ci        }
2634514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
2644514f5e3Sopenharmony_ci}
2654514f5e3Sopenharmony_ci
2664514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyEvacuateEden(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
2674514f5e3Sopenharmony_ci{
2684514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
2694514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
2704514f5e3Sopenharmony_ci    if (objectRegion->InGeneralOldSpace()) { // LCOV_EXCL_START
2714514f5e3Sopenharmony_ci        if (objectRegion->TestOldToNew(slot.SlotAddress())) {
2724514f5e3Sopenharmony_ci            if (!valueRegion->InActiveSemiSpace()) {
2734514f5e3Sopenharmony_ci                if (valueRegion->InEdenSpace()) {
2744514f5e3Sopenharmony_ci                    LogErrorForObjSlot(heap_, "Verify EvacuateEden: Old object, slot old_to_new bit = 1, "
2754514f5e3Sopenharmony_ci                        "but in EdenSpace object.", object, slot, value);
2764514f5e3Sopenharmony_ci                }
2774514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateEden: Old object, slot old_to_new bit = 1, "
2784514f5e3Sopenharmony_ci                    "but NOT ActiveSpace(ToSpace) object.", object, slot, value);
2794514f5e3Sopenharmony_ci            }
2804514f5e3Sopenharmony_ci        } else {
2814514f5e3Sopenharmony_ci            if (valueRegion->InGeneralNewSpace()) {
2824514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateEden: Old object, slot old_to_new bit = 0, "
2834514f5e3Sopenharmony_ci                    "but YoungSpace object.", object, slot, value);
2844514f5e3Sopenharmony_ci            }
2854514f5e3Sopenharmony_ci        }
2864514f5e3Sopenharmony_ci    }
2874514f5e3Sopenharmony_ci    if (objectRegion->InYoungSpace()) {
2884514f5e3Sopenharmony_ci        if (objectRegion->TestNewToEden(slot.SlotAddress())) {
2894514f5e3Sopenharmony_ci            if (!valueRegion->InEdenSpace()) {
2904514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateEden: Young object, slot young_to_eden bit = 1, "
2914514f5e3Sopenharmony_ci                    "but NOT Eden object.", object, slot, value);
2924514f5e3Sopenharmony_ci            } else {
2934514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateEden: Young object, slot young_to_eden bit = 1, "
2944514f5e3Sopenharmony_ci                    "but Eden object.", object, slot, value);
2954514f5e3Sopenharmony_ci            }
2964514f5e3Sopenharmony_ci        } else {
2974514f5e3Sopenharmony_ci            if (valueRegion->InEdenSpace()) {
2984514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateEden: Young object, slot young_to_eden bit = 0, "
2994514f5e3Sopenharmony_ci                    "but Eden object.", object, slot, value);
3004514f5e3Sopenharmony_ci            }
3014514f5e3Sopenharmony_ci        }
3024514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
3034514f5e3Sopenharmony_ci}
3044514f5e3Sopenharmony_ci
3054514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyEvacuateYoung(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
3064514f5e3Sopenharmony_ci{
3074514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
3084514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
3094514f5e3Sopenharmony_ci
3104514f5e3Sopenharmony_ci    if (objectRegion->InGeneralOldSpace()) { // LCOV_EXCL_START
3114514f5e3Sopenharmony_ci        if (objectRegion->TestOldToNew(slot.SlotAddress())) {
3124514f5e3Sopenharmony_ci            if (!valueRegion->InActiveSemiSpace()) {
3134514f5e3Sopenharmony_ci                if (valueRegion->InEdenSpace()) {
3144514f5e3Sopenharmony_ci                    LogErrorForObjSlot(heap_, "Verify EvacuateYoung: Old object, slot old_to_new bit = 1, "
3154514f5e3Sopenharmony_ci                        "but in EdenSpace object.", object, slot, value);
3164514f5e3Sopenharmony_ci                }
3174514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateYoung: Old object, slot old_to_new bit = 1, "
3184514f5e3Sopenharmony_ci                    "but NOT ActiveSpace(ToSpace) object.", object, slot, value);
3194514f5e3Sopenharmony_ci            }
3204514f5e3Sopenharmony_ci        } else {
3214514f5e3Sopenharmony_ci            if (valueRegion->InGeneralNewSpace()) {
3224514f5e3Sopenharmony_ci                LogErrorForObjSlot(heap_, "Verify EvacuateYoung: Old object, slot old_to_new bit = 0, "
3234514f5e3Sopenharmony_ci                    "but YoungSpace object.", object, slot, value);
3244514f5e3Sopenharmony_ci            }
3254514f5e3Sopenharmony_ci        }
3264514f5e3Sopenharmony_ci    }
3274514f5e3Sopenharmony_ci    if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
3284514f5e3Sopenharmony_ci        if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
3294514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify EvacuateYoung: Local object, slot local_to_share bit = 0, "
3304514f5e3Sopenharmony_ci                "but SharedHeap object.", object, slot, value);
3314514f5e3Sopenharmony_ci        }
3324514f5e3Sopenharmony_ci    }
3334514f5e3Sopenharmony_ci    if (objectRegion->InActiveSemiSpace()) {
3344514f5e3Sopenharmony_ci        if (valueRegion->InInactiveSemiSpace()) {
3354514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify EvacuateYoung: ActiveSpace object, slot in InactiveSpace(FromSpace).",
3364514f5e3Sopenharmony_ci                object, slot, value);
3374514f5e3Sopenharmony_ci        } else if (valueRegion->InEdenSpace()) {
3384514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify EvacuateYoung: ActiveSpace object, slot in EdenSpace.",
3394514f5e3Sopenharmony_ci                object, slot, value);
3404514f5e3Sopenharmony_ci        }
3414514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
3424514f5e3Sopenharmony_ci}
3434514f5e3Sopenharmony_ci
3444514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyMarkFull(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
3454514f5e3Sopenharmony_ci{
3464514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
3474514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
3484514f5e3Sopenharmony_ci    if (objectRegion->InGeneralOldSpace() && valueRegion->InGeneralNewSpace()) { // LCOV_EXCL_START
3494514f5e3Sopenharmony_ci        if (!objectRegion->TestOldToNew(slot.SlotAddress())) {
3504514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkFull: Old object, slot miss old_to_new bit.", object, slot, value);
3514514f5e3Sopenharmony_ci        }
3524514f5e3Sopenharmony_ci    }
3534514f5e3Sopenharmony_ci    if (objectRegion->Test(object)) {
3544514f5e3Sopenharmony_ci        if (!valueRegion->InSharedHeap() && !valueRegion->Test(value)) {
3554514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify MarkFull: Marked object, slot miss gc_mark bit.", object, slot, value);
3564514f5e3Sopenharmony_ci        }
3574514f5e3Sopenharmony_ci    }
3584514f5e3Sopenharmony_ci    if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
3594514f5e3Sopenharmony_ci        if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
3604514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify VerifyMarkFull: Local object, slot local_to_share bit = 0, "
3614514f5e3Sopenharmony_ci                "but SharedHeap object.", object, slot, value);
3624514f5e3Sopenharmony_ci        }
3634514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
3644514f5e3Sopenharmony_ci}
3654514f5e3Sopenharmony_ci
3664514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyEvacuateOld([[maybe_unused]]TaggedObject *root,
3674514f5e3Sopenharmony_ci                                            [[maybe_unused]]ObjectSlot slot,
3684514f5e3Sopenharmony_ci                                            [[maybe_unused]]TaggedObject *value) const
3694514f5e3Sopenharmony_ci{
3704514f5e3Sopenharmony_ci    VerifyEvacuateYoung(root, slot, value);
3714514f5e3Sopenharmony_ci}
3724514f5e3Sopenharmony_ci
3734514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifyEvacuateFull([[maybe_unused]]TaggedObject *root,
3744514f5e3Sopenharmony_ci                                             [[maybe_unused]]ObjectSlot slot,
3754514f5e3Sopenharmony_ci                                             [[maybe_unused]]TaggedObject *value) const
3764514f5e3Sopenharmony_ci{
3774514f5e3Sopenharmony_ci    VerifyEvacuateYoung(root, slot, value);
3784514f5e3Sopenharmony_ci}
3794514f5e3Sopenharmony_ci
3804514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifySharedObjectReference(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
3814514f5e3Sopenharmony_ci{
3824514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
3834514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
3844514f5e3Sopenharmony_ci    if (objectRegion->InSharedHeap()) { // LCOV_EXCL_START
3854514f5e3Sopenharmony_ci        if (!valueRegion->InSharedHeap()) {
3864514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify SharedObjectReference: Shared object references a local object",
3874514f5e3Sopenharmony_ci                object, slot, value);
3884514f5e3Sopenharmony_ci        }
3894514f5e3Sopenharmony_ci    } else if (valueRegion->InSharedSweepableSpace()) {
3904514f5e3Sopenharmony_ci        if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
3914514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify SharedObjectReference: Local object, slot local_to_share bit = 0, "
3924514f5e3Sopenharmony_ci                "but SharedHeap object.", object, slot, value);
3934514f5e3Sopenharmony_ci        }
3944514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
3954514f5e3Sopenharmony_ci}
3964514f5e3Sopenharmony_ci
3974514f5e3Sopenharmony_civoid VerifyObjectVisitor::VerifySharedRSetPostFullGC(TaggedObject *object, ObjectSlot slot, TaggedObject *value) const
3984514f5e3Sopenharmony_ci{
3994514f5e3Sopenharmony_ci    Region *objectRegion = Region::ObjectAddressToRange(object);
4004514f5e3Sopenharmony_ci    Region *valueRegion = Region::ObjectAddressToRange(value);
4014514f5e3Sopenharmony_ci    if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) { // LCOV_EXCL_START
4024514f5e3Sopenharmony_ci        if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
4034514f5e3Sopenharmony_ci            LogErrorForObjSlot(heap_, "Verify SharedRSetPostFullGC: Local object, slot local_to_share bit = 0, "
4044514f5e3Sopenharmony_ci                "but SharedHeap object.", object, slot, value);
4054514f5e3Sopenharmony_ci        }
4064514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
4074514f5e3Sopenharmony_ci}
4084514f5e3Sopenharmony_ci
4094514f5e3Sopenharmony_civoid VerifyObjectVisitor::operator()(TaggedObject *obj, JSTaggedValue value)
4104514f5e3Sopenharmony_ci{
4114514f5e3Sopenharmony_ci    ObjectSlot slot(reinterpret_cast<uintptr_t>(obj));
4124514f5e3Sopenharmony_ci    if (!value.IsHeapObject()) {
4134514f5e3Sopenharmony_ci        LOG_GC(DEBUG) << "Heap object(" << slot.SlotAddress() << ") old to new rset fail: value is "
4144514f5e3Sopenharmony_ci                      << slot.GetTaggedType();
4154514f5e3Sopenharmony_ci        return;
4164514f5e3Sopenharmony_ci    }
4174514f5e3Sopenharmony_ci
4184514f5e3Sopenharmony_ci    TaggedObject *object = value.GetRawTaggedObject();
4194514f5e3Sopenharmony_ci    auto region = Region::ObjectAddressToRange(object);
4204514f5e3Sopenharmony_ci    if (region->InGeneralOldSpace()) { // LCOV_EXCL_START
4214514f5e3Sopenharmony_ci        LOG_GC(ERROR) << "Heap object(" << slot.GetTaggedType() << ") old to new rset fail: value("
4224514f5e3Sopenharmony_ci                      << slot.GetTaggedObject() << "/"
4234514f5e3Sopenharmony_ci                      << JSHClass::DumpJSType(slot.GetTaggedObject()->GetClass()->GetObjectType())
4244514f5e3Sopenharmony_ci                      << ")" << " in " << region->GetSpaceTypeName();
4254514f5e3Sopenharmony_ci        ++(*failCount_);
4264514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
4274514f5e3Sopenharmony_ci}
4284514f5e3Sopenharmony_ci
4294514f5e3Sopenharmony_civoid Verification::VerifyAll() const
4304514f5e3Sopenharmony_ci{
4314514f5e3Sopenharmony_ci    [[maybe_unused]] VerifyScope verifyScope(heap_);
4324514f5e3Sopenharmony_ci    heap_->GetSweeper()->EnsureAllTaskFinished();
4334514f5e3Sopenharmony_ci    size_t result = VerifyRoot();
4344514f5e3Sopenharmony_ci    result += VerifyHeap();
4354514f5e3Sopenharmony_ci    if (result > 0) { // LCOV_EXCL_START
4364514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "Verify (type=" << static_cast<uint8_t>(verifyKind_)
4374514f5e3Sopenharmony_ci                      << ") corrupted and " << result << " corruptions";
4384514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
4394514f5e3Sopenharmony_ci}
4404514f5e3Sopenharmony_ci
4414514f5e3Sopenharmony_cisize_t Verification::VerifyRoot() const
4424514f5e3Sopenharmony_ci{
4434514f5e3Sopenharmony_ci    size_t failCount = 0;
4444514f5e3Sopenharmony_ci    RootVisitor visitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot slot) {
4454514f5e3Sopenharmony_ci        JSTaggedValue value(slot.GetTaggedType());
4464514f5e3Sopenharmony_ci        // Skip verifying shared object in local gc verification.
4474514f5e3Sopenharmony_ci        if (value.IsInSharedHeap()) {
4484514f5e3Sopenharmony_ci            return;
4494514f5e3Sopenharmony_ci        }
4504514f5e3Sopenharmony_ci        VerifyObjectSlot(slot, &failCount);
4514514f5e3Sopenharmony_ci    };
4524514f5e3Sopenharmony_ci    RootRangeVisitor rangeVisitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) {
4534514f5e3Sopenharmony_ci        for (ObjectSlot slot = start; slot < end; slot++) {
4544514f5e3Sopenharmony_ci            JSTaggedValue value(slot.GetTaggedType());
4554514f5e3Sopenharmony_ci            // Skip verifying shared object in local gc verification.
4564514f5e3Sopenharmony_ci            if (value.IsInSharedHeap()) {
4574514f5e3Sopenharmony_ci                return;
4584514f5e3Sopenharmony_ci            }
4594514f5e3Sopenharmony_ci            VerifyObjectSlot(slot, &failCount);
4604514f5e3Sopenharmony_ci        }
4614514f5e3Sopenharmony_ci    };
4624514f5e3Sopenharmony_ci    RootBaseAndDerivedVisitor derivedVisitor =
4634514f5e3Sopenharmony_ci        []([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived,
4644514f5e3Sopenharmony_ci           [[maybe_unused]] uintptr_t baseOldObject) {
4654514f5e3Sopenharmony_ci    };
4664514f5e3Sopenharmony_ci    ObjectXRay::VisitVMRoots(heap_->GetEcmaVM(), visitor, rangeVisitor, derivedVisitor, VMRootVisitType::VERIFY);
4674514f5e3Sopenharmony_ci    if (failCount > 0) {
4684514f5e3Sopenharmony_ci        LOG_GC(ERROR) << "VerifyRoot detects deadObject count is " << failCount;
4694514f5e3Sopenharmony_ci    }
4704514f5e3Sopenharmony_ci
4714514f5e3Sopenharmony_ci    return failCount;
4724514f5e3Sopenharmony_ci}
4734514f5e3Sopenharmony_ci
4744514f5e3Sopenharmony_cisize_t Verification::VerifyHeap() const
4754514f5e3Sopenharmony_ci{
4764514f5e3Sopenharmony_ci    size_t failCount = heap_->VerifyHeapObjects(verifyKind_);
4774514f5e3Sopenharmony_ci    if (failCount > 0) {
4784514f5e3Sopenharmony_ci        LOG_GC(ERROR) << "VerifyHeap detects deadObject count is " << failCount;
4794514f5e3Sopenharmony_ci    }
4804514f5e3Sopenharmony_ci    return failCount;
4814514f5e3Sopenharmony_ci}
4824514f5e3Sopenharmony_ci
4834514f5e3Sopenharmony_cisize_t Verification::VerifyOldToNewRSet() const
4844514f5e3Sopenharmony_ci{
4854514f5e3Sopenharmony_ci    size_t failCount = heap_->VerifyOldToNewRSet(verifyKind_);
4864514f5e3Sopenharmony_ci    if (failCount > 0) {
4874514f5e3Sopenharmony_ci        LOG_GC(ERROR) << "VerifyOldToNewRSet detects non new space count is " << failCount;
4884514f5e3Sopenharmony_ci    }
4894514f5e3Sopenharmony_ci    return failCount;
4904514f5e3Sopenharmony_ci}
4914514f5e3Sopenharmony_ci
4924514f5e3Sopenharmony_civoid Verification::VerifyObjectSlot(const ObjectSlot &slot, size_t *failCount) const
4934514f5e3Sopenharmony_ci{
4944514f5e3Sopenharmony_ci    JSTaggedValue value(slot.GetTaggedType());
4954514f5e3Sopenharmony_ci    if (value.IsWeak()) {
4964514f5e3Sopenharmony_ci        VerifyObjectVisitor(heap_, failCount, verifyKind_)(value.GetTaggedWeakRef());
4974514f5e3Sopenharmony_ci    } else if (value.IsHeapObject()) {
4984514f5e3Sopenharmony_ci        VerifyObjectVisitor(heap_, failCount, verifyKind_)(value.GetTaggedObject());
4994514f5e3Sopenharmony_ci    }
5004514f5e3Sopenharmony_ci}
5014514f5e3Sopenharmony_ci
5024514f5e3Sopenharmony_civoid Verification::VerifyMark(Heap *heap)
5034514f5e3Sopenharmony_ci{
5044514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "start verify mark";
5054514f5e3Sopenharmony_ci    switch (heap->GetMarkType()) {
5064514f5e3Sopenharmony_ci        case MarkType::MARK_EDEN:
5074514f5e3Sopenharmony_ci            Verification(heap, VerifyKind::VERIFY_MARK_EDEN).VerifyAll();
5084514f5e3Sopenharmony_ci            break;
5094514f5e3Sopenharmony_ci        case MarkType::MARK_YOUNG:
5104514f5e3Sopenharmony_ci            Verification(heap, VerifyKind::VERIFY_MARK_YOUNG).VerifyAll();
5114514f5e3Sopenharmony_ci            break;
5124514f5e3Sopenharmony_ci        case MarkType::MARK_FULL:
5134514f5e3Sopenharmony_ci            Verification(heap, VerifyKind::VERIFY_MARK_FULL).VerifyAll();
5144514f5e3Sopenharmony_ci            break;
5154514f5e3Sopenharmony_ci    }
5164514f5e3Sopenharmony_ci}
5174514f5e3Sopenharmony_ci
5184514f5e3Sopenharmony_civoid Verification::VerifyEvacuate(Heap *heap)
5194514f5e3Sopenharmony_ci{
5204514f5e3Sopenharmony_ci    LOG_ECMA(DEBUG) << "start verify evacuate and sweep";
5214514f5e3Sopenharmony_ci    switch (heap->GetMarkType()) {
5224514f5e3Sopenharmony_ci        case MarkType::MARK_EDEN:
5234514f5e3Sopenharmony_ci            Verification(heap, VerifyKind::VERIFY_EVACUATE_EDEN).VerifyAll();
5244514f5e3Sopenharmony_ci            break;
5254514f5e3Sopenharmony_ci        case MarkType::MARK_YOUNG:
5264514f5e3Sopenharmony_ci            Verification(heap, VerifyKind::VERIFY_EVACUATE_YOUNG).VerifyAll();
5274514f5e3Sopenharmony_ci            break;
5284514f5e3Sopenharmony_ci        case MarkType::MARK_FULL:
5294514f5e3Sopenharmony_ci            Verification(heap, VerifyKind::VERIFY_EVACUATE_OLD).VerifyAll();
5304514f5e3Sopenharmony_ci            break;
5314514f5e3Sopenharmony_ci    }
5324514f5e3Sopenharmony_ci}
5334514f5e3Sopenharmony_ci
5344514f5e3Sopenharmony_civoid SharedHeapVerification::VerifyAll() const
5354514f5e3Sopenharmony_ci{
5364514f5e3Sopenharmony_ci    [[maybe_unused]] VerifyScope verifyScope(sHeap_);
5374514f5e3Sopenharmony_ci    sHeap_->GetSweeper()->EnsureAllTaskFinished();
5384514f5e3Sopenharmony_ci    size_t result = VerifyRoot();
5394514f5e3Sopenharmony_ci    result += VerifyHeap();
5404514f5e3Sopenharmony_ci    if (result > 0) { // LCOV_EXCL_START
5414514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "Verify (type=" << static_cast<uint8_t>(verifyKind_)
5424514f5e3Sopenharmony_ci                      << ") corrupted and " << result << " corruptions";
5434514f5e3Sopenharmony_ci    } // LCOV_EXCL_STOP
5444514f5e3Sopenharmony_ci}
5454514f5e3Sopenharmony_ci
5464514f5e3Sopenharmony_civoid SharedHeapVerification::VerifyMark(bool cm) const
5474514f5e3Sopenharmony_ci{
5484514f5e3Sopenharmony_ci    LOG_GC(DEBUG) << "start verify shared mark";
5494514f5e3Sopenharmony_ci    [[maybe_unused]] VerifyScope verifyScope(sHeap_);
5504514f5e3Sopenharmony_ci    sHeap_->GetSweeper()->EnsureAllTaskFinished();
5514514f5e3Sopenharmony_ci    Runtime::GetInstance()->GCIterateThreadList([cm](JSThread *thread) {
5524514f5e3Sopenharmony_ci        auto vm = thread->GetEcmaVM();
5534514f5e3Sopenharmony_ci        auto heap = vm->GetHeap();
5544514f5e3Sopenharmony_ci        heap->GetSweeper()->EnsureAllTaskFinished();
5554514f5e3Sopenharmony_ci        const_cast<Heap*>(heap)->FillBumpPointerForTlab();
5564514f5e3Sopenharmony_ci        auto localBuffer = const_cast<Heap*>(heap)->GetMarkingObjectLocalBuffer();
5574514f5e3Sopenharmony_ci        if (localBuffer != nullptr) { // LCOV_EXCL_START
5584514f5e3Sopenharmony_ci            LOG_GC(FATAL) << "verify shared node not null " << cm << ':' << thread;
5594514f5e3Sopenharmony_ci            UNREACHABLE();
5604514f5e3Sopenharmony_ci        } // LCOV_EXCL_STOP
5614514f5e3Sopenharmony_ci        heap->IterateOverObjects([cm](TaggedObject *obj) {
5624514f5e3Sopenharmony_ci            auto jsHclass = obj->GetClass();
5634514f5e3Sopenharmony_ci            auto f = [cm] (ObjectSlot slot, TaggedObject *obj) {
5644514f5e3Sopenharmony_ci                Region *objectRegion = Region::ObjectAddressToRange(obj);
5654514f5e3Sopenharmony_ci                JSTaggedValue value(slot.GetTaggedType());
5664514f5e3Sopenharmony_ci                if (value.IsWeak() || !value.IsHeapObject()) {
5674514f5e3Sopenharmony_ci                    return;
5684514f5e3Sopenharmony_ci                }
5694514f5e3Sopenharmony_ci                Region *valueRegion = Region::ObjectAddressToRange(value.GetTaggedObject());
5704514f5e3Sopenharmony_ci                if (!valueRegion->InSharedSweepableSpace()) {
5714514f5e3Sopenharmony_ci                    return;
5724514f5e3Sopenharmony_ci                }
5734514f5e3Sopenharmony_ci                if (!objectRegion->TestLocalToShare(slot.SlotAddress())) { // LCOV_EXCL_START
5744514f5e3Sopenharmony_ci                    LOG_GC(FATAL) << "verify shared1 " << cm << ':' << slot.SlotAddress()
5754514f5e3Sopenharmony_ci                                  << ' ' << value.GetTaggedObject();
5764514f5e3Sopenharmony_ci                    UNREACHABLE();
5774514f5e3Sopenharmony_ci                }
5784514f5e3Sopenharmony_ci                if (!valueRegion->Test(value.GetTaggedObject())) {
5794514f5e3Sopenharmony_ci                    LOG_GC(FATAL) << "verify shared2 " << cm << ':' << slot.SlotAddress()
5804514f5e3Sopenharmony_ci                                  << ' ' << value.GetTaggedObject();
5814514f5e3Sopenharmony_ci                    UNREACHABLE();
5824514f5e3Sopenharmony_ci                }
5834514f5e3Sopenharmony_ci                if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
5844514f5e3Sopenharmony_ci                    LOG_GC(FATAL) << "verify shared3 " << cm << ':' << slot.SlotAddress()
5854514f5e3Sopenharmony_ci                                  << ' ' << value.GetTaggedObject();
5864514f5e3Sopenharmony_ci                    UNREACHABLE();
5874514f5e3Sopenharmony_ci                } // LCOV_EXCL_STOP
5884514f5e3Sopenharmony_ci            };
5894514f5e3Sopenharmony_ci            ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(
5904514f5e3Sopenharmony_ci                obj, jsHclass, [f](TaggedObject *root, ObjectSlot start, ObjectSlot end,
5914514f5e3Sopenharmony_ci                                VisitObjectArea area) {
5924514f5e3Sopenharmony_ci                if (area == VisitObjectArea::IN_OBJECT) {
5934514f5e3Sopenharmony_ci                    auto hclass = root->GetClass();
5944514f5e3Sopenharmony_ci                    ASSERT(!hclass->IsAllTaggedProp());
5954514f5e3Sopenharmony_ci                    int index = 0;
5964514f5e3Sopenharmony_ci                    for (ObjectSlot slot = start; slot < end; slot++) {
5974514f5e3Sopenharmony_ci                        auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
5984514f5e3Sopenharmony_ci                        auto attr = layout->GetAttr(index++);
5994514f5e3Sopenharmony_ci                        if (attr.IsTaggedRep()) {
6004514f5e3Sopenharmony_ci                            f(slot, root);
6014514f5e3Sopenharmony_ci                        }
6024514f5e3Sopenharmony_ci                    }
6034514f5e3Sopenharmony_ci                    return;
6044514f5e3Sopenharmony_ci                }
6054514f5e3Sopenharmony_ci                for (ObjectSlot slot = start; slot < end; slot++) {
6064514f5e3Sopenharmony_ci                    f(slot, root);
6074514f5e3Sopenharmony_ci                }
6084514f5e3Sopenharmony_ci            });
6094514f5e3Sopenharmony_ci        });
6104514f5e3Sopenharmony_ci    });
6114514f5e3Sopenharmony_ci    sHeap_->IterateOverObjects([cm](TaggedObject *obj) {
6124514f5e3Sopenharmony_ci        auto jsHclass = obj->GetClass();
6134514f5e3Sopenharmony_ci        auto f = [cm] (ObjectSlot slot, TaggedObject *obj) {
6144514f5e3Sopenharmony_ci            Region *objectRegion = Region::ObjectAddressToRange(obj);
6154514f5e3Sopenharmony_ci            if (!objectRegion->Test(obj)) {
6164514f5e3Sopenharmony_ci                return;
6174514f5e3Sopenharmony_ci            }
6184514f5e3Sopenharmony_ci            JSTaggedValue value(slot.GetTaggedType());
6194514f5e3Sopenharmony_ci            if (value.IsWeak() || !value.IsHeapObject()) {
6204514f5e3Sopenharmony_ci                return;
6214514f5e3Sopenharmony_ci            }
6224514f5e3Sopenharmony_ci            [[maybe_unused]] Region *valueRegion = Region::ObjectAddressToRange(value.GetTaggedObject());
6234514f5e3Sopenharmony_ci            if (!valueRegion->InSharedHeap()) { // LCOV_EXCL_START
6244514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared4 " << cm << ':' << slot.SlotAddress()
6254514f5e3Sopenharmony_ci                              << ' ' << value.GetTaggedObject();
6264514f5e3Sopenharmony_ci                UNREACHABLE();
6274514f5e3Sopenharmony_ci            }
6284514f5e3Sopenharmony_ci            if (!valueRegion->InSharedReadOnlySpace()
6294514f5e3Sopenharmony_ci                    && !valueRegion->Test(value.GetTaggedObject())) {
6304514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared5 " << cm << ':' << slot.SlotAddress()
6314514f5e3Sopenharmony_ci                              << ' ' << value.GetTaggedObject();
6324514f5e3Sopenharmony_ci                UNREACHABLE();
6334514f5e3Sopenharmony_ci            }
6344514f5e3Sopenharmony_ci            if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
6354514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared6 " << cm << ':' << slot.SlotAddress()
6364514f5e3Sopenharmony_ci                              << ' ' << value.GetTaggedObject();
6374514f5e3Sopenharmony_ci                UNREACHABLE();
6384514f5e3Sopenharmony_ci            } // LCOV_EXCL_STOP
6394514f5e3Sopenharmony_ci        };
6404514f5e3Sopenharmony_ci        ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(
6414514f5e3Sopenharmony_ci            obj, jsHclass, [f](TaggedObject *root, ObjectSlot start, ObjectSlot end,
6424514f5e3Sopenharmony_ci                               VisitObjectArea area) {
6434514f5e3Sopenharmony_ci            if (area == VisitObjectArea::IN_OBJECT) {
6444514f5e3Sopenharmony_ci                auto hclass = root->GetClass();
6454514f5e3Sopenharmony_ci                ASSERT(!hclass->IsAllTaggedProp());
6464514f5e3Sopenharmony_ci                int index = 0;
6474514f5e3Sopenharmony_ci                for (ObjectSlot slot = start; slot < end; slot++) {
6484514f5e3Sopenharmony_ci                    auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
6494514f5e3Sopenharmony_ci                    auto attr = layout->GetAttr(index++);
6504514f5e3Sopenharmony_ci                    if (attr.IsTaggedRep()) {
6514514f5e3Sopenharmony_ci                        f(slot, root);
6524514f5e3Sopenharmony_ci                    }
6534514f5e3Sopenharmony_ci                }
6544514f5e3Sopenharmony_ci                return;
6554514f5e3Sopenharmony_ci            }
6564514f5e3Sopenharmony_ci            for (ObjectSlot slot = start; slot < end; slot++) {
6574514f5e3Sopenharmony_ci                f(slot, root);
6584514f5e3Sopenharmony_ci            }
6594514f5e3Sopenharmony_ci        });
6604514f5e3Sopenharmony_ci    });
6614514f5e3Sopenharmony_ci}
6624514f5e3Sopenharmony_ci
6634514f5e3Sopenharmony_civoid SharedHeapVerification::VerifySweep(bool cm) const
6644514f5e3Sopenharmony_ci{
6654514f5e3Sopenharmony_ci    LOG_GC(DEBUG) << "start verify shared sweep";
6664514f5e3Sopenharmony_ci    [[maybe_unused]] VerifyScope verifyScope(sHeap_);
6674514f5e3Sopenharmony_ci    sHeap_->GetSweeper()->EnsureAllTaskFinished();
6684514f5e3Sopenharmony_ci    Runtime::GetInstance()->GCIterateThreadList([cm](JSThread *thread) {
6694514f5e3Sopenharmony_ci        auto vm = thread->GetEcmaVM();
6704514f5e3Sopenharmony_ci        auto heap = vm->GetHeap();
6714514f5e3Sopenharmony_ci        heap->GetSweeper()->EnsureAllTaskFinished();
6724514f5e3Sopenharmony_ci        const_cast<Heap*>(heap)->FillBumpPointerForTlab();
6734514f5e3Sopenharmony_ci        heap->IterateOverObjects([cm](TaggedObject *obj) {
6744514f5e3Sopenharmony_ci            auto jsHclass = obj->GetClass();
6754514f5e3Sopenharmony_ci            auto f = [cm] (ObjectSlot slot, TaggedObject *obj) {
6764514f5e3Sopenharmony_ci                Region *objectRegion = Region::ObjectAddressToRange(obj);
6774514f5e3Sopenharmony_ci                JSTaggedValue value(slot.GetTaggedType());
6784514f5e3Sopenharmony_ci                if (value.IsWeak() || !value.IsHeapObject()) {
6794514f5e3Sopenharmony_ci                    return;
6804514f5e3Sopenharmony_ci                }
6814514f5e3Sopenharmony_ci                Region *valueRegion = Region::ObjectAddressToRange(value.GetTaggedObject());
6824514f5e3Sopenharmony_ci                if (!valueRegion->InSharedSweepableSpace()) {
6834514f5e3Sopenharmony_ci                    return;
6844514f5e3Sopenharmony_ci                }
6854514f5e3Sopenharmony_ci                if (!objectRegion->TestLocalToShare(slot.SlotAddress())) { // LCOV_EXCL_START
6864514f5e3Sopenharmony_ci                    LOG_GC(FATAL) << "verify shared7 " << cm << ':' << slot.SlotAddress()
6874514f5e3Sopenharmony_ci                                  << ' ' << value.GetTaggedObject();
6884514f5e3Sopenharmony_ci                    UNREACHABLE();
6894514f5e3Sopenharmony_ci                }
6904514f5e3Sopenharmony_ci                if (!valueRegion->Test(value.GetTaggedObject())) {
6914514f5e3Sopenharmony_ci                    LOG_GC(FATAL) << "verify shared8 " << cm << ':' << slot.SlotAddress()
6924514f5e3Sopenharmony_ci                                  << ' ' << value.GetTaggedObject();
6934514f5e3Sopenharmony_ci                    UNREACHABLE();
6944514f5e3Sopenharmony_ci                }
6954514f5e3Sopenharmony_ci                if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
6964514f5e3Sopenharmony_ci                    LOG_GC(FATAL) << "verify shared9 " << cm << ':' << slot.SlotAddress()
6974514f5e3Sopenharmony_ci                                  << ' ' << value.GetTaggedObject();
6984514f5e3Sopenharmony_ci                    UNREACHABLE();
6994514f5e3Sopenharmony_ci                } // LCOV_EXCL_STOP
7004514f5e3Sopenharmony_ci            };
7014514f5e3Sopenharmony_ci            ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(
7024514f5e3Sopenharmony_ci                obj, jsHclass, [f](TaggedObject *root, ObjectSlot start, ObjectSlot end,
7034514f5e3Sopenharmony_ci                                VisitObjectArea area) {
7044514f5e3Sopenharmony_ci                if (area == VisitObjectArea::IN_OBJECT) {
7054514f5e3Sopenharmony_ci                    auto hclass = root->GetClass();
7064514f5e3Sopenharmony_ci                    ASSERT(!hclass->IsAllTaggedProp());
7074514f5e3Sopenharmony_ci                    int index = 0;
7084514f5e3Sopenharmony_ci                    for (ObjectSlot slot = start; slot < end; slot++) {
7094514f5e3Sopenharmony_ci                        auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
7104514f5e3Sopenharmony_ci                        auto attr = layout->GetAttr(index++);
7114514f5e3Sopenharmony_ci                        if (attr.IsTaggedRep()) {
7124514f5e3Sopenharmony_ci                            f(slot, root);
7134514f5e3Sopenharmony_ci                        }
7144514f5e3Sopenharmony_ci                    }
7154514f5e3Sopenharmony_ci                    return;
7164514f5e3Sopenharmony_ci                }
7174514f5e3Sopenharmony_ci                for (ObjectSlot slot = start; slot < end; slot++) {
7184514f5e3Sopenharmony_ci                    f(slot, root);
7194514f5e3Sopenharmony_ci                }
7204514f5e3Sopenharmony_ci            });
7214514f5e3Sopenharmony_ci        });
7224514f5e3Sopenharmony_ci    });
7234514f5e3Sopenharmony_ci    sHeap_->IterateOverObjects([cm](TaggedObject *obj) {
7244514f5e3Sopenharmony_ci        auto jsHclass = obj->GetClass();
7254514f5e3Sopenharmony_ci        auto f = [cm] (ObjectSlot slot, TaggedObject *obj) {
7264514f5e3Sopenharmony_ci            [[maybe_unused]] Region *objectRegion = Region::ObjectAddressToRange(obj);
7274514f5e3Sopenharmony_ci            if (!objectRegion->Test(obj)) { // LCOV_EXCL_START
7284514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared10 " << cm << ':' << obj;
7294514f5e3Sopenharmony_ci                UNREACHABLE();
7304514f5e3Sopenharmony_ci            }
7314514f5e3Sopenharmony_ci            JSTaggedValue value(slot.GetTaggedType());
7324514f5e3Sopenharmony_ci            if (value.IsWeak() || !value.IsHeapObject()) {
7334514f5e3Sopenharmony_ci                return;
7344514f5e3Sopenharmony_ci            }
7354514f5e3Sopenharmony_ci            [[maybe_unused]] Region *valueRegion = Region::ObjectAddressToRange(value.GetTaggedObject());
7364514f5e3Sopenharmony_ci            if (!valueRegion->InSharedHeap()) {
7374514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared11 " << cm << ':' << slot.SlotAddress()
7384514f5e3Sopenharmony_ci                              << ' ' << value.GetTaggedObject();
7394514f5e3Sopenharmony_ci                UNREACHABLE();
7404514f5e3Sopenharmony_ci            }
7414514f5e3Sopenharmony_ci            if (!valueRegion->InSharedReadOnlySpace()
7424514f5e3Sopenharmony_ci                    && !valueRegion->Test(value.GetTaggedObject())) {
7434514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared12 " << cm << ':' << slot.SlotAddress()
7444514f5e3Sopenharmony_ci                              << ' ' << value.GetTaggedObject();
7454514f5e3Sopenharmony_ci                UNREACHABLE();
7464514f5e3Sopenharmony_ci            }
7474514f5e3Sopenharmony_ci            if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
7484514f5e3Sopenharmony_ci                LOG_GC(FATAL) << "verify shared13 " << cm << ':' << slot.SlotAddress()
7494514f5e3Sopenharmony_ci                              << ' ' << value.GetTaggedObject();
7504514f5e3Sopenharmony_ci                UNREACHABLE();
7514514f5e3Sopenharmony_ci            } // LCOV_EXCL_STOP
7524514f5e3Sopenharmony_ci        };
7534514f5e3Sopenharmony_ci        ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(
7544514f5e3Sopenharmony_ci            obj, jsHclass, [f](TaggedObject *root, ObjectSlot start, ObjectSlot end,
7554514f5e3Sopenharmony_ci                                VisitObjectArea area) {
7564514f5e3Sopenharmony_ci            if (area == VisitObjectArea::IN_OBJECT) {
7574514f5e3Sopenharmony_ci                auto hclass = root->GetClass();
7584514f5e3Sopenharmony_ci                ASSERT(!hclass->IsAllTaggedProp());
7594514f5e3Sopenharmony_ci                int index = 0;
7604514f5e3Sopenharmony_ci                for (ObjectSlot slot = start; slot < end; slot++) {
7614514f5e3Sopenharmony_ci                    auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
7624514f5e3Sopenharmony_ci                    auto attr = layout->GetAttr(index++);
7634514f5e3Sopenharmony_ci                    if (attr.IsTaggedRep()) {
7644514f5e3Sopenharmony_ci                        f(slot, root);
7654514f5e3Sopenharmony_ci                    }
7664514f5e3Sopenharmony_ci                }
7674514f5e3Sopenharmony_ci                return;
7684514f5e3Sopenharmony_ci            }
7694514f5e3Sopenharmony_ci            for (ObjectSlot slot = start; slot < end; slot++) {
7704514f5e3Sopenharmony_ci                f(slot, root);
7714514f5e3Sopenharmony_ci            }
7724514f5e3Sopenharmony_ci        });
7734514f5e3Sopenharmony_ci    });
7744514f5e3Sopenharmony_ci}
7754514f5e3Sopenharmony_ci
7764514f5e3Sopenharmony_cisize_t SharedHeapVerification::VerifyRoot() const
7774514f5e3Sopenharmony_ci{
7784514f5e3Sopenharmony_ci    size_t failCount = 0;
7794514f5e3Sopenharmony_ci    RootVisitor visitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot slot) {
7804514f5e3Sopenharmony_ci        VerifyObjectSlot(slot, &failCount);
7814514f5e3Sopenharmony_ci    };
7824514f5e3Sopenharmony_ci    RootRangeVisitor rangeVisitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) {
7834514f5e3Sopenharmony_ci        for (ObjectSlot slot = start; slot < end; slot++) {
7844514f5e3Sopenharmony_ci            VerifyObjectSlot(slot, &failCount);
7854514f5e3Sopenharmony_ci        }
7864514f5e3Sopenharmony_ci    };
7874514f5e3Sopenharmony_ci    RootBaseAndDerivedVisitor derivedVisitor =
7884514f5e3Sopenharmony_ci        []([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived,
7894514f5e3Sopenharmony_ci           [[maybe_unused]] uintptr_t baseOldObject) {
7904514f5e3Sopenharmony_ci    };
7914514f5e3Sopenharmony_ci    RootVisitor serializeVisitor = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot slot) {
7924514f5e3Sopenharmony_ci        JSTaggedValue value(slot.GetTaggedType());
7934514f5e3Sopenharmony_ci        if (!sHeap_->IsAlive(value.GetTaggedObject())) {
7944514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "Serialize Heap verify detected a dead object. " << value.GetTaggedObject();
7954514f5e3Sopenharmony_ci            ++failCount;
7964514f5e3Sopenharmony_ci        }
7974514f5e3Sopenharmony_ci    };
7984514f5e3Sopenharmony_ci    Runtime::GetInstance()->IterateSerializeRoot(serializeVisitor);
7994514f5e3Sopenharmony_ci    Runtime::GetInstance()->GCIterateThreadList([&](JSThread *thread) {
8004514f5e3Sopenharmony_ci        ASSERT(!thread->IsInRunningState());
8014514f5e3Sopenharmony_ci        auto vm = thread->GetEcmaVM();
8024514f5e3Sopenharmony_ci        auto localHeap = const_cast<Heap*>(vm->GetHeap());
8034514f5e3Sopenharmony_ci        localHeap->GetSweeper()->EnsureAllTaskFinished();
8044514f5e3Sopenharmony_ci        ObjectXRay::VisitVMRoots(vm, visitor, rangeVisitor, derivedVisitor, VMRootVisitType::VERIFY);
8054514f5e3Sopenharmony_ci        if (failCount > 0) {
8064514f5e3Sopenharmony_ci            LOG_GC(ERROR) << "SharedHeap VerifyRoot detects deadObject count is " << failCount;
8074514f5e3Sopenharmony_ci        }
8084514f5e3Sopenharmony_ci    });
8094514f5e3Sopenharmony_ci    return failCount;
8104514f5e3Sopenharmony_ci}
8114514f5e3Sopenharmony_ci
8124514f5e3Sopenharmony_cisize_t SharedHeapVerification::VerifyHeap() const
8134514f5e3Sopenharmony_ci{
8144514f5e3Sopenharmony_ci    Runtime::GetInstance()->GCIterateThreadList([&](JSThread *thread) {
8154514f5e3Sopenharmony_ci        ASSERT(!thread->IsInRunningState());
8164514f5e3Sopenharmony_ci        const_cast<Heap*>(thread->GetEcmaVM()->GetHeap())->FillBumpPointerForTlab();
8174514f5e3Sopenharmony_ci    });
8184514f5e3Sopenharmony_ci    size_t failCount = sHeap_->VerifyHeapObjects(verifyKind_);
8194514f5e3Sopenharmony_ci    if (failCount > 0) {
8204514f5e3Sopenharmony_ci        LOG_GC(ERROR) << "SharedHeap VerifyHeap detects deadObject count is " << failCount;
8214514f5e3Sopenharmony_ci    }
8224514f5e3Sopenharmony_ci    VerifyKind localVerifyKind = VerifyKind::VERIFY_END;
8234514f5e3Sopenharmony_ci    if (verifyKind_ == VerifyKind::VERIFY_PRE_SHARED_GC) {
8244514f5e3Sopenharmony_ci        localVerifyKind = VerifyKind::VERIFY_PRE_GC;
8254514f5e3Sopenharmony_ci    } else if (verifyKind_ == VerifyKind::VERIFY_POST_SHARED_GC) {
8264514f5e3Sopenharmony_ci        localVerifyKind = VerifyKind::VERIFY_POST_GC;
8274514f5e3Sopenharmony_ci    }
8284514f5e3Sopenharmony_ci
8294514f5e3Sopenharmony_ci    Runtime::GetInstance()->GCIterateThreadList([&, localVerifyKind](JSThread *thread) {
8304514f5e3Sopenharmony_ci        ASSERT(!thread->IsInRunningState());
8314514f5e3Sopenharmony_ci        auto vm = thread->GetEcmaVM();
8324514f5e3Sopenharmony_ci        auto localHeap = const_cast<Heap*>(vm->GetHeap());
8334514f5e3Sopenharmony_ci        localHeap->GetSweeper()->EnsureAllTaskFinished();
8344514f5e3Sopenharmony_ci        if (localVerifyKind != VerifyKind::VERIFY_END) {
8354514f5e3Sopenharmony_ci            Verification(localHeap, localVerifyKind).VerifyAll();
8364514f5e3Sopenharmony_ci        }
8374514f5e3Sopenharmony_ci        if (failCount > 0) {
8384514f5e3Sopenharmony_ci            LOG_GC(ERROR) << "SharedHeap VerifyRoot detects deadObject in local heap count is " << failCount;
8394514f5e3Sopenharmony_ci        }
8404514f5e3Sopenharmony_ci    });
8414514f5e3Sopenharmony_ci    return failCount;
8424514f5e3Sopenharmony_ci}
8434514f5e3Sopenharmony_ci
8444514f5e3Sopenharmony_civoid SharedHeapVerification::VerifyObjectSlot(const ObjectSlot &slot, size_t *failCount) const
8454514f5e3Sopenharmony_ci{
8464514f5e3Sopenharmony_ci    JSTaggedValue value(slot.GetTaggedType());
8474514f5e3Sopenharmony_ci    if (value.IsWeak()) {
8484514f5e3Sopenharmony_ci        VerifyObjectVisitor(sHeap_, failCount, verifyKind_)(value.GetTaggedWeakRef());
8494514f5e3Sopenharmony_ci    } else if (value.IsHeapObject()) {
8504514f5e3Sopenharmony_ci        VerifyObjectVisitor(sHeap_, failCount, verifyKind_)(value.GetTaggedObject());
8514514f5e3Sopenharmony_ci    }
8524514f5e3Sopenharmony_ci}
8534514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
854