Optimize AOT memory

Support encode stackmap data and release stackmap data timely

Issue: IAHH00
Test: Build & Boot devices
Change-Id: I5335dce1fcfe7deee752d4be196120a2fd8ef334
Signed-off-by: w00443755 <wangzhilei2@huawei.com>
This commit is contained in:
w00443755 2024-08-02 14:50:54 +08:00
parent 7cf3dcb977
commit a73b9c5947
14 changed files with 112 additions and 54 deletions

View File

@ -100,15 +100,15 @@ struct CodeInfo {
void SaveFunc2CalleeOffsetInfo(std::string funcName, kungfu::CalleeRegAndOffsetVec calleeRegInfo);
void SavePC2DeoptInfo(uint64_t pc, std::vector<uint64_t> pc2DeoptInfo);
void SavePC2DeoptInfo(uint64_t pc, std::vector<uint8_t> pc2DeoptInfo);
void SavePC2CallSiteInfo(uint64_t pc, std::vector<uint64_t> callSiteInfo);
void SavePC2CallSiteInfo(uint64_t pc, std::vector<uint8_t> callSiteInfo);
const std::map<std::string, FuncInfo> &GetFuncInfos() const;
const std::map<uint64_t, std::vector<uint64_t>> &GetPC2DeoptInfo() const;
const std::map<uint64_t, std::vector<uint8_t>> &GetPC2DeoptInfo() const;
const std::unordered_map<uint64_t, std::vector<uint64_t>> &GetPC2CallsiteInfo() const;
const std::unordered_map<uint64_t, std::vector<uint8_t>> &GetPC2CallsiteInfo() const;
void Reset();
@ -133,8 +133,8 @@ private:
std::array<sectionInfo, static_cast<int>(ElfSecName::SIZE)> secInfos_;
std::vector<std::pair<uint8_t *, uintptr_t>> codeInfo_ {}; // info for disasssembler, planed to be deprecated
std::map<std::string, FuncInfo> func2FuncInfo;
std::map<uint64_t, std::vector<uint64_t>> pc2DeoptInfo;
std::unordered_map<uint64_t, std::vector<uint64_t>> pc2CallsiteInfo;
std::map<uint64_t, std::vector<uint8_t>> pc2DeoptInfo;
std::unordered_map<uint64_t, std::vector<uint8_t>> pc2CallsiteInfo;
bool alreadyPageAlign_ {false};
CodeSpaceOnDemand &codeSpaceOnDemand_;
};

View File

@ -283,14 +283,14 @@ void CodeInfo::SaveFunc2CalleeOffsetInfo(std::string funcName, kungfu::CalleeReg
std::pair<std::string, FuncInfo>(funcName, {0, 0, calleeRegInfo}));
}
void CodeInfo::SavePC2DeoptInfo(uint64_t pc, std::vector<uint64_t> deoptInfo)
void CodeInfo::SavePC2DeoptInfo(uint64_t pc, std::vector<uint8_t> deoptInfo)
{
pc2DeoptInfo.insert(std::pair<uint64_t, std::vector<uint64_t>>(pc, deoptInfo));
pc2DeoptInfo.insert(std::pair<uint64_t, std::vector<uint8_t>>(pc, deoptInfo));
}
void CodeInfo::SavePC2CallSiteInfo(uint64_t pc, std::vector<uint64_t> callSiteInfo)
void CodeInfo::SavePC2CallSiteInfo(uint64_t pc, std::vector<uint8_t> callSiteInfo)
{
pc2CallsiteInfo.insert(std::pair<uint64_t, std::vector<uint64_t>>(pc, callSiteInfo));
pc2CallsiteInfo.insert(std::pair<uint64_t, std::vector<uint8_t>>(pc, callSiteInfo));
}
const std::map<std::string, CodeInfo::FuncInfo> &CodeInfo::GetFuncInfos() const
@ -298,12 +298,12 @@ const std::map<std::string, CodeInfo::FuncInfo> &CodeInfo::GetFuncInfos() const
return func2FuncInfo;
}
const std::map<uint64_t, std::vector<uint64_t>> &CodeInfo::GetPC2DeoptInfo() const
const std::map<uint64_t, std::vector<uint8_t>> &CodeInfo::GetPC2DeoptInfo() const
{
return pc2DeoptInfo;
}
const std::unordered_map<uint64_t, std::vector<uint64_t>> &CodeInfo::GetPC2CallsiteInfo() const
const std::unordered_map<uint64_t, std::vector<uint8_t>> &CodeInfo::GetPC2CallsiteInfo() const
{
return pc2CallsiteInfo;
}

