14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/aot_file_info.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_cinamespace panda::ecmascript {
194514f5e3Sopenharmony_civoid AOTFileInfo::Destroy()
204514f5e3Sopenharmony_ci{
214514f5e3Sopenharmony_ci    entryNum_ = 0;
224514f5e3Sopenharmony_ci    moduleNum_ = 0;
234514f5e3Sopenharmony_ci    totalCodeSize_ = 0;
244514f5e3Sopenharmony_ci    entries_.clear();
254514f5e3Sopenharmony_ci    des_.clear();
264514f5e3Sopenharmony_ci    ExecutedMemoryAllocator::DestroyBuf(stubsMem_);
274514f5e3Sopenharmony_ci}
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_cibool AOTFileInfo::CalCallSiteInfo(uintptr_t retAddr, std::tuple<uint64_t, uint8_t *, int, CalleeRegAndOffsetVec> &ret,
304514f5e3Sopenharmony_ci                                  bool isInStub, bool isDeopt) const
314514f5e3Sopenharmony_ci{
324514f5e3Sopenharmony_ci    uint64_t textStart = 0;
334514f5e3Sopenharmony_ci    uint8_t *stackmapAddr = nullptr;
344514f5e3Sopenharmony_ci    int delta = 0;
354514f5e3Sopenharmony_ci    const auto &des = GetCodeUnits();
364514f5e3Sopenharmony_ci
374514f5e3Sopenharmony_ci    size_t len = des.size();
384514f5e3Sopenharmony_ci    for (size_t i = 0; i < len; i++) {
394514f5e3Sopenharmony_ci        auto &d = des[i];
404514f5e3Sopenharmony_ci        uint64_t addr = d.GetSecAddr(ElfSecName::TEXT);
414514f5e3Sopenharmony_ci        uint32_t size = d.GetSecSize(ElfSecName::TEXT);
424514f5e3Sopenharmony_ci        if (retAddr < addr || retAddr >= addr + size) {
434514f5e3Sopenharmony_ci            continue;
444514f5e3Sopenharmony_ci        }
454514f5e3Sopenharmony_ci
464514f5e3Sopenharmony_ci        stackmapAddr = d.GetArkStackMapRawPtr();
474514f5e3Sopenharmony_ci        ASSERT(stackmapAddr != nullptr);
484514f5e3Sopenharmony_ci        textStart = addr;
494514f5e3Sopenharmony_ci        CalleeRegAndOffsetVec calleeRegInfo;
504514f5e3Sopenharmony_ci        if (!isInStub && !isDeopt) {  // no need for getting funcEntryDes when not in stub nor in deopt
514514f5e3Sopenharmony_ci            ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo);
524514f5e3Sopenharmony_ci            return true;
534514f5e3Sopenharmony_ci        }
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ci        ASSERT(retAddr > 0);
564514f5e3Sopenharmony_ci        auto it = GetFuncEntryDesWithCallsite(retAddr - 1, d.GetStartIndex(), d.GetFuncCount());  // -1: for pc
574514f5e3Sopenharmony_ci        delta = it.fpDeltaPrevFrameSp_;
584514f5e3Sopenharmony_ci        if (!isDeopt) {  // no need for getting calleeRegInfo when in stub but not in deopt
594514f5e3Sopenharmony_ci            ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo);
604514f5e3Sopenharmony_ci            return true;
614514f5e3Sopenharmony_ci        }
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ci        StoreCalleeRegInfo(it.calleeRegisterNum_, it.CalleeReg2Offset_, calleeRegInfo);
644514f5e3Sopenharmony_ci        ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo);
654514f5e3Sopenharmony_ci        return true;
664514f5e3Sopenharmony_ci    }
674514f5e3Sopenharmony_ci    return false;
684514f5e3Sopenharmony_ci}
694514f5e3Sopenharmony_ci
704514f5e3Sopenharmony_ciAOTFileInfo::FuncEntryDes AOTFileInfo::GetFuncEntryDesWithCallsite(uintptr_t codeAddr, uint32_t startIndex,
714514f5e3Sopenharmony_ci                                                                   uint32_t funcCount) const
724514f5e3Sopenharmony_ci{
734514f5e3Sopenharmony_ci    const auto &funcEntryDes = GetStubs();
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ci    auto cmp = [](const AOTFileInfo::FuncEntryDes &a, const AOTFileInfo::FuncEntryDes &b) {
764514f5e3Sopenharmony_ci        return a.codeAddr_ < b.codeAddr_;
774514f5e3Sopenharmony_ci    };
784514f5e3Sopenharmony_ci    auto s = funcEntryDes.begin() + startIndex;
794514f5e3Sopenharmony_ci    auto t = funcEntryDes.begin() + startIndex + funcCount;
804514f5e3Sopenharmony_ci    AOTFileInfo::FuncEntryDes target;
814514f5e3Sopenharmony_ci    target.codeAddr_ = codeAddr;
824514f5e3Sopenharmony_ci    auto it = std::upper_bound(s, t, target, cmp);
834514f5e3Sopenharmony_ci    --it;
844514f5e3Sopenharmony_ci    ASSERT(it != t);
854514f5e3Sopenharmony_ci    ASSERT((it->codeAddr_ <= target.codeAddr_) && (target.codeAddr_ < it->codeAddr_ + it->funcSize_));
864514f5e3Sopenharmony_ci    return *it;
874514f5e3Sopenharmony_ci}
884514f5e3Sopenharmony_ci
894514f5e3Sopenharmony_civoid AOTFileInfo::StoreCalleeRegInfo(uint32_t calleeRegNum, int32_t *calleeReg2Offset,
904514f5e3Sopenharmony_ci                                     CalleeRegAndOffsetVec &calleeRegInfo) const
914514f5e3Sopenharmony_ci{
924514f5e3Sopenharmony_ci    for (uint32_t j = 0; j < calleeRegNum; j++) {
934514f5e3Sopenharmony_ci        DwarfRegType reg = static_cast<DwarfRegType>(calleeReg2Offset[2 * j]);
944514f5e3Sopenharmony_ci        OffsetType offset = static_cast<OffsetType>(calleeReg2Offset[2 * j + 1]);
954514f5e3Sopenharmony_ci        DwarfRegAndOffsetType regAndOffset = std::make_pair(reg, offset);
964514f5e3Sopenharmony_ci        calleeRegInfo.emplace_back(regAndOffset);
974514f5e3Sopenharmony_ci    }
984514f5e3Sopenharmony_ci}
994514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
100