14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 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#include "ecmascript/mem/gc_key_stats.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include <iostream> 194514f5e3Sopenharmony_ci#include <cstring> 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#ifdef ENABLE_HISYSEVENT 224514f5e3Sopenharmony_ci#include "hisysevent.h" 234514f5e3Sopenharmony_ci#endif 244514f5e3Sopenharmony_ci#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS) && !defined(PANDA_TARGET_IOS) 254514f5e3Sopenharmony_ci#include <sys/resource.h> 264514f5e3Sopenharmony_ci#endif 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_ci#include "ecmascript/mem/heap-inl.h" 294514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 304514f5e3Sopenharmony_ci 314514f5e3Sopenharmony_cinamespace panda::ecmascript { 324514f5e3Sopenharmony_ciusing PGOProfilerManager = pgo::PGOProfilerManager; 334514f5e3Sopenharmony_ciusing Clock = std::chrono::high_resolution_clock; 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_cibool GCKeyStats::CheckIfMainThread() const 364514f5e3Sopenharmony_ci{ 374514f5e3Sopenharmony_ci#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS) && !defined(PANDA_TARGET_IOS) 384514f5e3Sopenharmony_ci return getpid() == syscall(SYS_gettid); 394514f5e3Sopenharmony_ci#else 404514f5e3Sopenharmony_ci return true; 414514f5e3Sopenharmony_ci#endif 424514f5e3Sopenharmony_ci} 434514f5e3Sopenharmony_ci 444514f5e3Sopenharmony_cibool GCKeyStats::CheckIfKeyPauseTime() const 454514f5e3Sopenharmony_ci{ 464514f5e3Sopenharmony_ci return gcStats_->GetScopeDuration(GCStats::Scope::ScopeId::TotalGC) >= KEY_PAUSE_TIME; 474514f5e3Sopenharmony_ci} 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_civoid GCKeyStats::AddGCStatsToKey() 504514f5e3Sopenharmony_ci{ 514514f5e3Sopenharmony_ci LOG_GC(DEBUG) << "GCKeyStats AddGCStatsToKey!"; 524514f5e3Sopenharmony_ci 534514f5e3Sopenharmony_ci recordCount_++; 544514f5e3Sopenharmony_ci 554514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_TOTAL_MEM_USED, 564514f5e3Sopenharmony_ci SizeToIntKB(gcStats_->GetRecordData(RecordData::END_OBJ_SIZE))); 574514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_TOTAL_MEM_COMMITTED, 584514f5e3Sopenharmony_ci SizeToIntKB(gcStats_->GetRecordData(RecordData::END_COMMIT_SIZE))); 594514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_ACTIVE_MEM_USED, 604514f5e3Sopenharmony_ci SizeToIntKB(gcStats_->GetRecordData(RecordData::YOUNG_ALIVE_SIZE))); 614514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_ACTIVE_MEM_COMMITTED, 624514f5e3Sopenharmony_ci SizeToIntKB(gcStats_->GetRecordData(RecordData::YOUNG_COMMIT_SIZE))); 634514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_OLD_MEM_USED, 644514f5e3Sopenharmony_ci SizeToIntKB(gcStats_->GetRecordData(RecordData::OLD_ALIVE_SIZE))); 654514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_OLD_MEM_COMMITTED, 664514f5e3Sopenharmony_ci SizeToIntKB(gcStats_->GetRecordData(RecordData::OLD_COMMIT_SIZE))); 674514f5e3Sopenharmony_ci 684514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_HUGE_MEM_USED, 694514f5e3Sopenharmony_ci SizeToIntKB(heap_->GetHugeObjectSpace()->GetHeapObjectSize())); 704514f5e3Sopenharmony_ci AddRecordDataStats(RecordKeyData::GC_HUGE_MEM_COMMITTED, 714514f5e3Sopenharmony_ci SizeToIntKB(heap_->GetHugeObjectSpace()->GetCommittedSize())); 724514f5e3Sopenharmony_ci 734514f5e3Sopenharmony_ci AddRecordKeyDuration(RecordKeyDuration::GC_TOTAL_TIME, 744514f5e3Sopenharmony_ci gcStats_->GetScopeDuration(GCStats::Scope::ScopeId::TotalGC)); 754514f5e3Sopenharmony_ci AddRecordKeyDuration(RecordKeyDuration::GC_MARK_TIME, 764514f5e3Sopenharmony_ci gcStats_->GetScopeDuration(GCStats::Scope::ScopeId::Mark)); 774514f5e3Sopenharmony_ci AddRecordKeyDuration(RecordKeyDuration::GC_EVACUATE_TIME, 784514f5e3Sopenharmony_ci gcStats_->GetScopeDuration(GCStats::Scope::ScopeId::Evacuate)); 794514f5e3Sopenharmony_ci 804514f5e3Sopenharmony_ci if (CheckLastSendTimeIfSend() && CheckCountIfSend()) { 814514f5e3Sopenharmony_ci SendSysEvent(); 824514f5e3Sopenharmony_ci PrintKeyStatisticResult(); 834514f5e3Sopenharmony_ci InitializeRecordList(); 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci} 864514f5e3Sopenharmony_ci 874514f5e3Sopenharmony_civoid GCKeyStats::SendSysEvent() const 884514f5e3Sopenharmony_ci{ 894514f5e3Sopenharmony_ci#ifdef ENABLE_HISYSEVENT 904514f5e3Sopenharmony_ci int32_t ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::ARKTS_RUNTIME, 914514f5e3Sopenharmony_ci "ARK_STATS_GC", 924514f5e3Sopenharmony_ci OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, 934514f5e3Sopenharmony_ci "BUNDLE_NAME", PGOProfilerManager::GetInstance()->GetBundleName(), 944514f5e3Sopenharmony_ci "PID", getpid(), 954514f5e3Sopenharmony_ci "TID", syscall(SYS_gettid), 964514f5e3Sopenharmony_ci "GC_TOTAL_COUNT", gcCount_, 974514f5e3Sopenharmony_ci "GC_TOTAL_TIME", static_cast<int>(GetRecordKeyDuration(RecordKeyDuration::GC_TOTAL_TIME)), 984514f5e3Sopenharmony_ci "GC_MARK_TIME", static_cast<int>(GetRecordKeyDuration(RecordKeyDuration::GC_MARK_TIME)), 994514f5e3Sopenharmony_ci "GC_EVACUATE_TIME", static_cast<int>(GetRecordKeyDuration(RecordKeyDuration::GC_EVACUATE_TIME)), 1004514f5e3Sopenharmony_ci "GC_LONG_TIME", recordCount_, 1014514f5e3Sopenharmony_ci "GC_TOTAL_MEM_USED", GetRecordDataStats(RecordKeyData::GC_TOTAL_MEM_USED), 1024514f5e3Sopenharmony_ci "GC_TOTAL_MEM_COMMITTED", GetRecordDataStats(RecordKeyData::GC_TOTAL_MEM_COMMITTED), 1034514f5e3Sopenharmony_ci "GC_ACTIVE_MEM_USED", GetRecordDataStats(RecordKeyData::GC_ACTIVE_MEM_USED), 1044514f5e3Sopenharmony_ci "GC_ACTIVE_MEM_COMMITTED", GetRecordDataStats(RecordKeyData::GC_ACTIVE_MEM_COMMITTED), 1054514f5e3Sopenharmony_ci "GC_OLD_MEM_USED", GetRecordDataStats(RecordKeyData::GC_OLD_MEM_USED), 1064514f5e3Sopenharmony_ci "GC_OLD_MEM_COMMITTED", GetRecordDataStats(RecordKeyData::GC_OLD_MEM_COMMITTED), 1074514f5e3Sopenharmony_ci "GC_HUGE_MEM_USED", GetRecordDataStats(RecordKeyData::GC_HUGE_MEM_USED), 1084514f5e3Sopenharmony_ci "GC_HUGE_MEM_COMMITTED", GetRecordDataStats(RecordKeyData::GC_HUGE_MEM_COMMITTED)); 1094514f5e3Sopenharmony_ci if (ret != 0) { 1104514f5e3Sopenharmony_ci LOG_GC(ERROR) << "GCKeyStats HiSysEventWrite Failed! ret = " << ret; 1114514f5e3Sopenharmony_ci } 1124514f5e3Sopenharmony_ci#endif 1134514f5e3Sopenharmony_ci} 1144514f5e3Sopenharmony_ci 1154514f5e3Sopenharmony_civoid GCKeyStats::SendSysEventBeforeDump(std::string type, size_t limitSize, size_t activeMemory) const 1164514f5e3Sopenharmony_ci{ 1174514f5e3Sopenharmony_ci#ifdef ENABLE_HISYSEVENT 1184514f5e3Sopenharmony_ci int32_t ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::FRAMEWORK, 1194514f5e3Sopenharmony_ci "ARK_STATS_DUMP", 1204514f5e3Sopenharmony_ci OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, 1214514f5e3Sopenharmony_ci "PID", getprocpid(), 1224514f5e3Sopenharmony_ci "TID", syscall(SYS_gettid), 1234514f5e3Sopenharmony_ci "PROCESS_NAME", PGOProfilerManager::GetInstance()->GetBundleName(), 1244514f5e3Sopenharmony_ci "LIMITSIZE", limitSize, 1254514f5e3Sopenharmony_ci "ACTIVE_MEMORY", activeMemory, 1264514f5e3Sopenharmony_ci "TYPE", type); 1274514f5e3Sopenharmony_ci if (ret != 0) { 1284514f5e3Sopenharmony_ci LOG_GC(ERROR) << "GCKeyStats SendSysEventBeforeDump Failed! ret = " << ret; 1294514f5e3Sopenharmony_ci } 1304514f5e3Sopenharmony_ci#else 1314514f5e3Sopenharmony_ci LOG_GC(INFO) << "GCKeyStats type: " << type << ", limitSize: " << limitSize << ", activeMemory: " << activeMemory; 1324514f5e3Sopenharmony_ci#endif 1334514f5e3Sopenharmony_ci} 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_civoid GCKeyStats::PrintKeyStatisticResult() const 1364514f5e3Sopenharmony_ci{ 1374514f5e3Sopenharmony_ci LOG_GC(INFO) << "/******************* GCKeyStats HiSysEvent statistic: *******************/"; 1384514f5e3Sopenharmony_ci} 1394514f5e3Sopenharmony_ci 1404514f5e3Sopenharmony_civoid GCKeyStats::InitializeRecordList() 1414514f5e3Sopenharmony_ci{ 1424514f5e3Sopenharmony_ci gcCount_ = 0; 1434514f5e3Sopenharmony_ci recordCount_ = 0; 1444514f5e3Sopenharmony_ci std::fill(recordDurationStats_, recordDurationStats_ + (uint8_t)RecordKeyDuration::NUM_OF_KEY_DURATION, 0.0f); 1454514f5e3Sopenharmony_ci std::fill(recordDataStats_, recordDataStats_ + (uint8_t)RecordKeyData::NUM_OF_KEY_DATA, 0); 1464514f5e3Sopenharmony_ci lastSendTimestamp_ = Clock::now(); 1474514f5e3Sopenharmony_ci} 1484514f5e3Sopenharmony_ci 1494514f5e3Sopenharmony_ci} // namespace panda::ecmascript