View File

@ -83,13 +83,13 @@ static void SaveFunc2CalleeOffsetInfo(void *object, std::string funcName, kungfu
state.SaveFunc2CalleeOffsetInfo(funcName, calleeRegInfo);
}
static void SavePC2DeoptInfo(void *object, uint64_t pc, std::vector<uint64_t> deoptInfo)
static void SavePC2DeoptInfo(void *object, uint64_t pc, std::vector<uint8_t> deoptInfo)
{
struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
state.SavePC2DeoptInfo(pc, deoptInfo);
}
void SavePC2CallSiteInfo(void *object, uint64_t pc, std::vector<uint64_t> callSiteInfo)
void SavePC2CallSiteInfo(void *object, uint64_t pc, std::vector<uint8_t> callSiteInfo)
{
struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
state.SavePC2CallSiteInfo(pc, callSiteInfo);

View File

@ -41,9 +41,9 @@ typedef void (*MemoryManagerSaveFunc2FPtoPrevSPDeltaCallback)(void *object, std:
typedef void (*MemoryManagerSaveFunc2CalleeOffsetInfoCallback)(void *object, std::string funcName,
std::vector<std::pair<uint16_t, int32_t>> calleeRegInfo);
typedef void (*MemoryManagerSavePC2DeoptInfoCallback)(void *object, uint64_t pc, std::vector<uint64_t> deoptInfo);
typedef void (*MemoryManagerSavePC2DeoptInfoCallback)(void *object, uint64_t pc, std::vector<uint8_t> deoptInfo);
typedef void (*MemoryManagerSavePC2CallSiteInfoCallback)(void *object, uint64_t pc, std::vector<uint64_t> callSiteInfo);
typedef void (*MemoryManagerSavePC2CallSiteInfoCallback)(void *object, uint64_t pc, std::vector<uint8_t> callSiteInfo);
class CGOptions {
public:

View File

@ -160,8 +160,8 @@ public:
virtual ~ObjFuncEmitInfo() = default;
struct StackMapInfo {
const std::vector<uint64> referenceMap;
const std::vector<uint64> deoptInfo;
const std::vector<uint8> referenceMap;
const std::vector<uint8> deoptInfo;
};
uint32 GetEndOffset() const
@ -366,13 +366,13 @@ public:
return itr->second;
}
void RecordOffset2StackMapInfo(size_t offset, const std::vector<uint64> &referenceMap,
const std::vector<uint64> deoptInfo)
void RecordOffset2StackMapInfo(size_t offset, const std::vector<uint8> &referenceMap,
const std::vector<uint8> deoptInfo)
{
offset2StackMapInfo.insert(std::pair<size_t, StackMapInfo>(offset, {referenceMap, deoptInfo}));
}
const MapleUnorderedMap<size_t, StackMapInfo> &GetOffset2StackMapInfo() const
MapleUnorderedMap<size_t, StackMapInfo> &GetOffset2StackMapInfo()
{
return offset2StackMapInfo;
}

View File

@ -710,7 +710,9 @@ public:
fpCalleeRegSet(alloc.Adapter()),
fpParamRegSet(alloc.Adapter()),
fpSpillRegSet(alloc.Adapter()),
loopBBRegSet(alloc.Adapter()),
bfs(bbSort),
regUsedInBB(alloc.Adapter()),
liQue(alloc.Adapter()),
splitPosMap(alloc.Adapter()),
splitInsnMap(alloc.Adapter()),
@ -824,14 +826,14 @@ private:
MapleSet<uint32> fpCalleeRegSet; /* callee */
MapleSet<uint32> fpParamRegSet; /* parameter */
MapleVector<uint32> fpSpillRegSet; /* float regs put aside for spills */
std::unordered_set<uint32> loopBBRegSet;
MapleUnorderedSet<uint32> loopBBRegSet;
Bfs *bfs = nullptr;
uint32 fpCallerMask = 0; /* bit mask for all possible caller fp */
uint32 fpCalleeMask = 0; /* callee */
uint32 fpParamMask = 0; /* (physical-register) parameter */
uint64 blockForbiddenMask = 0; /* bit mask for forbidden physical reg */
uint32 debugSpillCnt = 0;
std::vector<uint64> regUsedInBB;
MapleVector<uint64> regUsedInBB;
uint32 maxInsnNum = 0;
regno_t minVregNum = 0xFFFFFFFF;
regno_t maxVregNum = 0;

View File

@ -41,7 +41,31 @@ struct DeoptVregLocationInfo {
DeoptVregLocationInfo(int32 vreg, LocationInfo info) : deoptVreg(vreg), locationInfo(info) {}
};
class DeoptInfo {
class DataEncoder {
public:
void EncodeLEB128(int64 value, std::vector<uint8_t> &res) const
{
bool needDecodeNextByte = true;
while (needDecodeNextByte) {
uint8 byte = static_cast<uint8>(static_cast<uint64_t>(value) & LOW_7_BITS_MASK);
value >>= DATA_BITS_SHIFT;
if ((value == 0 && (byte & FLAG_MASK) == 0) ||
(value == -1 && (byte & FLAG_MASK) != 0)) {
needDecodeNextByte = false;
} else {
byte |= NEXT_BYTE_FLAG_MASK;
}
res.push_back(byte);
}
}
private:
const uint8 FLAG_MASK = 0x40;
const uint8 LOW_7_BITS_MASK = 0x7f;
const uint8 NEXT_BYTE_FLAG_MASK = 0x80;
const uint8 DATA_BITS_SHIFT = 7;
};
class DeoptInfo : public DataEncoder {
public:
DeoptInfo(MapleAllocator &alloc) : deoptVreg2Opnd(alloc.Adapter()), deoptVreg2LocationInfo(alloc.Adapter()) {}
~DeoptInfo() = default;
@ -85,13 +109,13 @@ public:
}
}
std::vector<uint64> SerializeInfo() const
std::vector<uint8> SerializeInfo() const
{
std::vector<uint64> info;
std::vector<uint8> info;
for (const auto &elem : deoptVreg2LocationInfo) {
info.push_back(static_cast<uint64_t>(elem.deoptVreg));
info.push_back(static_cast<uint64_t>(elem.locationInfo.locationKind));
info.push_back(static_cast<uint64_t>(elem.locationInfo.value));
EncodeLEB128(static_cast<int64_t>(elem.deoptVreg), info);
EncodeLEB128(static_cast<int64_t>(elem.locationInfo.locationKind), info);
EncodeLEB128(static_cast<int64_t>(elem.locationInfo.value), info);
}
return info;
}
@ -102,7 +126,7 @@ private:
MapleVector<DeoptVregLocationInfo> deoptVreg2LocationInfo;
};
class ReferenceMap {
class ReferenceMap : public DataEncoder {
public:
ReferenceMap(MapleAllocator &alloc) : referenceLocations(alloc.Adapter()) {}
~ReferenceMap() = default;
@ -132,12 +156,12 @@ public:
}
}
std::vector<uint64> SerializeInfo() const
std::vector<uint8> SerializeInfo() const
{
std::vector<uint64> info;
std::vector<uint8> info;
for (const auto &elem : referenceLocations) {
info.push_back(static_cast<uint64_t>(elem.locationKind));
info.push_back(static_cast<uint64_t>(elem.value));
EncodeLEB128(static_cast<int64_t>(elem.locationKind), info);
EncodeLEB128(static_cast<int64_t>(elem.value), info);
}
return info;
}

View File

@ -356,7 +356,7 @@ public:
void Sqrtsd_r(Reg srcReg, Reg destReg) override;
/* end of X64 instructions */
/* process stackmap */
void RecordStackmap(const std::vector<uint64> &referenceMap, const std::vector<uint64> &deoptInfo) override {}
void RecordStackmap(const std::vector<uint8> &referenceMap, const std::vector<uint8> &deoptInfo) override {}
uint32 GetCurModulePC() override { return 0; }
void SetLastModulePC(uint32 pc) override {}

View File

@ -377,7 +377,7 @@ public:
virtual void Sqrtsd_r(Reg srcReg, Reg destReg) = 0;
/* end of X64 instructions */
/* process stackmap */
virtual void RecordStackmap(const std::vector<uint64> &referenceMap, const std::vector<uint64> &deoptInfo) = 0;
virtual void RecordStackmap(const std::vector<uint8> &referenceMap, const std::vector<uint8> &deoptInfo) = 0;
virtual uint32 GetCurModulePC() = 0;
virtual void SetLastModulePC(uint32 pc) = 0;

View File

@ -358,8 +358,8 @@ public:
void Sqrtsd_r(Reg srcReg, Reg destReg) override;
/* end of X64 instructions */
/* process stackmap */
void RecordStackmap(const std::vector<uint64> &referenceMap,
const std::vector<uint64> &deoptVreg2LocationInfo) override;
void RecordStackmap(const std::vector<uint8> &referenceMap,
const std::vector<uint8> &deoptVreg2LocationInfo) override;
uint32 GetCurModulePC() override;
void SetLastModulePC(uint32 pc) override;

View File

@ -260,7 +260,7 @@ void AArch64ObjEmitter::AppendGlobalLabel()
emitMemoryManager.funcAddressSaver(emitMemoryManager.codeSpace, funcName, offset);
}
if (emitMemoryManager.codeSpace != nullptr) {
const auto &offset2StackMapInfo = content->GetOffset2StackMapInfo();
auto &offset2StackMapInfo = content->GetOffset2StackMapInfo();
for (const auto &elem : offset2StackMapInfo) {
const auto &stackMapInfo = elem.second;
emitMemoryManager.pc2CallSiteInfoSaver(
@ -268,6 +268,7 @@ void AArch64ObjEmitter::AppendGlobalLabel()
emitMemoryManager.pc2DeoptInfoSaver(emitMemoryManager.codeSpace, content->GetStartOffset() + elem.first,
stackMapInfo.deoptInfo);
}
offset2StackMapInfo.clear();
}
offset += content->GetTextDataSize();

View File

@ -2334,8 +2334,8 @@ void ElfAssembler::Sqrtsd_r(Reg srcReg, Reg destReg)
/* end of X64 instructions */
/* process stackmap */
void ElfAssembler::RecordStackmap(const std::vector<uint64> &referenceMap,
const std::vector<uint64> &deoptVreg2LocationInfo)
void ElfAssembler::RecordStackmap(const std::vector<uint8> &referenceMap,
const std::vector<uint8> &deoptVreg2LocationInfo)
{
const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager();
if (emitMemoryManager.codeSpace == nullptr) {

View File

@ -15,6 +15,35 @@
#include "ecmascript/stackmap/litecg/litecg_stackmap_type.h"
namespace panda::ecmascript::kungfu {
static int64_t DecodeSLEB128(const std::vector<uint8_t> &bytes, size_t &index)
{
uint64_t res = 0;
bool isNegative = false;
uint64_t shift = 0;
constexpr uint8_t FLAG_MASK = 0x40;
constexpr uint8_t LOW_7_BITS_MASK = 0x7f;
constexpr uint8_t NEXT_BYTE_FLAG_MASK = 0x80;
constexpr uint8_t DATA_BITS_SHIFT = 7;
bool needDecodeNextByte = false;
do {
needDecodeNextByte = ((bytes[index] & NEXT_BYTE_FLAG_MASK) != 0);
uint8_t low7Bit = (bytes[index] & LOW_7_BITS_MASK);
res |= (static_cast<uint64_t>(low7Bit) << shift);
shift += DATA_BITS_SHIFT;
if (needDecodeNextByte) {
index++;
} else {
isNegative = ((bytes[index] & FLAG_MASK) != 0);
}
} while (needDecodeNextByte);
index++;
if (isNegative) {
res |= static_cast<uint64_t>(-static_cast<int64_t>(1 << shift));
}
return static_cast<int64_t>(res);
}
void LiteCGStackMapInfo::ConvertToLLVMStackMapInfo(
std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2StackMapsVec,
std::vector<LLVMStackMapType::Pc2Deopt> &pc2DeoptInfoVec, Triple triple) const
@ -23,12 +52,13 @@ void LiteCGStackMapInfo::ConvertToLLVMStackMapInfo(
for (const auto &callSiteInfo : pc2CallSiteInfoVec_) {
LLVMStackMapType::Pc2CallSiteInfo pc2CallSiteInfo;
for (const auto &elem : callSiteInfo) {
const std::vector<uint64_t> &litecgCallSiteInfo = elem.second;
const std::vector<uint8_t> &litecgCallSiteInfo = elem.second;
LLVMStackMapType::CallSiteInfo llvmCallSiteInfo;
// parse std::vector<uint64_t>
for (size_t i = 0; i < litecgCallSiteInfo.size(); i += 2) { // add 2 each time for kind and value
uint64_t kind = litecgCallSiteInfo[i];
uint64_t value = litecgCallSiteInfo[i + 1];
// parse std::vector<uint8_t>
size_t index = 0;
while (index < litecgCallSiteInfo.size()) {
int64_t kind = DecodeSLEB128(litecgCallSiteInfo, index);
int64_t value = DecodeSLEB128(litecgCallSiteInfo, index);
if (kind == 2) { // kind is 2 means register
llvmCallSiteInfo.push_back(std::pair<uint16_t, uint32_t>(0xFFFFU, static_cast<int32_t>(value)));
} else if (kind == 1) { // stack
@ -46,13 +76,14 @@ void LiteCGStackMapInfo::ConvertToLLVMStackMapInfo(
for (const auto &deoptInfo : pc2DeoptVec_) {
LLVMStackMapType::Pc2Deopt pc2DeoptInfo;
for (const auto &elem : deoptInfo) {
const std::vector<uint64_t> &litecgDeoptInfo = elem.second;
const std::vector<uint8_t> &litecgDeoptInfo = elem.second;
LLVMStackMapType::DeoptInfoType llvmDeoptInfo;
// parse std::vector<uint64_t>
for (size_t i = 0; i < litecgDeoptInfo.size(); i += 3) { // add 3 each time for deoptVreg, kind and value
uint64_t deoptVreg = litecgDeoptInfo[i];
uint64_t kind = litecgDeoptInfo[i + 1];
uint64_t value = litecgDeoptInfo[i + 2];
// parse std::vector<uint8_t>
size_t index = 0;
while (index < litecgDeoptInfo.size()) {
int64_t deoptVreg = DecodeSLEB128(litecgDeoptInfo, index);
int64_t kind = DecodeSLEB128(litecgDeoptInfo, index);
int64_t value = DecodeSLEB128(litecgDeoptInfo, index);
llvmDeoptInfo.push_back(static_cast<int32_t>(deoptVreg));
if (kind == 2) { // kind is 2 means register
llvmDeoptInfo.push_back(std::pair<uint16_t, uint32_t>(0xFFFFU, static_cast<int32_t>(value)));

View File

@ -24,8 +24,8 @@
namespace panda::ecmascript::kungfu {
class LiteCGStackMapType {
public:
using Pc2CallSiteInfo = std::unordered_map<uint64_t, std::vector<uint64_t>>;
using Pc2Deopt = std::map<uint64_t, std::vector<uint64_t>>;
using Pc2CallSiteInfo = std::unordered_map<uint64_t, std::vector<uint8_t>>;
using Pc2Deopt = std::map<uint64_t, std::vector<uint8_t>>;
};
class LiteCGStackMapInfo : public CGStackMapInfo {