• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 
17 #include "ecmascript/runtime_call_id.h"
18 
19 namespace panda::ecmascript {
20 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
EcmaRuntimeStat(const char * const runtimeCallerNames[],int count)21 EcmaRuntimeStat::EcmaRuntimeStat(const char *const runtimeCallerNames[], int count)
22 {
23     for (int i = 0; i < count; i++) {
24         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
25         callerStat_.emplace_back(PandaRuntimeCallerStat(CString(runtimeCallerNames[i])));
26     }
27 }
28 
StartCount(PandaRuntimeTimer * timer,int callerId)29 void EcmaRuntimeStat::StartCount(PandaRuntimeTimer *timer, int callerId)
30 {
31     if (currentTimer_ != nullptr) {
32         timer->SetParent(currentTimer_);
33     }
34     PandaRuntimeTimer *parent = currentTimer_;
35     currentTimer_ = timer;
36     PandaRuntimeCallerStat *callerStat = &callerStat_[callerId];
37     timer->Start(callerStat, parent);
38 }
39 
StopCount(const PandaRuntimeTimer * nowTimer)40 void EcmaRuntimeStat::StopCount(const PandaRuntimeTimer *nowTimer)
41 {
42     if (nowTimer != currentTimer_) {
43         return;
44     }
45     PandaRuntimeTimer *parentTimer = currentTimer_->Stop();
46     currentTimer_ = parentTimer;
47 }
48 
Print() const49 void EcmaRuntimeStat::Print() const
50 {
51     if (currentTimer_ != nullptr) {
52         currentTimer_->Snapshot();
53     }
54     PrintAllStats();
55 }
56 
ResetAllCount()57 void EcmaRuntimeStat::ResetAllCount()
58 {
59     while (currentTimer_ != nullptr) {
60         StopCount(currentTimer_);
61     }
62     for (auto &runCallerStat : callerStat_) {
63         runCallerStat.Reset();
64     }
65 }
66 
PrintAllStats() const67 void EcmaRuntimeStat::PrintAllStats() const
68 {
69     LOG_ECMA(INFO) << "panda runtime stat:";
70     static constexpr int nameRightAdjustment = 45;
71     static constexpr int numberRightAdjustment = 12;
72     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "InterPreter && GC && C++ Builtin Function"
73                        << std::setw(numberRightAdjustment) << "Time(ns)" << std::setw(numberRightAdjustment) << "Count"
74                        << std::setw(numberRightAdjustment) << "MaxTime(ns)"
75                        << std::setw(numberRightAdjustment) << "AvgTime(ns)";
76     LOG_ECMA(INFO) << "============================================================"
77                        << "=========================================================";
78 
79     CVector<PandaRuntimeCallerStat> callerStat;
80     for (auto &runCallerStat : callerStat_) {
81         callerStat.push_back(runCallerStat);
82     }
83     // Sort by TotalTime
84     std::sort(callerStat.begin(), callerStat.end(),
85         [](const PandaRuntimeCallerStat &a, const PandaRuntimeCallerStat &b) -> bool {
86             return a.TotalTime() > b.TotalTime();
87     });
88 
89     uint64_t totalTime = 0;
90     uint64_t interpreterTotalTime = 0;
91     uint64_t builtinTotalTime = 0;
92     uint64_t abstractOperationTotalTime = 0;
93     uint64_t memoryTotalTime = 0;
94     uint64_t runtimeTotalTime = 0;
95     for (auto &runCallerStat : callerStat) {
96         if (runCallerStat.TotalCount() != 0) {
97             totalTime += runCallerStat.TotalTime();
98             CString header = runCallerStat.GetHeaderOfName();
99             if (header == CString("Interpreter")) {
100                 interpreterTotalTime += runCallerStat.TotalTime();
101             } else if (header == CString("BuiltinsApi")) {
102                 builtinTotalTime += runCallerStat.TotalTime();
103             } else if (header == CString("AbstractOperation")) {
104                 abstractOperationTotalTime += runCallerStat.TotalTime();
105             } else if (header == CString("Memory")) {
106                 memoryTotalTime += runCallerStat.TotalTime();
107             } else if (header == CString("Runtime")) {
108                 runtimeTotalTime += runCallerStat.TotalTime();
109             }
110             LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << runCallerStat.Name()
111                                << std::setw(numberRightAdjustment) << runCallerStat.TotalTime()
112                                << std::setw(numberRightAdjustment) << runCallerStat.TotalCount()
113                                << std::setw(numberRightAdjustment) << runCallerStat.MaxTime()
114                                << std::setw(numberRightAdjustment)
115                                << runCallerStat.TotalTime() / runCallerStat.TotalCount();
116         }
117     }
118     LOG_ECMA(INFO) << "------------------------------------------------------------"
119                        << "---------------------------------------------------------";
120     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "Interpreter Total Time(ns)"
121                        << std::setw(numberRightAdjustment) << interpreterTotalTime;
122     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "BuiltinsApi Total Time(ns)"
123                        << std::setw(numberRightAdjustment) << builtinTotalTime;
124     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "AbstractOperation Total Time(ns)"
125                        << std::setw(numberRightAdjustment) << abstractOperationTotalTime;
126     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "Memory Total Time(ns)"
127                        << std::setw(numberRightAdjustment) << memoryTotalTime;
128     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "Runtime Total Time(ns)"
129                        << std::setw(numberRightAdjustment) << runtimeTotalTime;
130     LOG_ECMA(INFO) << "------------------------------------------------------------"
131                        << "---------------------------------------------------------";
132     LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "Total Time(ns)"
133                        << std::setw(numberRightAdjustment) << totalTime;
134 }
135 
EcmaRuntimeStatScope(EcmaVM * vm)136 EcmaRuntimeStatScope::EcmaRuntimeStatScope(EcmaVM *vm) : vm_(vm)
137 {
138     if (vm_->GetJSOptions().IsEnableRuntimeStat()) {
139         vm_->SetRuntimeStatEnable(true);
140     }
141 }
142 
~EcmaRuntimeStatScope()143 EcmaRuntimeStatScope::~EcmaRuntimeStatScope()
144 {
145     if (vm_->GetJSOptions().IsEnableRuntimeStat()) {
146         vm_->SetRuntimeStatEnable(false);
147     }
148     vm_ = nullptr;
149 }
150 }  // namespace panda::ecmascript
151