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