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(®ion_), updateAddress, mask); 5184514f5e3Sopenharmony_ci } 5194514f5e3Sopenharmony_ci if (kind == InYoung && idx == NewToEdenIdx) { 5204514f5e3Sopenharmony_ci auto set = region_.GetOrCreateNewToEdenRememberedSet(); 5214514f5e3Sopenharmony_ci set->InsertRange(ToUintPtr(®ion_), updateAddress, mask); 5224514f5e3Sopenharmony_ci } 5234514f5e3Sopenharmony_ci if (kind == InGeneralOld && idx == OldToNewIdx) { 5244514f5e3Sopenharmony_ci auto set = region_.GetOrCreateOldToNewRememberedSet(); 5254514f5e3Sopenharmony_ci set->InsertRange(ToUintPtr(®ion_), updateAddress, mask); 5264514f5e3Sopenharmony_ci } 5274514f5e3Sopenharmony_ci} 5284514f5e3Sopenharmony_ci 5294514f5e3Sopenharmony_ci} // namespace panda::ecmascript 5304514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_REGION_INL_H 531