From 9870d6cec14b619012bb8bcadb5b2c4342200434 Mon Sep 17 00:00:00 2001 From: lvninglei Date: Sat, 30 Aug 2025 15:39:30 +0800 Subject: [PATCH] Add sysEvent of long time CMCGC https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICVK92 Signed-off-by: lvninglei Change-Id: I6dd50bb3a36b4d34bea431ae6cb40f64bb270c13 --- .../heap/ark_collector/ark_collector.cpp | 1 + .../heap/collector/clock_scope.h | 77 ++++++ common_components/heap/collector/gc_stats.h | 57 ++++ .../heap/collector/long_gc_stats.h | 248 ++++++++++++++++++ .../heap/collector/marking_collector.cpp | 87 +++++- .../heap/collector/marking_collector.h | 1 + ecmascript/platform/dfx_hisys_event.h | 3 + .../platform/unix/linux/dfx_hisys_event.cpp | 7 +- .../platform/unix/mac/dfx_hisys_event.cpp | 7 +- .../platform/unix/ohos/dfx_hisys_event.cpp | 40 +++ .../platform/windows/dfx_hisys_event.cpp | 7 +- hisysevent.yaml | 28 +- 12 files changed, 553 insertions(+), 10 deletions(-) create mode 100644 common_components/heap/collector/clock_scope.h create mode 100644 common_components/heap/collector/long_gc_stats.h diff --git a/common_components/heap/ark_collector/ark_collector.cpp b/common_components/heap/ark_collector/ark_collector.cpp index 019834557f..a5d4df47e0 100755 --- a/common_components/heap/ark_collector/ark_collector.cpp +++ b/common_components/heap/ark_collector/ark_collector.cpp @@ -763,6 +763,7 @@ void ArkCollector::FixHeap() { TransitionToGCPhase(GCPhase::GC_PHASE_FIX, true); COMMON_PHASE_TIMER("FixHeap"); + TRACE_CMCGC(GCStats::Scope::ScopeId::FixHeap, &GetGCStats()); OHOS_HITRACE(HITRACE_LEVEL_COMMERCIAL, "CMCGC::FixHeap", ""); ParallelFixHeap(); diff --git a/common_components/heap/collector/clock_scope.h b/common_components/heap/collector/clock_scope.h new file mode 100644 index 0000000000..9d99e90ad3 --- /dev/null +++ b/common_components/heap/collector/clock_scope.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_HEAP_COLLECTOR_CLOCK_SCOPE_H +#define COMMON_HEAP_COLLECTOR_CLOCK_SCOPE_H + +#include +#include + +#include "libpandabase/macros.h" + +namespace common { + +#define CMC_SCOPE_LIST(V) \ + V(TotalGC) \ + V(MarkingRoots) \ + V(CopyFromSpace) \ + V(FixHeap) + +class ClockScope { +using Clock = std::chrono::high_resolution_clock; +using Duration = std::chrono::duration; + +public: + ClockScope() + { + start_ = Clock::now(); + } + + void Reset() + { + start_ = Clock::now(); + } + + Duration GetPauseTime() const + { + return Clock::now() - start_; + } + + float TotalSpentTime() const + { + auto duration = std::chrono::duration_cast(Clock::now() - start_); + return (float) duration.count() / MILLION_TIME; + } + + int TotalSpentTimeInMicroseconds() const + { + return std::chrono::duration_cast(Clock::now() - start_).count(); + } + + double GetCurTime() const + { + auto curTime_ = Duration(start_.time_since_epoch()); + return (double) curTime_.count() / MILLION_TIME; + } + +private: + NO_COPY_SEMANTIC(ClockScope); + NO_MOVE_SEMANTIC(ClockScope); + + Clock::time_point start_; + static constexpr uint32_t MILLION_TIME = 1000; +}; +} // common::ecmascript +#endif // COMMON_HEAP_COLLECTOR_CLOCK_SCOPE_H diff --git a/common_components/heap/collector/gc_stats.h b/common_components/heap/collector/gc_stats.h index ceb21991b8..17c221195e 100755 --- a/common_components/heap/collector/gc_stats.h +++ b/common_components/heap/collector/gc_stats.h @@ -26,16 +26,23 @@ #include "common_components/heap/collector/gc_request.h" #include "common_components/log/log.h" #include "common_interfaces/base_runtime.h" +#include "common_components/heap/collector/clock_scope.h" namespace common { + +#define TRACE_CMCGC(scope_id, gc_stats) \ + [[maybe_unused]] GCStats::Scope sp(scope_id, gc_stats) // statistics for previous gc. class GCStats { + using Duration = std::chrono::duration; public: GCStats() = default; ~GCStats() = default; void Init(); + static constexpr uint32_t THOUSAND = 1000; + size_t GetThreshold() const { return heapThreshold; } inline uint64_t TotalSTWTime() const { return totalSTWTime; } @@ -62,6 +69,31 @@ public: void IncreaseAccumulatedFreeSize(size_t size) { accumulatedFreeSize += size; } + class Scope : public ClockScope { + public: + enum ScopeId : uint8_t { +#define DEFINE_SCOPE(scope) scope, + CMC_SCOPE_LIST(DEFINE_SCOPE) +#undef DEFINE_SCOPE + CMC_SCOPE_NUM, + }; + + Scope(ScopeId id, GCStats* stats) : id_(id), stats_(stats) + { + } + + ~Scope() + { + float duration = stats_->PrintTimeMilliseconds(stats_->TimeToMicroseconds(GetPauseTime())); + stats_->SetScopeId(id_, duration); + } + + private: + ScopeId id_; + GCStats* stats_; + }; + + float scopeDuration_[Scope::ScopeId::CMC_SCOPE_NUM] {0.0f}; static uint64_t prevGcStartTime; static uint64_t prevGcFinishTime; @@ -99,6 +131,11 @@ public: size_t heapThreshold; size_t targetFootprint; + size_t beforeGCTAllocatedSize; + size_t beforeGCThreshold; + size_t beforeGCNativeAllocatedSize; + size_t beforeGCNativeThreshold; + // Use for heuristic request, set by last gc status. bool shouldRequestYoung; @@ -106,6 +143,26 @@ public: { return reason == GCReason::GC_REASON_YOUNG; } + + void SetScopeId(int pos, float duration) + { + scopeDuration_[pos] = duration; + } + + float PrintTimeMilliseconds(uint64_t ms) + { + return (float)ms / THOUSAND; + } + + float GetScopeDuration(int pos) const + { + return scopeDuration_[pos]; + } + + size_t TimeToMicroseconds(Duration time) + { + return std::chrono::duration_cast(time).count(); + } }; extern size_t g_gcCount; extern uint64_t g_gcTotalTimeUs; diff --git a/common_components/heap/collector/long_gc_stats.h b/common_components/heap/collector/long_gc_stats.h new file mode 100644 index 0000000000..841190fcfd --- /dev/null +++ b/common_components/heap/collector/long_gc_stats.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECMASCRIPT_MEM_LONG_CMC_GC_STATS_H +#define ECMASCRIPT_MEM_LONG_CMC_GC_STATS_H +#include + +namespace common { +class LongCMCGCStats { +public: + ~LongCMCGCStats() = default; + + void Reset() + { + gcType_ = 0; + gcReason_ = 0; + gcIsSensitive_ = false; + gcIsInBackground_ = false; + gcTotalTime_ = 0.0f; + gcCopyFromSpaceTime_ = 0.0f; + gcFixHeapTime_ = 0.0f; + gcMaxSTWTime_ = 0.0f; + gcSTWTime_ = 0.0f; + beforeGCTAllocatedSize_ = 0; + beforeGCThreshold_ = 0; + beforeGCNativeAllocatedSize_ = 0; + beforeGCNativeThreshold_ = 0; + afterGCTAllocatedSize_ = 0; + afterGCThreshold_ = 0; + afterGCNativeAllocatedSize_ = 0; + afterGCNativeThreshold_ = 0; + cpuLoad_ = 0.0; + } + static int SizeToIntKB(size_t size) + { + return static_cast(size / 1024); + } + size_t GetGCType() const + { + return gcType_; + } + void SetGCType(size_t gcType) + { + gcType_ = gcType; + } + + size_t GetGCReason() const + { + return gcReason_; + } + void SetGCReason(size_t gcReason) + { + gcReason_ = gcReason; + } + + bool GetGCIsSensitive() const + { + return gcIsSensitive_; + } + void SetGCIsSensitive(bool gcIsSensitive) + { + gcIsSensitive_ = gcIsSensitive; + } + + bool GetGCIsInBackground() const + { + return gcIsInBackground_; + } + void SetGCIsInBackground(bool gcIsInBackground) + { + gcIsInBackground_ = gcIsInBackground; + } + + float GetGCTotalTime() const + { + return gcTotalTime_; + } + void SetGCTotalTime(float gcTotalTime) + { + gcTotalTime_ = gcTotalTime; + } + + float GetGCMarkRootsTime() const + { + return gcMarkRootsTime_; + } + + void SetGCMarkRootsTime(float gcMarkRootsTime) + { + gcMarkRootsTime_ = gcMarkRootsTime; + } + + float GetGCCopyFromSpaceTime() const + { + return gcCopyFromSpaceTime_; + } + + void SetGCCopyFromSpaceTime(float gcCopyFromSpaceTime) + { + gcCopyFromSpaceTime_ = gcCopyFromSpaceTime; + } + + float GetGCFixHeapTime() const + { + return gcFixHeapTime_; + } + void SetGCFixHeapTime(float gcFixHeapTime) + { + gcFixHeapTime_ = gcFixHeapTime; + } + + float GetGCMaxSTWTime() const + { + return gcMaxSTWTime_; + } + void SetGCMaxSTWTime(float gcMaxSTWTime) + { + gcMaxSTWTime_ = gcMaxSTWTime; + } + + float GetGCSTWTime() const + { + return gcSTWTime_; + } + void SetGCSTWTime(float gcSTWTime) + { + gcSTWTime_ = gcSTWTime; + } + + size_t GetBeforeGCTAllocatedSize() const + { + return beforeGCTAllocatedSize_; + } + void SetBeforeGCTAllocatedSize(size_t beforeGCTAllocatedSize) + { + beforeGCTAllocatedSize_ = beforeGCTAllocatedSize; + } + + size_t GetBeforeGCThreshold() const + { + return beforeGCThreshold_; + } + void SetBeforeGCThreshold(size_t beforeGCThreshold) + { + beforeGCThreshold_ = beforeGCThreshold; + } + + size_t GetBeforeGCNativeAllocatedSize() const + { + return beforeGCNativeAllocatedSize_; + } + void SetBeforeGCNativeAllocatedSize(size_t beforeGCNativeAllocatedSize) + { + beforeGCNativeAllocatedSize_ = beforeGCNativeAllocatedSize; + } + + size_t GetBeforeGCNativeThreshold() const + { + return beforeGCNativeThreshold_; + } + void SetBeforeGCNativeThreshold(size_t beforeGCNativeThreshold) + { + beforeGCNativeThreshold_ = beforeGCNativeThreshold; + } + + size_t GetAfterGCTAllocatedSize() const + { + return afterGCTAllocatedSize_; + } + void SetAfterGCTAllocatedSize(size_t afterGCTAllocatedSize) + { + afterGCTAllocatedSize_ = afterGCTAllocatedSize; + } + + size_t GetAfterGCThreshold() const + { + return afterGCThreshold_; + } + void SetAfterGCThreshold(size_t afterGCThreshold) + { + afterGCThreshold_ = afterGCThreshold; + } + + size_t GetAfterGCNativeAllocatedSize() const + { + return afterGCNativeAllocatedSize_; + } + void SetAfterGCNativeAllocatedSize(size_t afterGCNativeAllocatedSize) + { + afterGCNativeAllocatedSize_ = afterGCNativeAllocatedSize; + } + + size_t GetAfterGCNativeThreshold() const + { + return afterGCNativeThreshold_; + } + void SetAfterGCNativeThreshold(size_t afterGCNativeThreshold) + { + afterGCNativeThreshold_ = afterGCNativeThreshold; + } + + + double GetCpuLoad() const + { + return cpuLoad_; + } + void SetCpuLoad(double cpuLoad) + { + cpuLoad_ = cpuLoad; + } + +private: + size_t gcType_ = 0; + size_t gcReason_ = 0; + bool gcIsSensitive_ = false; + bool gcIsInBackground_ = false; + float gcTotalTime_ = 0.0f; + float gcMarkRootsTime_ = 0.0f; + float gcCopyFromSpaceTime_ = 0.0f; + float gcFixHeapTime_ = 0.0f; + float gcMaxSTWTime_ = 0.0f; + float gcSTWTime_ = 0.0f; + + size_t beforeGCTAllocatedSize_ = 0; + size_t beforeGCThreshold_ = 0; + size_t beforeGCNativeAllocatedSize_ = 0; + size_t beforeGCNativeThreshold_ = 0; + size_t afterGCTAllocatedSize_ = 0; + size_t afterGCThreshold_ = 0; + size_t afterGCNativeAllocatedSize_ = 0; + size_t afterGCNativeThreshold_ = 0; + double cpuLoad_ = 0.0; +}; +} // common + +#endif // ECMASCRIPT_MEM_LONG_GC_STATS_H \ No newline at end of file diff --git a/common_components/heap/collector/marking_collector.cpp b/common_components/heap/collector/marking_collector.cpp index b8dbc386eb..ff71d3b3d4 100755 --- a/common_components/heap/collector/marking_collector.cpp +++ b/common_components/heap/collector/marking_collector.cpp @@ -22,8 +22,14 @@ #include "common_components/heap/collector/heuristic_gc_policy.h" #include "common_interfaces/base/runtime_param.h" #include +#ifdef ENABLE_HISYSEVENT +#include "hisysevent.h" +#endif +#include "ecmascript/platform/dfx_hisys_event.h" +#include "common_components/heap/collector/long_gc_stats.h" namespace common { +using DFXHiSysEvent = panda::ecmascript::DFXHiSysEvent; const size_t MarkingCollector::MAX_MARKING_WORK_SIZE = 16; // fork task if bigger const size_t MarkingCollector::MIN_MARKING_WORK_SIZE = 8; // forbid forking task if smaller @@ -411,7 +417,7 @@ void MarkingCollector::PushRootsToWorkStack(RootSet *workStack, const CArrayList void MarkingCollector::MarkingRoots(const CArrayList &collectedRoots) { OHOS_HITRACE(HITRACE_LEVEL_COMMERCIAL, "CMCGC::MarkingRoots", ""); - + TRACE_CMCGC(GCStats::Scope::ScopeId::MarkingRoots, &GetGCStats()); WorkStack workStack = NewWorkStack(); PushRootsToWorkStack(&workStack, collectedRoots); @@ -609,6 +615,10 @@ void MarkingCollector::PreGarbageCollection(bool isConcurrent) gcStats.gcStartTime = TimeUtil::NanoSeconds(); gcStats.totalSTWTime = 0; gcStats.maxSTWTime = 0; + gcStats.beforeGCTAllocatedSize = Heap::GetHeap().GetAllocatedSize(); + gcStats.beforeGCThreshold = Heap::GetHeap().GetCollector().GetGCStats().GetThreshold(); + gcStats.beforeGCNativeAllocatedSize = Heap::GetHeap().GetNotifiedNativeSize(); + gcStats.beforeGCNativeThreshold = Heap::GetHeap().GetNativeHeapThreshold(); #if defined(GCINFO_DEBUG) && GCINFO_DEBUG DumpBeforeGC(); #endif @@ -742,6 +752,8 @@ void MarkingCollector::RunGarbageCollection(uint64_t gcIndex, GCReason reason, G auto gcReasonName = std::string(g_gcRequests[gcReason_].name); auto currentAllocatedSize = Heap::GetHeap().GetAllocatedSize(); auto currentThreshold = Heap::GetHeap().GetCollector().GetGCStats().GetThreshold(); + auto currentNative = Heap::GetHeap().GetNotifiedNativeSize(); + auto nativeThreshold = Heap::GetHeap().GetNativeHeapThreshold(); VLOG(INFO, "Begin GC log. GCReason: %s, GCType: %s, Current allocated %s, Current threshold %s, gcIndex=%llu", gcReasonName.c_str(), GCTypeToString(gcType), Pretty(currentAllocatedSize).c_str(), Pretty(currentThreshold).c_str(), gcIndex); @@ -751,8 +763,8 @@ void MarkingCollector::RunGarbageCollection(uint64_t gcIndex, GCReason reason, G ";Startup:" + std::to_string(static_cast(Heap::GetHeap().GetStartupStatus())) + ";Current Allocated:" + Pretty(currentAllocatedSize) + ";Current Threshold:" + Pretty(currentThreshold) + - ";Current Native:" + Pretty(Heap::GetHeap().GetNotifiedNativeSize()) + - ";NativeThreshold:" + Pretty(Heap::GetHeap().GetNativeHeapThreshold()) + ";Current Native:" + Pretty(currentNative) + + ";NativeThreshold:" + Pretty(nativeThreshold) ).c_str()); // prevent other threads stop-the-world during GC. // this may be removed in the future. @@ -804,10 +816,11 @@ void MarkingCollector::RunGarbageCollection(uint64_t gcIndex, GCReason reason, G void MarkingCollector::CopyFromSpace() { + GCStats& stats = GetGCStats(); OHOS_HITRACE(HITRACE_LEVEL_COMMERCIAL, "CMCGC::CopyFromSpace", ""); + TRACE_CMCGC(GCStats::Scope::ScopeId::CopyFromSpace, stats); TransitionToGCPhase(GCPhase::GC_PHASE_COPY, true); RegionalHeap& space = reinterpret_cast(theAllocator_); - GCStats& stats = GetGCStats(); stats.liveBytesBeforeGC = space.GetAllocatedBytes(); stats.fromSpaceSize = space.FromSpaceSize(); space.CopyFromSpace(GetThreadPool()); @@ -821,4 +834,70 @@ void MarkingCollector::ExemptFromSpace() space.ExemptFromSpace(); } +/* +| The Judgment criteria of Long GC +| IsInBackground | IsSensitive or Idle | GCTime | +| -----------------| ---------------------|---------| +| false | Sensitive | 16 | +| false | !Sensitive & !Idle | 16 | +| true | Idle | 33 | +| true | !Idle | 33 | +| true | Idle | 33 | +*/ +void MarkingCollector::ProcessLongGCEvent() +{ + if (!DFXHiSysEvent::IsEnableDFXHiSysEvent()) { + return; + } + GCStats& gcStats = GetGCStats(); + auto currentAllocatedSize = Heap::GetHeap().GetAllocatedSize(); + auto currentThreshold = Heap::GetHeap().GetCollector().GetGCStats().GetThreshold(); + auto currentNative = Heap::GetHeap().GetNotifiedNativeSize(); + auto nativeThreshold = Heap::GetHeap().GetNativeHeapThreshold(); + bool gcIsSensitive = Heap::GetHeap().GetSensitiveStatus(); + bool gcIsInBackground = gcStats.reason == GC_REASON_BACKGROUND; + float gcSTWTime = gcStats.totalSTWTime; + LongCMCGCStats *longGCStats = new LongCMCGCStats(); + longGCStats->SetGCType(gcStats.gcType); + longGCStats->SetGCReason(gcStats.reason); + longGCStats->SetGCIsSensitive(gcIsSensitive); + longGCStats->SetGCIsInBackground(gcIsInBackground); + longGCStats->SetGCTotalTime(gcStats.gcEndTime - gcStats.gcStartTime); + longGCStats->SetGCMaxSTWTime(gcStats.maxSTWTime); + longGCStats->SetGCSTWTime(gcStats.totalSTWTime); + longGCStats->SetGCMarkRootsTime(GetScopeDuration(GCStats::Scope::ScopeId::MarkingRoots)); + longGCStats->SetGCCopyFromSpaceTime(GetScopeDuration(GCStats::Scope::ScopeId::CopyFromSpace)); + longGCStats->SetGCFixHeapTime(GetScopeDuration(GCStats::Scope::ScopeId::FixHeap)); + longGCStats->SetBeforeGCTAllocatedSize(gcStats.beforeGCTAllocatedSize); + longGCStats->SetBeforeGCThreshold(gcStats.beforeGCThreshold); + longGCStats->SetBeforeGCNativeAllocatedSize(gcStats.beforeGCNativeAllocatedSize); + longGCStats->SetBeforeGCNativeThreshold(gcStats.beforeGCNativeThreshold); + longGCStats->SetAfterGCTAllocatedSize(currentAllocatedSize); + longGCStats->SetAfterGCThreshold(currentThreshold); + longGCStats->SetAfterGCNativeAllocatedSize(currentNative); + longGCStats->SetAfterGCNativeThreshold(nativeThreshold); + if (gcIsSensitive) { + if (gcSTWTime > 16) { + DFXHiSysEvent::SendLongCMCGCEvent(longGCStats); + longGCStats->Reset(); + } + } else { + if (gcReason_ == GC_REASON_IDLE) { + if (!gcIsInBackground && gcSTWTime > 16) { + longGCStats->SetCpuLoad(DFXHiSysEvent::GetCpuUsage()); + DFXHiSysEvent::SendLongCMCGCEvent(longGCStats); + } else if (gcIsInBackground && gcSTWTime > 33) { + longGCStats->SetCpuLoad(DFXHiSysEvent::GetCpuUsage()); + DFXHiSysEvent::SendLongCMCGCEvent(longGCStats); + } + } else { + if (!gcIsInBackground && gcSTWTime > 33) { + DFXHiSysEvent::SendLongCMCGCEvent(longGCStats); + } else if (gcIsInBackground && gcSTWTime > 33) { + longGCStats->SetCpuLoad(DFXHiSysEvent::GetCpuUsage()); + DFXHiSysEvent::SendLongCMCGCEvent(longGCStats); + } + } + } +} } // namespace common diff --git a/common_components/heap/collector/marking_collector.h b/common_components/heap/collector/marking_collector.h index d15c225a87..f5eaba280d 100755 --- a/common_components/heap/collector/marking_collector.h +++ b/common_components/heap/collector/marking_collector.h @@ -330,6 +330,7 @@ private: void MarkAwaitingJitFort(); void EnumMutatorRoot(ObjectPtr& obj, RootSet& rootSet) const; void EnumConcurrencyModelRoots(RootSet& rootSet) const; + void ProcessLongGCEvent(); }; diff --git a/ecmascript/platform/dfx_hisys_event.h b/ecmascript/platform/dfx_hisys_event.h index ad8642960c..a3f395331b 100644 --- a/ecmascript/platform/dfx_hisys_event.h +++ b/ecmascript/platform/dfx_hisys_event.h @@ -17,6 +17,7 @@ #define ECMASCRIPT_PLATFORM_DFX_HISYS_EVENT_H #include "ecmascript/mem/long_gc_stats.h" +#include "common_components/heap/collector/long_gc_stats.h" #include "ecmascript/mem/mem_common.h" namespace panda::ecmascript { @@ -25,6 +26,8 @@ class DFXHiSysEvent { public: static void SendLongGCEvent(LongGCStats *longGCStats); + static void SendLongCMCGCEvent(common::LongCMCGCStats *longGCStats); + static bool IsEnableDFXHiSysEvent(); static double GetCpuUsage(); diff --git a/ecmascript/platform/unix/linux/dfx_hisys_event.cpp b/ecmascript/platform/unix/linux/dfx_hisys_event.cpp index 1af67d5c94..4e4386f2f7 100644 --- a/ecmascript/platform/unix/linux/dfx_hisys_event.cpp +++ b/ecmascript/platform/unix/linux/dfx_hisys_event.cpp @@ -14,8 +14,6 @@ */ #include "ecmascript/platform/dfx_hisys_event.h" -#include "ecmascript/mem/long_gc_stats.h" -#include "ecmascript/log_wrapper.h" #include "ecmascript/log_wrapper.h" namespace panda::ecmascript { @@ -25,6 +23,11 @@ void DFXHiSysEvent::SendLongGCEvent([[maybe_unused]]LongGCStats *longGCStats) LOG_GC(FATAL) << "Send LongGCEvent is not support in linux."; } +void DFXHiSysEvent::SendLongCMCGCEvent([[maybe_unused]]common::LongCMCGCStats *longGCStats) +{ + LOG_GC(FATAL) << "Send SendLongCMCGCEvent is not support in linux."; +} + bool DFXHiSysEvent::IsEnableDFXHiSysEvent() { return false; diff --git a/ecmascript/platform/unix/mac/dfx_hisys_event.cpp b/ecmascript/platform/unix/mac/dfx_hisys_event.cpp index 55ec7fe7ab..e8a032a8a4 100644 --- a/ecmascript/platform/unix/mac/dfx_hisys_event.cpp +++ b/ecmascript/platform/unix/mac/dfx_hisys_event.cpp @@ -15,7 +15,7 @@ #include "ecmascript/platform/dfx_hisys_event.h" #include "ecmascript/mem/long_gc_stats.h" -#include "ecmascript/log_wrapper.h" +#include "common/long_gc_stats.h" #include "ecmascript/log_wrapper.h" namespace panda::ecmascript { @@ -25,6 +25,11 @@ void DFXHiSysEvent::SendLongGCEvent([[maybe_unused]]LongGCStats *longGCStats) LOG_GC(FATAL) << "Send LongGCEvent is not support in macos/ios."; } +void DFXHiSysEvent::SendLongCMCGCEvent([[maybe_unused]]common::LongCMCGCStats *longGCStats) +{ + LOG_GC(FATAL) << "Send SendLongCMCGCEvent is not support in macos/ios."; +} + bool DFXHiSysEvent::IsEnableDFXHiSysEvent() { return false; diff --git a/ecmascript/platform/unix/ohos/dfx_hisys_event.cpp b/ecmascript/platform/unix/ohos/dfx_hisys_event.cpp index 8a71d899e1..61fc1ed60a 100644 --- a/ecmascript/platform/unix/ohos/dfx_hisys_event.cpp +++ b/ecmascript/platform/unix/ohos/dfx_hisys_event.cpp @@ -79,6 +79,46 @@ void DFXHiSysEvent::SendLongGCEvent([[maybe_unused]] LongGCStats *longGCStats) #endif } +void DFXHiSysEvent::SendLongCMCGCEvent([[maybe_unused]] common::LongCMCGCStats *longGCStats) +{ +#ifdef ENABLE_HISYSEVENT + LOG_GC(DEBUG) << "SendLongCMCGCEvent: GC_TYPE" << longGCStats->GetGCType() + << ";GC_REASON" << longGCStats->GetGCReason() + << ";GC_IS_SENSITIVE" << longGCStats->GetGCIsSensitive() + << ";GC_TOTAL_TIME" << longGCStats->GetGCTotalTime(); + int32_t ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::ARKTS_RUNTIME, + "ARK_GC_LONG_TIME", OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, + "BUNDLE_NAME", PGOProfilerManager::GetInstance()->GetBundleName(), + "PID", getpid(), + "TID", syscall(SYS_gettid), + "GC_TYPE", longGCStats->GetGCType(), + "GC_REASON", longGCStats->GetGCReason(), + "GC_IS_SENSITIVE", static_cast(longGCStats->GetGCIsSensitive()), + "GC_IS_INBACKGROUND", static_cast(longGCStats->GetGCIsInBackground()), + "GC_TOTAL_TIME", longGCStats->GetGCTotalTime(), + "GC_MAX_STW_TIME", longGCStats->GetGCMaxSTWTime(), + "GC_STW_TIME", longGCStats->GetGCSTWTime(), + "GC_MARKINGROOTS_TIME", longGCStats->GetGCMarkRootsTime(), + "GC_COPYFROMSPACE_TIME", longGCStats->GetGCCopyFromSpaceTime(), + "GC_FIXHEAP_TIME", longGCStats->GetGCFixHeapTime(), + "BEFORE_GC_ALLOCATED_SIZE", longGCStats->GetBeforeGCTAllocatedSize(), + "BEFORE_GC_THRESHOLD", longGCStats->GetBeforeGCThreshold(), + "BEFORE_GC_NATIVE_ALLOCATED_SIZE", longGCStats->GetBeforeGCNativeAllocatedSize(), + "BEFORE_GC_NATIVE_THRESHOLD", longGCStats->GetBeforeGCNativeThreshold(), + "AFTER_GC_ALLOCATED_SIZE", longGCStats->GetAfterGCTAllocatedSize(), + "AFTER_GC_THRESHOLD", longGCStats->GetAfterGCThreshold(), + "AFTER_GC_NATIVE_ALLOCATED_SIZE", longGCStats->GetAfterGCNativeAllocatedSize(), + "AFTER_GC_NATIVE_THRESHOLD", longGCStats->GetAfterGCNativeThreshold(), + "GC_IS_SENSITIVE", static_cast(longGCStats->GetGCIsSensitive()), + "GC_IS_INBACKGROUND", static_cast(longGCStats->GetGCIsInBackground()), + "GC_TOTAL_TIME", longGCStats->GetGCTotalTime(), + "CPU_LOAD", longGCStats->GetCpuLoad()); + if (ret != 0) { + LOG_GC(ERROR) << "GCKeyStats HiSysEventWrite ARK_CMC_GC_LONG_TIME Failed! ret = " << ret; + } +#endif +} + bool DFXHiSysEvent::IsEnableDFXHiSysEvent() { return true; diff --git a/ecmascript/platform/windows/dfx_hisys_event.cpp b/ecmascript/platform/windows/dfx_hisys_event.cpp index 24392d46f9..1ed4355cff 100644 --- a/ecmascript/platform/windows/dfx_hisys_event.cpp +++ b/ecmascript/platform/windows/dfx_hisys_event.cpp @@ -14,8 +14,6 @@ */ #include "ecmascript/platform/dfx_hisys_event.h" -#include "ecmascript/mem/long_gc_stats.h" -#include "ecmascript/log_wrapper.h" #include "ecmascript/log_wrapper.h" namespace panda::ecmascript { @@ -25,6 +23,11 @@ void DFXHiSysEvent::SendLongGCEvent([[maybe_unused]]LongGCStats *longGCStats) LOG_GC(FATAL) << "Send LongGCEvent is not support in windows."; } +void DFXHiSysEvent::SendLongCMCGCEvent([[maybe_unused]]common::LongCMCGCStats *longGCStats) +{ + LOG_GC(FATAL) << "Send SendLongCMCGCEvent is not support in windows."; +} + bool DFXHiSysEvent::IsEnableDFXHiSysEvent() { return false; diff --git a/hisysevent.yaml b/hisysevent.yaml index 0fae0a8656..aded284ce0 100644 --- a/hisysevent.yaml +++ b/hisysevent.yaml @@ -104,4 +104,30 @@ ARK_BLOCKUI_JIT: JIT_TYPE: {type: STRING, desc: Triggered jit type} JIT_FUNCTION_NAME: {type: STRING, desc: JIT compiled function name} TIME_ON_MAIN_THREAD: {type: INT32, desc: The time occupied by JIT on the main thread} - TIME_ON_JIT_THREAD: {type: INT32, desc: The time occupied on JIT thread} \ No newline at end of file + TIME_ON_JIT_THREAD: {type: INT32, desc: The time occupied on JIT thread} + +ARK_CMCGC_LONG_TIME: + __BASE: {type: BEHAVIOR, level: CRITICAL, tag: GC, desc: Long time CMCGC event, preserve: true} + BUNDLE_NAME: {type: STRING, desc: bundleName} + VERSION_CODE: {type: STRING, desc: VERSION CODE} + PID: {type: INT8, desc: pid} + TID: {type: INT8, desc: TID of JSVM} + GC_TYPE: {type: INT8, desc: GC TYPE} + GC_REASON: {type: INT8, desc: GC REASON} + GC_IS_SENSITIVE: {type: INT8, desc: GC IS IN SENSITIVE OR NOT} + GC_IS_INBACKGROUND: {type: INT8, desc: GC IS INBACKGROUND OR NOT} + GC_TOTAL_TIME: {type: FLOAT, desc: GC TOTAL TIME} + GC_MAX_STW_TIME: {type: FLOAT, desc: GC MAX STW TIME} + GC_STW_TIME: {type: FLOAT, desc: GC STW TIME} + GC_MARKINGROOTS_TIME: {type: FLOAT, desc: GC MARKINGROOTS TIME} + GC_COPYFROMSPACE_TIME: {type: FLOAT, desc: GC COPYFROMSPACE TIME} + GC_FIXHEAP_TIME: {type: FLOAT, desc: GC FIXHEAP TIME} + BEFORE_GC_ALLOCATED_SIZE: {type: INT32, desc: TOTAL MEM USED BEFORE GC} + BEFORE_GC_THRESHOLD: {type: INT32, desc: BEFORE GC THRESHOLD} + BEFORE_GC_NATIVE_ALLOCATED_SIZE: {type: INT32, desc: BEFORE GC NATIVE MEM USED} + BEFORE_GC_NATIVE_THRESHOLD: {type: INT32, desc: BEFORE GC NATIVE THRESHOLD} + AFTER_GC_ALLOCATED_SIZE: {type: INT32, desc: TOTAL MEM USED AFTER GC} + AFTER_GC_THRESHOLD: {type: INT32, desc: AFTER GC THRESHOLD} + AFTER_GC_NATIVE_ALLOCATED_SIZE: {type: INT32, desc: AFTER GC NATIVE MEM USED} + AFTER_GC_NATIVE_THRESHOLD: {type: INT32, desc: AFTER GC NATIVE THRESHOLD} + CPU_LOAD: {type: DOUBLE, desc: CPU LOAD} \ No newline at end of file -- Gitee