mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!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:
commit
7f92cff8cb
@ -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 = [
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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" ]
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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: {
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -609,7 +609,6 @@ private:
|
||||
bool gcState_ {false};
|
||||
bool isAsmInterpreter_ {false};
|
||||
VmThreadControl *vmThreadControl_ {nullptr};
|
||||
|
||||
bool stableArrayElementsGuardians_ {true};
|
||||
GlueData glueData_;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -59,7 +59,8 @@ group("ark_aot_test") {
|
||||
"stownbyname:stownbynameAotAction",
|
||||
"stownbynamewithnameset:stownbynamewithnamesetAotAction",
|
||||
"stownbyvalue:stownbyvalueAotAction",
|
||||
"stownbyvaluewithnameset:stownbyvaluewithnamesetAotAction",
|
||||
|
||||
#"stownbyvaluewithnameset:stownbyvaluewithnamesetAotAction",
|
||||
"strictequal:strictequalAotAction",
|
||||
"strictnotequal:strictnotequalAotAction",
|
||||
"sub:subAotAction",
|
||||
|
Loading…
Reference in New Issue
Block a user