14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-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_HEAP_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_HEAP_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/base/config.h" 204514f5e3Sopenharmony_ci#include "ecmascript/frames.h" 214514f5e3Sopenharmony_ci#include "ecmascript/js_object_resizing_strategy.h" 224514f5e3Sopenharmony_ci#include "ecmascript/mem/linear_space.h" 234514f5e3Sopenharmony_ci#include "ecmascript/mem/mark_stack.h" 244514f5e3Sopenharmony_ci#include "ecmascript/mem/shared_heap/shared_space.h" 254514f5e3Sopenharmony_ci#include "ecmascript/mem/sparse_space.h" 264514f5e3Sopenharmony_ci#include "ecmascript/mem/work_manager.h" 274514f5e3Sopenharmony_ci#include "ecmascript/taskpool/taskpool.h" 284514f5e3Sopenharmony_ci#include "ecmascript/mem/machine_code.h" 294514f5e3Sopenharmony_ci#include "ecmascript/mem/idle_gc_trigger.h" 304514f5e3Sopenharmony_ci 314514f5e3Sopenharmony_cinamespace panda::test { 324514f5e3Sopenharmony_ciclass GCTest_CallbackTask_Test; 334514f5e3Sopenharmony_ciclass HProfTestHelper; 344514f5e3Sopenharmony_ci} 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_cinamespace panda::ecmascript { 374514f5e3Sopenharmony_ciclass ConcurrentMarker; 384514f5e3Sopenharmony_ciclass ConcurrentSweeper; 394514f5e3Sopenharmony_ciclass EcmaVM; 404514f5e3Sopenharmony_ciclass FullGC; 414514f5e3Sopenharmony_ciclass GCStats; 424514f5e3Sopenharmony_ciclass GCKeyStats; 434514f5e3Sopenharmony_ciclass HeapRegionAllocator; 444514f5e3Sopenharmony_ciclass HeapTracker; 454514f5e3Sopenharmony_ci#if !WIN_OR_MAC_OR_IOS_PLATFORM 464514f5e3Sopenharmony_ciclass HeapProfilerInterface; 474514f5e3Sopenharmony_ciclass HeapProfiler; 484514f5e3Sopenharmony_ci#endif 494514f5e3Sopenharmony_ciclass IncrementalMarker; 504514f5e3Sopenharmony_ciclass JSNativePointer; 514514f5e3Sopenharmony_ciclass Marker; 524514f5e3Sopenharmony_ciclass MemController; 534514f5e3Sopenharmony_ciclass IdleGCTrigger; 544514f5e3Sopenharmony_ciclass NativeAreaAllocator; 554514f5e3Sopenharmony_ciclass ParallelEvacuator; 564514f5e3Sopenharmony_ciclass PartialGC; 574514f5e3Sopenharmony_ciclass RSetWorkListHandler; 584514f5e3Sopenharmony_ciclass SharedConcurrentMarker; 594514f5e3Sopenharmony_ciclass SharedConcurrentSweeper; 604514f5e3Sopenharmony_ciclass SharedGC; 614514f5e3Sopenharmony_ciclass SharedGCMarkerBase; 624514f5e3Sopenharmony_ciclass SharedGCMarker; 634514f5e3Sopenharmony_ciclass SharedFullGC; 644514f5e3Sopenharmony_ciclass SharedGCMovableMarker; 654514f5e3Sopenharmony_ciclass ThreadLocalAllocationBuffer; 664514f5e3Sopenharmony_ciclass JSThread; 674514f5e3Sopenharmony_ciclass DaemonThread; 684514f5e3Sopenharmony_ciclass GlobalEnvConstants; 694514f5e3Sopenharmony_ciclass SharedMemController; 704514f5e3Sopenharmony_ciclass IdleGCTrigger; 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ciusing IdleNotifyStatusCallback = std::function<void(bool)>; 734514f5e3Sopenharmony_ciusing FinishGCListener = void (*)(void *); 744514f5e3Sopenharmony_ciusing GCListenerId = std::vector<std::pair<FinishGCListener, void *>>::const_iterator; 754514f5e3Sopenharmony_ciusing Clock = std::chrono::high_resolution_clock; 764514f5e3Sopenharmony_ciusing AppFreezeFilterCallback = std::function<bool(const int32_t pid)>; 774514f5e3Sopenharmony_ciusing BytesAndDuration = std::pair<uint64_t, double>; 784514f5e3Sopenharmony_ciusing MemoryReduceDegree = panda::JSNApi::MemoryReduceDegree; 794514f5e3Sopenharmony_cienum class IdleTaskType : uint8_t { 804514f5e3Sopenharmony_ci NO_TASK, 814514f5e3Sopenharmony_ci YOUNG_GC, 824514f5e3Sopenharmony_ci FINISH_MARKING, 834514f5e3Sopenharmony_ci INCREMENTAL_MARK 844514f5e3Sopenharmony_ci}; 854514f5e3Sopenharmony_ci 864514f5e3Sopenharmony_cienum class MarkType : uint8_t { 874514f5e3Sopenharmony_ci MARK_EDEN, 884514f5e3Sopenharmony_ci MARK_YOUNG, 894514f5e3Sopenharmony_ci MARK_FULL 904514f5e3Sopenharmony_ci}; 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_cienum class MemGrowingType : uint8_t { 934514f5e3Sopenharmony_ci HIGH_THROUGHPUT, 944514f5e3Sopenharmony_ci CONSERVATIVE, 954514f5e3Sopenharmony_ci PRESSURE 964514f5e3Sopenharmony_ci}; 974514f5e3Sopenharmony_ci 984514f5e3Sopenharmony_cienum class HeapMode { 994514f5e3Sopenharmony_ci NORMAL, 1004514f5e3Sopenharmony_ci SPAWN, 1014514f5e3Sopenharmony_ci SHARE, 1024514f5e3Sopenharmony_ci}; 1034514f5e3Sopenharmony_ci 1044514f5e3Sopenharmony_cienum AppSensitiveStatus : uint8_t { 1054514f5e3Sopenharmony_ci NORMAL_SCENE, 1064514f5e3Sopenharmony_ci ENTER_HIGH_SENSITIVE, 1074514f5e3Sopenharmony_ci EXIT_HIGH_SENSITIVE, 1084514f5e3Sopenharmony_ci}; 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_cienum class VerifyKind { 1114514f5e3Sopenharmony_ci VERIFY_PRE_GC, 1124514f5e3Sopenharmony_ci VERIFY_POST_GC, 1134514f5e3Sopenharmony_ci VERIFY_MARK_EDEN, 1144514f5e3Sopenharmony_ci VERIFY_EVACUATE_EDEN, 1154514f5e3Sopenharmony_ci VERIFY_MARK_YOUNG, 1164514f5e3Sopenharmony_ci VERIFY_EVACUATE_YOUNG, 1174514f5e3Sopenharmony_ci VERIFY_MARK_FULL, 1184514f5e3Sopenharmony_ci VERIFY_EVACUATE_OLD, 1194514f5e3Sopenharmony_ci VERIFY_EVACUATE_FULL, 1204514f5e3Sopenharmony_ci VERIFY_SHARED_RSET_POST_FULL_GC, 1214514f5e3Sopenharmony_ci VERIFY_PRE_SHARED_GC, 1224514f5e3Sopenharmony_ci VERIFY_POST_SHARED_GC, 1234514f5e3Sopenharmony_ci VERIFY_SHARED_GC_MARK, 1244514f5e3Sopenharmony_ci VERIFY_SHARED_GC_SWEEP, 1254514f5e3Sopenharmony_ci VERIFY_END, 1264514f5e3Sopenharmony_ci}; 1274514f5e3Sopenharmony_ci 1284514f5e3Sopenharmony_ciclass BaseHeap { 1294514f5e3Sopenharmony_cipublic: 1304514f5e3Sopenharmony_ci BaseHeap(const EcmaParamConfiguration &config) : config_(config) {} 1314514f5e3Sopenharmony_ci virtual ~BaseHeap() = default; 1324514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(BaseHeap); 1334514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(BaseHeap); 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ci virtual void Destroy() = 0; 1364514f5e3Sopenharmony_ci 1374514f5e3Sopenharmony_ci virtual bool IsMarking() const = 0; 1384514f5e3Sopenharmony_ci 1394514f5e3Sopenharmony_ci virtual bool IsReadyToConcurrentMark() const = 0; 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_ci virtual bool NeedStopCollection() = 0; 1424514f5e3Sopenharmony_ci 1434514f5e3Sopenharmony_ci virtual void SetSensitiveStatus(AppSensitiveStatus status) = 0; 1444514f5e3Sopenharmony_ci 1454514f5e3Sopenharmony_ci virtual AppSensitiveStatus GetSensitiveStatus() const = 0; 1464514f5e3Sopenharmony_ci 1474514f5e3Sopenharmony_ci virtual bool FinishStartupEvent() = 0; 1484514f5e3Sopenharmony_ci 1494514f5e3Sopenharmony_ci virtual bool OnStartupEvent() const = 0; 1504514f5e3Sopenharmony_ci 1514514f5e3Sopenharmony_ci virtual void NotifyPostFork() = 0; 1524514f5e3Sopenharmony_ci 1534514f5e3Sopenharmony_ci virtual void TryTriggerIdleCollection() = 0; 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_ci virtual void TryTriggerIncrementalMarking() = 0; 1564514f5e3Sopenharmony_ci 1574514f5e3Sopenharmony_ci /* 1584514f5e3Sopenharmony_ci * Wait for existing concurrent marking tasks to be finished (if any). 1594514f5e3Sopenharmony_ci * Return true if there's ongoing concurrent marking. 1604514f5e3Sopenharmony_ci */ 1614514f5e3Sopenharmony_ci virtual bool CheckOngoingConcurrentMarking() = 0; 1624514f5e3Sopenharmony_ci 1634514f5e3Sopenharmony_ci virtual bool OldSpaceExceedCapacity(size_t size) const = 0; 1644514f5e3Sopenharmony_ci 1654514f5e3Sopenharmony_ci virtual bool OldSpaceExceedLimit() const = 0; 1664514f5e3Sopenharmony_ci 1674514f5e3Sopenharmony_ci virtual inline size_t GetCommittedSize() const = 0; 1684514f5e3Sopenharmony_ci 1694514f5e3Sopenharmony_ci virtual inline size_t GetHeapObjectSize() const = 0; 1704514f5e3Sopenharmony_ci 1714514f5e3Sopenharmony_ci virtual inline size_t GetRegionCount() const = 0; 1724514f5e3Sopenharmony_ci 1734514f5e3Sopenharmony_ci virtual void ChangeGCParams(bool inBackground) = 0; 1744514f5e3Sopenharmony_ci 1754514f5e3Sopenharmony_ci virtual const GlobalEnvConstants *GetGlobalConst() const = 0; 1764514f5e3Sopenharmony_ci 1774514f5e3Sopenharmony_ci virtual GCStats *GetEcmaGCStats() = 0; 1784514f5e3Sopenharmony_ci 1794514f5e3Sopenharmony_ci virtual bool ObjectExceedMaxHeapSize() const = 0; 1804514f5e3Sopenharmony_ci 1814514f5e3Sopenharmony_ci MarkType GetMarkType() const 1824514f5e3Sopenharmony_ci { 1834514f5e3Sopenharmony_ci return markType_; 1844514f5e3Sopenharmony_ci } 1854514f5e3Sopenharmony_ci 1864514f5e3Sopenharmony_ci void SetMarkType(MarkType markType) 1874514f5e3Sopenharmony_ci { 1884514f5e3Sopenharmony_ci markType_ = markType; 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci 1914514f5e3Sopenharmony_ci bool IsEdenMark() const 1924514f5e3Sopenharmony_ci { 1934514f5e3Sopenharmony_ci return markType_ == MarkType::MARK_EDEN; 1944514f5e3Sopenharmony_ci } 1954514f5e3Sopenharmony_ci 1964514f5e3Sopenharmony_ci bool IsYoungMark() const 1974514f5e3Sopenharmony_ci { 1984514f5e3Sopenharmony_ci return markType_ == MarkType::MARK_YOUNG; 1994514f5e3Sopenharmony_ci } 2004514f5e3Sopenharmony_ci 2014514f5e3Sopenharmony_ci bool IsFullMark() const 2024514f5e3Sopenharmony_ci { 2034514f5e3Sopenharmony_ci return markType_ == MarkType::MARK_FULL; 2044514f5e3Sopenharmony_ci } 2054514f5e3Sopenharmony_ci 2064514f5e3Sopenharmony_ci bool IsConcurrentFullMark() const 2074514f5e3Sopenharmony_ci { 2084514f5e3Sopenharmony_ci return markType_ == MarkType::MARK_FULL; 2094514f5e3Sopenharmony_ci } 2104514f5e3Sopenharmony_ci 2114514f5e3Sopenharmony_ci TriggerGCType GetGCType() const 2124514f5e3Sopenharmony_ci { 2134514f5e3Sopenharmony_ci return gcType_; 2144514f5e3Sopenharmony_ci } 2154514f5e3Sopenharmony_ci 2164514f5e3Sopenharmony_ci bool PUBLIC_API IsAlive(TaggedObject *object) const; 2174514f5e3Sopenharmony_ci 2184514f5e3Sopenharmony_ci bool ContainObject(TaggedObject *object) const; 2194514f5e3Sopenharmony_ci 2204514f5e3Sopenharmony_ci bool GetOldGCRequested() 2214514f5e3Sopenharmony_ci { 2224514f5e3Sopenharmony_ci return oldGCRequested_; 2234514f5e3Sopenharmony_ci } 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_ci EcmaParamConfiguration GetEcmaParamConfiguration() const 2264514f5e3Sopenharmony_ci { 2274514f5e3Sopenharmony_ci return config_; 2284514f5e3Sopenharmony_ci } 2294514f5e3Sopenharmony_ci 2304514f5e3Sopenharmony_ci NativeAreaAllocator *GetNativeAreaAllocator() const 2314514f5e3Sopenharmony_ci { 2324514f5e3Sopenharmony_ci return nativeAreaAllocator_; 2334514f5e3Sopenharmony_ci } 2344514f5e3Sopenharmony_ci 2354514f5e3Sopenharmony_ci HeapRegionAllocator *GetHeapRegionAllocator() const 2364514f5e3Sopenharmony_ci { 2374514f5e3Sopenharmony_ci return heapRegionAllocator_; 2384514f5e3Sopenharmony_ci } 2394514f5e3Sopenharmony_ci 2404514f5e3Sopenharmony_ci void ShouldThrowOOMError(bool shouldThrow) 2414514f5e3Sopenharmony_ci { 2424514f5e3Sopenharmony_ci shouldThrowOOMError_ = shouldThrow; 2434514f5e3Sopenharmony_ci } 2444514f5e3Sopenharmony_ci 2454514f5e3Sopenharmony_ci void SetCanThrowOOMError(bool canThrow) 2464514f5e3Sopenharmony_ci { 2474514f5e3Sopenharmony_ci canThrowOOMError_ = canThrow; 2484514f5e3Sopenharmony_ci } 2494514f5e3Sopenharmony_ci 2504514f5e3Sopenharmony_ci bool CanThrowOOMError() 2514514f5e3Sopenharmony_ci { 2524514f5e3Sopenharmony_ci return canThrowOOMError_; 2534514f5e3Sopenharmony_ci } 2544514f5e3Sopenharmony_ci 2554514f5e3Sopenharmony_ci bool IsInBackground() const 2564514f5e3Sopenharmony_ci { 2574514f5e3Sopenharmony_ci return inBackground_; 2584514f5e3Sopenharmony_ci } 2594514f5e3Sopenharmony_ci 2604514f5e3Sopenharmony_ci // ONLY used for heap verification. 2614514f5e3Sopenharmony_ci bool IsVerifying() const 2624514f5e3Sopenharmony_ci { 2634514f5e3Sopenharmony_ci return isVerifying_; 2644514f5e3Sopenharmony_ci } 2654514f5e3Sopenharmony_ci 2664514f5e3Sopenharmony_ci // ONLY used for heap verification. 2674514f5e3Sopenharmony_ci void SetVerifying(bool verifying) 2684514f5e3Sopenharmony_ci { 2694514f5e3Sopenharmony_ci isVerifying_ = verifying; 2704514f5e3Sopenharmony_ci } 2714514f5e3Sopenharmony_ci 2724514f5e3Sopenharmony_ci void NotifyHeapAliveSizeAfterGC(size_t size) 2734514f5e3Sopenharmony_ci { 2744514f5e3Sopenharmony_ci heapAliveSizeAfterGC_ = size; 2754514f5e3Sopenharmony_ci } 2764514f5e3Sopenharmony_ci 2774514f5e3Sopenharmony_ci size_t GetHeapAliveSizeAfterGC() const 2784514f5e3Sopenharmony_ci { 2794514f5e3Sopenharmony_ci return heapAliveSizeAfterGC_; 2804514f5e3Sopenharmony_ci } 2814514f5e3Sopenharmony_ci 2824514f5e3Sopenharmony_ci void UpdateHeapStatsAfterGC(TriggerGCType gcType) 2834514f5e3Sopenharmony_ci { 2844514f5e3Sopenharmony_ci if (gcType == TriggerGCType::EDEN_GC || gcType == TriggerGCType::YOUNG_GC) { 2854514f5e3Sopenharmony_ci return; 2864514f5e3Sopenharmony_ci } 2874514f5e3Sopenharmony_ci heapAliveSizeAfterGC_ = GetHeapObjectSize(); 2884514f5e3Sopenharmony_ci fragmentSizeAfterGC_ = GetCommittedSize() - GetHeapObjectSize(); 2894514f5e3Sopenharmony_ci if (gcType == TriggerGCType::FULL_GC || gcType == TriggerGCType::SHARED_FULL_GC) { 2904514f5e3Sopenharmony_ci heapBasicLoss_ = fragmentSizeAfterGC_; 2914514f5e3Sopenharmony_ci } 2924514f5e3Sopenharmony_ci } 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ci size_t GetFragmentSizeAfterGC() const 2954514f5e3Sopenharmony_ci { 2964514f5e3Sopenharmony_ci return fragmentSizeAfterGC_; 2974514f5e3Sopenharmony_ci } 2984514f5e3Sopenharmony_ci 2994514f5e3Sopenharmony_ci size_t GetHeapBasicLoss() const 3004514f5e3Sopenharmony_ci { 3014514f5e3Sopenharmony_ci return heapBasicLoss_; 3024514f5e3Sopenharmony_ci } 3034514f5e3Sopenharmony_ci 3044514f5e3Sopenharmony_ci size_t GetGlobalSpaceAllocLimit() const 3054514f5e3Sopenharmony_ci { 3064514f5e3Sopenharmony_ci return globalSpaceAllocLimit_; 3074514f5e3Sopenharmony_ci } 3084514f5e3Sopenharmony_ci 3094514f5e3Sopenharmony_ci // Whether should verify heap during gc. 3104514f5e3Sopenharmony_ci bool ShouldVerifyHeap() const 3114514f5e3Sopenharmony_ci { 3124514f5e3Sopenharmony_ci return shouldVerifyHeap_; 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci 3154514f5e3Sopenharmony_ci void ThrowOutOfMemoryErrorForDefault(JSThread *thread, size_t size, std::string functionName, 3164514f5e3Sopenharmony_ci bool NonMovableObjNearOOM = false); 3174514f5e3Sopenharmony_ci 3184514f5e3Sopenharmony_ci uint32_t GetMaxMarkTaskCount() const 3194514f5e3Sopenharmony_ci { 3204514f5e3Sopenharmony_ci return maxMarkTaskCount_; 3214514f5e3Sopenharmony_ci } 3224514f5e3Sopenharmony_ci 3234514f5e3Sopenharmony_ci bool InSensitiveStatus() const 3244514f5e3Sopenharmony_ci { 3254514f5e3Sopenharmony_ci return GetSensitiveStatus() == AppSensitiveStatus::ENTER_HIGH_SENSITIVE || OnStartupEvent(); 3264514f5e3Sopenharmony_ci } 3274514f5e3Sopenharmony_ci 3284514f5e3Sopenharmony_ci void OnAllocateEvent(EcmaVM *ecmaVm, TaggedObject* address, size_t size); 3294514f5e3Sopenharmony_ci inline void SetHClassAndDoAllocateEvent(JSThread *thread, TaggedObject *object, JSHClass *hclass, 3304514f5e3Sopenharmony_ci [[maybe_unused]] size_t size); 3314514f5e3Sopenharmony_ci bool CheckCanDistributeTask(); 3324514f5e3Sopenharmony_ci void IncreaseTaskCount(); 3334514f5e3Sopenharmony_ci void ReduceTaskCount(); 3344514f5e3Sopenharmony_ci void WaitRunningTaskFinished(); 3354514f5e3Sopenharmony_ci void WaitClearTaskFinished(); 3364514f5e3Sopenharmony_ci void ThrowOutOfMemoryError(JSThread *thread, size_t size, std::string functionName, 3374514f5e3Sopenharmony_ci bool NonMovableObjNearOOM = false); 3384514f5e3Sopenharmony_ci void SetMachineCodeOutOfMemoryError(JSThread *thread, size_t size, std::string functionName); 3394514f5e3Sopenharmony_ci void SetAppFreezeFilterCallback(AppFreezeFilterCallback cb); 3404514f5e3Sopenharmony_ci 3414514f5e3Sopenharmony_ci#ifndef NDEBUG 3424514f5e3Sopenharmony_ci bool TriggerCollectionOnNewObjectEnabled() const 3434514f5e3Sopenharmony_ci { 3444514f5e3Sopenharmony_ci return triggerCollectionOnNewObject_; 3454514f5e3Sopenharmony_ci }; 3464514f5e3Sopenharmony_ci 3474514f5e3Sopenharmony_ci void EnableTriggerCollectionOnNewObject() 3484514f5e3Sopenharmony_ci { 3494514f5e3Sopenharmony_ci triggerCollectionOnNewObject_ = true; 3504514f5e3Sopenharmony_ci } 3514514f5e3Sopenharmony_ci 3524514f5e3Sopenharmony_ci void DisableTriggerCollectionOnNewObject() 3534514f5e3Sopenharmony_ci { 3544514f5e3Sopenharmony_ci triggerCollectionOnNewObject_ = false; 3554514f5e3Sopenharmony_ci } 3564514f5e3Sopenharmony_ci#endif 3574514f5e3Sopenharmony_ci 3584514f5e3Sopenharmony_ciprotected: 3594514f5e3Sopenharmony_ci void FatalOutOfMemoryError(size_t size, std::string functionName); 3604514f5e3Sopenharmony_ci 3614514f5e3Sopenharmony_ci enum class HeapType { 3624514f5e3Sopenharmony_ci LOCAL_HEAP, 3634514f5e3Sopenharmony_ci SHARED_HEAP, 3644514f5e3Sopenharmony_ci INVALID, 3654514f5e3Sopenharmony_ci }; 3664514f5e3Sopenharmony_ci 3674514f5e3Sopenharmony_ci class RecursionScope { 3684514f5e3Sopenharmony_ci public: 3694514f5e3Sopenharmony_ci explicit RecursionScope(BaseHeap* heap, HeapType heapType) : heap_(heap), heapType_(heapType) 3704514f5e3Sopenharmony_ci { 3714514f5e3Sopenharmony_ci if (heap_->recursionDepth_++ != 0) { 3724514f5e3Sopenharmony_ci LOG_GC(FATAL) << "Recursion in HeapCollectGarbage(isShared=" << static_cast<int>(heapType_) 3734514f5e3Sopenharmony_ci << ") Constructor, depth: " << heap_->recursionDepth_; 3744514f5e3Sopenharmony_ci } 3754514f5e3Sopenharmony_ci } 3764514f5e3Sopenharmony_ci ~RecursionScope() 3774514f5e3Sopenharmony_ci { 3784514f5e3Sopenharmony_ci if (--heap_->recursionDepth_ != 0) { 3794514f5e3Sopenharmony_ci LOG_GC(FATAL) << "Recursion in HeapCollectGarbage(isShared=" << static_cast<int>(heapType_) 3804514f5e3Sopenharmony_ci << ") Destructor, depth: " << heap_->recursionDepth_; 3814514f5e3Sopenharmony_ci } 3824514f5e3Sopenharmony_ci } 3834514f5e3Sopenharmony_ci private: 3844514f5e3Sopenharmony_ci BaseHeap *heap_ {nullptr}; 3854514f5e3Sopenharmony_ci HeapType heapType_ {HeapType::INVALID}; 3864514f5e3Sopenharmony_ci }; 3874514f5e3Sopenharmony_ci 3884514f5e3Sopenharmony_ci static constexpr double TRIGGER_SHARED_CONCURRENT_MARKING_OBJECT_LIMIT_RATE = 0.75; 3894514f5e3Sopenharmony_ci 3904514f5e3Sopenharmony_ci const EcmaParamConfiguration config_; 3914514f5e3Sopenharmony_ci MarkType markType_ {MarkType::MARK_YOUNG}; 3924514f5e3Sopenharmony_ci TriggerGCType gcType_ {TriggerGCType::YOUNG_GC}; 3934514f5e3Sopenharmony_ci Mutex gcCollectGarbageMutex_; 3944514f5e3Sopenharmony_ci // Region allocators. 3954514f5e3Sopenharmony_ci NativeAreaAllocator *nativeAreaAllocator_ {nullptr}; 3964514f5e3Sopenharmony_ci HeapRegionAllocator *heapRegionAllocator_ {nullptr}; 3974514f5e3Sopenharmony_ci 3984514f5e3Sopenharmony_ci size_t heapAliveSizeAfterGC_ {0}; 3994514f5e3Sopenharmony_ci size_t globalSpaceAllocLimit_ {0}; 4004514f5e3Sopenharmony_ci size_t globalSpaceConcurrentMarkLimit_ {0}; 4014514f5e3Sopenharmony_ci size_t heapBasicLoss_ {1_MB}; 4024514f5e3Sopenharmony_ci size_t fragmentSizeAfterGC_ {0}; 4034514f5e3Sopenharmony_ci // parallel marker task count. 4044514f5e3Sopenharmony_ci uint32_t runningTaskCount_ {0}; 4054514f5e3Sopenharmony_ci uint32_t maxMarkTaskCount_ {0}; 4064514f5e3Sopenharmony_ci Mutex waitTaskFinishedMutex_; 4074514f5e3Sopenharmony_ci ConditionVariable waitTaskFinishedCV_; 4084514f5e3Sopenharmony_ci Mutex waitClearTaskFinishedMutex_; 4094514f5e3Sopenharmony_ci ConditionVariable waitClearTaskFinishedCV_; 4104514f5e3Sopenharmony_ci AppFreezeFilterCallback appfreezeCallback_ {nullptr}; 4114514f5e3Sopenharmony_ci bool clearTaskFinished_ {true}; 4124514f5e3Sopenharmony_ci bool inBackground_ {false}; 4134514f5e3Sopenharmony_ci bool shouldThrowOOMError_ {false}; 4144514f5e3Sopenharmony_ci bool canThrowOOMError_ {true}; 4154514f5e3Sopenharmony_ci bool oldGCRequested_ {false}; 4164514f5e3Sopenharmony_ci // ONLY used for heap verification. 4174514f5e3Sopenharmony_ci bool shouldVerifyHeap_ {false}; 4184514f5e3Sopenharmony_ci bool isVerifying_ {false}; 4194514f5e3Sopenharmony_ci int32_t recursionDepth_ {0}; 4204514f5e3Sopenharmony_ci#ifndef NDEBUG 4214514f5e3Sopenharmony_ci bool triggerCollectionOnNewObject_ {true}; 4224514f5e3Sopenharmony_ci#endif 4234514f5e3Sopenharmony_ci}; 4244514f5e3Sopenharmony_ci 4254514f5e3Sopenharmony_ciclass SharedHeap : public BaseHeap { 4264514f5e3Sopenharmony_cipublic: 4274514f5e3Sopenharmony_ci SharedHeap(const EcmaParamConfiguration &config) : BaseHeap(config) {} 4284514f5e3Sopenharmony_ci virtual ~SharedHeap() = default; 4294514f5e3Sopenharmony_ci 4304514f5e3Sopenharmony_ci static void CreateNewInstance(); 4314514f5e3Sopenharmony_ci static SharedHeap *GetInstance(); 4324514f5e3Sopenharmony_ci static void DestroyInstance(); 4334514f5e3Sopenharmony_ci 4344514f5e3Sopenharmony_ci void Initialize(NativeAreaAllocator *nativeAreaAllocator, HeapRegionAllocator *heapRegionAllocator, 4354514f5e3Sopenharmony_ci const JSRuntimeOptions &option, DaemonThread *dThread); 4364514f5e3Sopenharmony_ci 4374514f5e3Sopenharmony_ci void Destroy() override; 4384514f5e3Sopenharmony_ci 4394514f5e3Sopenharmony_ci void PostInitialization(const GlobalEnvConstants *globalEnvConstants, const JSRuntimeOptions &option); 4404514f5e3Sopenharmony_ci 4414514f5e3Sopenharmony_ci void EnableParallelGC(JSRuntimeOptions &option); 4424514f5e3Sopenharmony_ci 4434514f5e3Sopenharmony_ci void DisableParallelGC(JSThread *thread); 4444514f5e3Sopenharmony_ci 4454514f5e3Sopenharmony_ci void AdjustGlobalSpaceAllocLimit(); 4464514f5e3Sopenharmony_ci 4474514f5e3Sopenharmony_ci void OnMoveEvent(uintptr_t address, TaggedObject* forwardAddress, size_t size); 4484514f5e3Sopenharmony_ci 4494514f5e3Sopenharmony_ci class ParallelMarkTask : public Task { 4504514f5e3Sopenharmony_ci public: 4514514f5e3Sopenharmony_ci ParallelMarkTask(int32_t id, SharedHeap *heap, SharedParallelMarkPhase taskPhase) 4524514f5e3Sopenharmony_ci : Task(id), sHeap_(heap), taskPhase_(taskPhase) {}; 4534514f5e3Sopenharmony_ci ~ParallelMarkTask() override = default; 4544514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 4554514f5e3Sopenharmony_ci 4564514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(ParallelMarkTask); 4574514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(ParallelMarkTask); 4584514f5e3Sopenharmony_ci 4594514f5e3Sopenharmony_ci private: 4604514f5e3Sopenharmony_ci SharedHeap *sHeap_ {nullptr}; 4614514f5e3Sopenharmony_ci SharedParallelMarkPhase taskPhase_; 4624514f5e3Sopenharmony_ci }; 4634514f5e3Sopenharmony_ci 4644514f5e3Sopenharmony_ci class AsyncClearTask : public Task { 4654514f5e3Sopenharmony_ci public: 4664514f5e3Sopenharmony_ci AsyncClearTask(int32_t id, SharedHeap *heap, TriggerGCType type) 4674514f5e3Sopenharmony_ci : Task(id), sHeap_(heap), gcType_(type) {} 4684514f5e3Sopenharmony_ci ~AsyncClearTask() override = default; 4694514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 4704514f5e3Sopenharmony_ci 4714514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(AsyncClearTask); 4724514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(AsyncClearTask); 4734514f5e3Sopenharmony_ci private: 4744514f5e3Sopenharmony_ci SharedHeap *sHeap_; 4754514f5e3Sopenharmony_ci TriggerGCType gcType_; 4764514f5e3Sopenharmony_ci }; 4774514f5e3Sopenharmony_ci bool IsMarking() const override 4784514f5e3Sopenharmony_ci { 4794514f5e3Sopenharmony_ci LOG_FULL(ERROR) << "SharedHeap IsMarking() not support yet"; 4804514f5e3Sopenharmony_ci return false; 4814514f5e3Sopenharmony_ci } 4824514f5e3Sopenharmony_ci 4834514f5e3Sopenharmony_ci bool IsReadyToConcurrentMark() const override; 4844514f5e3Sopenharmony_ci 4854514f5e3Sopenharmony_ci bool NeedStopCollection() override; 4864514f5e3Sopenharmony_ci 4874514f5e3Sopenharmony_ci void SetSensitiveStatus(AppSensitiveStatus status) override 4884514f5e3Sopenharmony_ci { 4894514f5e3Sopenharmony_ci LockHolder lock(smartGCStats_.sensitiveStatusMutex_); 4904514f5e3Sopenharmony_ci smartGCStats_.sensitiveStatus_ = status; 4914514f5e3Sopenharmony_ci if (!InSensitiveStatus()) { 4924514f5e3Sopenharmony_ci smartGCStats_.sensitiveStatusCV_.Signal(); 4934514f5e3Sopenharmony_ci } 4944514f5e3Sopenharmony_ci } 4954514f5e3Sopenharmony_ci 4964514f5e3Sopenharmony_ci // This should be called when holding lock of sensitiveStatusMutex_. 4974514f5e3Sopenharmony_ci AppSensitiveStatus GetSensitiveStatus() const override 4984514f5e3Sopenharmony_ci { 4994514f5e3Sopenharmony_ci return smartGCStats_.sensitiveStatus_; 5004514f5e3Sopenharmony_ci } 5014514f5e3Sopenharmony_ci 5024514f5e3Sopenharmony_ci bool FinishStartupEvent() override 5034514f5e3Sopenharmony_ci { 5044514f5e3Sopenharmony_ci LockHolder lock(smartGCStats_.sensitiveStatusMutex_); 5054514f5e3Sopenharmony_ci if (!smartGCStats_.onStartupEvent_) { 5064514f5e3Sopenharmony_ci return false; 5074514f5e3Sopenharmony_ci } 5084514f5e3Sopenharmony_ci smartGCStats_.onStartupEvent_ = false; 5094514f5e3Sopenharmony_ci if (!InSensitiveStatus()) { 5104514f5e3Sopenharmony_ci smartGCStats_.sensitiveStatusCV_.Signal(); 5114514f5e3Sopenharmony_ci } 5124514f5e3Sopenharmony_ci return true; 5134514f5e3Sopenharmony_ci } 5144514f5e3Sopenharmony_ci 5154514f5e3Sopenharmony_ci // This should be called when holding lock of sensitiveStatusMutex_. 5164514f5e3Sopenharmony_ci bool OnStartupEvent() const override 5174514f5e3Sopenharmony_ci { 5184514f5e3Sopenharmony_ci return smartGCStats_.onStartupEvent_; 5194514f5e3Sopenharmony_ci } 5204514f5e3Sopenharmony_ci 5214514f5e3Sopenharmony_ci void NotifyPostFork() override 5224514f5e3Sopenharmony_ci { 5234514f5e3Sopenharmony_ci LockHolder lock(smartGCStats_.sensitiveStatusMutex_); 5244514f5e3Sopenharmony_ci smartGCStats_.onStartupEvent_ = true; 5254514f5e3Sopenharmony_ci } 5264514f5e3Sopenharmony_ci 5274514f5e3Sopenharmony_ci void WaitSensitiveStatusFinished() 5284514f5e3Sopenharmony_ci { 5294514f5e3Sopenharmony_ci LockHolder lock(smartGCStats_.sensitiveStatusMutex_); 5304514f5e3Sopenharmony_ci while (InSensitiveStatus() && !smartGCStats_.forceGC_) { 5314514f5e3Sopenharmony_ci smartGCStats_.sensitiveStatusCV_.Wait(&smartGCStats_.sensitiveStatusMutex_); 5324514f5e3Sopenharmony_ci } 5334514f5e3Sopenharmony_ci } 5344514f5e3Sopenharmony_ci 5354514f5e3Sopenharmony_ci bool ObjectExceedMaxHeapSize() const override; 5364514f5e3Sopenharmony_ci 5374514f5e3Sopenharmony_ci bool CheckAndTriggerSharedGC(JSThread *thread); 5384514f5e3Sopenharmony_ci 5394514f5e3Sopenharmony_ci bool CheckHugeAndTriggerSharedGC(JSThread *thread, size_t size); 5404514f5e3Sopenharmony_ci 5414514f5e3Sopenharmony_ci void TryTriggerLocalConcurrentMarking(); 5424514f5e3Sopenharmony_ci 5434514f5e3Sopenharmony_ci // Called when all vm is destroyed, and try to destroy daemon thread. 5444514f5e3Sopenharmony_ci void WaitAllTasksFinishedAfterAllJSThreadEliminated(); 5454514f5e3Sopenharmony_ci 5464514f5e3Sopenharmony_ci void WaitAllTasksFinished(JSThread *thread); 5474514f5e3Sopenharmony_ci 5484514f5e3Sopenharmony_ci void StartConcurrentMarking(TriggerGCType gcType, GCReason gcReason); // In daemon thread 5494514f5e3Sopenharmony_ci 5504514f5e3Sopenharmony_ci // Use JSThread instead of DaemonThread to check if IsReadyToSharedConcurrentMark, to avoid an atomic load. 5514514f5e3Sopenharmony_ci bool CheckCanTriggerConcurrentMarking(JSThread *thread); 5524514f5e3Sopenharmony_ci 5534514f5e3Sopenharmony_ci void TryTriggerIdleCollection() override 5544514f5e3Sopenharmony_ci { 5554514f5e3Sopenharmony_ci LOG_FULL(ERROR) << "SharedHeap TryTriggerIdleCollection() not support yet"; 5564514f5e3Sopenharmony_ci return; 5574514f5e3Sopenharmony_ci } 5584514f5e3Sopenharmony_ci 5594514f5e3Sopenharmony_ci void TryTriggerIncrementalMarking() override 5604514f5e3Sopenharmony_ci { 5614514f5e3Sopenharmony_ci LOG_FULL(ERROR) << "SharedHeap TryTriggerIncrementalMarking() not support yet"; 5624514f5e3Sopenharmony_ci return; 5634514f5e3Sopenharmony_ci } 5644514f5e3Sopenharmony_ci 5654514f5e3Sopenharmony_ci void UpdateWorkManager(SharedGCWorkManager *sWorkManager); 5664514f5e3Sopenharmony_ci 5674514f5e3Sopenharmony_ci bool CheckOngoingConcurrentMarking() override; 5684514f5e3Sopenharmony_ci 5694514f5e3Sopenharmony_ci bool OldSpaceExceedCapacity(size_t size) const override 5704514f5e3Sopenharmony_ci { 5714514f5e3Sopenharmony_ci size_t totalSize = sOldSpace_->GetCommittedSize() + size; 5724514f5e3Sopenharmony_ci return totalSize >= sOldSpace_->GetMaximumCapacity() + sOldSpace_->GetOutOfMemoryOvershootSize(); 5734514f5e3Sopenharmony_ci } 5744514f5e3Sopenharmony_ci 5754514f5e3Sopenharmony_ci bool OldSpaceExceedLimit() const override 5764514f5e3Sopenharmony_ci { 5774514f5e3Sopenharmony_ci return sOldSpace_->GetHeapObjectSize() >= sOldSpace_->GetInitialCapacity(); 5784514f5e3Sopenharmony_ci } 5794514f5e3Sopenharmony_ci 5804514f5e3Sopenharmony_ci SharedConcurrentMarker *GetConcurrentMarker() const 5814514f5e3Sopenharmony_ci { 5824514f5e3Sopenharmony_ci return sConcurrentMarker_; 5834514f5e3Sopenharmony_ci } 5844514f5e3Sopenharmony_ci 5854514f5e3Sopenharmony_ci SharedConcurrentSweeper *GetSweeper() const 5864514f5e3Sopenharmony_ci { 5874514f5e3Sopenharmony_ci return sSweeper_; 5884514f5e3Sopenharmony_ci } 5894514f5e3Sopenharmony_ci 5904514f5e3Sopenharmony_ci bool IsParallelGCEnabled() const 5914514f5e3Sopenharmony_ci { 5924514f5e3Sopenharmony_ci return parallelGC_; 5934514f5e3Sopenharmony_ci } 5944514f5e3Sopenharmony_ci 5954514f5e3Sopenharmony_ci SharedOldSpace *GetOldSpace() const 5964514f5e3Sopenharmony_ci { 5974514f5e3Sopenharmony_ci return sOldSpace_; 5984514f5e3Sopenharmony_ci } 5994514f5e3Sopenharmony_ci 6004514f5e3Sopenharmony_ci SharedNonMovableSpace *GetNonMovableSpace() const 6014514f5e3Sopenharmony_ci { 6024514f5e3Sopenharmony_ci return sNonMovableSpace_; 6034514f5e3Sopenharmony_ci } 6044514f5e3Sopenharmony_ci 6054514f5e3Sopenharmony_ci SharedHugeObjectSpace *GetHugeObjectSpace() const 6064514f5e3Sopenharmony_ci { 6074514f5e3Sopenharmony_ci return sHugeObjectSpace_; 6084514f5e3Sopenharmony_ci } 6094514f5e3Sopenharmony_ci 6104514f5e3Sopenharmony_ci SharedReadOnlySpace *GetReadOnlySpace() const 6114514f5e3Sopenharmony_ci { 6124514f5e3Sopenharmony_ci return sReadOnlySpace_; 6134514f5e3Sopenharmony_ci } 6144514f5e3Sopenharmony_ci 6154514f5e3Sopenharmony_ci SharedAppSpawnSpace *GetAppSpawnSpace() const 6164514f5e3Sopenharmony_ci { 6174514f5e3Sopenharmony_ci return sAppSpawnSpace_; 6184514f5e3Sopenharmony_ci } 6194514f5e3Sopenharmony_ci 6204514f5e3Sopenharmony_ci void SetForceGC(bool forceGC) 6214514f5e3Sopenharmony_ci { 6224514f5e3Sopenharmony_ci LockHolder lock(smartGCStats_.sensitiveStatusMutex_); 6234514f5e3Sopenharmony_ci smartGCStats_.forceGC_ = forceGC; 6244514f5e3Sopenharmony_ci if (smartGCStats_.forceGC_) { 6254514f5e3Sopenharmony_ci smartGCStats_.sensitiveStatusCV_.Signal(); 6264514f5e3Sopenharmony_ci } 6274514f5e3Sopenharmony_ci } 6284514f5e3Sopenharmony_ci 6294514f5e3Sopenharmony_ci inline void TryTriggerConcurrentMarking(JSThread *thread); 6304514f5e3Sopenharmony_ci 6314514f5e3Sopenharmony_ci template<TriggerGCType gcType, GCReason gcReason> 6324514f5e3Sopenharmony_ci void TriggerConcurrentMarking(JSThread *thread); 6334514f5e3Sopenharmony_ci 6344514f5e3Sopenharmony_ci template<TriggerGCType gcType, GCReason gcReason> 6354514f5e3Sopenharmony_ci void CollectGarbage(JSThread *thread); 6364514f5e3Sopenharmony_ci 6374514f5e3Sopenharmony_ci // Only means the main body of SharedGC is finished, i.e. if parallel_gc is enabled, this flags will be set 6384514f5e3Sopenharmony_ci // to true even if sweep_task and clear_task is running asynchronously 6394514f5e3Sopenharmony_ci void NotifyGCCompleted(); // In daemon thread 6404514f5e3Sopenharmony_ci 6414514f5e3Sopenharmony_ci // Called when all vm is destroyed, and try to destroy daemon thread 6424514f5e3Sopenharmony_ci void WaitGCFinishedAfterAllJSThreadEliminated(); 6434514f5e3Sopenharmony_ci 6444514f5e3Sopenharmony_ci void WaitGCFinished(JSThread *thread); 6454514f5e3Sopenharmony_ci 6464514f5e3Sopenharmony_ci void DaemonCollectGarbage(TriggerGCType gcType, GCReason reason); 6474514f5e3Sopenharmony_ci 6484514f5e3Sopenharmony_ci void SetMaxMarkTaskCount(uint32_t maxTaskCount) 6494514f5e3Sopenharmony_ci { 6504514f5e3Sopenharmony_ci maxMarkTaskCount_ = maxTaskCount; 6514514f5e3Sopenharmony_ci } 6524514f5e3Sopenharmony_ci 6534514f5e3Sopenharmony_ci inline size_t GetCommittedSize() const override 6544514f5e3Sopenharmony_ci { 6554514f5e3Sopenharmony_ci size_t result = sOldSpace_->GetCommittedSize() + 6564514f5e3Sopenharmony_ci sHugeObjectSpace_->GetCommittedSize() + 6574514f5e3Sopenharmony_ci sNonMovableSpace_->GetCommittedSize() + 6584514f5e3Sopenharmony_ci sReadOnlySpace_->GetCommittedSize(); 6594514f5e3Sopenharmony_ci return result; 6604514f5e3Sopenharmony_ci } 6614514f5e3Sopenharmony_ci 6624514f5e3Sopenharmony_ci inline size_t GetHeapObjectSize() const override 6634514f5e3Sopenharmony_ci { 6644514f5e3Sopenharmony_ci size_t result = sOldSpace_->GetHeapObjectSize() + 6654514f5e3Sopenharmony_ci sHugeObjectSpace_->GetHeapObjectSize() + 6664514f5e3Sopenharmony_ci sNonMovableSpace_->GetHeapObjectSize() + 6674514f5e3Sopenharmony_ci sReadOnlySpace_->GetCommittedSize(); 6684514f5e3Sopenharmony_ci return result; 6694514f5e3Sopenharmony_ci } 6704514f5e3Sopenharmony_ci 6714514f5e3Sopenharmony_ci inline size_t GetRegionCount() const override 6724514f5e3Sopenharmony_ci { 6734514f5e3Sopenharmony_ci size_t result = sOldSpace_->GetRegionCount() + 6744514f5e3Sopenharmony_ci sHugeObjectSpace_->GetRegionCount() + 6754514f5e3Sopenharmony_ci sNonMovableSpace_->GetRegionCount() + 6764514f5e3Sopenharmony_ci sReadOnlySpace_->GetRegionCount(); 6774514f5e3Sopenharmony_ci return result; 6784514f5e3Sopenharmony_ci } 6794514f5e3Sopenharmony_ci 6804514f5e3Sopenharmony_ci void ResetNativeSizeAfterLastGC() 6814514f5e3Sopenharmony_ci { 6824514f5e3Sopenharmony_ci nativeSizeAfterLastGC_.store(0, std::memory_order_relaxed); 6834514f5e3Sopenharmony_ci } 6844514f5e3Sopenharmony_ci 6854514f5e3Sopenharmony_ci void IncNativeSizeAfterLastGC(size_t size) 6864514f5e3Sopenharmony_ci { 6874514f5e3Sopenharmony_ci nativeSizeAfterLastGC_.fetch_add(size, std::memory_order_relaxed); 6884514f5e3Sopenharmony_ci } 6894514f5e3Sopenharmony_ci 6904514f5e3Sopenharmony_ci size_t GetNativeSizeAfterLastGC() const 6914514f5e3Sopenharmony_ci { 6924514f5e3Sopenharmony_ci return nativeSizeAfterLastGC_.load(std::memory_order_relaxed); 6934514f5e3Sopenharmony_ci } 6944514f5e3Sopenharmony_ci 6954514f5e3Sopenharmony_ci size_t GetNativeSizeTriggerSharedGC() const 6964514f5e3Sopenharmony_ci { 6974514f5e3Sopenharmony_ci return incNativeSizeTriggerSharedGC_; 6984514f5e3Sopenharmony_ci } 6994514f5e3Sopenharmony_ci 7004514f5e3Sopenharmony_ci size_t GetNativeSizeTriggerSharedCM() const 7014514f5e3Sopenharmony_ci { 7024514f5e3Sopenharmony_ci return incNativeSizeTriggerSharedCM_; 7034514f5e3Sopenharmony_ci } 7044514f5e3Sopenharmony_ci 7054514f5e3Sopenharmony_ci void ChangeGCParams([[maybe_unused]]bool inBackground) override 7064514f5e3Sopenharmony_ci { 7074514f5e3Sopenharmony_ci LOG_FULL(ERROR) << "SharedHeap ChangeGCParams() not support yet"; 7084514f5e3Sopenharmony_ci return; 7094514f5e3Sopenharmony_ci } 7104514f5e3Sopenharmony_ci 7114514f5e3Sopenharmony_ci GCStats *GetEcmaGCStats() override 7124514f5e3Sopenharmony_ci { 7134514f5e3Sopenharmony_ci return sGCStats_; 7144514f5e3Sopenharmony_ci } 7154514f5e3Sopenharmony_ci 7164514f5e3Sopenharmony_ci inline void SetGlobalEnvConstants(const GlobalEnvConstants *globalEnvConstants) 7174514f5e3Sopenharmony_ci { 7184514f5e3Sopenharmony_ci globalEnvConstants_ = globalEnvConstants; 7194514f5e3Sopenharmony_ci } 7204514f5e3Sopenharmony_ci 7214514f5e3Sopenharmony_ci inline const GlobalEnvConstants *GetGlobalConst() const override 7224514f5e3Sopenharmony_ci { 7234514f5e3Sopenharmony_ci return globalEnvConstants_; 7244514f5e3Sopenharmony_ci } 7254514f5e3Sopenharmony_ci 7264514f5e3Sopenharmony_ci SharedSparseSpace *GetSpaceWithType(MemSpaceType type) const 7274514f5e3Sopenharmony_ci { 7284514f5e3Sopenharmony_ci switch (type) { 7294514f5e3Sopenharmony_ci case MemSpaceType::SHARED_OLD_SPACE: 7304514f5e3Sopenharmony_ci return sOldSpace_; 7314514f5e3Sopenharmony_ci case MemSpaceType::SHARED_NON_MOVABLE: 7324514f5e3Sopenharmony_ci return sNonMovableSpace_; 7334514f5e3Sopenharmony_ci default: 7344514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 7354514f5e3Sopenharmony_ci UNREACHABLE(); 7364514f5e3Sopenharmony_ci break; 7374514f5e3Sopenharmony_ci } 7384514f5e3Sopenharmony_ci } 7394514f5e3Sopenharmony_ci 7404514f5e3Sopenharmony_ci void Prepare(bool inTriggerGCThread); 7414514f5e3Sopenharmony_ci void Reclaim(TriggerGCType gcType); 7424514f5e3Sopenharmony_ci void PostGCMarkingTask(SharedParallelMarkPhase sharedTaskPhase); 7434514f5e3Sopenharmony_ci void CompactHeapBeforeFork(JSThread *thread); 7444514f5e3Sopenharmony_ci void ReclaimForAppSpawn(); 7454514f5e3Sopenharmony_ci 7464514f5e3Sopenharmony_ci SharedGCWorkManager *GetWorkManager() const 7474514f5e3Sopenharmony_ci { 7484514f5e3Sopenharmony_ci return sWorkManager_; 7494514f5e3Sopenharmony_ci } 7504514f5e3Sopenharmony_ci 7514514f5e3Sopenharmony_ci SharedGCMarker *GetSharedGCMarker() const 7524514f5e3Sopenharmony_ci { 7534514f5e3Sopenharmony_ci return sharedGCMarker_; 7544514f5e3Sopenharmony_ci } 7554514f5e3Sopenharmony_ci 7564514f5e3Sopenharmony_ci SharedGCMovableMarker *GetSharedGCMovableMarker() const 7574514f5e3Sopenharmony_ci { 7584514f5e3Sopenharmony_ci return sharedGCMovableMarker_; 7594514f5e3Sopenharmony_ci } 7604514f5e3Sopenharmony_ci inline void SwapOldSpace(); 7614514f5e3Sopenharmony_ci 7624514f5e3Sopenharmony_ci SharedMemController *GetSharedMemController() const 7634514f5e3Sopenharmony_ci { 7644514f5e3Sopenharmony_ci return sharedMemController_; 7654514f5e3Sopenharmony_ci } 7664514f5e3Sopenharmony_ci 7674514f5e3Sopenharmony_ci void PrepareRecordRegionsForReclaim(); 7684514f5e3Sopenharmony_ci 7694514f5e3Sopenharmony_ci template<class Callback> 7704514f5e3Sopenharmony_ci void EnumerateOldSpaceRegions(const Callback &cb) const; 7714514f5e3Sopenharmony_ci 7724514f5e3Sopenharmony_ci template<class Callback> 7734514f5e3Sopenharmony_ci void EnumerateOldSpaceRegionsWithRecord(const Callback &cb) const; 7744514f5e3Sopenharmony_ci 7754514f5e3Sopenharmony_ci template<class Callback> 7764514f5e3Sopenharmony_ci void IterateOverObjects(const Callback &cb) const; 7774514f5e3Sopenharmony_ci 7784514f5e3Sopenharmony_ci inline TaggedObject *AllocateClassClass(JSThread *thread, JSHClass *hclass, size_t size); 7794514f5e3Sopenharmony_ci 7804514f5e3Sopenharmony_ci inline TaggedObject *AllocateNonMovableOrHugeObject(JSThread *thread, JSHClass *hclass); 7814514f5e3Sopenharmony_ci 7824514f5e3Sopenharmony_ci inline TaggedObject *AllocateNonMovableOrHugeObject(JSThread *thread, JSHClass *hclass, size_t size); 7834514f5e3Sopenharmony_ci 7844514f5e3Sopenharmony_ci inline TaggedObject *AllocateNonMovableOrHugeObject(JSThread *thread, size_t size); 7854514f5e3Sopenharmony_ci 7864514f5e3Sopenharmony_ci inline TaggedObject *AllocateOldOrHugeObject(JSThread *thread, JSHClass *hclass); 7874514f5e3Sopenharmony_ci 7884514f5e3Sopenharmony_ci inline TaggedObject *AllocateOldOrHugeObject(JSThread *thread, JSHClass *hclass, size_t size); 7894514f5e3Sopenharmony_ci 7904514f5e3Sopenharmony_ci inline TaggedObject *AllocateOldOrHugeObject(JSThread *thread, size_t size); 7914514f5e3Sopenharmony_ci 7924514f5e3Sopenharmony_ci inline TaggedObject *AllocateHugeObject(JSThread *thread, JSHClass *hclass, size_t size); 7934514f5e3Sopenharmony_ci 7944514f5e3Sopenharmony_ci inline TaggedObject *AllocateHugeObject(JSThread *thread, size_t size); 7954514f5e3Sopenharmony_ci 7964514f5e3Sopenharmony_ci inline TaggedObject *AllocateReadOnlyOrHugeObject(JSThread *thread, JSHClass *hclass); 7974514f5e3Sopenharmony_ci 7984514f5e3Sopenharmony_ci inline TaggedObject *AllocateReadOnlyOrHugeObject(JSThread *thread, JSHClass *hclass, size_t size); 7994514f5e3Sopenharmony_ci 8004514f5e3Sopenharmony_ci inline TaggedObject *AllocateSNonMovableTlab(JSThread *thread, size_t size); 8014514f5e3Sopenharmony_ci 8024514f5e3Sopenharmony_ci inline TaggedObject *AllocateSOldTlab(JSThread *thread, size_t size); 8034514f5e3Sopenharmony_ci 8044514f5e3Sopenharmony_ci size_t VerifyHeapObjects(VerifyKind verifyKind) const; 8054514f5e3Sopenharmony_ci 8064514f5e3Sopenharmony_ci inline void MergeToOldSpaceSync(SharedLocalSpace *localSpace); 8074514f5e3Sopenharmony_ci 8084514f5e3Sopenharmony_ci void DumpHeapSnapshotBeforeOOM(bool isFullGC, JSThread *thread); 8094514f5e3Sopenharmony_ci 8104514f5e3Sopenharmony_ci inline void ProcessSharedNativeDelete(const WeakRootVisitor& visitor); 8114514f5e3Sopenharmony_ci inline void PushToSharedNativePointerList(JSNativePointer* pointer); 8124514f5e3Sopenharmony_ci 8134514f5e3Sopenharmony_ci class SharedGCScope { 8144514f5e3Sopenharmony_ci public: 8154514f5e3Sopenharmony_ci SharedGCScope(); 8164514f5e3Sopenharmony_ci ~SharedGCScope(); 8174514f5e3Sopenharmony_ci }; 8184514f5e3Sopenharmony_ci 8194514f5e3Sopenharmony_ci bool InHeapProfiler() const 8204514f5e3Sopenharmony_ci { 8214514f5e3Sopenharmony_ci return inHeapProfiler_; 8224514f5e3Sopenharmony_ci } 8234514f5e3Sopenharmony_ci 8244514f5e3Sopenharmony_ci void CheckInHeapProfiler(); 8254514f5e3Sopenharmony_ci 8264514f5e3Sopenharmony_ciprivate: 8274514f5e3Sopenharmony_ci void ProcessAllGCListeners(); 8284514f5e3Sopenharmony_ci inline void CollectGarbageFinish(bool inDaemon, TriggerGCType gcType); 8294514f5e3Sopenharmony_ci 8304514f5e3Sopenharmony_ci void MoveOldSpaceToAppspawn(); 8314514f5e3Sopenharmony_ci 8324514f5e3Sopenharmony_ci void ReclaimRegions(TriggerGCType type); 8334514f5e3Sopenharmony_ci 8344514f5e3Sopenharmony_ci void ForceCollectGarbageWithoutDaemonThread(TriggerGCType gcType, GCReason gcReason, JSThread *thread); 8354514f5e3Sopenharmony_ci inline TaggedObject *AllocateInSOldSpace(JSThread *thread, size_t size); 8364514f5e3Sopenharmony_ci inline void InvokeSharedNativePointerCallbacks(); 8374514f5e3Sopenharmony_ci struct SharedHeapSmartGCStats { 8384514f5e3Sopenharmony_ci /** 8394514f5e3Sopenharmony_ci * For SmartGC. 8404514f5e3Sopenharmony_ci * For daemon thread, it check these status before trying to collect garbage, and wait until finish. 8414514f5e3Sopenharmony_ci * It need that check-wait events is atomic, so use a Mutex/CV. 8424514f5e3Sopenharmony_ci */ 8434514f5e3Sopenharmony_ci Mutex sensitiveStatusMutex_; 8444514f5e3Sopenharmony_ci ConditionVariable sensitiveStatusCV_; 8454514f5e3Sopenharmony_ci AppSensitiveStatus sensitiveStatus_ {AppSensitiveStatus::NORMAL_SCENE}; 8464514f5e3Sopenharmony_ci bool onStartupEvent_ {false}; 8474514f5e3Sopenharmony_ci // If the SharedHeap is almost OOM and a collect is failed, cause a GC with GCReason::ALLOCATION_FAILED, 8484514f5e3Sopenharmony_ci // must do GC at once even in sensitive status. 8494514f5e3Sopenharmony_ci bool forceGC_ {false}; 8504514f5e3Sopenharmony_ci }; 8514514f5e3Sopenharmony_ci 8524514f5e3Sopenharmony_ci SharedHeapSmartGCStats smartGCStats_; 8534514f5e3Sopenharmony_ci 8544514f5e3Sopenharmony_ci static SharedHeap *instance_; 8554514f5e3Sopenharmony_ci 8564514f5e3Sopenharmony_ci GCStats *sGCStats_ {nullptr}; 8574514f5e3Sopenharmony_ci 8584514f5e3Sopenharmony_ci bool localFullMarkTriggered_ {false}; 8594514f5e3Sopenharmony_ci 8604514f5e3Sopenharmony_ci bool optionalLogEnabled_ {false}; 8614514f5e3Sopenharmony_ci 8624514f5e3Sopenharmony_ci bool parallelGC_ {true}; 8634514f5e3Sopenharmony_ci 8644514f5e3Sopenharmony_ci // Only means the main body of SharedGC is finished, i.e. if parallel_gc is enabled, this flags will be set 8654514f5e3Sopenharmony_ci // to true even if sweep_task and clear_task is running asynchronously 8664514f5e3Sopenharmony_ci bool gcFinished_ {true}; 8674514f5e3Sopenharmony_ci Mutex waitGCFinishedMutex_; 8684514f5e3Sopenharmony_ci ConditionVariable waitGCFinishedCV_; 8694514f5e3Sopenharmony_ci 8704514f5e3Sopenharmony_ci DaemonThread *dThread_ {nullptr}; 8714514f5e3Sopenharmony_ci const GlobalEnvConstants *globalEnvConstants_ {nullptr}; 8724514f5e3Sopenharmony_ci SharedOldSpace *sOldSpace_ {nullptr}; 8734514f5e3Sopenharmony_ci SharedOldSpace *sCompressSpace_ {nullptr}; 8744514f5e3Sopenharmony_ci SharedNonMovableSpace *sNonMovableSpace_ {nullptr}; 8754514f5e3Sopenharmony_ci SharedReadOnlySpace *sReadOnlySpace_ {nullptr}; 8764514f5e3Sopenharmony_ci SharedHugeObjectSpace *sHugeObjectSpace_ {nullptr}; 8774514f5e3Sopenharmony_ci SharedAppSpawnSpace *sAppSpawnSpace_ {nullptr}; 8784514f5e3Sopenharmony_ci SharedGCWorkManager *sWorkManager_ {nullptr}; 8794514f5e3Sopenharmony_ci SharedConcurrentMarker *sConcurrentMarker_ {nullptr}; 8804514f5e3Sopenharmony_ci SharedConcurrentSweeper *sSweeper_ {nullptr}; 8814514f5e3Sopenharmony_ci SharedGC *sharedGC_ {nullptr}; 8824514f5e3Sopenharmony_ci SharedFullGC *sharedFullGC_ {nullptr}; 8834514f5e3Sopenharmony_ci SharedGCMarker *sharedGCMarker_ {nullptr}; 8844514f5e3Sopenharmony_ci SharedGCMovableMarker *sharedGCMovableMarker_ {nullptr}; 8854514f5e3Sopenharmony_ci SharedMemController *sharedMemController_ {nullptr}; 8864514f5e3Sopenharmony_ci size_t growingFactor_ {0}; 8874514f5e3Sopenharmony_ci size_t growingStep_ {0}; 8884514f5e3Sopenharmony_ci size_t incNativeSizeTriggerSharedCM_ {0}; 8894514f5e3Sopenharmony_ci size_t incNativeSizeTriggerSharedGC_ {0}; 8904514f5e3Sopenharmony_ci std::atomic<size_t> nativeSizeAfterLastGC_ {0}; 8914514f5e3Sopenharmony_ci bool inHeapProfiler_ {false}; 8924514f5e3Sopenharmony_ci CVector<JSNativePointer *> sharedNativePointerList_; 8934514f5e3Sopenharmony_ci std::mutex sNativePointerListMutex_; 8944514f5e3Sopenharmony_ci}; 8954514f5e3Sopenharmony_ci 8964514f5e3Sopenharmony_ciclass Heap : public BaseHeap { 8974514f5e3Sopenharmony_cipublic: 8984514f5e3Sopenharmony_ci explicit Heap(EcmaVM *ecmaVm); 8994514f5e3Sopenharmony_ci virtual ~Heap() = default; 9004514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(Heap); 9014514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(Heap); 9024514f5e3Sopenharmony_ci void Initialize(); 9034514f5e3Sopenharmony_ci void Destroy() override; 9044514f5e3Sopenharmony_ci void Prepare(); 9054514f5e3Sopenharmony_ci void GetHeapPrepare(); 9064514f5e3Sopenharmony_ci void Resume(TriggerGCType gcType); 9074514f5e3Sopenharmony_ci void ResumeForAppSpawn(); 9084514f5e3Sopenharmony_ci void CompactHeapBeforeFork(); 9094514f5e3Sopenharmony_ci void DisableParallelGC(); 9104514f5e3Sopenharmony_ci void EnableParallelGC(); 9114514f5e3Sopenharmony_ci#if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) && defined(PANDA_TARGET_OHOS) && defined(ENABLE_HISYSEVENT) 9124514f5e3Sopenharmony_ci void SetJsDumpThresholds(size_t thresholds) const; 9134514f5e3Sopenharmony_ci#endif 9144514f5e3Sopenharmony_ci 9154514f5e3Sopenharmony_ci EdenSpace *GetEdenSpace() const 9164514f5e3Sopenharmony_ci { 9174514f5e3Sopenharmony_ci return edenSpace_; 9184514f5e3Sopenharmony_ci } 9194514f5e3Sopenharmony_ci 9204514f5e3Sopenharmony_ci // fixme: Rename NewSpace to YoungSpace. 9214514f5e3Sopenharmony_ci // This is the active young generation space that the new objects are allocated in 9224514f5e3Sopenharmony_ci // or copied into (from the other semi space) during semi space GC. 9234514f5e3Sopenharmony_ci SemiSpace *GetNewSpace() const 9244514f5e3Sopenharmony_ci { 9254514f5e3Sopenharmony_ci return activeSemiSpace_; 9264514f5e3Sopenharmony_ci } 9274514f5e3Sopenharmony_ci 9284514f5e3Sopenharmony_ci /* 9294514f5e3Sopenharmony_ci * Return the original active space where the objects are to be evacuated during semi space GC. 9304514f5e3Sopenharmony_ci * This should be invoked only in the evacuation phase of semi space GC. 9314514f5e3Sopenharmony_ci * fixme: Get rid of this interface or make it safe considering the above implicit limitation / requirement. 9324514f5e3Sopenharmony_ci */ 9334514f5e3Sopenharmony_ci SemiSpace *GetFromSpaceDuringEvacuation() const 9344514f5e3Sopenharmony_ci { 9354514f5e3Sopenharmony_ci return inactiveSemiSpace_; 9364514f5e3Sopenharmony_ci } 9374514f5e3Sopenharmony_ci 9384514f5e3Sopenharmony_ci OldSpace *GetOldSpace() const 9394514f5e3Sopenharmony_ci { 9404514f5e3Sopenharmony_ci return oldSpace_; 9414514f5e3Sopenharmony_ci } 9424514f5e3Sopenharmony_ci 9434514f5e3Sopenharmony_ci NonMovableSpace *GetNonMovableSpace() const 9444514f5e3Sopenharmony_ci { 9454514f5e3Sopenharmony_ci return nonMovableSpace_; 9464514f5e3Sopenharmony_ci } 9474514f5e3Sopenharmony_ci 9484514f5e3Sopenharmony_ci HugeObjectSpace *GetHugeObjectSpace() const 9494514f5e3Sopenharmony_ci { 9504514f5e3Sopenharmony_ci return hugeObjectSpace_; 9514514f5e3Sopenharmony_ci } 9524514f5e3Sopenharmony_ci 9534514f5e3Sopenharmony_ci MachineCodeSpace *GetMachineCodeSpace() const 9544514f5e3Sopenharmony_ci { 9554514f5e3Sopenharmony_ci return machineCodeSpace_; 9564514f5e3Sopenharmony_ci } 9574514f5e3Sopenharmony_ci 9584514f5e3Sopenharmony_ci HugeMachineCodeSpace *GetHugeMachineCodeSpace() const 9594514f5e3Sopenharmony_ci { 9604514f5e3Sopenharmony_ci return hugeMachineCodeSpace_; 9614514f5e3Sopenharmony_ci } 9624514f5e3Sopenharmony_ci 9634514f5e3Sopenharmony_ci SnapshotSpace *GetSnapshotSpace() const 9644514f5e3Sopenharmony_ci { 9654514f5e3Sopenharmony_ci return snapshotSpace_; 9664514f5e3Sopenharmony_ci } 9674514f5e3Sopenharmony_ci 9684514f5e3Sopenharmony_ci ReadOnlySpace *GetReadOnlySpace() const 9694514f5e3Sopenharmony_ci { 9704514f5e3Sopenharmony_ci return readOnlySpace_; 9714514f5e3Sopenharmony_ci } 9724514f5e3Sopenharmony_ci 9734514f5e3Sopenharmony_ci AppSpawnSpace *GetAppSpawnSpace() const 9744514f5e3Sopenharmony_ci { 9754514f5e3Sopenharmony_ci return appSpawnSpace_; 9764514f5e3Sopenharmony_ci } 9774514f5e3Sopenharmony_ci 9784514f5e3Sopenharmony_ci SparseSpace *GetSpaceWithType(MemSpaceType type) const 9794514f5e3Sopenharmony_ci { 9804514f5e3Sopenharmony_ci switch (type) { 9814514f5e3Sopenharmony_ci case MemSpaceType::OLD_SPACE: 9824514f5e3Sopenharmony_ci return oldSpace_; 9834514f5e3Sopenharmony_ci case MemSpaceType::NON_MOVABLE: 9844514f5e3Sopenharmony_ci return nonMovableSpace_; 9854514f5e3Sopenharmony_ci case MemSpaceType::MACHINE_CODE_SPACE: 9864514f5e3Sopenharmony_ci return machineCodeSpace_; 9874514f5e3Sopenharmony_ci default: 9884514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 9894514f5e3Sopenharmony_ci UNREACHABLE(); 9904514f5e3Sopenharmony_ci break; 9914514f5e3Sopenharmony_ci } 9924514f5e3Sopenharmony_ci } 9934514f5e3Sopenharmony_ci 9944514f5e3Sopenharmony_ci PartialGC *GetPartialGC() const 9954514f5e3Sopenharmony_ci { 9964514f5e3Sopenharmony_ci return partialGC_; 9974514f5e3Sopenharmony_ci } 9984514f5e3Sopenharmony_ci 9994514f5e3Sopenharmony_ci FullGC *GetFullGC() const 10004514f5e3Sopenharmony_ci { 10014514f5e3Sopenharmony_ci return fullGC_; 10024514f5e3Sopenharmony_ci } 10034514f5e3Sopenharmony_ci 10044514f5e3Sopenharmony_ci ConcurrentSweeper *GetSweeper() const 10054514f5e3Sopenharmony_ci { 10064514f5e3Sopenharmony_ci return sweeper_; 10074514f5e3Sopenharmony_ci } 10084514f5e3Sopenharmony_ci 10094514f5e3Sopenharmony_ci ParallelEvacuator *GetEvacuator() const 10104514f5e3Sopenharmony_ci { 10114514f5e3Sopenharmony_ci return evacuator_; 10124514f5e3Sopenharmony_ci } 10134514f5e3Sopenharmony_ci 10144514f5e3Sopenharmony_ci ConcurrentMarker *GetConcurrentMarker() const 10154514f5e3Sopenharmony_ci { 10164514f5e3Sopenharmony_ci return concurrentMarker_; 10174514f5e3Sopenharmony_ci } 10184514f5e3Sopenharmony_ci 10194514f5e3Sopenharmony_ci IncrementalMarker *GetIncrementalMarker() const 10204514f5e3Sopenharmony_ci { 10214514f5e3Sopenharmony_ci return incrementalMarker_; 10224514f5e3Sopenharmony_ci } 10234514f5e3Sopenharmony_ci 10244514f5e3Sopenharmony_ci Marker *GetNonMovableMarker() const 10254514f5e3Sopenharmony_ci { 10264514f5e3Sopenharmony_ci return nonMovableMarker_; 10274514f5e3Sopenharmony_ci } 10284514f5e3Sopenharmony_ci 10294514f5e3Sopenharmony_ci Marker *GetSemiGCMarker() const 10304514f5e3Sopenharmony_ci { 10314514f5e3Sopenharmony_ci return semiGCMarker_; 10324514f5e3Sopenharmony_ci } 10334514f5e3Sopenharmony_ci 10344514f5e3Sopenharmony_ci Marker *GetCompressGCMarker() const 10354514f5e3Sopenharmony_ci { 10364514f5e3Sopenharmony_ci return compressGCMarker_; 10374514f5e3Sopenharmony_ci } 10384514f5e3Sopenharmony_ci 10394514f5e3Sopenharmony_ci EcmaVM *GetEcmaVM() const 10404514f5e3Sopenharmony_ci { 10414514f5e3Sopenharmony_ci return ecmaVm_; 10424514f5e3Sopenharmony_ci } 10434514f5e3Sopenharmony_ci 10444514f5e3Sopenharmony_ci JSThread *GetJSThread() const 10454514f5e3Sopenharmony_ci { 10464514f5e3Sopenharmony_ci return thread_; 10474514f5e3Sopenharmony_ci } 10484514f5e3Sopenharmony_ci 10494514f5e3Sopenharmony_ci WorkManager *GetWorkManager() const 10504514f5e3Sopenharmony_ci { 10514514f5e3Sopenharmony_ci return workManager_; 10524514f5e3Sopenharmony_ci } 10534514f5e3Sopenharmony_ci 10544514f5e3Sopenharmony_ci WorkNode *&GetMarkingObjectLocalBuffer() 10554514f5e3Sopenharmony_ci { 10564514f5e3Sopenharmony_ci return sharedGCData_.sharedConcurrentMarkingLocalBuffer_; 10574514f5e3Sopenharmony_ci } 10584514f5e3Sopenharmony_ci 10594514f5e3Sopenharmony_ci IdleGCTrigger *GetIdleGCTrigger() const 10604514f5e3Sopenharmony_ci { 10614514f5e3Sopenharmony_ci return idleGCTrigger_; 10624514f5e3Sopenharmony_ci } 10634514f5e3Sopenharmony_ci 10644514f5e3Sopenharmony_ci void SetRSetWorkListHandler(RSetWorkListHandler *handler) 10654514f5e3Sopenharmony_ci { 10664514f5e3Sopenharmony_ci ASSERT((sharedGCData_.rSetWorkListHandler_ == nullptr) != (handler == nullptr)); 10674514f5e3Sopenharmony_ci sharedGCData_.rSetWorkListHandler_ = handler; 10684514f5e3Sopenharmony_ci } 10694514f5e3Sopenharmony_ci 10704514f5e3Sopenharmony_ci void ProcessSharedGCMarkingLocalBuffer(); 10714514f5e3Sopenharmony_ci 10724514f5e3Sopenharmony_ci void ProcessSharedGCRSetWorkList(); 10734514f5e3Sopenharmony_ci 10744514f5e3Sopenharmony_ci const GlobalEnvConstants *GetGlobalConst() const override; 10754514f5e3Sopenharmony_ci 10764514f5e3Sopenharmony_ci MemController *GetMemController() const 10774514f5e3Sopenharmony_ci { 10784514f5e3Sopenharmony_ci return memController_; 10794514f5e3Sopenharmony_ci } 10804514f5e3Sopenharmony_ci 10814514f5e3Sopenharmony_ci inline void RecordOrResetObjectSize(size_t objectSize) 10824514f5e3Sopenharmony_ci { 10834514f5e3Sopenharmony_ci recordObjectSize_ = objectSize; 10844514f5e3Sopenharmony_ci } 10854514f5e3Sopenharmony_ci 10864514f5e3Sopenharmony_ci inline size_t GetRecordObjectSize() const 10874514f5e3Sopenharmony_ci { 10884514f5e3Sopenharmony_ci return recordObjectSize_; 10894514f5e3Sopenharmony_ci } 10904514f5e3Sopenharmony_ci 10914514f5e3Sopenharmony_ci inline void RecordOrResetNativeSize(size_t nativeSize) 10924514f5e3Sopenharmony_ci { 10934514f5e3Sopenharmony_ci recordNativeSize_ = nativeSize; 10944514f5e3Sopenharmony_ci } 10954514f5e3Sopenharmony_ci 10964514f5e3Sopenharmony_ci inline size_t GetRecordNativeSize() const 10974514f5e3Sopenharmony_ci { 10984514f5e3Sopenharmony_ci return recordNativeSize_; 10994514f5e3Sopenharmony_ci } 11004514f5e3Sopenharmony_ci 11014514f5e3Sopenharmony_ci /* 11024514f5e3Sopenharmony_ci * For object allocations. 11034514f5e3Sopenharmony_ci */ 11044514f5e3Sopenharmony_ci 11054514f5e3Sopenharmony_ci // Young 11064514f5e3Sopenharmony_ci inline TaggedObject *AllocateInGeneralNewSpace(size_t size); 11074514f5e3Sopenharmony_ci inline TaggedObject *AllocateYoungOrHugeObject(JSHClass *hclass); 11084514f5e3Sopenharmony_ci inline TaggedObject *AllocateYoungOrHugeObject(JSHClass *hclass, size_t size); 11094514f5e3Sopenharmony_ci inline TaggedObject *AllocateReadOnlyOrHugeObject(JSHClass *hclass); 11104514f5e3Sopenharmony_ci inline TaggedObject *AllocateReadOnlyOrHugeObject(JSHClass *hclass, size_t size); 11114514f5e3Sopenharmony_ci inline TaggedObject *AllocateYoungOrHugeObject(size_t size); 11124514f5e3Sopenharmony_ci inline uintptr_t AllocateYoungSync(size_t size); 11134514f5e3Sopenharmony_ci inline TaggedObject *TryAllocateYoungGeneration(JSHClass *hclass, size_t size); 11144514f5e3Sopenharmony_ci // Old 11154514f5e3Sopenharmony_ci inline TaggedObject *AllocateOldOrHugeObject(JSHClass *hclass); 11164514f5e3Sopenharmony_ci inline TaggedObject *AllocateOldOrHugeObject(JSHClass *hclass, size_t size); 11174514f5e3Sopenharmony_ci inline TaggedObject *AllocateOldOrHugeObject(size_t size); 11184514f5e3Sopenharmony_ci // Non-movable 11194514f5e3Sopenharmony_ci inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass); 11204514f5e3Sopenharmony_ci inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass, size_t size); 11214514f5e3Sopenharmony_ci inline TaggedObject *AllocateClassClass(JSHClass *hclass, size_t size); 11224514f5e3Sopenharmony_ci // Huge 11234514f5e3Sopenharmony_ci inline TaggedObject *AllocateHugeObject(size_t size); 11244514f5e3Sopenharmony_ci inline TaggedObject *AllocateHugeObject(JSHClass *hclass, size_t size); 11254514f5e3Sopenharmony_ci // Machine code 11264514f5e3Sopenharmony_ci inline TaggedObject *AllocateMachineCodeObject(JSHClass *hclass, size_t size, MachineCodeDesc *desc = nullptr); 11274514f5e3Sopenharmony_ci inline TaggedObject *AllocateHugeMachineCodeObject(size_t size, MachineCodeDesc *desc = nullptr); 11284514f5e3Sopenharmony_ci // Snapshot 11294514f5e3Sopenharmony_ci inline uintptr_t AllocateSnapshotSpace(size_t size); 11304514f5e3Sopenharmony_ci 11314514f5e3Sopenharmony_ci // shared non movable space tlab 11324514f5e3Sopenharmony_ci inline TaggedObject *AllocateSharedNonMovableSpaceFromTlab(JSThread *thread, size_t size); 11334514f5e3Sopenharmony_ci // shared old space tlab 11344514f5e3Sopenharmony_ci inline TaggedObject *AllocateSharedOldSpaceFromTlab(JSThread *thread, size_t size); 11354514f5e3Sopenharmony_ci 11364514f5e3Sopenharmony_ci void ResetTlab(); 11374514f5e3Sopenharmony_ci void FillBumpPointerForTlab(); 11384514f5e3Sopenharmony_ci /* 11394514f5e3Sopenharmony_ci * GC triggers. 11404514f5e3Sopenharmony_ci */ 11414514f5e3Sopenharmony_ci void CollectGarbage(TriggerGCType gcType, GCReason reason = GCReason::OTHER); 11424514f5e3Sopenharmony_ci bool CheckAndTriggerOldGC(size_t size = 0); 11434514f5e3Sopenharmony_ci bool CheckAndTriggerHintGC(MemoryReduceDegree degree, GCReason reason = GCReason::OTHER); 11444514f5e3Sopenharmony_ci TriggerGCType SelectGCType() const; 11454514f5e3Sopenharmony_ci /* 11464514f5e3Sopenharmony_ci * Parallel GC related configurations and utilities. 11474514f5e3Sopenharmony_ci */ 11484514f5e3Sopenharmony_ci 11494514f5e3Sopenharmony_ci void PostParallelGCTask(ParallelGCTaskPhase taskPhase); 11504514f5e3Sopenharmony_ci 11514514f5e3Sopenharmony_ci bool IsParallelGCEnabled() const 11524514f5e3Sopenharmony_ci { 11534514f5e3Sopenharmony_ci return parallelGC_; 11544514f5e3Sopenharmony_ci } 11554514f5e3Sopenharmony_ci void ChangeGCParams(bool inBackground) override; 11564514f5e3Sopenharmony_ci 11574514f5e3Sopenharmony_ci GCStats *GetEcmaGCStats() override; 11584514f5e3Sopenharmony_ci 11594514f5e3Sopenharmony_ci GCKeyStats *GetEcmaGCKeyStats(); 11604514f5e3Sopenharmony_ci 11614514f5e3Sopenharmony_ci JSObjectResizingStrategy *GetJSObjectResizingStrategy(); 11624514f5e3Sopenharmony_ci 11634514f5e3Sopenharmony_ci void TriggerIdleCollection(int idleMicroSec); 11644514f5e3Sopenharmony_ci void NotifyMemoryPressure(bool inHighMemoryPressure); 11654514f5e3Sopenharmony_ci 11664514f5e3Sopenharmony_ci void TryTriggerConcurrentMarking(); 11674514f5e3Sopenharmony_ci void AdjustBySurvivalRate(size_t originalNewSpaceSize); 11684514f5e3Sopenharmony_ci void TriggerConcurrentMarking(); 11694514f5e3Sopenharmony_ci bool CheckCanTriggerConcurrentMarking(); 11704514f5e3Sopenharmony_ci 11714514f5e3Sopenharmony_ci void TryTriggerIdleCollection() override; 11724514f5e3Sopenharmony_ci void TryTriggerIncrementalMarking() override; 11734514f5e3Sopenharmony_ci void CalculateIdleDuration(); 11744514f5e3Sopenharmony_ci void UpdateWorkManager(WorkManager *workManager); 11754514f5e3Sopenharmony_ci bool CheckOngoingConcurrentMarking() override; 11764514f5e3Sopenharmony_ci 11774514f5e3Sopenharmony_ci inline void SwapNewSpace(); 11784514f5e3Sopenharmony_ci inline void SwapOldSpace(); 11794514f5e3Sopenharmony_ci 11804514f5e3Sopenharmony_ci inline bool MoveYoungRegionSync(Region *region); 11814514f5e3Sopenharmony_ci inline void MergeToOldSpaceSync(LocalSpace *localSpace); 11824514f5e3Sopenharmony_ci 11834514f5e3Sopenharmony_ci template<class Callback> 11844514f5e3Sopenharmony_ci void EnumerateOldSpaceRegions(const Callback &cb, Region *region = nullptr) const; 11854514f5e3Sopenharmony_ci 11864514f5e3Sopenharmony_ci template<class Callback> 11874514f5e3Sopenharmony_ci void EnumerateNonNewSpaceRegions(const Callback &cb) const; 11884514f5e3Sopenharmony_ci 11894514f5e3Sopenharmony_ci template<class Callback> 11904514f5e3Sopenharmony_ci void EnumerateNonNewSpaceRegionsWithRecord(const Callback &cb) const; 11914514f5e3Sopenharmony_ci 11924514f5e3Sopenharmony_ci template<class Callback> 11934514f5e3Sopenharmony_ci void EnumerateEdenSpaceRegions(const Callback &cb) const; 11944514f5e3Sopenharmony_ci 11954514f5e3Sopenharmony_ci template<class Callback> 11964514f5e3Sopenharmony_ci void EnumerateNewSpaceRegions(const Callback &cb) const; 11974514f5e3Sopenharmony_ci 11984514f5e3Sopenharmony_ci template<class Callback> 11994514f5e3Sopenharmony_ci void EnumerateSnapshotSpaceRegions(const Callback &cb) const; 12004514f5e3Sopenharmony_ci 12014514f5e3Sopenharmony_ci template<class Callback> 12024514f5e3Sopenharmony_ci void EnumerateNonMovableRegions(const Callback &cb) const; 12034514f5e3Sopenharmony_ci 12044514f5e3Sopenharmony_ci template<class Callback> 12054514f5e3Sopenharmony_ci inline void EnumerateRegions(const Callback &cb) const; 12064514f5e3Sopenharmony_ci 12074514f5e3Sopenharmony_ci inline void ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); 12084514f5e3Sopenharmony_ci 12094514f5e3Sopenharmony_ci void WaitAllTasksFinished(); 12104514f5e3Sopenharmony_ci void WaitConcurrentMarkingFinished(); 12114514f5e3Sopenharmony_ci 12124514f5e3Sopenharmony_ci MemGrowingType GetMemGrowingType() const 12134514f5e3Sopenharmony_ci { 12144514f5e3Sopenharmony_ci return memGrowingtype_; 12154514f5e3Sopenharmony_ci } 12164514f5e3Sopenharmony_ci 12174514f5e3Sopenharmony_ci void SetMemGrowingType(MemGrowingType memGrowingType) 12184514f5e3Sopenharmony_ci { 12194514f5e3Sopenharmony_ci memGrowingtype_ = memGrowingType; 12204514f5e3Sopenharmony_ci } 12214514f5e3Sopenharmony_ci 12224514f5e3Sopenharmony_ci size_t CalculateLinearSpaceOverShoot() 12234514f5e3Sopenharmony_ci { 12244514f5e3Sopenharmony_ci return oldSpace_->GetMaximumCapacity() - oldSpace_->GetInitialCapacity(); 12254514f5e3Sopenharmony_ci } 12264514f5e3Sopenharmony_ci 12274514f5e3Sopenharmony_ci inline size_t GetCommittedSize() const override; 12284514f5e3Sopenharmony_ci 12294514f5e3Sopenharmony_ci inline size_t GetHeapObjectSize() const override; 12304514f5e3Sopenharmony_ci 12314514f5e3Sopenharmony_ci inline void NotifyRecordMemorySize(); 12324514f5e3Sopenharmony_ci 12334514f5e3Sopenharmony_ci inline size_t GetRegionCount() const override; 12344514f5e3Sopenharmony_ci 12354514f5e3Sopenharmony_ci size_t GetRegionCachedSize() const 12364514f5e3Sopenharmony_ci { 12374514f5e3Sopenharmony_ci return activeSemiSpace_->GetInitialCapacity(); 12384514f5e3Sopenharmony_ci } 12394514f5e3Sopenharmony_ci 12404514f5e3Sopenharmony_ci size_t GetLiveObjectSize() const; 12414514f5e3Sopenharmony_ci 12424514f5e3Sopenharmony_ci inline uint32_t GetHeapObjectCount() const; 12434514f5e3Sopenharmony_ci 12444514f5e3Sopenharmony_ci size_t GetPromotedSize() const 12454514f5e3Sopenharmony_ci { 12464514f5e3Sopenharmony_ci return promotedSize_; 12474514f5e3Sopenharmony_ci } 12484514f5e3Sopenharmony_ci size_t GetEdenToYoungSize() const 12494514f5e3Sopenharmony_ci { 12504514f5e3Sopenharmony_ci return edenToYoungSize_; 12514514f5e3Sopenharmony_ci } 12524514f5e3Sopenharmony_ci 12534514f5e3Sopenharmony_ci size_t GetArrayBufferSize() const; 12544514f5e3Sopenharmony_ci 12554514f5e3Sopenharmony_ci size_t GetHeapLimitSize() const; 12564514f5e3Sopenharmony_ci 12574514f5e3Sopenharmony_ci uint32_t GetMaxEvacuateTaskCount() const 12584514f5e3Sopenharmony_ci { 12594514f5e3Sopenharmony_ci return maxEvacuateTaskCount_; 12604514f5e3Sopenharmony_ci } 12614514f5e3Sopenharmony_ci 12624514f5e3Sopenharmony_ci /* 12634514f5e3Sopenharmony_ci * Receive callback function to control idletime. 12644514f5e3Sopenharmony_ci */ 12654514f5e3Sopenharmony_ci inline void InitializeIdleStatusControl(std::function<void(bool)> callback); 12664514f5e3Sopenharmony_ci 12674514f5e3Sopenharmony_ci void DisableNotifyIdle() 12684514f5e3Sopenharmony_ci { 12694514f5e3Sopenharmony_ci if (notifyIdleStatusCallback != nullptr) { 12704514f5e3Sopenharmony_ci notifyIdleStatusCallback(true); 12714514f5e3Sopenharmony_ci } 12724514f5e3Sopenharmony_ci } 12734514f5e3Sopenharmony_ci 12744514f5e3Sopenharmony_ci void EnableNotifyIdle() 12754514f5e3Sopenharmony_ci { 12764514f5e3Sopenharmony_ci if (enableIdleGC_ && notifyIdleStatusCallback != nullptr) { 12774514f5e3Sopenharmony_ci notifyIdleStatusCallback(false); 12784514f5e3Sopenharmony_ci } 12794514f5e3Sopenharmony_ci } 12804514f5e3Sopenharmony_ci 12814514f5e3Sopenharmony_ci void SetIdleTask(IdleTaskType task) 12824514f5e3Sopenharmony_ci { 12834514f5e3Sopenharmony_ci idleTask_ = task; 12844514f5e3Sopenharmony_ci } 12854514f5e3Sopenharmony_ci 12864514f5e3Sopenharmony_ci void ClearIdleTask(); 12874514f5e3Sopenharmony_ci 12884514f5e3Sopenharmony_ci bool IsEmptyIdleTask() 12894514f5e3Sopenharmony_ci { 12904514f5e3Sopenharmony_ci return idleTask_ == IdleTaskType::NO_TASK; 12914514f5e3Sopenharmony_ci } 12924514f5e3Sopenharmony_ci 12934514f5e3Sopenharmony_ci void SetOnSerializeEvent(bool isSerialize) 12944514f5e3Sopenharmony_ci { 12954514f5e3Sopenharmony_ci onSerializeEvent_ = isSerialize; 12964514f5e3Sopenharmony_ci if (!onSerializeEvent_ && !InSensitiveStatus()) { 12974514f5e3Sopenharmony_ci TryTriggerIncrementalMarking(); 12984514f5e3Sopenharmony_ci TryTriggerIdleCollection(); 12994514f5e3Sopenharmony_ci TryTriggerConcurrentMarking(); 13004514f5e3Sopenharmony_ci } 13014514f5e3Sopenharmony_ci } 13024514f5e3Sopenharmony_ci 13034514f5e3Sopenharmony_ci bool GetOnSerializeEvent() const 13044514f5e3Sopenharmony_ci { 13054514f5e3Sopenharmony_ci return onSerializeEvent_; 13064514f5e3Sopenharmony_ci } 13074514f5e3Sopenharmony_ci 13084514f5e3Sopenharmony_ci void NotifyFinishColdStart(bool isMainThread = true); 13094514f5e3Sopenharmony_ci 13104514f5e3Sopenharmony_ci void NotifyFinishColdStartSoon(); 13114514f5e3Sopenharmony_ci 13124514f5e3Sopenharmony_ci void NotifyHighSensitive(bool isStart); 13134514f5e3Sopenharmony_ci 13144514f5e3Sopenharmony_ci bool HandleExitHighSensitiveEvent(); 13154514f5e3Sopenharmony_ci 13164514f5e3Sopenharmony_ci bool ObjectExceedMaxHeapSize() const override; 13174514f5e3Sopenharmony_ci 13184514f5e3Sopenharmony_ci bool NeedStopCollection() override; 13194514f5e3Sopenharmony_ci 13204514f5e3Sopenharmony_ci void SetSensitiveStatus(AppSensitiveStatus status) override 13214514f5e3Sopenharmony_ci { 13224514f5e3Sopenharmony_ci sHeap_->SetSensitiveStatus(status); 13234514f5e3Sopenharmony_ci smartGCStats_.sensitiveStatus_.store(status, std::memory_order_release); 13244514f5e3Sopenharmony_ci } 13254514f5e3Sopenharmony_ci 13264514f5e3Sopenharmony_ci AppSensitiveStatus GetSensitiveStatus() const override 13274514f5e3Sopenharmony_ci { 13284514f5e3Sopenharmony_ci return smartGCStats_.sensitiveStatus_.load(std::memory_order_acquire); 13294514f5e3Sopenharmony_ci } 13304514f5e3Sopenharmony_ci 13314514f5e3Sopenharmony_ci void SetRecordHeapObjectSizeBeforeSensitive(size_t objSize) 13324514f5e3Sopenharmony_ci { 13334514f5e3Sopenharmony_ci recordObjSizeBeforeSensitive_ = objSize; 13344514f5e3Sopenharmony_ci } 13354514f5e3Sopenharmony_ci 13364514f5e3Sopenharmony_ci size_t GetRecordHeapObjectSizeBeforeSensitive() const 13374514f5e3Sopenharmony_ci { 13384514f5e3Sopenharmony_ci return recordObjSizeBeforeSensitive_; 13394514f5e3Sopenharmony_ci } 13404514f5e3Sopenharmony_ci 13414514f5e3Sopenharmony_ci bool CASSensitiveStatus(AppSensitiveStatus expect, AppSensitiveStatus status) 13424514f5e3Sopenharmony_ci { 13434514f5e3Sopenharmony_ci return smartGCStats_.sensitiveStatus_.compare_exchange_strong(expect, status, std::memory_order_seq_cst); 13444514f5e3Sopenharmony_ci } 13454514f5e3Sopenharmony_ci 13464514f5e3Sopenharmony_ci bool FinishStartupEvent() override 13474514f5e3Sopenharmony_ci { 13484514f5e3Sopenharmony_ci sHeap_->FinishStartupEvent(); 13494514f5e3Sopenharmony_ci return smartGCStats_.onStartupEvent_.exchange(false, std::memory_order_relaxed) == true; 13504514f5e3Sopenharmony_ci } 13514514f5e3Sopenharmony_ci 13524514f5e3Sopenharmony_ci bool OnStartupEvent() const override 13534514f5e3Sopenharmony_ci { 13544514f5e3Sopenharmony_ci return smartGCStats_.onStartupEvent_.load(std::memory_order_relaxed); 13554514f5e3Sopenharmony_ci } 13564514f5e3Sopenharmony_ci 13574514f5e3Sopenharmony_ci void NotifyPostFork() override 13584514f5e3Sopenharmony_ci { 13594514f5e3Sopenharmony_ci sHeap_->NotifyPostFork(); 13604514f5e3Sopenharmony_ci smartGCStats_.onStartupEvent_.store(true, std::memory_order_relaxed); 13614514f5e3Sopenharmony_ci LOG_GC(INFO) << "SmartGC: enter app cold start"; 13624514f5e3Sopenharmony_ci } 13634514f5e3Sopenharmony_ci 13644514f5e3Sopenharmony_ci#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER) 13654514f5e3Sopenharmony_ci void StartHeapTracking() 13664514f5e3Sopenharmony_ci { 13674514f5e3Sopenharmony_ci WaitAllTasksFinished(); 13684514f5e3Sopenharmony_ci } 13694514f5e3Sopenharmony_ci 13704514f5e3Sopenharmony_ci void StopHeapTracking() 13714514f5e3Sopenharmony_ci { 13724514f5e3Sopenharmony_ci WaitAllTasksFinished(); 13734514f5e3Sopenharmony_ci } 13744514f5e3Sopenharmony_ci#endif 13754514f5e3Sopenharmony_ci inline bool InHeapProfiler(); 13764514f5e3Sopenharmony_ci 13774514f5e3Sopenharmony_ci void OnMoveEvent(uintptr_t address, TaggedObject* forwardAddress, size_t size); 13784514f5e3Sopenharmony_ci 13794514f5e3Sopenharmony_ci // add allocationInspector to each space 13804514f5e3Sopenharmony_ci void AddAllocationInspectorToAllSpaces(AllocationInspector *inspector); 13814514f5e3Sopenharmony_ci 13824514f5e3Sopenharmony_ci // clear allocationInspector from each space 13834514f5e3Sopenharmony_ci void ClearAllocationInspectorFromAllSpaces(); 13844514f5e3Sopenharmony_ci 13854514f5e3Sopenharmony_ci /* 13864514f5e3Sopenharmony_ci * Funtions used by heap verification. 13874514f5e3Sopenharmony_ci */ 13884514f5e3Sopenharmony_ci 13894514f5e3Sopenharmony_ci template<class Callback> 13904514f5e3Sopenharmony_ci void IterateOverObjects(const Callback &cb, bool isSimplify = false) const; 13914514f5e3Sopenharmony_ci 13924514f5e3Sopenharmony_ci size_t VerifyHeapObjects(VerifyKind verifyKind = VerifyKind::VERIFY_PRE_GC) const; 13934514f5e3Sopenharmony_ci size_t VerifyOldToNewRSet(VerifyKind verifyKind = VerifyKind::VERIFY_PRE_GC) const; 13944514f5e3Sopenharmony_ci void StatisticHeapObject(TriggerGCType gcType) const; 13954514f5e3Sopenharmony_ci void StatisticHeapDetail(); 13964514f5e3Sopenharmony_ci void PrintHeapInfo(TriggerGCType gcType) const; 13974514f5e3Sopenharmony_ci 13984514f5e3Sopenharmony_ci bool OldSpaceExceedCapacity(size_t size) const override 13994514f5e3Sopenharmony_ci { 14004514f5e3Sopenharmony_ci size_t totalSize = oldSpace_->GetCommittedSize() + hugeObjectSpace_->GetCommittedSize() + size; 14014514f5e3Sopenharmony_ci return totalSize >= oldSpace_->GetMaximumCapacity() + oldSpace_->GetOvershootSize() + 14024514f5e3Sopenharmony_ci oldSpace_->GetOutOfMemoryOvershootSize(); 14034514f5e3Sopenharmony_ci } 14044514f5e3Sopenharmony_ci 14054514f5e3Sopenharmony_ci bool OldSpaceExceedLimit() const override 14064514f5e3Sopenharmony_ci { 14074514f5e3Sopenharmony_ci size_t totalSize = oldSpace_->GetHeapObjectSize() + hugeObjectSpace_->GetHeapObjectSize(); 14084514f5e3Sopenharmony_ci return totalSize >= oldSpace_->GetInitialCapacity() + oldSpace_->GetOvershootSize(); 14094514f5e3Sopenharmony_ci } 14104514f5e3Sopenharmony_ci 14114514f5e3Sopenharmony_ci void AdjustSpaceSizeForAppSpawn(); 14124514f5e3Sopenharmony_ci 14134514f5e3Sopenharmony_ci static bool ShouldMoveToRoSpace(JSHClass *hclass, TaggedObject *object); 14144514f5e3Sopenharmony_ci 14154514f5e3Sopenharmony_ci bool IsFullMarkRequested() const 14164514f5e3Sopenharmony_ci { 14174514f5e3Sopenharmony_ci return fullMarkRequested_; 14184514f5e3Sopenharmony_ci } 14194514f5e3Sopenharmony_ci 14204514f5e3Sopenharmony_ci void SetFullMarkRequestedState(bool fullMarkRequested) 14214514f5e3Sopenharmony_ci { 14224514f5e3Sopenharmony_ci fullMarkRequested_ = fullMarkRequested; 14234514f5e3Sopenharmony_ci } 14244514f5e3Sopenharmony_ci 14254514f5e3Sopenharmony_ci void SetHeapMode(HeapMode mode) 14264514f5e3Sopenharmony_ci { 14274514f5e3Sopenharmony_ci mode_ = mode; 14284514f5e3Sopenharmony_ci } 14294514f5e3Sopenharmony_ci 14304514f5e3Sopenharmony_ci void IncreaseNativeBindingSize(size_t size); 14314514f5e3Sopenharmony_ci void IncreaseNativeBindingSize(JSNativePointer *object); 14324514f5e3Sopenharmony_ci void DecreaseNativeBindingSize(size_t size); 14334514f5e3Sopenharmony_ci void ResetNativeBindingSize() 14344514f5e3Sopenharmony_ci { 14354514f5e3Sopenharmony_ci nativeBindingSize_ = 0; 14364514f5e3Sopenharmony_ci } 14374514f5e3Sopenharmony_ci 14384514f5e3Sopenharmony_ci size_t GetNativeBindingSize() const 14394514f5e3Sopenharmony_ci { 14404514f5e3Sopenharmony_ci return nativeBindingSize_; 14414514f5e3Sopenharmony_ci } 14424514f5e3Sopenharmony_ci 14434514f5e3Sopenharmony_ci size_t GetGlobalNativeSize() const 14444514f5e3Sopenharmony_ci { 14454514f5e3Sopenharmony_ci return GetNativeBindingSize() + nativeAreaAllocator_->GetNativeMemoryUsage(); 14464514f5e3Sopenharmony_ci } 14474514f5e3Sopenharmony_ci 14484514f5e3Sopenharmony_ci void ResetNativeSizeAfterLastGC() 14494514f5e3Sopenharmony_ci { 14504514f5e3Sopenharmony_ci nativeSizeAfterLastGC_ = 0; 14514514f5e3Sopenharmony_ci nativeBindingSizeAfterLastGC_= nativeBindingSize_; 14524514f5e3Sopenharmony_ci } 14534514f5e3Sopenharmony_ci 14544514f5e3Sopenharmony_ci void IncNativeSizeAfterLastGC(size_t size) 14554514f5e3Sopenharmony_ci { 14564514f5e3Sopenharmony_ci nativeSizeAfterLastGC_ += size; 14574514f5e3Sopenharmony_ci } 14584514f5e3Sopenharmony_ci 14594514f5e3Sopenharmony_ci bool GlobalNativeSizeLargerToTriggerGC() const 14604514f5e3Sopenharmony_ci { 14614514f5e3Sopenharmony_ci auto incNativeBindingSizeAfterLastGC = nativeBindingSize_ > nativeBindingSizeAfterLastGC_ ? 14624514f5e3Sopenharmony_ci nativeBindingSize_ - nativeBindingSizeAfterLastGC_ : 0; 14634514f5e3Sopenharmony_ci return GetGlobalNativeSize() > nativeSizeTriggerGCThreshold_ && 14644514f5e3Sopenharmony_ci nativeSizeAfterLastGC_ + incNativeBindingSizeAfterLastGC > incNativeSizeTriggerGC_; 14654514f5e3Sopenharmony_ci } 14664514f5e3Sopenharmony_ci 14674514f5e3Sopenharmony_ci bool GlobalNativeSizeLargerThanLimit() const 14684514f5e3Sopenharmony_ci { 14694514f5e3Sopenharmony_ci size_t overshoot = InSensitiveStatus() ? nativeSizeOvershoot_ : 0; 14704514f5e3Sopenharmony_ci return GetGlobalNativeSize() >= globalSpaceNativeLimit_ + overshoot; 14714514f5e3Sopenharmony_ci } 14724514f5e3Sopenharmony_ci 14734514f5e3Sopenharmony_ci bool GlobalNativeSizeLargerThanLimitForIdle() const 14744514f5e3Sopenharmony_ci { 14754514f5e3Sopenharmony_ci return GetGlobalNativeSize() >= static_cast<size_t>(globalSpaceNativeLimit_ * 14764514f5e3Sopenharmony_ci IDLE_SPACE_SIZE_LIMIT_RATE); 14774514f5e3Sopenharmony_ci } 14784514f5e3Sopenharmony_ci 14794514f5e3Sopenharmony_ci void TryTriggerFullMarkOrGCByNativeSize(); 14804514f5e3Sopenharmony_ci 14814514f5e3Sopenharmony_ci void TryTriggerFullMarkBySharedSize(size_t size); 14824514f5e3Sopenharmony_ci 14834514f5e3Sopenharmony_ci bool TryTriggerFullMarkBySharedLimit(); 14844514f5e3Sopenharmony_ci 14854514f5e3Sopenharmony_ci void CheckAndTriggerTaskFinishedGC(); 14864514f5e3Sopenharmony_ci 14874514f5e3Sopenharmony_ci bool IsMarking() const override; 14884514f5e3Sopenharmony_ci 14894514f5e3Sopenharmony_ci bool IsReadyToConcurrentMark() const override; 14904514f5e3Sopenharmony_ci 14914514f5e3Sopenharmony_ci bool IsEdenGC() const 14924514f5e3Sopenharmony_ci { 14934514f5e3Sopenharmony_ci return gcType_ == TriggerGCType::EDEN_GC; 14944514f5e3Sopenharmony_ci } 14954514f5e3Sopenharmony_ci 14964514f5e3Sopenharmony_ci bool IsYoungGC() const 14974514f5e3Sopenharmony_ci { 14984514f5e3Sopenharmony_ci return gcType_ == TriggerGCType::YOUNG_GC; 14994514f5e3Sopenharmony_ci } 15004514f5e3Sopenharmony_ci 15014514f5e3Sopenharmony_ci bool IsGeneralYoungGC() const 15024514f5e3Sopenharmony_ci { 15034514f5e3Sopenharmony_ci return gcType_ == TriggerGCType::YOUNG_GC || gcType_ == TriggerGCType::EDEN_GC; 15044514f5e3Sopenharmony_ci } 15054514f5e3Sopenharmony_ci 15064514f5e3Sopenharmony_ci void EnableEdenGC(); 15074514f5e3Sopenharmony_ci 15084514f5e3Sopenharmony_ci void TryEnableEdenGC(); 15094514f5e3Sopenharmony_ci 15104514f5e3Sopenharmony_ci void CheckNonMovableSpaceOOM(); 15114514f5e3Sopenharmony_ci void ReleaseEdenAllocator(); 15124514f5e3Sopenharmony_ci void InstallEdenAllocator(); 15134514f5e3Sopenharmony_ci void DumpHeapSnapshotBeforeOOM(bool isFullGC = true); 15144514f5e3Sopenharmony_ci std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const; 15154514f5e3Sopenharmony_ci MachineCode *GetMachineCodeObject(uintptr_t pc) const; 15164514f5e3Sopenharmony_ci 15174514f5e3Sopenharmony_ci PUBLIC_API GCListenerId AddGCListener(FinishGCListener listener, void *data); 15184514f5e3Sopenharmony_ci PUBLIC_API void RemoveGCListener(GCListenerId listenerId); 15194514f5e3Sopenharmony_ci void ProcessGCListeners(); 15204514f5e3Sopenharmony_ci 15214514f5e3Sopenharmony_ci inline void ProcessNativeDelete(const WeakRootVisitor& visitor); 15224514f5e3Sopenharmony_ci inline void ProcessReferences(const WeakRootVisitor& visitor); 15234514f5e3Sopenharmony_ci inline void PushToNativePointerList(JSNativePointer* pointer, bool isConcurrent); 15244514f5e3Sopenharmony_ci inline void RemoveFromNativePointerList(const JSNativePointer* pointer); 15254514f5e3Sopenharmony_ci inline void ClearNativePointerList(); 15264514f5e3Sopenharmony_ci 15274514f5e3Sopenharmony_ci size_t GetNativePointerListSize() const 15284514f5e3Sopenharmony_ci { 15294514f5e3Sopenharmony_ci return nativePointerList_.size(); 15304514f5e3Sopenharmony_ci } 15314514f5e3Sopenharmony_ci 15324514f5e3Sopenharmony_ciprivate: 15334514f5e3Sopenharmony_ci 15344514f5e3Sopenharmony_ci static constexpr int MIN_JSDUMP_THRESHOLDS = 85; 15354514f5e3Sopenharmony_ci static constexpr int MAX_JSDUMP_THRESHOLDS = 95; 15364514f5e3Sopenharmony_ci static constexpr int IDLE_TIME_LIMIT = 10; // if idle time over 10ms we can do something 15374514f5e3Sopenharmony_ci static constexpr int ALLOCATE_SIZE_LIMIT = 100_KB; 15384514f5e3Sopenharmony_ci static constexpr int IDLE_MAINTAIN_TIME = 500; 15394514f5e3Sopenharmony_ci static constexpr int BACKGROUND_GROW_LIMIT = 2_MB; 15404514f5e3Sopenharmony_ci // Threadshold that HintGC will actually trigger GC. 15414514f5e3Sopenharmony_ci static constexpr double SURVIVAL_RATE_THRESHOLD = 0.5; 15424514f5e3Sopenharmony_ci static constexpr size_t NEW_ALLOCATED_SHARED_OBJECT_SIZE_LIMIT = DEFAULT_SHARED_HEAP_SIZE / 10; // 10 : ten times. 15434514f5e3Sopenharmony_ci static constexpr size_t INIT_GLOBAL_SPACE_NATIVE_SIZE_LIMIT = 100_MB; 15444514f5e3Sopenharmony_ci void RecomputeLimits(); 15454514f5e3Sopenharmony_ci void AdjustOldSpaceLimit(); 15464514f5e3Sopenharmony_ci // record lastRegion for each space, which will be used in ReclaimRegions() 15474514f5e3Sopenharmony_ci void PrepareRecordRegionsForReclaim(); 15484514f5e3Sopenharmony_ci inline void ReclaimRegions(TriggerGCType gcType); 15494514f5e3Sopenharmony_ci inline size_t CalculateCommittedCacheSize(); 15504514f5e3Sopenharmony_ci#if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) && defined(PANDA_TARGET_OHOS) && defined(ENABLE_HISYSEVENT) 15514514f5e3Sopenharmony_ci uint64_t GetCurrentTickMillseconds(); 15524514f5e3Sopenharmony_ci void ThresholdReachedDump(); 15534514f5e3Sopenharmony_ci#endif 15544514f5e3Sopenharmony_ci void CleanCallBack(); 15554514f5e3Sopenharmony_ci void IncreasePendingAsyncNativeCallbackSize(size_t bindingSize) 15564514f5e3Sopenharmony_ci { 15574514f5e3Sopenharmony_ci pendingAsyncNativeCallbackSize_ += bindingSize; 15584514f5e3Sopenharmony_ci } 15594514f5e3Sopenharmony_ci void DecreasePendingAsyncNativeCallbackSize(size_t bindingSize) 15604514f5e3Sopenharmony_ci { 15614514f5e3Sopenharmony_ci pendingAsyncNativeCallbackSize_ -= bindingSize; 15624514f5e3Sopenharmony_ci } 15634514f5e3Sopenharmony_ci class ParallelGCTask : public Task { 15644514f5e3Sopenharmony_ci public: 15654514f5e3Sopenharmony_ci ParallelGCTask(int32_t id, Heap *heap, ParallelGCTaskPhase taskPhase) 15664514f5e3Sopenharmony_ci : Task(id), heap_(heap), taskPhase_(taskPhase) {}; 15674514f5e3Sopenharmony_ci ~ParallelGCTask() override = default; 15684514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 15694514f5e3Sopenharmony_ci 15704514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(ParallelGCTask); 15714514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(ParallelGCTask); 15724514f5e3Sopenharmony_ci 15734514f5e3Sopenharmony_ci private: 15744514f5e3Sopenharmony_ci Heap *heap_ {nullptr}; 15754514f5e3Sopenharmony_ci ParallelGCTaskPhase taskPhase_; 15764514f5e3Sopenharmony_ci }; 15774514f5e3Sopenharmony_ci 15784514f5e3Sopenharmony_ci class AsyncClearTask : public Task { 15794514f5e3Sopenharmony_ci public: 15804514f5e3Sopenharmony_ci AsyncClearTask(int32_t id, Heap *heap, TriggerGCType type) 15814514f5e3Sopenharmony_ci : Task(id), heap_(heap), gcType_(type) {} 15824514f5e3Sopenharmony_ci ~AsyncClearTask() override = default; 15834514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 15844514f5e3Sopenharmony_ci 15854514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(AsyncClearTask); 15864514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(AsyncClearTask); 15874514f5e3Sopenharmony_ci private: 15884514f5e3Sopenharmony_ci Heap *heap_; 15894514f5e3Sopenharmony_ci TriggerGCType gcType_; 15904514f5e3Sopenharmony_ci }; 15914514f5e3Sopenharmony_ci 15924514f5e3Sopenharmony_ci class FinishColdStartTask : public Task { 15934514f5e3Sopenharmony_ci public: 15944514f5e3Sopenharmony_ci FinishColdStartTask(int32_t id, Heap *heap) 15954514f5e3Sopenharmony_ci : Task(id), heap_(heap) {} 15964514f5e3Sopenharmony_ci ~FinishColdStartTask() override = default; 15974514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 15984514f5e3Sopenharmony_ci 15994514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(FinishColdStartTask); 16004514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(FinishColdStartTask); 16014514f5e3Sopenharmony_ci private: 16024514f5e3Sopenharmony_ci Heap *heap_; 16034514f5e3Sopenharmony_ci }; 16044514f5e3Sopenharmony_ci 16054514f5e3Sopenharmony_ci class DeleteCallbackTask : public Task { 16064514f5e3Sopenharmony_ci public: 16074514f5e3Sopenharmony_ci DeleteCallbackTask(int32_t id, std::vector<NativePointerCallbackData> &callbacks) : Task(id) 16084514f5e3Sopenharmony_ci { 16094514f5e3Sopenharmony_ci std::swap(callbacks, nativePointerCallbacks_); 16104514f5e3Sopenharmony_ci } 16114514f5e3Sopenharmony_ci ~DeleteCallbackTask() override = default; 16124514f5e3Sopenharmony_ci bool Run(uint32_t threadIndex) override; 16134514f5e3Sopenharmony_ci 16144514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(DeleteCallbackTask); 16154514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(DeleteCallbackTask); 16164514f5e3Sopenharmony_ci 16174514f5e3Sopenharmony_ci private: 16184514f5e3Sopenharmony_ci std::vector<NativePointerCallbackData> nativePointerCallbacks_ {}; 16194514f5e3Sopenharmony_ci }; 16204514f5e3Sopenharmony_ci 16214514f5e3Sopenharmony_ci struct MainLocalHeapSmartGCStats { 16224514f5e3Sopenharmony_ci /** 16234514f5e3Sopenharmony_ci * For SmartGC. 16244514f5e3Sopenharmony_ci * For main js thread, it check these status everytime when trying to 16254514f5e3Sopenharmony_ci * collect garbage(e.g. in JSThread::CheckSafePoint), and skip if need, so std::atomic is almost enough. 16264514f5e3Sopenharmony_ci */ 16274514f5e3Sopenharmony_ci std::atomic<AppSensitiveStatus> sensitiveStatus_ {AppSensitiveStatus::NORMAL_SCENE}; 16284514f5e3Sopenharmony_ci std::atomic<bool> onStartupEvent_ {false}; 16294514f5e3Sopenharmony_ci }; 16304514f5e3Sopenharmony_ci 16314514f5e3Sopenharmony_ci // Some data used in SharedGC is also need to store in local heap, e.g. the temporary local mark stack. 16324514f5e3Sopenharmony_ci struct SharedGCLocalStoragePackedData { 16334514f5e3Sopenharmony_ci /** 16344514f5e3Sopenharmony_ci * During SharedGC concurrent marking, barrier will push shared object to mark stack for marking, 16354514f5e3Sopenharmony_ci * in LocalGC can just push non-shared object to WorkNode for MAIN_THREAD_INDEX, but in SharedGC, only can 16364514f5e3Sopenharmony_ci * either use a global lock for DAEMON_THREAD_INDEX's WorkNode, or push to a local WorkNode, and push to global 16374514f5e3Sopenharmony_ci * in remark. 16384514f5e3Sopenharmony_ci * If the heap is destructed before push this node to global, check and try to push remain object as well. 16394514f5e3Sopenharmony_ci */ 16404514f5e3Sopenharmony_ci WorkNode *sharedConcurrentMarkingLocalBuffer_ {nullptr}; 16414514f5e3Sopenharmony_ci /** 16424514f5e3Sopenharmony_ci * Recording the local_to_share rset used in SharedGC concurrentMark, 16434514f5e3Sopenharmony_ci * which lifecycle is in one SharedGC. 16444514f5e3Sopenharmony_ci * Before mutate this local heap(e.g. LocalGC::Evacuate), should make sure the RSetWorkList is all processed, 16454514f5e3Sopenharmony_ci * other the SharedGC concurrentMark will visitor the incorrect local_to_share bit. 16464514f5e3Sopenharmony_ci * Before destroying local heap, RSetWorkList should be done as well. 16474514f5e3Sopenharmony_ci */ 16484514f5e3Sopenharmony_ci RSetWorkListHandler *rSetWorkListHandler_ {nullptr}; 16494514f5e3Sopenharmony_ci }; 16504514f5e3Sopenharmony_ci 16514514f5e3Sopenharmony_ci EcmaVM *ecmaVm_ {nullptr}; 16524514f5e3Sopenharmony_ci JSThread *thread_ {nullptr}; 16534514f5e3Sopenharmony_ci 16544514f5e3Sopenharmony_ci SharedHeap *sHeap_ {nullptr}; 16554514f5e3Sopenharmony_ci MainLocalHeapSmartGCStats smartGCStats_; 16564514f5e3Sopenharmony_ci 16574514f5e3Sopenharmony_ci /* 16584514f5e3Sopenharmony_ci * Heap spaces. 16594514f5e3Sopenharmony_ci */ 16604514f5e3Sopenharmony_ci 16614514f5e3Sopenharmony_ci /* 16624514f5e3Sopenharmony_ci * Young generation spaces where most new objects are allocated. 16634514f5e3Sopenharmony_ci * (only one of the spaces is active at a time in semi space GC). 16644514f5e3Sopenharmony_ci */ 16654514f5e3Sopenharmony_ci EdenSpace *edenSpace_ {nullptr}; 16664514f5e3Sopenharmony_ci SemiSpace *activeSemiSpace_ {nullptr}; 16674514f5e3Sopenharmony_ci SemiSpace *inactiveSemiSpace_ {nullptr}; 16684514f5e3Sopenharmony_ci 16694514f5e3Sopenharmony_ci // Old generation spaces where some long living objects are allocated or promoted. 16704514f5e3Sopenharmony_ci OldSpace *oldSpace_ {nullptr}; 16714514f5e3Sopenharmony_ci OldSpace *compressSpace_ {nullptr}; 16724514f5e3Sopenharmony_ci ReadOnlySpace *readOnlySpace_ {nullptr}; 16734514f5e3Sopenharmony_ci AppSpawnSpace *appSpawnSpace_ {nullptr}; 16744514f5e3Sopenharmony_ci // Spaces used for special kinds of objects. 16754514f5e3Sopenharmony_ci NonMovableSpace *nonMovableSpace_ {nullptr}; 16764514f5e3Sopenharmony_ci MachineCodeSpace *machineCodeSpace_ {nullptr}; 16774514f5e3Sopenharmony_ci HugeMachineCodeSpace *hugeMachineCodeSpace_ {nullptr}; 16784514f5e3Sopenharmony_ci HugeObjectSpace *hugeObjectSpace_ {nullptr}; 16794514f5e3Sopenharmony_ci SnapshotSpace *snapshotSpace_ {nullptr}; 16804514f5e3Sopenharmony_ci // tlab for shared non movable space 16814514f5e3Sopenharmony_ci ThreadLocalAllocationBuffer *sNonMovableTlab_ {nullptr}; 16824514f5e3Sopenharmony_ci // tlab for shared old space 16834514f5e3Sopenharmony_ci ThreadLocalAllocationBuffer *sOldTlab_ {nullptr}; 16844514f5e3Sopenharmony_ci /* 16854514f5e3Sopenharmony_ci * Garbage collectors collecting garbage in different scopes. 16864514f5e3Sopenharmony_ci */ 16874514f5e3Sopenharmony_ci 16884514f5e3Sopenharmony_ci /* 16894514f5e3Sopenharmony_ci * The mostly used partial GC which collects garbage in young spaces, 16904514f5e3Sopenharmony_ci * and part of old spaces if needed determined by GC heuristics. 16914514f5e3Sopenharmony_ci */ 16924514f5e3Sopenharmony_ci PartialGC *partialGC_ {nullptr}; 16934514f5e3Sopenharmony_ci 16944514f5e3Sopenharmony_ci // Full collector which collects garbage in all valid heap spaces. 16954514f5e3Sopenharmony_ci FullGC *fullGC_ {nullptr}; 16964514f5e3Sopenharmony_ci 16974514f5e3Sopenharmony_ci // Concurrent marker which coordinates actions of GC markers and mutators. 16984514f5e3Sopenharmony_ci ConcurrentMarker *concurrentMarker_ {nullptr}; 16994514f5e3Sopenharmony_ci 17004514f5e3Sopenharmony_ci // Concurrent sweeper which coordinates actions of sweepers (in spaces excluding young semi spaces) and mutators. 17014514f5e3Sopenharmony_ci ConcurrentSweeper *sweeper_ {nullptr}; 17024514f5e3Sopenharmony_ci 17034514f5e3Sopenharmony_ci // Parallel evacuator which evacuates objects from one space to another one. 17044514f5e3Sopenharmony_ci ParallelEvacuator *evacuator_ {nullptr}; 17054514f5e3Sopenharmony_ci 17064514f5e3Sopenharmony_ci // Incremental marker which coordinates actions of GC markers in idle time. 17074514f5e3Sopenharmony_ci IncrementalMarker *incrementalMarker_ {nullptr}; 17084514f5e3Sopenharmony_ci 17094514f5e3Sopenharmony_ci /* 17104514f5e3Sopenharmony_ci * Different kinds of markers used by different collectors. 17114514f5e3Sopenharmony_ci * Depending on the collector algorithm, some markers can do simple marking 17124514f5e3Sopenharmony_ci * while some others need to handle object movement. 17134514f5e3Sopenharmony_ci */ 17144514f5e3Sopenharmony_ci Marker *nonMovableMarker_ {nullptr}; 17154514f5e3Sopenharmony_ci Marker *semiGCMarker_ {nullptr}; 17164514f5e3Sopenharmony_ci Marker *compressGCMarker_ {nullptr}; 17174514f5e3Sopenharmony_ci 17184514f5e3Sopenharmony_ci // Work manager managing the tasks mostly generated in the GC mark phase. 17194514f5e3Sopenharmony_ci WorkManager *workManager_ {nullptr}; 17204514f5e3Sopenharmony_ci 17214514f5e3Sopenharmony_ci SharedGCLocalStoragePackedData sharedGCData_; 17224514f5e3Sopenharmony_ci 17234514f5e3Sopenharmony_ci bool onSerializeEvent_ {false}; 17244514f5e3Sopenharmony_ci bool parallelGC_ {true}; 17254514f5e3Sopenharmony_ci bool fullGCRequested_ {false}; 17264514f5e3Sopenharmony_ci bool fullMarkRequested_ {false}; 17274514f5e3Sopenharmony_ci bool oldSpaceLimitAdjusted_ {false}; 17284514f5e3Sopenharmony_ci bool enableIdleGC_ {false}; 17294514f5e3Sopenharmony_ci std::atomic_bool isCSetClearing_ {false}; 17304514f5e3Sopenharmony_ci HeapMode mode_ { HeapMode::NORMAL }; 17314514f5e3Sopenharmony_ci 17324514f5e3Sopenharmony_ci /* 17334514f5e3Sopenharmony_ci * The memory controller providing memory statistics (by allocations and coleections), 17344514f5e3Sopenharmony_ci * which is used for GC heuristics. 17354514f5e3Sopenharmony_ci */ 17364514f5e3Sopenharmony_ci MemController *memController_ {nullptr}; 17374514f5e3Sopenharmony_ci size_t edenToYoungSize_ {0}; 17384514f5e3Sopenharmony_ci size_t promotedSize_ {0}; 17394514f5e3Sopenharmony_ci size_t semiSpaceCopiedSize_ {0}; 17404514f5e3Sopenharmony_ci size_t nativeBindingSize_{0}; 17414514f5e3Sopenharmony_ci size_t globalSpaceNativeLimit_ {0}; 17424514f5e3Sopenharmony_ci size_t nativeSizeTriggerGCThreshold_ {0}; 17434514f5e3Sopenharmony_ci size_t incNativeSizeTriggerGC_ {0}; 17444514f5e3Sopenharmony_ci size_t nativeSizeOvershoot_ {0}; 17454514f5e3Sopenharmony_ci size_t asyncClearNativePointerThreshold_ {0}; 17464514f5e3Sopenharmony_ci size_t nativeSizeAfterLastGC_ {0}; 17474514f5e3Sopenharmony_ci size_t nativeBindingSizeAfterLastGC_ {0}; 17484514f5e3Sopenharmony_ci size_t newAllocatedSharedObjectSize_ {0}; 17494514f5e3Sopenharmony_ci // recordObjectSize_ & recordNativeSize_: 17504514f5e3Sopenharmony_ci // Record memory before taskpool start, used to determine trigger GC or not after task finish. 17514514f5e3Sopenharmony_ci size_t recordObjectSize_ {0}; 17524514f5e3Sopenharmony_ci size_t recordNativeSize_ {0}; 17534514f5e3Sopenharmony_ci // Record heap object size before enter sensitive status 17544514f5e3Sopenharmony_ci size_t recordObjSizeBeforeSensitive_ {0}; 17554514f5e3Sopenharmony_ci size_t pendingAsyncNativeCallbackSize_ {0}; 17564514f5e3Sopenharmony_ci MemGrowingType memGrowingtype_ {MemGrowingType::HIGH_THROUGHPUT}; 17574514f5e3Sopenharmony_ci 17584514f5e3Sopenharmony_ci // parallel evacuator task number. 17594514f5e3Sopenharmony_ci uint32_t maxEvacuateTaskCount_ {0}; 17604514f5e3Sopenharmony_ci 17614514f5e3Sopenharmony_ci // Application status 17624514f5e3Sopenharmony_ci 17634514f5e3Sopenharmony_ci IdleNotifyStatusCallback notifyIdleStatusCallback {nullptr}; 17644514f5e3Sopenharmony_ci 17654514f5e3Sopenharmony_ci IdleTaskType idleTask_ {IdleTaskType::NO_TASK}; 17664514f5e3Sopenharmony_ci float idlePredictDuration_ {0.0f}; 17674514f5e3Sopenharmony_ci double idleTaskFinishTime_ {0.0}; 17684514f5e3Sopenharmony_ci 17694514f5e3Sopenharmony_ci /* 17704514f5e3Sopenharmony_ci * The listeners which are called at the end of GC 17714514f5e3Sopenharmony_ci */ 17724514f5e3Sopenharmony_ci std::vector<std::pair<FinishGCListener, void *>> gcListeners_; 17734514f5e3Sopenharmony_ci 17744514f5e3Sopenharmony_ci IdleGCTrigger *idleGCTrigger_ {nullptr}; 17754514f5e3Sopenharmony_ci 17764514f5e3Sopenharmony_ci bool hasOOMDump_ {false}; 17774514f5e3Sopenharmony_ci bool enableEdenGC_ {false}; 17784514f5e3Sopenharmony_ci 17794514f5e3Sopenharmony_ci CVector<JSNativePointer *> nativePointerList_; 17804514f5e3Sopenharmony_ci CVector<JSNativePointer *> concurrentNativePointerList_; 17814514f5e3Sopenharmony_ci 17824514f5e3Sopenharmony_ci friend panda::test::HProfTestHelper; 17834514f5e3Sopenharmony_ci friend panda::test::GCTest_CallbackTask_Test; 17844514f5e3Sopenharmony_ci}; 17854514f5e3Sopenharmony_ci} // namespace panda::ecmascript 17864514f5e3Sopenharmony_ci 17874514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_HEAP_H 1788