1 /* 2 * Copyright (c) 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_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 24 namespace panda::ecmascript { 25 class PUBLIC_API AOTFileInfo { 26 public: 27 using CallSignature = kungfu::CallSignature; 28 using CalleeRegAndOffsetVec = kungfu::CalleeRegAndOffsetVec; 29 using DwarfRegType = kungfu::LLVMStackMapType::DwarfRegType; 30 using OffsetType = kungfu::LLVMStackMapType::OffsetType; 31 using DwarfRegAndOffsetType = kungfu::LLVMStackMapType::DwarfRegAndOffsetType; 32 AOTFileInfo() = default; 33 virtual ~AOTFileInfo() = default; 34 35 static constexpr uint32_t TEXT_SEC_ALIGN = 16; 36 static constexpr uint32_t DATA_SEC_ALIGN = 8; 37 static constexpr uint32_t PAGE_ALIGN = 4096; 38 39 struct FuncEntryDes { 40 uint64_t codeAddr_ {}; 41 CallSignature::TargetKind kind_; 42 bool isMainFunc_ {}; 43 bool isFastCall_ {}; 44 uint32_t indexInKindOrMethodId_ {}; 45 uint32_t moduleIndex_ {}; 46 int fpDeltaPrevFrameSp_ {}; 47 uint32_t funcSize_ {}; 48 uint32_t calleeRegisterNum_ {}; 49 int32_t CalleeReg2Offset_[2 * kungfu::MAX_CALLEE_SAVE_REIGISTER_NUM]; IsStubFuncEntryDes50 bool IsStub() const 51 { 52 return CallSignature::TargetKind::STUB_BEGIN <= kind_ && kind_ < CallSignature::TargetKind::STUB_END; 53 } 54 IsBCStubFuncEntryDes55 bool IsBCStub() const 56 { 57 return CallSignature::TargetKind::BCHANDLER_BEGIN <= kind_ && 58 kind_ < CallSignature::TargetKind::BCHANDLER_END; 59 } 60 IsBCHandlerStubFuncEntryDes61 bool IsBCHandlerStub() const 62 { 63 return (kind_ == CallSignature::TargetKind::BYTECODE_HANDLER); 64 } 65 IsBuiltinsStubFuncEntryDes66 bool IsBuiltinsStub() const 67 { 68 return (kind_ == CallSignature::TargetKind::BUILTINS_STUB || 69 kind_ == CallSignature::TargetKind::BUILTINS_WITH_ARGV_STUB); 70 } 71 IsCommonStubFuncEntryDes72 bool IsCommonStub() const 73 { 74 return (kind_ == CallSignature::TargetKind::COMMON_STUB); 75 } 76 IsGeneralRTStubFuncEntryDes77 bool IsGeneralRTStub() const 78 { 79 return (kind_ >= CallSignature::TargetKind::RUNTIME_STUB && kind_ <= CallSignature::TargetKind::DEOPT_STUB); 80 } 81 }; 82 GetStubDes(int index)83 const FuncEntryDes &GetStubDes(int index) const 84 { 85 return entries_[index]; 86 } 87 GetEntrySize()88 uint32_t GetEntrySize() const 89 { 90 return entries_.size(); 91 } 92 GetStubs()93 const std::vector<FuncEntryDes> &GetStubs() const 94 { 95 return entries_; 96 } 97 GetCodeUnits()98 const std::vector<ModuleSectionDes> &GetCodeUnits() const 99 { 100 return des_; 101 } 102 GetStubNum()103 uint32_t GetStubNum() const 104 { 105 return entryNum_; 106 } 107 SetStubNum(uint32_t n)108 void SetStubNum(uint32_t n) 109 { 110 entryNum_ = n; 111 } 112 113 void AddEntry(CallSignature::TargetKind kind, bool isMainFunc, bool isFastCall, int indexInKind, uint64_t offset, 114 uint32_t moduleIndex, int delta, uint32_t size, CalleeRegAndOffsetVec info = {}) 115 { 116 FuncEntryDes des; 117 if (memset_s(&des, sizeof(des), 0, sizeof(des)) != EOK) { 118 LOG_FULL(FATAL) << "memset_s failed"; 119 return; 120 } 121 des.kind_ = kind; 122 des.isMainFunc_ = isMainFunc; 123 des.isFastCall_ = isFastCall; 124 des.indexInKindOrMethodId_ = static_cast<uint32_t>(indexInKind); 125 des.codeAddr_ = offset; 126 des.moduleIndex_ = moduleIndex; 127 des.fpDeltaPrevFrameSp_ = delta; 128 des.funcSize_ = size; 129 des.calleeRegisterNum_ = info.size(); 130 DwarfRegType reg = 0; 131 OffsetType regOffset = 0; 132 for (size_t i = 0; i < info.size(); i++) { 133 std::tie(reg, regOffset) = info[i]; 134 des.CalleeReg2Offset_[2 * i] = static_cast<int32_t>(reg); 135 des.CalleeReg2Offset_[2 * i + 1] = static_cast<int32_t>(regOffset); 136 } 137 entries_.emplace_back(des); 138 } 139 GetModuleSectionDes()140 const std::vector<ModuleSectionDes> &GetModuleSectionDes() const 141 { 142 return des_; 143 } 144 UpdateStackMap(std::shared_ptr<uint8_t> ptr,uint32_t size,uint32_t moduleIdx)145 void UpdateStackMap(std::shared_ptr<uint8_t> ptr, uint32_t size, uint32_t moduleIdx) 146 { 147 ASSERT(moduleIdx < des_.size()); 148 ModuleSectionDes &des = des_[moduleIdx]; 149 des.SetArkStackMapPtr(ptr); 150 des.SetArkStackMapSize(size); 151 } 152 GetCodeUnitsNum()153 size_t GetCodeUnitsNum() const 154 { 155 return des_.size(); 156 } 157 accumulateTotalSize(uint32_t size)158 void accumulateTotalSize(uint32_t size) 159 { 160 totalCodeSize_ += size; 161 } 162 GetTotalCodeSize()163 uint32_t GetTotalCodeSize() const 164 { 165 return totalCodeSize_; 166 } 167 168 using CallSiteInfo = std::tuple<uint64_t, uint8_t *, int, CalleeRegAndOffsetVec>; 169 170 bool CalCallSiteInfo(uintptr_t retAddr, CallSiteInfo &ret) const; 171 172 virtual void Destroy(); 173 174 protected: GetStubsMem()175 ExecutedMemoryAllocator::ExeMem &GetStubsMem() 176 { 177 return stubsMem_; 178 } 179 GetFileMapMem()180 MemMap &GetFileMapMem() 181 { 182 return fileMapMem_; 183 } 184 185 uint32_t entryNum_ {0}; 186 uint32_t moduleNum_ {0}; 187 uint32_t totalCodeSize_ {0}; 188 std::vector<FuncEntryDes> entries_ {}; 189 std::vector<ModuleSectionDes> des_ {}; 190 ExecutedMemoryAllocator::ExeMem stubsMem_ {}; 191 MemMap fileMapMem_ {}; 192 }; 193 } // namespace panda::ecmascript 194 #endif // ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_INFO_H 195