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