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