!1345 Implement Prologue refactor and Add mulitple Optimized Frame In LLVM 12.0.1

Merge pull request !1345 from songzhengchao/optimizedjsfunction
This commit is contained in:
openharmony_ci 2022-06-07 13:49:24 +00:00 committed by Gitee
commit 7f92cff8cb
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
24 changed files with 508 additions and 1281 deletions

View File

@ -28,8 +28,8 @@ if (defined(ark_independent_build)) {
config("include_llvm") {
if (compile_llvm_online) {
include_dirs = [
"//third_party/llvm-project/build/include",
"//third_party/llvm-project/llvm/include/",
"//third_party/third_party_llvm-project/build/include",
"//third_party/third_party_llvm-project/llvm/include/",
]
} else {
include_dirs = [
@ -78,7 +78,7 @@ source_set("libark_jsoptimizer_set") {
]
if (compile_llvm_online) {
lib_dirs = [ "//third_party/llvm-project/build/lib" ]
lib_dirs = [ "//third_party/third_party_llvm-project/build/lib" ]
} else {
lib_dirs =
[ "//prebuilts/ark_tools/ark_js_prebuilts/llvm_prebuilts/build/lib" ]
@ -137,12 +137,13 @@ source_set("libark_jsoptimizer_set") {
"LLVMAArch64Desc",
"LLVMAArch64Disassembler",
"LLVMAArch64AsmParser",
"LLVMX86Utils",
"LLVMX86AsmParser",
"LLVMX86CodeGen",
"LLVMX86Desc",
"LLVMX86Disassembler",
"LLVMX86Info",
"LLVMFrontendOpenMP",
"LLVMBitWriter",
]
deps = [

View File

@ -28,14 +28,12 @@ echo ${BASE_HOME}
if [ ! -d "${BASE_HOME}/third_party/llvm-project" ]; then
cd ${BASE_HOME}/third_party
dd if=/dev/zero of=/tmp/mem.swap bs=1M count=4096
git clone https://gitee.com/surpassgoodchao/llvm-project.git
git clone git@gitee.com:openharmony-sig/third_party_llvm-project.git -b llvmorg-12.0.1-ark
git checkout 12.0.1-ark-1.0
fi
cd ${BASE_HOME}/third_party/llvm-project
if [ ! -d "build" ];then
git checkout -b local llvmorg-10.0.1
cp ../../ark/js_runtime/ecmascript/compiler/llvm/llvm_new.patch .
git apply --reject llvm_new.patch
mkdir build && cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_ARK_GC_SUPPORT=ON -DLLVM_ENABLE_TERMINFO=OFF DLLVM_STATIC_LINK_CXX_STDLIB=OFF -DLLVM_ENABLE_ZLIB=OFF ../llvm
ninja

View File

@ -23,14 +23,22 @@ void StubFileGenerator::CollectAsmStubCodeInfo(std::map<uintptr_t, std::string>
{
uintptr_t codeBegin = asmModule_.GetCodeBufferOffset();
auto asmCallSigns = asmModule_.GetCSigns();
uint32_t funSize = 0;
for (size_t i = 0; i < asmModule_.GetFunctionCount(); i++) {
auto cs = asmCallSigns[i];
auto entryOffset = asmModule_.GetFunction(cs->GetID());
stubInfo_.AddStubEntry(cs->GetTargetKind(), cs->GetID(), entryOffset + codeBegin, 0);
if (i < asmModule_.GetFunctionCount() - 1) {
auto nextcs = asmCallSigns[i + 1];
funSize = asmModule_.GetFunction(nextcs->GetID()) - entryOffset;
} else {
funSize = asmModule_.GetBufferSize() - entryOffset;
}
stubInfo_.AddStubEntry(cs->GetTargetKind(), cs->GetID(), entryOffset + codeBegin, 0, 0, funSize);
ASSERT(!cs->GetName().empty());
auto codeBuffer = modulePackage_[0].GetCodeBuffer();
uintptr_t entry = codeBuffer + entryOffset + codeBegin;
addr2name[entry] = cs->GetName();
DisassembleEachFunc(addr2name);
}
}
@ -38,7 +46,7 @@ void StubFileGenerator::CollectCodeInfo()
{
std::map<uintptr_t, std::string> addr2name;
for (size_t i = 0; i < modulePackage_.size(); i++) {
modulePackage_[i].CollectFuncEntryInfo(addr2name, stubInfo_, i);
modulePackage_[i].CollectFuncEntryInfo(addr2name, stubInfo_, i, GetLog());
if (i == 0) {
CollectAsmStubCodeInfo(addr2name);
}
@ -52,7 +60,7 @@ void AOTFileGenerator::CollectCodeInfo()
{
std::map<uintptr_t, std::string> addr2name;
for (size_t i = 0; i < modulePackage_.size(); i++) {
modulePackage_[i].CollectFuncEntryInfo(addr2name, aotInfo_, i);
modulePackage_[i].CollectFuncEntryInfo(addr2name, aotInfo_, i, GetLog());
auto des = modulePackage_[i].GetModuleSectionDes();
aotInfo_.AddModuleDes(des, aotfileHashs_[i]);
}

View File

@ -15,6 +15,7 @@
#ifndef ECMASCRIPT_COMPILER_FILE_GENERATORS_H
#define ECMASCRIPT_COMPILER_FILE_GENERATORS_H
#include <tuple>
#include "ecmascript/compiler/assembler_module.h"
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/compiler/llvm_codegen.h"
@ -32,35 +33,71 @@ public:
}
void CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, StubModulePackInfo &stubInfo,
uint32_t moduleIndex)
uint32_t moduleIndex, const CompilerLog &log)
{
auto codeBuff = assembler_->GetCodeBuffer();
auto engine = assembler_->GetEngine();
auto callSigns = llvmModule_->GetCSigns();
std::map<uintptr_t, int> addr2FpToPrevFrameSpDelta;
std::vector<uint64_t> funSizeVec;
std::vector<uintptr_t> entrys;
for (size_t j = 0; j < llvmModule_->GetFuncCount(); j++) {
auto cs = callSigns[j];
LLVMValueRef func = llvmModule_->GetFunction(j);
ASSERT(func != nullptr);
uintptr_t entry = reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, func));
stubInfo.AddStubEntry(cs->GetTargetKind(), cs->GetID(), entry - codeBuff, moduleIndex);
ASSERT(!cs->GetName().empty());
addr2name[entry] = cs->GetName();
entrys.push_back(entry);
}
const size_t funcCount = llvmModule_->GetFuncCount();
for (size_t j = 0; j < funcCount; j++) {
auto cs = callSigns[j];
LLVMValueRef func = llvmModule_->GetFunction(j);
ASSERT(func != nullptr);
int delta = assembler_->GetFpDeltaPrevFramSp(func, log);
ASSERT(delta >= 0 && (delta % sizeof(uintptr_t) == 0));
uint32_t funcSize = 0;
if (j < funcCount - 1) {
funcSize = entrys[j + 1] - entrys[j];
} else {
funcSize = codeBuff + assembler_->GetCodeSize() - entrys[j];
}
stubInfo.AddStubEntry(cs->GetTargetKind(), cs->GetID(), entrys[j] - codeBuff, moduleIndex, delta, funcSize);
ASSERT(!cs->GetName().empty());
addr2name[entrys[j]] = cs->GetName();
}
// GetCodeSize
}
void CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, AOTModulePackInfo &aotInfo,
uint32_t moduleIndex)
uint32_t moduleIndex, const CompilerLog &log)
{
auto codeBuff = assembler_->GetCodeBuffer();
auto engine = assembler_->GetEngine();
std::vector<std::tuple<uint64_t, size_t, int>> funcInfo; // entry、idx、delta
llvmModule_->IteratefuncIndexMap([&](size_t idx, LLVMValueRef func) {
uint64_t funcEntry = reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, func));
uint64_t length = 0;
std::string funcName(LLVMGetValueName2(func, &length));
assert(length != 0);
COMPILER_LOG(INFO) << "CollectCodeInfo for AOT func: " << funcName.c_str();
aotInfo.AddStubEntry(CallSignature::TargetKind::JSFUNCTION, idx, funcEntry - codeBuff, moduleIndex);
addr2name[funcEntry] = funcName;
int delta = assembler_->GetFpDeltaPrevFramSp(func, log);
ASSERT(delta >= 0 && (delta % sizeof(uintptr_t) == 0));
funcInfo.emplace_back(std::tuple(funcEntry, idx, delta));
});
const size_t funcCount = funcInfo.size();
for (size_t i = 0; i < funcInfo.size(); i++) {
uint64_t funcEntry;
size_t idx;
int delta;
uint32_t funcSize;
std::tie(funcEntry, idx, delta) = funcInfo[i];
if (i < funcCount - 1) {
funcSize = std::get<0>(funcInfo[i + 1]) - funcEntry;
} else {
funcSize = codeBuff + assembler_->GetCodeSize() - funcEntry;
}
aotInfo.AddStubEntry(CallSignature::TargetKind::JSFUNCTION, idx,
funcEntry - codeBuff, moduleIndex, delta, funcSize);
}
}
ModuleSectionDes GetModuleSectionDes()
@ -126,9 +163,9 @@ public:
explicit FileGenerator(const CompilerLog *log) : log_(log) {};
virtual ~FileGenerator() = default;
const CompilerLog *GetLog() const
const CompilerLog GetLog() const
{
return log_;
return *log_;
}
protected:
std::vector<Module> modulePackage_ {};

File diff suppressed because it is too large Load Diff

View File

@ -93,7 +93,7 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, OptimizedL
}
}
void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp) const
void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp, uintptr_t curPc) const
{
if (!IsLogEnabled()) {
return;
@ -105,7 +105,7 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t
uintptr_t derived = 0;
uintptr_t callsiteFp = *fp;
uintptr_t callSiteSp = FrameHandler::GetPrevFrameCallSiteSp(reinterpret_cast<JSTaggedType *>(fp));
uintptr_t callSiteSp = FrameHandler::GetPrevFrameCallSiteSp(reinterpret_cast<JSTaggedType *>(fp), curPc);
for (auto &info: *infos) {
if (info.first == GCStackMapRegisters::SP) {
@ -138,24 +138,26 @@ bool LLVMStackMapParser::IsDeriveredPointer(int callsitetime) const
}
bool LLVMStackMapParser::CollectStackMapSlots(uintptr_t callSiteAddr, uintptr_t frameFp,
std::set<uintptr_t> &baseSet, ChunkMap<DerivedDataKey, uintptr_t> *data, [[maybe_unused]] bool isVerifying) const
std::set<uintptr_t> &baseSet, ChunkMap<DerivedDataKey, uintptr_t> *data, [[maybe_unused]] bool isVerifying,
uintptr_t curPc) const
{
const CallSiteInfo *infos = GetCallSiteInfoByPc(callSiteAddr);
if (infos == nullptr) {
return false;
}
uintptr_t *fp = reinterpret_cast<uintptr_t *>(frameFp);
uintptr_t callsiteFp = *fp;
uintptr_t callSiteSp = FrameHandler::GetPrevFrameCallSiteSp(reinterpret_cast<JSTaggedType *>(frameFp), curPc);
uintptr_t address = 0;
uintptr_t base = 0;
uintptr_t derived = 0;
int i = 0;
if (IsLogEnabled()) {
PrintCallSiteInfo(infos, fp);
PrintCallSiteInfo(infos, fp, curPc);
}
uintptr_t callsiteFp = *fp;
uintptr_t callSiteSp = FrameHandler::GetPrevFrameCallSiteSp(reinterpret_cast<JSTaggedType *>(frameFp));
for (auto &info: *infos) {
if (info.first == GCStackMapRegisters::SP) {
address = callSiteSp + info.second;
@ -180,6 +182,7 @@ bool LLVMStackMapParser::CollectStackMapSlots(uintptr_t callSiteAddr, uintptr_t
}
} else {
base = reinterpret_cast<uintptr_t>(address);
baseSet.emplace(base);
}
i++;
}
@ -189,7 +192,9 @@ bool LLVMStackMapParser::CollectStackMapSlots(uintptr_t callSiteAddr, uintptr_t
void LLVMStackMapParser::CalcCallSite()
{
uint64_t recordNum = 0;
auto calStkMapRecordFunc = [this, &recordNum](uintptr_t address, int recordId) {
Pc2CallSiteInfo pc2CallSiteInfo;
Pc2ConstInfo pc2ConstInfo;
auto calStkMapRecordFunc = [this, &recordNum, &pc2CallSiteInfo, &pc2ConstInfo](uintptr_t address, int recordId) {
struct StkMapRecordHeadTy recordHead = llvmStackMap_.StkMapRecord[recordNum + recordId].head;
for (int j = 0; j < recordHead.NumLocations; j++) {
struct LocationTy loc = llvmStackMap_.StkMapRecord[recordNum + recordId].Locations[j];
@ -202,12 +207,16 @@ void LLVMStackMapParser::CalcCallSite()
instructionOffset << " callsite:" << " patchPointID :" << std::hex << patchPointID <<
callsite;
DwarfRegAndOffsetType info(loc.DwarfRegNum, loc.OffsetOrSmallConstant);
auto it = pc2CallSiteInfo_.find(callsite);
if (pc2CallSiteInfo_.find(callsite) == pc2CallSiteInfo_.end()) {
pc2CallSiteInfo_.insert(std::pair<uintptr_t, CallSiteInfo>(callsite, {info}));
auto it = pc2CallSiteInfo.find(callsite);
if (pc2CallSiteInfo.find(callsite) == pc2CallSiteInfo.end()) {
pc2CallSiteInfo.insert(std::pair<uintptr_t, CallSiteInfo>(callsite, {info}));
} else {
it->second.emplace_back(info);
}
} else if (loc.location == LocationTy::Kind::CONSTANT) {
if (j >= LocationTy::CONSTANT_FIRST_ELEMENT_INDEX) {
pc2ConstInfo[callsite].push_back(loc.OffsetOrSmallConstant);
}
}
}
};
@ -219,16 +228,17 @@ void LLVMStackMapParser::CalcCallSite()
}
recordNum += recordCount;
}
pc2CallSiteInfoVec_.emplace_back(pc2CallSiteInfo);
pc2ConstInfoVec_.emplace_back(pc2ConstInfo);
}
bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr<uint8_t []> stackMapAddr)
{
stackMapAddr_ = std::move(stackMapAddr);
if (!stackMapAddr_) {
COMPILER_LOG(ERROR) << "stackMapAddr_ nullptr error ! ";
if (!stackMapAddr) {
COMPILER_LOG(ERROR) << "stackMapAddr nullptr error ! ";
return false;
}
dataInfo_ = std::make_unique<DataInfo>(std::move(stackMapAddr_));
dataInfo_ = std::make_unique<DataInfo>(std::move(stackMapAddr));
llvmStackMap_.head = dataInfo_->Read<struct Header>();
uint32_t numFunctions, numConstants, numRecords;
numFunctions = dataInfo_->Read<uint32_t>();
@ -288,9 +298,56 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr<uint8_t []> stackMapA
COMPILER_OPTIONAL_LOG(DEBUG) << std::dec << i << "th function " << std::hex << hostAddr << " ---> "
<< deviceAddr;
}
pc2CallSiteInfo_.clear();
CalcCallSite();
pc2CallSiteInfoVec_.push_back(pc2CallSiteInfo_);
return true;
}
void LLVMStackMapParser::CalculateFuncFpDelta(Func2FpDelta info)
{
bool find = std::find(fun2FpDelta_.begin(), fun2FpDelta_.end(), info) == fun2FpDelta_.end();
if (!info.empty() && find) {
fun2FpDelta_.emplace_back(info);
}
for (auto &it: info) {
funAddr_.insert(it.first);
}
}
int LLVMStackMapParser::FindFpDelta(uintptr_t funcAddr, uintptr_t callsitePc) const
{
int delta = 0;
// next optimization can be performed via sorted/map.
for (auto &info: fun2FpDelta_) {
if (info.find(funcAddr) != info.end()) {
delta = info.at(funcAddr).first;
int funcSize = info.at(funcAddr).second;
if (callsitePc <= funcAddr + funcSize && callsitePc >= funcAddr) {
return delta;
}
}
}
return delta;
}
int LLVMStackMapParser::GetFuncFpDelta(uintptr_t callsitePc) const
{
int delta = 0;
auto itupper = funAddr_.upper_bound(callsitePc);
if (itupper != funAddr_.end()) { // find first element >= callsitePc
--itupper;
// callsitePC may jscall or entry, thus not existed in funAddr_
if ((itupper == funAddr_.end()) || (*itupper > callsitePc)) {
return delta;
}
delta = FindFpDelta(*itupper, callsitePc);
} else {
auto rit = funAddr_.crbegin(); // find last element
// callsitePC may jscall or entry, thus not existed in funAddr_
if ((rit == funAddr_.crend()) || (*rit > callsitePc)) {
return delta;
}
delta = FindFpDelta(*rit, callsitePc);
}
return delta;
}
} // namespace panda::ecmascript::kungfu

View File

@ -32,6 +32,10 @@ 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 Pc2ConstInfo = std::unordered_map<uintptr_t, ConstInfo>;
struct Header {
uint8_t stackmapversion; // Stack Map Version (current version is 3)
@ -89,6 +93,7 @@ struct LocationTy {
CONSTANT = 4,
CONSTANTNDEX = 5,
};
static constexpr int CONSTANT_FIRST_ELEMENT_INDEX = 3;
Kind location;
uint8_t Reserved_0;
uint16_t LocationSize;
@ -204,42 +209,59 @@ public:
const CallSiteInfo *GetCallSiteInfoByPc(uintptr_t funcAddr) const;
bool CollectStackMapSlots(uintptr_t callSiteAddr, uintptr_t frameFp,
std::set<uintptr_t> &baseSet, ChunkMap<DerivedDataKey, uintptr_t> *data,
[[maybe_unused]] bool isVerifying) const;
[[maybe_unused]] bool isVerifying,
uintptr_t curPc) const;
bool IsLogEnabled() const
{
return enableLog_;
}
void PUBLIC_API CalculateFuncFpDelta(Func2FpDelta info);
int PUBLIC_API GetFuncFpDelta(uintptr_t callsitePc) const;
ConstInfo GetConstInfo(uintptr_t callsite)
{
// next optimization can be performed via sorted/map to accelerate the search
for (auto &pc2ConstInfo : pc2ConstInfoVec_) {
auto it = pc2ConstInfo.find(callsite);
if (it != pc2ConstInfo.end()) {
return pc2ConstInfo[callsite];
}
}
return {};
}
private:
explicit LLVMStackMapParser(bool enableLog)
{
stackMapAddr_ = nullptr;
pc2CallSiteInfo_.clear();
pc2CallSiteInfoVec_.clear();
dataInfo_ = nullptr;
enableLog_ = enableLog;
funAddr_.clear();
fun2FpDelta_.clear();
pc2ConstInfoVec_.clear();
}
~LLVMStackMapParser()
{
if (stackMapAddr_) {
stackMapAddr_.release();
}
pc2CallSiteInfo_.clear();
pc2CallSiteInfoVec_.clear();
dataInfo_ = nullptr;
funAddr_.clear();
fun2FpDelta_.clear();
pc2ConstInfoVec_.clear();
}
void CalcCallSite();
bool IsDeriveredPointer(int callsitetime) const;
void PrintCallSiteInfo(const CallSiteInfo *infos, OptimizedLeaveFrame *frame) const;
void PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp) const;
void PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp, uintptr_t curPc) const;
int FindFpDelta(uintptr_t funcAddr, uintptr_t callsitePc) const;
std::unique_ptr<uint8_t[]> stackMapAddr_;
struct LLVMStackMap llvmStackMap_;
Pc2CallSiteInfo pc2CallSiteInfo_;
std::vector<Pc2CallSiteInfo> pc2CallSiteInfoVec_;
[[maybe_unused]] std::unique_ptr<DataInfo> dataInfo_;
bool enableLog_ {false};
std::set<uintptr_t> funAddr_;
std::vector<Func2FpDelta> fun2FpDelta_;
std::vector<Pc2ConstInfo> pc2ConstInfoVec_;
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_LLVM_LLVMSTACKPARSE_H

