• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_MANAGER_H
16 #define ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_MANAGER_H
17 
18 #include <string>
19 #include <utility>
20 
21 #include "ecmascript/base/file_header.h"
22 #include "ecmascript/compiler/aot_file/an_file_data_manager.h"
23 #include "ecmascript/compiler/aot_file/an_file_info.h"
24 #include "ecmascript/compiler/aot_file/aot_file_info.h"
25 #include "ecmascript/compiler/aot_file/binary_buffer_parser.h"
26 #include "ecmascript/compiler/aot_file/module_section_des.h"
27 #include "ecmascript/compiler/aot_file/stub_file_info.h"
28 #include "ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.h"
29 #include "ecmascript/compiler/binary_section.h"
30 #include "ecmascript/deoptimizer/calleeReg.h"
31 #include "ecmascript/js_function.h"
32 #include "ecmascript/js_runtime_options.h"
33 #include "ecmascript/mem/c_containers.h"
34 #include "ecmascript/platform/file.h"
35 #include "ecmascript/platform/map.h"
36 #include "ecmascript/stackmap/ark_stackmap.h"
37 
38 namespace panda::ecmascript {
39 class JSpandafile;
40 class JSThread;
41 namespace kungfu {
42     class ArkStackMapParser;
43 } // namespace kungfu
44 
45 /*                  AOTLiteralInfo
46  *      +-----------------------------------+----
47  *      |              ...                  |  ^
48  *      |              ...                  |  |
49  *      | cache(store function entry index) |  AOT Function Entry Index, if its value is -1,
50  *      |              ...                  |  means the function has not been compiled with AOT.
51  *      |              ...                  |  v
52  *      +-----------------------------------+----
53  *      |         Literal Type              |  JSTaggedValue(int32_t)
54  *      +-----------------------------------+----
55  *      |      AOT Instance Hclass (IHC)    |  JSTaggedValue(HClass)
56  *      +-----------------------------------+----
57  *      |   AOT Constructor Hclass (CHC)    |  JSTaggedValue(HClass)
58  *      +-----------------------------------+----
59  */
60 class AOTLiteralInfo : public TaggedArray {
61 public:
62     static constexpr size_t NO_FUNC_ENTRY_VALUE = -1;
63     static constexpr size_t AOT_CHC_INDEX = 1;
64     static constexpr size_t AOT_IHC_INDEX = 2;
65     static constexpr size_t LITERAL_TYPE_INDEX = 3;
66     static constexpr size_t RESERVED_LENGTH = LITERAL_TYPE_INDEX;
67 
68     static constexpr int32_t METHOD_LITERAL_TYPE = 1;
69     static constexpr int32_t INVALID_LITERAL_TYPE = 0;
70 
Cast(TaggedObject * object)71     static AOTLiteralInfo* Cast(TaggedObject* object)
72     {
73         ASSERT(JSTaggedValue(object).IsTaggedArray());
74         return static_cast<AOTLiteralInfo*>(object);
75     }
76 
ComputeSize(uint32_t cacheSize)77     static size_t ComputeSize(uint32_t cacheSize)
78     {
79         return TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), cacheSize + RESERVED_LENGTH);
80     }
81 
82     void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t capacity,
83                                     uint32_t extraLength = 0);
84 
GetCacheLength()85     inline uint32_t GetCacheLength() const
86     {
87         return GetLength() - RESERVED_LENGTH;
88     }
89 
SetIhcPrimitive(JSTaggedValue value)90     inline void SetIhcPrimitive(JSTaggedValue value)
91     {
92         Barriers::SetPrimitive(GetData(), GetIhcOffset(), value.GetRawData());
93     }
94 
SetChcPrimitive(JSTaggedValue value)95     inline void SetChcPrimitive(JSTaggedValue value)
96     {
97         Barriers::SetPrimitive(GetData(), GetChcOffset(), value.GetRawData());
98     }
99 
SetIhc(JSThread * thread,JSTaggedValue value)100     inline void SetIhc(JSThread *thread, JSTaggedValue value)
101     {
102         if (value.IsHeapObject()) {
103             Barriers::SetObject(thread, GetData(), GetIhcOffset(), value.GetRawData());
104         } else {
105             Barriers::SetPrimitive<JSTaggedType>(GetData(), GetIhcOffset(), value.GetRawData());
106         }
107     }
108 
GetIhc(JSThread * thread)109     inline JSTaggedValue GetIhc(JSThread *thread) const
110     {
111         return JSTaggedValue(Barriers::GetTaggedValue(thread, GetData(), GetIhcOffset()));
112     }
113 
SetChc(JSThread * thread,JSTaggedValue value)114     inline void SetChc(JSThread *thread, JSTaggedValue value)
115     {
116         if (value.IsHeapObject()) {
117             Barriers::SetObject(thread, GetData(), GetChcOffset(), value.GetRawData());
118         } else {
119             Barriers::SetPrimitive<JSTaggedType>(GetData(), GetChcOffset(), value.GetRawData());
120         }
121     }
122 
GetChc(JSThread * thread)123     inline JSTaggedValue GetChc(JSThread *thread) const
124     {
125         return JSTaggedValue(Barriers::GetTaggedValue(thread, GetData(), GetChcOffset()));
126     }
127 
SetLiteralType(JSTaggedValue value)128     inline void SetLiteralType(JSTaggedValue value)
129     {
130         Barriers::SetPrimitive(GetData(), GetLiteralTypeOffset(), value.GetRawData());
131     }
132 
GetLiteralType()133     inline int GetLiteralType() const
134     {
135         return JSTaggedValue(Barriers::GetPrimitive<JSTaggedValue>(GetData(), GetLiteralTypeOffset())).GetInt();
136     }
137 
138     void SetObjectToCache(JSThread *thread, uint32_t index, JSTaggedValue value);
139 
GetObjectFromCache(JSThread * thread,uint32_t index)140     inline JSTaggedValue GetObjectFromCache(JSThread *thread, uint32_t index) const
141     {
142         return Get(thread, index);
143     }
144 
145 private:
GetIhcOffset()146     inline size_t GetIhcOffset() const
147     {
148         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_IHC_INDEX);
149     }
150 
GetChcOffset()151     inline size_t GetChcOffset() const
152     {
153         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_CHC_INDEX);
154     }
155 
GetLiteralTypeOffset()156     inline size_t GetLiteralTypeOffset() const
157     {
158         return JSTaggedValue::TaggedTypeSize() * (GetLength() - LITERAL_TYPE_INDEX);
159     }
160 };
161 
162 using JsAotReaderCallback = std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)>;
163 
164 class AOTFileManager {
165 public:
166     explicit AOTFileManager(EcmaVM* vm);
167     virtual ~AOTFileManager();
168 
169     static constexpr char FILE_EXTENSION_AN[] = ".an";
170     static constexpr char FILE_EXTENSION_AI[] = ".ai";
171     static constexpr uint32_t STUB_FILE_INDEX = 1;
172 
173     static void SetJsAotReader(JsAotReaderCallback cb);
174     static JsAotReaderCallback GetJsAotReader();
175 
176     void LoadStubFile(const std::string& fileName);
177     static bool LoadAnFile(const std::string& fileName);
178     static AOTFileInfo::CallSiteInfo CalCallSiteInfo(uintptr_t retAddr, bool isDeopt);
179     static bool TryReadLock();
180     static bool InsideStub(uintptr_t pc);
181     static bool InsideAOT(uintptr_t pc);
182     static bool AOTFileExist(const std::string &aotFileName, const std::string &extension);
183     PUBLIC_API bool IsEnableAOT() const;
184     void Iterate(RootVisitor& v);
185 
186     static std::string GetAOTFileFullPath(EcmaVM* vm, const std::string& moduleName);
187     const std::shared_ptr<AnFileInfo> GetAnFileInfo(const JSPandaFile* jsPandaFile) const;
188     bool IsLoadMain(const JSPandaFile* jsPandaFile, const CString& entry) const;
189     uint32_t GetFileIndex(uint32_t anFileInfoIndex, CString abcNormalizedName) const;
190     std::list<CString> GetPandaFiles(uint32_t aotFileInfoIndex);
191     uint32_t GetAnFileIndex(const JSPandaFile* jsPandaFile) const;
192     void BindPreloadedPandaFilesInAotFile(const std::string& moduleName);
193     bool HasPandaFile(uint32_t aotFileInfoIndex, const CString& abcNormalizedName) const;
194     void BindPandaFileInAotFile(const std::string& aotFileBaseName, JSPandaFile* jsPandaFile) const;
195     void SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc,
196                              const JSPandaFile* jsPandaFile,
197                              std::string_view entryPoint);
198     void SetAOTFuncEntry(const JSPandaFile* jsPandaFile,
199                          JSFunction* function,
200                          Method* method,
201                          uint32_t entryIndex = 0,
202                          bool* canFastCall = nullptr);
203     bool LoadAiFile([[maybe_unused]] const std::string& filename);
204     bool LoadAiFile(const JSPandaFile* jsPandaFile, EcmaVM* vm);
205     kungfu::ArkStackMapParser* GetStackMapParser() const;
206     static JSTaggedValue GetAbsolutePath(JSThread* thread, JSTaggedValue relativePathVal);
207     static bool GetAbsolutePath(const CString& relativePathCstr, CString& absPathCstr);
208     static bool RewriteDataSection(uintptr_t dataSec, size_t size, uintptr_t newData, size_t newSize);
209     void ParseDeserializedData(const CString& snapshotFileName, JSTaggedValue deserializedData);
210     JSHandle<JSTaggedValue> GetDeserializedConstantPool(const JSPandaFile* jsPandaFile, int32_t cpID);
211     const Heap* GetHeap();
212 
213     static void DumpAOTInfo() DUMP_API_ATTR;
214 
215 private:
216     using MultiConstantPoolMap = CMap<int32_t, JSTaggedValue>; // key: constpool id, value: constantpool
217 
218     struct PandaCpInfo {
219         uint32_t fileIndex_;
220         MultiConstantPoolMap multiCpsMap_;
221     };
222     using FileNameToMultiConstantPoolMap = CMap<CString, PandaCpInfo>;
223     using AIDatum = CUnorderedMap<uint32_t, FileNameToMultiConstantPoolMap>; // key: ai file index
224 
225     void LoadingCommonStubsLog(size_t id, Address entry);
226     void LoadingByteCodeStubsLog(size_t id, Address entry);
227     void LoadingBuiltinsStubsLog(size_t id, Address entry);
228     void LoadingBaselineStubsLog(size_t id, Address entry);
229     void LoadingRuntimeStubsLog(size_t id, Address entry);
230     static void PrintAOTEntry(const JSPandaFile *file, const Method *method, uintptr_t entry);
231     void InitializeStubEntries(const std::vector<AnFileInfo::FuncEntryDes>& stubs);
232     static void AdjustBCStubAndDebuggerStubEntries(JSThread *thread,
233                                                    const std::vector<AOTFileInfo::FuncEntryDes> &stubs,
234                                                    const AsmInterParsedOption &asmInterOpt);
235     EcmaVM *vm_ {nullptr};
236     ObjectFactory *factory_ {nullptr};
237     AIDatum aiDatum_ {};
238     kungfu::ArkStackMapParser *arkStackMapParser_ {nullptr};
239     static JsAotReaderCallback jsAotReader_;
240 
241     friend class AnFileInfo;
242     friend class StubFileInfo;
243 };
244 } // namespace panda::ecmascript
245 #endif // ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_MANAGER_H
246