• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_snapshot/snapshot_constantpool_data.h"
26 #include "ecmascript/compiler/aot_file/binary_buffer_parser.h"
27 #include "ecmascript/compiler/aot_file/module_section_des.h"
28 #include "ecmascript/compiler/aot_file/stub_file_info.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 
42 /*                  AOTLiteralInfo
43  *      +-----------------------------------+----
44  *      |             cache                 |  ^
45  *      |              ...                  |  |
46  *      |   -1 (No AOT Function Entry)      |  |
47  *      |     AOT Function Entry Index      |  |
48  *      |     AOT Function Entry Index      |  |
49  *      +-----------------------------------+----
50  *      |      AOT Instance Hclass (IHC)    |
51  *      |   AOT Constructor Hclass (CHC)    |
52  *      |   AOT ElementIndex (ElementIndex) |
53  *      +-----------------------------------+
54  */
55 class AOTLiteralInfo : public TaggedArray {
56 public:
57     static constexpr size_t NO_FUNC_ENTRY_VALUE = -1;
58     static constexpr size_t AOT_CHC_INDEX = 1;
59     static constexpr size_t AOT_IHC_INDEX = 2;
60     static constexpr size_t AOT_ELEMENT_INDEX = 3;
61     static constexpr size_t RESERVED_LENGTH = AOT_ELEMENT_INDEX;
62 
Cast(TaggedObject * object)63     static AOTLiteralInfo *Cast(TaggedObject *object)
64     {
65         ASSERT(JSTaggedValue(object).IsTaggedArray());
66         return static_cast<AOTLiteralInfo *>(object);
67     }
68 
ComputeSize(uint32_t cacheSize)69     static size_t ComputeSize(uint32_t cacheSize)
70     {
71         return TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), cacheSize + RESERVED_LENGTH);
72     }
73 
74     inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t capacity, uint32_t extraLength = 0)
75     {
76         TaggedArray::InitializeWithSpecialValue(initValue, capacity + RESERVED_LENGTH, extraLength);
77         SetIhc(JSTaggedValue::Undefined());
78         SetChc(JSTaggedValue::Undefined());
79         SetElementIndex(JSTaggedValue(kungfu::BaseSnapshotInfo::AOT_ELEMENT_INDEX_DEFAULT_VALUE));
80     }
81 
GetCacheLength()82     inline uint32_t GetCacheLength() const
83     {
84         return GetLength() - RESERVED_LENGTH;
85     }
86 
SetIhc(JSTaggedValue value)87     inline void SetIhc(JSTaggedValue value)
88     {
89         Barriers::SetPrimitive(GetData(), GetIhcOffset(), value.GetRawData());
90     }
91 
GetIhc()92     inline JSTaggedValue GetIhc() const
93     {
94         return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetIhcOffset()));
95     }
96 
SetChc(JSTaggedValue value)97     inline void SetChc(JSTaggedValue value)
98     {
99         Barriers::SetPrimitive(GetData(), GetChcOffset(), value.GetRawData());
100     }
101 
GetChc()102     inline JSTaggedValue GetChc() const
103     {
104         return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetChcOffset()));
105     }
106 
SetElementIndex(JSTaggedValue value)107     inline void SetElementIndex(JSTaggedValue value)
108     {
109         Barriers::SetPrimitive(GetData(), GetElementIndexOffset(), value.GetRawData());
110     }
111 
GetElementIndex()112     inline int GetElementIndex() const
113     {
114         return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetElementIndexOffset())).GetInt();
115     }
116 
SetObjectToCache(JSThread * thread,uint32_t index,JSTaggedValue value)117     inline void SetObjectToCache(JSThread *thread, uint32_t index, JSTaggedValue value)
118     {
119         Set(thread, index, value);
120     }
121 
GetObjectFromCache(uint32_t index)122     inline JSTaggedValue GetObjectFromCache(uint32_t index) const
123     {
124         return Get(index);
125     }
126 private:
127 
GetIhcOffset()128     inline size_t GetIhcOffset() const
129     {
130         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_IHC_INDEX);
131     }
132 
GetChcOffset()133     inline size_t GetChcOffset() const
134     {
135         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_CHC_INDEX);
136     }
137 
GetElementIndexOffset()138     inline size_t GetElementIndexOffset() const
139     {
140         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_ELEMENT_INDEX);
141     }
142 };
143 
144 class AOTFileManager {
145 public:
146     explicit AOTFileManager(EcmaVM *vm);
147     virtual ~AOTFileManager();
148 
149     static constexpr char FILE_EXTENSION_AN[] = ".an";
150     static constexpr char FILE_EXTENSION_AI[] = ".ai";
151     static constexpr uint32_t STUB_FILE_INDEX = 1;
152 
153     void LoadStubFile(const std::string &fileName);
154     static bool LoadAnFile(const std::string &fileName);
155     static AOTFileInfo::CallSiteInfo CalCallSiteInfo(uintptr_t retAddr);
156     static bool TryReadLock();
157     static bool InsideStub(uintptr_t pc);
158     static bool InsideAOT(uintptr_t pc);
159     void Iterate(const RootVisitor &v);
160 
161     const std::shared_ptr<AnFileInfo> GetAnFileInfo(const JSPandaFile *jsPandaFile) const;
162     bool IsLoadMain(const JSPandaFile *jsPandaFile, const CString &entry) const;
163     uint32_t GetFileIndex(uint32_t anFileInfoIndex, CString abcNormalizedName) const;
164     std::list<CString> GetPandaFiles(uint32_t aotFileInfoIndex);
165     uint32_t GetAnFileIndex(const JSPandaFile *jsPandaFile) const;
166     void BindPandaFilesInAotFile(const std::string &aotFileBaseName, const std::string &moduleName);
167     void SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile,
168                              std::string_view entryPoint);
169     void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method,
170                          uint32_t entryIndex, bool *canFastCall = nullptr);
171     bool LoadAiFile([[maybe_unused]] const std::string &filename);
172     bool LoadAiFile(const JSPandaFile *jsPandaFile);
173     kungfu::ArkStackMapParser* GetStackMapParser() const;
174     static JSTaggedValue GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal);
175     static bool GetAbsolutePath(const CString &relativePathCstr, CString &absPathCstr);
176     static bool RewriteDataSection(uintptr_t dataSec, size_t size, uintptr_t newData, size_t newSize);
177     void ParseDeserializedData(const CString &snapshotFileName, JSTaggedValue deserializedData);
178     JSHandle<JSTaggedValue> GetDeserializedConstantPool(const JSPandaFile *jsPandaFile, int32_t cpID);
179     const Heap *GetHeap();
180 
181     static void DumpAOTInfo() DUMP_API_ATTR;
182 
183 private:
184     using MultiConstantPoolMap = CMap<int32_t, JSTaggedValue>; // key: constpool id, value: constantpool
185 
186     struct PandaCpInfo {
187         uint32_t fileIndex_;
188         MultiConstantPoolMap multiCpsMap_;
189     };
190     using FileNameToMultiConstantPoolMap = CMap<CString, PandaCpInfo>;
191     using AIDatum = CUnorderedMap<uint32_t, FileNameToMultiConstantPoolMap>; // key: ai file index
192 
193     static void PrintAOTEntry(const JSPandaFile *file, const Method *method, uintptr_t entry);
194     void InitializeStubEntries(const std::vector<AnFileInfo::FuncEntryDes>& stubs);
195     static void AdjustBCStubAndDebuggerStubEntries(JSThread *thread,
196                                                    const std::vector<AOTFileInfo::FuncEntryDes> &stubs,
197                                                    const AsmInterParsedOption &asmInterOpt);
198     EcmaVM *vm_ {nullptr};
199     ObjectFactory *factory_ {nullptr};
200     AIDatum aiDatum_ {};
201     kungfu::ArkStackMapParser *arkStackMapParser_ {nullptr};
202 
203     friend class AnFileInfo;
204     friend class StubFileInfo;
205 };
206 }  // namespace panda::ecmascript
207 #endif // ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_MANAGER_H
208