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 27 namespace panda::ecmascript { 28 class EcmaRuntimeStat; 29 class PandaRuntimeCallerStat { 30 public: 31 // NOLINTNEXTLINE(modernize-pass-by-value) PandaRuntimeCallerStat(const CString & name)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 UpdateState(uint64_t elapsed)39 void UpdateState(uint64_t elapsed) 40 { 41 totalCount_++; 42 totalTime_ += elapsed; 43 maxTime_ = elapsed < maxTime_ ? maxTime_ : elapsed; 44 } Name()45 const char *Name() const 46 { 47 return name_.c_str(); 48 } GetHeaderOfName()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 } TotalCount()58 uint64_t TotalCount() const 59 { 60 return totalCount_; 61 } TotalTime()62 uint64_t TotalTime() const 63 { 64 return totalTime_; 65 } MaxTime()66 uint64_t MaxTime() const 67 { 68 return maxTime_; 69 } 70 Reset()71 void Reset() 72 { 73 totalCount_ = 0; 74 totalTime_ = 0; 75 maxTime_ = 0; 76 } 77 78 private: 79 CString name_ {}; 80 uint64_t totalCount_ {0}; 81 uint64_t totalTime_ {0}; 82 uint64_t maxTime_ {0}; 83 }; 84 85 class PandaRuntimeTimer { 86 public: 87 void Start(PandaRuntimeCallerStat *callerStat, PandaRuntimeTimer *parent); Now()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 Elapsed()95 uint64_t Elapsed() const 96 { 97 return elapsed_; 98 } 99 IsStarted()100 inline bool IsStarted() const 101 { 102 return start_ != 0; 103 } 104 SetParent(PandaRuntimeTimer * parent)105 inline void SetParent(PandaRuntimeTimer *parent) 106 { 107 parent_ = parent; 108 } 109 110 void Snapshot(); 111 UpdateCallerState()112 inline void UpdateCallerState() 113 { 114 callerStat_->UpdateState(elapsed_); 115 } 116 117 private: 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