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 16#include "ecmascript/compiler/aot_file/aot_file_info.h" 17 18namespace panda::ecmascript { 19void AOTFileInfo::Destroy() 20{ 21 entryNum_ = 0; 22 moduleNum_ = 0; 23 totalCodeSize_ = 0; 24 entries_.clear(); 25 des_.clear(); 26 ExecutedMemoryAllocator::DestroyBuf(stubsMem_); 27} 28 29bool AOTFileInfo::CalCallSiteInfo(uintptr_t retAddr, std::tuple<uint64_t, uint8_t *, int, CalleeRegAndOffsetVec> &ret, 30 bool isInStub, bool isDeopt) const 31{ 32 uint64_t textStart = 0; 33 uint8_t *stackmapAddr = nullptr; 34 int delta = 0; 35 const auto &des = GetCodeUnits(); 36 37 size_t len = des.size(); 38 for (size_t i = 0; i < len; i++) { 39 auto &d = des[i]; 40 uint64_t addr = d.GetSecAddr(ElfSecName::TEXT); 41 uint32_t size = d.GetSecSize(ElfSecName::TEXT); 42 if (retAddr < addr || retAddr >= addr + size) { 43 continue; 44 } 45 46 stackmapAddr = d.GetArkStackMapRawPtr(); 47 ASSERT(stackmapAddr != nullptr); 48 textStart = addr; 49 CalleeRegAndOffsetVec calleeRegInfo; 50 if (!isInStub && !isDeopt) { // no need for getting funcEntryDes when not in stub nor in deopt 51 ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo); 52 return true; 53 } 54 55 ASSERT(retAddr > 0); 56 auto it = GetFuncEntryDesWithCallsite(retAddr - 1, d.GetStartIndex(), d.GetFuncCount()); // -1: for pc 57 delta = it.fpDeltaPrevFrameSp_; 58 if (!isDeopt) { // no need for getting calleeRegInfo when in stub but not in deopt 59 ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo); 60 return true; 61 } 62 63 StoreCalleeRegInfo(it.calleeRegisterNum_, it.CalleeReg2Offset_, calleeRegInfo); 64 ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo); 65 return true; 66 } 67 return false; 68} 69 70AOTFileInfo::FuncEntryDes AOTFileInfo::GetFuncEntryDesWithCallsite(uintptr_t codeAddr, uint32_t startIndex, 71 uint32_t funcCount) const 72{ 73 const auto &funcEntryDes = GetStubs(); 74 75 auto cmp = [](const AOTFileInfo::FuncEntryDes &a, const AOTFileInfo::FuncEntryDes &b) { 76 return a.codeAddr_ < b.codeAddr_; 77 }; 78 auto s = funcEntryDes.begin() + startIndex; 79 auto t = funcEntryDes.begin() + startIndex + funcCount; 80 AOTFileInfo::FuncEntryDes target; 81 target.codeAddr_ = codeAddr; 82 auto it = std::upper_bound(s, t, target, cmp); 83 --it; 84 ASSERT(it != t); 85 ASSERT((it->codeAddr_ <= target.codeAddr_) && (target.codeAddr_ < it->codeAddr_ + it->funcSize_)); 86 return *it; 87} 88 89void AOTFileInfo::StoreCalleeRegInfo(uint32_t calleeRegNum, int32_t *calleeReg2Offset, 90 CalleeRegAndOffsetVec &calleeRegInfo) const 91{ 92 for (uint32_t j = 0; j < calleeRegNum; j++) { 93 DwarfRegType reg = static_cast<DwarfRegType>(calleeReg2Offset[2 * j]); 94 OffsetType offset = static_cast<OffsetType>(calleeReg2Offset[2 * j + 1]); 95 DwarfRegAndOffsetType regAndOffset = std::make_pair(reg, offset); 96 calleeRegInfo.emplace_back(regAndOffset); 97 } 98} 99} // namespace panda::ecmascript 100