View File

@ -87,6 +87,7 @@ void LLVMIRGeneratorImpl::GenerateCode(Circuit *circuit, const ControlFlowGraph
const panda::ecmascript::JSMethod *method)
{
auto function = module_->AddFunc(method);
circuit->SetFrameType(FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
LLVMIRBuilder builder(&graph, circuit, module_, function, cfg, CallSignature::CallConv::WebKitJSCallConv,
enableLog_);
builder.Build();
@ -248,7 +249,26 @@ static const char *SymbolLookupCallback([[maybe_unused]] void *disInfo, [[maybe_
return nullptr;
}
void LLVMAssembler::Disassemble(const std::map<uint64_t, std::string> &addr2name, const CompilerLog &log) const
int LLVMAssembler::GetFpDeltaPrevFramSp(LLVMValueRef fn, const CompilerLog &log)
{
int fpToCallerSpDelta = 0;
const char attrKey[] = "fpToCallerSpDelta"; // this key must consistent with llvm backend.
LLVMAttributeRef attrirbuteRef = LLVMGetStringAttributeAtIndex(fn,
llvm::AttributeList::FunctionIndex, attrKey, strlen(attrKey));
if (attrirbuteRef) {
llvm::Attribute attr = llvm::unwrap(attrirbuteRef);
auto value = attr.getValueAsString().data();
fpToCallerSpDelta = atoi(value);
if (log.IsAlwaysEnabled()) {
size_t length;
COMPILER_LOG(INFO) << " funcName: " << LLVMGetValueName2(fn, &length) << " fpToCallerSpDelta:"
<< fpToCallerSpDelta;
}
}
return fpToCallerSpDelta;
}
void LLVMAssembler::Disassemble(const std::map<uintptr_t, std::string> &addr2name, const CompilerLog &log) const
{
LLVMDisasmContextRef dcr = LLVMCreateDisasm(LLVMGetTarget(module_), nullptr, 0, nullptr, SymbolLookupCallback);
bool logFlag = false;

View File

@ -194,7 +194,8 @@ public:
{
return engine_;
}
void Disassemble(const std::map<uint64_t, std::string> &addr2name, const CompilerLog &log) const;
void Disassemble(const std::map<uintptr_t, std::string> &addr2name, const CompilerLog &log) const;
static int GetFpDeltaPrevFramSp(LLVMValueRef fn, const CompilerLog &log);
static void Disassemble(uint8_t *buf, size_t size);
uintptr_t GetStackMapsSection() const
{

View File

@ -371,10 +371,14 @@ void LLVMIRBuilder::GenPrologue([[maybe_unused]] LLVMModuleRef &module, LLVMBuil
LLVMValueRef addr = LLVMBuildIntToPtr(builder, frameTypeSlotAddr,
LLVMPointerType(slotType_, 0), "frameType.Addr");
int reservedSlotsSize = slotSize_ * static_cast<int>(ReservedSlots::OPTIMIZED_RESERVED_SLOT);
if (frameType == panda::ecmascript::FrameType::OPTIMIZED_FRAME) {
LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "0");
} else if (frameType == panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME) {
LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "1");
LLVMAddTargetDependentFunctionAttr(function_, "frame-reserved-slots",
std::to_string(reservedSlotsSize).c_str());
} else if (frameType == panda::ecmascript::FrameType::OPTIMIZED_JS_FUNCTION_FRAME) {
reservedSlotsSize = slotSize_ * static_cast<int>(ReservedSlots::OPTIMIZED_JS_FUNCTION_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(function_, "frame-reserved-slots",
std::to_string(reservedSlotsSize).c_str());
} else {
COMPILER_OPTIONAL_LOG(FATAL) << "frameType interpret type error !";
ASSERT_PRINT(static_cast<uintptr_t>(frameType), "is not support !");
@ -629,56 +633,6 @@ LLVMValueRef LLVMIRBuilder::GetCurrentSP()
return spValue;
}
void LLVMIRBuilder::SaveCurrentSP()
{
if (compCfg_->Is64Bit()) {
LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false);
LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder_, llvmFpAddr, slotType_, "cast_int_t");
auto callSiteSpOffset = IsInterpreted() ?
AsmInterpretedFrame::GetCallSiteFpToSpDelta(compCfg_->Is32Bit()) :
OptimizedFrame::GetCallSiteFpToSpDelta(compCfg_->Is32Bit());
LLVMValueRef frameSpSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(slotType_,
callSiteSpOffset, false), "");
LLVMValueRef addr = LLVMBuildIntToPtr(builder_, frameSpSlotAddr,
LLVMPointerType(slotType_, 0), "frameCallSiteSP.Addr");
LLVMMetadataRef meta;
if (compCfg_->IsAmd64()) {
meta = LLVMMDStringInContext2(context_, "rsp", 4); // 4 : 4 means len of "rsp"
} else {
meta = LLVMMDStringInContext2(context_, "sp", 3); // 3 : 3 means len of "sp"
}
LLVMMetadataRef metadataNode = LLVMMDNodeInContext2(context_, &meta, 1);
LLVMValueRef spValue = ReadRegister(module_, builder_, metadataNode);
LLVMBuildStore(builder_, spValue, addr);
}
}
LLVMValueRef LLVMIRBuilder::GetCurrentSPFrameAddr()
{
LLVMValueRef glue = LLVMGetParam(function_, 0);
LLVMTypeRef glueType = LLVMTypeOf(glue);
LLVMValueRef rtoffset = LLVMConstInt(glueType,
JSThread::GlueData::GetCurrentFrameOffset(compCfg_->Is32Bit()),
0);
LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
return rtbaseoffset;
}
LLVMValueRef LLVMIRBuilder::GetCurrentSPFrame()
{
LLVMValueRef addr = GetCurrentSPFrameAddr();
LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), "");
LLVMValueRef currentSpFrame = LLVMBuildLoad(builder_, rtbaseAddr, "");
return currentSpFrame;
}
void LLVMIRBuilder::SetCurrentSPFrame(LLVMValueRef sp)
{
LLVMValueRef addr = GetCurrentSPFrameAddr();
LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), "");
LLVMBuildStore(builder_, sp, rtbaseAddr);
}
LLVMValueRef LLVMIRBuilder::GetCurrentFrameType(LLVMValueRef currentSpFrameAddr)
{
LLVMValueRef tmp = LLVMBuildSub(builder_, currentSpFrameAddr, LLVMConstInt(slotType_, slotSize_, 1), "");
@ -749,9 +703,6 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector<GateRef> &inList,
GateRef gateTmp = inList[paraIdx];
params.push_back(gate2LValue_[gateTmp]);
}
if (op == OpCode::CALL) {
SaveCurrentSP();
}
LLVMValueRef call = LLVMBuildCall(builder_, callee, params.data(),
inList.size() - firstArg + extraParameterCnt, "");
SetCallConvAttr(calleeDescriptor, call);

