1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef ECMASCRIPT_MEM_GC_TRIGGER_H 16 #define ECMASCRIPT_MEM_GC_TRIGGER_H 17 18 #include <atomic> 19 #include <ctime> 20 #include <chrono> 21 22 #include "libpandabase/macros.h" 23 #include "ecmascript/common.h" 24 #include "ecmascript/mem/mem_common.h" 25 #include "ecmascript/base/gc_ring_buffer.h" 26 #include "ecmascript/mem/heap.h" 27 #include "ecmascript/napi/include/jsnapi_expo.h" 28 29 namespace panda::ecmascript { 30 class Heap; 31 class SharedHeap; 32 class ConcurrentMarker; 33 class MemController; 34 class EcmaVM; 35 36 class IdleGCTrigger { 37 using TRIGGER_IDLE_GC_TYPE = panda::JSNApi::TRIGGER_IDLE_GC_TYPE; 38 using Clock = std::chrono::high_resolution_clock; 39 public: 40 explicit IdleGCTrigger(Heap *heap, SharedHeap *sHeap, JSThread *thread, bool logEnable = false) heap_(heap)41 : heap_(heap), 42 sHeap_(sHeap), 43 thread_(thread), 44 optionalLogEnabled_(logEnable) {}; 45 virtual ~IdleGCTrigger() = default; 46 IsIdleState()47 bool IsIdleState() const 48 { 49 return idleState_.load(); 50 } 51 GetGCTypeName(TRIGGER_IDLE_GC_TYPE gcType)52 const char *GetGCTypeName(TRIGGER_IDLE_GC_TYPE gcType) const 53 { 54 switch (gcType) { 55 case TRIGGER_IDLE_GC_TYPE::OLD_GC: 56 return "old gc"; 57 case TRIGGER_IDLE_GC_TYPE::FULL_GC: 58 return "full gc"; 59 case TRIGGER_IDLE_GC_TYPE::SHARED_GC: 60 return "shared gc"; 61 case TRIGGER_IDLE_GC_TYPE::SHARED_FULL_GC: 62 return "shared full gc"; 63 case TRIGGER_IDLE_GC_TYPE::LOCAL_CONCURRENT_MARK: 64 return "local concurrent mark"; 65 case TRIGGER_IDLE_GC_TYPE::LOCAL_REMARK: 66 return "local remark"; 67 default: 68 return "UnknownType"; 69 } 70 } 71 IsPossiblePostGCTask(TRIGGER_IDLE_GC_TYPE gcType)72 bool IsPossiblePostGCTask(TRIGGER_IDLE_GC_TYPE gcType) const 73 { 74 uint8_t bit = static_cast<uint8_t>(gcType); 75 return (bit & gcTaskPostedState_) != bit; 76 } 77 SetPostGCTask(TRIGGER_IDLE_GC_TYPE gcType)78 void SetPostGCTask(TRIGGER_IDLE_GC_TYPE gcType) 79 { 80 uint8_t bit = static_cast<uint8_t>(gcType); 81 gcTaskPostedState_ = (gcTaskPostedState_ | bit); 82 } 83 ClearPostGCTask(TRIGGER_IDLE_GC_TYPE gcType)84 void ClearPostGCTask(TRIGGER_IDLE_GC_TYPE gcType) 85 { 86 uint8_t bit = static_cast<uint8_t>(gcType); 87 gcTaskPostedState_ = (gcTaskPostedState_ & ~bit); 88 } 89 SetTriggerGCTaskCallback(const TriggerGCTaskCallback & callback)90 void SetTriggerGCTaskCallback(const TriggerGCTaskCallback& callback) 91 { 92 triggerGCTaskCallback_ = callback; 93 } 94 95 void NotifyVsyncIdleStart(); 96 void NotifyLooperIdleStart(int64_t timestamp, int idleTime); 97 void NotifyLooperIdleEnd(int64_t timestamp); 98 void TryTriggerHandleMarkFinished(); 99 void TryTriggerLocalConcurrentMark(); 100 bool TryTriggerIdleLocalOldGC(); 101 bool TryTriggerIdleSharedOldGC(); 102 bool ReachIdleLocalOldGCThresholds(); 103 bool ReachIdleSharedGCThresholds(); 104 void TryPostHandleMarkFinished(); 105 void TryTriggerIdleGC(TRIGGER_IDLE_GC_TYPE gcType); 106 bool CheckIdleYoungGC() const; 107 template<class T> 108 bool ShouldCheckIdleOldGC(const T *baseHeap) const; 109 template<class T> 110 bool ShouldCheckIdleFullGC(const T *baseHeap) const; 111 112 private: 113 void PostIdleGCTask(TRIGGER_IDLE_GC_TYPE gcType); 114 115 Heap *heap_ {nullptr}; 116 SharedHeap *sHeap_ {nullptr}; 117 JSThread *thread_ {nullptr}; 118 bool optionalLogEnabled_ {false}; 119 120 std::atomic<bool> idleState_ {false}; 121 uint8_t gcTaskPostedState_ {0}; 122 TriggerGCTaskCallback triggerGCTaskCallback_ {nullptr}; 123 }; 124 125 } 126 127 #endif // ECMASCRIPT_MEM_GC_TRIGGER_H