1 /* 2 * Copyright (c) 2023-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_INFO_H 16 #define ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_INFO_H 17 18 #include "ecmascript/common.h" 19 #include "ecmascript/compiler/aot_file/executed_memory_allocator.h" 20 #include "ecmascript/compiler/aot_file/module_section_des.h" 21 #include "ecmascript/compiler/bc_call_signature.h" 22 #include "ecmascript/deoptimizer/calleeReg.h" 23 #include "ecmascript/compiler/aot_file/func_entry_des.h" 24 #include "ecmascript/stackmap/ark_stackmap.h" 25 26 namespace panda::ecmascript { 27 class PUBLIC_API AOTFileInfo { 28 public: 29 using FuncEntryDes = ecmascript::FuncEntryDes; 30 using CallSignature = kungfu::CallSignature; 31 using CalleeRegAndOffsetVec = kungfu::CalleeRegAndOffsetVec; 32 using DwarfRegType = kungfu::LLVMStackMapType::DwarfRegType; 33 using OffsetType = kungfu::LLVMStackMapType::OffsetType; 34 using DwarfRegAndOffsetType = kungfu::LLVMStackMapType::DwarfRegAndOffsetType; 35 AOTFileInfo() = default; 36 virtual ~AOTFileInfo() = default; 37 38 static constexpr uint32_t TEXT_SEC_ALIGN = 16; 39 static constexpr uint32_t DATA_SEC_ALIGN = 8; 40 static constexpr uint32_t PAGE_ALIGN = 4096; 41 GetStubDes(int index) const42 const FuncEntryDes &GetStubDes(int index) const 43 { 44 return entries_[index]; 45 } 46 GetEntrySize() const47 uint32_t GetEntrySize() const 48 { 49 return entries_.size(); 50 } 51 GetStubs() const52 const std::vector<FuncEntryDes> &GetStubs() const 53 { 54 return entries_; 55 } 56 GetCodeUnits() const57 const std::vector<ModuleSectionDes> &GetCodeUnits() const 58 { 59 return des_; 60 } 61 GetStubNum() const62 uint32_t GetStubNum() const 63 { 64 return entryNum_; 65 } 66 SetStubNum(uint32_t n)67 void SetStubNum(uint32_t n) 68 { 69 entryNum_ = n; 70 } 71 AddEntry(CallSignature::TargetKind kind, bool isMainFunc, bool isFastCall, int indexInKind, uint64_t offset, uint32_t fileIndex, uint32_t moduleIndex, int delta, uint32_t size, CalleeRegAndOffsetVec info = {})72 void AddEntry(CallSignature::TargetKind kind, bool isMainFunc, bool isFastCall, int indexInKind, uint64_t offset, 73 uint32_t fileIndex, uint32_t moduleIndex, int delta, uint32_t size, CalleeRegAndOffsetVec info = {}) 74 { 75 FuncEntryDes des; 76 if (memset_s(&des, sizeof(des), 0, sizeof(des)) != EOK) { 77 LOG_FULL(FATAL) << "memset_s failed"; 78 return; 79 } 80 des.kind_ = kind; 81 des.isMainFunc_ = isMainFunc; 82 des.isFastCall_ = isFastCall; 83 des.indexInKindOrMethodId_ = static_cast<uint32_t>(indexInKind); 84 des.abcIndexInAi_ = fileIndex; 85 des.codeAddr_ = offset; 86 des.moduleIndex_ = moduleIndex; 87 des.fpDeltaPrevFrameSp_ = delta; 88 des.funcSize_ = size; 89 des.calleeRegisterNum_ = info.size(); 90 DwarfRegType reg = 0; 91 OffsetType regOffset = 0; 92 for (size_t i = 0; i < info.size(); i++) { 93 std::tie(reg, regOffset) = info[i]; 94 des.CalleeReg2Offset_[2 * i] = static_cast<int32_t>(reg); 95 des.CalleeReg2Offset_[2 * i + 1] = static_cast<int32_t>(regOffset); 96 } 97 entries_.emplace_back(des); 98 } 99 GetModuleSectionDes() const100 const std::vector<ModuleSectionDes> &GetModuleSectionDes() const 101 { 102 return des_; 103 } 104 UpdateStackMap(std::shared_ptr<uint8_t> ptr, uint32_t size, uint32_t moduleIdx)105 void UpdateStackMap(std::shared_ptr<uint8_t> ptr, uint32_t size, uint32_t moduleIdx) 106 { 107 ASSERT(moduleIdx < des_.size()); 108 ModuleSectionDes &des = des_[moduleIdx]; 109 des.SetArkStackMapPtr(ptr); 110 des.SetArkStackMapSize(size); 111 } 112 113 size_t GetCodeUnitsNum() const 114 { 115 return des_.size(); 116 } 117 118 void accumulateTotalSize(uint32_t size) 119 { 120 totalCodeSize_ += size; 121 } 122 123 uint32_t GetTotalCodeSize() const 124 { 125 return totalCodeSize_; 126 } 127 128 using CallSiteInfo = std::tuple<uint64_t, uint8_t *, int, CalleeRegAndOffsetVec>; 129 130 bool CalCallSiteInfo(uintptr_t retAddr, CallSiteInfo &ret, bool isInStub, bool isDeopt) const; 131 132 virtual void Destroy(); 133 134 protected: 135 ExecutedMemoryAllocator::ExeMem &GetStubsMem() 136 { 137 return stubsMem_; 138 } 139 140 MemMap &GetFileMapMem() 141 { 142 return fileMapMem_; 143 } 144 145 uint32_t entryNum_ {0}; 146 uint32_t moduleNum_ {0}; 147 uint32_t totalCodeSize_ {0}; 148 std::vector<FuncEntryDes> entries_ {}; 149 std::vector<ModuleSectionDes> des_ {}; 150 ExecutedMemoryAllocator::ExeMem stubsMem_ {}; 151 MemMap fileMapMem_ {}; 152 153 private: 154 AOTFileInfo::FuncEntryDes GetFuncEntryDesWithCallsite(uintptr_t codeAddr, uint32_t startIndex, 155 uint32_t funcCount) const; 156 157 void StoreCalleeRegInfo(uint32_t calleeRegNum, int32_t *calleeReg2Offset, 158 CalleeRegAndOffsetVec &calleeRegInfo) const; 159 }; 160 } // namespace panda::ecmascript 161 #endif // ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_INFO_H 162