View File

@ -124,12 +124,18 @@ public:
void SetFunction(size_t index, LLVMValueRef func)
{
funcIndexMap_[index] = func;
funcIndexMap_.emplace_back(std::make_pair(index, func));
}
LLVMValueRef GetFunction(size_t index)
{
return funcIndexMap_.at(index);
// next optimization can be performed
for (auto &it: funcIndexMap_) {
if (it.first == index) {
return it.second;
}
}
return nullptr;
}
size_t GetFuncCount() const
@ -166,7 +172,7 @@ private:
// index:
// stub scenario - sequence of function adding to llvmModule
// aot scenario - method Id of function generated by panda files
std::map<size_t, LLVMValueRef> funcIndexMap_;
std::vector<std::pair<size_t, LLVMValueRef>> funcIndexMap_;
std::vector<const CallSignature *> callSigns_;
LLVMModuleRef module_;
CompilationConfig cfg_;
@ -245,7 +251,6 @@ private:
void LinkToLLVMCfg(int bbId, const OperandsVector &predecessors);
BasicBlock *EnsureBB(int id);
LLVMValueRef CallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder, bool isCaller);
void SaveCurrentSP();
LLVMValueRef GetCurrentSP();
LLVMValueRef ReadRegister(LLVMModuleRef &module, LLVMBuilderRef &builder,
LLVMMetadataRef meta);
@ -276,9 +281,6 @@ private:
LLVMValueRef VectorAdd(LLVMValueRef e1Value, LLVMValueRef e2Value, LLVMTypeRef rep);
LLVMValueRef CanonicalizeToInt(LLVMValueRef value);
LLVMValueRef CanonicalizeToPtr(LLVMValueRef value);
LLVMValueRef GetCurrentSPFrame();
LLVMValueRef GetCurrentSPFrameAddr();
void SetCurrentSPFrame(LLVMValueRef sp);
LLVMValueRef GetCurrentFrameType(LLVMValueRef currentSpFrameAddr);
bool IsGCRelated(GateType typeCode) const;
void SetFunctionCallConv();

