• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "ecmascript/compiler/compiler_log.h"
17 
18 namespace panda::ecmascript::kungfu {
CompilerLog(const std::string & logOpt,bool TraceBC)19 CompilerLog::CompilerLog(const std::string &logOpt, bool TraceBC)
20 {
21     outputCIR_ = logOpt.find("cir") != std::string::npos ||
22         logOpt.find("0") != std::string::npos;
23     outputLLIR_ = logOpt.find("llir") != std::string::npos ||
24         logOpt.find("1") != std::string::npos;
25     outputASM_ = logOpt.find("asm") != std::string::npos ||
26         logOpt.find("2") != std::string::npos;
27     outputType_ = logOpt.find("type") != std::string::npos ||
28         logOpt.find("3") != std::string::npos;
29     allMethod_ = logOpt.find("all") != std::string::npos;
30     cerMethod_ = logOpt.find("all") == std::string::npos &&
31         logOpt.find("cer") != std::string::npos;
32     noneMethod_ = logOpt.find("all") == std::string::npos &&
33         logOpt.find("cer") == std::string::npos;
34     traceBc_ = TraceBC;
35 }
36 
SetMethodLog(const std::string & fileName,const CString & recordName,const std::string & methodName,AotMethodLogList * logList)37 void CompilerLog::SetMethodLog(const std::string &fileName, const CString& recordName,
38                                const std::string &methodName, AotMethodLogList *logList)
39 {
40     bool enableMethodLog = !NoneMethod();
41     if (CertainMethod()) {
42         enableMethodLog = logList->IncludesMethod(fileName, methodName);
43     }
44     SetEnableMethodLog(enableMethodLog);
45     AddCompiledMethod(methodName, recordName);
46 }
47 
IncludesMethod(const std::string & methodName) const48 bool MethodLogList::IncludesMethod(const std::string &methodName) const
49 {
50     bool empty = methodName.empty();
51     bool found = methods_.find(methodName) != std::string::npos;
52     return !empty && found;
53 }
54 
IncludesMethod(const std::string & fileName,const std::string & methodName) const55 bool AotMethodLogList::IncludesMethod(const std::string &fileName, const std::string &methodName) const
56 {
57     if (fileMethods_.find(fileName) == fileMethods_.end()) {
58         return false;
59     }
60     std::vector methodVector = fileMethods_.at(fileName);
61     auto it = find(methodVector.begin(), methodVector.end(), methodName);
62     return (it != methodVector.end());
63 }
64 
spiltString(const std::string & str,const char ch)65 std::vector<std::string> AotMethodLogList::spiltString(const std::string &str, const char ch)
66 {
67     std::vector<std::string> vec {};
68     std::istringstream sstr(str.c_str());
69     std::string spilt;
70     while (getline(sstr, spilt, ch)) {
71         vec.emplace_back(spilt);
72     }
73     return vec;
74 }
75 
ParseFileMethodsName(const std::string & logMethods)76 void AotMethodLogList::ParseFileMethodsName(const std::string &logMethods)
77 {
78     std::vector<std::string> fileVector = spiltString(logMethods, fileSplitSign);
79     std::vector<std::string> itemVector;
80     for (size_t index = 0; index < fileVector.size(); ++index) {
81         itemVector = spiltString(fileVector[index], methodSplitSign);
82         std::vector<std::string> methodVector(itemVector.begin() + 1, itemVector.end());
83         fileMethods_[itemVector[0]] = methodVector;
84     }
85 }
86 
TimeScope(std::string name,std::string methodName,uint32_t methodOffset,CompilerLog * log)87 TimeScope::TimeScope(std::string name, std::string methodName, uint32_t methodOffset, CompilerLog* log)
88     : ClockScope(), name_(std::move(name)), methodName_(std::move(methodName)), methodOffset_(methodOffset), log_(log)
89 {
90     if (log_->GetEnableCompilerLogTime()) {
91         if (log_->nameIndex_.find(name_) == log_->nameIndex_.end()) {
92             log_->nameIndex_[name_] = log_->GetIndex();
93         }
94         startTime_ = ClockScope().GetCurTime();
95     }
96 }
97 
TimeScope(std::string name,CompilerLog * log)98 TimeScope::TimeScope(std::string name, CompilerLog* log)
99     : ClockScope(), name_(std::move(name)), log_(log)
100 {
101     if (log_->GetEnableCompilerLogTime()) {
102         if (log_->nameIndex_.find(name_) == log_->nameIndex_.end()) {
103             log_->nameIndex_[name_] = log_->GetIndex();
104         }
105         startTime_ = ClockScope().GetCurTime();
106     }
107 }
108 
~TimeScope()109 TimeScope::~TimeScope()
110 {
111     if (log_->GetEnableCompilerLogTime()) {
112         timeUsed_ = ClockScope().GetCurTime() - startTime_;
113         if (log_->CertainMethod() && log_->GetEnableMethodLog()) {
114             LOG_COMPILER(INFO) << std::setw(PASS_LENS) << name_ << " " << std::setw(METHOD_LENS)
115                                << GetShortName(methodName_) << " offset:" << std::setw(OFFSET_LENS) << methodOffset_
116                                << " time used:" << std::setw(TIME_LENS) << timeUsed_ / MILLION_TIME << "ms";
117         }
118         std::string shortName = GetShortName(methodName_);
119         log_->AddPassTime(name_, timeUsed_);
120         log_->AddMethodTime(shortName, methodOffset_, timeUsed_);
121     }
122 }
123 
GetShortName(const std::string & methodName)124 const std::string TimeScope::GetShortName(const std::string& methodName)
125 {
126     std::string KeyStr = "@";
127     if (methodName.find(KeyStr) != std::string::npos) {
128         std::string::size_type index = methodName.find(KeyStr);
129         std::string extracted = methodName.substr(0, index);
130         return extracted;
131     } else {
132         return methodName;
133     }
134 }
135 
Print() const136 void CompilerLog::Print() const
137 {
138     if (compilerLogTime_) {
139         PrintTime();
140     }
141     PrintCompiledMethod();
142 }
143 
PrintPassTime() const144 void CompilerLog::PrintPassTime() const
145 {
146     double allPassTimeforAllMethods = 0;
147     auto myMap = timePassMap_;
148     auto myIndexMap = nameIndex_;
149     std::multimap<int, std::string> PassTimeMap;
150     for (auto it = myMap.begin(); it != myMap.end(); it++) {
151         PassTimeMap.insert(make_pair(myIndexMap[it->first], it->first));
152         allPassTimeforAllMethods += it->second;
153     }
154     for (auto [key, val] : PassTimeMap) {
155         LOG_COMPILER(INFO) << std::setw(PASS_LENS) << val << " Total cost time is "<< std::setw(TIME_LENS)
156                            << myMap[val] / MILLION_TIME << "ms " << "percentage:"
157                            << std::fixed << std::setprecision(PERCENT_LENS)
158                            << myMap[val] / allPassTimeforAllMethods * HUNDRED_TIME << "% ";
159     }
160 }
161 
PrintMethodTime() const162 void CompilerLog::PrintMethodTime() const
163 {
164     double methodTotalTime = 0;
165     auto myMap = timeMethodMap_;
166     std::multimap<double, std::pair<uint32_t, std::string>> MethodTimeMap;
167     std::map<std::pair<uint32_t, std::string>, double>::iterator it;
168     for (it = myMap.begin(); it != myMap.end(); it++) {
169         MethodTimeMap.insert(make_pair(it->second, it->first));
170     }
171     for (auto [key, val] : MethodTimeMap) {
172         methodTotalTime += key;
173     }
174     for (auto [key, val] : MethodTimeMap) {
175         LOG_COMPILER(INFO) << "method:" << std::setw(METHOD_LENS) << val.second
176                            << " offset:" << std::setw(OFFSET_LENS) << val.first << " all pass cost time is "
177                            << std::setw(TIME_LENS) << key / MILLION_TIME << "ms " << "percentage:" << std::fixed
178                            << std::setprecision(PERCENT_LENS) << key / methodTotalTime * HUNDRED_TIME << "% ";
179     }
180     LOG_COMPILER(INFO) << "total compile time is " << std::setw(TIME_LENS) << methodTotalTime / MILLION_TIME << "ms ";
181 }
182 
PrintTime() const183 void CompilerLog::PrintTime() const
184 {
185     LOG_COMPILER(INFO) << " ";
186     PrintPassTime();
187     LOG_COMPILER(INFO) << " ";
188     PrintMethodTime();
189 }
190 
PrintCompiledMethod() const191 void CompilerLog::PrintCompiledMethod() const
192 {
193     LOG_COMPILER(INFO) << " ";
194     LOG_COMPILER(INFO) << " Total number of full compiled methods is: " << compiledMethodSet_.size();
195     for (auto it = compiledMethodSet_.begin(); it != compiledMethodSet_.end(); it++) {
196         LOG_COMPILER(INFO) << " method: " << std::setw(METHOD_LENS) << it->first
197                            << " in record: " << std::setw(RECORD_LENS) << it->second
198                            << " has been full compiled ";
199     }
200 }
201 
AddMethodTime(const std::string & name,uint32_t id,double time)202 void CompilerLog::AddMethodTime(const std::string& name, uint32_t id, double time)
203 {
204     auto methodInfo = std::make_pair(id, name);
205     timeMethodMap_[methodInfo] += time;
206 }
207 
AddPassTime(const std::string & name,double time)208 void CompilerLog::AddPassTime(const std::string& name, double time)
209 {
210     timePassMap_[name] += time;
211 }
212 
AddCompiledMethod(const std::string & name,const CString & recordName)213 void CompilerLog::AddCompiledMethod(const std::string& name, const CString& recordName)
214 {
215     auto info = std::make_pair(name, recordName);
216     compiledMethodSet_.insert(info);
217 }
218 
GetIndex()219 int CompilerLog::GetIndex()
220 {
221     return (idx_++);
222 }
223 // namespace panda::ecmascript::kungfu
224 }