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 #ifndef BYTECODE_OPTIMIZER_BYTECODE_ANALYSIS_RESULT_H
17 #define BYTECODE_OPTIMIZER_BYTECODE_ANALYSIS_RESULT_H
18 
19 #include <mutex>
20 #include "assembler/assembly-emitter.h"
21 #include "bytecode_optimizer/module_constant_analyzer.h"
22 #include "bytecode_optimizer/constant_propagation/constant_value.h"
23 
24 namespace panda::bytecodeopt {
25 
26 class BytecodeAnalysisResult {
27 public:
28     explicit BytecodeAnalysisResult() = default;
29 
GetConstantLocalExportSlots()30     const std::unordered_set<uint32_t> &GetConstantLocalExportSlots()
31     {
32         return constant_local_export_slots_;
33     }
34 
35     void SetModuleConstantAnalysisResult(const ModuleConstantAnalysisResult &result);
36     void SetConstantLocalExportSlots(const std::unordered_set<uint32_t> &slots);
37     void SetLocalExportInfo(uint32_t slot, const std::string &external_name);
38     void SetRegularImportInfo(uint32_t slot, const std::string &import_name, const std::string &source_record);
39     void SetNamespaceImportInfo(uint32_t slot, const std::string &source_record);
40     void Dump(std::ostream &os);
41 
42 private:
43     using LocalExportInfo = std::vector<std::string>;
44     struct RegularImportInfo {
45         std::string import_name;
46         std::string source_record_name;
47     };
48 
49     bool GetExportedConstantValue(const std::string &name, ConstantValue &value) const;
50     bool GetLocalExportInfo(uint32_t slot, uint32_t name_idx, std::string &external_name) const;
51     bool GetRegularImportInfo(uint32_t slot, std::string &import_name, std::string &source_record) const;
52     bool GetNamespaceImportInfo(uint32_t slot, std::string &source_record) const;
53 
54     std::unordered_map<std::string, ConstantValue> constant_local_export_values_;
55     std::unordered_set<uint32_t> constant_local_export_slots_;
56     std::vector<LocalExportInfo> local_export_slot_external_names_;
57     std::unordered_map<uint32_t, RegularImportInfo> regular_import_slot_infos_;
58     std::unordered_map<uint32_t, std::string> namespace_import_slot_source_record_names_;
59 
60     friend class BytecodeAnalysisResults;
61 };
62 
63 using BytecodeAnalysisResultMap = std::unordered_map<std::string, std::unique_ptr<BytecodeAnalysisResult>>;
64 using BytecodeMapsMap =
65         std::unordered_map<std::string, std::unique_ptr<pandasm::AsmEmitter::PandaFileToPandaAsmMaps>>;
66 
67 class BytecodeAnalysisResults {
68 public:
69     static pandasm::AsmEmitter::PandaFileToPandaAsmMaps &GetOrCreateBytecodeMaps(const std::string &filename,
70                                                                                  bool &exists);
71     static void DeleteBytecodeMaps(const std::string &filename);
72 
73     static BytecodeAnalysisResult &GetOrCreateBytecodeAnalysisResult(const std::string &recordname, bool &exists);
74 
75     static void Clear();
76 
77     // Following methods should only be called when no writer modifying analysis results exists
78     static bool GetLocalExportConstForRecord(const std::string &recordname, uint32_t local_export_slot,
79                                              ConstantValue &value);
80     static bool GetRegularImportConstForRecord(const std::string &recordname, uint32_t regular_import_slot,
81                                                ConstantValue &value);
82     static bool GetModuleNamespaceConstForRecord(const std::string &recordname, uint32_t module_namespace_slot,
83                                                  const std::string &property_name, ConstantValue &value);
84 private:
85     static BytecodeAnalysisResultMap analysis_results_;
86     static BytecodeMapsMap bytecode_maps_;
87     static std::mutex mutex_;
88 
89     template<typename T>
GetOrCreateElementInMap(std::unordered_map<std::string, std::unique_ptr<T>> &map, const std::string &name, bool &exists)90     static T& GetOrCreateElementInMap(std::unordered_map<std::string, std::unique_ptr<T>> &map,
91                                       const std::string &name, bool &exists)
92     {
93         std::unique_lock<std::mutex> lock(mutex_);
94         auto iter = map.find(name);
95         if (iter == map.end()) {
96             exists = false;
97             auto new_element = std::make_unique<T>();
98             auto ret = map.emplace(name, std::move(new_element));
99             ASSERT(ret.second == true);
100             return *ret.first->second;
101         }
102         return *(iter->second);
103     }
104 };
105 
106 }  // namespace panda::bytecodeopt
107 
108 #endif  // BYTECODE_OPTIMIZER_BYTECODE_ANALYSIS_RESULT_H
109