mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
Optimize arkstackmap size and add stackmap dump
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6E00K Signed-off-by: wuzhangda <wuzhangda@huawei.com> Change-Id: I9961aca3de3da6a727b48bf848bb7338465b0f6f
This commit is contained in:
parent
a051f661ca
commit
682f28bf73
1
BUILD.gn
1
BUILD.gn
@ -726,6 +726,7 @@ ecma_source = [
|
||||
"ecmascript/stackmap/ark_stackmap_builder.cpp",
|
||||
"ecmascript/stackmap/ark_stackmap_parser.cpp",
|
||||
"ecmascript/stackmap/llvm_stackmap_parser.cpp",
|
||||
"ecmascript/stackmap/llvm_stackmap_type.cpp",
|
||||
"ecmascript/subtyping_operator.cpp",
|
||||
"ecmascript/taskpool/taskpool.cpp",
|
||||
"ecmascript/taskpool/runner.cpp",
|
||||
|
@ -288,7 +288,6 @@ bool AnFileInfo::Load(const std::string &filename)
|
||||
}
|
||||
|
||||
fileMapMem_ = FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ);
|
||||
|
||||
if (fileMapMem_.GetOriginAddr() == nullptr) {
|
||||
LOG_ECMA(ERROR) << "File mmap failed";
|
||||
return false;
|
||||
@ -790,7 +789,7 @@ void AOTFileInfo::Destroy()
|
||||
}
|
||||
|
||||
bool AOTFileInfo::CalCallSiteInfo(uintptr_t retAddr,
|
||||
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec>& ret) const
|
||||
std::tuple<uint64_t, uint8_t *, int, CalleeRegAndOffsetVec>& ret) const
|
||||
{
|
||||
uint64_t textStart = 0;
|
||||
uint8_t *stackmapAddr = nullptr;
|
||||
@ -823,11 +822,11 @@ bool AOTFileInfo::CalCallSiteInfo(uintptr_t retAddr,
|
||||
ASSERT(it != t);
|
||||
ASSERT((it->codeAddr_ <= target.codeAddr_) && (target.codeAddr_ < it->codeAddr_ + it->funcSize_));
|
||||
delta = it->fpDeltaPrevFrameSp_;
|
||||
kungfu::CalleeRegAndOffsetVec calleeRegInfo;
|
||||
CalleeRegAndOffsetVec calleeRegInfo;
|
||||
for (uint32_t j = 0; j < it->calleeRegisterNum_; j++) {
|
||||
kungfu::DwarfRegType reg = static_cast<kungfu::DwarfRegType>(it->CalleeReg2Offset_[2 * j]);
|
||||
kungfu::OffsetType offset = static_cast<kungfu::OffsetType>(it->CalleeReg2Offset_[2 * j + 1]);
|
||||
kungfu::DwarfRegAndOffsetType regAndOffset = std::make_pair(reg, offset);
|
||||
DwarfRegType reg = static_cast<DwarfRegType>(it->CalleeReg2Offset_[2 * j]);
|
||||
OffsetType offset = static_cast<OffsetType>(it->CalleeReg2Offset_[2 * j + 1]);
|
||||
DwarfRegAndOffsetType regAndOffset = std::make_pair(reg, offset);
|
||||
calleeRegInfo.emplace_back(regAndOffset);
|
||||
}
|
||||
ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo);
|
||||
|
@ -182,6 +182,10 @@ private:
|
||||
class PUBLIC_API AOTFileInfo {
|
||||
public:
|
||||
using CallSignature = kungfu::CallSignature;
|
||||
using CalleeRegAndOffsetVec = kungfu::CalleeRegAndOffsetVec;
|
||||
using DwarfRegType = kungfu::LLVMStackMapType::DwarfRegType;
|
||||
using OffsetType = kungfu::LLVMStackMapType::OffsetType;
|
||||
using DwarfRegAndOffsetType = kungfu::LLVMStackMapType::DwarfRegAndOffsetType;
|
||||
AOTFileInfo() = default;
|
||||
virtual ~AOTFileInfo() = default;
|
||||
|
||||
@ -260,7 +264,7 @@ public:
|
||||
}
|
||||
|
||||
void AddEntry(CallSignature::TargetKind kind, bool isMainFunc, int indexInKind, uint64_t offset,
|
||||
uint32_t moduleIndex, int delta, uint32_t size, kungfu::CalleeRegAndOffsetVec info = {})
|
||||
uint32_t moduleIndex, int delta, uint32_t size, CalleeRegAndOffsetVec info = {})
|
||||
{
|
||||
FuncEntryDes des;
|
||||
if (memset_s(&des, sizeof(des), 0, sizeof(des)) != EOK) {
|
||||
@ -275,8 +279,8 @@ public:
|
||||
des.fpDeltaPrevFrameSp_ = delta;
|
||||
des.funcSize_ = size;
|
||||
des.calleeRegisterNum_ = info.size();
|
||||
kungfu::DwarfRegType reg = 0;
|
||||
kungfu::OffsetType regOffset = 0;
|
||||
DwarfRegType reg = 0;
|
||||
OffsetType regOffset = 0;
|
||||
for (size_t i = 0; i < info.size(); i ++) {
|
||||
std::tie(reg, regOffset) = info[i];
|
||||
des.CalleeReg2Offset_[2 * i] = static_cast<int32_t>(reg);
|
||||
@ -300,7 +304,7 @@ public:
|
||||
totalCodeSize_ += size;
|
||||
}
|
||||
|
||||
using CallSiteInfo = std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec>;
|
||||
using CallSiteInfo = std::tuple<uint64_t, uint8_t *, int, CalleeRegAndOffsetVec>;
|
||||
|
||||
bool CalCallSiteInfo(uintptr_t retAddr, CallSiteInfo& ret) const;
|
||||
|
||||
|
@ -351,7 +351,6 @@ Section Headers:
|
||||
*/
|
||||
void ElfBuilder::PackELFSections(std::ofstream &file)
|
||||
{
|
||||
|
||||
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = sectionDes_.sectionsInfo_;
|
||||
uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section
|
||||
std::unique_ptr<llvm::ELF::Elf64_Shdr []> shdr = std::make_unique<llvm::ELF::Elf64_Shdr []>(secNum);
|
||||
@ -440,7 +439,7 @@ void ElfBuilder::PackELFSegment(std::ofstream &file)
|
||||
{
|
||||
llvm::ELF::Elf64_Off e_phoff = file.tellp();
|
||||
long phoff = (long)offsetof(struct llvm::ELF::Elf64_Ehdr, e_phoff);
|
||||
// write Elf32_Off e_phoff;
|
||||
// write Elf32_Off e_phoff
|
||||
file.seekp(phoff);
|
||||
file.write(reinterpret_cast<char *>(&e_phoff), sizeof(e_phoff));
|
||||
file.seekp(e_phoff);
|
||||
|
@ -39,6 +39,46 @@ public:
|
||||
static constexpr int SP = -1;
|
||||
static constexpr int FP = -1;
|
||||
#endif
|
||||
|
||||
static int GetFpRegByTriple(Triple triple)
|
||||
{
|
||||
int fp = -1;
|
||||
switch (triple) {
|
||||
case Triple::TRIPLE_AMD64:
|
||||
fp = 6;
|
||||
break;
|
||||
case Triple::TRIPLE_ARM32:
|
||||
fp = 11;
|
||||
break;
|
||||
case Triple::TRIPLE_AARCH64:
|
||||
fp = 29;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
static int GetSpRegByTriple(Triple triple)
|
||||
{
|
||||
int sp = -1;
|
||||
switch (triple) {
|
||||
case Triple::TRIPLE_AMD64:
|
||||
sp = 7;
|
||||
break;
|
||||
case Triple::TRIPLE_ARM32:
|
||||
sp = 13;
|
||||
break;
|
||||
case Triple::TRIPLE_AARCH64:
|
||||
sp = 31;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
};
|
||||
|
||||
enum Distance {
|
||||
|
@ -100,8 +100,8 @@ public:
|
||||
|
||||
bool ShouldDumpToAOTFile() const
|
||||
{
|
||||
bool saveForAot = false;
|
||||
switch (value_) {
|
||||
bool saveForAot = false;
|
||||
switch (value_) {
|
||||
case ElfSecName::RODATA:
|
||||
case ElfSecName::RODATA_CST4:
|
||||
case ElfSecName::RODATA_CST8:
|
||||
@ -119,8 +119,8 @@ public:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return saveForAot;
|
||||
}
|
||||
return saveForAot;
|
||||
}
|
||||
|
||||
ElfSecName Value() const
|
||||
@ -144,20 +144,20 @@ public:
|
||||
void InitShTypeAndFlag()
|
||||
{
|
||||
std::map<ElfSecName, std::pair<unsigned, unsigned>> nameToTypeAndFlag = {
|
||||
{ElfSecName::RODATA, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE)},
|
||||
{ElfSecName::RODATA_CST4, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE)},
|
||||
{ElfSecName::RODATA_CST8, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE)},
|
||||
{ElfSecName::RODATA_CST16, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE)},
|
||||
{ElfSecName::RODATA_CST32, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE)},
|
||||
{ElfSecName::TEXT, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR)},
|
||||
{ElfSecName::DATA, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE)},
|
||||
{ElfSecName::GOT, std::pair<unsigned, unsigned>(llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE)},
|
||||
{ElfSecName::RELATEXT, std::pair<unsigned, unsigned>(llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE)},
|
||||
{ElfSecName::STRTAB, std::pair<unsigned, unsigned>(llvm::ELF::SHT_STRTAB, llvm::ELF::SHF_ALLOC)},
|
||||
{ElfSecName::SYMTAB, std::pair<unsigned, unsigned>(llvm::ELF::SHT_SYMTAB, llvm::ELF::SHF_ALLOC)},
|
||||
{ElfSecName::LLVM_STACKMAP, std::pair<unsigned, unsigned>(llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC)},
|
||||
{ElfSecName::ARK_FUNCENTRY, std::pair<unsigned, unsigned>(llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC)},
|
||||
{ElfSecName::ARK_STACKMAP, std::pair<unsigned, unsigned>(llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC)},
|
||||
{ElfSecName::RODATA, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::RODATA_CST4, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::RODATA_CST8, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::RODATA_CST16, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::RODATA_CST32, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::TEXT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}},
|
||||
{ElfSecName::DATA, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}},
|
||||
{ElfSecName::GOT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}},
|
||||
{ElfSecName::RELATEXT, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}},
|
||||
{ElfSecName::STRTAB, {llvm::ELF::SHT_STRTAB, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::SYMTAB, {llvm::ELF::SHT_SYMTAB, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::LLVM_STACKMAP, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::ARK_FUNCENTRY, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::ARK_STACKMAP, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}},
|
||||
};
|
||||
auto it = nameToTypeAndFlag.find(value_);
|
||||
if (it == nameToTypeAndFlag.end()) {
|
||||
|
@ -35,12 +35,17 @@ void Module::CollectStackMapDes(ModuleSectionDes& des) const
|
||||
std::shared_ptr<uint8_t> ptr = nullptr;
|
||||
uint32_t size = 0;
|
||||
ArkStackMapBuilder builder;
|
||||
std::tie(ptr, size) = builder.Run(std::move(stackmapPtr), textAddr);
|
||||
std::tie(ptr, size) = builder.Run(std::move(stackmapPtr), textAddr, GetTriple());
|
||||
des.EraseSec(ElfSecName::LLVM_STACKMAP);
|
||||
des.SetArkStackMapPtr(ptr);
|
||||
des.SetArkStackMapSize(size);
|
||||
}
|
||||
|
||||
Triple Module::GetTriple() const
|
||||
{
|
||||
return llvmModule_->GetCompilationConfig()->GetTriple();
|
||||
}
|
||||
|
||||
void Module::CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, StubFileInfo &stubInfo,
|
||||
uint32_t moduleIndex, const CompilerLog &log)
|
||||
{
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
|
||||
void CollectStackMapDes(ModuleSectionDes &moduleDes) const;
|
||||
|
||||
Triple GetTriple() const;
|
||||
|
||||
const CompilationConfig *GetCompilationConfig()
|
||||
{
|
||||
return llvmModule_->GetCompilationConfig();
|
||||
|
@ -52,7 +52,7 @@ CalleeReg::CalleeReg()
|
||||
#endif
|
||||
}
|
||||
|
||||
int CalleeReg::FindCallRegOrder(const DwarfRegType reg) const
|
||||
int CalleeReg::FindCallRegOrder(const LLVMStackMapType::DwarfRegType reg) const
|
||||
{
|
||||
auto it = reg2Location_.find(static_cast<DwarfReg>(reg));
|
||||
if (it != reg2Location_.end()) {
|
||||
@ -65,7 +65,7 @@ int CalleeReg::FindCallRegOrder(const DwarfRegType reg) const
|
||||
|
||||
int CalleeReg::FindCallRegOrder(const DwarfReg reg) const
|
||||
{
|
||||
auto order = FindCallRegOrder(static_cast<DwarfRegType>(reg));
|
||||
auto order = FindCallRegOrder(static_cast<LLVMStackMapType::DwarfRegType>(reg));
|
||||
return order;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace panda::ecmascript::kungfu {
|
||||
#if defined(PANDA_TARGET_AMD64)
|
||||
static const int MAX_CALLEE_SAVE_REIGISTER_NUM = 32;
|
||||
enum class DwarfReg: DwarfRegType {
|
||||
enum class DwarfReg: LLVMStackMapType::DwarfRegType {
|
||||
RBX = 3,
|
||||
R12 = 12,
|
||||
R13 = 13,
|
||||
@ -31,7 +31,7 @@ enum class DwarfReg: DwarfRegType {
|
||||
};
|
||||
#elif defined(PANDA_TARGET_ARM64)
|
||||
static const int MAX_CALLEE_SAVE_REIGISTER_NUM = 32;
|
||||
enum class DwarfReg: DwarfRegType {
|
||||
enum class DwarfReg: LLVMStackMapType::DwarfRegType {
|
||||
D8 = 72,
|
||||
D9 = 73,
|
||||
D10 = 74,
|
||||
@ -54,14 +54,14 @@ enum class DwarfReg: DwarfRegType {
|
||||
};
|
||||
#else
|
||||
static const int MAX_CALLEE_SAVE_REIGISTER_NUM = 16;
|
||||
enum class DwarfReg: DwarfRegType {
|
||||
enum class DwarfReg: LLVMStackMapType::DwarfRegType {
|
||||
};
|
||||
#endif
|
||||
class CalleeReg {
|
||||
public:
|
||||
PUBLIC_API CalleeReg();
|
||||
virtual PUBLIC_API ~CalleeReg() = default;
|
||||
int PUBLIC_API FindCallRegOrder(const DwarfRegType reg) const;
|
||||
int PUBLIC_API FindCallRegOrder(const LLVMStackMapType::DwarfRegType reg) const;
|
||||
int PUBLIC_API FindCallRegOrder(const DwarfReg reg) const;
|
||||
int PUBLIC_API GetCallRegNum() const;
|
||||
private:
|
||||
|
@ -69,18 +69,18 @@ private:
|
||||
JSTaggedType *top_;
|
||||
};
|
||||
|
||||
void Deoptimizier::CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle)
|
||||
void Deoptimizier::CollectVregs(const std::vector<ARKDeopt>& deoptBundle)
|
||||
{
|
||||
deoptVregs_.clear();
|
||||
for (size_t i = 0; i < deoptBundle.size(); i++) {
|
||||
kungfu::ARKDeopt deopt = deoptBundle.at(i);
|
||||
ARKDeopt deopt = deoptBundle.at(i);
|
||||
JSTaggedType v;
|
||||
kungfu::OffsetType id = deopt.Id;
|
||||
if (std::holds_alternative<kungfu::DwarfRegAndOffsetType>(deopt.value)) {
|
||||
ASSERT(deopt.kind == kungfu::LocationTy::Kind::INDIRECT);
|
||||
auto value = std::get<kungfu::DwarfRegAndOffsetType>(deopt.value);
|
||||
kungfu::DwarfRegType dwarfReg = value.first;
|
||||
kungfu::OffsetType offset = value.second;
|
||||
VRegId id = deopt.id;
|
||||
if (std::holds_alternative<DwarfRegAndOffsetType>(deopt.value)) {
|
||||
ASSERT(deopt.kind == LocationTy::Kind::INDIRECT);
|
||||
auto value = std::get<DwarfRegAndOffsetType>(deopt.value);
|
||||
DwarfRegType dwarfReg = value.first;
|
||||
OffsetType offset = value.second;
|
||||
ASSERT (dwarfReg == GCStackMapRegisters::FP || dwarfReg == GCStackMapRegisters::SP);
|
||||
uintptr_t addr;
|
||||
if (dwarfReg == GCStackMapRegisters::SP) {
|
||||
@ -89,16 +89,16 @@ void Deoptimizier::CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle
|
||||
addr = context_.callsiteFp + offset;
|
||||
}
|
||||
v = *(reinterpret_cast<JSTaggedType *>(addr));
|
||||
} else if (std::holds_alternative<kungfu::LargeInt>(deopt.value)) {
|
||||
ASSERT(deopt.kind == kungfu::LocationTy::Kind::CONSTANTNDEX);
|
||||
v = JSTaggedType(static_cast<int64_t>(std::get<kungfu::LargeInt>(deopt.value)));
|
||||
} else if (std::holds_alternative<LargeInt>(deopt.value)) {
|
||||
ASSERT(deopt.kind == LocationTy::Kind::CONSTANTNDEX);
|
||||
v = JSTaggedType(static_cast<int64_t>(std::get<LargeInt>(deopt.value)));
|
||||
} else {
|
||||
ASSERT(std::holds_alternative<kungfu::OffsetType>(deopt.value));
|
||||
ASSERT(deopt.kind == kungfu::LocationTy::Kind::CONSTANT);
|
||||
v = JSTaggedType(static_cast<int64_t>(std::get<kungfu::OffsetType>(deopt.value)));
|
||||
ASSERT(std::holds_alternative<IntType>(deopt.value));
|
||||
ASSERT(deopt.kind == LocationTy::Kind::CONSTANT);
|
||||
v = JSTaggedType(static_cast<int64_t>(std::get<IntType>(deopt.value)));
|
||||
}
|
||||
if (id != static_cast<kungfu::OffsetType>(SpecVregIndex::PC_OFFSET_INDEX)) {
|
||||
if (id == static_cast<kungfu::OffsetType>(SpecVregIndex::ENV_INDEX)) {
|
||||
if (id != static_cast<VRegId>(SpecVregIndex::PC_OFFSET_INDEX)) {
|
||||
if (id == static_cast<VRegId>(SpecVregIndex::ENV_INDEX)) {
|
||||
env_ = JSTaggedValue(v);
|
||||
} else {
|
||||
deoptVregs_[id] = JSTaggedValue(v);
|
||||
@ -155,7 +155,7 @@ void Deoptimizier::CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle
|
||||
// | ......... | v
|
||||
// |--------------------------| ---------------
|
||||
|
||||
void Deoptimizier::CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBundle)
|
||||
void Deoptimizier::CollectDeoptBundleVec(std::vector<ARKDeopt>& deoptBundle)
|
||||
{
|
||||
JSTaggedType *lastLeave = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
|
||||
FrameIterator it(lastLeave, thread_);
|
||||
@ -166,7 +166,7 @@ void Deoptimizier::CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBun
|
||||
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
|
||||
auto frame = it.GetFrame<OptimizedJSFunctionFrame>();
|
||||
frame->GetDeoptBundleInfo(it, deoptBundle);
|
||||
kungfu::CalleeRegAndOffsetVec calleeRegInfo;
|
||||
CalleeRegAndOffsetVec calleeRegInfo;
|
||||
frame->GetFuncCalleeRegAndOffset(it, calleeRegInfo);
|
||||
context_.calleeRegAndOffset = calleeRegInfo;
|
||||
context_.callsiteSp = it.GetCallSiteSp();
|
||||
@ -208,7 +208,7 @@ Method* Deoptimizier::GetMethod(JSTaggedValue &target)
|
||||
|
||||
void Deoptimizier::RelocateCalleeSave()
|
||||
{
|
||||
kungfu::CalleeReg callreg;
|
||||
CalleeReg callreg;
|
||||
for (auto &it: context_.calleeRegAndOffset) {
|
||||
auto reg = it.first;
|
||||
auto offset = it.second;
|
||||
@ -249,7 +249,7 @@ bool Deoptimizier::CollectVirtualRegisters(Method* method, FrameWriter *frameWri
|
||||
JSTaggedValue value = JSTaggedValue::Undefined();
|
||||
// deopt value
|
||||
if (HasDeoptValue(virtualIndex)) {
|
||||
value = deoptVregs_.at(static_cast<kungfu::OffsetType>(virtualIndex));
|
||||
value = deoptVregs_.at(static_cast<VRegId>(virtualIndex));
|
||||
} else {
|
||||
value = GetActualFrameArgs(i);
|
||||
}
|
||||
@ -259,17 +259,17 @@ bool Deoptimizier::CollectVirtualRegisters(Method* method, FrameWriter *frameWri
|
||||
|
||||
// [reserved args]
|
||||
if (method->HaveThisWithCallField()) {
|
||||
JSTaggedValue value = deoptVregs_.at(static_cast<kungfu::OffsetType>(SpecVregIndex::THIS_OBJECT_INDEX));
|
||||
JSTaggedValue value = deoptVregs_.at(static_cast<VRegId>(SpecVregIndex::THIS_OBJECT_INDEX));
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
if (method->HaveNewTargetWithCallField()) {
|
||||
JSTaggedValue value = deoptVregs_.at(static_cast<kungfu::OffsetType>(SpecVregIndex::NEWTARGET_INDEX));
|
||||
JSTaggedValue value = deoptVregs_.at(static_cast<VRegId>(SpecVregIndex::NEWTARGET_INDEX));
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
if (method->HaveFuncWithCallField()) {
|
||||
JSTaggedValue value = deoptVregs_.at(static_cast<kungfu::OffsetType>(SpecVregIndex::FUNC_INDEX));
|
||||
JSTaggedValue value = deoptVregs_.at(static_cast<VRegId>(SpecVregIndex::FUNC_INDEX));
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
@ -283,7 +283,7 @@ bool Deoptimizier::CollectVirtualRegisters(Method* method, FrameWriter *frameWri
|
||||
return true;
|
||||
}
|
||||
|
||||
void Deoptimizier::Dump(Method* method, kungfu::DeoptType type)
|
||||
void Deoptimizier::Dump(Method* method, DeoptType type)
|
||||
{
|
||||
if (traceDeopt_) {
|
||||
std::string checkType = DisplayItems(type);
|
||||
@ -296,40 +296,40 @@ void Deoptimizier::Dump(Method* method, kungfu::DeoptType type)
|
||||
}
|
||||
}
|
||||
|
||||
std::string Deoptimizier::DisplayItems(kungfu::DeoptType type)
|
||||
std::string Deoptimizier::DisplayItems(DeoptType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kungfu::DeoptType::NOTINT:
|
||||
case DeoptType::NOTINT:
|
||||
return "NOT INT";
|
||||
case kungfu::DeoptType::DIVZERO:
|
||||
case DeoptType::DIVZERO:
|
||||
return "DIV ZERO";
|
||||
case kungfu::DeoptType::NOTDOUBLE:
|
||||
case DeoptType::NOTDOUBLE:
|
||||
return "NOT DOUBLE";
|
||||
case kungfu::DeoptType::NOTNUMBER:
|
||||
case DeoptType::NOTNUMBER:
|
||||
return "NOT NUMBER";
|
||||
case kungfu::DeoptType::NOTBOOL:
|
||||
case DeoptType::NOTBOOL:
|
||||
return "NOT BOOL";
|
||||
case kungfu::DeoptType::NOTHEAPOBJECT:
|
||||
case DeoptType::NOTHEAPOBJECT:
|
||||
return "NOT HEAP OBJECT";
|
||||
case kungfu::DeoptType::NOTSARRAY:
|
||||
case DeoptType::NOTSARRAY:
|
||||
return "NOT SARRAY";
|
||||
case kungfu::DeoptType::NOTF32ARRAY:
|
||||
case DeoptType::NOTF32ARRAY:
|
||||
return "NOT F32ARRAY";
|
||||
case kungfu::DeoptType::INCONSISTENTHCLASS:
|
||||
case DeoptType::INCONSISTENTHCLASS:
|
||||
return "INCONSISTENT HCLASS";
|
||||
case kungfu::DeoptType::NOTNEWOBJ:
|
||||
return "NOT NEWOBJ TYPE";
|
||||
case kungfu::DeoptType::NOTARRAYIDX:
|
||||
case DeoptType::NOTARRAYIDX:
|
||||
return "NOT ARRAY IDX";
|
||||
case kungfu::DeoptType::NOTF32ARRAYIDX:
|
||||
case DeoptType::NOTF32ARRAYIDX:
|
||||
return "NOT F32 ARRAY IDX";
|
||||
case kungfu::DeoptType::NOTINCOV:
|
||||
case DeoptType::NOTINCOV:
|
||||
return "NOT INC OVERFLOW";
|
||||
case kungfu::DeoptType::NOTDECOV:
|
||||
case DeoptType::NOTDECOV:
|
||||
return "NOT DEC OVERFLOW";
|
||||
case kungfu::DeoptType::NOTNEGOV:
|
||||
case DeoptType::NOTNEGOV:
|
||||
return "NOT NEG OVERFLOW";
|
||||
case kungfu::DeoptType::NOTCALLTGT:
|
||||
case DeoptType::NOTCALLTGT:
|
||||
return "NOT CALL TARGET";
|
||||
default: {
|
||||
return "NOT CHECK";
|
||||
@ -337,7 +337,7 @@ std::string Deoptimizier::DisplayItems(kungfu::DeoptType type)
|
||||
}
|
||||
}
|
||||
|
||||
JSTaggedType Deoptimizier::ConstructAsmInterpretFrame(kungfu::DeoptType type)
|
||||
JSTaggedType Deoptimizier::ConstructAsmInterpretFrame(DeoptType type)
|
||||
{
|
||||
JSTaggedValue callTarget = GetDeoptValue(static_cast<int32_t>(SpecVregIndex::FUNC_INDEX));
|
||||
auto method = GetMethod(callTarget);
|
||||
|
@ -90,17 +90,30 @@ struct AsmStackContext : public base::AlignedStruct<base::AlignedPointer::Size()
|
||||
class FrameWriter;
|
||||
class Deoptimizier {
|
||||
public:
|
||||
using ARKDeopt = kungfu::ARKDeopt;
|
||||
using CalleeReg = kungfu::CalleeReg;
|
||||
using CalleeRegAndOffsetVec = kungfu::CalleeRegAndOffsetVec;
|
||||
using CommonArgIdx = kungfu::CommonArgIdx;
|
||||
using DeoptType = kungfu::DeoptType;
|
||||
using DwarfRegType = kungfu::LLVMStackMapType::DwarfRegType;
|
||||
using DwarfRegAndOffsetType = kungfu::LLVMStackMapType::DwarfRegAndOffsetType;
|
||||
using IntType = kungfu::LLVMStackMapType::IntType;
|
||||
using LargeInt = kungfu::LLVMStackMapType::LargeInt;
|
||||
using LocationTy = kungfu::LocationTy;
|
||||
using OffsetType = kungfu::LLVMStackMapType::OffsetType;
|
||||
using VRegId = kungfu::LLVMStackMapType::VRegId;
|
||||
|
||||
explicit Deoptimizier(JSThread *thread) : thread_(thread)
|
||||
{
|
||||
kungfu::CalleeReg callreg;
|
||||
CalleeReg callreg;
|
||||
numCalleeRegs_ = static_cast<size_t>(callreg.GetCallRegNum());
|
||||
JSRuntimeOptions options = thread_->GetEcmaVM()->GetJSOptions();
|
||||
traceDeopt_ = options.GetTraceDeopt();
|
||||
}
|
||||
void CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle);
|
||||
void CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBundle);
|
||||
JSTaggedType ConstructAsmInterpretFrame(kungfu::DeoptType type);
|
||||
static std::string DisplayItems(kungfu::DeoptType type);
|
||||
void CollectVregs(const std::vector<ARKDeopt>& deoptBundle);
|
||||
void CollectDeoptBundleVec(std::vector<ARKDeopt>& deoptBundle);
|
||||
JSTaggedType ConstructAsmInterpretFrame(DeoptType type);
|
||||
static std::string DisplayItems(DeoptType type);
|
||||
|
||||
JSThread *GetThread() const
|
||||
{
|
||||
@ -113,9 +126,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
size_t GetFrameIndex(kungfu::CommonArgIdx index)
|
||||
size_t GetFrameIndex(CommonArgIdx index)
|
||||
{
|
||||
return static_cast<size_t>(index) - static_cast<size_t>(kungfu::CommonArgIdx::FUNC);
|
||||
return static_cast<size_t>(index) - static_cast<size_t>(CommonArgIdx::FUNC);
|
||||
}
|
||||
JSTaggedValue GetFrameArgv(size_t idx)
|
||||
{
|
||||
@ -123,7 +136,7 @@ private:
|
||||
ASSERT(idx < frameArgc_);
|
||||
return JSTaggedValue(frameArgvs_[idx]);
|
||||
}
|
||||
JSTaggedValue GetFrameArgv(kungfu::CommonArgIdx index)
|
||||
JSTaggedValue GetFrameArgv(CommonArgIdx index)
|
||||
{
|
||||
return GetFrameArgv(GetFrameIndex(index));
|
||||
}
|
||||
@ -135,24 +148,24 @@ private:
|
||||
bool CollectVirtualRegisters(Method* method, FrameWriter *frameWriter);
|
||||
bool HasDeoptValue(int32_t index) const
|
||||
{
|
||||
return deoptVregs_.find(static_cast<kungfu::OffsetType>(index)) != deoptVregs_.end();
|
||||
return deoptVregs_.find(static_cast<VRegId>(index)) != deoptVregs_.end();
|
||||
}
|
||||
JSTaggedValue GetDeoptValue(int32_t index) const
|
||||
{
|
||||
if (!HasDeoptValue(index)) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
return deoptVregs_.at(static_cast<kungfu::OffsetType>(index));
|
||||
return deoptVregs_.at(static_cast<VRegId>(index));
|
||||
}
|
||||
Method* GetMethod(JSTaggedValue &target);
|
||||
void RelocateCalleeSave();
|
||||
void Dump(Method* method, kungfu::DeoptType type);
|
||||
void Dump(Method* method, DeoptType type);
|
||||
JSThread *thread_ {nullptr};
|
||||
uintptr_t *calleeRegAddr_ {nullptr};
|
||||
size_t numCalleeRegs_ {0};
|
||||
AsmStackContext stackContext_;
|
||||
|
||||
std::unordered_map<kungfu::OffsetType, JSTaggedValue> deoptVregs_;
|
||||
std::unordered_map<VRegId, JSTaggedValue> deoptVregs_;
|
||||
struct Context context_ {0, 0, {}};
|
||||
uint32_t pc_ {0};
|
||||
JSTaggedValue env_ {JSTaggedValue::Undefined()};
|
||||
|
@ -393,7 +393,7 @@ uint32_t FrameIterator::GetBytecodeOffset() const
|
||||
}
|
||||
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
|
||||
auto frame = this->GetFrame<OptimizedJSFunctionFrame>();
|
||||
kungfu::ConstInfo constInfo;
|
||||
ConstInfo constInfo;
|
||||
frame->CollectPcOffsetInfo(*this, constInfo);
|
||||
if (!constInfo.empty()) {
|
||||
return constInfo[0];
|
||||
@ -460,7 +460,7 @@ ARK_INLINE void OptimizedFrame::GCIterate(const FrameIterator &it,
|
||||
}
|
||||
}
|
||||
|
||||
void FrameIterator::CollectPcOffsetInfo(kungfu::ConstInfo &info) const
|
||||
void FrameIterator::CollectPcOffsetInfo(ConstInfo &info) const
|
||||
{
|
||||
arkStackMapParser_->GetConstInfo(optimizedReturnAddr_, info, stackMapAddr_);
|
||||
}
|
||||
@ -486,7 +486,7 @@ ARK_INLINE uintptr_t* OptimizedJSFunctionFrame::ComputePrevFrameSp(const FrameIt
|
||||
}
|
||||
|
||||
|
||||
void OptimizedJSFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const
|
||||
void OptimizedJSFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const
|
||||
{
|
||||
it.CollectPcOffsetInfo(info);
|
||||
}
|
||||
|
@ -439,6 +439,7 @@ struct OptimizedJSFunctionFrame : public base::AlignedStruct<JSTaggedValue::Tagg
|
||||
base::AlignedPointer,
|
||||
base::AlignedPointer> {
|
||||
public:
|
||||
using ConstInfo = kungfu::LLVMStackMapType::ConstInfo;
|
||||
enum class Index : size_t {
|
||||
JSFuncIndex = 0,
|
||||
TypeIndex,
|
||||
@ -477,7 +478,7 @@ public:
|
||||
|
||||
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
||||
const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
||||
void CollectPcOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const;
|
||||
void CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const;
|
||||
|
||||
inline JSTaggedValue GetFunction() const
|
||||
{
|
||||
@ -1427,6 +1428,7 @@ enum class GCVisitedFlag : bool {
|
||||
|
||||
class FrameIterator {
|
||||
public:
|
||||
using ConstInfo = kungfu::LLVMStackMapType::ConstInfo;
|
||||
explicit FrameIterator(JSTaggedType *sp, const JSThread *thread = nullptr);
|
||||
FrameType GetFrameType() const
|
||||
{
|
||||
@ -1483,7 +1485,7 @@ public:
|
||||
return thread_;
|
||||
}
|
||||
bool IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
||||
void CollectPcOffsetInfo(kungfu::ConstInfo &info) const;
|
||||
void CollectPcOffsetInfo(ConstInfo &info) const;
|
||||
void CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const;
|
||||
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
|
||||
int GetCallSiteDelta(uintptr_t retAddr) const;
|
||||
|
@ -20,67 +20,78 @@
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
struct ARKConst {
|
||||
OffsetType offset;
|
||||
LLVMStackMapType::IntType offset;
|
||||
};
|
||||
|
||||
struct StackMapSecHead {
|
||||
uint32_t totalSize;
|
||||
struct ArkStackMapHeader {
|
||||
uint32_t secSize;
|
||||
uint32_t callsiteNum;
|
||||
uint32_t callsitStart;
|
||||
uint32_t callsitEnd;
|
||||
};
|
||||
struct CallsiteHead {
|
||||
|
||||
#pragma pack(1)
|
||||
struct CallsiteHeader {
|
||||
uint32_t calliteOffset {0}; // relative text start addr
|
||||
uint32_t stackmapOffset {0}; // relative stackmap start addr
|
||||
uint32_t arkStackMapNum {0};
|
||||
uint32_t deoptOffset {0};
|
||||
uint32_t deoptNum {0};
|
||||
uint16_t stackmapNum {0};
|
||||
uint16_t deoptNum {0};
|
||||
};
|
||||
#pragma pack ()
|
||||
|
||||
/* <deoptId, kind, value> */
|
||||
/* <vregId and kind, value> */
|
||||
struct ARKDeopt {
|
||||
OffsetType Id; // deoptid
|
||||
LLVMStackMapType::VRegId id; // deoptid
|
||||
LocationTy::Kind kind;
|
||||
std::variant<OffsetType, DwarfRegAndOffsetType, LargeInt> value;
|
||||
std::variant<LLVMStackMapType::IntType, LLVMStackMapType::LargeInt, LLVMStackMapType::DwarfRegAndOffsetType> value;
|
||||
};
|
||||
|
||||
struct ARKCallsite {
|
||||
CallsiteHead head;
|
||||
CallSiteInfo stackmaps;
|
||||
CallsiteHeader head;
|
||||
LLVMStackMapType::CallSiteInfo stackmaps;
|
||||
std::vector<kungfu::ARKDeopt> callsite2Deopt;
|
||||
bool operator < (const ARKCallsite & x) const
|
||||
{
|
||||
return head.calliteOffset < x.head.calliteOffset;
|
||||
}
|
||||
uint32_t CalHeadSize() const;
|
||||
uint32_t CalStackMapSize() const;
|
||||
uint32_t CalStackMapSize(Triple triple) const;
|
||||
};
|
||||
|
||||
struct ARKCallsiteAOTFileInfo {
|
||||
StackMapSecHead secHead;
|
||||
ArkStackMapHeader secHead;
|
||||
std::vector<ARKCallsite> callsites;
|
||||
};
|
||||
using ArkStackMap = CallSiteInfo;
|
||||
using CalleeRegAndOffsetVec = std::vector<DwarfRegAndOffsetType>;
|
||||
/*
|
||||
totalSize callsiteNum callsitStart callsitEnd
|
||||
-----head1--------
|
||||
-----head2--------
|
||||
|
|
||||
|
|
||||
-----head[N]------
|
||||
|
||||
-----stackmap1----
|
||||
-----stackmap2----
|
||||
|
|
||||
|
|
||||
-----stackmap2[N]-
|
||||
|
||||
-----deopt1-----
|
||||
-<deoptid, LocationTy::Kind, LocationTy
|
||||
- CONSTANT, <OffsetType OffsetOrSmallConstant>
|
||||
- INDIRECT <loc.DwarfRegNum, loc.OffsetOrSmallConstant>
|
||||
- CONSTANTNDEX <LargeInt>
|
||||
*/
|
||||
using ArkStackMap = LLVMStackMapType::CallSiteInfo;
|
||||
using CalleeRegAndOffsetVec = std::vector<LLVMStackMapType::DwarfRegAndOffsetType>;
|
||||
// * ArkStackMap layout as the following:
|
||||
// +-----------------------------------------+ ---------
|
||||
// | secSize | ^
|
||||
// |-----------------------------------------| ArkStackMapHeader
|
||||
// | callsiteNum | v
|
||||
// +-----------------------------------------+ ---------
|
||||
// | calliteOffset | ^
|
||||
// |-----------------------------------------| |
|
||||
// | stackmapOffset | |
|
||||
// |-----------------------------------------| |
|
||||
// | deoptOffset | CallsiteHeader[0]
|
||||
// |-----------------------------------------| |
|
||||
// | stackmapNum | |
|
||||
// |-----------------------------------------| |
|
||||
// | deoptNum | v
|
||||
// |-----------------------------------------| ---------
|
||||
// | . . . . . |
|
||||
// +-----------------------------------------+ ---------
|
||||
// | dwarfRegAndOff(sleb128) | StackMaps[0]
|
||||
// |-----------------------------------------| ---------
|
||||
// | . . . . . |
|
||||
// +-----------------------------------------+ ---------
|
||||
// | vregIdAndKind(sleb128) | ^
|
||||
// |-----------------------------------------| Deopts[0]
|
||||
// | value(sleb128) | v
|
||||
// |-----------------------------------------| ---------
|
||||
// | . . . . . |
|
||||
// +-----------------------------------------+ ---------
|
||||
//
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_ARK_STACKMAP_H
|
@ -37,8 +37,25 @@ void BinaryBufferWriter::WriteBuffer(const uint8_t *src, uint32_t count, bool fl
|
||||
}
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::Dump(const StackMapDumper& dumpInfo) const
|
||||
{
|
||||
LOG_COMPILER(INFO) << "total callsite num: " << dumpInfo.callsiteNum
|
||||
<< ", total ark stack map num: " << dumpInfo.stackmapNum
|
||||
<< ", total deopt num: " << dumpInfo.deoptNum;
|
||||
double callsiteHeadsSize = static_cast<double>(dumpInfo.callsiteHeadSize);
|
||||
double stackMapsSize = static_cast<double>(dumpInfo.arkStackMapSize);
|
||||
double deoptsSize = static_cast<double>(dumpInfo.deoptSize);
|
||||
LOG_COMPILER(INFO) << "total callsite head size: "
|
||||
<< std::fixed << std::setprecision(DECIMAL_LENS)
|
||||
<< (callsiteHeadsSize / 1_KB) << "KB, total stackmap size: "
|
||||
<< std::fixed << std::setprecision(DECIMAL_LENS)
|
||||
<< (stackMapsSize / 1_KB) << "KB, total deopt size: "
|
||||
<< std::fixed << std::setprecision(DECIMAL_LENS)
|
||||
<< (deoptsSize / 1_KB) << "KB";
|
||||
}
|
||||
|
||||
std::pair<std::shared_ptr<uint8_t>, uint32_t> ArkStackMapBuilder::Run(std::unique_ptr<uint8_t []> stackMapAddr,
|
||||
uintptr_t hostCodeSectionAddr)
|
||||
uintptr_t hostCodeSectionAddr, Triple triple)
|
||||
{
|
||||
LLVMStackMapParser parser;
|
||||
auto result = parser.CalculateStackMap(std::move(stackMapAddr), hostCodeSectionAddr);
|
||||
@ -49,41 +66,48 @@ std::pair<std::shared_ptr<uint8_t>, uint32_t> ArkStackMapBuilder::Run(std::uniqu
|
||||
auto pc2stackMapVec = parser.GetPc2StackMapVec();
|
||||
auto pc2DeoptVec = parser.GetPc2Deopt();
|
||||
ARKCallsiteAOTFileInfo AOTFileInfo;
|
||||
GenArkCallsiteAOTFileInfo(pc2stackMapVec, pc2DeoptVec, AOTFileInfo);
|
||||
uint32_t totalSize = AOTFileInfo.secHead.totalSize;
|
||||
uint8_t *p = new(std::nothrow) uint8_t[totalSize];
|
||||
GenArkCallsiteAOTFileInfo(pc2stackMapVec, pc2DeoptVec, AOTFileInfo, triple);
|
||||
uint32_t secSize = AOTFileInfo.secHead.secSize;
|
||||
uint8_t *p = new(std::nothrow) uint8_t[secSize];
|
||||
if (p == nullptr) {
|
||||
LOG_FULL(FATAL) << "new totalSize:0x" << std::hex << totalSize << " failed";
|
||||
LOG_FULL(FATAL) << "new secSize:0x" << std::hex << secSize << " failed";
|
||||
}
|
||||
std::shared_ptr<uint8_t> ptr(p, [](uint8_t *p) { delete []p;});
|
||||
SaveArkCallsiteAOTFileInfo(ptr.get(), totalSize, AOTFileInfo);
|
||||
return std::make_pair(ptr, totalSize);
|
||||
SaveArkCallsiteAOTFileInfo(ptr.get(), secSize, AOTFileInfo, triple);
|
||||
if (traceStackMap_) {
|
||||
Dump(dumper_);
|
||||
}
|
||||
return std::make_pair(ptr, secSize);
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::SaveArkStackMap(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer)
|
||||
void ArkStackMapBuilder::SaveArkStackMap(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer, Triple triple)
|
||||
{
|
||||
size_t n = info.callsites.size();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
auto &callSite = info.callsites.at(i);
|
||||
CallSiteInfo stackmaps = callSite.stackmaps;
|
||||
LLVMStackMapType::CallSiteInfo stackmaps = callSite.stackmaps;
|
||||
size_t m = stackmaps.size();
|
||||
for (size_t j = 0; j < m; j++) {
|
||||
auto &stackmap = stackmaps.at(j);
|
||||
DwarfRegType reg = stackmap.first;
|
||||
OffsetType offset = stackmap.second;
|
||||
LLVMStackMapType::DwarfRegType reg = stackmap.first;
|
||||
LLVMStackMapType::OffsetType offset = stackmap.second;
|
||||
if (j == 0) {
|
||||
ASSERT(callSite.head.stackmapOffset == writer.GetOffset());
|
||||
}
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(reg)), sizeof(DwarfRegType));
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(offset)), sizeof(OffsetType));
|
||||
std::vector<uint8_t> regOffset;
|
||||
size_t regOffsetSize = 0;
|
||||
LLVMStackMapType::EncodeRegAndOffset(regOffset, regOffsetSize, reg, offset, triple);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(regOffset.data()), regOffset.size());
|
||||
dumper_.arkStackMapSize += regOffsetSize;
|
||||
if (j == m - 1) {
|
||||
ASSERT((callSite.head.stackmapOffset + callSite.CalStackMapSize()) == writer.GetOffset());
|
||||
ASSERT((callSite.head.stackmapOffset + callSite.CalStackMapSize(triple)) == writer.GetOffset());
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.AlignOffset();
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::SaveArkDeopt(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer)
|
||||
void ArkStackMapBuilder::SaveArkDeopt(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer, Triple triple)
|
||||
{
|
||||
for (auto &it: info.callsites) {
|
||||
auto& callsite2Deopt = it.callsite2Deopt;
|
||||
@ -93,19 +117,33 @@ void ArkStackMapBuilder::SaveArkDeopt(const ARKCallsiteAOTFileInfo& info, Binary
|
||||
if (j == 0) {
|
||||
ASSERT(it.head.deoptOffset == writer.GetOffset());
|
||||
}
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(deopt.Id)), sizeof(deopt.Id));
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(deopt.kind)), sizeof(deopt.kind));
|
||||
std::vector<uint8_t> vregsInfo;
|
||||
size_t vregsInfoSize = 0;
|
||||
LLVMStackMapType::EncodeVRegsInfo(vregsInfo, vregsInfoSize, deopt.id, deopt.kind);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(vregsInfo.data()), vregsInfoSize);
|
||||
dumper_.deoptSize += vregsInfoSize;
|
||||
auto& value = deopt.value;
|
||||
if (std::holds_alternative<OffsetType>(value)) {
|
||||
OffsetType v = std::get<OffsetType>(value);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(v)), sizeof(v));
|
||||
} else if (std::holds_alternative<LargeInt>(value)) {
|
||||
LargeInt v = std::get<LargeInt>(value);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(v)), sizeof(v));
|
||||
} else if (std::holds_alternative<DwarfRegAndOffsetType>(value)) {
|
||||
DwarfRegAndOffsetType v = std::get<DwarfRegAndOffsetType>(value);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(v.first)), sizeof(v.first));
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(v.second)), sizeof(v.second));
|
||||
if (std::holds_alternative<LLVMStackMapType::IntType>(value)) {
|
||||
LLVMStackMapType::IntType v = std::get<LLVMStackMapType::IntType>(value);
|
||||
std::vector<uint8_t> num;
|
||||
size_t numSize = 0;
|
||||
LLVMStackMapType::EncodeData(num, numSize, v);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(num.data()), numSize);
|
||||
dumper_.deoptSize += numSize;
|
||||
} else if (std::holds_alternative<LLVMStackMapType::LargeInt>(value)) {
|
||||
LLVMStackMapType::LargeInt v = std::get<LLVMStackMapType::LargeInt>(value);
|
||||
std::vector<uint8_t> num;
|
||||
size_t numSize = 0;
|
||||
LLVMStackMapType::EncodeData(num, numSize, v);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(num.data()), numSize);
|
||||
dumper_.deoptSize += numSize;
|
||||
} else if (std::holds_alternative<LLVMStackMapType::DwarfRegAndOffsetType>(value)) {
|
||||
LLVMStackMapType::DwarfRegAndOffsetType v = std::get<LLVMStackMapType::DwarfRegAndOffsetType>(value);
|
||||
std::vector<uint8_t> regOffset;
|
||||
size_t regOffsetSize = 0;
|
||||
LLVMStackMapType::EncodeRegAndOffset(regOffset, regOffsetSize, v.first, v.second, triple);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(regOffset.data()), regOffset.size());
|
||||
dumper_.arkStackMapSize += regOffsetSize;
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
@ -114,110 +152,19 @@ void ArkStackMapBuilder::SaveArkDeopt(const ARKCallsiteAOTFileInfo& info, Binary
|
||||
}
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkStackMap(const CallsiteHead& callsiteHead, BinaryBufferParser& binBufparser,
|
||||
uint8_t *ptr, ArkStackMap &arkStackMaps) const
|
||||
{
|
||||
DwarfRegType reg;
|
||||
OffsetType offsetType;
|
||||
uint32_t offset = callsiteHead.stackmapOffset;
|
||||
uint32_t arkStackMapNum = callsiteHead.arkStackMapNum;
|
||||
ASSERT(arkStackMapNum % 2 == 0); // 2:base and derive
|
||||
for (uint32_t j = 0; j < arkStackMapNum; j++) {
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(®), sizeof(DwarfRegType), ptr + offset);
|
||||
offset += sizeof(DwarfRegType);
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(&offsetType), sizeof(OffsetType), ptr + offset);
|
||||
offset += sizeof(OffsetType);
|
||||
LOG_COMPILER(VERBOSE) << " reg: " << std::dec << reg << " offset:" << offsetType;
|
||||
arkStackMaps.emplace_back(std::make_pair(reg, offsetType));
|
||||
}
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkDeopt(const CallsiteHead& callsiteHead,
|
||||
BinaryBufferParser& binBufparser, uint8_t *ptr, std::vector<kungfu::ARKDeopt> &deopts) const
|
||||
{
|
||||
kungfu::ARKDeopt deopt;
|
||||
uint32_t deoptOffset = callsiteHead.deoptOffset;
|
||||
uint32_t deoptNum = callsiteHead.deoptNum;
|
||||
OffsetType id;
|
||||
LocationTy::Kind kind;
|
||||
DwarfRegType reg;
|
||||
OffsetType offsetType;
|
||||
ASSERT(deoptNum % 2 == 0); // 2:<id, value>
|
||||
for (uint32_t j = 0; j < deoptNum; j += 2) { // 2:<id, value>
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(&id), sizeof(id), ptr + deoptOffset);
|
||||
deoptOffset += sizeof(id);
|
||||
deopt.Id = id;
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(&kind), sizeof(kind), ptr + deoptOffset);
|
||||
deoptOffset += sizeof(kind);
|
||||
deopt.kind = kind;
|
||||
switch (kind) {
|
||||
case LocationTy::Kind::CONSTANT: {
|
||||
OffsetType v;
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(&v), sizeof(v), ptr + deoptOffset);
|
||||
deoptOffset += sizeof(v);
|
||||
LOG_COMPILER(VERBOSE) << "const offset:" << deoptOffset;
|
||||
deopt.value = v;
|
||||
break;
|
||||
}
|
||||
case LocationTy::Kind::CONSTANTNDEX: {
|
||||
LargeInt v;
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(&v), sizeof(v), ptr + deoptOffset);
|
||||
deoptOffset += sizeof(v);
|
||||
LOG_COMPILER(VERBOSE) << "large Int:" << v;
|
||||
deopt.value = v;
|
||||
break;
|
||||
}
|
||||
case LocationTy::Kind::INDIRECT: {
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(®), sizeof(reg), ptr + deoptOffset);
|
||||
deoptOffset += sizeof(reg);
|
||||
binBufparser.ParseBuffer(reinterpret_cast<uint8_t *>(&offsetType),
|
||||
sizeof(offsetType), ptr + deoptOffset);
|
||||
deoptOffset += sizeof(offsetType);
|
||||
LOG_COMPILER(VERBOSE) << " reg:" << std::dec << reg << " offset:" << static_cast<int>(offsetType);
|
||||
deopt.value = std::make_pair(reg, offsetType);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
deopts.emplace_back(deopt);
|
||||
}
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkStackMapAndDeopt(uint8_t *ptr, uint32_t length) const
|
||||
{
|
||||
CallsiteHead callsiteHead;
|
||||
StackMapSecHead secHead;
|
||||
BinaryBufferParser binBufparser(ptr, length);
|
||||
binBufparser.ParseBuffer(&secHead, sizeof(StackMapSecHead));
|
||||
for (uint32_t i = 0; i < secHead.callsiteNum; i++) {
|
||||
binBufparser.ParseBuffer(&callsiteHead, sizeof(CallsiteHead));
|
||||
uint32_t offset = callsiteHead.stackmapOffset;
|
||||
uint32_t arkStackMapNum = callsiteHead.arkStackMapNum;
|
||||
uint32_t deoptOffset = callsiteHead.deoptOffset;
|
||||
uint32_t deoptNum = callsiteHead.deoptNum;
|
||||
std::vector<kungfu::ARKDeopt> deopts;
|
||||
ArkStackMap arkStackMaps;
|
||||
LOG_COMPILER(VERBOSE) << " calliteOffset:0x" << std::hex << callsiteHead.calliteOffset
|
||||
<< " stackmap offset:0x" << std::hex << offset << " num:" << arkStackMapNum
|
||||
<< " deopt Offset:0x" << deoptOffset << " num:" << deoptNum;
|
||||
ParseArkStackMap(callsiteHead, binBufparser, ptr, arkStackMaps);
|
||||
ParseArkDeopt(callsiteHead, binBufparser, ptr, deopts);
|
||||
}
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::SaveArkCallsiteAOTFileInfo(uint8_t *ptr, uint32_t length, const ARKCallsiteAOTFileInfo& info)
|
||||
void ArkStackMapBuilder::SaveArkCallsiteAOTFileInfo(uint8_t *ptr, uint32_t length,
|
||||
const ARKCallsiteAOTFileInfo& info, Triple triple)
|
||||
{
|
||||
BinaryBufferWriter writer(ptr, length);
|
||||
ASSERT(length >= info.secHead.totalSize);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(info.secHead)), sizeof(StackMapSecHead));
|
||||
ASSERT(length >= info.secHead.secSize);
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(info.secHead)), sizeof(ArkStackMapHeader));
|
||||
dumper_.callsiteHeadSize += sizeof(ArkStackMapHeader);
|
||||
for (auto &it: info.callsites) {
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(it.head)), sizeof(CallsiteHead));
|
||||
writer.WriteBuffer(reinterpret_cast<const uint8_t *>(&(it.head)), sizeof(CallsiteHeader));
|
||||
dumper_.callsiteHeadSize += sizeof(CallsiteHeader);
|
||||
}
|
||||
SaveArkStackMap(info, writer);
|
||||
SaveArkDeopt(info, writer);
|
||||
SaveArkStackMap(info, writer, triple);
|
||||
SaveArkDeopt(info, writer, triple);
|
||||
#ifndef NDEBUG
|
||||
ArkStackMapParser parser;
|
||||
parser.ParseArkStackMapAndDeopt(ptr, length);
|
||||
@ -241,8 +188,8 @@ void ArkStackMapBuilder::SortCallSite(
|
||||
});
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::CalcCallsitePc(std::vector<std::pair<uintptr_t, DeoptInfoType>> &pc2Deopt,
|
||||
std::vector<std::pair<uintptr_t, CallSiteInfo>> &pc2StackMap, std::vector<intptr_t> &callsitePcs)
|
||||
void ArkStackMapBuilder::CalcCallsitePc(std::vector<std::pair<uintptr_t, LLVMStackMapType::DeoptInfoType>> &pc2Deopt,
|
||||
std::vector<std::pair<uintptr_t, LLVMStackMapType::CallSiteInfo>> &pc2StackMap, std::vector<intptr_t> &callsitePcs)
|
||||
{
|
||||
std::set<uintptr_t> pcSet;
|
||||
for (auto &it: pc2Deopt) {
|
||||
@ -264,31 +211,46 @@ int ArkStackMapBuilder::FindLoc(std::vector<intptr_t> &CallsitePcs, intptr_t pc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::GenARKDeopt(const DeoptInfoType& deopt, std::pair<uint32_t,
|
||||
std::vector<kungfu::ARKDeopt>> &sizeAndArkDeopt)
|
||||
void ArkStackMapBuilder::GenARKDeopt(const LLVMStackMapType::DeoptInfoType& deopt, std::pair<uint32_t,
|
||||
std::vector<ARKDeopt>> &sizeAndArkDeopt, Triple triple)
|
||||
{
|
||||
ASSERT(deopt.size() % 2 == 0); // 2:<id, value>
|
||||
uint32_t total = 0;
|
||||
ARKDeopt v;
|
||||
for (size_t i = 0; i < deopt.size(); i += 2) { // 2:<id, value>
|
||||
ASSERT(std::holds_alternative<OffsetType>(deopt[i]));
|
||||
const auto &id = std::get<OffsetType>(deopt[i]);
|
||||
total += sizeof(OffsetType);
|
||||
v.Id = id;
|
||||
total += sizeof(LocationTy::Kind); // derive
|
||||
ASSERT(std::holds_alternative<LLVMStackMapType::IntType>(deopt[i]));
|
||||
LLVMStackMapType::VRegId id = static_cast<LLVMStackMapType::VRegId>(
|
||||
std::get<LLVMStackMapType::IntType>(deopt[i]));
|
||||
v.id = id;
|
||||
auto value = deopt[i + 1];
|
||||
if (std::holds_alternative<OffsetType>(value)) {
|
||||
total += sizeof(OffsetType);
|
||||
if (std::holds_alternative<LLVMStackMapType::IntType>(value)) {
|
||||
v.kind = LocationTy::Kind::CONSTANT;
|
||||
v.value = std::get<OffsetType>(value);
|
||||
} else if (std::holds_alternative<LargeInt>(value)) {
|
||||
total += sizeof(LargeInt);
|
||||
v.value = std::get<LLVMStackMapType::IntType>(value);
|
||||
std::vector<uint8_t> vregsInfo;
|
||||
size_t vregsInfoSize = 0;
|
||||
LLVMStackMapType::EncodeVRegsInfo(vregsInfo, vregsInfoSize, v.id, v.kind);
|
||||
size_t valueSize = panda::leb128::SignedEncodingSize(std::get<LLVMStackMapType::IntType>(value));
|
||||
total += (vregsInfoSize + valueSize);
|
||||
} else if (std::holds_alternative<LLVMStackMapType::LargeInt>(value)) {
|
||||
v.kind = LocationTy::Kind::CONSTANTNDEX;
|
||||
v.value = std::get<LargeInt>(value);
|
||||
} else if (std::holds_alternative<DwarfRegAndOffsetType>(value)) {
|
||||
total += (sizeof(DwarfRegType) + sizeof(OffsetType));
|
||||
v.value = std::get<LLVMStackMapType::LargeInt>(value);
|
||||
std::vector<uint8_t> vregsInfo;
|
||||
size_t vregsInfoSize = 0;
|
||||
LLVMStackMapType::EncodeVRegsInfo(vregsInfo, vregsInfoSize, v.id, v.kind);
|
||||
size_t valueSize = panda::leb128::SignedEncodingSize(std::get<LLVMStackMapType::LargeInt>(value));
|
||||
total += (vregsInfoSize + valueSize);
|
||||
} else if (std::holds_alternative<LLVMStackMapType::DwarfRegAndOffsetType>(value)) {
|
||||
v.kind = LocationTy::Kind::INDIRECT;
|
||||
v.value = std::get<DwarfRegAndOffsetType>(value);
|
||||
v.value = std::get<LLVMStackMapType::DwarfRegAndOffsetType>(value);
|
||||
std::vector<uint8_t> vregsInfo;
|
||||
size_t vregsInfoSize = 0;
|
||||
LLVMStackMapType::EncodeVRegsInfo(vregsInfo, vregsInfoSize, v.id, v.kind);
|
||||
LLVMStackMapType::DwarfRegType reg = std::get<LLVMStackMapType::DwarfRegAndOffsetType>(value).first;
|
||||
LLVMStackMapType::OffsetType offset = std::get<LLVMStackMapType::DwarfRegAndOffsetType>(value).second;
|
||||
std::vector<uint8_t> regOffset;
|
||||
size_t regOffsetSize = 0;
|
||||
LLVMStackMapType::EncodeRegAndOffset(regOffset, regOffsetSize, reg, offset, triple);
|
||||
total += (vregsInfoSize + regOffsetSize);
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
@ -297,54 +259,58 @@ void ArkStackMapBuilder::GenARKDeopt(const DeoptInfoType& deopt, std::pair<uint3
|
||||
}
|
||||
std::sort(sizeAndArkDeopt.second.begin(), sizeAndArkDeopt.second.end(),
|
||||
[](const ARKDeopt &a, const ARKDeopt &b) {
|
||||
return a.Id < b.Id;
|
||||
return a.id < b.id;
|
||||
});
|
||||
sizeAndArkDeopt.first = total;
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::GenArkCallsiteAOTFileInfo(std::vector<Pc2CallSiteInfo> &pc2stackMapVec,
|
||||
std::vector<Pc2Deopt>& pc2DeoptVec, ARKCallsiteAOTFileInfo &result)
|
||||
void ArkStackMapBuilder::GenArkCallsiteAOTFileInfo(std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2stackMapVec,
|
||||
std::vector<LLVMStackMapType::Pc2Deopt>& pc2DeoptVec, ARKCallsiteAOTFileInfo &result, Triple triple)
|
||||
{
|
||||
ARKCallsite callsite;
|
||||
uint32_t totalSize = 0;
|
||||
std::vector<std::pair<uintptr_t, CallSiteInfo>> pc2stackMaps;
|
||||
std::vector<std::pair<uintptr_t, DeoptInfoType>> pc2Deopts;
|
||||
uint32_t secSize = 0;
|
||||
std::vector<std::pair<uintptr_t, LLVMStackMapType::CallSiteInfo>> pc2StackMaps;
|
||||
std::vector<std::pair<uintptr_t, LLVMStackMapType::DeoptInfoType>> pc2Deopts;
|
||||
std::vector<intptr_t> CallsitePcs;
|
||||
SortCallSite(pc2stackMapVec, pc2stackMaps);
|
||||
SortCallSite(pc2stackMapVec, pc2StackMaps);
|
||||
SortCallSite(pc2DeoptVec, pc2Deopts);
|
||||
CalcCallsitePc(pc2Deopts, pc2stackMaps, CallsitePcs);
|
||||
CalcCallsitePc(pc2Deopts, pc2StackMaps, CallsitePcs);
|
||||
uint32_t callsiteNum = CallsitePcs.size();
|
||||
dumper_.callsiteNum = callsiteNum;
|
||||
result.callsites.resize(callsiteNum);
|
||||
uint32_t stackmapOffset = sizeof(StackMapSecHead) + sizeof(CallsiteHead) * callsiteNum;
|
||||
for (auto &x: pc2stackMaps) {
|
||||
CallSiteInfo i = x.second;
|
||||
uint32_t stackmapOffset = sizeof(ArkStackMapHeader) + sizeof(CallsiteHeader) * callsiteNum;
|
||||
for (auto &x: pc2StackMaps) {
|
||||
LLVMStackMapType::CallSiteInfo i = x.second;
|
||||
callsite.head.calliteOffset = x.first;
|
||||
callsite.head.arkStackMapNum = i.size();
|
||||
ASSERT(std::numeric_limits<uint16_t>::min() <= i.size() && i.size() <= std::numeric_limits<uint16_t>::max());
|
||||
callsite.head.stackmapNum = i.size();
|
||||
callsite.head.stackmapOffset = stackmapOffset;
|
||||
callsite.head.deoptOffset = 0;
|
||||
callsite.head.deoptNum = 0;
|
||||
callsite.stackmaps = i;
|
||||
stackmapOffset += callsite.CalStackMapSize();
|
||||
stackmapOffset += callsite.CalStackMapSize(triple);
|
||||
int loc = FindLoc(CallsitePcs, x.first);
|
||||
ASSERT(loc >= 0 && loc < static_cast<int>(callsiteNum));
|
||||
result.callsites[static_cast<uint32_t>(loc)] = callsite;
|
||||
dumper_.stackmapNum += i.size();
|
||||
}
|
||||
totalSize = stackmapOffset;
|
||||
stackmapOffset = AlignUp(stackmapOffset, LLVMStackMapType::STACKMAP_ALIGN_BYTES);
|
||||
secSize = stackmapOffset;
|
||||
for (auto &x: pc2Deopts) {
|
||||
int loc = FindLoc(CallsitePcs, x.first);
|
||||
ASSERT(loc >= 0 && loc < static_cast<int>(callsiteNum));
|
||||
DeoptInfoType deopt = x.second;
|
||||
LLVMStackMapType::DeoptInfoType deopt = x.second;
|
||||
result.callsites[static_cast<uint32_t>(loc)].head.calliteOffset = x.first;
|
||||
ASSERT(std::numeric_limits<uint16_t>::min() <= deopt.size() && deopt.size() <= std::numeric_limits<uint16_t>::max());
|
||||
result.callsites[static_cast<uint32_t>(loc)].head.deoptNum = deopt.size();
|
||||
result.callsites[static_cast<uint32_t>(loc)].head.deoptOffset = totalSize;
|
||||
std::pair<uint32_t, std::vector<kungfu::ARKDeopt>> sizeAndArkDeopt;
|
||||
GenARKDeopt(deopt, sizeAndArkDeopt);
|
||||
totalSize += sizeAndArkDeopt.first;
|
||||
result.callsites[static_cast<uint32_t>(loc)].head.deoptOffset = secSize;
|
||||
std::pair<uint32_t, std::vector<ARKDeopt>> sizeAndArkDeopt;
|
||||
GenARKDeopt(deopt, sizeAndArkDeopt, triple);
|
||||
secSize += sizeAndArkDeopt.first;
|
||||
result.callsites[static_cast<uint32_t>(loc)].callsite2Deopt = sizeAndArkDeopt.second;
|
||||
dumper_.deoptNum += deopt.size();
|
||||
}
|
||||
result.secHead.callsiteNum = callsiteNum;
|
||||
result.secHead.callsitStart = sizeof(StackMapSecHead);
|
||||
result.secHead.callsitEnd = result.secHead.callsitStart + (result.secHead.callsiteNum - 1) * sizeof(CallsiteHead);
|
||||
result.secHead.totalSize = totalSize;
|
||||
result.secHead.secSize = secSize;
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -21,10 +21,13 @@
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
|
||||
#include "ecmascript/frames.h"
|
||||
#include "ecmascript/stackmap/ark_stackmap.h"
|
||||
#include "ecmascript/stackmap/llvm_stackmap_type.h"
|
||||
|
||||
#include "libpandabase/utils/leb128.h"
|
||||
namespace panda::ecmascript {
|
||||
class BinaryBufferParser;
|
||||
}
|
||||
@ -39,33 +42,57 @@ public:
|
||||
{
|
||||
return offset_;
|
||||
}
|
||||
void AlignOffset()
|
||||
{
|
||||
offset_ = AlignUp(offset_, LLVMStackMapType::STACKMAP_ALIGN_BYTES);
|
||||
}
|
||||
private:
|
||||
uint8_t *buffer_ {nullptr};
|
||||
uint32_t length_ {0};
|
||||
uint32_t offset_ {0};
|
||||
};
|
||||
|
||||
struct StackMapDumper {
|
||||
uint32_t callsiteHeadSize {0};
|
||||
uint32_t arkStackMapSize {0};
|
||||
uint32_t deoptSize {0};
|
||||
uint32_t callsiteNum {0};
|
||||
uint32_t stackmapNum {0};
|
||||
uint32_t deoptNum {0};
|
||||
};
|
||||
|
||||
class ArkStackMapBuilder {
|
||||
public:
|
||||
ArkStackMapBuilder() = default;
|
||||
~ArkStackMapBuilder() = default;
|
||||
std::pair<std::shared_ptr<uint8_t>, uint32_t> PUBLIC_API Run(std::unique_ptr<uint8_t []> stackMapAddr,
|
||||
uintptr_t hostCodeSectionAddr);
|
||||
uintptr_t hostCodeSectionAddr, Triple triple);
|
||||
|
||||
void SetTraceStackMap(bool flag)
|
||||
{
|
||||
traceStackMap_ = flag;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int DECIMAL_LENS = 2;
|
||||
StackMapDumper dumper_;
|
||||
|
||||
template <class Vec>
|
||||
void SortCallSite(std::vector<std::unordered_map<uintptr_t, Vec>> &infos,
|
||||
std::vector<std::pair<uintptr_t, Vec>>& result);
|
||||
|
||||
void CalcCallsitePc(std::vector<std::pair<uintptr_t, DeoptInfoType>> &pc2Deopt,
|
||||
std::vector<std::pair<uintptr_t, CallSiteInfo>> &pc2StackMap, std::vector<intptr_t> &callsitePcs);
|
||||
|
||||
void GenArkCallsiteAOTFileInfo(std::vector<Pc2CallSiteInfo> &pc2stackMaps,
|
||||
std::vector<Pc2Deopt>& pc2DeoptVec, ARKCallsiteAOTFileInfo &result);
|
||||
void SaveArkDeopt(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer);
|
||||
void SaveArkStackMap(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer);
|
||||
void SaveArkCallsiteAOTFileInfo(uint8_t *ptr, uint32_t length, const ARKCallsiteAOTFileInfo& info);
|
||||
void CalcCallsitePc(std::vector<std::pair<uintptr_t, LLVMStackMapType::DeoptInfoType>> &pc2Deopt,
|
||||
std::vector<std::pair<uintptr_t, LLVMStackMapType::CallSiteInfo>> &pc2StackMap,
|
||||
std::vector<intptr_t> &callsitePcs);
|
||||
void GenArkCallsiteAOTFileInfo(std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2StackMaps,
|
||||
std::vector<LLVMStackMapType::Pc2Deopt>& pc2DeoptVec, ARKCallsiteAOTFileInfo &result, Triple triple);
|
||||
void SaveArkDeopt(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer, Triple triple);
|
||||
void SaveArkStackMap(const ARKCallsiteAOTFileInfo& info, BinaryBufferWriter& writer, Triple triple);
|
||||
void SaveArkCallsiteAOTFileInfo(uint8_t *ptr, uint32_t length, const ARKCallsiteAOTFileInfo& info, Triple triple);
|
||||
int FindLoc(std::vector<intptr_t> &CallsitePcs, intptr_t pc);
|
||||
void GenARKDeopt(const DeoptInfoType& deopt, std::pair<uint32_t, std::vector<kungfu::ARKDeopt>> &sizeAndArkDeopt);
|
||||
void GenARKDeopt(const LLVMStackMapType::DeoptInfoType& deopt,
|
||||
std::pair<uint32_t, std::vector<ARKDeopt>> &sizeAndArkDeopt, Triple triple);
|
||||
void Dump(const StackMapDumper& dumpInfo) const;
|
||||
bool traceStackMap_{false};
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_ARK_STACKMAP_BUILD_H
|
||||
|
@ -20,8 +20,8 @@
|
||||
#include "ecmascript/stackmap/ark_stackmap_builder.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
// implement simple binary-search is improve performance. if use std api, it'll trigger copy CallsiteHead.
|
||||
int ArkStackMapParser::BinaraySearch(CallsiteHead *callsiteHead, uint32_t callsiteNum, uintptr_t callSiteAddr) const
|
||||
// implement simple binary-search is improve performance. if use std api, it'll trigger copy CallsiteHeader.
|
||||
int ArkStackMapParser::BinaraySearch(CallsiteHeader *callsiteHead, uint32_t callsiteNum, uintptr_t callSiteAddr) const
|
||||
{
|
||||
int slow = 0;
|
||||
int high = static_cast<int>(callsiteNum) - 1;
|
||||
@ -41,56 +41,54 @@ int ArkStackMapParser::BinaraySearch(CallsiteHead *callsiteHead, uint32_t callsi
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ArkStackMapParser::GetArkDeopt(uint8_t *stackmapAddr, uint32_t length,
|
||||
const CallsiteHead& callsiteHead, std::vector<kungfu::ARKDeopt> &deopts) const
|
||||
void ArkStackMapParser::GetArkDeopt(uint8_t *stackmapAddr,
|
||||
const CallsiteHeader& callsiteHead, std::vector<ARKDeopt>& deopts) const
|
||||
{
|
||||
BinaryBufferParser binBufparser(stackmapAddr, length);
|
||||
ParseArkDeopt(callsiteHead, binBufparser, stackmapAddr, deopts);
|
||||
ParseArkDeopt(callsiteHead, stackmapAddr, deopts);
|
||||
}
|
||||
|
||||
void ArkStackMapParser::GetArkDeopt(uintptr_t callSiteAddr, uint8_t *stackmapAddr,
|
||||
std::vector<kungfu::ARKDeopt> &deopts) const
|
||||
std::vector<ARKDeopt>& deopts) const
|
||||
{
|
||||
StackMapSecHead *head = reinterpret_cast<StackMapSecHead *>(stackmapAddr);
|
||||
ArkStackMapHeader *head = reinterpret_cast<ArkStackMapHeader *>(stackmapAddr);
|
||||
ASSERT(head != nullptr);
|
||||
uint32_t callsiteNum = head->callsiteNum;
|
||||
uint32_t length = head->totalSize;
|
||||
ASSERT((head->callsitEnd - head->callsitStart) == ((callsiteNum - 1) * sizeof(CallsiteHead)));
|
||||
|
||||
CallsiteHead *callsiteHead = reinterpret_cast<CallsiteHead *>(stackmapAddr + sizeof(StackMapSecHead));
|
||||
CallsiteHeader *callsiteHead = reinterpret_cast<CallsiteHeader *>(stackmapAddr + sizeof(ArkStackMapHeader));
|
||||
int mid = BinaraySearch(callsiteHead, callsiteNum, callSiteAddr);
|
||||
if (mid == -1) {
|
||||
return;
|
||||
}
|
||||
CallsiteHead *found = callsiteHead + mid;
|
||||
GetArkDeopt(stackmapAddr, length, *found, deopts);
|
||||
CallsiteHeader *found = callsiteHead + mid;
|
||||
GetArkDeopt(stackmapAddr, *found, deopts);
|
||||
}
|
||||
|
||||
void ArkStackMapParser::GetConstInfo(uintptr_t callSiteAddr, ConstInfo &info, uint8_t *stackmapAddr) const
|
||||
void ArkStackMapParser::GetConstInfo(uintptr_t callSiteAddr, LLVMStackMapType::ConstInfo& info,
|
||||
uint8_t *stackmapAddr) const
|
||||
{
|
||||
std::vector<kungfu::ARKDeopt> deopts;
|
||||
std::vector<ARKDeopt> deopts;
|
||||
GetArkDeopt(callSiteAddr, stackmapAddr, deopts);
|
||||
if (deopts.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ARKDeopt target;
|
||||
OffsetType id = static_cast<OffsetType>(SpecVregIndex::PC_OFFSET_INDEX);
|
||||
target.Id = id;
|
||||
LLVMStackMapType::VRegId id = static_cast<LLVMStackMapType::VRegId>(SpecVregIndex::PC_OFFSET_INDEX);
|
||||
target.id = id;
|
||||
auto it = std::lower_bound(deopts.begin(), deopts.end(), target,
|
||||
[](const ARKDeopt& a, const ARKDeopt& b) {
|
||||
return a.Id < b.Id;
|
||||
return a.id < b.id;
|
||||
});
|
||||
if (it == deopts.end() || (it->Id > id)) {
|
||||
if (it == deopts.end() || (it->id > id)) {
|
||||
return;
|
||||
}
|
||||
ASSERT(it->kind == LocationTy::Kind::CONSTANT);
|
||||
ASSERT(std::holds_alternative<OffsetType>(it->value));
|
||||
auto v = std::get<OffsetType>(it->value);
|
||||
ASSERT(std::holds_alternative<LLVMStackMapType::IntType>(it->value));
|
||||
auto v = std::get<LLVMStackMapType::IntType>(it->value);
|
||||
info.emplace_back(v);
|
||||
}
|
||||
|
||||
uintptr_t ArkStackMapParser::GetStackSlotAddress(const DwarfRegAndOffsetType info,
|
||||
uintptr_t ArkStackMapParser::GetStackSlotAddress(const LLVMStackMapType::DwarfRegAndOffsetType info,
|
||||
uintptr_t callSiteSp, uintptr_t callsiteFp) const
|
||||
{
|
||||
uintptr_t address = 0;
|
||||
@ -105,36 +103,33 @@ uintptr_t ArkStackMapParser::GetStackSlotAddress(const DwarfRegAndOffsetType inf
|
||||
return address;
|
||||
}
|
||||
|
||||
bool ArkStackMapParser::IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor,
|
||||
bool ArkStackMapParser::IteratorStackMap(const RootVisitor& visitor, const RootBaseAndDerivedVisitor& derivedVisitor,
|
||||
uintptr_t callSiteAddr, uintptr_t callsiteFp, uintptr_t callSiteSp, uint8_t *stackmapAddr) const
|
||||
{
|
||||
StackMapSecHead *head = reinterpret_cast<StackMapSecHead *>(stackmapAddr);
|
||||
ArkStackMapHeader *head = reinterpret_cast<ArkStackMapHeader *>(stackmapAddr);
|
||||
ASSERT(head != nullptr);
|
||||
uint32_t callsiteNum = head->callsiteNum;
|
||||
uint32_t length = head->totalSize;
|
||||
ArkStackMap arkStackMap;
|
||||
// BuiltinsStub current only sample stub, don't have stackmap&deopt.
|
||||
if (callsiteNum == 0) {
|
||||
return false;
|
||||
}
|
||||
ASSERT((head->callsitEnd - head->callsitStart) == ((callsiteNum - 1) * sizeof(CallsiteHead)));
|
||||
|
||||
CallsiteHead *callsiteHead = reinterpret_cast<CallsiteHead *>(stackmapAddr + sizeof(StackMapSecHead));
|
||||
CallsiteHeader *callsiteHead = reinterpret_cast<CallsiteHeader *>(stackmapAddr + sizeof(ArkStackMapHeader));
|
||||
int mid = BinaraySearch(callsiteHead, callsiteNum, callSiteAddr);
|
||||
if (mid == -1) {
|
||||
return false;
|
||||
}
|
||||
CallsiteHead *found = callsiteHead + mid;
|
||||
BinaryBufferParser binBufparser(stackmapAddr, length);
|
||||
ParseArkStackMap(*found, binBufparser, stackmapAddr, arkStackMap);
|
||||
CallsiteHeader *found = callsiteHead + mid;
|
||||
ParseArkStackMap(*found, stackmapAddr, arkStackMap);
|
||||
if (arkStackMap.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
ASSERT(callsiteFp != callSiteSp);
|
||||
std::map<uintptr_t, uintptr_t> baseSet;
|
||||
for (size_t i = 0; i < arkStackMap.size(); i += 2) { // 2:base and derive
|
||||
const DwarfRegAndOffsetType baseInfo = arkStackMap.at(i);
|
||||
const DwarfRegAndOffsetType derivedInfo = arkStackMap.at(i + 1);
|
||||
const LLVMStackMapType::DwarfRegAndOffsetType baseInfo = arkStackMap.at(i);
|
||||
const LLVMStackMapType::DwarfRegAndOffsetType derivedInfo = arkStackMap.at(i + 1);
|
||||
uintptr_t base = GetStackSlotAddress(baseInfo, callSiteSp, callsiteFp);
|
||||
uintptr_t derived = GetStackSlotAddress(derivedInfo, callSiteSp, callsiteFp);
|
||||
if (*reinterpret_cast<uintptr_t *>(base) == 0) {
|
||||
@ -155,4 +150,82 @@ bool ArkStackMapParser::IteratorStackMap(const RootVisitor &visitor, const RootB
|
||||
baseSet.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkStackMap(const CallsiteHeader& callsiteHead, uint8_t *ptr,
|
||||
ArkStackMap& arkStackMaps) const
|
||||
{
|
||||
LLVMStackMapType::DwarfRegType reg;
|
||||
LLVMStackMapType::OffsetType offsetType;
|
||||
uint32_t offset = callsiteHead.stackmapOffset;
|
||||
uint16_t stackmapNum = callsiteHead.stackmapNum;
|
||||
ASSERT(stackmapNum % 2 == 0); // 2:base and derive
|
||||
for (uint32_t j = 0; j < stackmapNum; j++) {
|
||||
auto [regOffset, regOffsetSize, is_full] =
|
||||
panda::leb128::DecodeSigned<LLVMStackMapType::SLeb128Type>(ptr + offset);
|
||||
LLVMStackMapType::DecodeRegAndOffset(regOffset, reg, offsetType);
|
||||
offset += regOffsetSize;
|
||||
LOG_COMPILER(VERBOSE) << " reg: " << std::dec << reg << " offset:" << offsetType;
|
||||
arkStackMaps.emplace_back(std::make_pair(reg, offsetType));
|
||||
}
|
||||
offset = AlignUp(offset, LLVMStackMapType::STACKMAP_ALIGN_BYTES);
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkDeopt(const CallsiteHeader& callsiteHead, uint8_t *ptr,
|
||||
std::vector<ARKDeopt> &deopts) const
|
||||
{
|
||||
ARKDeopt deopt;
|
||||
uint32_t deoptOffset = callsiteHead.deoptOffset;
|
||||
uint16_t deoptNum = callsiteHead.deoptNum;
|
||||
LLVMStackMapType::KindType kindType;
|
||||
LLVMStackMapType::DwarfRegType reg;
|
||||
LLVMStackMapType::OffsetType offsetType;
|
||||
ASSERT(deoptNum % 2 == 0); // 2:<id, value>
|
||||
for (uint32_t j = 0; j < deoptNum; j += 2) { // 2:<id, value>
|
||||
auto [vregsInfo, vregsInfoSize, InfoIsFull] =
|
||||
panda::leb128::DecodeSigned<LLVMStackMapType::SLeb128Type>(ptr + deoptOffset);
|
||||
LLVMStackMapType::DecodeVRegsInfo(vregsInfo, deopt.id, kindType);
|
||||
deoptOffset += vregsInfoSize;
|
||||
ASSERT(kindType == LLVMStackMapType::CONSTANT_TYPE || kindType == LLVMStackMapType::OFFSET_TYPE);
|
||||
if (kindType == LLVMStackMapType::CONSTANT_TYPE) {
|
||||
auto [constant, constantSize, constIsFull] =
|
||||
panda::leb128::DecodeSigned<LLVMStackMapType::SLeb128Type>(ptr + deoptOffset);
|
||||
if (constant > INT32_MAX || constant < INT32_MIN) {
|
||||
deopt.kind = LocationTy::Kind::CONSTANTNDEX;
|
||||
deopt.value = static_cast<LLVMStackMapType::LargeInt>(constant);
|
||||
} else {
|
||||
deopt.kind = LocationTy::Kind::CONSTANT;
|
||||
deopt.value = static_cast<LLVMStackMapType::IntType>(constant);
|
||||
}
|
||||
deoptOffset += constantSize;
|
||||
} else {
|
||||
auto [regOffset, regOffsetSize, regOffIsFull] =
|
||||
panda::leb128::DecodeSigned<LLVMStackMapType::SLeb128Type>(ptr + deoptOffset);
|
||||
LLVMStackMapType::DecodeRegAndOffset(regOffset, reg, offsetType);
|
||||
deopt.kind = LocationTy::Kind::INDIRECT;
|
||||
deopt.value = std::make_pair(reg, offsetType);
|
||||
deoptOffset += regOffsetSize;
|
||||
}
|
||||
deopts.emplace_back(deopt);
|
||||
}
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkStackMapAndDeopt(uint8_t *ptr, uint32_t length) const
|
||||
{
|
||||
CallsiteHeader callsiteHead;
|
||||
ArkStackMapHeader secHead;
|
||||
BinaryBufferParser binBufparser(ptr, length);
|
||||
binBufparser.ParseBuffer(&secHead, sizeof(ArkStackMapHeader));
|
||||
for (uint32_t i = 0; i < secHead.callsiteNum; i++) {
|
||||
binBufparser.ParseBuffer(&callsiteHead, sizeof(CallsiteHeader));
|
||||
std::vector<ARKDeopt> deopts;
|
||||
ArkStackMap arkStackMaps;
|
||||
LOG_COMPILER(VERBOSE) << " calliteOffset:0x" << std::hex << callsiteHead.calliteOffset
|
||||
<< " stackmap offset:0x" << std::hex << callsiteHead.stackmapOffset
|
||||
<< " num:" << callsiteHead.stackmapNum
|
||||
<< " deopt Offset:0x" << std::hex << callsiteHead.deoptOffset
|
||||
<< " num:" << callsiteHead.deoptNum;
|
||||
ParseArkStackMap(callsiteHead, ptr, arkStackMaps);
|
||||
ParseArkDeopt(callsiteHead, ptr, deopts);
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
@ -37,22 +37,20 @@ public:
|
||||
{
|
||||
enableLog_ = false;
|
||||
}
|
||||
void GetConstInfo(uintptr_t callsite, ConstInfo &info, uint8_t *stackmapAddr = nullptr) const;
|
||||
bool IteratorStackMap(const RootVisitor &visitor,
|
||||
const RootBaseAndDerivedVisitor &derivedVisitor,
|
||||
void GetConstInfo(uintptr_t callsite, LLVMStackMapType::ConstInfo& info, uint8_t *stackmapAddr = nullptr) const;
|
||||
bool IteratorStackMap(const RootVisitor& visitor,
|
||||
const RootBaseAndDerivedVisitor& derivedVisitor,
|
||||
uintptr_t callSiteAddr, uintptr_t callsiteFp,
|
||||
uintptr_t callSiteSp, uint8_t *stackmapAddr) const;
|
||||
void GetArkDeopt(uintptr_t callSiteAddr, uint8_t *stackmapAddr, std::vector<kungfu::ARKDeopt>& deopts) const;
|
||||
void GetArkDeopt(uintptr_t callSiteAddr, uint8_t *stackmapAddr, std::vector<ARKDeopt>& deopts) const;
|
||||
private:
|
||||
int BinaraySearch(CallsiteHead *callsiteHead, uint32_t callsiteNum, uintptr_t callSiteAddr) const;
|
||||
void GetArkDeopt(uint8_t *stackmapAddr, uint32_t length, const CallsiteHead& callsiteHead,
|
||||
std::vector<kungfu::ARKDeopt>& deopt) const;
|
||||
void ParseArkDeopt(const CallsiteHead& callsiteHead, BinaryBufferParser& binBufparser,
|
||||
uint8_t *ptr, std::vector<kungfu::ARKDeopt> &deopts) const;
|
||||
void ParseArkStackMap(const CallsiteHead& callsiteHead, BinaryBufferParser& binBufparser,
|
||||
uint8_t *ptr, ArkStackMap &stackMap) const;
|
||||
int BinaraySearch(CallsiteHeader *callsiteHead, uint32_t callsiteNum, uintptr_t callSiteAddr) const;
|
||||
void GetArkDeopt(uint8_t *stackmapAddr, const CallsiteHeader& callsiteHead,
|
||||
std::vector<ARKDeopt>& deopt) const;
|
||||
void ParseArkDeopt(const CallsiteHeader& callsiteHead, uint8_t *ptr, std::vector<ARKDeopt>& deopts) const;
|
||||
void ParseArkStackMap(const CallsiteHeader& callsiteHead, uint8_t *ptr, ArkStackMap& stackMap) const;
|
||||
void ParseArkStackMapAndDeopt(uint8_t *ptr, uint32_t length) const;
|
||||
uintptr_t GetStackSlotAddress(const DwarfRegAndOffsetType info,
|
||||
uintptr_t GetStackSlotAddress(const LLVMStackMapType::DwarfRegAndOffsetType info,
|
||||
uintptr_t callSiteSp, uintptr_t callsiteFp) const;
|
||||
friend class ArkStackMapBuilder;
|
||||
bool enableLog_ {false};
|
||||
|
@ -41,7 +41,7 @@ std::string LocationTy::TypeToString(Kind loc) const
|
||||
}
|
||||
}
|
||||
|
||||
const CallSiteInfo* LLVMStackMapParser::GetCallSiteInfoByPc(uintptr_t callSiteAddr) const
|
||||
const LLVMStackMapType::CallSiteInfo* LLVMStackMapParser::GetCallSiteInfoByPc(uintptr_t callSiteAddr) const
|
||||
{
|
||||
for (auto &pc2CallSiteInfo: pc2CallSiteInfoVec_) {
|
||||
auto it = pc2CallSiteInfo.find(callSiteAddr);
|
||||
@ -55,31 +55,31 @@ const CallSiteInfo* LLVMStackMapParser::GetCallSiteInfoByPc(uintptr_t callSiteAd
|
||||
void LLVMStackMapParser::CalcCallSite()
|
||||
{
|
||||
uint64_t recordNum = 0;
|
||||
Pc2CallSiteInfo pc2CallSiteInfo;
|
||||
Pc2Deopt deoptbundles;
|
||||
LLVMStackMapType::Pc2CallSiteInfo pc2CallSiteInfo;
|
||||
LLVMStackMapType::Pc2Deopt deoptbundles;
|
||||
auto calStkMapRecordFunc =
|
||||
[this, &recordNum, &pc2CallSiteInfo, &deoptbundles](uintptr_t address, uint32_t recordId) {
|
||||
struct StkMapRecordHeadTy recordHead = llvmStackMap_.StkMapRecord[recordNum + recordId].head;
|
||||
struct StkMapRecordHeadTy recordHead = llvmStackMap_.stkMapRecord[recordNum + recordId].head;
|
||||
int lastDeoptIndex = -1;
|
||||
for (int j = 0; j < recordHead.NumLocations; j++) {
|
||||
struct LocationTy loc = llvmStackMap_.StkMapRecord[recordNum + recordId].Locations[j];
|
||||
uint32_t instructionOffset = recordHead.InstructionOffset;
|
||||
for (int j = 0; j < recordHead.numLocations; j++) {
|
||||
struct LocationTy loc = llvmStackMap_.stkMapRecord[recordNum + recordId].locations[j];
|
||||
uint32_t instructionOffset = recordHead.instructionOffset;
|
||||
uintptr_t callsite = address + instructionOffset;
|
||||
uint64_t patchPointID = recordHead.PatchPointID;
|
||||
uint64_t patchPointID = recordHead.patchPointID;
|
||||
if (j == LocationTy::CONSTANT_DEOPT_CNT_INDEX) {
|
||||
ASSERT(loc.location == LocationTy::Kind::CONSTANT);
|
||||
lastDeoptIndex = loc.OffsetOrSmallConstant + LocationTy::CONSTANT_DEOPT_CNT_INDEX;
|
||||
lastDeoptIndex = loc.offsetOrSmallConstant + LocationTy::CONSTANT_DEOPT_CNT_INDEX;
|
||||
}
|
||||
if (loc.location == LocationTy::Kind::INDIRECT) {
|
||||
OPTIONAL_LOG_COMPILER(DEBUG) << "DwarfRegNum:" << loc.DwarfRegNum << " loc.OffsetOrSmallConstant:"
|
||||
<< loc.OffsetOrSmallConstant << "address:" << address << " instructionOffset:" <<
|
||||
OPTIONAL_LOG_COMPILER(DEBUG) << "DwarfRegNum:" << loc.dwarfRegNum << " loc.OffsetOrSmallConstant:"
|
||||
<< loc.offsetOrSmallConstant << "address:" << address << " instructionOffset:" <<
|
||||
instructionOffset << " callsite:" << " patchPointID :" << std::hex << patchPointID <<
|
||||
callsite;
|
||||
DwarfRegAndOffsetType info(loc.DwarfRegNum, loc.OffsetOrSmallConstant);
|
||||
LLVMStackMapType::DwarfRegAndOffsetType info(loc.dwarfRegNum, loc.offsetOrSmallConstant);
|
||||
auto it = pc2CallSiteInfo.find(callsite);
|
||||
if (j > lastDeoptIndex) {
|
||||
if (pc2CallSiteInfo.find(callsite) == pc2CallSiteInfo.end()) {
|
||||
pc2CallSiteInfo.insert(std::pair<uintptr_t, CallSiteInfo>(callsite, {info}));
|
||||
pc2CallSiteInfo.insert(std::pair<uintptr_t, LLVMStackMapType::CallSiteInfo>(callsite, {info}));
|
||||
} else {
|
||||
it->second.emplace_back(info);
|
||||
}
|
||||
@ -88,17 +88,17 @@ void LLVMStackMapParser::CalcCallSite()
|
||||
}
|
||||
} else if (loc.location == LocationTy::Kind::CONSTANT) {
|
||||
if (j >= LocationTy::CONSTANT_FIRST_ELEMENT_INDEX && j <= lastDeoptIndex) {
|
||||
deoptbundles[callsite].push_back(loc.OffsetOrSmallConstant);
|
||||
deoptbundles[callsite].push_back(loc.offsetOrSmallConstant);
|
||||
}
|
||||
} else if (loc.location == LocationTy::Kind::DIRECT) {
|
||||
if (j >= LocationTy::CONSTANT_FIRST_ELEMENT_INDEX && j <= lastDeoptIndex) {
|
||||
DwarfRegAndOffsetType info(loc.DwarfRegNum, loc.OffsetOrSmallConstant);
|
||||
LLVMStackMapType::DwarfRegAndOffsetType info(loc.dwarfRegNum, loc.offsetOrSmallConstant);
|
||||
deoptbundles[callsite].push_back(info);
|
||||
}
|
||||
} else if (loc.location == LocationTy::Kind::CONSTANTNDEX) {
|
||||
if (j >= LocationTy::CONSTANT_FIRST_ELEMENT_INDEX && j <= lastDeoptIndex) {
|
||||
LargeInt v = static_cast<LargeInt>(llvmStackMap_.
|
||||
Constants[loc.OffsetOrSmallConstant].LargeConstant);
|
||||
LLVMStackMapType::LargeInt v = static_cast<LLVMStackMapType::LargeInt>(llvmStackMap_.
|
||||
constants[loc.offsetOrSmallConstant].largeConstant);
|
||||
deoptbundles[callsite].push_back(v);
|
||||
}
|
||||
} else {
|
||||
@ -107,10 +107,10 @@ void LLVMStackMapParser::CalcCallSite()
|
||||
}
|
||||
}
|
||||
};
|
||||
for (size_t i = 0; i < llvmStackMap_.StkSizeRecords.size(); i++) {
|
||||
for (size_t i = 0; i < llvmStackMap_.stkSizeRecords.size(); i++) {
|
||||
// relative offset
|
||||
uintptr_t address = llvmStackMap_.StkSizeRecords[i].functionAddress;
|
||||
uint64_t recordCount = llvmStackMap_.StkSizeRecords[i].recordCount;
|
||||
uintptr_t address = llvmStackMap_.stkSizeRecords[i].functionAddress;
|
||||
uint64_t recordCount = llvmStackMap_.stkSizeRecords[i].recordCount;
|
||||
fun2RecordNum_.emplace_back(std::make_pair(address, recordCount));
|
||||
for (uint64_t k = 0; k < recordCount; k++) {
|
||||
calStkMapRecordFunc(address, k);
|
||||
@ -134,21 +134,21 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr<uint8_t []> stackMapA
|
||||
numConstants = dataInfo_->Read<uint32_t>();
|
||||
numRecords = dataInfo_->Read<uint32_t>();
|
||||
for (uint32_t i = 0; i < numFunctions; i++) {
|
||||
auto stkRecord = dataInfo_->Read<struct StkSizeRecordTy>();
|
||||
llvmStackMap_.StkSizeRecords.push_back(stkRecord);
|
||||
auto stkRecord = dataInfo_->Read<struct StkMapSizeRecordTy>();
|
||||
llvmStackMap_.stkSizeRecords.push_back(stkRecord);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numConstants; i++) {
|
||||
auto val = dataInfo_->Read<struct ConstantsTy>();
|
||||
llvmStackMap_.Constants.push_back(val);
|
||||
llvmStackMap_.constants.push_back(val);
|
||||
}
|
||||
for (uint32_t i = 0; i < numRecords; i++) {
|
||||
struct StkMapRecordTy stkSizeRecord;
|
||||
auto head = dataInfo_->Read<struct StkMapRecordHeadTy>();
|
||||
stkSizeRecord.head = head;
|
||||
for (uint16_t j = 0; j < head.NumLocations; j++) {
|
||||
for (uint16_t j = 0; j < head.numLocations; j++) {
|
||||
auto location = dataInfo_->Read<struct LocationTy>();
|
||||
stkSizeRecord.Locations.push_back(location);
|
||||
stkSizeRecord.locations.push_back(location);
|
||||
}
|
||||
while (dataInfo_->GetOffset() & 7) { // 7: 8 byte align
|
||||
dataInfo_->Read<uint16_t>();
|
||||
@ -157,13 +157,13 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr<uint8_t []> stackMapA
|
||||
if (numLiveOuts > 0) {
|
||||
for (uint32_t j = 0; j < numLiveOuts; j++) {
|
||||
auto liveOut = dataInfo_->Read<struct LiveOutsTy>();
|
||||
stkSizeRecord.LiveOuts.push_back(liveOut);
|
||||
stkSizeRecord.liveOuts.push_back(liveOut);
|
||||
}
|
||||
}
|
||||
while (dataInfo_->GetOffset() & 7) { // 7: 8 byte align
|
||||
dataInfo_->Read<uint16_t>();
|
||||
}
|
||||
llvmStackMap_.StkMapRecord.push_back(stkSizeRecord);
|
||||
llvmStackMap_.stkMapRecord.push_back(stkSizeRecord);
|
||||
}
|
||||
CalcCallSite();
|
||||
return true;
|
||||
@ -175,9 +175,15 @@ uint32_t ARKCallsite::CalHeadSize() const
|
||||
return headSize;
|
||||
}
|
||||
|
||||
uint32_t ARKCallsite::CalStackMapSize() const
|
||||
uint32_t ARKCallsite::CalStackMapSize(Triple triple) const
|
||||
{
|
||||
size_t stackmapSize = stackmaps.size() * (sizeof(OffsetType) + sizeof(DwarfRegType));
|
||||
size_t stackmapSize = 0;
|
||||
for (auto &x : stackmaps) {
|
||||
std::vector<uint8_t> value;
|
||||
size_t valueSize = 0;
|
||||
LLVMStackMapType::EncodeRegAndOffset(value, valueSize, x.first, x.second, triple);
|
||||
stackmapSize += value.size();
|
||||
}
|
||||
return stackmapSize;
|
||||
}
|
||||
|
||||
@ -191,10 +197,10 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr<uint8_t []> stackMapA
|
||||
|
||||
OPTIONAL_LOG_COMPILER(DEBUG) << "stackmap calculate update funcitonaddress ";
|
||||
|
||||
for (size_t i = 0; i < llvmStackMap_.StkSizeRecords.size(); i++) {
|
||||
uintptr_t hostAddr = llvmStackMap_.StkSizeRecords[i].functionAddress;
|
||||
for (size_t i = 0; i < llvmStackMap_.stkSizeRecords.size(); i++) {
|
||||
uintptr_t hostAddr = llvmStackMap_.stkSizeRecords[i].functionAddress;
|
||||
uintptr_t offset = hostAddr - hostCodeSectionAddr;
|
||||
llvmStackMap_.StkSizeRecords[i].functionAddress = offset;
|
||||
llvmStackMap_.stkSizeRecords[i].functionAddress = offset;
|
||||
OPTIONAL_LOG_COMPILER(DEBUG) << std::dec << i << "th function " << std::hex << hostAddr << " ---> "
|
||||
<< " offset:" << offset;
|
||||
}
|
||||
@ -205,9 +211,9 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr<uint8_t []> stackMapA
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLVMStackMapParser::CalculateFuncFpDelta(Func2FpDelta info, uint32_t moduleIndex)
|
||||
void LLVMStackMapParser::CalculateFuncFpDelta(LLVMStackMapType::Func2FpDelta info, uint32_t moduleIndex)
|
||||
{
|
||||
std::vector<Func2FpDelta> fun2FpDelta;
|
||||
std::vector<LLVMStackMapType::Func2FpDelta> fun2FpDelta;
|
||||
auto it = module2fun2FpDelta_.find(moduleIndex);
|
||||
if (it != module2fun2FpDelta_.end()) {
|
||||
fun2FpDelta = module2fun2FpDelta_.at(moduleIndex);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ecmascript/ecma_macros.h"
|
||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||
#include "ecmascript/stackmap/ark_stackmap.h"
|
||||
#include "ecmascript/stackmap/ark_stackmap_builder.h"
|
||||
#include "ecmascript/stackmap/llvm_stackmap_type.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
@ -40,13 +41,13 @@ public:
|
||||
llvmStackMap_.Print();
|
||||
}
|
||||
}
|
||||
const CallSiteInfo *GetCallSiteInfoByPc(uintptr_t funcAddr) const;
|
||||
const LLVMStackMapType::CallSiteInfo *GetCallSiteInfoByPc(uintptr_t funcAddr) const;
|
||||
bool IsLogEnabled() const
|
||||
{
|
||||
return enableLog_;
|
||||
}
|
||||
|
||||
void PUBLIC_API CalculateFuncFpDelta(Func2FpDelta info, uint32_t moduleIndex);
|
||||
void PUBLIC_API CalculateFuncFpDelta(LLVMStackMapType::Func2FpDelta info, uint32_t moduleIndex);
|
||||
|
||||
explicit LLVMStackMapParser(bool enableLog = false)
|
||||
{
|
||||
@ -67,25 +68,25 @@ public:
|
||||
fun2FpDelta_.clear();
|
||||
pc2DeoptVec_.clear();
|
||||
}
|
||||
std::vector<Pc2CallSiteInfo> PUBLIC_API GetPc2StackMapVec() const
|
||||
std::vector<LLVMStackMapType::Pc2CallSiteInfo> PUBLIC_API GetPc2StackMapVec() const
|
||||
{
|
||||
return pc2CallSiteInfoVec_;
|
||||
}
|
||||
std::vector<Pc2Deopt> GetPc2Deopt() const
|
||||
std::vector<LLVMStackMapType::Pc2Deopt> GetPc2Deopt() const
|
||||
{
|
||||
return pc2DeoptVec_;
|
||||
}
|
||||
private:
|
||||
void CalcCallSite();
|
||||
struct LLVMStackMap llvmStackMap_;
|
||||
std::vector<Pc2CallSiteInfo> pc2CallSiteInfoVec_;
|
||||
std::vector<LLVMStackMapType::Pc2CallSiteInfo> pc2CallSiteInfoVec_;
|
||||
std::vector<std::pair<uintptr_t, uint64_t>> fun2RecordNum_;
|
||||
std::unique_ptr<DataInfo> dataInfo_;
|
||||
bool enableLog_ {false};
|
||||
std::set<uintptr_t> funAddr_;
|
||||
std::vector<Func2FpDelta> fun2FpDelta_;
|
||||
std::vector<Pc2Deopt> pc2DeoptVec_;
|
||||
std::map<uint32_t, std::vector<Func2FpDelta>> module2fun2FpDelta_;
|
||||
std::vector<LLVMStackMapType::Func2FpDelta> fun2FpDelta_;
|
||||
std::vector<LLVMStackMapType::Pc2Deopt> pc2DeoptVec_;
|
||||
std::map<uint32_t, std::vector<LLVMStackMapType::Func2FpDelta>> module2fun2FpDelta_;
|
||||
std::map<uint32_t, std::set<uintptr_t>> module2funAddr_;
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
73
ecmascript/stackmap/llvm_stackmap_type.cpp
Normal file
73
ecmascript/stackmap/llvm_stackmap_type.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ecmascript/stackmap/llvm_stackmap_type.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
void LLVMStackMapType::EncodeRegAndOffset(std::vector<uint8_t> ®Offset, size_t ®OffsetSize,
|
||||
DwarfRegType reg, OffsetType offset, Triple triple)
|
||||
{
|
||||
SLeb128Type dwarfRegAndOff = offset;
|
||||
auto fpReg = GCStackMapRegisters::GetFpRegByTriple(triple);
|
||||
auto spReg = GCStackMapRegisters::GetSpRegByTriple(triple);
|
||||
if (reg == fpReg) {
|
||||
dwarfRegAndOff = (dwarfRegAndOff << 1) + FP_VALUE;
|
||||
} else if (reg == spReg) {
|
||||
dwarfRegAndOff = (dwarfRegAndOff << 1) + SP_VALUE;
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "dwarfreg branch is unreachable";
|
||||
UNREACHABLE();
|
||||
}
|
||||
size_t valueSize = panda::leb128::SignedEncodingSize(dwarfRegAndOff);
|
||||
regOffset.resize(valueSize);
|
||||
regOffsetSize = panda::leb128::EncodeSigned(dwarfRegAndOff, regOffset.data());
|
||||
}
|
||||
|
||||
void LLVMStackMapType::DecodeRegAndOffset(SLeb128Type regOffset, DwarfRegType ®, OffsetType &offset)
|
||||
{
|
||||
if (regOffset % STACKMAP_TYPE_NUM == LLVMStackMapType::FP_VALUE) {
|
||||
reg = GCStackMapRegisters::FP;
|
||||
} else {
|
||||
reg = GCStackMapRegisters::SP;
|
||||
}
|
||||
offset = static_cast<LLVMStackMapType::OffsetType>(regOffset >> 1);
|
||||
}
|
||||
|
||||
void LLVMStackMapType::EncodeVRegsInfo(std::vector<uint8_t> &vregsInfo, size_t &vregsInfoSize,
|
||||
VRegId id, LocationTy::Kind kind)
|
||||
{
|
||||
SLeb128Type vregIdAndKind = id;
|
||||
if (kind == LocationTy::Kind::CONSTANT || kind == LocationTy::Kind::CONSTANTNDEX) {
|
||||
vregIdAndKind = (vregIdAndKind << 1) + CONSTANT_TYPE;
|
||||
} else if (kind == LocationTy::Kind::INDIRECT) {
|
||||
vregIdAndKind = (vregIdAndKind << 1) + OFFSET_TYPE;
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "vreg kind branch is unreachable";
|
||||
UNREACHABLE();
|
||||
}
|
||||
size_t vregIdAndKindSize = panda::leb128::SignedEncodingSize(vregIdAndKind);
|
||||
vregsInfo.resize(vregIdAndKindSize);
|
||||
vregsInfoSize = panda::leb128::EncodeSigned(vregIdAndKind, vregsInfo.data());
|
||||
}
|
||||
|
||||
void LLVMStackMapType::DecodeVRegsInfo(SLeb128Type vregsInfo, VRegId &id, KindType &kind)
|
||||
{
|
||||
if (vregsInfo % STACKMAP_TYPE_NUM == CONSTANT_TYPE) {
|
||||
kind = CONSTANT_TYPE;
|
||||
} else {
|
||||
kind = OFFSET_TYPE;
|
||||
}
|
||||
id = static_cast<VRegId>(vregsInfo >> 1);
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
@ -21,27 +21,96 @@
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include "ecmascript/base/bit_helper.h"
|
||||
#include "ecmascript/common.h"
|
||||
#include "ecmascript/compiler/assembler/assembler.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/mem/mem.h"
|
||||
|
||||
#include "libpandabase/utils/leb128.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
using OffsetType = int32_t;
|
||||
using DwarfRegType = uint16_t;
|
||||
using LargeInt = int64_t;
|
||||
using DwarfRegAndOffsetType = std::pair<DwarfRegType, OffsetType>;
|
||||
using CallSiteInfo = std::vector<DwarfRegAndOffsetType>;
|
||||
using Fun2InfoType = std::pair<uintptr_t, DwarfRegAndOffsetType>;
|
||||
using Pc2CallSiteInfo = std::unordered_map<uintptr_t, CallSiteInfo>;
|
||||
using FpDelta = std::pair<int, uint32_t>;
|
||||
using Func2FpDelta = std::unordered_map<uintptr_t, FpDelta>; // value: fpDelta & funcSize
|
||||
using ConstInfo = std::vector<OffsetType>;
|
||||
using DeoptInfoType = std::vector<std::variant<OffsetType, LargeInt, DwarfRegAndOffsetType>>;
|
||||
using Pc2Deopt = std::unordered_map<uintptr_t, DeoptInfoType>;
|
||||
struct LocationTy {
|
||||
enum class Kind: uint8_t {
|
||||
REGISTER = 1,
|
||||
DIRECT = 2,
|
||||
INDIRECT = 3,
|
||||
CONSTANT = 4,
|
||||
CONSTANTNDEX = 5,
|
||||
};
|
||||
static constexpr int CONSTANT_FIRST_ELEMENT_INDEX = 3;
|
||||
static constexpr int CONSTANT_DEOPT_CNT_INDEX = 2;
|
||||
|
||||
Kind location;
|
||||
uint8_t reserved_0;
|
||||
uint16_t locationSize;
|
||||
uint16_t dwarfRegNum;
|
||||
uint16_t reserved_1;
|
||||
int32_t offsetOrSmallConstant;
|
||||
|
||||
std::string PUBLIC_API TypeToString(Kind loc) const;
|
||||
|
||||
void Print() const
|
||||
{
|
||||
LOG_COMPILER(DEBUG) << TypeToString(location);
|
||||
LOG_COMPILER(DEBUG) << ", size:" << std::dec << locationSize;
|
||||
LOG_COMPILER(DEBUG) << "\tDwarfRegNum:" << dwarfRegNum;
|
||||
LOG_COMPILER(DEBUG) << "\t OffsetOrSmallConstant:" << offsetOrSmallConstant;
|
||||
}
|
||||
};
|
||||
|
||||
class LLVMStackMapType {
|
||||
public:
|
||||
using OffsetType = int32_t;
|
||||
using DwarfRegType = uint16_t;
|
||||
using IntType = int32_t;
|
||||
using LargeInt = int64_t;
|
||||
using RegType = int8_t;
|
||||
using KindType = int8_t;
|
||||
using VRegId = int16_t;
|
||||
using SLeb128Type = int64_t;
|
||||
using DwarfRegAndOffsetType = std::pair<DwarfRegType, OffsetType>;
|
||||
using CallSiteInfo = std::vector<DwarfRegAndOffsetType>;
|
||||
using Fun2InfoType = std::pair<uintptr_t, DwarfRegAndOffsetType>;
|
||||
using Pc2CallSiteInfo = std::unordered_map<uintptr_t, CallSiteInfo>;
|
||||
using FpDelta = std::pair<int, uint32_t>;
|
||||
using Func2FpDelta = std::unordered_map<uintptr_t, FpDelta>; // value: fpDelta & funcSize
|
||||
using ConstInfo = std::vector<IntType>;
|
||||
using DeoptInfoType = std::vector<std::variant<IntType, LargeInt, DwarfRegAndOffsetType>>;
|
||||
using Pc2Deopt = std::unordered_map<uintptr_t, DeoptInfoType>;
|
||||
|
||||
static constexpr size_t STACKMAP_ALIGN_BYTES = 2;
|
||||
static constexpr KindType CONSTANT_TYPE = 0;
|
||||
static constexpr KindType OFFSET_TYPE = 1;
|
||||
|
||||
template <typename T>
|
||||
static void EncodeData(std::vector<uint8_t> &outData, size_t &dataSize, T value)
|
||||
{
|
||||
static_assert(std::is_signed_v<T>, "T must be signed");
|
||||
SLeb128Type data = value;
|
||||
size_t valueSize = panda::leb128::SignedEncodingSize(data);
|
||||
outData.resize(valueSize);
|
||||
dataSize = panda::leb128::EncodeSigned(data, outData.data());
|
||||
}
|
||||
|
||||
static void EncodeRegAndOffset(std::vector<uint8_t> ®Offset, size_t ®OffsetSize,
|
||||
DwarfRegType reg, OffsetType offset, Triple triple);
|
||||
static void DecodeRegAndOffset(SLeb128Type regOffset, DwarfRegType ®, OffsetType &offset);
|
||||
static void EncodeVRegsInfo(std::vector<uint8_t> &vregsInfo, size_t &vregsInfoSize,
|
||||
VRegId id, LocationTy::Kind kind);
|
||||
static void DecodeVRegsInfo(SLeb128Type vregsInfo, VRegId &id, KindType &kind);
|
||||
|
||||
private:
|
||||
static constexpr size_t STACKMAP_TYPE_NUM = 2;
|
||||
static constexpr RegType FP_VALUE = 0;
|
||||
static constexpr RegType SP_VALUE = 1;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
uint8_t stackmapversion; // Stack Map Version (current version is 3)
|
||||
uint8_t Reserved0; // Reserved (expected to be 0)
|
||||
uint16_t Reserved1; // Reserved (expected to be 0)
|
||||
uint8_t reserved0; // Reserved (expected to be 0)
|
||||
uint16_t reserved1; // Reserved (expected to be 0)
|
||||
void Print() const
|
||||
{
|
||||
LOG_COMPILER(DEBUG) << "----- head ----";
|
||||
@ -51,7 +120,7 @@ struct Header {
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct StkSizeRecordTy {
|
||||
struct StkMapSizeRecordTy {
|
||||
uintptr_t functionAddress;
|
||||
uint64_t stackSize;
|
||||
uint64_t recordCount;
|
||||
@ -65,79 +134,50 @@ struct StkSizeRecordTy {
|
||||
#pragma pack()
|
||||
|
||||
struct ConstantsTy {
|
||||
uintptr_t LargeConstant;
|
||||
uintptr_t largeConstant;
|
||||
void Print() const
|
||||
{
|
||||
LOG_COMPILER(DEBUG) << " LargeConstant:0x" << std::hex << LargeConstant;
|
||||
LOG_COMPILER(DEBUG) << " LargeConstant:0x" << std::hex << largeConstant;
|
||||
}
|
||||
};
|
||||
|
||||
struct StkMapRecordHeadTy {
|
||||
uint64_t PatchPointID;
|
||||
uint32_t InstructionOffset;
|
||||
uint16_t Reserved;
|
||||
uint16_t NumLocations;
|
||||
uint64_t patchPointID;
|
||||
uint32_t instructionOffset;
|
||||
uint16_t reserved;
|
||||
uint16_t numLocations;
|
||||
void Print() const
|
||||
{
|
||||
LOG_COMPILER(DEBUG) << " PatchPointID:0x" << std::hex << PatchPointID;
|
||||
LOG_COMPILER(DEBUG) << " instructionOffset:0x" << std::hex << InstructionOffset;
|
||||
LOG_COMPILER(DEBUG) << " Reserved:0x" << std::hex << Reserved;
|
||||
LOG_COMPILER(DEBUG) << " NumLocations:0x" << std::hex << NumLocations;
|
||||
LOG_COMPILER(DEBUG) << " PatchPointID:0x" << std::hex << patchPointID;
|
||||
LOG_COMPILER(DEBUG) << " instructionOffset:0x" << std::hex << instructionOffset;
|
||||
LOG_COMPILER(DEBUG) << " Reserved:0x" << std::hex << reserved;
|
||||
LOG_COMPILER(DEBUG) << " NumLocations:0x" << std::hex << numLocations;
|
||||
}
|
||||
};
|
||||
|
||||
struct LocationTy {
|
||||
enum class Kind: uint8_t {
|
||||
REGISTER = 1,
|
||||
DIRECT = 2,
|
||||
INDIRECT = 3,
|
||||
CONSTANT = 4,
|
||||
CONSTANTNDEX = 5,
|
||||
};
|
||||
static constexpr int CONSTANT_FIRST_ELEMENT_INDEX = 3;
|
||||
static constexpr int CONSTANT_DEOPT_CNT_INDEX = 2;
|
||||
Kind location;
|
||||
uint8_t Reserved_0;
|
||||
uint16_t LocationSize;
|
||||
uint16_t DwarfRegNum;
|
||||
uint16_t Reserved_1;
|
||||
OffsetType OffsetOrSmallConstant;
|
||||
|
||||
std::string PUBLIC_API TypeToString(Kind loc) const;
|
||||
|
||||
void Print() const
|
||||
{
|
||||
LOG_COMPILER(DEBUG) << TypeToString(location);
|
||||
LOG_COMPILER(DEBUG) << ", size:" << std::dec << LocationSize;
|
||||
LOG_COMPILER(DEBUG) << "\tDwarfRegNum:" << DwarfRegNum;
|
||||
LOG_COMPILER(DEBUG) << "\t OffsetOrSmallConstant:" << OffsetOrSmallConstant;
|
||||
}
|
||||
};
|
||||
|
||||
struct LiveOutsTy {
|
||||
DwarfRegType DwarfRegNum;
|
||||
uint8_t Reserved;
|
||||
uint8_t SizeinBytes;
|
||||
LLVMStackMapType::DwarfRegType dwarfRegNum;
|
||||
uint8_t reserved;
|
||||
uint8_t sizeinBytes;
|
||||
void Print() const
|
||||
{
|
||||
LOG_COMPILER(DEBUG) << " Dwarf RegNum:" << DwarfRegNum;
|
||||
LOG_COMPILER(DEBUG) << " Reserved:" << Reserved;
|
||||
LOG_COMPILER(DEBUG) << " SizeinBytes:" << SizeinBytes;
|
||||
LOG_COMPILER(DEBUG) << " Dwarf RegNum:" << dwarfRegNum;
|
||||
LOG_COMPILER(DEBUG) << " Reserved:" << reserved;
|
||||
LOG_COMPILER(DEBUG) << " SizeinBytes:" << sizeinBytes;
|
||||
}
|
||||
};
|
||||
struct StkMapRecordTy {
|
||||
struct StkMapRecordHeadTy head;
|
||||
std::vector<struct LocationTy> Locations;
|
||||
std::vector<struct LiveOutsTy> LiveOuts;
|
||||
std::vector<struct LocationTy> locations;
|
||||
std::vector<struct LiveOutsTy> liveOuts;
|
||||
void Print() const
|
||||
{
|
||||
head.Print();
|
||||
auto size = Locations.size();
|
||||
auto size = locations.size();
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
LOG_COMPILER(DEBUG) << " #" << std::dec << i << ":";
|
||||
Locations[i].Print();
|
||||
locations[i].Print();
|
||||
}
|
||||
size = LiveOuts.size();
|
||||
size = liveOuts.size();
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
LOG_COMPILER(DEBUG) << " liveOuts[" << i << "] info:";
|
||||
}
|
||||
@ -170,23 +210,23 @@ private:
|
||||
|
||||
struct LLVMStackMap {
|
||||
struct Header head;
|
||||
std::vector<struct StkSizeRecordTy> StkSizeRecords;
|
||||
std::vector<struct ConstantsTy> Constants;
|
||||
std::vector<struct StkMapRecordTy> StkMapRecord;
|
||||
std::vector<struct StkMapSizeRecordTy> stkSizeRecords;
|
||||
std::vector<struct ConstantsTy> constants;
|
||||
std::vector<struct StkMapRecordTy> stkMapRecord;
|
||||
void Print() const
|
||||
{
|
||||
head.Print();
|
||||
for (size_t i = 0; i < StkSizeRecords.size(); i++) {
|
||||
LOG_COMPILER(DEBUG) << "stkSizeRecord[" << i << "] info:";
|
||||
StkSizeRecords[i].Print();
|
||||
for (size_t i = 0; i < stkSizeRecords.size(); i++) {
|
||||
LOG_COMPILER(DEBUG) << "StkSizeRecord[" << i << "] info:";
|
||||
stkSizeRecords[i].Print();
|
||||
}
|
||||
for (size_t i = 0; i < Constants.size(); i++) {
|
||||
LOG_COMPILER(DEBUG) << "constants[" << i << "] info:";
|
||||
Constants[i].Print();
|
||||
for (size_t i = 0; i < constants.size(); i++) {
|
||||
LOG_COMPILER(DEBUG) << "Constants[" << i << "] info:";
|
||||
constants[i].Print();
|
||||
}
|
||||
for (size_t i = 0; i < StkMapRecord.size(); i++) {
|
||||
for (size_t i = 0; i < stkMapRecord.size(); i++) {
|
||||
LOG_COMPILER(DEBUG) << "StkMapRecord[" << i << "] info:";
|
||||
StkMapRecord[i].Print();
|
||||
stkMapRecord[i].Print();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user