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