1/* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef ECMASCRIPT_DFX_VMSTAT_CALLER_STAT_H 17#define ECMASCRIPT_DFX_VMSTAT_CALLER_STAT_H 18 19#include <cstdint> 20#include <cstring> 21#include <ctime> 22 23#include "ecmascript/mem/c_string.h" 24 25#include "libpandabase/macros.h" 26 27namespace panda::ecmascript { 28class EcmaRuntimeStat; 29class PandaRuntimeCallerStat { 30public: 31 // NOLINTNEXTLINE(modernize-pass-by-value) 32 explicit PandaRuntimeCallerStat(const CString &name) : name_(name) {} 33 PandaRuntimeCallerStat() = default; 34 virtual ~PandaRuntimeCallerStat() = default; 35 36 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PandaRuntimeCallerStat); 37 DEFAULT_COPY_SEMANTIC(PandaRuntimeCallerStat); 38 39 void UpdateState(uint64_t elapsed) 40 { 41 totalCount_++; 42 totalTime_ += elapsed; 43 maxTime_ = elapsed < maxTime_ ? maxTime_ : elapsed; 44 } 45 const char *Name() const 46 { 47 return name_.c_str(); 48 } 49 CString GetHeaderOfName() const 50 { 51 CString::size_type index = name_.find_first_of("::"); 52 if (index == CString::npos) { 53 return CString(""); 54 } 55 CString header = name_.substr(0, index); 56 return header; 57 } 58 uint64_t TotalCount() const 59 { 60 return totalCount_; 61 } 62 uint64_t TotalTime() const 63 { 64 return totalTime_; 65 } 66 uint64_t MaxTime() const 67 { 68 return maxTime_; 69 } 70 71 void Reset() 72 { 73 totalCount_ = 0; 74 totalTime_ = 0; 75 maxTime_ = 0; 76 } 77 78private: 79 CString name_ {}; 80 uint64_t totalCount_ {0}; 81 uint64_t totalTime_ {0}; 82 uint64_t maxTime_ {0}; 83}; 84 85class PandaRuntimeTimer { 86public: 87 void Start(PandaRuntimeCallerStat *callerStat, PandaRuntimeTimer *parent); 88 inline static uint64_t Now() 89 { 90 struct timespec timeNow = {0, 0}; 91 clock_gettime(CLOCK_REALTIME, &timeNow); 92 return timeNow.tv_sec * NANOSECONDSINSECOND + timeNow.tv_nsec; 93 } 94 95 uint64_t Elapsed() const 96 { 97 return elapsed_; 98 } 99 100 inline bool IsStarted() const 101 { 102 return start_ != 0; 103 } 104 105 inline void SetParent(PandaRuntimeTimer *parent) 106 { 107 parent_ = parent; 108 } 109 110 void Snapshot(); 111 112 inline void UpdateCallerState() 113 { 114 callerStat_->UpdateState(elapsed_); 115 } 116 117private: 118 static constexpr uint64_t NANOSECONDSINSECOND = 1000000000; 119 PandaRuntimeTimer *Stop(); 120 void Pause(uint64_t now); 121 void Resume(uint64_t now); 122 PandaRuntimeCallerStat *callerStat_ {nullptr}; 123 PandaRuntimeTimer *parent_ {nullptr}; 124 uint64_t start_ {0}; 125 uint64_t elapsed_ {0}; 126 127 friend class EcmaRuntimeStat; 128 friend class FunctionCallTimer; 129}; 130} // namespace panda::ecmascript 131#endif // ECMASCRIPT_DFX_VMSTAT_CALLER_STAT_H 132