14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_MEM_PARALLEL_MARKER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_PARALLEL_MARKER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/js_hclass.h"
204514f5e3Sopenharmony_ci#include "ecmascript/mem/gc_bitset.h"
214514f5e3Sopenharmony_ci#include "ecmascript/mem/object_xray.h"
224514f5e3Sopenharmony_ci#include "ecmascript/mem/slots.h"
234514f5e3Sopenharmony_ci#include "ecmascript/mem/work_manager.h"
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_cinamespace panda::ecmascript {
264514f5e3Sopenharmony_ciclass Heap;
274514f5e3Sopenharmony_ciclass Region;
284514f5e3Sopenharmony_ciclass TaggedObject;
294514f5e3Sopenharmony_ci
304514f5e3Sopenharmony_ciclass Marker {
314514f5e3Sopenharmony_cipublic:
324514f5e3Sopenharmony_ci    explicit Marker(Heap *heap);
334514f5e3Sopenharmony_ci    virtual ~Marker() = default;
344514f5e3Sopenharmony_ci
354514f5e3Sopenharmony_ci    virtual void Initialize()
364514f5e3Sopenharmony_ci    {
374514f5e3Sopenharmony_ci        LOG_GC(DEBUG) << "Marker::Initialize do nothing";
384514f5e3Sopenharmony_ci    }
394514f5e3Sopenharmony_ci
404514f5e3Sopenharmony_ci    void MarkRoots(uint32_t threadId, VMRootVisitType type = VMRootVisitType::MARK);
414514f5e3Sopenharmony_ci    void ProcessNewToEden(uint32_t threadId);                  // for HPPGC only sticky mode
424514f5e3Sopenharmony_ci    void ProcessNewToEdenNoMarkStack(uint32_t threadId);
434514f5e3Sopenharmony_ci    void ProcessOldToNew(uint32_t threadId);                  // for HPPGC only semi mode
444514f5e3Sopenharmony_ci    void ProcessOldToNewNoMarkStack(uint32_t threadId);
454514f5e3Sopenharmony_ci    void ProcessOldToNew(uint32_t threadId, Region *region);  // for SemiGC
464514f5e3Sopenharmony_ci    void ProcessSnapshotRSet(uint32_t threadId);              // for SemiGC
474514f5e3Sopenharmony_ci    void ProcessSnapshotRSetNoMarkStack(uint32_t threadId);
484514f5e3Sopenharmony_ci    virtual void MarkJitCodeMap([[maybe_unused]] uint32_t threadId)
494514f5e3Sopenharmony_ci    {
504514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "can not call this method";
514514f5e3Sopenharmony_ci    }
524514f5e3Sopenharmony_ci
534514f5e3Sopenharmony_ci    virtual void ProcessMarkStack([[maybe_unused]] uint32_t threadId)
544514f5e3Sopenharmony_ci    {
554514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "can not call this method";
564514f5e3Sopenharmony_ci    }
574514f5e3Sopenharmony_ci
584514f5e3Sopenharmony_ci    virtual void ProcessIncrementalMarkStack([[maybe_unused]] uint32_t threadId,
594514f5e3Sopenharmony_ci                                             [[maybe_unused]] uint32_t markStepSize)
604514f5e3Sopenharmony_ci    {
614514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "can not call this method";
624514f5e3Sopenharmony_ci    }
634514f5e3Sopenharmony_ci
644514f5e3Sopenharmony_ciprotected:
654514f5e3Sopenharmony_ci    // non move
664514f5e3Sopenharmony_ci    virtual inline void MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object)
674514f5e3Sopenharmony_ci    {
684514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "can not call this method";
694514f5e3Sopenharmony_ci    }
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ci    virtual inline SlotStatus MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object,
724514f5e3Sopenharmony_ci                                         [[maybe_unused]] ObjectSlot slot)  // move
734514f5e3Sopenharmony_ci    {
744514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "can not call this method";
754514f5e3Sopenharmony_ci        return SlotStatus::KEEP_SLOT;
764514f5e3Sopenharmony_ci    }
774514f5e3Sopenharmony_ci
784514f5e3Sopenharmony_ci    virtual inline void HandleNewToEdenRSet(uint32_t threadId, Region *region) = 0;
794514f5e3Sopenharmony_ci    virtual inline void HandleOldToNewRSet(uint32_t threadId, Region *region) = 0;
804514f5e3Sopenharmony_ci    virtual inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) = 0;
814514f5e3Sopenharmony_ci    virtual inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start,
824514f5e3Sopenharmony_ci                                         ObjectSlot end) = 0;
834514f5e3Sopenharmony_ci    virtual inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived,
844514f5e3Sopenharmony_ci                                           uintptr_t baseOldObject) = 0;
854514f5e3Sopenharmony_ci    virtual inline void RecordWeakReference([[maybe_unused]] uint32_t threadId, [[maybe_unused]] JSTaggedType *ref,
864514f5e3Sopenharmony_ci                                            [[maybe_unused]] Region *objectRegion)
874514f5e3Sopenharmony_ci    {
884514f5e3Sopenharmony_ci        LOG_GC(FATAL) << "can not call this method";
894514f5e3Sopenharmony_ci    }
904514f5e3Sopenharmony_ci
914514f5e3Sopenharmony_ci    Heap *heap_ {nullptr};
924514f5e3Sopenharmony_ci    WorkManager *workManager_ {nullptr};
934514f5e3Sopenharmony_ci
944514f5e3Sopenharmony_ci    friend class Heap;
954514f5e3Sopenharmony_ci};
964514f5e3Sopenharmony_ci
974514f5e3Sopenharmony_ciclass NonMovableMarker : public Marker {
984514f5e3Sopenharmony_cipublic:
994514f5e3Sopenharmony_ci    explicit NonMovableMarker(Heap *heap) : Marker(heap) {}
1004514f5e3Sopenharmony_ci    ~NonMovableMarker() override = default;
1014514f5e3Sopenharmony_ci
1024514f5e3Sopenharmony_ciprotected:
1034514f5e3Sopenharmony_ci    void ProcessMarkStack(uint32_t threadId) override;
1044514f5e3Sopenharmony_ci    void MarkJitCodeMap(uint32_t threadId) override;
1054514f5e3Sopenharmony_ci    template <typename Callback>
1064514f5e3Sopenharmony_ci    inline bool VisitBodyInObj(TaggedObject *root, ObjectSlot start, ObjectSlot end,
1074514f5e3Sopenharmony_ci                               bool needBarrier, Callback callback);
1084514f5e3Sopenharmony_ci    inline void MarkValue(uint32_t threadId, ObjectSlot &slot, Region *rootRegion, bool needBarrier);
1094514f5e3Sopenharmony_ci    inline void MarkObject(uint32_t threadId, TaggedObject *object) override;
1104514f5e3Sopenharmony_ci    inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override;
1114514f5e3Sopenharmony_ci    inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start,
1124514f5e3Sopenharmony_ci                                 ObjectSlot end) override;
1134514f5e3Sopenharmony_ci    inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived,
1144514f5e3Sopenharmony_ci                                   uintptr_t baseOldObject) override;
1154514f5e3Sopenharmony_ci
1164514f5e3Sopenharmony_ci    inline void HandleNewToEdenRSet(uint32_t threadId, Region *region) override;
1174514f5e3Sopenharmony_ci    inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override;
1184514f5e3Sopenharmony_ci    inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion) override;
1194514f5e3Sopenharmony_ci    void ProcessIncrementalMarkStack(uint32_t threadId, uint32_t markStepSize) override;
1204514f5e3Sopenharmony_ci};
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ciclass MovableMarker : public Marker {
1234514f5e3Sopenharmony_cipublic:
1244514f5e3Sopenharmony_ci    explicit MovableMarker(Heap *heap) : Marker(heap) {}
1254514f5e3Sopenharmony_ci    ~MovableMarker() override = default;
1264514f5e3Sopenharmony_ci
1274514f5e3Sopenharmony_ciprotected:
1284514f5e3Sopenharmony_ci    template <typename Callback>
1294514f5e3Sopenharmony_ci    inline bool VisitBodyInObj(TaggedObject *root, ObjectSlot start, ObjectSlot end, Callback callback);
1304514f5e3Sopenharmony_ci    inline void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override;
1314514f5e3Sopenharmony_ci    inline void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start,
1324514f5e3Sopenharmony_ci                                 ObjectSlot end) override;
1334514f5e3Sopenharmony_ci    inline void HandleDerivedRoots(Root type, ObjectSlot base, ObjectSlot derived,
1344514f5e3Sopenharmony_ci                                   uintptr_t baseOldObject) override;
1354514f5e3Sopenharmony_ci    virtual inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord,
1364514f5e3Sopenharmony_ci                                             ObjectSlot slot) = 0;
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_ci    inline void HandleNewToEdenRSet(uint32_t threadId, Region *region) override;
1394514f5e3Sopenharmony_ci    inline void HandleOldToNewRSet(uint32_t threadId, Region *region) override;
1404514f5e3Sopenharmony_ci
1414514f5e3Sopenharmony_ci    inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size, bool &shouldPromote);
1424514f5e3Sopenharmony_ci    inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass,
1434514f5e3Sopenharmony_ci                                              uintptr_t toAddress, size_t size, ObjectSlot slot,
1444514f5e3Sopenharmony_ci                                              bool isPromoted = false);
1454514f5e3Sopenharmony_ci    inline bool UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot);
1464514f5e3Sopenharmony_ci    inline void RawCopyObject(uintptr_t fromAddress, uintptr_t toAddress, size_t size, const MarkWord &markWord);
1474514f5e3Sopenharmony_ci    inline void UpdateLocalToShareRSet(TaggedObject *object, JSHClass *cls);
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_ci    inline void SetLocalToShareRSet(ObjectSlot slot, Region *region);
1504514f5e3Sopenharmony_ci};
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_ciclass SemiGCMarker : public MovableMarker {
1534514f5e3Sopenharmony_cipublic:
1544514f5e3Sopenharmony_ci    explicit SemiGCMarker(Heap *heap) : MovableMarker(heap) {}
1554514f5e3Sopenharmony_ci    ~SemiGCMarker() override = default;
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ci    void Initialize() override;
1584514f5e3Sopenharmony_ci
1594514f5e3Sopenharmony_ciprotected:
1604514f5e3Sopenharmony_ci    void ProcessMarkStack(uint32_t threadId) override;
1614514f5e3Sopenharmony_ci    inline void MarkValue(uint32_t threadId, TaggedObject *root, ObjectSlot slot);
1624514f5e3Sopenharmony_ci    inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override;
1634514f5e3Sopenharmony_ci    inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord,
1644514f5e3Sopenharmony_ci                                     ObjectSlot slot) override;
1654514f5e3Sopenharmony_ci    inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override;
1664514f5e3Sopenharmony_ci
1674514f5e3Sopenharmony_ciprivate:
1684514f5e3Sopenharmony_ci    inline bool ShouldBePromoted(TaggedObject *object);
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_ci    uintptr_t waterLine_ {0};
1714514f5e3Sopenharmony_ci};
1724514f5e3Sopenharmony_ci
1734514f5e3Sopenharmony_ciclass CompressGCMarker : public MovableMarker {
1744514f5e3Sopenharmony_cipublic:
1754514f5e3Sopenharmony_ci    explicit CompressGCMarker(Heap *heap) : MovableMarker(heap) {}
1764514f5e3Sopenharmony_ci    ~CompressGCMarker() override = default;
1774514f5e3Sopenharmony_ci
1784514f5e3Sopenharmony_ci    inline bool NeedEvacuate(Region *region);
1794514f5e3Sopenharmony_ci    void SetAppSpawn(bool flag)
1804514f5e3Sopenharmony_ci    {
1814514f5e3Sopenharmony_ci        isAppSpawn_ = flag;
1824514f5e3Sopenharmony_ci    }
1834514f5e3Sopenharmony_ci
1844514f5e3Sopenharmony_ciprotected:
1854514f5e3Sopenharmony_ci    void MarkJitCodeMap(uint32_t threadId) override;
1864514f5e3Sopenharmony_ci    void ProcessMarkStack(uint32_t threadId) override;
1874514f5e3Sopenharmony_ci    void HandleVisitJitCodeMap(uint32_t threadId, std::map<JSTaggedType, JitCodeVector *> &jitCodeMaps);
1884514f5e3Sopenharmony_ci    inline void MarkValue(uint32_t threadId, ObjectSlot slot);
1894514f5e3Sopenharmony_ci    inline SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override;
1904514f5e3Sopenharmony_ci
1914514f5e3Sopenharmony_ci    inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord,
1924514f5e3Sopenharmony_ci                                     ObjectSlot slot) override;
1934514f5e3Sopenharmony_ci    uintptr_t AllocateForwardAddress(uint32_t threadId, size_t size, JSHClass *hclass, TaggedObject *object);
1944514f5e3Sopenharmony_ci    inline uintptr_t AllocateAppSpawnSpace(size_t size);
1954514f5e3Sopenharmony_ci    inline uintptr_t AllocateReadOnlySpace(size_t size);
1964514f5e3Sopenharmony_ci    inline void RecordWeakReference(uint32_t threadId, JSTaggedType *ref, Region *objectRegion = nullptr) override;
1974514f5e3Sopenharmony_ci
1984514f5e3Sopenharmony_ciprivate:
1994514f5e3Sopenharmony_ci    bool isAppSpawn_ {false};
2004514f5e3Sopenharmony_ci    Mutex mutex_;
2014514f5e3Sopenharmony_ci};
2024514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
2034514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_MEM_PARALLEL_MARKER_H
204