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 #ifndef ECMASCRIPT_DFX_VMSTAT_OPT_CODE_PROFILER_H 16 #define ECMASCRIPT_DFX_VMSTAT_OPT_CODE_PROFILER_H 17 18 #include "ecmascript/compiler/bytecodes.h" 19 #include "ecmascript/compiler/ecma_opcode_des.h" 20 #include "ecmascript/compiler/share_opcodes.h" 21 22 // bcIndex bytecode count fast slow typerate 23 // ====================(print all)======================= 24 // ........ 25 // ====================================================== 26 // total 27 28 // tip: not print if count below 10000 29 // ====================(top1 method: name, methodId)===== 30 // ....... 31 // (bcIndex bytecode count fast slow typerate) 32 // ....... 33 // ====================================================== 34 35 // ====================(top2 method: name)=============== 36 // ....... 37 // ====================================================== 38 39 // ....... 40 41 // ====================(top10 method: name)============== 42 // ....... 43 // ====================================================== 44 45 // methodId, abcId, bcIndex, Value1(opcode, fastcount, slowcount),Value2(methodName, totalcount) 46 // key: methodId, abcId 47 // std::map<key, <bcIndex, Value1>> 48 // std::map<key, Value2> 49 50 namespace panda::ecmascript { 51 class OptCodeProfiler { 52 public: 53 using EcmaOpcode = kungfu::EcmaOpcode; 54 55 enum Mode { 56 TYPED_PATH, 57 SLOW_PATH, 58 }; 59 60 struct Value { ValueValue61 Value() : typedPathValue(0), slowPathValue(0) {} 62 TypedPathCountValue63 uint64_t TypedPathCount() const 64 { 65 return typedPathValue; 66 } 67 SlowPathCountValue68 uint64_t SlowPathCount() const 69 { 70 return slowPathValue; 71 } 72 CountValue73 uint64_t Count() const 74 { 75 return typedPathValue + slowPathValue; 76 } 77 ResetStatValue78 void ResetStat() 79 { 80 typedPathValue = 0; 81 slowPathValue = 0; 82 } 83 84 uint64_t typedPathValue; 85 uint64_t slowPathValue; 86 }; 87 88 struct Key { KeyKey89 Key(uint32_t abcId, uint32_t methodId) 90 { 91 abcAndMethodId_ = (((uint64_t)abcId) << 32) + methodId; // 32: 32bit 92 } 93 KeyKey94 Key(uint64_t key) : abcAndMethodId_(key) {}; 95 GetAbcIdKey96 uint32_t GetAbcId() const 97 { 98 return (uint32_t) (abcAndMethodId_ >> 32); // 32: 32bit 99 } 100 GetMehodIdKey101 uint32_t GetMehodId() const 102 { 103 return (uint32_t) abcAndMethodId_; 104 } 105 ValueKey106 uint64_t Value() const 107 { 108 return abcAndMethodId_; 109 } 110 111 uint64_t abcAndMethodId_; 112 }; 113 114 struct Name { NameName115 Name(std::string name) : methodName_(name), totalCount_(1) {} 116 CountName117 uint64_t Count() const 118 { 119 return totalCount_; 120 } 121 IncName122 void Inc() 123 { 124 totalCount_ = totalCount_ + 1; 125 } 126 GetNameName127 std::string GetName() const 128 { 129 return methodName_; 130 } 131 132 std::string methodName_; 133 uint64_t totalCount_; 134 }; 135 136 struct Record { RecordRecord137 Record(EcmaOpcode opcode) : opcode_(opcode), fast_(0), slow_(0) {} 138 CountRecord139 uint64_t Count() const 140 { 141 return fast_ + slow_; 142 } 143 GetFastRecord144 uint64_t GetFast() const 145 { 146 return fast_; 147 } 148 GetSlowRecord149 uint64_t GetSlow() const 150 { 151 return slow_; 152 } 153 GetOpCodeRecord154 EcmaOpcode GetOpCode() const 155 { 156 return opcode_; 157 } 158 IncFastRecord159 void IncFast() 160 { 161 fast_ = fast_ + 1; 162 } 163 IncSlowRecord164 void IncSlow() 165 { 166 slow_ = slow_ + 1; 167 } 168 169 EcmaOpcode opcode_; 170 uint64_t fast_; 171 uint64_t slow_; 172 }; 173 OptCodeProfiler()174 OptCodeProfiler() 175 { 176 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER 177 profMap_ = { 178 #define BYTECODE_PROF_MAP(name) { kungfu::EcmaOpcode::name, OptCodeProfiler::Value() }, 179 ECMA_OPCODE_LIST(BYTECODE_PROF_MAP) 180 #undef BYTECODE_PROF_MAP 181 }; 182 #endif 183 } 184 185 ~OptCodeProfiler(); 186 187 void Update(JSHandle<JSTaggedValue> &func, int bcIndex, EcmaOpcode opcode, Mode mode); 188 189 void PrintAndReset(); 190 191 using BcRecord = std::map<int, Record>; 192 private: 193 void FilterMethodToPrint(); 194 void PrintMethodRecord(Key key, std::string methodName); ResetMethodInfo()195 void ResetMethodInfo() 196 { 197 methodIdToRecord_.clear(); 198 methodIdToName_.clear(); 199 } 200 201 int printMehodCount_ {10}; 202 int skipMaxCount_ {10000}; 203 std::map<EcmaOpcode, Value> profMap_; 204 std::map<uint64_t, BcRecord> methodIdToRecord_; 205 std::map<uint64_t, Name> methodIdToName_; 206 std::vector<CString> abcNames_; 207 }; 208 209 class TypedOpProfiler { 210 public: 211 using OpCode = kungfu::OpCode; 212 TypedOpProfiler()213 TypedOpProfiler() 214 { 215 strOpMap_ = { 216 { "LOAD_BUILTIN_OBJECT", OpCode::LOAD_BUILTIN_OBJECT }, 217 { "LOAD_PROPERTY", OpCode::LOAD_PROPERTY }, 218 { "LOAD_ELEMENT", OpCode::LOAD_ELEMENT } 219 }; 220 221 profMap_ = { 222 { OpCode::LOAD_BUILTIN_OBJECT, 0 }, 223 { OpCode::LOAD_PROPERTY, 0 }, 224 { OpCode::LOAD_ELEMENT, 0 } 225 }; 226 } 227 Update(OpCode opcode)228 void Update(OpCode opcode) 229 { 230 auto it = profMap_.find(opcode); 231 if (it != profMap_.end()) { 232 it->second++; 233 } 234 } 235 PrintAndReset(std::string opStr)236 void PrintAndReset(std::string opStr) 237 { 238 auto it = strOpMap_.find(opStr); 239 if (it != strOpMap_.end()) { 240 LOG_TRACE(INFO) << "Opcode: " << it->first << " Count:" 241 << profMap_.at(it->second); 242 243 profMap_.at(it->second) = 0; 244 } 245 } 246 247 private: 248 std::map<std::string, OpCode> strOpMap_; 249 std::map<OpCode, uint64_t> profMap_; 250 }; 251 } // namespace panda::ecmascript 252 #endif // ECMASCRIPT_DFX_VMSTAT_OPT_CODE_PROFILER_H 253