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