View File

@ -18,8 +18,8 @@ import("//build/test.gni")
config("include_llvm_config") {
if (compile_llvm_online) {
include_dirs = [
"//third_party/llvm-project/build/include",
"//third_party/llvm-project/llvm/include/",
"//third_party/third_party_llvm-project/build/include",
"//third_party/third_party_llvm-project/llvm/include/",
]
} else {
include_dirs = [
@ -46,7 +46,7 @@ host_unittest_action("StubTest") {
]
if (compile_llvm_online) {
lib_dirs = [ "//third_party/llvm-project/build/lib" ]
lib_dirs = [ "//third_party/third_party_llvm-project/build/lib" ]
} else {
lib_dirs =
[ "//prebuilts/ark_tools/ark_js_prebuilts/llvm_prebuilts/build/lib" ]
@ -135,7 +135,7 @@ host_unittest_action("AssemblerTest") {
]
if (compile_llvm_online) {
lib_dirs = [ "//third_party/llvm-project/build/lib" ]
lib_dirs = [ "//third_party/third_party_llvm-project/build/lib" ]
} else {
lib_dirs =
[ "//prebuilts/ark_tools/ark_js_prebuilts/llvm_prebuilts/build/lib" ]

View File

@ -555,7 +555,8 @@ HWTEST_F_L0(StubTest, JSEntryTest)
/* implement stub1 */
LLVMValueRef stub1 = LLVMAddFunction(module, "stub1", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0));
LLVMAddTargetDependentFunctionAttr(stub1, "frame-pointer", "all");
LLVMAddTargetDependentFunctionAttr(stub1, "js-stub-call", "1");
int reservedSlotsSize = sizeof(uint64_t) * static_cast<int>(ReservedSlots::OPTIMIZED_ENTRY_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(stub1, "frame-reserved-slots", std::to_string(reservedSlotsSize).c_str());
LLVMBasicBlockRef entryBb = LLVMAppendBasicBlock(stub1, "entry");
LLVMPositionBuilderAtEnd(builder, entryBb);
@ -593,7 +594,8 @@ HWTEST_F_L0(StubTest, JSEntryTest)
/* implement stub2 call stub3 */
LLVMValueRef stub2 = LLVMAddFunction(module, "stub2", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0));
LLVMAddTargetDependentFunctionAttr(stub2, "frame-pointer", "all");
LLVMAddTargetDependentFunctionAttr(stub2, "js-stub-call", "1");
int reservedSlotsSize = sizeof(uint64_t) * static_cast<int>(ReservedSlots::OPTIMIZED_ENTRY_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(stub2, "frame-reserved-slots", std::to_string(reservedSlotsSize).c_str());
entryBb = LLVMAppendBasicBlock(stub2, "entry");
LLVMPositionBuilderAtEnd(builder, entryBb);
@ -623,7 +625,8 @@ HWTEST_F_L0(StubTest, JSEntryTest)
/* implement stub3 call RuntimeFunc2 */
LLVMAddTargetDependentFunctionAttr(stub3, "frame-pointer", "all");
LLVMAddTargetDependentFunctionAttr(stub3, "js-stub-call", "0");
int reservedSlotsSize = sizeof(uint64_t) * static_cast<int>(ReservedSlots::OPTIMIZED_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(stub3, "frame-reserved-slots", std::to_string(reservedSlotsSize).c_str());
entryBb = LLVMAppendBasicBlock(stub3, "entry");
LLVMPositionBuilderAtEnd(builder, entryBb);
@ -686,7 +689,8 @@ HWTEST_F_L0(StubTest, Prologue)
/* implement main implement */
LLVMValueRef func = LLVMAddFunction(module, "main", LLVMFunctionType(LLVMInt64Type(), nullptr, 0, 0));
LLVMAddTargetDependentFunctionAttr(func, "frame-pointer", "all");
LLVMAddTargetDependentFunctionAttr(func, "js-stub-call", "1");
int reservedSlotsSize = sizeof(uint64_t) * static_cast<int>(ReservedSlots::OPTIMIZED_ENTRY_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(func, "frame-reserved-slots", std::to_string(reservedSlotsSize).c_str());
LLVMBasicBlockRef entryBb = LLVMAppendBasicBlock(func, "entry");
LLVMPositionBuilderAtEnd(builder, entryBb);
@ -695,7 +699,8 @@ HWTEST_F_L0(StubTest, Prologue)
LLVMBuilderRef builderBar = LLVMCreateBuilder();
LLVMValueRef bar = LLVMAddFunction(module, "bar", LLVMFunctionType(LLVMInt64Type(), paramTys0, 2, 0));
LLVMAddTargetDependentFunctionAttr(bar, "frame-pointer", "all");
LLVMAddTargetDependentFunctionAttr(bar, "js-stub-call", "0");
int reservedSlotsSize = sizeof(uint64_t) * static_cast<int>(ReservedSlots::OPTIMIZED_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(bar, "frame-reserved-slots", std::to_string(reservedSlotsSize).c_str());
LLVMBasicBlockRef entryBbBar = LLVMAppendBasicBlock(bar, "entry");
LLVMPositionBuilderAtEnd(builderBar, entryBbBar);
LLVMValueRef value0Bar = LLVMGetParam(bar, 0);
@ -744,7 +749,8 @@ HWTEST_F_L0(StubTest, CEntryFp)
/* implement main call RuntimeFunc */
LLVMValueRef func = LLVMAddFunction(module, "main", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0));
LLVMAddTargetDependentFunctionAttr(func, "frame-pointer", "all");
LLVMAddTargetDependentFunctionAttr(func, "js-stub-call", "1");
int reservedSlotsSize = sizeof(uint64_t) * static_cast<int>(ReservedSlots::OPTIMIZED_ENTRY_RESERVED_SLOT);
LLVMAddTargetDependentFunctionAttr(func, "frame-reserved-slots", std::to_string(reservedSlotsSize).c_str());
LLVMBasicBlockRef entryBb = LLVMAppendBasicBlock(func, "entry");
LLVMPositionBuilderAtEnd(builder, entryBb);

View File

@ -236,7 +236,7 @@ void AssemblerStubs::OptimizedCallOptimized(ExtendedAssembler *assembler)
__ SaveFpAndLr();
// Construct frame
Register frameType(X5);
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_FRAME)));
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)));
__ Str(frameType, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
// callee save
@ -378,32 +378,33 @@ void AssemblerStubs::CallBuiltinTrampoline(ExtendedAssembler *assembler)
// uint64_t JSCall(uintptr_t glue, uint32_t argc, JSTaggedType calltarget, JSTaggedType new, JSTaggedType this, ...)
// webkit_jscc calling convention call js function()
// Input: %x0 - glue
// stack layout: sp + N*8 argvN
// ........
// sp + 24: argc
// sp + 16: this
// sp + 8: new
// sp: jsfunc
// +--------------------------+
// | argv[argc-1] |
// +--------------------------+
// | .......... |
// +--------------------------+
// | argv[1] |
// +--------------------------+
// | argv[0] |
// +--------------------------+ ---
// | argc | ^
// |--------------------------| Fixed
// | RuntimeId | OptimizedFrame
// |--------------------------| |
// | returnAddr | |
// |--------------------------| |
// | callsiteFp | |
// |--------------------------| |
// | frameType | v
// +--------------------------+ ---
// %x0 - glue
// stack layout
// sp + N*8 argvN
// ........
// sp + 24: argc
// sp + 16: this
// sp + 8: new
// sp: jsfunc
// +--------------------------+
// | ... |
// +--------------------------+
// | arg0 |
// +--------------------------+
// | this |
// +--------------------------+
// | new |
// +--------------------------+ ---
// | jsfunction | ^
// |--------------------------| Fixed
// | argc | OptimizedFrame
// |--------------------------| |
// | returnAddr | |
// |--------------------------| |
// | callsiteFp | |
// |--------------------------| |
// | frameType | v
// +--------------------------+ ---
void AssemblerStubs::JSCall(ExtendedAssembler *assembler)
{
__ BindAssemblerStub(RTSTUB_ID(JSCall));
@ -502,7 +503,7 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
// construct frame
Register frameType(X5);
Register fp(X29);
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_FRAME)));
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)));
__ Str(frameType, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
Register argVEnd(X4);
__ Add(argVEnd, fp, Immediate(GetStackArgOffSetToFp(0)));
@ -597,7 +598,7 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
Register frameType(X6);
Register taggedMessageId(X5);
__ SaveFpAndLr();
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_FRAME)));
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)));
__ Mov(taggedMessageId,
Immediate(JSTaggedValue(GET_MESSAGE_STRING_ID(NonCallable)).GetRawData()));
// 2 : 2 means pair
@ -1890,4 +1891,4 @@ void AssemblerStubs::PushArgsSlowPath(ExtendedAssembler *assembler, Register &gl
PushArgsFastPath(assembler, glueRegister, argcRegister, argvRegister, callTargetRegister, methodRegister,
prevSpRegister, fpRegister, callFieldRegister);
}
} // panda::ecmascript::aarch64
} // panda::ecmascript::aarch64

