• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 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 AOT_PROFILING_DATA_H
17 #define AOT_PROFILING_DATA_H
18 
19 #include "utils/span.h"
20 #include "runtime/include/mem/panda_string.h"
21 #include "runtime/include/mem/panda_containers.h"
22 #include "runtime/jit/profiling_data.h"
23 
24 #include <cstdint>
25 #include <atomic>
26 
27 namespace ark::pgo {
28 using PandaFileIdxType = int32_t;  // >= -1
29 
30 class AotProfilingData {
31 public:
32     struct AotCallSiteInlineCache;
33     struct AotBranchData;
34     struct AotThrowData;
35     class AotMethodProfilingData {  // NOLINT(cppcoreguidelines-special-member-functions)
36     public:
AotMethodProfilingData(uint32_t methodIdx,uint32_t classIdx,uint32_t inlineCaches,uint32_t branchData,uint32_t throwData)37         AotMethodProfilingData(uint32_t methodIdx, uint32_t classIdx, uint32_t inlineCaches, uint32_t branchData,
38                                uint32_t throwData)
39             : methodIdx_(methodIdx),
40               classIdx_(classIdx),
41               inlineCaches_(inlineCaches),
42               branchData_(branchData),
43               throwData_(throwData)
44         {
45         }
46 
AotMethodProfilingData(uint32_t methodIdx,uint32_t classIdx,PandaVector<AotCallSiteInlineCache> inlineCaches,PandaVector<AotBranchData> branchData,PandaVector<AotThrowData> throwData)47         AotMethodProfilingData(uint32_t methodIdx, uint32_t classIdx, PandaVector<AotCallSiteInlineCache> inlineCaches,
48                                PandaVector<AotBranchData> branchData, PandaVector<AotThrowData> throwData)
49             : methodIdx_(methodIdx),
50               classIdx_(classIdx),
51               inlineCaches_(std::move(inlineCaches)),
52               branchData_(std::move(branchData)),
53               throwData_(std::move(throwData))
54         {
55         }
56 
GetInlineCaches()57         Span<AotCallSiteInlineCache> GetInlineCaches()
58         {
59             return Span<AotCallSiteInlineCache>(inlineCaches_.data(), inlineCaches_.size());
60         }
61 
GetBranchData()62         Span<AotBranchData> GetBranchData()
63         {
64             return Span<AotBranchData>(branchData_.data(), branchData_.size());
65         }
66 
GetThrowData()67         Span<AotThrowData> GetThrowData()
68         {
69             return Span<AotThrowData>(throwData_.data(), throwData_.size());
70         }
71 
GetInlineCaches()72         Span<const AotCallSiteInlineCache> GetInlineCaches() const
73         {
74             return Span<const AotCallSiteInlineCache>(inlineCaches_.data(), inlineCaches_.size());
75         }
76 
GetBranchData()77         Span<const AotBranchData> GetBranchData() const
78         {
79             return Span<const AotBranchData>(branchData_.data(), branchData_.size());
80         }
81 
GetThrowData()82         Span<const AotThrowData> GetThrowData() const
83         {
84             return Span<const AotThrowData>(throwData_.data(), throwData_.size());
85         }
86 
GetMethodIdx()87         uint32_t GetMethodIdx() const
88         {
89             return methodIdx_;
90         }
91 
GetClassIdx()92         uint32_t GetClassIdx() const
93         {
94             return classIdx_;
95         }
96 
97     private:
98         uint32_t methodIdx_;
99         uint32_t classIdx_;
100 
101         PandaVector<AotCallSiteInlineCache> inlineCaches_;
102         PandaVector<AotBranchData> branchData_;
103         PandaVector<AotThrowData> throwData_;
104     };
105 
106 #pragma pack(push, 4)
107     struct AotCallSiteInlineCache {                              // NOLINT(cppcoreguidelines-pro-type-member-init)
108         static constexpr size_t CLASSES_COUNT = 4;               // CC-OFF(G.NAM.03-CPP) project code style
109         static constexpr int32_t MEGAMORPHIC_FLAG = 0xFFFFFFFF;  // CC-OFF(G.NAM.03-CPP) project code style
110 
ClearClassesAotCallSiteInlineCache111         static void ClearClasses(std::array<std::pair<uint32_t, PandaFileIdxType>, CLASSES_COUNT> &classes)
112         {
113             std::fill(classes.begin(), classes.end(), std::make_pair(0, -1));
114         }
115 
116         uint32_t pc;
117         std::array<std::pair<uint32_t, PandaFileIdxType>, CLASSES_COUNT> classes;
118     };
119 
120     struct AotBranchData {
121         uint32_t pc;
122         uint64_t taken;
123         uint64_t notTaken;
124     };
125 
126     struct AotThrowData {
127         uint32_t pc;
128         uint64_t taken;
129     };
130 #pragma pack(pop)
131 
132 public:
GetPandaFileMap()133     PandaMap<std::string_view, PandaFileIdxType> &GetPandaFileMap()
134     {
135         return pandaFileMap_;
136     }
137 
GetPandaFileMapReverse()138     PandaMap<PandaFileIdxType, std::string_view> &GetPandaFileMapReverse()
139     {
140         return pandaFileMapRev_;
141     }
142 
143     using MethodsMap = PandaMap<uint32_t, AotMethodProfilingData>;
GetAllMethods()144     PandaMap<PandaFileIdxType, MethodsMap> &GetAllMethods()
145     {
146         return allMethodsMap_;
147     }
148 
GetPandaFileIdxByName(std::string_view pandaFileName)149     int32_t GetPandaFileIdxByName(std::string_view pandaFileName)
150     {
151         auto pfIdx = pandaFileMap_.find(pandaFileName);
152         if (pfIdx == pandaFileMap_.end()) {
153             return -1;
154         }
155         return pfIdx->second;
156     }
157 
158     template <typename Rng>
AddPandaFiles(Rng && profiledPandaFiles)159     void AddPandaFiles(Rng &&profiledPandaFiles)
160     {
161         auto count = static_cast<int32_t>(pandaFileMap_.size());
162         for (auto &pandaFile : profiledPandaFiles) {
163             if (pandaFileMap_.find(pandaFile) != pandaFileMap_.end()) {
164                 continue;
165             }
166             pandaFileMap_[pandaFile] = count;
167             pandaFileMapRev_[count] = pandaFile;
168             count++;
169         }
170     }
171 
AddMethod(PandaFileIdxType pfIdx,uint32_t methodIdx,AotMethodProfilingData && profData)172     void AddMethod(PandaFileIdxType pfIdx, uint32_t methodIdx, AotMethodProfilingData &&profData)
173     {
174         if (allMethodsMap_[pfIdx].find(methodIdx) != allMethodsMap_[pfIdx].end()) {
175             allMethodsMap_[pfIdx].erase(methodIdx);
176         }
177         allMethodsMap_[pfIdx].insert(std::make_pair(methodIdx, std::move(profData)));
178     }
179 
180 private:
181     PandaMap<std::string_view, PandaFileIdxType> pandaFileMap_;
182     PandaMap<PandaFileIdxType, std::string_view> pandaFileMapRev_;
183     PandaMap<PandaFileIdxType, MethodsMap> allMethodsMap_;
184 };
185 }  // namespace ark::pgo
186 
187 #endif  // AOT_PROFILING_DATA_H
188