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_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_REGION_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include <type_traits>
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ci#include "ecmascript/base/aligned_struct.h"
224514f5e3Sopenharmony_ci#include "ecmascript/base/asan_interface.h"
234514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h"
244514f5e3Sopenharmony_ci#include "ecmascript/mem/free_object_list.h"
254514f5e3Sopenharmony_ci#include "ecmascript/mem/gc_bitset.h"
264514f5e3Sopenharmony_ci#include "ecmascript/mem/remembered_set.h"
274514f5e3Sopenharmony_ci#include "ecmascript/mem/mem_common.h"
284514f5e3Sopenharmony_ci#include "ecmascript/platform/map.h"
294514f5e3Sopenharmony_ci
304514f5e3Sopenharmony_ci#include "ecmascript/platform/mutex.h"
314514f5e3Sopenharmony_ci
324514f5e3Sopenharmony_ci#include "securec.h"
334514f5e3Sopenharmony_ci
344514f5e3Sopenharmony_cinamespace panda {
354514f5e3Sopenharmony_cinamespace ecmascript {
364514f5e3Sopenharmony_ciclass JSThread;
374514f5e3Sopenharmony_ci
384514f5e3Sopenharmony_cienum RegionSpaceFlag {
394514f5e3Sopenharmony_ci    UNINITIALIZED = 0,
404514f5e3Sopenharmony_ci    // We should avoid using the lower 3 bits (bits 0 to 2).
414514f5e3Sopenharmony_ci    // If ZAP_MEM is enabled, the value of the lower 3 bits conflicts with the INVALID_VALUE.
424514f5e3Sopenharmony_ci
434514f5e3Sopenharmony_ci    // Bits 3 to 7 are reserved to denote the space where the region is located.
444514f5e3Sopenharmony_ci    IN_EDEN_SPACE = 0x08,
454514f5e3Sopenharmony_ci    IN_YOUNG_SPACE = 0x09,
464514f5e3Sopenharmony_ci    IN_SNAPSHOT_SPACE = 0x0A,
474514f5e3Sopenharmony_ci    IN_HUGE_OBJECT_SPACE = 0x0B,
484514f5e3Sopenharmony_ci    IN_OLD_SPACE = 0x0C,
494514f5e3Sopenharmony_ci    IN_NON_MOVABLE_SPACE = 0x0D,
504514f5e3Sopenharmony_ci    IN_MACHINE_CODE_SPACE = 0x0E,
514514f5e3Sopenharmony_ci    IN_READ_ONLY_SPACE = 0X0F,
524514f5e3Sopenharmony_ci    IN_APPSPAWN_SPACE = 0x10,
534514f5e3Sopenharmony_ci    IN_HUGE_MACHINE_CODE_SPACE = 0x11,
544514f5e3Sopenharmony_ci    IN_SHARED_NON_MOVABLE = 0x12,
554514f5e3Sopenharmony_ci    IN_SHARED_OLD_SPACE = 0x13,
564514f5e3Sopenharmony_ci    IN_SHARED_APPSPAWN_SPACE = 0X14,
574514f5e3Sopenharmony_ci    IN_SHARED_HUGE_OBJECT_SPACE = 0x15,
584514f5e3Sopenharmony_ci    IN_SHARED_READ_ONLY_SPACE = 0x16,
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ci    VALID_SPACE_MASK = 0xFF,
614514f5e3Sopenharmony_ci
624514f5e3Sopenharmony_ci    GENERAL_YOUNG_BEGIN = IN_EDEN_SPACE,
634514f5e3Sopenharmony_ci    GENERAL_YOUNG_END = IN_YOUNG_SPACE,
644514f5e3Sopenharmony_ci    GENERAL_OLD_BEGIN = IN_SNAPSHOT_SPACE,
654514f5e3Sopenharmony_ci    GENERAL_OLD_END = IN_HUGE_MACHINE_CODE_SPACE,
664514f5e3Sopenharmony_ci    SHARED_SPACE_BEGIN = IN_SHARED_NON_MOVABLE,
674514f5e3Sopenharmony_ci    SHARED_SPACE_END = IN_SHARED_READ_ONLY_SPACE,
684514f5e3Sopenharmony_ci    SHARED_SWEEPABLE_SPACE_BEGIN = IN_SHARED_NON_MOVABLE,
694514f5e3Sopenharmony_ci    SHARED_SWEEPABLE_SPACE_END = IN_SHARED_HUGE_OBJECT_SPACE,
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ci    HEAP_SPACE_BEGIN = IN_EDEN_SPACE,
724514f5e3Sopenharmony_ci    HEAP_SPACE_END = IN_SHARED_READ_ONLY_SPACE
734514f5e3Sopenharmony_ci};
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_cienum RegionGCFlags {
764514f5e3Sopenharmony_ci    // We should avoid using the lower 3 bits (bits 0 to 2).
774514f5e3Sopenharmony_ci    // If ZAP_MEM is enabled, the value of the lower 3 bits conflicts with the INVALID_VALUE.
784514f5e3Sopenharmony_ci
794514f5e3Sopenharmony_ci    // Below flags are used for GC, and each flag has a dedicated bit starting from the 3rd bit.
804514f5e3Sopenharmony_ci    NEVER_EVACUATE = 1 << 3,
814514f5e3Sopenharmony_ci    HAS_AGE_MARK = 1 << 4,
824514f5e3Sopenharmony_ci    BELOW_AGE_MARK = 1 << 5,
834514f5e3Sopenharmony_ci    IN_COLLECT_SET = 1 << 6,
844514f5e3Sopenharmony_ci    IN_NEW_TO_NEW_SET = 1 << 7,
854514f5e3Sopenharmony_ci    // Bits 8 to 10 (the lower 3 bits for the next byte) are also excluded for the sake of
864514f5e3Sopenharmony_ci    // INVALID_VALUE in ZAP_MEM.
874514f5e3Sopenharmony_ci    HAS_BEEN_SWEPT = 1 << 11,
884514f5e3Sopenharmony_ci    NEED_RELOCATE = 1 << 12,
894514f5e3Sopenharmony_ci    // ONLY used for heap verification.
904514f5e3Sopenharmony_ci    IN_INACTIVE_SEMI_SPACE = 1 << 13,
914514f5e3Sopenharmony_ci};
924514f5e3Sopenharmony_ci
934514f5e3Sopenharmony_ci// Currently only use for region in LinearSpace, to check if the region is allocated during concurrent marking.
944514f5e3Sopenharmony_cienum class RegionTypeFlag : uint8_t {
954514f5e3Sopenharmony_ci    DEFAULT = 0,
964514f5e3Sopenharmony_ci    // We should avoid using the lower 3 bits (bits 0 to 2).
974514f5e3Sopenharmony_ci    // If ZAP_MEM is enabled, the value of the lower 3 bits conflicts with the INVALID_VALUE.
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ci    // Region is allocated before concurrent marking, but some new object may be allocated here
1004514f5e3Sopenharmony_ci    // during concurrent marking.
1014514f5e3Sopenharmony_ci    HALF_FRESH = 0x08,
1024514f5e3Sopenharmony_ci    // Region is allocated during concurrent marking.
1034514f5e3Sopenharmony_ci    FRESH = 0x09,
1044514f5e3Sopenharmony_ci};
1054514f5e3Sopenharmony_ci
1064514f5e3Sopenharmony_cienum RSetType {
1074514f5e3Sopenharmony_ci    OLD_TO_NEW,
1084514f5e3Sopenharmony_ci    LOCAL_TO_SHARE,
1094514f5e3Sopenharmony_ci};
1104514f5e3Sopenharmony_ci
1114514f5e3Sopenharmony_cistatic inline std::string ToSpaceTypeName(uint8_t space)
1124514f5e3Sopenharmony_ci{
1134514f5e3Sopenharmony_ci    switch (space) {
1144514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_EDEN_SPACE:
1154514f5e3Sopenharmony_ci            return "eden space";
1164514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_YOUNG_SPACE:
1174514f5e3Sopenharmony_ci            return "young space";
1184514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_SNAPSHOT_SPACE:
1194514f5e3Sopenharmony_ci            return "snapshot space";
1204514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_HUGE_OBJECT_SPACE:
1214514f5e3Sopenharmony_ci            return "huge object space";
1224514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_OLD_SPACE:
1234514f5e3Sopenharmony_ci            return "old space";
1244514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_NON_MOVABLE_SPACE:
1254514f5e3Sopenharmony_ci            return "non movable space";
1264514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_MACHINE_CODE_SPACE:
1274514f5e3Sopenharmony_ci            return "machine code space";
1284514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_READ_ONLY_SPACE:
1294514f5e3Sopenharmony_ci            return "read only space";
1304514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_APPSPAWN_SPACE:
1314514f5e3Sopenharmony_ci            return "appspawn space";
1324514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_HUGE_MACHINE_CODE_SPACE:
1334514f5e3Sopenharmony_ci            return "huge machine code space";
1344514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_SHARED_NON_MOVABLE:
1354514f5e3Sopenharmony_ci            return "shared non movable space";
1364514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_SHARED_OLD_SPACE:
1374514f5e3Sopenharmony_ci            return "shared old space";
1384514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_SHARED_READ_ONLY_SPACE:
1394514f5e3Sopenharmony_ci            return "shared read only space";
1404514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_SHARED_HUGE_OBJECT_SPACE:
1414514f5e3Sopenharmony_ci            return "shared huge object space";
1424514f5e3Sopenharmony_ci        case RegionSpaceFlag::IN_SHARED_APPSPAWN_SPACE:
1434514f5e3Sopenharmony_ci            return "shared appspawn space";
1444514f5e3Sopenharmony_ci        default:
1454514f5e3Sopenharmony_ci            return "invalid space";
1464514f5e3Sopenharmony_ci    }
1474514f5e3Sopenharmony_ci}
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_ci// |---------------------------------------------------------------------------------------|
1504514f5e3Sopenharmony_ci// |                                   Region (256 kb)                                     |
1514514f5e3Sopenharmony_ci// |---------------------------------|--------------------------------|--------------------|
1524514f5e3Sopenharmony_ci// |     Head (sizeof(Region))       |         Mark bitset (4kb)      |      Data          |
1534514f5e3Sopenharmony_ci// |---------------------------------|--------------------------------|--------------------|
1544514f5e3Sopenharmony_ci
1554514f5e3Sopenharmony_ciclass Region {
1564514f5e3Sopenharmony_cipublic:
1574514f5e3Sopenharmony_ci    Region(NativeAreaAllocator *allocator, uintptr_t allocateBase, uintptr_t begin, uintptr_t end,
1584514f5e3Sopenharmony_ci        RegionSpaceFlag spaceType, RegionTypeFlag typeFlag)
1594514f5e3Sopenharmony_ci        : packedData_(begin, end, spaceType, typeFlag),
1604514f5e3Sopenharmony_ci          nativeAreaAllocator_(allocator),
1614514f5e3Sopenharmony_ci          allocateBase_(allocateBase),
1624514f5e3Sopenharmony_ci          end_(end),
1634514f5e3Sopenharmony_ci          highWaterMark_(end),
1644514f5e3Sopenharmony_ci          aliveObject_(0),
1654514f5e3Sopenharmony_ci          wasted_(0),
1664514f5e3Sopenharmony_ci          snapshotData_(0) {}
1674514f5e3Sopenharmony_ci
1684514f5e3Sopenharmony_ci    // JitFort space is divided into regions (JitForRegion) to enable
1694514f5e3Sopenharmony_ci    // reusing free_object_list and free_object_set operations for
1704514f5e3Sopenharmony_ci    // JitFort space, and GC marking actually happens in corresponding
1714514f5e3Sopenharmony_ci    // MachineCode objects where JitFort space is allocated to. So no
1724514f5e3Sopenharmony_ci    // gc mark bits needed in JitFortRegions.
1734514f5e3Sopenharmony_ci    Region(NativeAreaAllocator *allocator, uintptr_t allocateBase, uintptr_t end,
1744514f5e3Sopenharmony_ci        RegionSpaceFlag spaceType)
1754514f5e3Sopenharmony_ci        : packedData_(allocateBase, spaceType), // no markGCBitset_ for JitFort
1764514f5e3Sopenharmony_ci          nativeAreaAllocator_(allocator),
1774514f5e3Sopenharmony_ci          allocateBase_(allocateBase),
1784514f5e3Sopenharmony_ci          end_(end),
1794514f5e3Sopenharmony_ci          highWaterMark_(end),
1804514f5e3Sopenharmony_ci          aliveObject_(0),
1814514f5e3Sopenharmony_ci          wasted_(0),
1824514f5e3Sopenharmony_ci          snapshotData_(0) {}
1834514f5e3Sopenharmony_ci
1844514f5e3Sopenharmony_ci    ~Region() = default;
1854514f5e3Sopenharmony_ci
1864514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(Region);
1874514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(Region);
1884514f5e3Sopenharmony_ci
1894514f5e3Sopenharmony_ci    enum RegionSpaceKind { InYoung, InGeneralOld, Other };
1904514f5e3Sopenharmony_ci
1914514f5e3Sopenharmony_ci    template <RegionSpaceKind kind>
1924514f5e3Sopenharmony_ci    class Updater final {
1934514f5e3Sopenharmony_ci    public:
1944514f5e3Sopenharmony_ci        Updater(uintptr_t updateAddress, Region& region)
1954514f5e3Sopenharmony_ci            : bitsetUpdater_(updateAddress),
1964514f5e3Sopenharmony_ci              region_(region)
1974514f5e3Sopenharmony_ci        {
1984514f5e3Sopenharmony_ci        }
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci        NO_COPY_SEMANTIC(Updater);
2014514f5e3Sopenharmony_ci
2024514f5e3Sopenharmony_ci        ARK_INLINE ~Updater()
2034514f5e3Sopenharmony_ci        {
2044514f5e3Sopenharmony_ci            Flush();
2054514f5e3Sopenharmony_ci        }
2064514f5e3Sopenharmony_ci
2074514f5e3Sopenharmony_ci        ARK_INLINE void UpdateLocalToShare()
2084514f5e3Sopenharmony_ci        {
2094514f5e3Sopenharmony_ci            bitsetUpdater_.Update(LocalToShareIdx);
2104514f5e3Sopenharmony_ci        }
2114514f5e3Sopenharmony_ci
2124514f5e3Sopenharmony_ci        template <RegionSpaceKind T = kind, std::enable_if_t<T == InYoung, int>  = 0>
2134514f5e3Sopenharmony_ci        ARK_INLINE void UpdateNewToEden()
2144514f5e3Sopenharmony_ci        {
2154514f5e3Sopenharmony_ci            bitsetUpdater_.Update(NewToEdenIdx);
2164514f5e3Sopenharmony_ci        }
2174514f5e3Sopenharmony_ci
2184514f5e3Sopenharmony_ci        template <RegionSpaceKind T = kind, std::enable_if_t<T == InGeneralOld, int>  = 0>
2194514f5e3Sopenharmony_ci        ARK_INLINE void UpdateOldToNew()
2204514f5e3Sopenharmony_ci        {
2214514f5e3Sopenharmony_ci            bitsetUpdater_.Update(OldToNewIdx);
2224514f5e3Sopenharmony_ci        }
2234514f5e3Sopenharmony_ci
2244514f5e3Sopenharmony_ci        ARK_INLINE void Next()
2254514f5e3Sopenharmony_ci        {
2264514f5e3Sopenharmony_ci            if (bitsetUpdater_.Next()) {
2274514f5e3Sopenharmony_ci                Flush();
2284514f5e3Sopenharmony_ci            }
2294514f5e3Sopenharmony_ci        }
2304514f5e3Sopenharmony_ci
2314514f5e3Sopenharmony_ci    private:
2324514f5e3Sopenharmony_ci        ARK_INLINE void Consume(size_t idx, uintptr_t updateAddress, uint32_t mask);
2334514f5e3Sopenharmony_ci
2344514f5e3Sopenharmony_ci        ARK_INLINE void Flush();
2354514f5e3Sopenharmony_ci
2364514f5e3Sopenharmony_ci        static constexpr size_t CalculateBitSetNum()
2374514f5e3Sopenharmony_ci        {
2384514f5e3Sopenharmony_ci            constexpr size_t InYoungBitSetNum = 2;
2394514f5e3Sopenharmony_ci            constexpr size_t InGeneralOldBitSetNum = 2;
2404514f5e3Sopenharmony_ci            constexpr size_t OtherBitSetNum = 1;
2414514f5e3Sopenharmony_ci            switch (kind) {
2424514f5e3Sopenharmony_ci                case InYoung:
2434514f5e3Sopenharmony_ci                    return InYoungBitSetNum;
2444514f5e3Sopenharmony_ci                case InGeneralOld:
2454514f5e3Sopenharmony_ci                    return InGeneralOldBitSetNum;
2464514f5e3Sopenharmony_ci                case Other:
2474514f5e3Sopenharmony_ci                    return OtherBitSetNum;
2484514f5e3Sopenharmony_ci            }
2494514f5e3Sopenharmony_ci            return 0;
2504514f5e3Sopenharmony_ci        }
2514514f5e3Sopenharmony_ci
2524514f5e3Sopenharmony_ci        static constexpr size_t BitSetNum = CalculateBitSetNum();
2534514f5e3Sopenharmony_ci        static constexpr size_t LocalToShareIdx = 0;
2544514f5e3Sopenharmony_ci        static constexpr size_t NewToEdenIdx = 1; // NewToEden and OldToNew can't be used at same time.
2554514f5e3Sopenharmony_ci        static constexpr size_t OldToNewIdx = 1;
2564514f5e3Sopenharmony_ci        GCBitSetUpdater<BitSetNum> bitsetUpdater_;
2574514f5e3Sopenharmony_ci        Region& region_;
2584514f5e3Sopenharmony_ci    };
2594514f5e3Sopenharmony_ci
2604514f5e3Sopenharmony_ci    void Initialize()
2614514f5e3Sopenharmony_ci    {
2624514f5e3Sopenharmony_ci        lock_ = new Mutex();
2634514f5e3Sopenharmony_ci        if (InSparseSpace()) {
2644514f5e3Sopenharmony_ci            InitializeFreeObjectSets();
2654514f5e3Sopenharmony_ci        }
2664514f5e3Sopenharmony_ci    }
2674514f5e3Sopenharmony_ci
2684514f5e3Sopenharmony_ci    void LinkNext(Region *next)
2694514f5e3Sopenharmony_ci    {
2704514f5e3Sopenharmony_ci        next_ = next;
2714514f5e3Sopenharmony_ci    }
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ci    Region *GetNext() const
2744514f5e3Sopenharmony_ci    {
2754514f5e3Sopenharmony_ci        return next_;
2764514f5e3Sopenharmony_ci    }
2774514f5e3Sopenharmony_ci
2784514f5e3Sopenharmony_ci    void LinkPrev(Region *prev)
2794514f5e3Sopenharmony_ci    {
2804514f5e3Sopenharmony_ci        prev_ = prev;
2814514f5e3Sopenharmony_ci    }
2824514f5e3Sopenharmony_ci
2834514f5e3Sopenharmony_ci    Region *GetPrev() const
2844514f5e3Sopenharmony_ci    {
2854514f5e3Sopenharmony_ci        return prev_;
2864514f5e3Sopenharmony_ci    }
2874514f5e3Sopenharmony_ci
2884514f5e3Sopenharmony_ci    uintptr_t GetBegin() const
2894514f5e3Sopenharmony_ci    {
2904514f5e3Sopenharmony_ci        return packedData_.begin_;
2914514f5e3Sopenharmony_ci    }
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ci    uintptr_t GetEnd() const
2944514f5e3Sopenharmony_ci    {
2954514f5e3Sopenharmony_ci        return end_;
2964514f5e3Sopenharmony_ci    }
2974514f5e3Sopenharmony_ci
2984514f5e3Sopenharmony_ci    uintptr_t GetHighWaterMark() const
2994514f5e3Sopenharmony_ci    {
3004514f5e3Sopenharmony_ci        return highWaterMark_;
3014514f5e3Sopenharmony_ci    }
3024514f5e3Sopenharmony_ci
3034514f5e3Sopenharmony_ci    size_t GetCapacity() const
3044514f5e3Sopenharmony_ci    {
3054514f5e3Sopenharmony_ci        return end_ - allocateBase_;
3064514f5e3Sopenharmony_ci    }
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ci    size_t GetSize() const
3094514f5e3Sopenharmony_ci    {
3104514f5e3Sopenharmony_ci        return end_ - packedData_.begin_;
3114514f5e3Sopenharmony_ci    }
3124514f5e3Sopenharmony_ci
3134514f5e3Sopenharmony_ci    bool IsGCFlagSet(RegionGCFlags flag) const
3144514f5e3Sopenharmony_ci    {
3154514f5e3Sopenharmony_ci        return (packedData_.flags_.gcFlags_ & flag) == flag;
3164514f5e3Sopenharmony_ci    }
3174514f5e3Sopenharmony_ci
3184514f5e3Sopenharmony_ci    void SetGCFlag(RegionGCFlags flag)
3194514f5e3Sopenharmony_ci    {
3204514f5e3Sopenharmony_ci        packedData_.flags_.gcFlags_ |= flag;
3214514f5e3Sopenharmony_ci    }
3224514f5e3Sopenharmony_ci
3234514f5e3Sopenharmony_ci    void ClearGCFlag(RegionGCFlags flag)
3244514f5e3Sopenharmony_ci    {
3254514f5e3Sopenharmony_ci        // NOLINTNEXTLINE(hicpp-signed-bitwise)
3264514f5e3Sopenharmony_ci        packedData_.flags_.gcFlags_ &= ~flag;
3274514f5e3Sopenharmony_ci    }
3284514f5e3Sopenharmony_ci
3294514f5e3Sopenharmony_ci    std::string GetSpaceTypeName()
3304514f5e3Sopenharmony_ci    {
3314514f5e3Sopenharmony_ci        return ToSpaceTypeName(packedData_.flags_.spaceFlag_);
3324514f5e3Sopenharmony_ci    }
3334514f5e3Sopenharmony_ci
3344514f5e3Sopenharmony_ci    uint8_t GetSpaceType() const
3354514f5e3Sopenharmony_ci    {
3364514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_;
3374514f5e3Sopenharmony_ci    }
3384514f5e3Sopenharmony_ci
3394514f5e3Sopenharmony_ci    // Mark bitset
3404514f5e3Sopenharmony_ci    GCBitset *GetMarkGCBitset() const;
3414514f5e3Sopenharmony_ci    bool AtomicMark(void *address);
3424514f5e3Sopenharmony_ci    // Objects in fresh region should only mark in JS Thread.
3434514f5e3Sopenharmony_ci    bool NonAtomicMark(void *address);
3444514f5e3Sopenharmony_ci    void ClearMark(void *address);
3454514f5e3Sopenharmony_ci    bool Test(void *addr) const;
3464514f5e3Sopenharmony_ci    bool Test(uintptr_t addr) const;
3474514f5e3Sopenharmony_ci    // ONLY used for heap verification.
3484514f5e3Sopenharmony_ci    bool TestNewToEden(uintptr_t addr);
3494514f5e3Sopenharmony_ci    bool TestOldToNew(uintptr_t addr);
3504514f5e3Sopenharmony_ci    bool TestLocalToShare(uintptr_t addr);
3514514f5e3Sopenharmony_ci    template <typename Visitor>
3524514f5e3Sopenharmony_ci    void IterateAllMarkedBits(Visitor visitor) const;
3534514f5e3Sopenharmony_ci    void ClearMarkGCBitset();
3544514f5e3Sopenharmony_ci    // local to share remembered set
3554514f5e3Sopenharmony_ci    bool HasLocalToShareRememberedSet() const;
3564514f5e3Sopenharmony_ci    RememberedSet *ExtractLocalToShareRSet();
3574514f5e3Sopenharmony_ci    void InsertLocalToShareRSet(uintptr_t addr);
3584514f5e3Sopenharmony_ci    template<RegionSpaceKind kind>
3594514f5e3Sopenharmony_ci    Updater<kind> GetBatchRSetUpdater(uintptr_t addr);
3604514f5e3Sopenharmony_ci    void AtomicInsertLocalToShareRSet(uintptr_t addr);
3614514f5e3Sopenharmony_ci    void ClearLocalToShareRSetInRange(uintptr_t start, uintptr_t end);
3624514f5e3Sopenharmony_ci    void AtomicClearLocalToShareRSetInRange(uintptr_t start, uintptr_t end);
3634514f5e3Sopenharmony_ci    void AtomicClearSweepingLocalToShareRSetInRange(uintptr_t start, uintptr_t end);
3644514f5e3Sopenharmony_ci    template <typename Visitor>
3654514f5e3Sopenharmony_ci    void IterateAllLocalToShareBits(Visitor visitor);
3664514f5e3Sopenharmony_ci    void DeleteLocalToShareRSet();
3674514f5e3Sopenharmony_ci    void DeleteSweepingLocalToShareRSet();
3684514f5e3Sopenharmony_ci    // Cross region remembered set
3694514f5e3Sopenharmony_ci    void InsertCrossRegionRSet(uintptr_t addr);
3704514f5e3Sopenharmony_ci    void AtomicInsertCrossRegionRSet(uintptr_t addr);
3714514f5e3Sopenharmony_ci    template <typename Visitor>
3724514f5e3Sopenharmony_ci    void IterateAllCrossRegionBits(Visitor visitor) const;
3734514f5e3Sopenharmony_ci    void ClearCrossRegionRSet();
3744514f5e3Sopenharmony_ci    void ClearCrossRegionRSetInRange(uintptr_t start, uintptr_t end);
3754514f5e3Sopenharmony_ci    void AtomicClearCrossRegionRSetInRange(uintptr_t start, uintptr_t end);
3764514f5e3Sopenharmony_ci    void DeleteCrossRegionRSet();
3774514f5e3Sopenharmony_ci    // New to eden remembered set
3784514f5e3Sopenharmony_ci    void InsertNewToEdenRSet(uintptr_t addr);
3794514f5e3Sopenharmony_ci    void AtomicInsertNewToEdenRSet(uintptr_t addr);
3804514f5e3Sopenharmony_ci    void ClearNewToEdenRSet(uintptr_t addr);
3814514f5e3Sopenharmony_ci    // Old to new remembered set
3824514f5e3Sopenharmony_ci    void InsertOldToNewRSet(uintptr_t addr);
3834514f5e3Sopenharmony_ci    void ClearOldToNewRSet(uintptr_t addr);
3844514f5e3Sopenharmony_ci
3854514f5e3Sopenharmony_ci    template <typename Visitor>
3864514f5e3Sopenharmony_ci    void IterateAllNewToEdenBits(Visitor visitor);
3874514f5e3Sopenharmony_ci    template <typename Visitor>
3884514f5e3Sopenharmony_ci    void IterateAllOldToNewBits(Visitor visitor);
3894514f5e3Sopenharmony_ci    RememberedSet* GetNewToEdenRSet();
3904514f5e3Sopenharmony_ci    void ClearNewToEdenRSet();
3914514f5e3Sopenharmony_ci    void ClearNewToEdenRSetInRange(uintptr_t start, uintptr_t end);
3924514f5e3Sopenharmony_ci    void DeleteNewToEdenRSet();
3934514f5e3Sopenharmony_ci    void ClearOldToNewRSet();
3944514f5e3Sopenharmony_ci    void ClearOldToNewRSetInRange(uintptr_t start, uintptr_t end);
3954514f5e3Sopenharmony_ci    void DeleteOldToNewRSet();
3964514f5e3Sopenharmony_ci
3974514f5e3Sopenharmony_ci    void AtomicClearSweepingOldToNewRSetInRange(uintptr_t start, uintptr_t end);
3984514f5e3Sopenharmony_ci    void ClearSweepingOldToNewRSetInRange(uintptr_t start, uintptr_t end);
3994514f5e3Sopenharmony_ci    void DeleteSweepingOldToNewRSet();
4004514f5e3Sopenharmony_ci    template <typename Visitor>
4014514f5e3Sopenharmony_ci    void AtomicIterateAllSweepingRSetBits(Visitor visitor);
4024514f5e3Sopenharmony_ci    template <typename Visitor>
4034514f5e3Sopenharmony_ci    void IterateAllSweepingRSetBits(Visitor visitor);
4044514f5e3Sopenharmony_ci
4054514f5e3Sopenharmony_ci    static Region *ObjectAddressToRange(TaggedObject *obj)
4064514f5e3Sopenharmony_ci    {
4074514f5e3Sopenharmony_ci        return reinterpret_cast<Region *>(ToUintPtr(obj) & ~DEFAULT_REGION_MASK);
4084514f5e3Sopenharmony_ci    }
4094514f5e3Sopenharmony_ci
4104514f5e3Sopenharmony_ci    static Region *ObjectAddressToRange(uintptr_t objAddress)
4114514f5e3Sopenharmony_ci    {
4124514f5e3Sopenharmony_ci        return reinterpret_cast<Region *>(objAddress & ~DEFAULT_REGION_MASK);
4134514f5e3Sopenharmony_ci    }
4144514f5e3Sopenharmony_ci
4154514f5e3Sopenharmony_ci    static size_t GetRegionAvailableSize()
4164514f5e3Sopenharmony_ci    {
4174514f5e3Sopenharmony_ci        size_t regionHeaderSize = AlignUp(sizeof(Region), static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
4184514f5e3Sopenharmony_ci        size_t bitsetSize = GCBitset::SizeOfGCBitset(DEFAULT_REGION_SIZE - regionHeaderSize);
4194514f5e3Sopenharmony_ci        return DEFAULT_REGION_SIZE - regionHeaderSize - bitsetSize;
4204514f5e3Sopenharmony_ci    }
4214514f5e3Sopenharmony_ci
4224514f5e3Sopenharmony_ci    void ClearMembers()
4234514f5e3Sopenharmony_ci    {
4244514f5e3Sopenharmony_ci        if (lock_ != nullptr) {
4254514f5e3Sopenharmony_ci            delete lock_;
4264514f5e3Sopenharmony_ci            lock_ = nullptr;
4274514f5e3Sopenharmony_ci        }
4284514f5e3Sopenharmony_ci    }
4294514f5e3Sopenharmony_ci
4304514f5e3Sopenharmony_ci    void Invalidate()
4314514f5e3Sopenharmony_ci    {
4324514f5e3Sopenharmony_ci        ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<void *>(GetBegin()), GetSize());
4334514f5e3Sopenharmony_ci        packedData_.flags_.spaceFlag_ = RegionSpaceFlag::UNINITIALIZED;
4344514f5e3Sopenharmony_ci    }
4354514f5e3Sopenharmony_ci
4364514f5e3Sopenharmony_ci    uint8_t GetRegionSpaceFlag();
4374514f5e3Sopenharmony_ci
4384514f5e3Sopenharmony_ci    void SetRegionSpaceFlag(RegionSpaceFlag flag)
4394514f5e3Sopenharmony_ci    {
4404514f5e3Sopenharmony_ci        packedData_.flags_.spaceFlag_ = flag;
4414514f5e3Sopenharmony_ci    }
4424514f5e3Sopenharmony_ci    bool InEdenSpace() const
4434514f5e3Sopenharmony_ci    {
4444514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_EDEN_SPACE;
4454514f5e3Sopenharmony_ci    }
4464514f5e3Sopenharmony_ci
4474514f5e3Sopenharmony_ci    bool InYoungSpace() const
4484514f5e3Sopenharmony_ci    {
4494514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_YOUNG_SPACE;
4504514f5e3Sopenharmony_ci    }
4514514f5e3Sopenharmony_ci
4524514f5e3Sopenharmony_ci    bool InOldSpace() const
4534514f5e3Sopenharmony_ci    {
4544514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_OLD_SPACE;
4554514f5e3Sopenharmony_ci    }
4564514f5e3Sopenharmony_ci
4574514f5e3Sopenharmony_ci    bool InYoungOrOldSpace() const
4584514f5e3Sopenharmony_ci    {
4594514f5e3Sopenharmony_ci        return InGeneralNewSpace() || InOldSpace();
4604514f5e3Sopenharmony_ci    }
4614514f5e3Sopenharmony_ci
4624514f5e3Sopenharmony_ci    bool InGeneralNewSpace() const
4634514f5e3Sopenharmony_ci    {
4644514f5e3Sopenharmony_ci        auto flag = packedData_.flags_.spaceFlag_;
4654514f5e3Sopenharmony_ci        return flag >= RegionSpaceFlag::GENERAL_YOUNG_BEGIN && flag <= RegionSpaceFlag::GENERAL_YOUNG_END;
4664514f5e3Sopenharmony_ci    }
4674514f5e3Sopenharmony_ci
4684514f5e3Sopenharmony_ci    bool InGeneralOldSpace() const
4694514f5e3Sopenharmony_ci    {
4704514f5e3Sopenharmony_ci        ASSERT(packedData_.flags_.spaceFlag_ != 0);
4714514f5e3Sopenharmony_ci        auto flag = packedData_.flags_.spaceFlag_;
4724514f5e3Sopenharmony_ci        return flag >= RegionSpaceFlag::GENERAL_OLD_BEGIN && flag <= RegionSpaceFlag::GENERAL_OLD_END;
4734514f5e3Sopenharmony_ci    }
4744514f5e3Sopenharmony_ci
4754514f5e3Sopenharmony_ci    bool InHugeObjectSpace() const
4764514f5e3Sopenharmony_ci    {
4774514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_HUGE_OBJECT_SPACE;
4784514f5e3Sopenharmony_ci    }
4794514f5e3Sopenharmony_ci
4804514f5e3Sopenharmony_ci    bool InMachineCodeSpace() const
4814514f5e3Sopenharmony_ci    {
4824514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_MACHINE_CODE_SPACE;
4834514f5e3Sopenharmony_ci    }
4844514f5e3Sopenharmony_ci
4854514f5e3Sopenharmony_ci    bool InHugeMachineCodeSpace() const
4864514f5e3Sopenharmony_ci    {
4874514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_HUGE_MACHINE_CODE_SPACE;
4884514f5e3Sopenharmony_ci    }
4894514f5e3Sopenharmony_ci
4904514f5e3Sopenharmony_ci    bool InNonMovableSpace() const
4914514f5e3Sopenharmony_ci    {
4924514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_NON_MOVABLE_SPACE;
4934514f5e3Sopenharmony_ci    }
4944514f5e3Sopenharmony_ci
4954514f5e3Sopenharmony_ci    bool InSnapshotSpace() const
4964514f5e3Sopenharmony_ci    {
4974514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SNAPSHOT_SPACE;
4984514f5e3Sopenharmony_ci    }
4994514f5e3Sopenharmony_ci
5004514f5e3Sopenharmony_ci    bool InReadOnlySpace() const
5014514f5e3Sopenharmony_ci    {
5024514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_READ_ONLY_SPACE;
5034514f5e3Sopenharmony_ci    }
5044514f5e3Sopenharmony_ci
5054514f5e3Sopenharmony_ci    bool InSharedOldSpace() const
5064514f5e3Sopenharmony_ci    {
5074514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_OLD_SPACE;
5084514f5e3Sopenharmony_ci    }
5094514f5e3Sopenharmony_ci
5104514f5e3Sopenharmony_ci    bool InSharedNonMovableSpace() const
5114514f5e3Sopenharmony_ci    {
5124514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_NON_MOVABLE;
5134514f5e3Sopenharmony_ci    }
5144514f5e3Sopenharmony_ci
5154514f5e3Sopenharmony_ci    bool InSharedHugeObjectSpace() const
5164514f5e3Sopenharmony_ci    {
5174514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_HUGE_OBJECT_SPACE;
5184514f5e3Sopenharmony_ci    }
5194514f5e3Sopenharmony_ci
5204514f5e3Sopenharmony_ci    bool InSharedReadOnlySpace() const
5214514f5e3Sopenharmony_ci    {
5224514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_READ_ONLY_SPACE;
5234514f5e3Sopenharmony_ci    }
5244514f5e3Sopenharmony_ci
5254514f5e3Sopenharmony_ci    bool InSharedAppSpawnSpace() const
5264514f5e3Sopenharmony_ci    {
5274514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_APPSPAWN_SPACE;
5284514f5e3Sopenharmony_ci    }
5294514f5e3Sopenharmony_ci
5304514f5e3Sopenharmony_ci    bool InAppSpawnSpace() const
5314514f5e3Sopenharmony_ci    {
5324514f5e3Sopenharmony_ci        return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_APPSPAWN_SPACE;
5334514f5e3Sopenharmony_ci    }
5344514f5e3Sopenharmony_ci
5354514f5e3Sopenharmony_ci    // Not including shared read only space.
5364514f5e3Sopenharmony_ci    bool InSharedSweepableSpace() const
5374514f5e3Sopenharmony_ci    {
5384514f5e3Sopenharmony_ci        auto flag = packedData_.flags_.spaceFlag_;
5394514f5e3Sopenharmony_ci        return flag >= RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_BEGIN &&
5404514f5e3Sopenharmony_ci               flag <= RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_END;
5414514f5e3Sopenharmony_ci    }
5424514f5e3Sopenharmony_ci
5434514f5e3Sopenharmony_ci    bool InSharedHeap() const
5444514f5e3Sopenharmony_ci    {
5454514f5e3Sopenharmony_ci        auto flag = packedData_.flags_.spaceFlag_;
5464514f5e3Sopenharmony_ci        return flag >= RegionSpaceFlag::SHARED_SPACE_BEGIN && flag <= RegionSpaceFlag::SHARED_SPACE_END;
5474514f5e3Sopenharmony_ci    }
5484514f5e3Sopenharmony_ci
5494514f5e3Sopenharmony_ci    bool InSparseSpace() const
5504514f5e3Sopenharmony_ci    {
5514514f5e3Sopenharmony_ci        auto flag = packedData_.flags_.spaceFlag_;
5524514f5e3Sopenharmony_ci        switch (flag) {
5534514f5e3Sopenharmony_ci            case RegionSpaceFlag::IN_OLD_SPACE:
5544514f5e3Sopenharmony_ci            case RegionSpaceFlag::IN_NON_MOVABLE_SPACE:
5554514f5e3Sopenharmony_ci            case RegionSpaceFlag::IN_MACHINE_CODE_SPACE:
5564514f5e3Sopenharmony_ci            case RegionSpaceFlag::IN_APPSPAWN_SPACE:
5574514f5e3Sopenharmony_ci            case RegionSpaceFlag::IN_SHARED_NON_MOVABLE:
5584514f5e3Sopenharmony_ci            case RegionSpaceFlag::IN_SHARED_OLD_SPACE:
5594514f5e3Sopenharmony_ci                return true;
5604514f5e3Sopenharmony_ci            default:
5614514f5e3Sopenharmony_ci                return false;
5624514f5e3Sopenharmony_ci        }
5634514f5e3Sopenharmony_ci    }
5644514f5e3Sopenharmony_ci
5654514f5e3Sopenharmony_ci    bool InHeapSpace() const
5664514f5e3Sopenharmony_ci    {
5674514f5e3Sopenharmony_ci        uint8_t space = packedData_.flags_.spaceFlag_;
5684514f5e3Sopenharmony_ci        return space >= RegionSpaceFlag::HEAP_SPACE_BEGIN && space <= RegionSpaceFlag::HEAP_SPACE_END;
5694514f5e3Sopenharmony_ci    }
5704514f5e3Sopenharmony_ci
5714514f5e3Sopenharmony_ci    bool InCollectSet() const
5724514f5e3Sopenharmony_ci    {
5734514f5e3Sopenharmony_ci        return IsGCFlagSet(RegionGCFlags::IN_COLLECT_SET);
5744514f5e3Sopenharmony_ci    }
5754514f5e3Sopenharmony_ci
5764514f5e3Sopenharmony_ci    bool InGeneralNewSpaceOrCSet() const
5774514f5e3Sopenharmony_ci    {
5784514f5e3Sopenharmony_ci        return InGeneralNewSpace() || InCollectSet();
5794514f5e3Sopenharmony_ci    }
5804514f5e3Sopenharmony_ci
5814514f5e3Sopenharmony_ci    bool InNewToNewSet() const
5824514f5e3Sopenharmony_ci    {
5834514f5e3Sopenharmony_ci        return IsGCFlagSet(RegionGCFlags::IN_NEW_TO_NEW_SET);
5844514f5e3Sopenharmony_ci    }
5854514f5e3Sopenharmony_ci
5864514f5e3Sopenharmony_ci    bool HasAgeMark() const
5874514f5e3Sopenharmony_ci    {
5884514f5e3Sopenharmony_ci        return IsGCFlagSet(RegionGCFlags::HAS_AGE_MARK);
5894514f5e3Sopenharmony_ci    }
5904514f5e3Sopenharmony_ci
5914514f5e3Sopenharmony_ci    bool BelowAgeMark() const
5924514f5e3Sopenharmony_ci    {
5934514f5e3Sopenharmony_ci        return IsGCFlagSet(RegionGCFlags::BELOW_AGE_MARK);
5944514f5e3Sopenharmony_ci    }
5954514f5e3Sopenharmony_ci
5964514f5e3Sopenharmony_ci    bool NeedRelocate() const
5974514f5e3Sopenharmony_ci    {
5984514f5e3Sopenharmony_ci        return IsGCFlagSet(RegionGCFlags::NEED_RELOCATE);
5994514f5e3Sopenharmony_ci    }
6004514f5e3Sopenharmony_ci
6014514f5e3Sopenharmony_ci    // ONLY used for heap verification.
6024514f5e3Sopenharmony_ci    bool InInactiveSemiSpace() const
6034514f5e3Sopenharmony_ci    {
6044514f5e3Sopenharmony_ci        return IsGCFlagSet(RegionGCFlags::IN_INACTIVE_SEMI_SPACE);
6054514f5e3Sopenharmony_ci    }
6064514f5e3Sopenharmony_ci
6074514f5e3Sopenharmony_ci    // ONLY used for heap verification.
6084514f5e3Sopenharmony_ci    bool InActiveSemiSpace() const
6094514f5e3Sopenharmony_ci    {
6104514f5e3Sopenharmony_ci        return InYoungSpace() && !InInactiveSemiSpace();
6114514f5e3Sopenharmony_ci    }
6124514f5e3Sopenharmony_ci
6134514f5e3Sopenharmony_ci    RegionTypeFlag GetRegionTypeFlag() const
6144514f5e3Sopenharmony_ci    {
6154514f5e3Sopenharmony_ci        return packedData_.typeFlag_;
6164514f5e3Sopenharmony_ci    }
6174514f5e3Sopenharmony_ci
6184514f5e3Sopenharmony_ci    void SetRegionTypeFlag(RegionTypeFlag typeFlag)
6194514f5e3Sopenharmony_ci    {
6204514f5e3Sopenharmony_ci        packedData_.typeFlag_ = typeFlag;
6214514f5e3Sopenharmony_ci    }
6224514f5e3Sopenharmony_ci
6234514f5e3Sopenharmony_ci    void ResetRegionTypeFlag()
6244514f5e3Sopenharmony_ci    {
6254514f5e3Sopenharmony_ci        SetRegionTypeFlag(RegionTypeFlag::DEFAULT);
6264514f5e3Sopenharmony_ci    }
6274514f5e3Sopenharmony_ci
6284514f5e3Sopenharmony_ci    bool IsFreshRegion() const
6294514f5e3Sopenharmony_ci    {
6304514f5e3Sopenharmony_ci        return GetRegionTypeFlag() == RegionTypeFlag::FRESH;
6314514f5e3Sopenharmony_ci    }
6324514f5e3Sopenharmony_ci
6334514f5e3Sopenharmony_ci    bool IsHalfFreshRegion() const
6344514f5e3Sopenharmony_ci    {
6354514f5e3Sopenharmony_ci        return GetRegionTypeFlag() == RegionTypeFlag::HALF_FRESH;
6364514f5e3Sopenharmony_ci    }
6374514f5e3Sopenharmony_ci
6384514f5e3Sopenharmony_ci    // ONLY used for heap verification.
6394514f5e3Sopenharmony_ci    void SetInactiveSemiSpace()
6404514f5e3Sopenharmony_ci    {
6414514f5e3Sopenharmony_ci        SetGCFlag(RegionGCFlags::IN_INACTIVE_SEMI_SPACE);
6424514f5e3Sopenharmony_ci    }
6434514f5e3Sopenharmony_ci
6444514f5e3Sopenharmony_ci    // ONLY used for heap verification.
6454514f5e3Sopenharmony_ci    void ResetInactiveSemiSpace()
6464514f5e3Sopenharmony_ci    {
6474514f5e3Sopenharmony_ci        ClearGCFlag(RegionGCFlags::IN_INACTIVE_SEMI_SPACE);
6484514f5e3Sopenharmony_ci    }
6494514f5e3Sopenharmony_ci
6504514f5e3Sopenharmony_ci    void SetSwept()
6514514f5e3Sopenharmony_ci    {
6524514f5e3Sopenharmony_ci        SetGCFlag(RegionGCFlags::HAS_BEEN_SWEPT);
6534514f5e3Sopenharmony_ci    }
6544514f5e3Sopenharmony_ci
6554514f5e3Sopenharmony_ci    void ResetSwept()
6564514f5e3Sopenharmony_ci    {
6574514f5e3Sopenharmony_ci        ClearGCFlag(RegionGCFlags::HAS_BEEN_SWEPT);
6584514f5e3Sopenharmony_ci    }
6594514f5e3Sopenharmony_ci
6604514f5e3Sopenharmony_ci    bool InRange(uintptr_t address) const
6614514f5e3Sopenharmony_ci    {
6624514f5e3Sopenharmony_ci        return address >= packedData_.begin_ && address <= end_;
6634514f5e3Sopenharmony_ci    }
6644514f5e3Sopenharmony_ci
6654514f5e3Sopenharmony_ci    uintptr_t GetAllocateBase() const
6664514f5e3Sopenharmony_ci    {
6674514f5e3Sopenharmony_ci        return allocateBase_;
6684514f5e3Sopenharmony_ci    }
6694514f5e3Sopenharmony_ci
6704514f5e3Sopenharmony_ci    size_t GetAllocatedBytes(uintptr_t top = 0)
6714514f5e3Sopenharmony_ci    {
6724514f5e3Sopenharmony_ci        ASSERT(top == 0 || InRange(top));
6734514f5e3Sopenharmony_ci        return (top == 0) ? (highWaterMark_ - packedData_.begin_) : (top - packedData_.begin_);
6744514f5e3Sopenharmony_ci    }
6754514f5e3Sopenharmony_ci
6764514f5e3Sopenharmony_ci    void SetHighWaterMark(uintptr_t mark)
6774514f5e3Sopenharmony_ci    {
6784514f5e3Sopenharmony_ci        ASSERT(InRange(mark));
6794514f5e3Sopenharmony_ci        highWaterMark_ = mark;
6804514f5e3Sopenharmony_ci    }
6814514f5e3Sopenharmony_ci
6824514f5e3Sopenharmony_ci    void SetReadOnlyAndMarked()
6834514f5e3Sopenharmony_ci    {
6844514f5e3Sopenharmony_ci        packedData_.markGCBitset_->SetAllBits(packedData_.bitsetSize_);
6854514f5e3Sopenharmony_ci        PageProtect(reinterpret_cast<void *>(allocateBase_), GetCapacity(), PAGE_PROT_READ);
6864514f5e3Sopenharmony_ci    }
6874514f5e3Sopenharmony_ci
6884514f5e3Sopenharmony_ci    void ClearReadOnly()
6894514f5e3Sopenharmony_ci    {
6904514f5e3Sopenharmony_ci        PageProtect(reinterpret_cast<void *>(allocateBase_), GetCapacity(), PAGE_PROT_READWRITE);
6914514f5e3Sopenharmony_ci    }
6924514f5e3Sopenharmony_ci
6934514f5e3Sopenharmony_ci    void InitializeFreeObjectSets()
6944514f5e3Sopenharmony_ci    {
6954514f5e3Sopenharmony_ci        FreeObjectSet<FreeObject> **sets = new FreeObjectSet<FreeObject> *[FreeObjectList<FreeObject>::NumberOfSets()];
6964514f5e3Sopenharmony_ci        for (int i = 0; i < FreeObjectList<FreeObject>::NumberOfSets(); i++) {
6974514f5e3Sopenharmony_ci            sets[i] = new FreeObjectSet<FreeObject>(i);
6984514f5e3Sopenharmony_ci        }
6994514f5e3Sopenharmony_ci        freeObjectSets_ = Span<FreeObjectSet<FreeObject> *>(sets, FreeObjectList<FreeObject>::NumberOfSets());
7004514f5e3Sopenharmony_ci    }
7014514f5e3Sopenharmony_ci
7024514f5e3Sopenharmony_ci    void DestroyFreeObjectSets()
7034514f5e3Sopenharmony_ci    {
7044514f5e3Sopenharmony_ci        for (int i = 0; i < FreeObjectList<FreeObject>::NumberOfSets(); i++) {
7054514f5e3Sopenharmony_ci            delete freeObjectSets_[i];
7064514f5e3Sopenharmony_ci            freeObjectSets_[i] = nullptr;
7074514f5e3Sopenharmony_ci        }
7084514f5e3Sopenharmony_ci        delete[] freeObjectSets_.data();
7094514f5e3Sopenharmony_ci    }
7104514f5e3Sopenharmony_ci
7114514f5e3Sopenharmony_ci    FreeObjectSet<FreeObject> *GetFreeObjectSet(SetType type)
7124514f5e3Sopenharmony_ci    {
7134514f5e3Sopenharmony_ci        // Thread safe
7144514f5e3Sopenharmony_ci        if (freeObjectSets_[type] == nullptr) {
7154514f5e3Sopenharmony_ci            freeObjectSets_[type] = new FreeObjectSet<FreeObject>(type);
7164514f5e3Sopenharmony_ci        }
7174514f5e3Sopenharmony_ci        return freeObjectSets_[type];
7184514f5e3Sopenharmony_ci    }
7194514f5e3Sopenharmony_ci
7204514f5e3Sopenharmony_ci    template<class Callback>
7214514f5e3Sopenharmony_ci    void EnumerateFreeObjectSets(Callback cb)
7224514f5e3Sopenharmony_ci    {
7234514f5e3Sopenharmony_ci        for (auto set : freeObjectSets_) {
7244514f5e3Sopenharmony_ci            cb(set);
7254514f5e3Sopenharmony_ci        }
7264514f5e3Sopenharmony_ci    }
7274514f5e3Sopenharmony_ci
7284514f5e3Sopenharmony_ci    template<class Callback>
7294514f5e3Sopenharmony_ci    void REnumerateFreeObjectSets(Callback cb)
7304514f5e3Sopenharmony_ci    {
7314514f5e3Sopenharmony_ci        auto last = freeObjectSets_.crbegin();
7324514f5e3Sopenharmony_ci        auto first = freeObjectSets_.crend();
7334514f5e3Sopenharmony_ci        for (; last != first; last++) {
7344514f5e3Sopenharmony_ci            if (!cb(*last)) {
7354514f5e3Sopenharmony_ci                break;
7364514f5e3Sopenharmony_ci            }
7374514f5e3Sopenharmony_ci        }
7384514f5e3Sopenharmony_ci    }
7394514f5e3Sopenharmony_ci
7404514f5e3Sopenharmony_ci    void IncreaseAliveObjectSafe(size_t size)
7414514f5e3Sopenharmony_ci    {
7424514f5e3Sopenharmony_ci        ASSERT(aliveObject_ + size <= GetSize());
7434514f5e3Sopenharmony_ci        aliveObject_ += size;
7444514f5e3Sopenharmony_ci    }
7454514f5e3Sopenharmony_ci
7464514f5e3Sopenharmony_ci    void IncreaseAliveObject(size_t size)
7474514f5e3Sopenharmony_ci    {
7484514f5e3Sopenharmony_ci        aliveObject_.fetch_add(size, std::memory_order_relaxed);
7494514f5e3Sopenharmony_ci    }
7504514f5e3Sopenharmony_ci
7514514f5e3Sopenharmony_ci    void SetRegionAliveSize()
7524514f5e3Sopenharmony_ci    {
7534514f5e3Sopenharmony_ci        gcAliveSize_ = aliveObject_;
7544514f5e3Sopenharmony_ci    }
7554514f5e3Sopenharmony_ci
7564514f5e3Sopenharmony_ci    void ResetAliveObject()
7574514f5e3Sopenharmony_ci    {
7584514f5e3Sopenharmony_ci        aliveObject_ = 0;
7594514f5e3Sopenharmony_ci    }
7604514f5e3Sopenharmony_ci
7614514f5e3Sopenharmony_ci    size_t AliveObject() const
7624514f5e3Sopenharmony_ci    {
7634514f5e3Sopenharmony_ci        return aliveObject_.load(std::memory_order_relaxed);
7644514f5e3Sopenharmony_ci    }
7654514f5e3Sopenharmony_ci
7664514f5e3Sopenharmony_ci    size_t GetGCAliveSize() const
7674514f5e3Sopenharmony_ci    {
7684514f5e3Sopenharmony_ci        return gcAliveSize_;
7694514f5e3Sopenharmony_ci    }
7704514f5e3Sopenharmony_ci
7714514f5e3Sopenharmony_ci    bool MostObjectAlive() const
7724514f5e3Sopenharmony_ci    {
7734514f5e3Sopenharmony_ci        return aliveObject_ > MOST_OBJECT_ALIVE_THRESHOLD_PERCENT * GetSize();
7744514f5e3Sopenharmony_ci    }
7754514f5e3Sopenharmony_ci
7764514f5e3Sopenharmony_ci    bool BelowCompressThreasholdAlive() const
7774514f5e3Sopenharmony_ci    {
7784514f5e3Sopenharmony_ci        return gcAliveSize_ < COMPRESS_THREASHOLD_PERCENT * GetSize();
7794514f5e3Sopenharmony_ci    }
7804514f5e3Sopenharmony_ci
7814514f5e3Sopenharmony_ci    void ResetWasted()
7824514f5e3Sopenharmony_ci    {
7834514f5e3Sopenharmony_ci        wasted_ = 0;
7844514f5e3Sopenharmony_ci    }
7854514f5e3Sopenharmony_ci
7864514f5e3Sopenharmony_ci    void IncreaseWasted(uint64_t size)
7874514f5e3Sopenharmony_ci    {
7884514f5e3Sopenharmony_ci        wasted_ += size;
7894514f5e3Sopenharmony_ci    }
7904514f5e3Sopenharmony_ci
7914514f5e3Sopenharmony_ci    uint64_t GetWastedSize()
7924514f5e3Sopenharmony_ci    {
7934514f5e3Sopenharmony_ci        return wasted_;
7944514f5e3Sopenharmony_ci    }
7954514f5e3Sopenharmony_ci
7964514f5e3Sopenharmony_ci    uint64_t GetSnapshotData()
7974514f5e3Sopenharmony_ci    {
7984514f5e3Sopenharmony_ci        return snapshotData_;
7994514f5e3Sopenharmony_ci    }
8004514f5e3Sopenharmony_ci
8014514f5e3Sopenharmony_ci    void SetSnapshotData(uint64_t value)
8024514f5e3Sopenharmony_ci    {
8034514f5e3Sopenharmony_ci        snapshotData_ = value;
8044514f5e3Sopenharmony_ci    }
8054514f5e3Sopenharmony_ci
8064514f5e3Sopenharmony_ci    void SwapOldToNewRSetForCS()
8074514f5e3Sopenharmony_ci    {
8084514f5e3Sopenharmony_ci        sweepingOldToNewRSet_ = packedData_.oldToNewSet_;
8094514f5e3Sopenharmony_ci        packedData_.oldToNewSet_ = nullptr;
8104514f5e3Sopenharmony_ci    }
8114514f5e3Sopenharmony_ci
8124514f5e3Sopenharmony_ci    void SwapLocalToShareRSetForCS()
8134514f5e3Sopenharmony_ci    {
8144514f5e3Sopenharmony_ci        sweepingLocalToShareRSet_ = packedData_.localToShareSet_;
8154514f5e3Sopenharmony_ci        packedData_.localToShareSet_ = nullptr;
8164514f5e3Sopenharmony_ci    }
8174514f5e3Sopenharmony_ci
8184514f5e3Sopenharmony_ci    void SetLocalHeap(uintptr_t localHeap)
8194514f5e3Sopenharmony_ci    {
8204514f5e3Sopenharmony_ci        ASSERT(localHeap != (uintptr_t)nullptr);
8214514f5e3Sopenharmony_ci        localHeap_ = localHeap;
8224514f5e3Sopenharmony_ci    }
8234514f5e3Sopenharmony_ci
8244514f5e3Sopenharmony_ci    uintptr_t GetLocalHeap(void)
8254514f5e3Sopenharmony_ci    {
8264514f5e3Sopenharmony_ci        return localHeap_;
8274514f5e3Sopenharmony_ci    }
8284514f5e3Sopenharmony_ci
8294514f5e3Sopenharmony_ci    // should call in js-thread
8304514f5e3Sopenharmony_ci    void MergeOldToNewRSetForCS();
8314514f5e3Sopenharmony_ci    void MergeLocalToShareRSetForCS();
8324514f5e3Sopenharmony_ci
8334514f5e3Sopenharmony_ci    // should call in daemon-thread, or in js-thread in RUNNING state
8344514f5e3Sopenharmony_ci    void MergeLocalToShareRSetForCM(RememberedSet *set);
8354514f5e3Sopenharmony_ci
8364514f5e3Sopenharmony_ci    struct alignas(JSTaggedValue::TaggedTypeSize()) PackedPtr : public base::AlignedPointer {
8374514f5e3Sopenharmony_ci        uint8_t spaceFlag_;
8384514f5e3Sopenharmony_ci        uint16_t  gcFlags_;
8394514f5e3Sopenharmony_ci    };
8404514f5e3Sopenharmony_ci
8414514f5e3Sopenharmony_ci    struct PackedData : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
8424514f5e3Sopenharmony_ci                                                 base::AlignedPointer,
8434514f5e3Sopenharmony_ci                                                 base::AlignedPointer,
8444514f5e3Sopenharmony_ci                                                 base::AlignedPointer,
8454514f5e3Sopenharmony_ci                                                 base::AlignedPointer,
8464514f5e3Sopenharmony_ci                                                 base::AlignedPointer,
8474514f5e3Sopenharmony_ci                                                 base::AlignedPointer,
8484514f5e3Sopenharmony_ci                                                 base::AlignedSize> {
8494514f5e3Sopenharmony_ci        enum class Index : size_t {
8504514f5e3Sopenharmony_ci            FlagsIndex = 0,
8514514f5e3Sopenharmony_ci            TypeFlagIndex,
8524514f5e3Sopenharmony_ci            MarkGCBitSetIndex,
8534514f5e3Sopenharmony_ci            OldToNewSetIndex,
8544514f5e3Sopenharmony_ci            LocalToShareSetIndex,
8554514f5e3Sopenharmony_ci            BeginIndex,
8564514f5e3Sopenharmony_ci            BitSetSizeIndex,
8574514f5e3Sopenharmony_ci            NumOfMembers
8584514f5e3Sopenharmony_ci        };
8594514f5e3Sopenharmony_ci
8604514f5e3Sopenharmony_ci        static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
8614514f5e3Sopenharmony_ci
8624514f5e3Sopenharmony_ci        inline PackedData(uintptr_t begin, uintptr_t end, RegionSpaceFlag spaceType, RegionTypeFlag typeFlag)
8634514f5e3Sopenharmony_ci        {
8644514f5e3Sopenharmony_ci            flags_.spaceFlag_ = spaceType;
8654514f5e3Sopenharmony_ci            flags_.gcFlags_ = 0;
8664514f5e3Sopenharmony_ci            typeFlag_ = typeFlag;
8674514f5e3Sopenharmony_ci            bitsetSize_ = (spaceType == RegionSpaceFlag::IN_HUGE_OBJECT_SPACE ||
8684514f5e3Sopenharmony_ci                           spaceType == RegionSpaceFlag::IN_HUGE_MACHINE_CODE_SPACE ||
8694514f5e3Sopenharmony_ci                           spaceType == RegionSpaceFlag::IN_SHARED_HUGE_OBJECT_SPACE) ?
8704514f5e3Sopenharmony_ci                GCBitset::BYTE_PER_WORD : GCBitset::SizeOfGCBitset(end - begin);
8714514f5e3Sopenharmony_ci            markGCBitset_ = new (ToVoidPtr(begin)) GCBitset();
8724514f5e3Sopenharmony_ci            markGCBitset_->Clear(bitsetSize_);
8734514f5e3Sopenharmony_ci            begin_ = AlignUp(begin + bitsetSize_, static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
8744514f5e3Sopenharmony_ci            // The object region marked with poison until it is allocated if is_asan is true
8754514f5e3Sopenharmony_ci#ifdef ARK_ASAN_ON
8764514f5e3Sopenharmony_ci            ASAN_POISON_MEMORY_REGION(reinterpret_cast<void *>(begin_), (end - begin_));
8774514f5e3Sopenharmony_ci#endif
8784514f5e3Sopenharmony_ci        }
8794514f5e3Sopenharmony_ci
8804514f5e3Sopenharmony_ci        inline PackedData(uintptr_t begin, RegionSpaceFlag spaceType)
8814514f5e3Sopenharmony_ci        {
8824514f5e3Sopenharmony_ci            flags_.spaceFlag_ = spaceType;
8834514f5e3Sopenharmony_ci            flags_.gcFlags_ = 0;
8844514f5e3Sopenharmony_ci            typeFlag_ = RegionTypeFlag::DEFAULT;
8854514f5e3Sopenharmony_ci            // no markGCBitset
8864514f5e3Sopenharmony_ci            begin_ = begin;
8874514f5e3Sopenharmony_ci            markGCBitset_ = nullptr;
8884514f5e3Sopenharmony_ci        }
8894514f5e3Sopenharmony_ci
8904514f5e3Sopenharmony_ci        static size_t GetFlagsOffset(bool isArch32)
8914514f5e3Sopenharmony_ci        {
8924514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::FlagsIndex)>(isArch32);
8934514f5e3Sopenharmony_ci        }
8944514f5e3Sopenharmony_ci
8954514f5e3Sopenharmony_ci        static size_t GetTypeFlagOffset(bool isArch32)
8964514f5e3Sopenharmony_ci        {
8974514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::TypeFlagIndex)>(isArch32);
8984514f5e3Sopenharmony_ci        }
8994514f5e3Sopenharmony_ci
9004514f5e3Sopenharmony_ci        static size_t GetGCBitsetOffset(bool isArch32)
9014514f5e3Sopenharmony_ci        {
9024514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::MarkGCBitSetIndex)>(isArch32);
9034514f5e3Sopenharmony_ci        }
9044514f5e3Sopenharmony_ci
9054514f5e3Sopenharmony_ci        static size_t GetNewToEdenSetOffset(bool isArch32)
9064514f5e3Sopenharmony_ci        {
9074514f5e3Sopenharmony_ci            // NewToEdenRSet is Union with OldToNewRSet
9084514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::OldToNewSetIndex)>(isArch32);
9094514f5e3Sopenharmony_ci        }
9104514f5e3Sopenharmony_ci
9114514f5e3Sopenharmony_ci        static size_t GetOldToNewSetOffset(bool isArch32)
9124514f5e3Sopenharmony_ci        {
9134514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::OldToNewSetIndex)>(isArch32);
9144514f5e3Sopenharmony_ci        }
9154514f5e3Sopenharmony_ci
9164514f5e3Sopenharmony_ci        static size_t GetLocalToShareSetOffset(bool isArch32)
9174514f5e3Sopenharmony_ci        {
9184514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::LocalToShareSetIndex)>(isArch32);
9194514f5e3Sopenharmony_ci        }
9204514f5e3Sopenharmony_ci
9214514f5e3Sopenharmony_ci        static size_t GetBeginOffset(bool isArch32)
9224514f5e3Sopenharmony_ci        {
9234514f5e3Sopenharmony_ci            return GetOffset<static_cast<size_t>(Index::BeginIndex)>(isArch32);
9244514f5e3Sopenharmony_ci        }
9254514f5e3Sopenharmony_ci
9264514f5e3Sopenharmony_ci        alignas(EAS) PackedPtr flags_;
9274514f5e3Sopenharmony_ci        // Use different UIntPtr from flags_ to prevent the potential data race.
9284514f5e3Sopenharmony_ci        // Be careful when storing to this value, currently this is only from JS_Thread during ConcurrentMarking,
9294514f5e3Sopenharmony_ci        // or from GC_Thread during GC ClearTask.
9304514f5e3Sopenharmony_ci        alignas(EAS) RegionTypeFlag typeFlag_;
9314514f5e3Sopenharmony_ci        alignas(EAS) GCBitset *markGCBitset_ {nullptr};
9324514f5e3Sopenharmony_ci        // OldToNewRSet only for general OldSpace, NewToEdenRSet only for YoungSpace. Their pointers can union
9334514f5e3Sopenharmony_ci        union {
9344514f5e3Sopenharmony_ci            alignas(EAS) RememberedSet *oldToNewSet_ {nullptr};
9354514f5e3Sopenharmony_ci            alignas(EAS) RememberedSet *newToEdenSet_;
9364514f5e3Sopenharmony_ci        };
9374514f5e3Sopenharmony_ci        alignas(EAS) RememberedSet *localToShareSet_ {nullptr};
9384514f5e3Sopenharmony_ci        alignas(EAS) uintptr_t begin_ {0};
9394514f5e3Sopenharmony_ci        alignas(EAS) size_t bitsetSize_ {0};
9404514f5e3Sopenharmony_ci    };
9414514f5e3Sopenharmony_ci    STATIC_ASSERT_EQ_ARCH(sizeof(PackedData), PackedData::SizeArch32, PackedData::SizeArch64);
9424514f5e3Sopenharmony_ci
9434514f5e3Sopenharmony_ci    static constexpr double MOST_OBJECT_ALIVE_THRESHOLD_PERCENT = 0.8;
9444514f5e3Sopenharmony_ci    static constexpr double AVERAGE_REGION_EVACUATE_SIZE = MOST_OBJECT_ALIVE_THRESHOLD_PERCENT *
9454514f5e3Sopenharmony_ci                                                           DEFAULT_REGION_SIZE / 2;  // 2 means half
9464514f5e3Sopenharmony_ciprivate:
9474514f5e3Sopenharmony_ci    static constexpr double COMPRESS_THREASHOLD_PERCENT = 0.1;
9484514f5e3Sopenharmony_ci
9494514f5e3Sopenharmony_ci    RememberedSet *CreateRememberedSet();
9504514f5e3Sopenharmony_ci    RememberedSet *GetOrCreateCrossRegionRememberedSet();
9514514f5e3Sopenharmony_ci    RememberedSet *GetOrCreateNewToEdenRememberedSet();
9524514f5e3Sopenharmony_ci    RememberedSet *GetOrCreateOldToNewRememberedSet();
9534514f5e3Sopenharmony_ci    RememberedSet *GetOrCreateLocalToShareRememberedSet();
9544514f5e3Sopenharmony_ci
9554514f5e3Sopenharmony_ci    inline RememberedSet *CreateNewToEdenRememberedSet();
9564514f5e3Sopenharmony_ci    inline RememberedSet *CreateOldToNewRememberedSet();
9574514f5e3Sopenharmony_ci    inline RememberedSet *CreateLocalToShareRememberedSet();
9584514f5e3Sopenharmony_ci
9594514f5e3Sopenharmony_ci    PackedData packedData_;
9604514f5e3Sopenharmony_ci    NativeAreaAllocator *nativeAreaAllocator_;
9614514f5e3Sopenharmony_ci
9624514f5e3Sopenharmony_ci    uintptr_t allocateBase_;
9634514f5e3Sopenharmony_ci    uintptr_t end_;
9644514f5e3Sopenharmony_ci    uintptr_t highWaterMark_;
9654514f5e3Sopenharmony_ci    std::atomic_size_t aliveObject_ {0};
9664514f5e3Sopenharmony_ci    size_t gcAliveSize_ {0};
9674514f5e3Sopenharmony_ci    Region *next_ {nullptr};
9684514f5e3Sopenharmony_ci    Region *prev_ {nullptr};
9694514f5e3Sopenharmony_ci
9704514f5e3Sopenharmony_ci    RememberedSet *crossRegionSet_ {nullptr};
9714514f5e3Sopenharmony_ci    RememberedSet *sweepingOldToNewRSet_ {nullptr};
9724514f5e3Sopenharmony_ci    RememberedSet *sweepingLocalToShareRSet_ {nullptr};
9734514f5e3Sopenharmony_ci    Span<FreeObjectSet<FreeObject> *> freeObjectSets_;
9744514f5e3Sopenharmony_ci    Mutex *lock_ {nullptr};
9754514f5e3Sopenharmony_ci    uint64_t wasted_;
9764514f5e3Sopenharmony_ci    // snapshotdata_ is used to encode the region for snapshot. Its upper 32 bits are used to store the size of
9774514f5e3Sopenharmony_ci    // the huge object, and the lower 32 bits are used to store the region index
9784514f5e3Sopenharmony_ci    uint64_t snapshotData_;
9794514f5e3Sopenharmony_ci    uintptr_t localHeap_ {0};
9804514f5e3Sopenharmony_ci
9814514f5e3Sopenharmony_ci    friend class Snapshot;
9824514f5e3Sopenharmony_ci    friend class SnapshotProcessor;
9834514f5e3Sopenharmony_ci};
9844514f5e3Sopenharmony_ci}  // namespace ecmascript
9854514f5e3Sopenharmony_ci}  // namespace panda
9864514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_MEM_REGION_H
987