View File

@ -193,7 +193,7 @@ void AssemblerStubsX64::OptimizedCallOptimized(ExtendedAssembler *assembler)
Label lPopFrame1;
__ Pushq(rbp);
__ Movq(rsp, rbp);
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_FRAME));
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
// callee save
__ Pushq(r14);
__ Pushq(rbx);
@ -402,7 +402,7 @@ void AssemblerStubsX64::JSCallWithArgV(ExtendedAssembler *assembler)
{
__ Pushq(rbp);
__ Movq(rsp, rbp); // set frame pointer
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_FRAME)); // set frame type
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)); // set frame type
__ Movq(MessageString::Message_NonCallable, rax);
__ Pushq(rax); // message id
__ Pushq(1); // argc
@ -473,7 +473,7 @@ void AssemblerStubsX64::JSCallWithArgV(ExtendedAssembler *assembler)
{
__ Pushq(rbp);
__ Movq(rsp, rbp);
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_FRAME));
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
__ Pushq(r10); // callee save
__ Movq(rsp, rdx);
__ Addq(32, rdx); // 32: sp + 32 argv
@ -653,7 +653,7 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
{
__ Pushq(rbp);
__ Movq(rsp, rbp); // set frame pointer
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_FRAME)); // set frame type
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)); // set frame type
__ Movq(MessageString::Message_NonCallable, rax);
__ Pushq(rax); // message id
__ Pushq(1); // argc
@ -724,7 +724,7 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
{
__ Pushq(rbp);
__ Movq(rsp, rbp);
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_FRAME));
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
__ Pushq(r10); // callee save
__ Movq(rsp, rdx);
__ Addq(32, rdx); // 32: sp + 32 argv

View File

