1 /* 2 * Copyright (c) 2023-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 #ifndef ECMASCRIPT_COMPILER_PGO_BC_INFO_RECORDER_H 17 #define ECMASCRIPT_COMPILER_PGO_BC_INFO_RECORDER_H 18 19 #include "ecmascript/jspandafile/method_literal.h" 20 #include "ecmascript/mem/c_containers.h" 21 #include "libpandafile/bytecode_instruction.h" 22 23 namespace panda::ecmascript::kungfu { 24 class PGOBCInfo { 25 public: 26 enum Type { 27 OBJ_LITERAL = 0, 28 ARRAY_LITERAL, 29 EMPTY_ARRAY, 30 CALL_TARGET, 31 CLASS, 32 FUNCTION, 33 34 TYPE_NUM, 35 TYPE_FIRST = OBJ_LITERAL, 36 TYPE_LAST = FUNCTION, 37 }; 38 39 struct InfoDetail { 40 const CString &recordName; 41 uint32_t methodOffset; 42 uint32_t bcIndex; 43 uint32_t bcOffset; 44 uint32_t cpIndex; 45 }; 46 47 class Info { 48 public: 49 void Record(const InfoDetail &detail); 50 51 uint32_t GetPGOExtendGTCount(const CString &recordName) const; 52 53 template <class Callback> IterateValByMethodOffset(uint32_t methodOffset, Type type, const Callback &cb) const54 void IterateValByMethodOffset(uint32_t methodOffset, Type type, const Callback &cb) const 55 { 56 if (methodOffsetToValVec_.find(methodOffset) != methodOffsetToValVec_.end()) { 57 const ValVec &valVec = methodOffsetToValVec_.at(methodOffset); 58 for (auto val : valVec) { 59 cb(type, val.bcIndex, val.bcOffset, val.cpIndex); 60 } 61 } 62 } 63 64 template <class Callback> IterateValByMethodOffsetAndType(uint32_t methodOffset, const Callback &cb) const65 void IterateValByMethodOffsetAndType(uint32_t methodOffset, const Callback &cb) const 66 { 67 if (methodOffsetToValVec_.find(methodOffset) != methodOffsetToValVec_.end()) { 68 const ValVec &valVec = methodOffsetToValVec_.at(methodOffset); 69 for (auto val : valVec) { 70 cb(val.bcIndex, val.bcOffset, val.cpIndex); 71 } 72 } 73 } 74 75 private: 76 struct Val { 77 uint32_t bcIndex; 78 uint32_t bcOffset; 79 uint32_t cpIndex; 80 }; 81 using ValVec = CVector<Val>; 82 CMap<CString, uint32_t> recordNameToValCount_; 83 CUnorderedMap<uint32_t, ValVec> methodOffsetToValVec_; 84 }; 85 PGOBCInfo()86 PGOBCInfo() : infos_(Type::TYPE_NUM, Info{}) {} 87 ~PGOBCInfo() = default; 88 89 const Info& GetInfo(Type type) const; 90 91 uint32_t GetPGOExtendGTCount(const CString &recordName) const; 92 93 void PUBLIC_API Record(const BytecodeInstruction &bcIns, int32_t bcIndex, 94 const CString &recordName, const MethodLiteral *method); 95 96 template <class Callback> IterateInfoAndType(uint32_t methodOffset, const Callback &cb) const97 void IterateInfoAndType(uint32_t methodOffset, const Callback &cb) const 98 { 99 for (size_t idx = 0; idx < Type::TYPE_NUM; ++idx) { 100 Type type = static_cast<Type>(idx); 101 infos_[idx].IterateValByMethodOffset(methodOffset, type, cb); 102 } 103 } 104 105 template <class Callback> IterateInfoByType(uint32_t methodOffset, Type type, const Callback &cb) const106 void IterateInfoByType(uint32_t methodOffset, Type type, const Callback &cb) const 107 { 108 infos_[type].IterateValByMethodOffsetAndType(methodOffset, cb); 109 } 110 private: 111 void Record(const InfoDetail &detail, Type type); 112 113 CVector<Info> infos_; 114 }; 115 } // panda::ecmascript::kungfu 116 #endif // ECMASCRIPT_COMPILER_PGO_BC_INFO_RECORDER_H 117