mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-12 23:29:14 +00:00
add stack map
Signed-off-by: songzhengchao <songzhengchao@huawei.com>
This commit is contained in:
parent
ac567731db
commit
67f43f8ec4
@ -47,7 +47,7 @@ struct ARKDeopt {
|
||||
struct ARKCallsite {
|
||||
CallsiteHead head;
|
||||
CallSiteInfo stackmaps;
|
||||
std::vector<ARKDeopt> callsite2Deopt;
|
||||
std::vector<kungfu::ARKDeopt> callsite2Deopt;
|
||||
bool operator < (const ARKCallsite & x) const
|
||||
{
|
||||
return head.calliteOffset < x.head.calliteOffset;
|
||||
@ -61,6 +61,7 @@ struct ARKCallsitePackInfo {
|
||||
std::vector<ARKCallsite> callsites;
|
||||
};
|
||||
using ArkStackMap = CallSiteInfo;
|
||||
using CalleeRegAndOffsetVec = std::vector<DwarfRegAndOffsetType>;
|
||||
/*
|
||||
totalSize callsiteNum callsitStart callsitEnd
|
||||
-----head1--------
|
||||
@ -81,10 +82,5 @@ totalSize callsiteNum callsitStart callsitEnd
|
||||
- INDIRECT <loc.DwarfRegNum, loc.OffsetOrSmallConstant>
|
||||
- CONSTANTNDEX <LargeInt>
|
||||
*/
|
||||
enum class SpecVregIndex: int {
|
||||
PC_INDEX = -1,
|
||||
ACC_INDEX = -2,
|
||||
BC_OFFSET_INDEX = -3,
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_ARK_STACKMAP_H
|
@ -131,9 +131,9 @@ void ArkStackMapParser::ParseArkStackMap(const CallsiteHead& callsiteHead, Binar
|
||||
}
|
||||
|
||||
void ArkStackMapParser::ParseArkDeopt(const CallsiteHead& callsiteHead,
|
||||
BinaryBufferParser& binBufparser, uint8_t *ptr, std::vector<ARKDeopt> &deopts) const
|
||||
BinaryBufferParser& binBufparser, uint8_t *ptr, std::vector<kungfu::ARKDeopt> &deopts) const
|
||||
{
|
||||
ARKDeopt deopt;
|
||||
kungfu::ARKDeopt deopt;
|
||||
uint32_t deoptOffset = callsiteHead.deoptOffset;
|
||||
uint32_t deoptNum = callsiteHead.deoptNum;
|
||||
OffsetType id;
|
||||
@ -196,7 +196,7 @@ void ArkStackMapParser::ParseArkStackMapAndDeopt(uint8_t *ptr, uint32_t length)
|
||||
uint32_t arkStackMapNum = callsiteHead.arkStackMapNum;
|
||||
uint32_t deoptOffset = callsiteHead.deoptOffset;
|
||||
uint32_t deoptNum = callsiteHead.deoptNum;
|
||||
std::vector<ARKDeopt> deopts;
|
||||
std::vector<kungfu::ARKDeopt> deopts;
|
||||
ArkStackMap arkStackMaps;
|
||||
LOG_COMPILER(VERBOSE) << " calliteOffset:0x" << std::hex << callsiteHead.calliteOffset
|
||||
<< " stackmap offset:0x" << std::hex << offset << " num:" << arkStackMapNum
|
||||
@ -263,7 +263,7 @@ int ArkStackMapBuilder::FindLoc(std::vector<intptr_t> &CallsitePcs, intptr_t pc)
|
||||
}
|
||||
|
||||
void ArkStackMapBuilder::GenARKDeopt(const DeoptInfoType& deopt, std::pair<uint32_t,
|
||||
std::vector<ARKDeopt>> &sizeAndArkDeopt)
|
||||
std::vector<kungfu::ARKDeopt>> &sizeAndArkDeopt)
|
||||
{
|
||||
ASSERT(deopt.size() % 2 == 0); // 2:<id, value>
|
||||
uint32_t total = 0;
|
||||
@ -334,7 +334,7 @@ void ArkStackMapBuilder::GenArkCallsitePackInfo(std::vector<Pc2CallSiteInfo> &pc
|
||||
result.callsites[loc].head.calliteOffset = x.first;
|
||||
result.callsites[loc].head.deoptNum = deopt.size();
|
||||
result.callsites[loc].head.deoptOffset = totalSize;
|
||||
std::pair<uint32_t, std::vector<ARKDeopt>> sizeAndArkDeopt;
|
||||
std::pair<uint32_t, std::vector<kungfu::ARKDeopt>> sizeAndArkDeopt;
|
||||
GenARKDeopt(deopt, sizeAndArkDeopt);
|
||||
totalSize += sizeAndArkDeopt.first;
|
||||
result.callsites[loc].callsite2Deopt = sizeAndArkDeopt.second;
|
||||
|
@ -65,7 +65,7 @@ private:
|
||||
void SaveArkStackMap(const ARKCallsitePackInfo& info, BinaryBufferWriter& writer);
|
||||
void SaveArkCallsitePackInfo(uint8_t *ptr, uint32_t length, const ARKCallsitePackInfo& info);
|
||||
int FindLoc(std::vector<intptr_t> &CallsitePcs, intptr_t pc);
|
||||
void GenARKDeopt(const DeoptInfoType& deopt, std::pair<uint32_t, std::vector<ARKDeopt>> &sizeAndArkDeopt);
|
||||
void GenARKDeopt(const DeoptInfoType& deopt, std::pair<uint32_t, std::vector<kungfu::ARKDeopt>> &sizeAndArkDeopt);
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_ARK_STACKMAP_BUILD_H
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "ecmascript/ark_stackmap_parser.h"
|
||||
#include "ecmascript/ark_stackmap_builder.h"
|
||||
#include "ecmascript/compiler/assembler/assembler.h"
|
||||
#include "ecmascript/deoptimizer.h"
|
||||
#include "ecmascript/file_loader.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
@ -40,13 +41,13 @@ int ArkStackMapParser::BinaraySearch(CallsiteHead *callsiteHead, uint32_t callsi
|
||||
}
|
||||
|
||||
void ArkStackMapParser::GetArkDeopt(uint8_t *stackmapAddr, uint32_t length,
|
||||
const CallsiteHead& callsiteHead, std::vector<ARKDeopt> &deopts) const
|
||||
const CallsiteHead& callsiteHead, std::vector<kungfu::ARKDeopt> &deopts) const
|
||||
{
|
||||
BinaryBufferParser binBufparser(stackmapAddr, length);
|
||||
ParseArkDeopt(callsiteHead, binBufparser, stackmapAddr, deopts);
|
||||
}
|
||||
|
||||
void ArkStackMapParser::GetConstInfo(uintptr_t callSiteAddr, ConstInfo &info, uint8_t *stackmapAddr) const
|
||||
void ArkStackMapParser::GetArkDeopt(uintptr_t callSiteAddr, uint8_t *stackmapAddr, std::vector<kungfu::ARKDeopt> &deopts) const
|
||||
{
|
||||
StackMapSecHead *head = reinterpret_cast<StackMapSecHead *>(stackmapAddr);
|
||||
ASSERT(head != nullptr);
|
||||
@ -60,8 +61,16 @@ void ArkStackMapParser::GetConstInfo(uintptr_t callSiteAddr, ConstInfo &info, ui
|
||||
return;
|
||||
}
|
||||
CallsiteHead *found = callsiteHead + mid;
|
||||
std::vector<ARKDeopt> deopts;
|
||||
GetArkDeopt(stackmapAddr, length, *found, deopts);
|
||||
}
|
||||
|
||||
void ArkStackMapParser::GetConstInfo(uintptr_t callSiteAddr, ConstInfo &info, uint8_t *stackmapAddr) const
|
||||
{
|
||||
std::vector<kungfu::ARKDeopt> deopts;
|
||||
GetArkDeopt(callSiteAddr, stackmapAddr, deopts);
|
||||
if (deopts.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ARKDeopt target;
|
||||
OffsetType id = static_cast<OffsetType>(SpecVregIndex::BC_OFFSET_INDEX);
|
||||
|
@ -41,12 +41,13 @@ public:
|
||||
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;
|
||||
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<ARKDeopt>& deopt) const;
|
||||
std::vector<kungfu::ARKDeopt>& deopt) const;
|
||||
void ParseArkDeopt(const CallsiteHead& callsiteHead, BinaryBufferParser& binBufparser,
|
||||
uint8_t *ptr, std::vector<ARKDeopt> &deopts) const;
|
||||
uint8_t *ptr, std::vector<kungfu::ARKDeopt> &deopts) const;
|
||||
void ParseArkStackMap(const CallsiteHead& callsiteHead, BinaryBufferParser& binBufparser,
|
||||
uint8_t *ptr, ArkStackMap &stackMap) const;
|
||||
void ParseArkStackMapAndDeopt(uint8_t *ptr, uint32_t length) const;
|
||||
|
@ -54,6 +54,10 @@ public:
|
||||
// method must be set
|
||||
GateRef GetArgGate(const size_t currentVreg) const;
|
||||
GateRef GetCommonArgGate(const CommonArgIdx arg) const;
|
||||
GateRef ArgsAt(const size_t index) const
|
||||
{
|
||||
return args_.at(index);
|
||||
}
|
||||
void FillArgsGateType(const TypeRecorder *typeRecorder);
|
||||
void CollectArgs();
|
||||
static size_t GetFixArgsNum()
|
||||
|
@ -252,10 +252,6 @@ void BytecodeCircuitBuilder::CompleteBytecodeBlockInfo()
|
||||
{
|
||||
std::sort(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintCollectBlockInfo(bytecodeBlockInfos_);
|
||||
}
|
||||
|
||||
// Deduplicate
|
||||
auto deduplicateIndex = std::unique(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
|
||||
bytecodeBlockInfos_.erase(deduplicateIndex, bytecodeBlockInfos_.end());
|
||||
@ -314,14 +310,10 @@ void BytecodeCircuitBuilder::CompleteBytecodeBlockInfo()
|
||||
// Deduplicate
|
||||
deduplicateIndex = std::unique(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
|
||||
bytecodeBlockInfos_.erase(deduplicateIndex, bytecodeBlockInfos_.end());
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintCollectBlockInfo(bytecodeBlockInfos_);
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::BuildBasicBlocks(std::map<std::pair<uint8_t *, uint8_t *>,
|
||||
std::vector<uint8_t *>> &exception)
|
||||
std::vector<uint8_t *>> &exception)
|
||||
{
|
||||
std::map<uint8_t *, BytecodeRegion *> startPcToBB; // [start, bb]
|
||||
std::map<uint8_t *, BytecodeRegion *> endPcToBB; // [end, bb]
|
||||
@ -385,7 +377,7 @@ void BytecodeCircuitBuilder::BuildBasicBlocks(std::map<std::pair<uint8_t *, uint
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintGraph();
|
||||
PrintGraph("Build Basic Block");
|
||||
}
|
||||
ComputeDominatorTree();
|
||||
}
|
||||
@ -420,16 +412,8 @@ void BytecodeCircuitBuilder::ComputeDominatorTree()
|
||||
for (size_t idx = 0; idx < basicBlockList.size(); idx++) {
|
||||
bbDfsTimestampToIdx[basicBlockList[idx]] = idx;
|
||||
}
|
||||
|
||||
RemoveDeadRegions(bbIdToDfsTimestamp);
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
// print cfg order
|
||||
for (auto iter : bbIdToDfsTimestamp) {
|
||||
LOG_COMPILER(INFO) << "BB_" << iter.first << " dfs timestamp is : " << iter.second;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<size_t> immDom(basicBlockList.size()); // immediate dominator with dfs order index
|
||||
std::vector<size_t> semiDom(basicBlockList.size());
|
||||
std::vector<size_t> realImmDom(graph_.size()); // immediate dominator with real index
|
||||
@ -484,11 +468,7 @@ void BytecodeCircuitBuilder::ComputeDominatorTree()
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
// print immediate dominator
|
||||
for (size_t i = 0; i < realImmDom.size(); i++) {
|
||||
LOG_COMPILER(INFO) << i << " immediate dominator: " << realImmDom[i];
|
||||
}
|
||||
PrintGraph();
|
||||
PrintGraph("Computed Dom Trees");
|
||||
}
|
||||
|
||||
BuildImmediateDominator(realImmDom);
|
||||
@ -506,16 +486,6 @@ void BytecodeCircuitBuilder::BuildImmediateDominator(const std::vector<size_t> &
|
||||
dominatedBlock->iDominator = immDomBlock;
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
for (auto block : graph_) {
|
||||
if (block.isDead) {
|
||||
continue;
|
||||
}
|
||||
LOG_COMPILER(INFO) << "current block " << block.id
|
||||
<< " immediate dominator block id: " << block.iDominator->id;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &block : graph_) {
|
||||
if (block.isDead) {
|
||||
continue;
|
||||
@ -525,19 +495,6 @@ void BytecodeCircuitBuilder::BuildImmediateDominator(const std::vector<size_t> &
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
for (auto &block : graph_) {
|
||||
if (block.isDead) {
|
||||
continue;
|
||||
}
|
||||
std::string log("block " + std::to_string(block.id) + " dominate block has: ");
|
||||
for (size_t i = 0; i < block.immDomBlocks.size(); i++) {
|
||||
log += std::to_string(block.immDomBlocks[i]->id) + ",";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
}
|
||||
}
|
||||
|
||||
ComputeDomFrontiers(immDom);
|
||||
InsertPhi();
|
||||
UpdateCFG();
|
||||
@ -568,16 +525,6 @@ void BytecodeCircuitBuilder::ComputeDomFrontiers(const std::vector<size_t> &immD
|
||||
graph_[i].domFrontiers.emplace_back(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
for (size_t i = 0; i < domFrontiers.size(); i++) {
|
||||
std::string log("basic block " + std::to_string(i) + " dominate Frontiers is: ");
|
||||
for (auto iter = domFrontiers[i].cbegin(); iter != domFrontiers[i].cend(); iter++) {
|
||||
log += std::to_string((*iter)->id) + ", ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::RemoveDeadRegions(const std::map<size_t, size_t> &bbIdToDfsTimestamp)
|
||||
@ -606,8 +553,8 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
BytecodeInstruction inst(pc);
|
||||
auto opcode = inst.GetOpcode();
|
||||
info.offset = BytecodeInstruction::Size(opcode);
|
||||
info.pcOffset = pc - method_->GetBytecodeArray();
|
||||
info.opcode = static_cast<EcmaOpcode>(opcode);
|
||||
info.pcOffset = pc - method_->GetBytecodeArray();
|
||||
info.accIn = inst.HasFlag(BytecodeInstruction::Flags::ACC_READ);
|
||||
info.accOut = inst.HasFlag(BytecodeInstruction::Flags::ACC_WRITE);
|
||||
switch (static_cast<EcmaOpcode>(opcode)) {
|
||||
@ -1682,10 +1629,6 @@ void BytecodeCircuitBuilder::InsertPhi()
|
||||
// handle phi generated from multiple control flow in the same source block
|
||||
InsertExceptionPhi(defsitesInfo);
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintDefsitesInfo(defsitesInfo);
|
||||
}
|
||||
|
||||
for (const auto&[variable, defsites] : defsitesInfo) {
|
||||
std::queue<uint16_t> workList;
|
||||
for (auto blockId: defsites) {
|
||||
@ -1706,7 +1649,7 @@ void BytecodeCircuitBuilder::InsertPhi()
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintGraph();
|
||||
PrintGraph("Inserted Phis");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2044,7 +1987,6 @@ GateRef BytecodeCircuitBuilder::NewConst(const BytecodeInfo &info)
|
||||
void BytecodeCircuitBuilder::NewJSGate(BytecodeRegion &bb, const uint8_t *pc, GateRef &state, GateRef &depend)
|
||||
{
|
||||
auto bytecodeInfo = GetBytecodeInfo(pc);
|
||||
|
||||
size_t numValueInputs = bytecodeInfo.ComputeTotalValueCount();
|
||||
GateRef gate = 0;
|
||||
std::vector<GateRef> inList = CreateGateInList(bytecodeInfo);
|
||||
@ -2055,7 +1997,6 @@ void BytecodeCircuitBuilder::NewJSGate(BytecodeRegion &bb, const uint8_t *pc, Ga
|
||||
gate = circuit_.NewGate(OpCode(OpCode::JS_BYTECODE), MachineType::NOVALUE, numValueInputs,
|
||||
inList, GateType::Empty());
|
||||
}
|
||||
|
||||
// 1: store bcoffset in the end.
|
||||
AddBytecodeOffsetInfo(gate, bytecodeInfo, numValueInputs + 1, const_cast<uint8_t *>(pc));
|
||||
gateAcc_.NewIn(gate, 0, state);
|
||||
@ -2445,10 +2386,6 @@ void BytecodeCircuitBuilder::BuildFrameState()
|
||||
|
||||
void BytecodeCircuitBuilder::BuildCircuit()
|
||||
{
|
||||
if (IsLogEnabled()) {
|
||||
PrintBBInfo();
|
||||
}
|
||||
|
||||
// create arg gates array
|
||||
BuildCircuitArgs();
|
||||
CollectPredsInfo();
|
||||
@ -2466,11 +2403,7 @@ void BytecodeCircuitBuilder::BuildCircuit()
|
||||
ASSERT(bb.forwardIndex == bb.numOfStatePreds - bb.numOfLoopBacks);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintBytecodeInfo();
|
||||
}
|
||||
|
||||
std::vector<GateRef> jsGateList;
|
||||
// resolve def-site of virtual regs and set all value inputs
|
||||
std::vector<GateRef> gates;
|
||||
circuit_.GetAllGates(gates);
|
||||
@ -2497,6 +2430,9 @@ void BytecodeCircuitBuilder::BuildCircuit()
|
||||
ASSERT(numValueOutputs <= 1);
|
||||
auto stateCount = gateAcc_.GetStateCount(gate);
|
||||
auto dependCount = gateAcc_.GetDependCount(gate);
|
||||
if (gateAcc_.GetOpCode(gate) == OpCode::JS_BYTECODE && !bytecodeInfo.IsJump()) {
|
||||
jsGateList.emplace_back(gate);
|
||||
}
|
||||
for (size_t valueIdx = 0; valueIdx < valueCount; valueIdx++) {
|
||||
auto inIdx = valueIdx + stateCount + dependCount;
|
||||
if (!gateAcc_.IsInGateNull(gate, inIdx)) {
|
||||
@ -2505,8 +2441,8 @@ void BytecodeCircuitBuilder::BuildCircuit()
|
||||
if (valueIdx < bytecodeInfo.inputs.size()) {
|
||||
gateAcc_.NewIn(gate, inIdx,
|
||||
RenameVariable(id, pc - 1,
|
||||
std::get<VirtualRegister>(bytecodeInfo.inputs.at(valueIdx)).GetId(),
|
||||
false));
|
||||
std::get<VirtualRegister>(bytecodeInfo.inputs.at(valueIdx)).GetId(),
|
||||
false));
|
||||
} else {
|
||||
gateAcc_.NewIn(gate, inIdx, RenameVariable(id, pc - 1, 0, true));
|
||||
}
|
||||
@ -2515,7 +2451,10 @@ void BytecodeCircuitBuilder::BuildCircuit()
|
||||
BuildFrameState();
|
||||
|
||||
if (IsLogEnabled()) {
|
||||
PrintGraph("Bytecode2Gate");
|
||||
LOG_COMPILER(INFO) << "\033[34m" << "============= After bytecode2circuit lowering =============" << "\033[0m";
|
||||
circuit_.PrintAllGates(*this);
|
||||
LOG_COMPILER(INFO) << "\033[34m" << "=========================== End ===========================" << "\033[0m";
|
||||
}
|
||||
}
|
||||
|
||||
@ -2545,157 +2484,106 @@ void BytecodeCircuitBuilder::SetExistingRestore(GateRef resumeGate, uint16_t tmp
|
||||
resumeRegToRestore_[pr] = restoreGate;
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::PrintCollectBlockInfo(std::vector<CfgInfo> &bytecodeBlockInfos)
|
||||
void BytecodeCircuitBuilder::PrintGraph(const char* title)
|
||||
{
|
||||
for (auto iter = bytecodeBlockInfos.cbegin(); iter != bytecodeBlockInfos.cend(); iter++) {
|
||||
std::string log("offset: " + std::to_string(reinterpret_cast<uintptr_t>(iter->pc)) + " splitKind: " +
|
||||
std::to_string(static_cast<int32_t>(iter->splitKind)) + " successor are: ");
|
||||
auto &vec = iter->succs;
|
||||
for (size_t i = 0; i < vec.size(); i++) {
|
||||
log += std::to_string(reinterpret_cast<uintptr_t>(vec[i])) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
std::map<const uint8_t *, GateRef> bcToGate;
|
||||
for (const auto &[key, value]: jsgateToBytecode_) {
|
||||
bcToGate[value.second] = key;
|
||||
}
|
||||
LOG_COMPILER(INFO) << "-----------------------------------------------------------------------";
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::PrintGraph()
|
||||
{
|
||||
LOG_COMPILER(INFO) << "======================== " << title << " ========================";
|
||||
for (size_t i = 0; i < graph_.size(); i++) {
|
||||
if (graph_[i].isDead) {
|
||||
LOG_COMPILER(INFO) << "BB_" << graph_[i].id << ": ;predsId= invalid BB";
|
||||
LOG_COMPILER(INFO) << "curStartPc: " << reinterpret_cast<uintptr_t>(graph_[i].start) <<
|
||||
" curEndPc: " << reinterpret_cast<uintptr_t>(graph_[i].end);
|
||||
BytecodeRegion& bb = graph_[i];
|
||||
if (bb.isDead) {
|
||||
LOG_COMPILER(INFO) << "B" << bb.id << ": ;preds= invalid BB";
|
||||
LOG_COMPILER(INFO) << "\tBytecodePC: [" << reinterpret_cast<void*>(bb.start) << ", "
|
||||
<< reinterpret_cast<void*>(bb.end) << ")";
|
||||
continue;
|
||||
}
|
||||
std::string log("BB_" + std::to_string(graph_[i].id) + ": ;predsId= ");
|
||||
for (size_t k = 0; k < graph_[i].preds.size(); ++k) {
|
||||
log += std::to_string(graph_[i].preds[k]->id) + ", ";
|
||||
std::string log("B" + std::to_string(bb.id) + ": ;preds= ");
|
||||
for (size_t k = 0; k < bb.preds.size(); ++k) {
|
||||
log += std::to_string(bb.preds[k]->id) + ", ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
LOG_COMPILER(INFO) << "curStartPc: " << reinterpret_cast<uintptr_t>(graph_[i].start) <<
|
||||
" curEndPc: " << reinterpret_cast<uintptr_t>(graph_[i].end);
|
||||
LOG_COMPILER(INFO) << "\tBytecodePC: [" << reinterpret_cast<void*>(bb.start) << ", "
|
||||
<< reinterpret_cast<void*>(bb.end) << ")";
|
||||
|
||||
for (size_t j = 0; j < graph_[i].preds.size(); j++) {
|
||||
LOG_COMPILER(INFO) << "predsStartPc: " << reinterpret_cast<uintptr_t>(graph_[i].preds[j]->start) <<
|
||||
" predsEndPc: " << reinterpret_cast<uintptr_t>(graph_[i].preds[j]->end);
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < graph_[i].succs.size(); j++) {
|
||||
LOG_COMPILER(INFO) << "succesStartPc: " << reinterpret_cast<uintptr_t>(graph_[i].succs[j]->start) <<
|
||||
" succesEndPc: " << reinterpret_cast<uintptr_t>(graph_[i].succs[j]->end);
|
||||
}
|
||||
|
||||
std::string log1("succesId: ");
|
||||
for (size_t j = 0; j < graph_[i].succs.size(); j++) {
|
||||
log1 += std::to_string(graph_[i].succs[j]->id) + ", ";
|
||||
std::string log1("\tSucces: ");
|
||||
for (size_t j = 0; j < bb.succs.size(); j++) {
|
||||
log1 += std::to_string(bb.succs[j]->id) + ", ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log1;
|
||||
|
||||
for (size_t j = 0; j < graph_[i].catchs.size(); j++) {
|
||||
LOG_COMPILER(INFO) << "catchStartPc: " << reinterpret_cast<uintptr_t>(graph_[i].catchs[j]->start) <<
|
||||
" catchEndPc: " << reinterpret_cast<uintptr_t>(graph_[i].catchs[j]->end);
|
||||
for (size_t j = 0; j < bb.catchs.size(); j++) {
|
||||
LOG_COMPILER(INFO) << "\tcatch [: " << reinterpret_cast<void*>(bb.catchs[j]->start) << ", "
|
||||
<< reinterpret_cast<void*>(bb.catchs[j]->end) << ")";
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < graph_[i].immDomBlocks.size(); j++) {
|
||||
LOG_COMPILER(INFO) << "dominate block id: " << graph_[i].immDomBlocks[j]->id << " startPc: " <<
|
||||
reinterpret_cast<uintptr_t>(graph_[i].immDomBlocks[j]->start) << " endPc: " <<
|
||||
reinterpret_cast<uintptr_t>(graph_[i].immDomBlocks[j]->end);
|
||||
}
|
||||
|
||||
if (graph_[i].iDominator) {
|
||||
LOG_COMPILER(INFO) << "current block " << graph_[i].id <<
|
||||
" immediate dominator is " << graph_[i].iDominator->id;
|
||||
}
|
||||
|
||||
std::string log2("current block " + std::to_string(graph_[i].id) + " dominance Frontiers: ");
|
||||
for (const auto &frontier: graph_[i].domFrontiers) {
|
||||
log2 += std::to_string(frontier->id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log2;
|
||||
|
||||
std::string log3("current block " + std::to_string(graph_[i].id) + " phi variable: ");
|
||||
for (auto variable: graph_[i].phi) {
|
||||
log3 += std::to_string(variable) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log3;
|
||||
LOG_COMPILER(INFO) << "-------------------------------------------------------";
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::PrintBytecodeInfo()
|
||||
{
|
||||
for (auto &bb: graph_) {
|
||||
if (bb.isDead) {
|
||||
continue;
|
||||
}
|
||||
LOG_COMPILER(INFO) << "BB_" << bb.id << ": ";
|
||||
EnumerateBlock(bb, [](uint8_t * pc, BytecodeInfo &bytecodeInfo) -> bool {
|
||||
std::string log;
|
||||
BytecodeInstruction inst(pc);
|
||||
log += std::to_string(bytecodeInfo.pcOffset) + ": ";
|
||||
log += GetEcmaOpcodeStr(static_cast<EcmaOpcode>(inst.GetOpcode())) + ": " + "In=[";
|
||||
if (bytecodeInfo.accIn) {
|
||||
log += "acc,";
|
||||
}
|
||||
for (const auto &in: bytecodeInfo.inputs) {
|
||||
if (std::holds_alternative<VirtualRegister>(in)) {
|
||||
log += std::to_string(std::get<VirtualRegister>(in).GetId()) + ",";
|
||||
}
|
||||
}
|
||||
log += "] Out=[";
|
||||
if (bytecodeInfo.accOut) {
|
||||
log += "acc,";
|
||||
}
|
||||
for (const auto &out: bytecodeInfo.vregOut) {
|
||||
log += std::to_string(out) + ",";
|
||||
}
|
||||
log += "]";
|
||||
LOG_COMPILER(INFO) << log;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::PrintBBInfo()
|
||||
{
|
||||
for (auto &bb: graph_) {
|
||||
if (bb.isDead) {
|
||||
continue;
|
||||
}
|
||||
LOG_COMPILER(INFO) << "------------------------";
|
||||
LOG_COMPILER(INFO) << "block: " << bb.id;
|
||||
std::string log("preds: ");
|
||||
for (auto pred: bb.preds) {
|
||||
log += std::to_string(pred->id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
std::string log1("succs: ");
|
||||
for (auto succ: bb.succs) {
|
||||
log1 += std::to_string(succ->id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log1;
|
||||
std::string log2("catchs: ");
|
||||
for (auto catchBlock: bb.catchs) {
|
||||
log2 += std::to_string(catchBlock->id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log2;
|
||||
std::string log3("trys: ");
|
||||
std::string log2("\tTrys: ");
|
||||
for (auto tryBlock: bb.trys) {
|
||||
log3 += std::to_string(tryBlock->id) + " , ";
|
||||
log2 += std::to_string(tryBlock->id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log2;
|
||||
|
||||
std::string log3 = "\tDom: ";
|
||||
for (size_t j = 0; j < bb.immDomBlocks.size(); j++) {
|
||||
log3 += "B" + std::to_string(bb.immDomBlocks[j]->id) + std::string(", ");
|
||||
}
|
||||
LOG_COMPILER(INFO) << log3;
|
||||
|
||||
if (bb.iDominator) {
|
||||
LOG_COMPILER(INFO) << "\tIDom B" << bb.iDominator->id;
|
||||
}
|
||||
|
||||
std::string log4("\tDom Frontiers: ");
|
||||
for (const auto &frontier: bb.domFrontiers) {
|
||||
log4 += std::to_string(frontier->id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log4;
|
||||
|
||||
std::string log5("\tPhi: ");
|
||||
for (auto variable: bb.phi) {
|
||||
log5 += std::to_string(variable) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log5;
|
||||
|
||||
PrintBytecodeInfo(bb, bcToGate);
|
||||
LOG_COMPILER(INFO) << "";
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::PrintDefsitesInfo(const std::map<uint16_t, std::set<size_t>> &defsitesInfo)
|
||||
void BytecodeCircuitBuilder::PrintBytecodeInfo(BytecodeRegion& bb, const std::map<const uint8_t *, GateRef>& bcToGate)
|
||||
{
|
||||
for (const auto&[variable, defsites] : defsitesInfo) {
|
||||
std::string log("variable: " + std::to_string(variable) + " locate block have: ");
|
||||
for (auto id : defsites) {
|
||||
log += std::to_string(id) + " , ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
if (bb.isDead) {
|
||||
return;
|
||||
}
|
||||
LOG_COMPILER(INFO) << "\tBytecode[] = ";
|
||||
EnumerateBlock(bb, [=](uint8_t * pc, BytecodeInfo &bytecodeInfo) -> bool {
|
||||
std::string log;
|
||||
log += std::string("\t\t< ") + GetEcmaOpcodeStr(static_cast<EcmaOpcode>(*pc)) + ", " + "In=[";
|
||||
if (bytecodeInfo.accIn) {
|
||||
log += "acc,";
|
||||
}
|
||||
for (const auto &in: bytecodeInfo.inputs) {
|
||||
if (std::holds_alternative<VirtualRegister>(in)) {
|
||||
log += std::to_string(std::get<VirtualRegister>(in).GetId()) + ",";
|
||||
}
|
||||
}
|
||||
log += "], Out=[";
|
||||
if (bytecodeInfo.accOut) {
|
||||
log += "acc,";
|
||||
}
|
||||
for (const auto &out: bytecodeInfo.vregOut) {
|
||||
log += std::to_string(out) + ",";
|
||||
}
|
||||
log += "] >";
|
||||
LOG_COMPILER(INFO) << log;
|
||||
|
||||
auto r = bcToGate.find(pc);
|
||||
if (r != bcToGate.end()) {
|
||||
this->gateAcc_.ShortPrint(r->second);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -261,7 +261,7 @@ struct BytecodeInfo {
|
||||
bool accOut {false}; // write acc
|
||||
EcmaOpcode opcode {0};
|
||||
uint16_t offset {0};
|
||||
uint16_t pcOffset {0};
|
||||
uint32_t pcOffset {0};
|
||||
|
||||
bool IsOut(VRegIDType reg, uint32_t index) const
|
||||
{
|
||||
@ -592,10 +592,10 @@ private:
|
||||
void BuildFrameState();
|
||||
GateRef GetExistingRestore(GateRef resumeGate, uint16_t tmpReg) const;
|
||||
void SetExistingRestore(GateRef resumeGate, uint16_t tmpReg, GateRef restoreGate);
|
||||
void PrintCollectBlockInfo(std::vector<CfgInfo> &bytecodeBlockInfos);
|
||||
void PrintGraph();
|
||||
void PrintBytecodeInfo();
|
||||
void PrintBBInfo();
|
||||
void PrintGraph(const char* title);
|
||||
void PrintBytecodeInfo(BytecodeRegion& region, const std::map<const uint8_t *, GateRef>& bcToGate);
|
||||
void PrintDefsitesInfo(const std::map<uint16_t, std::set<size_t>> &defsitesInfo);
|
||||
|
||||
inline bool IsEntryBlock(const size_t bbId) const
|
||||
|
@ -67,7 +67,9 @@ public:
|
||||
} else {
|
||||
funcSize = codeBuff + assembler_->GetSectionSize(ElfSecName::TEXT) - entrys[j];
|
||||
}
|
||||
stubInfo.AddStubEntry(cs->GetTargetKind(), cs->GetID(), entrys[j] - codeBuff, moduleIndex, delta, funcSize);
|
||||
kungfu::CalleeRegAndOffsetVec info = assembler_->GetCalleeReg2Offset(func, log);
|
||||
stubInfo.AddStubEntry(cs->GetTargetKind(), cs->GetID(), entrys[j] - codeBuff, moduleIndex, delta, funcSize,
|
||||
info);
|
||||
ASSERT(!cs->GetName().empty());
|
||||
addr2name[entrys[j]] = cs->GetName();
|
||||
}
|
||||
@ -77,7 +79,8 @@ public:
|
||||
uint32_t moduleIndex, const CompilerLog &log)
|
||||
{
|
||||
auto engine = assembler_->GetEngine();
|
||||
std::vector<std::tuple<uint64_t, size_t, int>> funcInfo; // entry、idx、delta
|
||||
std::vector<std::tuple<uint64_t, size_t, int>> funcInfo; // entry idx delta
|
||||
std::vector<kungfu::CalleeRegAndOffsetVec> calleeSaveRegisters; // entry idx delta
|
||||
llvmModule_->IteratefuncIndexMap([&](size_t idx, LLVMValueRef func) {
|
||||
uint64_t funcEntry = reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, func));
|
||||
uint64_t length = 0;
|
||||
@ -89,6 +92,8 @@ public:
|
||||
int delta = assembler_->GetFpDeltaPrevFramSp(func, log);
|
||||
ASSERT(delta >= 0 && (delta % sizeof(uintptr_t) == 0));
|
||||
funcInfo.emplace_back(std::tuple(funcEntry, idx, delta));
|
||||
kungfu::CalleeRegAndOffsetVec info = assembler_->GetCalleeReg2Offset(func, log);
|
||||
calleeSaveRegisters.emplace_back(info);
|
||||
});
|
||||
auto codeBuff = assembler_->GetSectionAddr(ElfSecName::TEXT);
|
||||
const size_t funcCount = funcInfo.size();
|
||||
@ -106,7 +111,7 @@ public:
|
||||
funcSize = codeBuff + assembler_->GetSectionSize(ElfSecName::TEXT) - funcEntry;
|
||||
}
|
||||
aotInfo.AddStubEntry(CallSignature::TargetKind::JSFUNCTION, idx,
|
||||
funcEntry - codeBuff, moduleIndex, delta, funcSize);
|
||||
funcEntry - codeBuff, moduleIndex, delta, funcSize, calleeSaveRegisters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ void FrameStateBuilder::BindCheckPoint(GateRef gate, size_t pcOffset)
|
||||
auto depend = gateAcc_.GetDep(gate);
|
||||
GateRef frameState = FrameState(pcOffset);
|
||||
GateRef checkPoint = circuit_->NewGate(
|
||||
OpCode(OpCode::CHECK_POINT), 1, {depend, frameState}, GateType::Empty());
|
||||
OpCode(OpCode::GUARD), 1, {depend, frameState}, GateType::Empty());
|
||||
gateAcc_.ReplaceDependIn(gate, checkPoint);
|
||||
}
|
||||
|
||||
|
@ -254,6 +254,32 @@ static const char *SymbolLookupCallback([[maybe_unused]] void *disInfo, [[maybe_
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
kungfu::CalleeRegAndOffsetVec LLVMAssembler::GetCalleeReg2Offset(LLVMValueRef fn, const CompilerLog &log)
|
||||
{
|
||||
kungfu::CalleeRegAndOffsetVec info;
|
||||
llvm::Function* func = llvm::unwrap<llvm::Function>(fn);
|
||||
for (const auto &Attr : func->getAttributes().getFnAttributes()) {
|
||||
if (Attr.isStringAttribute()) {
|
||||
std::string str = std::string(Attr.getKindAsString().data());
|
||||
std::string expectedKey = "DwarfReg";
|
||||
if (str.size() >= expectedKey.size() &&
|
||||
str.substr(0, expectedKey.size()) == expectedKey) {
|
||||
int RegNum = std::stoi(str.substr(expectedKey.size(), str.size() - expectedKey.size()));
|
||||
auto value = std::stoi(std::string(Attr.getValueAsString()));
|
||||
info.push_back(std::make_pair(RegNum, value));
|
||||
(void)log;
|
||||
auto logFlag = true;
|
||||
if (logFlag) {
|
||||
LOG_COMPILER(INFO) << " RegNum:" << RegNum << " value:" << value << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
int LLVMAssembler::GetFpDeltaPrevFramSp(LLVMValueRef fn, const CompilerLog &log)
|
||||
{
|
||||
int fpToCallerSpDelta = 0;
|
||||
|
@ -219,6 +219,7 @@ public:
|
||||
void Disassemble(const std::map<uintptr_t, std::string> &addr2name,
|
||||
const CompilerLog &log, const MethodLogList &logList) const;
|
||||
static int GetFpDeltaPrevFramSp(LLVMValueRef fn, const CompilerLog &log);
|
||||
static kungfu::CalleeRegAndOffsetVec GetCalleeReg2Offset(LLVMValueRef fn, const CompilerLog &log);
|
||||
static void Disassemble(uint8_t *buf, size_t size);
|
||||
|
||||
uintptr_t GetSectionAddr(ElfSecName sec) const
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ecmascript/compiler/common_stubs.h"
|
||||
#include "ecmascript/compiler/gate.h"
|
||||
#include "ecmascript/compiler/rt_call_signature.h"
|
||||
#include "ecmascript/deoptimizer.h"
|
||||
#include "ecmascript/frames.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/method.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/compiler/type_lowering.h"
|
||||
#include "ecmascript/ark_stackmap.h"
|
||||
#include "ecmascript/deoptimizer.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
void TypeLowering::RunTypeLowering()
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ecmascript/base/config.h"
|
||||
#include "ecmascript/compiler/bc_call_signature.h"
|
||||
#include "ecmascript/compiler/common_stubs.h"
|
||||
#include "ecmascript/deoptimizer.h"
|
||||
#include "ecmascript/llvm_stackmap_parser.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
@ -230,6 +231,7 @@ bool AOTModulePackInfo::Load(EcmaVM *vm, const std::string &filename)
|
||||
if (!VerifyFilePath(filename)) {
|
||||
LOG_COMPILER(ERROR) << "Can not load aot file from path [ " << filename << " ], "
|
||||
<< "please execute ark_aot_compiler with options --aot-file.";
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
std::ifstream file(filename.c_str(), std::ofstream::binary);
|
||||
@ -368,9 +370,9 @@ bool FileLoader::InsideStub(uint64_t pc) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<uint64_t, uint8_t *, int> FileLoader::CalCallSiteInfo(uintptr_t retAddr) const
|
||||
ModulePackInfo::CallSiteInfo FileLoader::CalCallSiteInfo(uintptr_t retAddr) const
|
||||
{
|
||||
std::tuple<uint64_t, uint8_t *, int> callsiteInfo;
|
||||
ModulePackInfo::CallSiteInfo callsiteInfo;
|
||||
bool ans = stubPackInfo_.CalCallSiteInfo(retAddr, callsiteInfo);
|
||||
if (ans) {
|
||||
return callsiteInfo;
|
||||
@ -488,6 +490,15 @@ bool FileLoader::RewriteDataSection(uintptr_t dataSec, size_t size,
|
||||
LOG_FULL(FATAL) << "memset failed";
|
||||
return false;
|
||||
}
|
||||
ASSERT(size % sizeof(uint64_t) == 0);
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
uint64_t *ptr = reinterpret_cast<uint64_t *>(dataSec);
|
||||
for (size_t i = 0; i < size / sizeof(uint64_t); i++) {
|
||||
if (ptr[i] == Deoptimizier::LLVM_DEOPT_RELOCATE_ADDR) {
|
||||
ptr[i] = thread->GetRTInterface(RTSTUB_ID(DeoptHandlerAsm));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -581,7 +592,8 @@ void BinaryBufferParser::ParseBuffer(uint8_t *dst, uint32_t count, uint8_t *src)
|
||||
}
|
||||
}
|
||||
|
||||
bool ModulePackInfo::CalCallSiteInfo(uintptr_t retAddr, std::tuple<uint64_t, uint8_t *, int>& ret) const
|
||||
bool ModulePackInfo::CalCallSiteInfo(uintptr_t retAddr,
|
||||
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec>& ret) const
|
||||
{
|
||||
uint64_t textStart = 0;
|
||||
uint8_t *stackmapAddr = nullptr;
|
||||
@ -613,9 +625,16 @@ bool ModulePackInfo::CalCallSiteInfo(uintptr_t retAddr, std::tuple<uint64_t, uin
|
||||
ASSERT(it != t);
|
||||
ASSERT((it->codeAddr_ <= target.codeAddr_) && (target.codeAddr_ < it->codeAddr_ + it->funcSize_));
|
||||
delta = it->fpDeltaPrevFrameSp_;
|
||||
ret = std::make_tuple(textStart, stackmapAddr, delta);
|
||||
kungfu::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);
|
||||
calleeRegInfo.emplace_back(regAndOffset);
|
||||
}
|
||||
ret = std::make_tuple(textStart, stackmapAddr, delta, calleeRegInfo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
#ifndef ECMASCRIPT_COMPILER_FILE_LOADER_H
|
||||
#define ECMASCRIPT_COMPILER_FILE_LOADER_H
|
||||
|
||||
#include "ecmascript/ark_stackmap.h"
|
||||
#include "ecmascript/calleeReg.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_runtime_options.h"
|
||||
#include "ecmascript/compiler/binary_section.h"
|
||||
@ -22,9 +24,6 @@
|
||||
namespace panda::ecmascript {
|
||||
class JSpandafile;
|
||||
class JSThread;
|
||||
namespace kungfu {
|
||||
class LLVMStackMapParser;
|
||||
};
|
||||
|
||||
class BinaryBufferParser {
|
||||
public:
|
||||
@ -146,12 +145,15 @@ public:
|
||||
bool VerifyFilePath([[maybe_unused]] const std::string &filePath, [[maybe_unused]] bool toGenerate = false) const;
|
||||
|
||||
struct FuncEntryDes {
|
||||
uint64_t codeAddr_ {0};
|
||||
CallSignature::TargetKind kind_ {CallSignature::TargetKind::COMMON_STUB};
|
||||
uint32_t indexInKind_ {0};
|
||||
uint32_t moduleIndex_ {0};
|
||||
int fpDeltaPrevFrameSp_ {0};
|
||||
uint32_t funcSize_ {0};
|
||||
uint64_t codeAddr_;
|
||||
CallSignature::TargetKind kind_;
|
||||
uint32_t indexInKind_;
|
||||
uint32_t moduleIndex_;
|
||||
int fpDeltaPrevFrameSp_;
|
||||
uint32_t funcSize_;
|
||||
//kungfu::CalleeRegAndOffsetVec infos_;
|
||||
[[maybe_unused]] uint32_t calleeRegisterNum_;
|
||||
int32_t CalleeReg2Offset_[2 * kungfu::MAX_CALLEE_SAVE_REIGISTER_NUM];
|
||||
bool IsStub() const
|
||||
{
|
||||
return CallSignature::TargetKind::STUB_BEGIN <= kind_ && kind_ < CallSignature::TargetKind::STUB_END;
|
||||
@ -233,7 +235,7 @@ public:
|
||||
}
|
||||
|
||||
void AddStubEntry(CallSignature::TargetKind kind, int indexInKind, uint64_t offset,
|
||||
uint32_t moduleIndex, int delta, uint32_t size)
|
||||
uint32_t moduleIndex, int delta, uint32_t size, kungfu::CalleeRegAndOffsetVec info = {})
|
||||
{
|
||||
FuncEntryDes des;
|
||||
if (memset_s(&des, sizeof(des), 0, sizeof(des)) != EOK) {
|
||||
@ -246,6 +248,14 @@ public:
|
||||
des.moduleIndex_ = moduleIndex;
|
||||
des.fpDeltaPrevFrameSp_ = delta;
|
||||
des.funcSize_ = size;
|
||||
des.calleeRegisterNum_ = info.size();
|
||||
kungfu::DwarfRegType reg = 0;
|
||||
kungfu::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);
|
||||
des.CalleeReg2Offset_[2 * i + 1] = static_cast<int32_t>(regOffset);
|
||||
}
|
||||
entries_.emplace_back(des);
|
||||
}
|
||||
|
||||
@ -263,7 +273,9 @@ public:
|
||||
{
|
||||
totalCodeSize_ += size;
|
||||
}
|
||||
bool CalCallSiteInfo(uintptr_t retAddr, std::tuple<uint64_t, uint8_t *, int>& ret) const;
|
||||
|
||||
using CallSiteInfo = std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec>;
|
||||
bool CalCallSiteInfo(uintptr_t retAddr, CallSiteInfo& ret) const;
|
||||
|
||||
protected:
|
||||
uint32_t entryNum_ {0};
|
||||
@ -367,7 +379,7 @@ public:
|
||||
virtual ~FileLoader();
|
||||
void LoadStubFile();
|
||||
void LoadAOTFile(const std::string &fileName);
|
||||
std::tuple<uint64_t, uint8_t *, int> CalCallSiteInfo(uintptr_t retAddr) const;
|
||||
ModulePackInfo::CallSiteInfo CalCallSiteInfo(uintptr_t retAddr) const;
|
||||
bool InsideStub(uint64_t pc) const;
|
||||
|
||||
void Iterate(const RootVisitor &v)
|
||||
@ -446,4 +458,4 @@ private:
|
||||
friend class StubModulePackInfo;
|
||||
};
|
||||
}
|
||||
#endif // ECMASCRIPT_COMPILER_FILE_LOADER_H
|
||||
#endif // ECMASCRIPT_COMPILER_FILE_LOADER_H
|
||||
|
@ -48,11 +48,10 @@ int FrameIterator::GetCallSiteDelta(uintptr_t returnAddr) const
|
||||
return delta;
|
||||
}
|
||||
|
||||
std::tuple<uint64_t, uint8_t *, int> FrameIterator::CalCallSiteInfo(uintptr_t retAddr) const
|
||||
ModulePackInfo::CallSiteInfo FrameIterator::CalCallSiteInfo(uintptr_t retAddr) const
|
||||
{
|
||||
auto loader = thread_->GetEcmaVM()->GetFileLoader();
|
||||
std::tuple<uint64_t, uint8_t *, int> callsiteInfo = loader->CalCallSiteInfo(retAddr);
|
||||
return callsiteInfo;
|
||||
return loader->CalCallSiteInfo(retAddr);
|
||||
}
|
||||
|
||||
template <GCVisitedFlag GCVisit>
|
||||
@ -228,7 +227,7 @@ void FrameIterator::Advance()
|
||||
return;
|
||||
}
|
||||
uint64_t textStart;
|
||||
std::tie(textStart, stackMapAddr_, fpDeltaPrevFrameSp_) = CalCallSiteInfo(optimizedReturnAddr_);
|
||||
std::tie(textStart, stackMapAddr_, fpDeltaPrevFrameSp_, calleeRegInfo_) = CalCallSiteInfo(optimizedReturnAddr_);
|
||||
ASSERT(optimizedReturnAddr_ >= textStart);
|
||||
optimizedReturnAddr_ = optimizedReturnAddr_ - textStart;
|
||||
}
|
||||
@ -351,6 +350,11 @@ void FrameIterator::CollectBCOffsetInfo(kungfu::ConstInfo &info) const
|
||||
arkStackMapParser_->GetConstInfo(optimizedReturnAddr_, info, stackMapAddr_);
|
||||
}
|
||||
|
||||
void FrameIterator::CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const
|
||||
{
|
||||
arkStackMapParser_->GetArkDeopt(optimizedReturnAddr_, stackMapAddr_, deopts);
|
||||
}
|
||||
|
||||
ARK_INLINE JSTaggedType* OptimizedJSFunctionFrame::GetArgv(const FrameIterator &it) const
|
||||
{
|
||||
uintptr_t *preFrameSp = ComputePrevFrameSp(it);
|
||||
@ -401,6 +405,17 @@ ARK_INLINE void OptimizedJSFunctionFrame::GCIterate(const FrameIterator &it,
|
||||
}
|
||||
}
|
||||
|
||||
void OptimizedJSFunctionFrame::GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const
|
||||
{
|
||||
it.CollectArkDeopt(deopts);
|
||||
}
|
||||
|
||||
void OptimizedJSFunctionFrame::GetFuncCalleeRegAndOffset(
|
||||
const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const
|
||||
{
|
||||
it.GetCalleeRegAndOffsetVec(ret);
|
||||
}
|
||||
|
||||
ARK_INLINE void AsmInterpretedFrame::GCIterate(const FrameIterator &it,
|
||||
const RootVisitor &visitor,
|
||||
const RootRangeVisitor &rangeVisitor,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef ECMASCRIPT_FRAMES_H
|
||||
#define ECMASCRIPT_FRAMES_H
|
||||
|
||||
#include "ecmascript/ark_stackmap.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
|
||||
// Frame Layout
|
||||
@ -475,7 +476,6 @@ public:
|
||||
{
|
||||
return prevFp;
|
||||
}
|
||||
uintptr_t* ComputePrevFrameSp(const FrameIterator &it) const;
|
||||
|
||||
JSTaggedType* GetArgv(uintptr_t *preFrameSp) const
|
||||
{
|
||||
@ -519,13 +519,17 @@ public:
|
||||
return MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp);
|
||||
}
|
||||
friend class FrameIterator;
|
||||
|
||||
void GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const;
|
||||
void GetFuncCalleeRegAndOffset(
|
||||
const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const;
|
||||
uintptr_t* ComputePrevFrameSp(const FrameIterator &it) const;
|
||||
private:
|
||||
static OptimizedJSFunctionFrame* GetFrameFromSp(const JSTaggedType *sp)
|
||||
{
|
||||
return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp)
|
||||
- MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
|
||||
}
|
||||
|
||||
// dynamic callee saveregisters for x86-64
|
||||
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
||||
[[maybe_unused]] alignas(EAS) FrameType type {0};
|
||||
@ -593,6 +597,11 @@ struct InterpretedFrameBase : public base::AlignedStruct<base::AlignedPointer::S
|
||||
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static constexpr size_t GetSize(bool isArch32)
|
||||
{
|
||||
return isArch32 ? InterpretedFrameBase::SizeArch32 : InterpretedFrameBase::SizeArch64;
|
||||
}
|
||||
|
||||
alignas(EAS) JSTaggedType *prev {nullptr}; // for llvm :c-fp ; for interrupt: thread-fp for gc
|
||||
alignas(EAS) FrameType type {FrameType::OPTIMIZED_FRAME}; // 0
|
||||
};
|
||||
@ -866,6 +875,11 @@ struct AsmInterpretedEntryFrame : public base::AlignedStruct<JSTaggedValue::Tagg
|
||||
return base.prev;
|
||||
}
|
||||
|
||||
static size_t GetBaseOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static AsmInterpretedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
|
||||
{
|
||||
return reinterpret_cast<AsmInterpretedEntryFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
||||
@ -875,7 +889,7 @@ struct AsmInterpretedEntryFrame : public base::AlignedStruct<JSTaggedValue::Tagg
|
||||
alignas(EAS) InterpretedFrameBase base;
|
||||
};
|
||||
|
||||
struct AsmInterpretedBridgeFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
||||
struct AsmInterpretedBridgeFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
||||
AsmInterpretedEntryFrame,
|
||||
base::AlignedPointer> {
|
||||
enum class Index : size_t {
|
||||
@ -899,7 +913,17 @@ struct AsmInterpretedBridgeFrame : public base::AlignedStruct<JSTaggedValue::Tag
|
||||
return entry.base.prev;
|
||||
}
|
||||
|
||||
alignas(EAS) AsmInterpretedEntryFrame entry;
|
||||
static size_t GetReturnAddrOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::ReturnAddrIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static constexpr size_t GetSize(bool isArch32)
|
||||
{
|
||||
return isArch32 ? AsmInterpretedBridgeFrame::SizeArch32 : AsmInterpretedBridgeFrame::SizeArch64;
|
||||
}
|
||||
|
||||
AsmInterpretedEntryFrame entry;
|
||||
alignas(EAS) uintptr_t returnAddr;
|
||||
uintptr_t GetReturnAddr() const
|
||||
{
|
||||
@ -1169,6 +1193,10 @@ public:
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
void GetCalleeRegAndOffsetVec(kungfu::CalleeRegAndOffsetVec &ret) const
|
||||
{
|
||||
ret = calleeRegInfo_;
|
||||
}
|
||||
int ComputeDelta() const;
|
||||
template <GCVisitedFlag GCVisit = GCVisitedFlag::IGNORED>
|
||||
void Advance();
|
||||
@ -1188,7 +1216,8 @@ public:
|
||||
}
|
||||
bool IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
||||
void CollectBCOffsetInfo(kungfu::ConstInfo &info) const;
|
||||
std::tuple<uint64_t, uint8_t *, int> CalCallSiteInfo(uintptr_t retAddr) 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;
|
||||
private:
|
||||
JSTaggedType *current_ {nullptr};
|
||||
@ -1198,6 +1227,8 @@ private:
|
||||
uintptr_t optimizedReturnAddr_ {0};
|
||||
uint8_t *stackMapAddr_ {nullptr};
|
||||
int fpDeltaPrevFrameSp_ {0};
|
||||
kungfu::CalleeRegAndOffsetVec calleeRegInfo_;
|
||||
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
extern "C" int step_ark_managed_native_frame(
|
||||
|
@ -7174,6 +7174,23 @@ bool EcmaInterpreter::IsFastNewFrameEnter(JSFunction *ctor, JSHandle<Method> met
|
||||
return false;
|
||||
}
|
||||
|
||||
JSTaggedType *EcmaInterpreter::GetInterpreterFrameEnd(JSThread *thread, JSTaggedType *sp)
|
||||
{
|
||||
JSTaggedType *newSp;
|
||||
if (thread->IsAsmInterpreter()) {
|
||||
newSp = sp - InterpretedEntryFrame::NumOfMembers();
|
||||
} else {
|
||||
if (FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_FRAME ||
|
||||
FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_FAST_NEW_FRAME) {
|
||||
newSp = sp - InterpretedFrame::NumOfMembers(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
} else {
|
||||
newSp =
|
||||
sp - InterpretedEntryFrame::NumOfMembers(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
}
|
||||
}
|
||||
return newSp;
|
||||
}
|
||||
|
||||
bool EcmaInterpreter::IsFastNewFrameExit(JSTaggedType *sp)
|
||||
{
|
||||
return GET_FRAME(sp)->base.type == FrameType::INTERPRETER_FAST_NEW_FRAME;
|
||||
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/interpreter/interpreter.h"
|
||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||
|
||||
#include "ecmascript/frames.h"
|
||||
#include "ecmascript/interpreter/frame_handler.h"
|
||||
@ -40,20 +40,8 @@ EcmaRuntimeCallInfo* EcmaInterpreter::NewRuntimeCallInfo(
|
||||
JSThread *thread, JSHandle<JSTaggedValue> func, JSHandle<JSTaggedValue> thisObj, JSHandle<JSTaggedValue> newTarget,
|
||||
uint32_t numArgs, bool needCheckStack)
|
||||
{
|
||||
JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
JSTaggedType *newSp = nullptr;
|
||||
JSTaggedType *prevSp = sp;
|
||||
if (thread->IsAsmInterpreter()) {
|
||||
newSp = sp - InterpretedEntryFrame::NumOfMembers();
|
||||
} else {
|
||||
if (FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_FRAME ||
|
||||
FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_FAST_NEW_FRAME) {
|
||||
newSp = sp - InterpretedFrame::NumOfMembers(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
} else {
|
||||
newSp =
|
||||
sp - InterpretedEntryFrame::NumOfMembers(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
}
|
||||
}
|
||||
JSTaggedType *prevSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
JSTaggedType *newSp = GetInterpreterFrameEnd(thread, prevSp);
|
||||
if (needCheckStack && UNLIKELY(thread->DoStackOverflowCheck(newSp - numArgs - NUM_MANDATORY_JSFUNC_ARGS))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -63,6 +63,9 @@ public:
|
||||
static inline bool IsFastNewFrameEnter(JSFunction *ctor, JSHandle<Method> method);
|
||||
static inline bool IsFastNewFrameExit(JSTaggedType *sp);
|
||||
static inline int16_t GetHotnessCounter(uint32_t codeSize);
|
||||
static inline JSTaggedType *GetInterpreterFrameEnd(JSThread *thread, JSTaggedType *sp);
|
||||
|
||||
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_INTERPRETER_INTERPRETER_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user