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