@ -105,6 +105,17 @@ bool StubModulePackInfo::Load(EcmaVM *vm, const std::string &filename)
des_[i].GetHostCodeSecAddr(), startAddr);
}
}
for (auto &funcEntryDes : GetStubs()) {
auto codeAddr = funcEntryDes.codeAddr_; // offset
auto moduleIndex = funcEntryDes.moduleIndex_;
auto startAddr = des_[moduleIndex].GetDeviceCodeSecAddr();
auto delta = funcEntryDes.fpDeltaPrevFramSp_;
uintptr_t funAddr = startAddr + codeAddr;
kungfu::Func2FpDelta fun2fpDelta;
auto funSize = funcEntryDes.funcSize_;
fun2fpDelta[funAddr] = std::make_pair(delta, funSize);
kungfu::LLVMStackMapParser::GetInstance().CalculateFuncFpDelta(fun2fpDelta);
}
for (size_t i = 0; i < entries_.size(); i++) {
auto des = des_[entries_[i].moduleIndex_];
entries_[i].codeAddr_ += des.GetDeviceCodeSecAddr();
@ -184,6 +195,18 @@ bool AOTModulePackInfo::Load(EcmaVM *vm, const std::string &filename)
des_[i].GetHostCodeSecAddr(), startAddr);
}
}
for (auto &funcEntryDes : GetStubs()) {
auto codeAddr = funcEntryDes.codeAddr_; // offset
auto moduleIndex = funcEntryDes.moduleIndex_;
auto delta = funcEntryDes.fpDeltaPrevFramSp_;
auto funSize = funcEntryDes.funcSize_;
auto startAddr = des_[moduleIndex].GetDeviceCodeSecAddr();
uintptr_t funAddr = startAddr + codeAddr;
kungfu::Func2FpDelta fun2fpDelta;
fun2fpDelta[funAddr] = std::make_pair(delta, funSize);
kungfu::LLVMStackMapParser::GetInstance().CalculateFuncFpDelta(fun2fpDelta);
}
for (size_t i = 0; i < entries_.size(); i++) {
auto des = des_[entries_[i].moduleIndex_];
entries_[i].codeAddr_ += des.GetDeviceCodeSecAddr();

View File

@ -95,6 +95,8 @@ public:
CallSignature::TargetKind kind_;
uint32_t indexInKind_;
uint32_t moduleIndex_;
int fpDeltaPrevFramSp_;
uint32_t funcSize_;
bool IsStub() const
{
return CallSignature::TargetKind::STUB_BEGIN <= kind_ && kind_ < CallSignature::TargetKind::STUB_END;
@ -154,13 +156,16 @@ public:
entryNum_ = n;
}
void AddStubEntry(CallSignature::TargetKind kind, int indexInKind, uint64_t offset, uint32_t moduleIndex)
void AddStubEntry(CallSignature::TargetKind kind, int indexInKind, uint64_t offset,
uint32_t moduleIndex, int delta, uint32_t size)
{
FuncEntryDes des;
des.kind_ = kind;
des.indexInKind_ = static_cast<uint32_t>(indexInKind);
des.codeAddr_ = offset;
des.moduleIndex_ = moduleIndex;
des.fpDeltaPrevFramSp_ = delta;
des.funcSize_ = size;
entries_.emplace_back(des);
}

View File

@ -237,17 +237,19 @@ namespace panda::ecmascript {
enum class FrameType: uintptr_t {
OPTIMIZED_FRAME = 0,
OPTIMIZED_ENTRY_FRAME = 1,
LEAVE_FRAME = 2,
LEAVE_FRAME_WITH_ARGV = 3,
INTERPRETER_FRAME = 4,
ASM_INTERPRETER_FRAME = 5,
INTERPRETER_CONSTRUCTOR_FRAME = 6,
BUILTIN_FRAME = 7,
BUILTIN_FRAME_WITH_ARGV = 8,
BUILTIN_ENTRY_FRAME = 9,
INTERPRETER_FAST_NEW_FRAME = 10,
INTERPRETER_ENTRY_FRAME = 11,
ASM_INTERPRETER_ENTRY_FRAME = 12,
OPTIMIZED_JS_FUNCTION_FRAME = 2,
LEAVE_FRAME = 3,
LEAVE_FRAME_WITH_ARGV = 4,
INTERPRETER_FRAME = 5,
ASM_INTERPRETER_FRAME = 6,
INTERPRETER_CONSTRUCTOR_FRAME = 7,
BUILTIN_FRAME = 8,
BUILTIN_FRAME_WITH_ARGV = 9,
BUILTIN_ENTRY_FRAME = 10,
INTERPRETER_FAST_NEW_FRAME = 11,
INTERPRETER_ENTRY_FRAME = 12,
ASM_INTERPRETER_ENTRY_FRAME = 13,
OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME = 14,
INTERPRETER_BEGIN = INTERPRETER_FRAME,
INTERPRETER_END = INTERPRETER_FAST_NEW_FRAME,
@ -255,6 +257,12 @@ enum class FrameType: uintptr_t {
BUILTIN_END = BUILTIN_ENTRY_FRAME,
};
enum class ReservedSlots: int {
OPTIMIZED_RESERVED_SLOT = 1,
OPTIMIZED_JS_FUNCTION_RESERVED_SLOT = 1,
OPTIMIZED_ENTRY_RESERVED_SLOT = 2,
};
enum class JSCallMode : uintptr_t {
CALL_ARG0 = 0,
CALL_ARG1,
@ -278,9 +286,9 @@ struct OptimizedFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
base::AlignedPointer> {
public:
enum class Index : size_t {
CallSiteSpIndex = 0,
TypeIndex,
TypeIndex = 0,
PrevFpIndex,
ReturnAddrIndex,
NumOfMembers
};
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
@ -294,22 +302,84 @@ public:
{
return prevFp;
}
inline uintptr_t GetCallSiteSp() const
{
return callSiteSp;
}
static int32_t GetCallSiteFpToSpDelta(bool isArch32)
{
auto prevFpOffset = GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
auto callSiteSpOffset = GetOffset<static_cast<size_t>(Index::CallSiteSpIndex)>(isArch32);
return prevFpOffset - callSiteSpOffset;
}
alignas(EAS) FrameType type {0};
alignas(EAS) JSTaggedType *prevFp {nullptr};
alignas(EAS) uintptr_t returnAddr {0};
};
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedFrame), OptimizedFrame::SizeArch32, OptimizedFrame::SizeArch64);
alignas(EAS) uintptr_t callSiteSp {0};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
struct OptimizedJSFunctionArgConfigFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
base::AlignedPointer,
base::AlignedPointer> {
public:
enum class Index : size_t {
TypeIndex = 0,
PrevFpIndex,
NumOfMembers
};
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
static OptimizedJSFunctionArgConfigFrame* GetFrameFromSp(const JSTaggedType *sp)
{
return reinterpret_cast<OptimizedJSFunctionArgConfigFrame *>(reinterpret_cast<uintptr_t>(sp)
- MEMBER_OFFSET(OptimizedJSFunctionArgConfigFrame, prevFp));
}
inline JSTaggedType* GetPrevFrameFp()
{
return prevFp;
}
alignas(EAS) FrameType type {0};
alignas(EAS) JSTaggedType *prevFp {nullptr};
};
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedFrame), OptimizedFrame::SizeArch32, OptimizedFrame::SizeArch64);
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionArgConfigFrame),
OptimizedJSFunctionArgConfigFrame::SizeArch32, OptimizedJSFunctionArgConfigFrame::SizeArch64);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
struct OptimizedJSFunctionFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
base::AlignedPointer,
base::AlignedPointer,
base::AlignedPointer> {
public:
enum class Index : size_t {
TypeIndex = 0,
PrevFpIndex,
ReturnAddrIndex,
NumOfMembers
};
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
static OptimizedJSFunctionFrame* GetFrameFromSp(const JSTaggedType *sp)
{
return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp)
- MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
}
inline JSTaggedType* GetPrevFrameFp()
{
return prevFp;
}
uintptr_t* ComputePrevFrameSp(const JSTaggedType *sp, int delta)
{
uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp))
+ delta / sizeof(uintptr_t);
return preFrameSp;
}
JSTaggedType* GetArgv(uintptr_t *preFrameSp)
{
return reinterpret_cast<JSTaggedType *>(preFrameSp + sizeof(uint64_t) / sizeof(uintptr_t));
}
// dynamic callee saveregisters for x86-64
alignas(EAS) FrameType type {0};
alignas(EAS) JSTaggedType *prevFp {nullptr};
alignas(EAS) uintptr_t returnAddr {0};
// dynamic callee saveregisters for arm64
// argc
// argv[0]
// argv[1]
// ... argv[n - 1]
};
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionFrame), OptimizedJSFunctionFrame::SizeArch32,
OptimizedJSFunctionFrame::SizeArch64);
struct OptimizedEntryFrame {
public:
@ -427,7 +497,7 @@ struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTyp
FunctionIndex = 0,
AccIndex,
EnvIndex,
CallSizeOrCallSiteSpIndex,
CallSizeIndex,
FpIndex,
PcIndex,
BaseIndex,
@ -458,7 +528,7 @@ struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTyp
static size_t GetCallSizeOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::CallSizeOrCallSiteSpIndex)>(isArch32);
return GetOffset<static_cast<size_t>(Index::CallSizeIndex)>(isArch32);
}
static size_t GetFunctionOffset(bool isArch32)
@ -491,18 +561,6 @@ struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTyp
return isArch32 ? AsmInterpretedFrame::SizeArch32 : AsmInterpretedFrame::SizeArch64;
}
inline uintptr_t GetCallSiteSp() const
{
return callSizeOrCallSiteSp;
}
static int32_t GetCallSiteFpToSpDelta(bool isArch32)
{
auto fpOffset = GetSize(isArch32);
auto callSiteSpOffset = GetOffset<static_cast<size_t>(Index::CallSizeOrCallSiteSpIndex)>(isArch32);
return fpOffset - callSiteSpOffset;
}
static uint32_t NumOfMembers()
{
return sizeof(AsmInterpretedFrame) / JSTaggedValue::TaggedTypeSize();
@ -511,7 +569,7 @@ struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTyp
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
alignas(EAS) uintptr_t callSizeOrCallSiteSp {0};
alignas(EAS) uintptr_t callSize {0};
alignas(EAS) JSTaggedType *fp {nullptr};
alignas(EAS) const uint8_t *pc {nullptr};
alignas(EAS) InterpretedFrameBase base;

View File

@ -33,6 +33,16 @@ void FrameHandler::PrevFrame()
sp_ = frame->GetPrevFrameFp();
break;
}
case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME: {
auto frame = OptimizedJSFunctionArgConfigFrame::GetFrameFromSp(sp_);
sp_ = frame->GetPrevFrameFp();
break;
}
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
auto frame = OptimizedJSFunctionFrame::GetFrameFromSp(sp_);
sp_ = frame->GetPrevFrameFp();
break;
}
case FrameType::OPTIMIZED_ENTRY_FRAME: {
auto frame = OptimizedEntryFrame::GetFrameFromSp(sp_);
sp_ = frame->GetPrevFrameFp();
@ -95,7 +105,7 @@ void FrameHandler::PrevFrame()
}
}
uintptr_t FrameHandler::GetPrevFrameCallSiteSp(const JSTaggedType *sp)
uintptr_t FrameHandler::GetPrevFrameCallSiteSp(const JSTaggedType *sp, uintptr_t curPc)
{
if (sp == nullptr) {
return 0U;
@ -119,11 +129,11 @@ uintptr_t FrameHandler::GetPrevFrameCallSiteSp(const JSTaggedType *sp)
auto frame = BuiltinFrame::GetFrameFromSp(sp);
return frame->GetCallSiteSp();
}
case FrameType::OPTIMIZED_FRAME: {
auto frame = OptimizedFrame::GetFrameFromSp(sp);
sp = frame->GetPrevFrameFp();
type = GetFrameType(sp);
break;
case FrameType::OPTIMIZED_FRAME:
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
auto callSiteSp = reinterpret_cast<uintptr_t>(sp) +
kungfu::LLVMStackMapParser::GetInstance().GetFuncFpDelta(curPc);
return callSiteSp;
}
case FrameType::BUILTIN_ENTRY_FRAME:
case FrameType::ASM_INTERPRETER_FRAME:
@ -138,14 +148,6 @@ uintptr_t FrameHandler::GetPrevFrameCallSiteSp(const JSTaggedType *sp)
UNREACHABLE();
}
}
if (type == FrameType::OPTIMIZED_FRAME) {
auto frame = OptimizedFrame::GetFrameFromSp(sp);
return frame->GetCallSiteSp();
}
auto frame = AsmInterpretedFrame::GetFrameFromSp(sp);
return frame->GetCallSiteSp();
}
ARK_INLINE void FrameHandler::AdvanceToInterpretedFrame()
@ -438,7 +440,8 @@ ARK_INLINE void FrameHandler::BuiltinFrameIterate(const JSTaggedType *sp,
std::set<uintptr_t> slotAddrs;
bool ret = kungfu::LLVMStackMapParser::GetInstance().CollectStackMapSlots(
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying);
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying,
optimizedReturnAddr_);
if (!ret) {
#ifndef NDEBUG
LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << frame->returnAddr;
@ -466,7 +469,8 @@ ARK_INLINE void FrameHandler::BuiltinWithArgvFrameIterate(const JSTaggedType *sp
std::set<uintptr_t> slotAddrs;
bool ret = kungfu::LLVMStackMapParser::GetInstance().CollectStackMapSlots(
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying);
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs,
derivedPointers, isVerifying, optimizedReturnAddr_);
if (!ret) {
#ifndef NDEBUG
LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << frame->returnAddr;
@ -497,10 +501,10 @@ ARK_INLINE void FrameHandler::InterpretedEntryFrameIterate(const JSTaggedType *s
}
ARK_INLINE void FrameHandler::OptimizedFrameIterate(const JSTaggedType *sp,
const RootVisitor &v0,
[[maybe_unused]] const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
bool isVerifying) const
const RootVisitor &v0,
[[maybe_unused]] const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
bool isVerifying) const
{
std::set<uintptr_t> slotAddrs;
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
@ -508,7 +512,45 @@ ARK_INLINE void FrameHandler::OptimizedFrameIterate(const JSTaggedType *sp,
reinterpret_cast<uintptr_t>(*(reinterpret_cast<uintptr_t*>(const_cast<JSTaggedType *>(sp)) + 1));
bool enableCompilerLog = thread_->GetEcmaVM()->GetJSOptions().WasSetlogCompiledMethods();
bool ret = kungfu::LLVMStackMapParser::GetInstance(enableCompilerLog).CollectStackMapSlots(
returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying);
returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying, optimizedReturnAddr_);
if (!ret) {
#ifndef NDEBUG
LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << returnAddr;
#endif
return;
}
for (const auto &slot : slotAddrs) {
v0(Root::ROOT_FRAME, ObjectSlot(slot));
}
}
ARK_INLINE void FrameHandler::OptimizedJSFunctionFrameIterate(const JSTaggedType *sp,
const RootVisitor &v0,
[[maybe_unused]] const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
bool isVerifying)
{
OptimizedJSFunctionFrame *frame = OptimizedJSFunctionFrame::GetFrameFromSp(sp);
auto currentPc = optimizedReturnAddr_;
optimizedReturnAddr_ = frame->returnAddr;
int delta = kungfu::LLVMStackMapParser::GetInstance().GetFuncFpDelta(currentPc);
uintptr_t *preFrameSp = frame->ComputePrevFrameSp(sp, delta);
auto argc = *(reinterpret_cast<uint64_t *>(preFrameSp));
JSTaggedType *argv = frame->GetArgv(preFrameSp);
if (argc > 0) {
uintptr_t start = ToUintPtr(argv); // argv
uintptr_t end = ToUintPtr(argv + argc);
v1(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
}
std::set<uintptr_t> slotAddrs;
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
auto returnAddr =
reinterpret_cast<uintptr_t>(*(reinterpret_cast<uintptr_t*>(const_cast<JSTaggedType *>(sp)) + 1));
bool enableCompilerLog = thread_->GetEcmaVM()->GetJSOptions().WasSetlogCompiledMethods();
bool ret = kungfu::LLVMStackMapParser::GetInstance(enableCompilerLog).CollectStackMapSlots(
returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying, optimizedReturnAddr_);
if (!ret) {
#ifndef NDEBUG
LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << returnAddr;
@ -525,14 +567,14 @@ ARK_INLINE void FrameHandler::OptimizedEntryFrameIterate(const JSTaggedType *sp,
const RootVisitor &v0,
[[maybe_unused]] const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
bool isVerifying) const
bool isVerifying)
{
std::set<uintptr_t> slotAddrs;
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
auto returnAddr = reinterpret_cast<uintptr_t>(*(reinterpret_cast<uintptr_t*>(const_cast<JSTaggedType *>(sp)) + 1));
bool enableCompilerLog = thread_->GetEcmaVM()->GetJSOptions().WasSetlogCompiledMethods();
bool ret = kungfu::LLVMStackMapParser::GetInstance(enableCompilerLog).CollectStackMapSlots(
returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying);
returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying, optimizedReturnAddr_);
if (!ret) {
#ifndef NDEBUG
LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << returnAddr;
@ -549,7 +591,7 @@ ARK_INLINE void FrameHandler::OptimizedLeaveFrameIterate(const JSTaggedType *sp,
const RootVisitor &v0,
[[maybe_unused]] const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
bool isVerifying) const
bool isVerifying)
{
OptimizedLeaveFrame *frame = OptimizedLeaveFrame::GetFrameFromSp(sp);
if (frame->argc > 0) {
@ -561,7 +603,8 @@ ARK_INLINE void FrameHandler::OptimizedLeaveFrameIterate(const JSTaggedType *sp,
std::set<uintptr_t> slotAddrs;
bool ret = kungfu::LLVMStackMapParser::GetInstance().CollectStackMapSlots(
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying);
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs,
derivedPointers, isVerifying, optimizedReturnAddr_);
if (!ret) {
return;
}
@ -575,7 +618,7 @@ ARK_INLINE void FrameHandler::OptimizedWithArgvLeaveFrameIterate(const JSTaggedT
const RootVisitor &v0,
[[maybe_unused]] const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
bool isVerifying) const
bool isVerifying)
{
OptimizedLeaveFrame *frame = OptimizedLeaveFrame::GetFrameFromSp(sp);
if (frame->argc > 0) {
@ -588,7 +631,8 @@ ARK_INLINE void FrameHandler::OptimizedWithArgvLeaveFrameIterate(const JSTaggedT
std::set<uintptr_t> slotAddrs;
bool ret = kungfu::LLVMStackMapParser::GetInstance().CollectStackMapSlots(
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs, derivedPointers, isVerifying);
frame->returnAddr, reinterpret_cast<uintptr_t>(sp), slotAddrs,
derivedPointers, isVerifying, optimizedReturnAddr_);
if (!ret) {
return;
}
@ -598,13 +642,13 @@ ARK_INLINE void FrameHandler::OptimizedWithArgvLeaveFrameIterate(const JSTaggedT
}
}
void FrameHandler::IterateRsp(const RootVisitor &v0, const RootRangeVisitor &v1) const
void FrameHandler::IterateRsp(const RootVisitor &v0, const RootRangeVisitor &v1)
{
JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
IterateFrameChain(current, v0, v1);
}
void FrameHandler::IterateSp(const RootVisitor &v0, const RootRangeVisitor &v1) const
void FrameHandler::IterateSp(const RootVisitor &v0, const RootRangeVisitor &v1)
{
JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame());
while (current) {
@ -616,7 +660,7 @@ void FrameHandler::IterateSp(const RootVisitor &v0, const RootRangeVisitor &v1)
}
}
void FrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const
void FrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1)
{
if (thread_->IsAsmInterpreter()) {
IterateSp(v0, v1);
@ -634,7 +678,7 @@ void FrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) co
IterateFrameChain(current, v0, v1);
}
void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0, const RootRangeVisitor &v1) const
void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0, const RootRangeVisitor &v1)
{
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers = thread_->GetEcmaVM()->GetHeap()->GetDerivedPointers();
bool isVerifying = false;
@ -648,18 +692,36 @@ void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0,
switch (type) {
case FrameType::OPTIMIZED_FRAME: {
auto frame = OptimizedFrame::GetFrameFromSp(current);
auto prevFrame = frame->GetPrevFrameFp();
OptimizedFrameIterate(current, v0, v1, derivedPointers, isVerifying);
current = prevFrame;
optimizedReturnAddr_ = frame->returnAddr;
break;
}
case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME: {
OptimizedJSFunctionFrame *frame = OptimizedJSFunctionFrame::GetFrameFromSp(current);
optimizedReturnAddr_ = frame->returnAddr;
current = frame->GetPrevFrameFp();
break;
}
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
auto frame = OptimizedJSFunctionFrame::GetFrameFromSp(current);
auto prevFrame = frame->GetPrevFrameFp();
OptimizedJSFunctionFrameIterate(current, v0, v1, derivedPointers, isVerifying);
current = prevFrame;
optimizedReturnAddr_ = frame->returnAddr;
break;
}
case FrameType::OPTIMIZED_ENTRY_FRAME: {
auto frame = OptimizedEntryFrame::GetFrameFromSp(current);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = 0;
break;
}
case FrameType::ASM_INTERPRETER_ENTRY_FRAME: {
auto frame = AsmInterpretedEntryFrame::GetFrameFromSp(current);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = 0;
break;
}
case FrameType::ASM_INTERPRETER_FRAME:
@ -667,6 +729,7 @@ void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0,
auto frame = AsmInterpretedFrame::GetFrameFromSp(current);
AsmInterpretedFrameIterate(current, v0, v1);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = 0;
break;
}
case FrameType::INTERPRETER_FRAME:
@ -674,24 +737,28 @@ void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0,
auto frame = InterpretedFrame::GetFrameFromSp(current);
InterpretedFrameIterate(current, v0, v1);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = 0;
break;
}
case FrameType::LEAVE_FRAME: {
auto frame = OptimizedLeaveFrame::GetFrameFromSp(current);
OptimizedLeaveFrameIterate(current, v0, v1, derivedPointers, isVerifying);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = frame->returnAddr;
break;
}
case FrameType::LEAVE_FRAME_WITH_ARGV: {
auto frame = OptimizedLeaveFrame::GetFrameFromSp(current);
OptimizedWithArgvLeaveFrameIterate(current, v0, v1, derivedPointers, isVerifying);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = frame->returnAddr;
break;
}
case FrameType::BUILTIN_FRAME_WITH_ARGV: {
auto frame = BuiltinWithArgvFrame::GetFrameFromSp(current);
BuiltinWithArgvFrameIterate(current, v0, v1, derivedPointers, isVerifying);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = frame->returnAddr;
break;
}
case FrameType::BUILTIN_ENTRY_FRAME:
@ -699,12 +766,14 @@ void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0,
auto frame = BuiltinFrame::GetFrameFromSp(current);
BuiltinFrameIterate(current, v0, v1, derivedPointers, isVerifying);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = frame->returnAddr;
break;
}
case FrameType::INTERPRETER_ENTRY_FRAME: {
auto frame = InterpretedEntryFrame::GetFrameFromSp(current);
InterpretedEntryFrameIterate(current, v0, v1);
current = frame->GetPrevFrameFp();
optimizedReturnAddr_ = 0;
break;
}
default: {

View File

@ -115,7 +115,7 @@ public:
JSTaggedType *GetPrevInterpretedFrame();
// for llvm.
static uintptr_t GetPrevFrameCallSiteSp(const JSTaggedType *sp);
static uintptr_t GetPrevFrameCallSiteSp(const JSTaggedType *sp, uintptr_t curPc);
// for InterpretedFrame.
JSTaggedValue GetVRegValue(size_t index) const;
@ -147,10 +147,10 @@ public:
static JSTaggedType* GetInterpretedEntryFrameStart(const JSTaggedType *sp);
// for Frame GC.
void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const;
void IterateFrameChain(JSTaggedType *start, const RootVisitor &v0, const RootRangeVisitor &v1) const;
void IterateRsp(const RootVisitor &v0, const RootRangeVisitor &v1) const;
void IterateSp(const RootVisitor &v0, const RootRangeVisitor &v1) const;
void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1);
void IterateFrameChain(JSTaggedType *start, const RootVisitor &v0, const RootRangeVisitor &v1);
void IterateRsp(const RootVisitor &v0, const RootRangeVisitor &v1);
void IterateSp(const RootVisitor &v0, const RootRangeVisitor &v1);
private:
FrameType GetFrameType() const
@ -177,20 +177,24 @@ private:
void OptimizedFrameIterate(
const JSTaggedType *sp, const RootVisitor &v0, const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
void OptimizedJSFunctionFrameIterate(
const JSTaggedType *sp, const RootVisitor &v0, const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying);
void OptimizedEntryFrameIterate(
const JSTaggedType *sp, const RootVisitor &v0, const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying);
void OptimizedLeaveFrameIterate(
const JSTaggedType *sp, const RootVisitor &v0, const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying);
void OptimizedWithArgvLeaveFrameIterate(
const JSTaggedType *sp, const RootVisitor &v0, const RootRangeVisitor &v1,
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying);
private:
JSTaggedType *sp_ {nullptr};
JSTaggedType *fp_ {nullptr};
const JSThread *thread_ {nullptr};
uintptr_t optimizedReturnAddr_ {0};
};
class StackAssertScope {

View File

@ -98,8 +98,8 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
JSFunction* prevFunc = JSFunction::Cast(prevState->function.GetTaggedObject()); \
method = prevFunc->GetMethod(); \
hotnessCounter = static_cast<int32_t>(method->GetHotnessCounter()); \
ASSERT(prevState->callSizeOrCallSiteSp == GetJumpSizeAfterCall(pc)); \
DISPATCH_OFFSET(prevState->callSizeOrCallSiteSp); \
ASSERT(prevState->callSize == GetJumpSizeAfterCall(pc)); \
DISPATCH_OFFSET(prevState->callSize); \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
@ -401,7 +401,7 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
} \
SAVE_PC(); \
GET_ASM_FRAME(sp)->callSizeOrCallSiteSp = GetJumpSizeAfterCall(pc); \
GET_ASM_FRAME(sp)->callSize = GetJumpSizeAfterCall(pc); \
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp); \
state->base.prev = sp; \
state->base.type = FrameType::ASM_INTERPRETER_FRAME; \
@ -2073,7 +2073,7 @@ void InterpreterAssembly::HandleNewObjDynRangePrefImm16V8(
if (IsFastNewFrameEnter(ctorFunc, ctorMethod)) {
SAVE_PC();
GET_ASM_FRAME(sp)->callSizeOrCallSiteSp = GetJumpSizeAfterCall(pc);
GET_ASM_FRAME(sp)->callSize = GetJumpSizeAfterCall(pc);
uint32_t numVregs = ctorMethod->GetNumVregsWithCallField();
uint32_t numDeclaredArgs = ctorFunc->IsBase() ?
ctorMethod->GetNumArgsWithCallField() + 1 : // +1 for this
@ -2465,8 +2465,8 @@ void InterpreterAssembly::HandleSuspendGeneratorPrefV8V8(
return;
}
ASSERT(prevState->callSizeOrCallSiteSp == GetJumpSizeAfterCall(pc));
DISPATCH_OFFSET(prevState->callSizeOrCallSiteSp);
ASSERT(prevState->callSize == GetJumpSizeAfterCall(pc));
DISPATCH_OFFSET(prevState->callSize);
}
void InterpreterAssembly::HandleAsyncFunctionAwaitUncaughtPrefV8V8(

View File

@ -609,7 +609,6 @@ private:
bool gcState_ {false};
bool isAsmInterpreter_ {false};
VmThreadControl *vmThreadControl_ {nullptr};
bool stableArrayElementsGuardians_ {true};
GlueData glueData_;

View File

@ -18,6 +18,7 @@
#include "runtime_stubs.h"
#include "ecmascript/builtins/builtins_regexp.h"
#include "ecmascript/compiler/llvm/llvm_stackmap_parser.h"
#include "ecmascript/ecma_string_table.h"
#include "ecmascript/global_dictionary-inl.h"
#include "ecmascript/global_env.h"

View File

@ -59,7 +59,8 @@ group("ark_aot_test") {
"stownbyname:stownbynameAotAction",
"stownbynamewithnameset:stownbynamewithnamesetAotAction",
"stownbyvalue:stownbyvalueAotAction",
"stownbyvaluewithnameset:stownbyvaluewithnamesetAotAction",
#"stownbyvaluewithnameset:stownbyvaluewithnamesetAotAction",
"strictequal:strictequalAotAction",
"strictnotequal:strictnotequalAotAction",
"sub:subAotAction",