• 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_info.h"
23 #include "ecmascript/compiler/aot_file/aot_file_info.h"
24 #include "ecmascript/compiler/aot_file/binary_buffer_parser.h"
25 #include "ecmascript/compiler/aot_file/module_section_des.h"
26 #include "ecmascript/compiler/aot_file/stub_file_info.h"
27 #include "ecmascript/compiler/binary_section.h"
28 #include "ecmascript/deoptimizer/calleeReg.h"
29 #include "ecmascript/js_function.h"
30 #include "ecmascript/js_runtime_options.h"
31 #include "ecmascript/platform/file.h"
32 #include "ecmascript/platform/map.h"
33 #include "ecmascript/stackmap/ark_stackmap.h"
34 
35 namespace panda::ecmascript {
36 class JSpandafile;
37 class JSThread;
38 
39 /*                  AOTLiteralInfo
40  *      +--------------------------------+----
41  *      |             cache              |  ^
42  *      |              ...               |  |
43  *      |   -1 (No AOT Function Entry)   |  |
44  *      |     AOT Function Entry Index   |  |
45  *      |     AOT Function Entry Index   |  |
46  *      +--------------------------------+----
47  *      |      AOT Instance Hclass (IHC) |
48  *      |   AOT Constructor Hclass (CHC) |
49  *      +--------------------------------+
50  */
51 class AOTLiteralInfo : public TaggedArray {
52 public:
Cast(TaggedObject * object)53     static AOTLiteralInfo *Cast(TaggedObject *object)
54     {
55         ASSERT(JSTaggedValue(object).IsTaggedArray());
56         return static_cast<AOTLiteralInfo *>(object);
57     }
58 
ComputeSize(uint32_t cacheSize)59     static size_t ComputeSize(uint32_t cacheSize)
60     {
61         return TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), cacheSize + RESERVED_LENGTH);
62     }
63 
64     inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t capacity, uint32_t extraLength = 0)
65     {
66         TaggedArray::InitializeWithSpecialValue(initValue, capacity + RESERVED_LENGTH, extraLength);
67         SetIhc(JSTaggedValue::Undefined());
68         SetChc(JSTaggedValue::Undefined());
69     }
70 
GetCacheLength()71     inline uint32_t GetCacheLength() const
72     {
73         return GetLength() - RESERVED_LENGTH;
74     }
75 
SetIhc(JSTaggedValue value)76     inline void SetIhc(JSTaggedValue value)
77     {
78         Barriers::SetPrimitive(GetData(), GetIhcOffset(), value.GetRawData());
79     }
80 
GetIhc()81     inline JSTaggedValue GetIhc() const
82     {
83         return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetIhcOffset()));
84     }
85 
SetChc(JSTaggedValue value)86     inline void SetChc(JSTaggedValue value)
87     {
88         Barriers::SetPrimitive(GetData(), GetChcOffset(), value.GetRawData());
89     }
90 
GetChc()91     inline JSTaggedValue GetChc() const
92     {
93         return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetChcOffset()));
94     }
95 
SetObjectToCache(JSThread * thread,uint32_t index,JSTaggedValue value)96     inline void SetObjectToCache(JSThread *thread, uint32_t index, JSTaggedValue value)
97     {
98         Set(thread, index, value);
99     }
100 
GetObjectFromCache(uint32_t index)101     inline JSTaggedValue GetObjectFromCache(uint32_t index) const
102     {
103         return Get(index);
104     }
105 private:
106     static constexpr size_t AOT_CHC_INDEX = 1;
107     static constexpr size_t AOT_IHC_INDEX = 2;
108     static constexpr size_t RESERVED_LENGTH = AOT_IHC_INDEX;
109 
GetIhcOffset()110     inline size_t GetIhcOffset() const
111     {
112         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_IHC_INDEX);
113     }
114 
GetChcOffset()115     inline size_t GetChcOffset() const
116     {
117         return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_CHC_INDEX);
118     }
119 };
120 
121 class AOTFileManager {
122 public:
123     explicit AOTFileManager(EcmaVM *vm);
124     virtual ~AOTFileManager();
125 
126     static constexpr char FILE_EXTENSION_AN[] = ".an";
127     static constexpr char FILE_EXTENSION_AI[] = ".ai";
128     static constexpr uint8_t DESERI_CP_ITEM_SIZE = 2;
129 
130     void LoadStubFile(const std::string &fileName);
131     static bool LoadAnFile(const std::string &fileName);
132     static AOTFileInfo::CallSiteInfo CalCallSiteInfo(uintptr_t retAddr);
133     static bool TryReadLock();
134     static bool InsideStub(uintptr_t pc);
135     static bool InsideAOT(uintptr_t pc);
136     void Iterate(const RootVisitor &v);
137 
138     const std::shared_ptr<AnFileInfo> GetAnFileInfo(const JSPandaFile *jsPandaFile) const;
139     bool IsLoad(const JSPandaFile *jsPandaFile) const;
140     bool IsLoadMain(const JSPandaFile *jsPandaFile, const CString &entry) const;
141     uint32_t GetAnFileIndex(const JSPandaFile *jsPandaFile) const;
142     void SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile,
143                              std::string_view entryPoint);
144     void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method,
145                          uint32_t entryIndex, bool *canFastCall = nullptr);
146     bool LoadAiFile([[maybe_unused]] const std::string &filename);
147     void LoadAiFile(const JSPandaFile *jsPandaFile);
148     kungfu::ArkStackMapParser* GetStackMapParser() const;
149     static JSTaggedValue GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal);
150     static bool GetAbsolutePath(const CString &relativePathCstr, CString &absPathCstr);
151     static bool RewriteDataSection(uintptr_t dataSec, size_t size, uintptr_t newData, size_t newSize);
152     void AddConstantPool(const CString &snapshotFileName, JSTaggedValue deserializedCPList);
153     JSHandle<JSTaggedValue> GetDeserializedConstantPool(const JSPandaFile *jsPandaFile, int32_t cpID);
154     const Heap *GetHeap();
155 
156     static void DumpAOTInfo() DUMP_API_ATTR;
157 
158 private:
159     static void PrintAOTEntry(const JSPandaFile *file, const Method *method, uintptr_t entry);
160     void InitializeStubEntries(const std::vector<AnFileInfo::FuncEntryDes>& stubs);
161     static void AdjustBCStubAndDebuggerStubEntries(JSThread *thread,
162                                                    const std::vector<AOTFileInfo::FuncEntryDes> &stubs,
163                                                    const AsmInterParsedOption &asmInterOpt);
164     EcmaVM *vm_ {nullptr};
165     ObjectFactory *factory_ {nullptr};
166     std::unordered_map<uint32_t, CMap<int32_t, JSTaggedValue>> desCPs_ {};
167     kungfu::ArkStackMapParser *arkStackMapParser_ {nullptr};
168 
169     friend class AnFileInfo;
170     friend class StubFileInfo;
171 };
172 }  // namespace panda::ecmascript
173 #endif // ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_MANAGER_H
174