1 /* 2 * Copyright (c) 2023 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 16 #ifndef ECMASCRIPT_MEM_INCREMENTAL_MARKER_H 17 #define ECMASCRIPT_MEM_INCREMENTAL_MARKER_H 18 19 #include "ecmascript/mem/allocator.h" 20 #include "ecmascript/mem/garbage_collector.h" 21 #include "ecmascript/mem/heap.h" 22 #include "ecmascript/mem/mark_stack.h" 23 #include "ecmascript/mem/mark_word.h" 24 #include "ecmascript/mem/mem.h" 25 #include "ecmascript/mem/slots.h" 26 #include "ecmascript/mem/visitor.h" 27 #include "ecmascript/mem/work_manager.h" 28 29 namespace panda::ecmascript { 30 class EcmaVM; 31 class Heap; 32 33 enum class IncrementalGCStates { 34 ROOT_SCAN, 35 INCREMENTAL_MARK, 36 REMARK, 37 }; 38 39 // Incremental Mark only suport old gc 40 class IncrementalMarker { 41 public: 42 IncrementalMarker(Heap *heap); 43 ~IncrementalMarker() = default; 44 45 void TriggerIncrementalMark(int64_t idleMicroSec = 0); 46 void Reset(); IsTriggeredIncrementalMark()47 bool IsTriggeredIncrementalMark() 48 { 49 return isIncrementalMarking_; 50 } 51 UpdateMarkingSpeed(uint32_t visitAddrNum,double costTime)52 void UpdateMarkingSpeed(uint32_t visitAddrNum, double costTime) 53 { 54 if (costTime > 1) { 55 markingSpeed_ = static_cast<uint32_t>((double)visitAddrNum / costTime + markingSpeed_) >> 1; 56 } 57 } 58 GetMarkingSpeed()59 uint32_t GetMarkingSpeed() 60 { 61 return markingSpeed_; 62 } 63 SetMarkingFinished(bool value)64 void SetMarkingFinished(bool value) 65 { 66 markingFinished_ = value; 67 } 68 GetIncrementalGCStates()69 IncrementalGCStates GetIncrementalGCStates() 70 { 71 return states_; 72 } 73 GetAverageIncrementalMarkingSpeed()74 uint32_t GetAverageIncrementalMarkingSpeed() 75 { 76 return incrementalMarkingSpeed_; 77 } 78 79 double GetCurrentTimeInMs(); 80 81 private: 82 void MarkRoots(); 83 void Mark(); 84 void Initialize(); 85 void Finish(); 86 void ProcessIncrementalMark(int64_t idleMicroSec); 87 void RecordIdleTime(int64_t idleMicroSec, double startTime, bool needInitialize = false); 88 void PrintGCIdleUsageStatistic(); 89 UpdateIncrementalMarkingSpeed(double duration)90 void UpdateIncrementalMarkingSpeed(double duration) 91 { 92 if (duration > 1) { 93 incrementalMarkingSpeed_ = static_cast<uint32_t>( 94 (double)startObjectSize_ / duration + incrementalMarkingSpeed_) >> 1; 95 } 96 } 97 98 class RecursionScope { 99 public: RecursionScope(IncrementalMarker * marker)100 explicit RecursionScope(IncrementalMarker* marker) : marker_(marker) 101 { 102 if (marker_->recursionDepth_++ != 0) { 103 LOG_GC(FATAL) << "Recursion in IncrementalMarker Constructor, depth:" << marker_->recursionDepth_; 104 } 105 } ~RecursionScope()106 ~RecursionScope() 107 { 108 if (--marker_->recursionDepth_ != 0) { 109 LOG_GC(FATAL) << "Recursion in IncrementalMarker Destructor, depth:" << marker_->recursionDepth_; 110 } 111 } 112 private: 113 IncrementalMarker* marker_ {nullptr}; 114 }; 115 116 Heap *heap_ {nullptr}; 117 EcmaVM *vm_ {nullptr}; 118 119 WorkManager *workManager_ {nullptr}; 120 double startTime_ {0.0}; 121 size_t startObjectSize_ {0}; 122 123 bool isIncrementalMarking_ {false}; 124 bool markingFinished_ {false}; 125 126 uint32_t markingSpeed_ {200_KB}; 127 uint32_t incrementalMarkingSpeed_ {100_KB}; 128 IncrementalGCStates states_ {IncrementalGCStates::ROOT_SCAN}; 129 130 int64_t receiveIdleTime_ {0}; 131 double totalUsedIdleTime_ {0.0}; 132 double exceedIdleTime_ {0.0}; 133 int32_t recursionDepth_ {0}; 134 135 friend class Heap; 136 }; 137 } // namespace panda::ecmascript 138 #endif // ECMASCRIPT_MEM_INCREMENTAL_MARKER_H 139