14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_MEM_GC_STATS_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_GC_STATS_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <chrono> 204514f5e3Sopenharmony_ci#include <cstring> 214514f5e3Sopenharmony_ci#include <ctime> 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_ci#include "ecmascript/common.h" 244514f5e3Sopenharmony_ci#include "ecmascript/mem/clock_scope.h" 254514f5e3Sopenharmony_ci#include "ecmascript/mem/mem_common.h" 264514f5e3Sopenharmony_ci#include "libpandabase/macros.h" 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_cinamespace panda::ecmascript { 294514f5e3Sopenharmony_ciclass Heap; 304514f5e3Sopenharmony_ciclass SharedHeap; 314514f5e3Sopenharmony_ci 324514f5e3Sopenharmony_cienum class GCType : int { 334514f5e3Sopenharmony_ci PARTIAL_EDEN_GC, 344514f5e3Sopenharmony_ci PARTIAL_YOUNG_GC, 354514f5e3Sopenharmony_ci PARTIAL_OLD_GC, 364514f5e3Sopenharmony_ci COMPRESS_GC, 374514f5e3Sopenharmony_ci SHARED_GC, 384514f5e3Sopenharmony_ci SHARED_FULL_GC, 394514f5e3Sopenharmony_ci OTHER, 404514f5e3Sopenharmony_ci START, 414514f5e3Sopenharmony_ci}; 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_cienum class RecordData : uint8_t { 444514f5e3Sopenharmony_ci#define DEFINE_SCOPE(scope) scope, 454514f5e3Sopenharmony_ci RECORD_DATA(DEFINE_SCOPE) 464514f5e3Sopenharmony_ci#undef DEFINE_SCOPE 474514f5e3Sopenharmony_ci NUM_OF_DATA, 484514f5e3Sopenharmony_ci FIRST_DATA = START_OBJ_SIZE, 494514f5e3Sopenharmony_ci END_RECORD_OVERWRITE = COLLECT_REGION_SET_SIZE, 504514f5e3Sopenharmony_ci}; 514514f5e3Sopenharmony_ci 524514f5e3Sopenharmony_cienum class SpeedData : uint8_t { 534514f5e3Sopenharmony_ci#define DEFINE_SCOPE(scope) scope, 544514f5e3Sopenharmony_ci TRACE_GC_SPEED(DEFINE_SCOPE) 554514f5e3Sopenharmony_ci#undef DEFINE_SCOPE 564514f5e3Sopenharmony_ci NUM_OF_SPEED, 574514f5e3Sopenharmony_ci}; 584514f5e3Sopenharmony_ci 594514f5e3Sopenharmony_cienum class RecordDuration : uint8_t { 604514f5e3Sopenharmony_ci#define DEFINE_SCOPE(scope) scope, 614514f5e3Sopenharmony_ci RECORD_DURATION(DEFINE_SCOPE) 624514f5e3Sopenharmony_ci#undef DEFINE_SCOPE 634514f5e3Sopenharmony_ci NUM_OF_DURATION, 644514f5e3Sopenharmony_ci FIRST_DATA = SEMI_MIN_PAUSE, 654514f5e3Sopenharmony_ci}; 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_ci#define TRACE_GC(scope_id, gc_stats) \ 684514f5e3Sopenharmony_ci [[maybe_unused]] GCStats::Scope sp(scope_id, gc_stats) 694514f5e3Sopenharmony_ci 704514f5e3Sopenharmony_ciclass GCStats { 714514f5e3Sopenharmony_ci using Duration = std::chrono::duration<uint64_t, std::nano>; 724514f5e3Sopenharmony_ci 734514f5e3Sopenharmony_cipublic: 744514f5e3Sopenharmony_ci explicit GCStats(const Heap *heap) : heap_(heap) {} 754514f5e3Sopenharmony_ci GCStats(const Heap *heap, size_t longPuaseTime) : heap_(heap), 764514f5e3Sopenharmony_ci longPauseTime_(longPuaseTime) {} 774514f5e3Sopenharmony_ci virtual ~GCStats() = default; 784514f5e3Sopenharmony_ci 794514f5e3Sopenharmony_ci virtual void PrintStatisticResult(); 804514f5e3Sopenharmony_ci virtual void PrintGCMemoryStatistic(); 814514f5e3Sopenharmony_ci bool CheckIfLongTimePause(); 824514f5e3Sopenharmony_ci virtual void PrintGCStatistic(); 834514f5e3Sopenharmony_ci 844514f5e3Sopenharmony_ci float GetGCSpeed(SpeedData data) 854514f5e3Sopenharmony_ci { 864514f5e3Sopenharmony_ci return gcSpeed_[(uint8_t)data]; 874514f5e3Sopenharmony_ci } 884514f5e3Sopenharmony_ci 894514f5e3Sopenharmony_ci void SetRecordData(RecordData dataIdx, size_t value) 904514f5e3Sopenharmony_ci { 914514f5e3Sopenharmony_ci recordData_[GetRecordDataIndex(dataIdx)] = value; 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci 944514f5e3Sopenharmony_ci size_t GetRecordData(RecordData dataIdx) 954514f5e3Sopenharmony_ci { 964514f5e3Sopenharmony_ci return recordData_[GetRecordDataIndex(dataIdx)]; 974514f5e3Sopenharmony_ci } 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_ci void SetGCReason(GCReason reason) 1004514f5e3Sopenharmony_ci { 1014514f5e3Sopenharmony_ci reason_ = reason; 1024514f5e3Sopenharmony_ci } 1034514f5e3Sopenharmony_ci 1044514f5e3Sopenharmony_ci GCReason GetGCReason() const 1054514f5e3Sopenharmony_ci { 1064514f5e3Sopenharmony_ci return reason_; 1074514f5e3Sopenharmony_ci } 1084514f5e3Sopenharmony_ci 1094514f5e3Sopenharmony_ci const char *GetGCTypeName() 1104514f5e3Sopenharmony_ci { 1114514f5e3Sopenharmony_ci switch (gcType_) { 1124514f5e3Sopenharmony_ci case GCType::PARTIAL_EDEN_GC: 1134514f5e3Sopenharmony_ci return "HPP EdenGC"; 1144514f5e3Sopenharmony_ci case GCType::PARTIAL_YOUNG_GC: 1154514f5e3Sopenharmony_ci return "HPP YoungGC"; 1164514f5e3Sopenharmony_ci case GCType::PARTIAL_OLD_GC: 1174514f5e3Sopenharmony_ci return "HPP OldGC"; 1184514f5e3Sopenharmony_ci case GCType::COMPRESS_GC: 1194514f5e3Sopenharmony_ci return "CompressGC"; 1204514f5e3Sopenharmony_ci case GCType::SHARED_GC: 1214514f5e3Sopenharmony_ci return "SharedGC"; 1224514f5e3Sopenharmony_ci case GCType::SHARED_FULL_GC: 1234514f5e3Sopenharmony_ci return "SharedCompressGC"; 1244514f5e3Sopenharmony_ci default: 1254514f5e3Sopenharmony_ci return "UnknownType"; 1264514f5e3Sopenharmony_ci } 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci 1294514f5e3Sopenharmony_ci static const char *GCReasonToString(GCReason reason); 1304514f5e3Sopenharmony_ci const char *GCReasonToString(); 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_ci double GetAvgSurvivalRate() 1334514f5e3Sopenharmony_ci { 1344514f5e3Sopenharmony_ci if (gcType_ == GCType::PARTIAL_EDEN_GC) { 1354514f5e3Sopenharmony_ci size_t commitSize = GetRecordData(RecordData::EDEN_TOTAL_COMMIT); 1364514f5e3Sopenharmony_ci if (commitSize == 0) { 1374514f5e3Sopenharmony_ci return 0; 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci double copiedRate = double(GetRecordData(RecordData::EDEN_TOTAL_ALIVE)) / commitSize; 1404514f5e3Sopenharmony_ci double promotedRate = double(GetRecordData(RecordData::EDEN_TOTAL_PROMOTE)) / commitSize; 1414514f5e3Sopenharmony_ci return std::min(copiedRate + promotedRate, 1.0); 1424514f5e3Sopenharmony_ci } 1434514f5e3Sopenharmony_ci double copiedRate = double(GetRecordData(RecordData::YOUNG_TOTAL_ALIVE)) / 1444514f5e3Sopenharmony_ci GetRecordData(RecordData::YOUNG_TOTAL_COMMIT); 1454514f5e3Sopenharmony_ci double promotedRate = double(GetRecordData(RecordData::YOUNG_TOTAL_PROMOTE)) / 1464514f5e3Sopenharmony_ci GetRecordData(RecordData::YOUNG_TOTAL_COMMIT); 1474514f5e3Sopenharmony_ci return std::min(copiedRate + promotedRate, 1.0); 1484514f5e3Sopenharmony_ci } 1494514f5e3Sopenharmony_ci 1504514f5e3Sopenharmony_ci virtual void RecordGCSpeed(); 1514514f5e3Sopenharmony_ci virtual void RecordStatisticBeforeGC(TriggerGCType gcType, GCReason reason); 1524514f5e3Sopenharmony_ci virtual void RecordStatisticAfterGC(); 1534514f5e3Sopenharmony_ci 1544514f5e3Sopenharmony_ci class Scope : public ClockScope { 1554514f5e3Sopenharmony_ci public: 1564514f5e3Sopenharmony_ci enum ScopeId : uint8_t { 1574514f5e3Sopenharmony_ci#define DEFINE_SCOPE(scope) scope, 1584514f5e3Sopenharmony_ci SCOPE_LIST(DEFINE_SCOPE) 1594514f5e3Sopenharmony_ci#undef DEFINE_SCOPE 1604514f5e3Sopenharmony_ci SCOPE_NUM, 1614514f5e3Sopenharmony_ci }; 1624514f5e3Sopenharmony_ci 1634514f5e3Sopenharmony_ci Scope(ScopeId id, GCStats* stats) : id_(id), stats_(stats) 1644514f5e3Sopenharmony_ci { 1654514f5e3Sopenharmony_ci if (id_ == ScopeId::ConcurrentMark) { 1664514f5e3Sopenharmony_ci stats_->NotifyConcurrentMark(); 1674514f5e3Sopenharmony_ci } 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci ~Scope() 1704514f5e3Sopenharmony_ci { 1714514f5e3Sopenharmony_ci float duration = stats_->PrintTimeMilliseconds(stats_->TimeToMicroseconds(GetPauseTime())); 1724514f5e3Sopenharmony_ci stats_->SetScopeId(id_, duration); 1734514f5e3Sopenharmony_ci } 1744514f5e3Sopenharmony_ci 1754514f5e3Sopenharmony_ci private: 1764514f5e3Sopenharmony_ci ScopeId id_; 1774514f5e3Sopenharmony_ci GCStats* stats_; 1784514f5e3Sopenharmony_ci }; 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ci float GetScopeDuration(int pos) const 1814514f5e3Sopenharmony_ci { 1824514f5e3Sopenharmony_ci return scopeDuration_[pos]; 1834514f5e3Sopenharmony_ci } 1844514f5e3Sopenharmony_ci 1854514f5e3Sopenharmony_ci void IncreaseTotalDuration(float duration) 1864514f5e3Sopenharmony_ci { 1874514f5e3Sopenharmony_ci gcDuration_ += duration; 1884514f5e3Sopenharmony_ci } 1894514f5e3Sopenharmony_ci 1904514f5e3Sopenharmony_ci size_t GetGCCount() 1914514f5e3Sopenharmony_ci { 1924514f5e3Sopenharmony_ci return GetRecordData(RecordData::SEMI_COUNT) + GetRecordData(RecordData::YOUNG_COUNT) + 1934514f5e3Sopenharmony_ci GetRecordData(RecordData::OLD_COUNT) + GetRecordData(RecordData::COMPRESS_COUNT) + 1944514f5e3Sopenharmony_ci GetRecordData(RecordData::SHARED_COUNT); 1954514f5e3Sopenharmony_ci } 1964514f5e3Sopenharmony_ci 1974514f5e3Sopenharmony_ci size_t GetGCDuration() const 1984514f5e3Sopenharmony_ci { 1994514f5e3Sopenharmony_ci return static_cast<size_t>(gcDuration_); 2004514f5e3Sopenharmony_ci } 2014514f5e3Sopenharmony_ci 2024514f5e3Sopenharmony_ci virtual size_t GetAccumulatedAllocateSize(); 2034514f5e3Sopenharmony_ci size_t GetAccumulatedFreeSize() const 2044514f5e3Sopenharmony_ci { 2054514f5e3Sopenharmony_ci return accumulatedFreeSize_; 2064514f5e3Sopenharmony_ci } 2074514f5e3Sopenharmony_ci 2084514f5e3Sopenharmony_ci void IncreaseFullGCLongTimeCount() 2094514f5e3Sopenharmony_ci { 2104514f5e3Sopenharmony_ci fullGCLongTimeCount_ += 1; 2114514f5e3Sopenharmony_ci } 2124514f5e3Sopenharmony_ci 2134514f5e3Sopenharmony_ci size_t GetFullGCLongTimeCount() const 2144514f5e3Sopenharmony_ci { 2154514f5e3Sopenharmony_ci return fullGCLongTimeCount_; 2164514f5e3Sopenharmony_ci } 2174514f5e3Sopenharmony_ci 2184514f5e3Sopenharmony_ciprotected: 2194514f5e3Sopenharmony_ci bool CheckIfNeedPrint(GCType type); 2204514f5e3Sopenharmony_ci void PrintVerboseGCStatistic(); 2214514f5e3Sopenharmony_ci void PrintGCDurationStatistic(); 2224514f5e3Sopenharmony_ci void PrintGCSummaryStatistic(GCType type = GCType::START); 2234514f5e3Sopenharmony_ci GCType GetGCType(TriggerGCType gcType); 2244514f5e3Sopenharmony_ci void InitializeRecordList(); 2254514f5e3Sopenharmony_ci float GetConcurrrentMarkDuration(); 2264514f5e3Sopenharmony_ci 2274514f5e3Sopenharmony_ci int GetRecordDurationIndex(RecordDuration durationIdx) 2284514f5e3Sopenharmony_ci { 2294514f5e3Sopenharmony_ci return (int)durationIdx - (int)RecordDuration::FIRST_DATA; 2304514f5e3Sopenharmony_ci } 2314514f5e3Sopenharmony_ci 2324514f5e3Sopenharmony_ci float GetRecordDuration(RecordDuration durationIdx) 2334514f5e3Sopenharmony_ci { 2344514f5e3Sopenharmony_ci return recordDuration_[GetRecordDurationIndex(durationIdx)]; 2354514f5e3Sopenharmony_ci } 2364514f5e3Sopenharmony_ci 2374514f5e3Sopenharmony_ci void SetRecordDuration(RecordDuration durationIdx, float value) 2384514f5e3Sopenharmony_ci { 2394514f5e3Sopenharmony_ci recordDuration_[GetRecordDurationIndex(durationIdx)] = value; 2404514f5e3Sopenharmony_ci } 2414514f5e3Sopenharmony_ci 2424514f5e3Sopenharmony_ci void IncreaseRecordDuration(RecordDuration durationIdx, float value) 2434514f5e3Sopenharmony_ci { 2444514f5e3Sopenharmony_ci recordDuration_[GetRecordDurationIndex(durationIdx)] += value; 2454514f5e3Sopenharmony_ci } 2464514f5e3Sopenharmony_ci 2474514f5e3Sopenharmony_ci int GetRecordDataIndex(RecordData dataIdx) 2484514f5e3Sopenharmony_ci { 2494514f5e3Sopenharmony_ci return (int)dataIdx - (int)RecordData::FIRST_DATA; 2504514f5e3Sopenharmony_ci } 2514514f5e3Sopenharmony_ci 2524514f5e3Sopenharmony_ci void IncreaseRecordData(RecordData dataIdx, size_t value = 1) 2534514f5e3Sopenharmony_ci { 2544514f5e3Sopenharmony_ci recordData_[GetRecordDataIndex(dataIdx)] += value; 2554514f5e3Sopenharmony_ci } 2564514f5e3Sopenharmony_ci 2574514f5e3Sopenharmony_ci void SetScopeId(int pos, float duration) 2584514f5e3Sopenharmony_ci { 2594514f5e3Sopenharmony_ci scopeDuration_[pos] = duration; 2604514f5e3Sopenharmony_ci } 2614514f5e3Sopenharmony_ci 2624514f5e3Sopenharmony_ci void NotifyConcurrentMark() 2634514f5e3Sopenharmony_ci { 2644514f5e3Sopenharmony_ci concurrentMark_ = true; 2654514f5e3Sopenharmony_ci } 2664514f5e3Sopenharmony_ci 2674514f5e3Sopenharmony_ci void IncreaseAccumulatedFreeSize(size_t size) 2684514f5e3Sopenharmony_ci { 2694514f5e3Sopenharmony_ci accumulatedFreeSize_ += size; 2704514f5e3Sopenharmony_ci } 2714514f5e3Sopenharmony_ci 2724514f5e3Sopenharmony_ci size_t TimeToMicroseconds(Duration time) 2734514f5e3Sopenharmony_ci { 2744514f5e3Sopenharmony_ci return std::chrono::duration_cast<std::chrono::microseconds>(time).count(); 2754514f5e3Sopenharmony_ci } 2764514f5e3Sopenharmony_ci 2774514f5e3Sopenharmony_ci float PrintTimeMilliseconds(uint64_t ms) 2784514f5e3Sopenharmony_ci { 2794514f5e3Sopenharmony_ci return (float)ms / THOUSAND; 2804514f5e3Sopenharmony_ci } 2814514f5e3Sopenharmony_ci 2824514f5e3Sopenharmony_ci float sizeToMB(size_t size) 2834514f5e3Sopenharmony_ci { 2844514f5e3Sopenharmony_ci return (float)size / 1_MB; 2854514f5e3Sopenharmony_ci } 2864514f5e3Sopenharmony_ci 2874514f5e3Sopenharmony_ci float sizeToKB(size_t size) 2884514f5e3Sopenharmony_ci { 2894514f5e3Sopenharmony_ci return (float)size / 1_KB; 2904514f5e3Sopenharmony_ci } 2914514f5e3Sopenharmony_ci 2924514f5e3Sopenharmony_ci const Heap *heap_ {nullptr}; 2934514f5e3Sopenharmony_ci float gcDuration_ = 0.0f; 2944514f5e3Sopenharmony_ci size_t longPauseTime_ = 0; 2954514f5e3Sopenharmony_ci size_t fullGCLongTimeCount_ = 0; 2964514f5e3Sopenharmony_ci size_t accumulatedFreeSize_ = 0; 2974514f5e3Sopenharmony_ci 2984514f5e3Sopenharmony_ci static constexpr size_t DEFAULT_UPDATE_REFERENCE_SPEED = 10_MB; 2994514f5e3Sopenharmony_ci static constexpr size_t DEFAULT_OLD_CLEAR_NATIVE_OBJ_SPEED = 1_KB; 3004514f5e3Sopenharmony_ci static constexpr size_t DEFAULT_OLD_EVACUATE_SPACE_SPEED = 600_KB; 3014514f5e3Sopenharmony_ci static constexpr size_t DEFAULT_YOUNG_CLEAR_NATIVE_OBJ_SPEED = 3_KB; 3024514f5e3Sopenharmony_ci 3034514f5e3Sopenharmony_ci GCType gcType_ {GCType::START}; 3044514f5e3Sopenharmony_ci GCReason reason_ {GCReason::OTHER}; 3054514f5e3Sopenharmony_ci float scopeDuration_[Scope::ScopeId::SCOPE_NUM] {0.0f}; 3064514f5e3Sopenharmony_ci size_t recordData_[(uint8_t)RecordData::NUM_OF_DATA] {0}; 3074514f5e3Sopenharmony_ci size_t gcSpeed_ [(uint8_t)SpeedData::NUM_OF_SPEED] = { 3084514f5e3Sopenharmony_ci DEFAULT_UPDATE_REFERENCE_SPEED, DEFAULT_OLD_CLEAR_NATIVE_OBJ_SPEED, 3094514f5e3Sopenharmony_ci DEFAULT_OLD_EVACUATE_SPACE_SPEED, DEFAULT_YOUNG_CLEAR_NATIVE_OBJ_SPEED}; 3104514f5e3Sopenharmony_ci float recordDuration_[(uint8_t)RecordDuration::NUM_OF_DURATION] {0.0f}; 3114514f5e3Sopenharmony_ci bool concurrentMark_ {false}; 3124514f5e3Sopenharmony_ci 3134514f5e3Sopenharmony_ci static constexpr uint32_t THOUSAND = 1000; 3144514f5e3Sopenharmony_ci 3154514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(GCStats); 3164514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(GCStats); 3174514f5e3Sopenharmony_ci}; 3184514f5e3Sopenharmony_ci 3194514f5e3Sopenharmony_ciclass SharedGCStats : public GCStats { 3204514f5e3Sopenharmony_cipublic: 3214514f5e3Sopenharmony_ci SharedGCStats(const SharedHeap *sHeap, bool enableGCTracer) 3224514f5e3Sopenharmony_ci : GCStats(nullptr), sHeap_(sHeap), enableGCTracer_(enableGCTracer) 3234514f5e3Sopenharmony_ci { 3244514f5e3Sopenharmony_ci SetRecordData(RecordData::SHARED_COUNT, 0); 3254514f5e3Sopenharmony_ci } 3264514f5e3Sopenharmony_ci ~SharedGCStats() = default; 3274514f5e3Sopenharmony_ci 3284514f5e3Sopenharmony_ci void PrintStatisticResult() override; 3294514f5e3Sopenharmony_ci void PrintGCMemoryStatistic() override; 3304514f5e3Sopenharmony_ci void PrintGCStatistic() override; 3314514f5e3Sopenharmony_ci 3324514f5e3Sopenharmony_ci void RecordStatisticBeforeGC(TriggerGCType gcType, GCReason reason) override; 3334514f5e3Sopenharmony_ci void RecordStatisticAfterGC() override; 3344514f5e3Sopenharmony_ci size_t GetAccumulatedAllocateSize() override; 3354514f5e3Sopenharmony_ciprivate: 3364514f5e3Sopenharmony_ci void PrintSharedGCDuration(); 3374514f5e3Sopenharmony_ci void PrintSharedGCSummaryStatistic(); 3384514f5e3Sopenharmony_ci 3394514f5e3Sopenharmony_ci const SharedHeap *sHeap_ {nullptr}; 3404514f5e3Sopenharmony_ci bool enableGCTracer_ {false}; 3414514f5e3Sopenharmony_ci}; 3424514f5e3Sopenharmony_ci} // namespace panda::ecmascript 3434514f5e3Sopenharmony_ci 3444514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_GC_STATS_H 345