• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "bytecode_analysis_results.h"
17 
18 namespace panda::bytecodeopt {
19 
20 std::mutex BytecodeAnalysisResults::mutex_;
21 BytecodeAnalysisResultMap BytecodeAnalysisResults::analysis_results_;
22 BytecodeMapsMap BytecodeAnalysisResults::bytecode_maps_;
23 
SetModuleConstantAnalysisResult(const ModuleConstantAnalysisResult & result)24 void BytecodeAnalysisResult::SetModuleConstantAnalysisResult(const ModuleConstantAnalysisResult &result)
25 {
26     for (auto &iter : result) {
27         uint32_t slot = iter.first;
28         if (slot < local_export_slot_external_names_.size()) {
29             const auto &external_names = local_export_slot_external_names_[slot];
30             for (const auto &external_name_iter : external_names) {
31                 constant_local_export_values_.emplace(external_name_iter, *iter.second);
32             }
33         }
34     }
35 }
36 
SetConstantLocalExportSlots(const std::unordered_set<uint32_t> & slots)37 void BytecodeAnalysisResult::SetConstantLocalExportSlots(const std::unordered_set<uint32_t> &slots)
38 {
39     constant_local_export_slots_ = slots;
40 }
41 
SetLocalExportInfo(uint32_t slot,const std::string & external_name)42 void BytecodeAnalysisResult::SetLocalExportInfo(uint32_t slot, const std::string &external_name)
43 {
44     if (slot == local_export_slot_external_names_.size()) {
45         auto &vec = local_export_slot_external_names_.emplace_back();
46         vec.push_back(external_name);
47     } else {
48         ASSERT(slot < local_export_slot_external_names_.size());
49         local_export_slot_external_names_[slot].push_back(external_name);
50     }
51 }
52 
SetRegularImportInfo(uint32_t slot,const std::string & import_name,const std::string & source_record)53 void BytecodeAnalysisResult::SetRegularImportInfo(uint32_t slot,
54                                                   const std::string &import_name,
55                                                   const std::string &source_record)
56 {
57     [[maybe_unused]] auto iter = regular_import_slot_infos_.find(slot);
58     ASSERT(iter == regular_import_slot_infos_.end());
59     RegularImportInfo info {import_name, source_record};
60     regular_import_slot_infos_.emplace(slot, info);
61 }
62 
SetNamespaceImportInfo(uint32_t slot,const std::string & source_record)63 void BytecodeAnalysisResult::SetNamespaceImportInfo(uint32_t slot, const std::string &source_record)
64 {
65     namespace_import_slot_source_record_names_.emplace(slot, source_record);
66 }
67 
GetLocalExportInfo(uint32_t slot,uint32_t name_idx,std::string & external_name) const68 bool BytecodeAnalysisResult::GetLocalExportInfo(uint32_t slot, uint32_t name_idx, std::string &external_name) const
69 {
70     if (slot >= local_export_slot_external_names_.size()) {
71         return false;
72     }
73     const auto &names = local_export_slot_external_names_[slot];
74     if (name_idx > names.size()) {
75         return false;
76     }
77     external_name = names[name_idx];
78     return true;
79 }
80 
GetRegularImportInfo(uint32_t slot,std::string & import_name,std::string & source_record) const81 bool BytecodeAnalysisResult::GetRegularImportInfo(uint32_t slot,
82                                                   std::string &import_name,
83                                                   std::string &source_record) const
84 {
85     auto iter = regular_import_slot_infos_.find(slot);
86     if (iter == regular_import_slot_infos_.end()) {
87         return false;
88     }
89     import_name = iter->second.import_name;
90     source_record = iter->second.source_record_name;
91     return true;
92 }
93 
GetNamespaceImportInfo(uint32_t slot,std::string & source_record) const94 bool BytecodeAnalysisResult::GetNamespaceImportInfo(uint32_t slot, std::string &source_record) const
95 {
96     auto iter = namespace_import_slot_source_record_names_.find(slot);
97     if (iter == namespace_import_slot_source_record_names_.end()) {
98         return false;
99     }
100     source_record = iter->second;
101     return true;
102 }
103 
GetExportedConstantValue(const std::string & name,ConstantValue & value) const104 bool BytecodeAnalysisResult::GetExportedConstantValue(const std::string &name, ConstantValue &value) const
105 {
106     auto iter = constant_local_export_values_.find(name);
107     if (iter != constant_local_export_values_.end()) {
108         value = iter->second;
109         return true;
110     }
111     return false;
112 }
113 
Dump(std::ostream & os)114 void BytecodeAnalysisResult::Dump(std::ostream &os)
115 {
116     os << "------------------------------------" << std::endl;
117     os << "Constant local export values: " << std::endl;
118     for (auto iter : constant_local_export_values_) {
119         os << iter.first << ": " << iter.second.ToString() << std::endl;
120     }
121     os << "Constant local export slots: " << std::endl;
122     for (auto iter : constant_local_export_slots_) {
123         os << iter << ", ";
124     }
125     os << std::endl;
126     os << "Local export slot external names: " << std::endl;
127     for (size_t i = 0; i < local_export_slot_external_names_.size(); i++) {
128         os << i << ": ";
129         for (auto iter : local_export_slot_external_names_[i]) {
130             os << iter << ", ";
131         }
132         os << std::endl;
133     }
134     os << "Regular import slot infos: " << std::endl;
135     for (auto iter : regular_import_slot_infos_) {
136         os << iter.first << ": import_name: " << iter.second.import_name
137            << ", source_record_name: " << iter.second.source_record_name << std::endl;
138     }
139     os << "Namespace import slot source record names: " << std::endl;
140     for (auto iter : namespace_import_slot_source_record_names_) {
141         os << iter.first << ": " << iter.second << std::endl;
142     }
143     os << "------------------------------------" << std::endl;
144 }
145 
GetOrCreateBytecodeMaps(const std::string & filename,bool & exists)146 pandasm::AsmEmitter::PandaFileToPandaAsmMaps &BytecodeAnalysisResults::GetOrCreateBytecodeMaps(
147     const std::string &filename, bool &exists)
148 {
149     return GetOrCreateElementInMap<pandasm::AsmEmitter::PandaFileToPandaAsmMaps>(bytecode_maps_, filename, exists);
150 }
151 
DeleteBytecodeMaps(const std::string & filename)152 void BytecodeAnalysisResults::DeleteBytecodeMaps(const std::string &filename)
153 {
154     std::unique_lock<std::mutex> lock(mutex_);
155     bytecode_maps_.erase(filename);
156 }
157 
GetOrCreateBytecodeAnalysisResult(const std::string & recordname,bool & exists)158 BytecodeAnalysisResult &BytecodeAnalysisResults::GetOrCreateBytecodeAnalysisResult(const std::string &recordname,
159                                                                                    bool &exists)
160 {
161     return GetOrCreateElementInMap<BytecodeAnalysisResult>(analysis_results_, recordname, exists);
162 }
163 
GetLocalExportConstForRecord(const std::string & recordname,uint32_t local_export_slot,ConstantValue & value)164 bool BytecodeAnalysisResults::GetLocalExportConstForRecord(const std::string &recordname,
165                                                            uint32_t local_export_slot,
166                                                            ConstantValue &value)
167 {
168     constexpr uint32_t DEFAULT_EXTERNAL_NAME_IDX = 0;
169     auto iter = analysis_results_.find(recordname);
170     if (iter == analysis_results_.end()) {
171         return false;
172     }
173     auto &analysis_resut = iter->second;
174     std::string external_name;
175     if (!analysis_resut->GetLocalExportInfo(local_export_slot, DEFAULT_EXTERNAL_NAME_IDX, external_name)) {
176         return false;
177     }
178     return analysis_resut->GetExportedConstantValue(external_name, value);
179 }
180 
GetRegularImportConstForRecord(const std::string & recordname,uint32_t regular_import_slot,ConstantValue & value)181 bool BytecodeAnalysisResults::GetRegularImportConstForRecord(const std::string &recordname,
182                                                              uint32_t regular_import_slot,
183                                                              ConstantValue &value)
184 {
185     auto iter = analysis_results_.find(recordname);
186     if (iter == analysis_results_.end()) {
187         return false;
188     }
189     std::string import_name;
190     std::string source_record;
191     if (!iter->second->GetRegularImportInfo(regular_import_slot, import_name, source_record)) {
192         return false;
193     }
194 
195     iter = analysis_results_.find(source_record);
196     if (iter == analysis_results_.end()) {
197         return false;
198     }
199     return iter->second->GetExportedConstantValue(import_name, value);
200 }
201 
GetModuleNamespaceConstForRecord(const std::string & recordname,uint32_t module_namespace_slot,const std::string & property_name,ConstantValue & value)202 bool BytecodeAnalysisResults::GetModuleNamespaceConstForRecord(const std::string &recordname,
203                                                                uint32_t module_namespace_slot,
204                                                                const std::string &property_name,
205                                                                ConstantValue &value)
206 {
207     auto iter = analysis_results_.find(recordname);
208     if (iter == analysis_results_.end()) {
209         return false;
210     }
211     std::string source_record;
212     if (!iter->second->GetNamespaceImportInfo(module_namespace_slot, source_record)) {
213         return false;
214     }
215     iter = analysis_results_.find(source_record);
216     if (iter == analysis_results_.end()) {
217         return false;
218     }
219     return iter->second->GetExportedConstantValue(property_name, value);
220 }
221 
Clear()222 void BytecodeAnalysisResults::Clear()
223 {
224     std::unique_lock<std::mutex> lock(mutex_);
225     bytecode_maps_.clear();
226     analysis_results_.clear();
227 }
228 
229 }  // namespace panda::bytecodeopt