14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2022-2024 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#ifndef ECMASCRIPT_MEM_REGION_INL_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_REGION_INL_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/mem/region.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ci#include "ecmascript/mem/mem.h"
224514f5e3Sopenharmony_ci#include "ecmascript/mem/native_area_allocator.h"
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_cinamespace panda::ecmascript {
254514f5e3Sopenharmony_ciinline RememberedSet *Region::CreateRememberedSet()
264514f5e3Sopenharmony_ci{
274514f5e3Sopenharmony_ci    auto bitSize = GCBitset::SizeOfGCBitset(GetCapacity());
284514f5e3Sopenharmony_ci    auto setAddr = nativeAreaAllocator_->Allocate(bitSize + RememberedSet::GCBITSET_DATA_OFFSET);
294514f5e3Sopenharmony_ci    auto ret = new (setAddr) RememberedSet(bitSize);
304514f5e3Sopenharmony_ci    ret->ClearAll();
314514f5e3Sopenharmony_ci    std::atomic_thread_fence(std::memory_order_seq_cst);
324514f5e3Sopenharmony_ci    return ret;
334514f5e3Sopenharmony_ci}
344514f5e3Sopenharmony_ci
354514f5e3Sopenharmony_ciinline RememberedSet *Region::GetOrCreateCrossRegionRememberedSet()
364514f5e3Sopenharmony_ci{
374514f5e3Sopenharmony_ci    if (UNLIKELY(crossRegionSet_ == nullptr)) {
384514f5e3Sopenharmony_ci        LockHolder lock(*lock_);
394514f5e3Sopenharmony_ci        if (crossRegionSet_ == nullptr) {
404514f5e3Sopenharmony_ci            crossRegionSet_ = CreateRememberedSet();
414514f5e3Sopenharmony_ci        }
424514f5e3Sopenharmony_ci    }
434514f5e3Sopenharmony_ci    return crossRegionSet_;
444514f5e3Sopenharmony_ci}
454514f5e3Sopenharmony_ci
464514f5e3Sopenharmony_ciARK_NOINLINE RememberedSet* Region::CreateNewToEdenRememberedSet()
474514f5e3Sopenharmony_ci{
484514f5e3Sopenharmony_ci    LockHolder lock(*lock_);
494514f5e3Sopenharmony_ci    if (packedData_.newToEdenSet_ == nullptr) {
504514f5e3Sopenharmony_ci        packedData_.newToEdenSet_ = CreateRememberedSet();
514514f5e3Sopenharmony_ci    }
524514f5e3Sopenharmony_ci    return packedData_.newToEdenSet_;
534514f5e3Sopenharmony_ci}
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ciinline RememberedSet *Region::GetOrCreateNewToEdenRememberedSet()
564514f5e3Sopenharmony_ci{
574514f5e3Sopenharmony_ci    if (UNLIKELY(packedData_.newToEdenSet_ == nullptr)) {
584514f5e3Sopenharmony_ci        return CreateNewToEdenRememberedSet();
594514f5e3Sopenharmony_ci    }
604514f5e3Sopenharmony_ci    return packedData_.newToEdenSet_;
614514f5e3Sopenharmony_ci}
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ciARK_NOINLINE RememberedSet* Region::CreateOldToNewRememberedSet()
644514f5e3Sopenharmony_ci{
654514f5e3Sopenharmony_ci    LockHolder lock(*lock_);
664514f5e3Sopenharmony_ci    if (packedData_.oldToNewSet_ == nullptr) {
674514f5e3Sopenharmony_ci        if (sweepingOldToNewRSet_ != nullptr && IsGCFlagSet(RegionGCFlags::HAS_BEEN_SWEPT)) {
684514f5e3Sopenharmony_ci            packedData_.oldToNewSet_ = sweepingOldToNewRSet_;
694514f5e3Sopenharmony_ci            sweepingOldToNewRSet_ = nullptr;
704514f5e3Sopenharmony_ci        } else {
714514f5e3Sopenharmony_ci            packedData_.oldToNewSet_ = CreateRememberedSet();
724514f5e3Sopenharmony_ci        }
734514f5e3Sopenharmony_ci    }
744514f5e3Sopenharmony_ci    return packedData_.oldToNewSet_;
754514f5e3Sopenharmony_ci}
764514f5e3Sopenharmony_ci
774514f5e3Sopenharmony_ciinline RememberedSet* Region::GetOrCreateOldToNewRememberedSet()
784514f5e3Sopenharmony_ci{
794514f5e3Sopenharmony_ci    if (UNLIKELY(packedData_.oldToNewSet_ == nullptr)) {
804514f5e3Sopenharmony_ci        return CreateOldToNewRememberedSet();
814514f5e3Sopenharmony_ci    }
824514f5e3Sopenharmony_ci    return packedData_.oldToNewSet_;
834514f5e3Sopenharmony_ci}
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ciARK_NOINLINE RememberedSet* Region::CreateLocalToShareRememberedSet()
864514f5e3Sopenharmony_ci{
874514f5e3Sopenharmony_ci    LockHolder lock(*lock_);
884514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ == nullptr) {
894514f5e3Sopenharmony_ci        if (sweepingLocalToShareRSet_ != nullptr && IsGCFlagSet(RegionGCFlags::HAS_BEEN_SWEPT)) {
904514f5e3Sopenharmony_ci            packedData_.localToShareSet_ = sweepingLocalToShareRSet_;
914514f5e3Sopenharmony_ci            sweepingLocalToShareRSet_ = nullptr;
924514f5e3Sopenharmony_ci        } else {
934514f5e3Sopenharmony_ci            packedData_.localToShareSet_ = CreateRememberedSet();
944514f5e3Sopenharmony_ci        }
954514f5e3Sopenharmony_ci    }
964514f5e3Sopenharmony_ci    return packedData_.localToShareSet_;
974514f5e3Sopenharmony_ci}
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ciinline RememberedSet *Region::GetOrCreateLocalToShareRememberedSet()
1004514f5e3Sopenharmony_ci{
1014514f5e3Sopenharmony_ci    if (UNLIKELY(packedData_.localToShareSet_ == nullptr)) {
1024514f5e3Sopenharmony_ci        return CreateLocalToShareRememberedSet();
1034514f5e3Sopenharmony_ci    }
1044514f5e3Sopenharmony_ci    return packedData_.localToShareSet_;
1054514f5e3Sopenharmony_ci}
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_ciinline void Region::MergeLocalToShareRSetForCS()
1084514f5e3Sopenharmony_ci{
1094514f5e3Sopenharmony_ci    if (sweepingLocalToShareRSet_ == nullptr) {
1104514f5e3Sopenharmony_ci        return;
1114514f5e3Sopenharmony_ci    }
1124514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ == nullptr) {
1134514f5e3Sopenharmony_ci        packedData_.localToShareSet_ = sweepingLocalToShareRSet_;
1144514f5e3Sopenharmony_ci        sweepingLocalToShareRSet_ = nullptr;
1154514f5e3Sopenharmony_ci    } else {
1164514f5e3Sopenharmony_ci        packedData_.localToShareSet_->Merge(sweepingLocalToShareRSet_);
1174514f5e3Sopenharmony_ci        DeleteSweepingLocalToShareRSet();
1184514f5e3Sopenharmony_ci        sweepingLocalToShareRSet_ = nullptr;
1194514f5e3Sopenharmony_ci    }
1204514f5e3Sopenharmony_ci}
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ciinline void Region::MergeOldToNewRSetForCS()
1234514f5e3Sopenharmony_ci{
1244514f5e3Sopenharmony_ci    if (sweepingOldToNewRSet_ == nullptr) {
1254514f5e3Sopenharmony_ci        return;
1264514f5e3Sopenharmony_ci    }
1274514f5e3Sopenharmony_ci    if (packedData_.oldToNewSet_ == nullptr) {
1284514f5e3Sopenharmony_ci        packedData_.oldToNewSet_ = sweepingOldToNewRSet_;
1294514f5e3Sopenharmony_ci        sweepingOldToNewRSet_   = nullptr;
1304514f5e3Sopenharmony_ci    } else {
1314514f5e3Sopenharmony_ci        packedData_.oldToNewSet_->Merge(sweepingOldToNewRSet_);
1324514f5e3Sopenharmony_ci        DeleteSweepingOldToNewRSet();
1334514f5e3Sopenharmony_ci        sweepingOldToNewRSet_ = nullptr;
1344514f5e3Sopenharmony_ci    }
1354514f5e3Sopenharmony_ci}
1364514f5e3Sopenharmony_ci
1374514f5e3Sopenharmony_ciinline void Region::MergeLocalToShareRSetForCM(RememberedSet *set)
1384514f5e3Sopenharmony_ci{
1394514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ == nullptr) {
1404514f5e3Sopenharmony_ci        packedData_.localToShareSet_ = set;
1414514f5e3Sopenharmony_ci    } else {
1424514f5e3Sopenharmony_ci        packedData_.localToShareSet_->Merge(set);
1434514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(set, set->Size());
1444514f5e3Sopenharmony_ci    }
1454514f5e3Sopenharmony_ci}
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ciinline GCBitset *Region::GetMarkGCBitset() const
1484514f5e3Sopenharmony_ci{
1494514f5e3Sopenharmony_ci    return packedData_.markGCBitset_;
1504514f5e3Sopenharmony_ci}
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_ciinline bool Region::AtomicMark(void *address)
1534514f5e3Sopenharmony_ci{
1544514f5e3Sopenharmony_ci    auto addrPtr = reinterpret_cast<uintptr_t>(address);
1554514f5e3Sopenharmony_ci    ASSERT(InRange(addrPtr));
1564514f5e3Sopenharmony_ci    return packedData_.markGCBitset_->SetBit<AccessType::ATOMIC>(
1574514f5e3Sopenharmony_ci        (addrPtr & DEFAULT_REGION_MASK) >> TAGGED_TYPE_SIZE_LOG);
1584514f5e3Sopenharmony_ci}
1594514f5e3Sopenharmony_ci
1604514f5e3Sopenharmony_ciinline bool Region::NonAtomicMark(void *address)
1614514f5e3Sopenharmony_ci{
1624514f5e3Sopenharmony_ci    ASSERT(IsFreshRegion());
1634514f5e3Sopenharmony_ci    auto addrPtr = reinterpret_cast<uintptr_t>(address);
1644514f5e3Sopenharmony_ci    ASSERT(InRange(addrPtr));
1654514f5e3Sopenharmony_ci    return packedData_.markGCBitset_->SetBit<AccessType::NON_ATOMIC>(
1664514f5e3Sopenharmony_ci        (addrPtr & DEFAULT_REGION_MASK) >> TAGGED_TYPE_SIZE_LOG);
1674514f5e3Sopenharmony_ci}
1684514f5e3Sopenharmony_ci
1694514f5e3Sopenharmony_ciinline void Region::ClearMark(void *address)
1704514f5e3Sopenharmony_ci{
1714514f5e3Sopenharmony_ci    auto addrPtr = reinterpret_cast<uintptr_t>(address);
1724514f5e3Sopenharmony_ci    ASSERT(InRange(addrPtr));
1734514f5e3Sopenharmony_ci    packedData_.markGCBitset_->ClearBit((addrPtr & DEFAULT_REGION_MASK) >> TAGGED_TYPE_SIZE_LOG);
1744514f5e3Sopenharmony_ci}
1754514f5e3Sopenharmony_ci
1764514f5e3Sopenharmony_ciinline bool Region::Test(void *addr) const
1774514f5e3Sopenharmony_ci{
1784514f5e3Sopenharmony_ci    auto addrPtr = reinterpret_cast<uintptr_t>(addr);
1794514f5e3Sopenharmony_ci    return Test(addrPtr);
1804514f5e3Sopenharmony_ci}
1814514f5e3Sopenharmony_ci
1824514f5e3Sopenharmony_ciinline bool Region::Test(uintptr_t addrPtr) const
1834514f5e3Sopenharmony_ci{
1844514f5e3Sopenharmony_ci    ASSERT(InRange(addrPtr));
1854514f5e3Sopenharmony_ci    return packedData_.markGCBitset_->TestBit((addrPtr & DEFAULT_REGION_MASK) >> TAGGED_TYPE_SIZE_LOG);
1864514f5e3Sopenharmony_ci}
1874514f5e3Sopenharmony_ci
1884514f5e3Sopenharmony_ci// ONLY used for heap verification.
1894514f5e3Sopenharmony_ciinline bool Region::TestNewToEden(uintptr_t addr)
1904514f5e3Sopenharmony_ci{
1914514f5e3Sopenharmony_ci    ASSERT(InRange(addr));
1924514f5e3Sopenharmony_ci    // Only used for heap verification, so donot need to use lock
1934514f5e3Sopenharmony_ci    auto set = packedData_.newToEdenSet_;
1944514f5e3Sopenharmony_ci    if (set == nullptr) {
1954514f5e3Sopenharmony_ci        return false;
1964514f5e3Sopenharmony_ci    }
1974514f5e3Sopenharmony_ci    return set->TestBit(ToUintPtr(this), addr);
1984514f5e3Sopenharmony_ci}
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci// ONLY used for heap verification.
2014514f5e3Sopenharmony_ciinline bool Region::TestOldToNew(uintptr_t addr)
2024514f5e3Sopenharmony_ci{
2034514f5e3Sopenharmony_ci    ASSERT(InRange(addr));
2044514f5e3Sopenharmony_ci    // Only used for heap verification, so donot need to use lock
2054514f5e3Sopenharmony_ci    auto set = packedData_.oldToNewSet_;
2064514f5e3Sopenharmony_ci    if (set == nullptr) {
2074514f5e3Sopenharmony_ci        return false;
2084514f5e3Sopenharmony_ci    }
2094514f5e3Sopenharmony_ci    return set->TestBit(ToUintPtr(this), addr);
2104514f5e3Sopenharmony_ci}
2114514f5e3Sopenharmony_ci
2124514f5e3Sopenharmony_ci// ONLY used for heap verification.
2134514f5e3Sopenharmony_ciinline bool Region::TestLocalToShare(uintptr_t addr)
2144514f5e3Sopenharmony_ci{
2154514f5e3Sopenharmony_ci    ASSERT(InRange(addr));
2164514f5e3Sopenharmony_ci    // Only used for heap verification, so donot need to use lock
2174514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ == nullptr) {
2184514f5e3Sopenharmony_ci        return false;
2194514f5e3Sopenharmony_ci    }
2204514f5e3Sopenharmony_ci    return packedData_.localToShareSet_->TestBit(ToUintPtr(this), addr);
2214514f5e3Sopenharmony_ci}
2224514f5e3Sopenharmony_ci
2234514f5e3Sopenharmony_citemplate <typename Visitor>
2244514f5e3Sopenharmony_ciinline void Region::IterateAllMarkedBits(Visitor visitor) const
2254514f5e3Sopenharmony_ci{
2264514f5e3Sopenharmony_ci    packedData_.markGCBitset_->IterateMarkedBitsConst(
2274514f5e3Sopenharmony_ci        reinterpret_cast<uintptr_t>(this), packedData_.bitsetSize_, visitor);
2284514f5e3Sopenharmony_ci}
2294514f5e3Sopenharmony_ci
2304514f5e3Sopenharmony_ciinline void Region::ClearMarkGCBitset()
2314514f5e3Sopenharmony_ci{
2324514f5e3Sopenharmony_ci    if (packedData_.markGCBitset_ != nullptr) {
2334514f5e3Sopenharmony_ci        packedData_.markGCBitset_->Clear(packedData_.bitsetSize_);
2344514f5e3Sopenharmony_ci    }
2354514f5e3Sopenharmony_ci}
2364514f5e3Sopenharmony_ci
2374514f5e3Sopenharmony_ciinline void Region::InsertCrossRegionRSet(uintptr_t addr)
2384514f5e3Sopenharmony_ci{
2394514f5e3Sopenharmony_ci    auto set = GetOrCreateCrossRegionRememberedSet();
2404514f5e3Sopenharmony_ci    set->Insert(ToUintPtr(this), addr);
2414514f5e3Sopenharmony_ci}
2424514f5e3Sopenharmony_ci
2434514f5e3Sopenharmony_ciinline void Region::AtomicInsertCrossRegionRSet(uintptr_t addr)
2444514f5e3Sopenharmony_ci{
2454514f5e3Sopenharmony_ci    auto set = GetOrCreateCrossRegionRememberedSet();
2464514f5e3Sopenharmony_ci    set->AtomicInsert(ToUintPtr(this), addr);
2474514f5e3Sopenharmony_ci}
2484514f5e3Sopenharmony_ci
2494514f5e3Sopenharmony_ciinline bool Region::HasLocalToShareRememberedSet() const
2504514f5e3Sopenharmony_ci{
2514514f5e3Sopenharmony_ci    return packedData_.localToShareSet_ != nullptr;
2524514f5e3Sopenharmony_ci}
2534514f5e3Sopenharmony_ci
2544514f5e3Sopenharmony_ciinline RememberedSet *Region::ExtractLocalToShareRSet()
2554514f5e3Sopenharmony_ci{
2564514f5e3Sopenharmony_ci    RememberedSet *set = packedData_.localToShareSet_;
2574514f5e3Sopenharmony_ci    packedData_.localToShareSet_ = nullptr;
2584514f5e3Sopenharmony_ci    return set;
2594514f5e3Sopenharmony_ci}
2604514f5e3Sopenharmony_ci
2614514f5e3Sopenharmony_ciinline void Region::InsertLocalToShareRSet(uintptr_t addr)
2624514f5e3Sopenharmony_ci{
2634514f5e3Sopenharmony_ci    auto set = GetOrCreateLocalToShareRememberedSet();
2644514f5e3Sopenharmony_ci    set->Insert(ToUintPtr(this), addr);
2654514f5e3Sopenharmony_ci}
2664514f5e3Sopenharmony_ci
2674514f5e3Sopenharmony_citemplate <Region::RegionSpaceKind kind>
2684514f5e3Sopenharmony_ciRegion::Updater<kind> Region::GetBatchRSetUpdater(uintptr_t addr)
2694514f5e3Sopenharmony_ci{
2704514f5e3Sopenharmony_ci    return Region::Updater<kind>(addr, *this);
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ciinline void Region::AtomicInsertLocalToShareRSet(uintptr_t addr)
2744514f5e3Sopenharmony_ci{
2754514f5e3Sopenharmony_ci    auto set = GetOrCreateLocalToShareRememberedSet();
2764514f5e3Sopenharmony_ci    set->AtomicInsert(ToUintPtr(this), addr);
2774514f5e3Sopenharmony_ci}
2784514f5e3Sopenharmony_ci
2794514f5e3Sopenharmony_ciinline void Region::ClearLocalToShareRSetInRange(uintptr_t start, uintptr_t end)
2804514f5e3Sopenharmony_ci{
2814514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ != nullptr) {
2824514f5e3Sopenharmony_ci        packedData_.localToShareSet_->ClearRange(ToUintPtr(this), start, end);
2834514f5e3Sopenharmony_ci    }
2844514f5e3Sopenharmony_ci}
2854514f5e3Sopenharmony_ci
2864514f5e3Sopenharmony_ciinline void Region::AtomicClearLocalToShareRSetInRange(uintptr_t start, uintptr_t end)
2874514f5e3Sopenharmony_ci{
2884514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ != nullptr) {
2894514f5e3Sopenharmony_ci        packedData_.localToShareSet_->AtomicClearRange(ToUintPtr(this), start, end);
2904514f5e3Sopenharmony_ci    }
2914514f5e3Sopenharmony_ci}
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ciinline void Region::DeleteLocalToShareRSet()
2944514f5e3Sopenharmony_ci{
2954514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ != nullptr) {
2964514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(packedData_.localToShareSet_, packedData_.localToShareSet_->Size());
2974514f5e3Sopenharmony_ci        packedData_.localToShareSet_ = nullptr;
2984514f5e3Sopenharmony_ci    }
2994514f5e3Sopenharmony_ci}
3004514f5e3Sopenharmony_ci
3014514f5e3Sopenharmony_ciinline void Region::AtomicClearSweepingLocalToShareRSetInRange(uintptr_t start, uintptr_t end)
3024514f5e3Sopenharmony_ci{
3034514f5e3Sopenharmony_ci    if (sweepingLocalToShareRSet_ != nullptr) {
3044514f5e3Sopenharmony_ci        sweepingLocalToShareRSet_->AtomicClearRange(ToUintPtr(this), start, end);
3054514f5e3Sopenharmony_ci    }
3064514f5e3Sopenharmony_ci}
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ciinline void Region::DeleteSweepingLocalToShareRSet()
3094514f5e3Sopenharmony_ci{
3104514f5e3Sopenharmony_ci    if (sweepingLocalToShareRSet_!= nullptr) {
3114514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(sweepingLocalToShareRSet_, sweepingLocalToShareRSet_->Size());
3124514f5e3Sopenharmony_ci        sweepingLocalToShareRSet_ = nullptr;
3134514f5e3Sopenharmony_ci    }
3144514f5e3Sopenharmony_ci}
3154514f5e3Sopenharmony_ci
3164514f5e3Sopenharmony_citemplate <typename Visitor>
3174514f5e3Sopenharmony_ciinline void Region::IterateAllLocalToShareBits(Visitor visitor)
3184514f5e3Sopenharmony_ci{
3194514f5e3Sopenharmony_ci    if (packedData_.localToShareSet_ != nullptr) {
3204514f5e3Sopenharmony_ci        packedData_.localToShareSet_->IterateAllMarkedBits(ToUintPtr(this), visitor);
3214514f5e3Sopenharmony_ci    }
3224514f5e3Sopenharmony_ci}
3234514f5e3Sopenharmony_ci
3244514f5e3Sopenharmony_citemplate <typename Visitor>
3254514f5e3Sopenharmony_ciinline void Region::IterateAllCrossRegionBits(Visitor visitor) const
3264514f5e3Sopenharmony_ci{
3274514f5e3Sopenharmony_ci    if (crossRegionSet_ != nullptr) {
3284514f5e3Sopenharmony_ci        crossRegionSet_->IterateAllMarkedBitsConst(ToUintPtr(this), visitor);
3294514f5e3Sopenharmony_ci    }
3304514f5e3Sopenharmony_ci}
3314514f5e3Sopenharmony_ci
3324514f5e3Sopenharmony_ciinline void Region::ClearCrossRegionRSet()
3334514f5e3Sopenharmony_ci{
3344514f5e3Sopenharmony_ci    if (crossRegionSet_ != nullptr) {
3354514f5e3Sopenharmony_ci        crossRegionSet_->ClearAll();
3364514f5e3Sopenharmony_ci    }
3374514f5e3Sopenharmony_ci}
3384514f5e3Sopenharmony_ci
3394514f5e3Sopenharmony_ciinline void Region::ClearCrossRegionRSetInRange(uintptr_t start, uintptr_t end)
3404514f5e3Sopenharmony_ci{
3414514f5e3Sopenharmony_ci    if (crossRegionSet_ != nullptr) {
3424514f5e3Sopenharmony_ci        crossRegionSet_->ClearRange(ToUintPtr(this), start, end);
3434514f5e3Sopenharmony_ci    }
3444514f5e3Sopenharmony_ci}
3454514f5e3Sopenharmony_ci
3464514f5e3Sopenharmony_ciinline void Region::AtomicClearCrossRegionRSetInRange(uintptr_t start, uintptr_t end)
3474514f5e3Sopenharmony_ci{
3484514f5e3Sopenharmony_ci    if (crossRegionSet_ != nullptr) {
3494514f5e3Sopenharmony_ci        crossRegionSet_->AtomicClearRange(ToUintPtr(this), start, end);
3504514f5e3Sopenharmony_ci    }
3514514f5e3Sopenharmony_ci}
3524514f5e3Sopenharmony_ci
3534514f5e3Sopenharmony_ciinline void Region::DeleteCrossRegionRSet()
3544514f5e3Sopenharmony_ci{
3554514f5e3Sopenharmony_ci    if (crossRegionSet_ != nullptr) {
3564514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(crossRegionSet_, crossRegionSet_->Size());
3574514f5e3Sopenharmony_ci        crossRegionSet_ = nullptr;
3584514f5e3Sopenharmony_ci    }
3594514f5e3Sopenharmony_ci}
3604514f5e3Sopenharmony_ci
3614514f5e3Sopenharmony_ciinline void Region::InsertNewToEdenRSet(uintptr_t addr)
3624514f5e3Sopenharmony_ci{
3634514f5e3Sopenharmony_ci    auto set = GetOrCreateNewToEdenRememberedSet();
3644514f5e3Sopenharmony_ci    set->Insert(ToUintPtr(this), addr);
3654514f5e3Sopenharmony_ci}
3664514f5e3Sopenharmony_ci
3674514f5e3Sopenharmony_ciinline void Region::AtomicInsertNewToEdenRSet(uintptr_t addr)
3684514f5e3Sopenharmony_ci{
3694514f5e3Sopenharmony_ci    auto set = GetOrCreateNewToEdenRememberedSet();
3704514f5e3Sopenharmony_ci    set->AtomicInsert(ToUintPtr(this), addr);
3714514f5e3Sopenharmony_ci}
3724514f5e3Sopenharmony_ci
3734514f5e3Sopenharmony_ciinline void Region::ClearNewToEdenRSet(uintptr_t addr)
3744514f5e3Sopenharmony_ci{
3754514f5e3Sopenharmony_ci    auto set = GetOrCreateNewToEdenRememberedSet();
3764514f5e3Sopenharmony_ci    set->ClearBit(ToUintPtr(this), addr);
3774514f5e3Sopenharmony_ci}
3784514f5e3Sopenharmony_ci
3794514f5e3Sopenharmony_ciinline void Region::InsertOldToNewRSet(uintptr_t addr)
3804514f5e3Sopenharmony_ci{
3814514f5e3Sopenharmony_ci    auto set = GetOrCreateOldToNewRememberedSet();
3824514f5e3Sopenharmony_ci    set->Insert(ToUintPtr(this), addr);
3834514f5e3Sopenharmony_ci}
3844514f5e3Sopenharmony_ci
3854514f5e3Sopenharmony_ciinline void Region::ClearOldToNewRSet(uintptr_t addr)
3864514f5e3Sopenharmony_ci{
3874514f5e3Sopenharmony_ci    auto set = GetOrCreateOldToNewRememberedSet();
3884514f5e3Sopenharmony_ci    set->ClearBit(ToUintPtr(this), addr);
3894514f5e3Sopenharmony_ci}
3904514f5e3Sopenharmony_ci
3914514f5e3Sopenharmony_citemplate <typename Visitor>
3924514f5e3Sopenharmony_ciinline void Region::IterateAllNewToEdenBits(Visitor visitor)
3934514f5e3Sopenharmony_ci{
3944514f5e3Sopenharmony_ci    if (packedData_.newToEdenSet_ != nullptr) {
3954514f5e3Sopenharmony_ci        packedData_.newToEdenSet_->IterateAllMarkedBits(ToUintPtr(this), visitor);
3964514f5e3Sopenharmony_ci    }
3974514f5e3Sopenharmony_ci}
3984514f5e3Sopenharmony_ci
3994514f5e3Sopenharmony_citemplate <typename Visitor>
4004514f5e3Sopenharmony_ciinline void Region::IterateAllOldToNewBits(Visitor visitor)
4014514f5e3Sopenharmony_ci{
4024514f5e3Sopenharmony_ci    if (packedData_.oldToNewSet_ != nullptr) {
4034514f5e3Sopenharmony_ci        packedData_.oldToNewSet_->IterateAllMarkedBits(ToUintPtr(this), visitor);
4044514f5e3Sopenharmony_ci    }
4054514f5e3Sopenharmony_ci}
4064514f5e3Sopenharmony_ci
4074514f5e3Sopenharmony_citemplate <typename Visitor>
4084514f5e3Sopenharmony_ciinline void Region::AtomicIterateAllSweepingRSetBits(Visitor visitor)
4094514f5e3Sopenharmony_ci{
4104514f5e3Sopenharmony_ci    if (sweepingOldToNewRSet_ != nullptr) {
4114514f5e3Sopenharmony_ci        sweepingOldToNewRSet_->AtomicIterateAllMarkedBits(ToUintPtr(this), visitor);
4124514f5e3Sopenharmony_ci    }
4134514f5e3Sopenharmony_ci}
4144514f5e3Sopenharmony_ci
4154514f5e3Sopenharmony_citemplate <typename Visitor>
4164514f5e3Sopenharmony_ciinline void Region::IterateAllSweepingRSetBits(Visitor visitor)
4174514f5e3Sopenharmony_ci{
4184514f5e3Sopenharmony_ci    if (sweepingOldToNewRSet_ != nullptr) {
4194514f5e3Sopenharmony_ci        sweepingOldToNewRSet_->IterateAllMarkedBits(ToUintPtr(this), visitor);
4204514f5e3Sopenharmony_ci    }
4214514f5e3Sopenharmony_ci}
4224514f5e3Sopenharmony_ci
4234514f5e3Sopenharmony_ciinline RememberedSet *Region::GetNewToEdenRSet()
4244514f5e3Sopenharmony_ci{
4254514f5e3Sopenharmony_ci    return  packedData_.newToEdenSet_;
4264514f5e3Sopenharmony_ci}
4274514f5e3Sopenharmony_ci
4284514f5e3Sopenharmony_ciinline void Region::ClearNewToEdenRSet()
4294514f5e3Sopenharmony_ci{
4304514f5e3Sopenharmony_ci    if (packedData_.newToEdenSet_ != nullptr) {
4314514f5e3Sopenharmony_ci        packedData_.newToEdenSet_->ClearAll();
4324514f5e3Sopenharmony_ci    }
4334514f5e3Sopenharmony_ci}
4344514f5e3Sopenharmony_ci
4354514f5e3Sopenharmony_ciinline void Region::ClearNewToEdenRSetInRange(uintptr_t start, uintptr_t end)
4364514f5e3Sopenharmony_ci{
4374514f5e3Sopenharmony_ci    if (packedData_.newToEdenSet_ != nullptr) {
4384514f5e3Sopenharmony_ci        packedData_.newToEdenSet_->ClearRange(ToUintPtr(this), start, end);
4394514f5e3Sopenharmony_ci    }
4404514f5e3Sopenharmony_ci}
4414514f5e3Sopenharmony_ci
4424514f5e3Sopenharmony_ciinline void Region::DeleteNewToEdenRSet()
4434514f5e3Sopenharmony_ci{
4444514f5e3Sopenharmony_ci    if (packedData_.newToEdenSet_ != nullptr) {
4454514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(packedData_.newToEdenSet_, packedData_.newToEdenSet_->Size());
4464514f5e3Sopenharmony_ci        packedData_.newToEdenSet_ = nullptr;
4474514f5e3Sopenharmony_ci    }
4484514f5e3Sopenharmony_ci}
4494514f5e3Sopenharmony_ci
4504514f5e3Sopenharmony_ciinline void Region::ClearOldToNewRSet()
4514514f5e3Sopenharmony_ci{
4524514f5e3Sopenharmony_ci    if (packedData_.oldToNewSet_ != nullptr) {
4534514f5e3Sopenharmony_ci        packedData_.oldToNewSet_->ClearAll();
4544514f5e3Sopenharmony_ci    }
4554514f5e3Sopenharmony_ci}
4564514f5e3Sopenharmony_ci
4574514f5e3Sopenharmony_ciinline void Region::ClearOldToNewRSetInRange(uintptr_t start, uintptr_t end)
4584514f5e3Sopenharmony_ci{
4594514f5e3Sopenharmony_ci    if (packedData_.oldToNewSet_ != nullptr) {
4604514f5e3Sopenharmony_ci        packedData_.oldToNewSet_->ClearRange(ToUintPtr(this), start, end);
4614514f5e3Sopenharmony_ci    }
4624514f5e3Sopenharmony_ci}
4634514f5e3Sopenharmony_ci
4644514f5e3Sopenharmony_ciinline void Region::DeleteOldToNewRSet()
4654514f5e3Sopenharmony_ci{
4664514f5e3Sopenharmony_ci    if (packedData_.oldToNewSet_ != nullptr) {
4674514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(packedData_.oldToNewSet_, packedData_.oldToNewSet_->Size());
4684514f5e3Sopenharmony_ci        packedData_.oldToNewSet_ = nullptr;
4694514f5e3Sopenharmony_ci    }
4704514f5e3Sopenharmony_ci}
4714514f5e3Sopenharmony_ci
4724514f5e3Sopenharmony_ciinline void Region::AtomicClearSweepingOldToNewRSetInRange(uintptr_t start, uintptr_t end)
4734514f5e3Sopenharmony_ci{
4744514f5e3Sopenharmony_ci    if (sweepingOldToNewRSet_ != nullptr) {
4754514f5e3Sopenharmony_ci        sweepingOldToNewRSet_->AtomicClearRange(ToUintPtr(this), start, end);
4764514f5e3Sopenharmony_ci    }
4774514f5e3Sopenharmony_ci}
4784514f5e3Sopenharmony_ci
4794514f5e3Sopenharmony_ciinline void Region::ClearSweepingOldToNewRSetInRange(uintptr_t start, uintptr_t end)
4804514f5e3Sopenharmony_ci{
4814514f5e3Sopenharmony_ci    if (sweepingOldToNewRSet_ != nullptr) {
4824514f5e3Sopenharmony_ci        sweepingOldToNewRSet_->ClearRange(ToUintPtr(this), start, end);
4834514f5e3Sopenharmony_ci    }
4844514f5e3Sopenharmony_ci}
4854514f5e3Sopenharmony_ci
4864514f5e3Sopenharmony_ciinline void Region::DeleteSweepingOldToNewRSet()
4874514f5e3Sopenharmony_ci{
4884514f5e3Sopenharmony_ci    if (sweepingOldToNewRSet_ != nullptr) {
4894514f5e3Sopenharmony_ci        nativeAreaAllocator_->Free(sweepingOldToNewRSet_, sweepingOldToNewRSet_->Size());
4904514f5e3Sopenharmony_ci        sweepingOldToNewRSet_ = nullptr;
4914514f5e3Sopenharmony_ci    }
4924514f5e3Sopenharmony_ci}
4934514f5e3Sopenharmony_ci
4944514f5e3Sopenharmony_ciinline uint8_t Region::GetRegionSpaceFlag()
4954514f5e3Sopenharmony_ci{
4964514f5e3Sopenharmony_ci    return packedData_.flags_.spaceFlag_;
4974514f5e3Sopenharmony_ci}
4984514f5e3Sopenharmony_ci
4994514f5e3Sopenharmony_citemplate <Region::RegionSpaceKind kind>
5004514f5e3Sopenharmony_ciARK_INLINE void Region::Updater<kind>::Flush()
5014514f5e3Sopenharmony_ci{
5024514f5e3Sopenharmony_ci    uintptr_t updateAddress = 0;
5034514f5e3Sopenharmony_ci    std::array<std::bitset<GCBitset::BIT_PER_WORD>, BitSetNum> bitsets = bitsetUpdater_.GetAndResetAll(updateAddress);
5044514f5e3Sopenharmony_ci    for (size_t idx = 0; idx < BitSetNum; idx++) {
5054514f5e3Sopenharmony_ci        if (bitsets[idx].none()) {
5064514f5e3Sopenharmony_ci            continue;
5074514f5e3Sopenharmony_ci        }
5084514f5e3Sopenharmony_ci        Consume(idx, updateAddress, static_cast<uint32_t>(bitsets[idx].to_ulong()));
5094514f5e3Sopenharmony_ci    }
5104514f5e3Sopenharmony_ci}
5114514f5e3Sopenharmony_ci
5124514f5e3Sopenharmony_citemplate <Region::RegionSpaceKind kind>
5134514f5e3Sopenharmony_ciARK_INLINE void Region::Updater<kind>::Consume(size_t idx, uintptr_t updateAddress, uint32_t mask)
5144514f5e3Sopenharmony_ci{
5154514f5e3Sopenharmony_ci    if (idx == LocalToShareIdx) {
5164514f5e3Sopenharmony_ci        auto set = region_.GetOrCreateLocalToShareRememberedSet();
5174514f5e3Sopenharmony_ci        set->InsertRange(ToUintPtr(&region_), updateAddress, mask);
5184514f5e3Sopenharmony_ci    }
5194514f5e3Sopenharmony_ci    if (kind == InYoung && idx == NewToEdenIdx) {
5204514f5e3Sopenharmony_ci        auto set = region_.GetOrCreateNewToEdenRememberedSet();
5214514f5e3Sopenharmony_ci        set->InsertRange(ToUintPtr(&region_), updateAddress, mask);
5224514f5e3Sopenharmony_ci    }
5234514f5e3Sopenharmony_ci    if (kind == InGeneralOld && idx == OldToNewIdx) {
5244514f5e3Sopenharmony_ci        auto set = region_.GetOrCreateOldToNewRememberedSet();
5254514f5e3Sopenharmony_ci        set->InsertRange(ToUintPtr(&region_), updateAddress, mask);
5264514f5e3Sopenharmony_ci    }
5274514f5e3Sopenharmony_ci}
5284514f5e3Sopenharmony_ci
5294514f5e3Sopenharmony_ci} // namespace panda::ecmascript
5304514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_MEM_REGION_INL_H
531