14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 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_INCREMENTAL_MARKER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_INCREMENTAL_MARKER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/mem/allocator.h" 204514f5e3Sopenharmony_ci#include "ecmascript/mem/garbage_collector.h" 214514f5e3Sopenharmony_ci#include "ecmascript/mem/heap.h" 224514f5e3Sopenharmony_ci#include "ecmascript/mem/mark_stack.h" 234514f5e3Sopenharmony_ci#include "ecmascript/mem/mark_word.h" 244514f5e3Sopenharmony_ci#include "ecmascript/mem/mem.h" 254514f5e3Sopenharmony_ci#include "ecmascript/mem/slots.h" 264514f5e3Sopenharmony_ci#include "ecmascript/mem/visitor.h" 274514f5e3Sopenharmony_ci#include "ecmascript/mem/work_manager.h" 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_cinamespace panda::ecmascript { 304514f5e3Sopenharmony_ciclass EcmaVM; 314514f5e3Sopenharmony_ciclass Heap; 324514f5e3Sopenharmony_ci 334514f5e3Sopenharmony_cienum class IncrementalGCStates { 344514f5e3Sopenharmony_ci ROOT_SCAN, 354514f5e3Sopenharmony_ci INCREMENTAL_MARK, 364514f5e3Sopenharmony_ci REMARK, 374514f5e3Sopenharmony_ci}; 384514f5e3Sopenharmony_ci 394514f5e3Sopenharmony_ci// Incremental Mark only suport old gc 404514f5e3Sopenharmony_ciclass IncrementalMarker { 414514f5e3Sopenharmony_cipublic: 424514f5e3Sopenharmony_ci IncrementalMarker(Heap *heap); 434514f5e3Sopenharmony_ci ~IncrementalMarker() = default; 444514f5e3Sopenharmony_ci 454514f5e3Sopenharmony_ci void TriggerIncrementalMark(int64_t idleMicroSec = 0); 464514f5e3Sopenharmony_ci void Reset(); 474514f5e3Sopenharmony_ci bool IsTriggeredIncrementalMark() 484514f5e3Sopenharmony_ci { 494514f5e3Sopenharmony_ci return isIncrementalMarking_; 504514f5e3Sopenharmony_ci } 514514f5e3Sopenharmony_ci 524514f5e3Sopenharmony_ci void UpdateMarkingSpeed(uint32_t visitAddrNum, double costTime) 534514f5e3Sopenharmony_ci { 544514f5e3Sopenharmony_ci if (costTime > 1) { 554514f5e3Sopenharmony_ci markingSpeed_ = static_cast<uint32_t>((double)visitAddrNum / costTime + markingSpeed_) >> 1; 564514f5e3Sopenharmony_ci } 574514f5e3Sopenharmony_ci } 584514f5e3Sopenharmony_ci 594514f5e3Sopenharmony_ci uint32_t GetMarkingSpeed() 604514f5e3Sopenharmony_ci { 614514f5e3Sopenharmony_ci return markingSpeed_; 624514f5e3Sopenharmony_ci } 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_ci void SetMarkingFinished(bool value) 654514f5e3Sopenharmony_ci { 664514f5e3Sopenharmony_ci markingFinished_ = value; 674514f5e3Sopenharmony_ci } 684514f5e3Sopenharmony_ci 694514f5e3Sopenharmony_ci IncrementalGCStates GetIncrementalGCStates() 704514f5e3Sopenharmony_ci { 714514f5e3Sopenharmony_ci return states_; 724514f5e3Sopenharmony_ci } 734514f5e3Sopenharmony_ci 744514f5e3Sopenharmony_ci uint32_t GetAverageIncrementalMarkingSpeed() 754514f5e3Sopenharmony_ci { 764514f5e3Sopenharmony_ci return incrementalMarkingSpeed_; 774514f5e3Sopenharmony_ci } 784514f5e3Sopenharmony_ci 794514f5e3Sopenharmony_ci double GetCurrentTimeInMs(); 804514f5e3Sopenharmony_ci 814514f5e3Sopenharmony_ciprivate: 824514f5e3Sopenharmony_ci void Mark(); 834514f5e3Sopenharmony_ci void Initialize(); 844514f5e3Sopenharmony_ci void Finish(); 854514f5e3Sopenharmony_ci void ProcessIncrementalMark(int64_t idleMicroSec); 864514f5e3Sopenharmony_ci void RecordIdleTime(int64_t idleMicroSec, double startTime, bool needInitialize = false); 874514f5e3Sopenharmony_ci void PrintGCIdleUsageStatistic(); 884514f5e3Sopenharmony_ci 894514f5e3Sopenharmony_ci void UpdateIncrementalMarkingSpeed(double duration) 904514f5e3Sopenharmony_ci { 914514f5e3Sopenharmony_ci if (duration > 1) { 924514f5e3Sopenharmony_ci incrementalMarkingSpeed_ = static_cast<uint32_t>( 934514f5e3Sopenharmony_ci (double)startObjectSize_ / duration + incrementalMarkingSpeed_) >> 1; 944514f5e3Sopenharmony_ci } 954514f5e3Sopenharmony_ci } 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ci class RecursionScope { 984514f5e3Sopenharmony_ci public: 994514f5e3Sopenharmony_ci explicit RecursionScope(IncrementalMarker* marker) : marker_(marker) 1004514f5e3Sopenharmony_ci { 1014514f5e3Sopenharmony_ci if (marker_->recursionDepth_++ != 0) { 1024514f5e3Sopenharmony_ci LOG_GC(FATAL) << "Recursion in IncrementalMarker Constructor, depth:" << marker_->recursionDepth_; 1034514f5e3Sopenharmony_ci } 1044514f5e3Sopenharmony_ci } 1054514f5e3Sopenharmony_ci ~RecursionScope() 1064514f5e3Sopenharmony_ci { 1074514f5e3Sopenharmony_ci if (--marker_->recursionDepth_ != 0) { 1084514f5e3Sopenharmony_ci LOG_GC(FATAL) << "Recursion in IncrementalMarker Destructor, depth:" << marker_->recursionDepth_; 1094514f5e3Sopenharmony_ci } 1104514f5e3Sopenharmony_ci } 1114514f5e3Sopenharmony_ci private: 1124514f5e3Sopenharmony_ci IncrementalMarker* marker_ {nullptr}; 1134514f5e3Sopenharmony_ci }; 1144514f5e3Sopenharmony_ci 1154514f5e3Sopenharmony_ci Heap *heap_ {nullptr}; 1164514f5e3Sopenharmony_ci EcmaVM *vm_ {nullptr}; 1174514f5e3Sopenharmony_ci 1184514f5e3Sopenharmony_ci WorkManager *workManager_ {nullptr}; 1194514f5e3Sopenharmony_ci double startTime_ {0.0}; 1204514f5e3Sopenharmony_ci size_t startObjectSize_ {0}; 1214514f5e3Sopenharmony_ci 1224514f5e3Sopenharmony_ci bool isIncrementalMarking_ {false}; 1234514f5e3Sopenharmony_ci bool markingFinished_ {false}; 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci uint32_t markingSpeed_ {200_KB}; 1264514f5e3Sopenharmony_ci uint32_t incrementalMarkingSpeed_ {100_KB}; 1274514f5e3Sopenharmony_ci IncrementalGCStates states_ {IncrementalGCStates::ROOT_SCAN}; 1284514f5e3Sopenharmony_ci 1294514f5e3Sopenharmony_ci int64_t receiveIdleTime_ {0}; 1304514f5e3Sopenharmony_ci double totalUsedIdleTime_ {0.0}; 1314514f5e3Sopenharmony_ci double exceedIdleTime_ {0.0}; 1324514f5e3Sopenharmony_ci int32_t recursionDepth_ {0}; 1334514f5e3Sopenharmony_ci 1344514f5e3Sopenharmony_ci friend class Heap; 1354514f5e3Sopenharmony_ci}; 1364514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1374514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_INCREMENTAL_MARKER_H 138