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