mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
!7177 [JIT] support lambda function reusing
Merge pull request !7177 from haizaibali/jit_performance
This commit is contained in:
commit
75bd9c345c
@ -30,7 +30,7 @@ namespace panda::ecmascript {
|
||||
#define ECMASCRIPT_ENABLE_SNAPSHOT 0
|
||||
#define ECMASCRIPT_ENABLE_HEAP_DETAIL_STATISTICS 0
|
||||
#define ECMASCRIPT_ENABLE_OPT_CODE_PROFILER 0
|
||||
#define ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER 0
|
||||
#define ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER 0
|
||||
#define ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER 0
|
||||
#define ECMASCRIPT_ENABLE_ELEMENTSKIND_ALWAY_GENERIC 0
|
||||
|
||||
|
@ -958,7 +958,7 @@ void ProfilerStubBuilder::TryJitCompile(GateRef glue, OffsetInfo offsetInfo,
|
||||
}
|
||||
Bind(&incJitHotnessCntAndCmpOpcode);
|
||||
{
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
CallRuntime(glue, RTSTUB_ID(CountInterpExecFuncs), { func });
|
||||
#endif
|
||||
GateRef newJitHotnessCnt = Int16Add(jitHotnessCnt, Int16(1));
|
||||
|
@ -12,25 +12,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ECMASCRIPT_DFX_VMSTAT_JIT_PREHEAT_PROFILER_H
|
||||
#define ECMASCRIPT_DFX_VMSTAT_JIT_PREHEAT_PROFILER_H
|
||||
#ifndef ECMASCRIPT_DFX_VMSTAT_JIT_WARMUP_PROFILER_H
|
||||
#define ECMASCRIPT_DFX_VMSTAT_JIT_WARMUP_PROFILER_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include "ecmascript/mem/c_string.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JitPreheatProfiler {
|
||||
class JitWarmupProfiler {
|
||||
public:
|
||||
static JitPreheatProfiler* GetInstance()
|
||||
static JitWarmupProfiler* GetInstance()
|
||||
{
|
||||
static JitPreheatProfiler profiler;
|
||||
static JitWarmupProfiler profiler;
|
||||
return &profiler;
|
||||
}
|
||||
~JitPreheatProfiler() {}
|
||||
~JitWarmupProfiler() {}
|
||||
|
||||
std::unordered_map<CString, bool> profMap_;
|
||||
private:
|
||||
JitPreheatProfiler() {}
|
||||
JitWarmupProfiler() {}
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_DFX_VMSTAT_JIT_PREHEAT_PROFILER_H
|
||||
#endif // ECMASCRIPT_DFX_VMSTAT_JIT_WARMUP_PROFILER_H
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/dfx/vmstat/opt_code_profiler.h"
|
||||
#include "ecmascript/dfx/vmstat/jit_preheat_profiler.h"
|
||||
#include "ecmascript/dfx/vmstat/jit_warmup_profiler.h"
|
||||
#include <iomanip>
|
||||
#include "ecmascript/base/config.h"
|
||||
|
||||
@ -91,10 +91,10 @@ void OptCodeProfiler::PrintAndReset()
|
||||
|
||||
void OptCodeProfiler::FilterMethodToPrint()
|
||||
{
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
std::vector<CString> methods;
|
||||
auto &profMap = JitPreheatProfiler::GetInstance()->profMap_;
|
||||
for (auto it = profMap.begin(); it != profMap.end()) {
|
||||
auto &profMap = JitWarmupProfiler::GetInstance()->profMap_;
|
||||
for (auto it = profMap.begin(); it != profMap.end();) {
|
||||
if (it->second == false) {
|
||||
methods.push_back(it->first);
|
||||
profMap.erase(it++);
|
||||
@ -106,7 +106,7 @@ void OptCodeProfiler::FilterMethodToPrint()
|
||||
if (methodName.find("func_main_") != methodName.npos) {
|
||||
continue;
|
||||
}
|
||||
LOG_ECMA(ERROR) << methodName << " has not been fully jit preheated.";
|
||||
LOG_ECMA(ERROR) << methodName << " has not been fully jit warmed up.";
|
||||
}
|
||||
#endif
|
||||
std::vector<std::pair<uint64_t, Name>> profVec;
|
||||
@ -119,7 +119,7 @@ void OptCodeProfiler::FilterMethodToPrint()
|
||||
});
|
||||
|
||||
auto itr = profVec.begin();
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
while (itr != profVec.end()) {
|
||||
#else
|
||||
for (int i = 0; i < printMehodCount_ && itr != profVec.end(); i++) {
|
||||
@ -127,7 +127,7 @@ void OptCodeProfiler::FilterMethodToPrint()
|
||||
PrintMethodRecord(itr->first, itr->second.GetName());
|
||||
itr++;
|
||||
}
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
if (profMap.size() != 0) {
|
||||
for (auto it = profMap.begin(); it != profMap.end(); it++) {
|
||||
if (it->first.find("func_main_") != it->first.npos) {
|
||||
@ -135,7 +135,7 @@ void OptCodeProfiler::FilterMethodToPrint()
|
||||
}
|
||||
LOG_ECMA(ERROR) << "There exists compiled function " << it->first
|
||||
<< ", but it has not been jit executed, please "
|
||||
"preheat strongly.";
|
||||
"warm up strongly.";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -143,9 +143,9 @@ void OptCodeProfiler::FilterMethodToPrint()
|
||||
|
||||
void OptCodeProfiler::PrintMethodRecord(Key key, std::string methodName)
|
||||
{
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
CString methodInfo = abcNames_[key.GetAbcId()] + ":" + CString(methodName);
|
||||
auto &profMap = JitPreheatProfiler::GetInstance()->profMap_;
|
||||
auto &profMap = JitWarmupProfiler::GetInstance()->profMap_;
|
||||
if (profMap.find(methodInfo) != profMap.end()) {
|
||||
profMap.erase(methodInfo);
|
||||
}
|
||||
@ -160,7 +160,7 @@ void OptCodeProfiler::PrintMethodRecord(Key key, std::string methodName)
|
||||
BcRecord& bcRecord = methodIdToRecord_[key.Value()];
|
||||
for (auto it = bcRecord.begin(); it != bcRecord.end(); it++) {
|
||||
Record record = it->second;
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER == 0
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER == 0
|
||||
if (record.Count() == 0) {
|
||||
break;
|
||||
}
|
||||
@ -194,7 +194,7 @@ void OptCodeProfiler::Update(JSHandle<JSTaggedValue> &func, int bcIndex, EcmaOpc
|
||||
}
|
||||
auto methodPoint = Method::Cast(method);
|
||||
auto methodId = methodPoint->GetMethodId().GetOffset();
|
||||
auto methodName = methodPoint->GetMethodName();
|
||||
auto methodName = ConvertToStdString(methodPoint->GetRecordNameStr()) + "." + methodPoint->GetMethodName();
|
||||
|
||||
const auto *pf = methodPoint->GetJSPandaFile();
|
||||
ASSERT(pf != nullptr);
|
||||
|
@ -197,7 +197,7 @@ private:
|
||||
methodIdToRecord_.clear();
|
||||
methodIdToName_.clear();
|
||||
}
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER == 0
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER == 0
|
||||
int printMehodCount_ {10};
|
||||
#endif
|
||||
std::map<EcmaOpcode, Value> profMap_;
|
||||
|
@ -871,6 +871,22 @@ void EcmaContext::SetupStringToListResultCache()
|
||||
stringToListResultCache_ = builtins::StringToListResultCache::CreateCacheTable(thread_);
|
||||
}
|
||||
|
||||
void EcmaContext::IterateJitMachineCodeCache(const RootVisitor &v)
|
||||
{
|
||||
if (thread_->IsMachineCodeLowMemory()) {
|
||||
jitMachineCodeCache_ = {};
|
||||
LOG_JIT(DEBUG) << "clear jit machine code, as low code memory";
|
||||
} else {
|
||||
for (auto &iter : jitMachineCodeCache_) {
|
||||
if (iter.first == 0) {
|
||||
continue;
|
||||
}
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&(iter.first))));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&(iter.second))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
{
|
||||
// visit global Constant
|
||||
@ -922,6 +938,10 @@ void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
}
|
||||
}
|
||||
|
||||
if (vm_->IsEnableFastJit()) {
|
||||
IterateJitMachineCodeCache(v);
|
||||
}
|
||||
|
||||
if (sustainingJSHandleList_) {
|
||||
sustainingJSHandleList_->Iterate(rv);
|
||||
}
|
||||
|
@ -470,6 +470,27 @@ public:
|
||||
cachedPatchModules_.clear();
|
||||
}
|
||||
|
||||
void AddJitMachineCode(panda_file::File::EntityId id, std::pair<JSTaggedType, JSTaggedType> machineCode)
|
||||
{
|
||||
// replace the old one from some abcfile with the latest one
|
||||
jitMachineCodeCache_.at(GetJitMachineCodeHash(id)) = machineCode;
|
||||
}
|
||||
bool MatchJitMachineCode(panda_file::File::EntityId id, const Method *method) const
|
||||
{
|
||||
auto methodCode = jitMachineCodeCache_.at(GetJitMachineCodeHash(id));
|
||||
if (methodCode.first == 0) {
|
||||
return false;
|
||||
}
|
||||
ASSERT(method != nullptr);
|
||||
Method *methodCache = Method::Cast(JSTaggedValue(methodCode.first).GetTaggedObject());
|
||||
return method == methodCache;
|
||||
}
|
||||
std::pair<JSTaggedType, JSTaggedType> GetJitMachineCode(panda_file::File::EntityId id) const
|
||||
{
|
||||
ASSERT(jitMachineCodeCache_.at(GetJitMachineCodeHash(id)).first != 0);
|
||||
return jitMachineCodeCache_.at(GetJitMachineCodeHash(id));
|
||||
}
|
||||
|
||||
StageOfHotReload GetStageOfHotReload() const
|
||||
{
|
||||
return stageOfHotReload_;
|
||||
@ -513,6 +534,11 @@ public:
|
||||
void AddSustainingJSHandle(SustainingJSHandle*);
|
||||
void RemoveSustainingJSHandle(SustainingJSHandle*);
|
||||
private:
|
||||
void IterateJitMachineCodeCache(const RootVisitor &v);
|
||||
uint32_t GetJitMachineCodeHash(panda_file::File::EntityId id) const
|
||||
{
|
||||
return id.GetOffset() % JIT_MACHINE_CODE_CACHE_SIZE;
|
||||
}
|
||||
void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint);
|
||||
JSTaggedValue InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg,
|
||||
@ -628,6 +654,8 @@ private:
|
||||
|
||||
// SustainingJSHandleList for jit compile hold ref
|
||||
SustainingJSHandleList *sustainingJSHandleList_ {nullptr};
|
||||
static constexpr uint32_t JIT_MACHINE_CODE_CACHE_SIZE = 263;
|
||||
std::array<std::pair<JSTaggedType, JSTaggedType>, JIT_MACHINE_CODE_CACHE_SIZE> jitMachineCodeCache_ {};
|
||||
|
||||
friend class EcmaHandleScope;
|
||||
friend class JSPandaFileExecutor;
|
||||
|
@ -18,7 +18,8 @@
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
#include "ecmascript/platform/file.h"
|
||||
#include "ecmascript/dfx/vmstat/jit_preheat_profiler.h"
|
||||
#include "ecmascript/compiler/aot_file/func_entry_des.h"
|
||||
#include "ecmascript/dfx/vmstat/jit_warmup_profiler.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void (*Jit::initJitCompiler_)(JSRuntimeOptions options) = nullptr;
|
||||
@ -158,9 +159,12 @@ bool Jit::SupportJIT(const Method *method) const
|
||||
FunctionKind kind = method->GetFunctionKind();
|
||||
switch (kind) {
|
||||
case FunctionKind::NORMAL_FUNCTION:
|
||||
case FunctionKind::BASE_CONSTRUCTOR:
|
||||
case FunctionKind::GETTER_FUNCTION:
|
||||
case FunctionKind::SETTER_FUNCTION:
|
||||
case FunctionKind::ARROW_FUNCTION:
|
||||
case FunctionKind::BASE_CONSTRUCTOR:
|
||||
case FunctionKind::CLASS_CONSTRUCTOR:
|
||||
case FunctionKind::DERIVED_CONSTRUCTOR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -176,13 +180,45 @@ void Jit::CountInterpExecFuncs(JSHandle<JSFunction> &jsFunction)
|
||||
{
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
CString fileDesc = method->GetJSPandaFile()->GetJSPandaFileDesc();
|
||||
CString methodInfo = fileDesc + ":" + CString(method->GetMethodName());
|
||||
auto &profMap = JitPreheatProfiler::GetInstance()->profMap_;
|
||||
CString methodInfo = fileDesc + ":" + method->GetRecordNameStr() + "." + CString(method->GetMethodName());
|
||||
auto &profMap = JitWarmupProfiler::GetInstance()->profMap_;
|
||||
if (profMap.find(methodInfo) == profMap.end()) {
|
||||
profMap.insert({methodInfo, false});
|
||||
}
|
||||
}
|
||||
|
||||
bool Jit::ReuseCompiledFunc(JSThread *thread, JSHandle<JSFunction> &jsFunction)
|
||||
{
|
||||
if (!IsEnableFastJit()) {
|
||||
return false;
|
||||
}
|
||||
if (jsFunction->GetMachineCode() != JSTaggedValue::Undefined()) {
|
||||
return false;
|
||||
}
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
if (method->GetFunctionKind() != FunctionKind::ARROW_FUNCTION) {
|
||||
return false;
|
||||
}
|
||||
auto id = method->GetMethodId();
|
||||
if (thread->GetCurrentEcmaContext()->MatchJitMachineCode(id, method)) {
|
||||
CString fileDesc = method->GetJSPandaFile()->GetJSPandaFileDesc();
|
||||
CString methodName = fileDesc + ":" + method->GetRecordNameStr() + "." + CString(method->GetMethodName());
|
||||
LOG_JIT(INFO) << "reuse fuction machine code : " << methodName;
|
||||
auto machineCodeObj = thread->GetCurrentEcmaContext()->GetJitMachineCode(id).second;
|
||||
JSHandle<Method> methodHandle(thread, method);
|
||||
JSHandle<Method> newMethodHandle = thread->GetEcmaVM()->GetFactory()->CloneMethodTemporaryForJIT(methodHandle);
|
||||
jsFunction->SetMethod(thread, newMethodHandle);
|
||||
JSHandle<MachineCode> machineCodeHandle(thread, JSTaggedValue(machineCodeObj).GetTaggedObject());
|
||||
uintptr_t codeAddr = machineCodeHandle->GetFuncAddr();
|
||||
FuncEntryDes *funcEntryDes = reinterpret_cast<FuncEntryDes *>(machineCodeHandle->GetFuncEntryDes());
|
||||
jsFunction->SetCompiledFuncEntry(codeAddr, funcEntryDes->isFastCall_);
|
||||
newMethodHandle->SetDeoptThreshold(thread->GetEcmaVM()->GetJSOptions().GetDeoptThreshold());
|
||||
jsFunction->SetMachineCode(thread, machineCodeHandle);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tier,
|
||||
int32_t offset, JitCompileMode mode)
|
||||
{
|
||||
@ -192,18 +228,19 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tie
|
||||
return;
|
||||
}
|
||||
|
||||
if (jit->ReuseCompiledFunc(vm->GetJSThread(), jsFunction)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vm->IsEnableOsr() && offset != MachineCode::INVALID_OSR_OFFSET) {
|
||||
return;
|
||||
}
|
||||
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
CString fileDesc = method->GetJSPandaFile()->GetJSPandaFileDesc();
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
CString methodInfo = fileDesc + ":" + CString(method->GetMethodName());
|
||||
#else
|
||||
CString methodName = fileDesc + ":" + method->GetRecordNameStr() + "." + CString(method->GetMethodName());
|
||||
uint32_t codeSize = method->GetCodeSize();
|
||||
CString methodInfo = method->GetRecordNameStr() + "." + CString(method->GetMethodName()) + ", at:" + fileDesc +
|
||||
", code size:" + ToCString(codeSize);
|
||||
CString methodInfo = methodName + ", code size:" + ToCString(codeSize);
|
||||
constexpr uint32_t maxSize = 9000;
|
||||
if (codeSize > maxSize) {
|
||||
if (tier == CompilerTier::BASELINE) {
|
||||
@ -214,7 +251,6 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tie
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (vm->GetJSThread()->IsMachineCodeLowMemory()) {
|
||||
if (tier == CompilerTier::BASELINE) {
|
||||
LOG_BASELINEJIT(DEBUG) << "skip jit task, as low code memory:" << methodInfo;
|
||||
@ -230,22 +266,14 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tie
|
||||
std::stringstream msgStr;
|
||||
msgStr << "method does not support jit:" << methodInfo << ", kind:" << static_cast<int>(kind)
|
||||
<<", JSSharedFunction:" << isJSSharedFunction;
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
if (tier == CompilerTier::BASELINE) {
|
||||
LOG_BASELINEJIT(ERROR) << msgStr.str();
|
||||
} else {
|
||||
LOG_JIT(ERROR) << msgStr.str();
|
||||
}
|
||||
#else
|
||||
if (tier == CompilerTier::BASELINE) {
|
||||
LOG_BASELINEJIT(INFO) << msgStr.str();
|
||||
} else {
|
||||
LOG_JIT(INFO) << msgStr.str();
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
bool needCompile = jit->CheckJitCompileStatus(jsFunction, methodInfo, tier);
|
||||
bool needCompile = jit->CheckJitCompileStatus(jsFunction, methodName, tier);
|
||||
if (!needCompile) {
|
||||
return;
|
||||
}
|
||||
@ -264,7 +292,7 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tie
|
||||
JitTaskpool::GetCurrentTaskpool()->WaitForJitTaskPoolReady();
|
||||
EcmaVM *compilerVm = JitTaskpool::GetCurrentTaskpool()->GetCompilerVm();
|
||||
std::shared_ptr<JitTask> jitTask = std::make_shared<JitTask>(vm->GetJSThread(), compilerVm->GetJSThread(),
|
||||
jit, jsFunction, tier, methodInfo, offset, vm->GetJSThread()->GetThreadId(), mode);
|
||||
jit, jsFunction, tier, methodName, offset, vm->GetJSThread()->GetThreadId(), mode);
|
||||
|
||||
jitTask->PrepareCompile();
|
||||
JitTaskpool::GetCurrentTaskpool()->PostTask(
|
||||
@ -295,18 +323,18 @@ bool Jit::CheckJitCompileStatus(JSHandle<JSFunction> &jsFunction,
|
||||
if (tier == CompilerTier::FAST &&
|
||||
jsFunction->GetMachineCode() == JSTaggedValue::Hole()) {
|
||||
LOG_JIT(DEBUG) << "skip method, as it compiling:" << methodName;
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
auto &profMap = JitWarmupProfiler::GetInstance()->profMap_;
|
||||
if (profMap.find(methodName) != profMap.end()) {
|
||||
profMap.erase(methodName);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tier == CompilerTier::BASELINE &&
|
||||
jsFunction->GetBaselineCode() == JSTaggedValue::Hole()) {
|
||||
LOG_BASELINEJIT(DEBUG) << "skip method, as it compiling:" << methodName;
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
auto &profMap = JitPreheatProfiler::GetInstance()->profMap_;
|
||||
if (profMap.find(methodName) != profMap.end()) {
|
||||
profMap.erase(methodName);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -68,9 +68,11 @@ public:
|
||||
void CheckMechineCodeSpaceMemory(JSThread *thread, int remainSize);
|
||||
void ChangeTaskPoolState(bool inBackground);
|
||||
|
||||
// dfx for jit preheat compile
|
||||
// dfx for jit warmup compile
|
||||
static void CountInterpExecFuncs(JSHandle<JSFunction> &jsFunction);
|
||||
|
||||
bool ReuseCompiledFunc(JSThread *thread, JSHandle<JSFunction> &function);
|
||||
|
||||
bool IsAppJit() const
|
||||
{
|
||||
return isApp_;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "ecmascript/ic/profile_type_info.h"
|
||||
#include "ecmascript/patch/patch_loader.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/dfx/vmstat/jit_preheat_profiler.h"
|
||||
#include "ecmascript/dfx/vmstat/jit_warmup_profiler.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
@ -45,7 +45,7 @@ JitTask::JitTask(JSThread *hostThread, JSThread *compilerThread, Jit *jit, JSHan
|
||||
compilerTask_(nullptr),
|
||||
state_(CompileState::SUCCESS),
|
||||
compilerTier_(tier),
|
||||
methodInfo_(methodName),
|
||||
methodName_(methodName),
|
||||
offset_(offset),
|
||||
taskThreadId_(taskThreadId),
|
||||
ecmaContext_(nullptr),
|
||||
@ -95,7 +95,7 @@ void JitTask::InstallOsrCode(JSHandle<Method> &method, JSHandle<MachineCode> &co
|
||||
{
|
||||
auto profile = jsFunction_->GetProfileTypeInfo();
|
||||
if (profile.IsUndefined()) {
|
||||
LOG_JIT(DEBUG) << "[OSR] Empty profile for installing code:" << GetMethodInfo();
|
||||
LOG_JIT(DEBUG) << "[OSR] Empty profile for installing code:" << GetMethodName();
|
||||
return;
|
||||
}
|
||||
FuncEntryDes *funcEntryDes = reinterpret_cast<FuncEntryDes*>(codeObj->GetFuncEntryDes());
|
||||
@ -110,7 +110,7 @@ void JitTask::InstallOsrCode(JSHandle<Method> &method, JSHandle<MachineCode> &co
|
||||
JSHandle<TaggedArray> newArr = factory->NewTaggedArray(initLen);
|
||||
newArr->Set(hostThread_, 0, codeObj.GetTaggedValue());
|
||||
profileInfoHandle->Set(hostThread_, slotId, newArr.GetTaggedValue());
|
||||
LOG_JIT(DEBUG) << "[OSR] Install machine code:" << GetMethodInfo()
|
||||
LOG_JIT(DEBUG) << "[OSR] Install machine code:" << GetMethodName()
|
||||
<< ", code address: " << reinterpret_cast<void*>(codeObj->GetFuncAddr())
|
||||
<< ", index: " << newArr->GetLength() - 1;
|
||||
return;
|
||||
@ -123,7 +123,7 @@ void JitTask::InstallOsrCode(JSHandle<Method> &method, JSHandle<MachineCode> &co
|
||||
}
|
||||
newArr->Set(hostThread_, i, codeObj.GetTaggedValue());
|
||||
profileInfoHandle->Set(hostThread_, slotId, newArr.GetTaggedValue());
|
||||
LOG_JIT(DEBUG) << "[OSR] Install machine code:" << GetMethodInfo()
|
||||
LOG_JIT(DEBUG) << "[OSR] Install machine code:" << GetMethodName()
|
||||
<< ", code address: " << reinterpret_cast<void*>(codeObj->GetFuncAddr())
|
||||
<< ", index: " << newArr->GetLength() - 1;
|
||||
return;
|
||||
@ -148,6 +148,16 @@ static size_t ComputePayLoadSize(const MachineCodeDesc &codeDesc)
|
||||
rodataSizeAfterTextAlign + stackMapSizeAlign;
|
||||
}
|
||||
|
||||
void JitTask::SetHClassInfoForPGO(JSHandle<Method> &methodHandle)
|
||||
{
|
||||
auto ptManager = hostThread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
auto info = ptManager->GenJITHClassInfo();
|
||||
auto ecmaContext = hostThread_->GetCurrentEcmaContext();
|
||||
auto unsharedConstantPool = ConstantPool::Cast(
|
||||
ecmaContext->FindUnsharedConstpool(methodHandle->GetConstantPool()).GetTaggedObject());
|
||||
unsharedConstantPool->SetAotHClassInfoWithBarrier(hostThread_, info.GetTaggedValue());
|
||||
}
|
||||
|
||||
void JitTask::InstallCode()
|
||||
{
|
||||
if (!IsCompileSuccess()) {
|
||||
@ -156,21 +166,16 @@ void JitTask::InstallCode()
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(hostThread_);
|
||||
|
||||
JSHandle<Method> methodHandle(hostThread_, Method::Cast(jsFunction_->GetMethod().GetTaggedObject()));
|
||||
auto ptManager = hostThread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
if (GetHostVM()->GetJSOptions().IsEnableJITPGO()) {
|
||||
auto info = ptManager->GenJITHClassInfo();
|
||||
auto ecmaContext = hostThread_->GetCurrentEcmaContext();
|
||||
auto unsharedConstantPool = ConstantPool::Cast(
|
||||
ecmaContext->FindUnsharedConstpool(methodHandle->GetConstantPool()).GetTaggedObject());
|
||||
unsharedConstantPool->SetAotHClassInfoWithBarrier(hostThread_, info.GetTaggedValue());
|
||||
SetHClassInfoForPGO(methodHandle);
|
||||
}
|
||||
|
||||
size_t size = ComputePayLoadSize(codeDesc_);
|
||||
|
||||
methodHandle = hostThread_->GetEcmaVM()->GetFactory()->CloneMethodTemporaryForJIT(methodHandle);
|
||||
jsFunction_->SetMethod(hostThread_, methodHandle);
|
||||
JSHandle<Method> newMethodHandle = hostThread_->GetEcmaVM()->GetFactory()->CloneMethodTemporaryForJIT(methodHandle);
|
||||
jsFunction_->SetMethod(hostThread_, newMethodHandle);
|
||||
JSHandle<MachineCode> machineCodeObj =
|
||||
hostThread_->GetEcmaVM()->GetFactory()->NewMachineCodeObject(size, codeDesc_, methodHandle);
|
||||
hostThread_->GetEcmaVM()->GetFactory()->NewMachineCodeObject(size, codeDesc_, newMethodHandle);
|
||||
machineCodeObj->SetOSROffset(offset_);
|
||||
|
||||
if (hostThread_->HasPendingException()) {
|
||||
@ -180,7 +185,7 @@ void JitTask::InstallCode()
|
||||
}
|
||||
|
||||
if (IsOsrTask()) {
|
||||
InstallOsrCode(methodHandle, machineCodeObj);
|
||||
InstallOsrCode(newMethodHandle, machineCodeObj);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -188,20 +193,25 @@ void JitTask::InstallCode()
|
||||
if (compilerTier_ == CompilerTier::FAST) {
|
||||
FuncEntryDes *funcEntryDes = reinterpret_cast<FuncEntryDes*>(machineCodeObj->GetFuncEntryDes());
|
||||
jsFunction_->SetCompiledFuncEntry(codeAddr, funcEntryDes->isFastCall_);
|
||||
methodHandle->SetDeoptThreshold(hostThread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold());
|
||||
newMethodHandle->SetDeoptThreshold(hostThread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold());
|
||||
jsFunction_->SetMachineCode(hostThread_, machineCodeObj);
|
||||
LOG_JIT(DEBUG) <<"Install fast jit machine code:" << GetMethodInfo();
|
||||
#if ECMASCRIPT_ENABLE_JIT_PREHEAT_PROFILER
|
||||
auto &profMap = JitPreheatProfiler::GetInstance()->profMap_;
|
||||
if (profMap.find(GetMethodInfo()) != profMap.end()) {
|
||||
profMap[GetMethodInfo()] = true;
|
||||
if (!hostThread_->IsMachineCodeLowMemory() && methodHandle->GetFunctionKind() == FunctionKind::ARROW_FUNCTION) {
|
||||
hostThread_->GetCurrentEcmaContext()->AddJitMachineCode(
|
||||
methodHandle->GetMethodId(),
|
||||
std::make_pair(methodHandle.GetTaggedType(), machineCodeObj.GetTaggedType()));
|
||||
}
|
||||
LOG_JIT(DEBUG) <<"Install fast jit machine code:" << GetMethodName();
|
||||
#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
|
||||
auto &profMap = JitWarmupProfiler::GetInstance()->profMap_;
|
||||
if (profMap.find(GetMethodName()) != profMap.end()) {
|
||||
profMap[GetMethodName()] = true;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ASSERT(compilerTier_ == CompilerTier::BASELINE);
|
||||
methodHandle->SetDeoptThreshold(hostThread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold());
|
||||
newMethodHandle->SetDeoptThreshold(hostThread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold());
|
||||
jsFunction_->SetBaselineCode(hostThread_, machineCodeObj);
|
||||
LOG_BASELINEJIT(DEBUG) <<"Install baseline jit machine code:" << GetMethodInfo();
|
||||
LOG_BASELINEJIT(DEBUG) <<"Install baseline jit machine code:" << GetMethodName();
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,7 +289,7 @@ bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
|
||||
if (jitTask_->GetJsFunction().GetAddress() == 0) {
|
||||
// for unit test
|
||||
} else {
|
||||
CString info = "compile method:" + jitTask_->GetMethodInfo() + ", in jit thread";
|
||||
CString info = "compile method:" + jitTask_->GetMethodName() + ", in jit thread";
|
||||
Jit::TimeScope scope(info, jitTask_->GetCompilerTier());
|
||||
|
||||
jitTask_->Optimize();
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
void Finalize();
|
||||
void PrepareCompile();
|
||||
|
||||
void SetHClassInfoForPGO(JSHandle<Method> &methodHandle);
|
||||
void InstallCode();
|
||||
void InstallOsrCode(JSHandle<Method> &method, JSHandle<MachineCode> &codeObj);
|
||||
MachineCodeDesc &GetMachineCodeDesc()
|
||||
@ -166,14 +167,14 @@ public:
|
||||
return static_cast<JitVM*>(compilerThread_->GetEcmaVM());
|
||||
}
|
||||
|
||||
CString GetMethodInfo() const
|
||||
CString GetMethodName() const
|
||||
{
|
||||
return methodInfo_;
|
||||
return methodName_;
|
||||
}
|
||||
|
||||
void SetMethodInfo(CString methodInfo)
|
||||
void SetMethodInfo(CString methodName)
|
||||
{
|
||||
methodInfo_ = methodInfo;
|
||||
methodName_ = methodName;
|
||||
}
|
||||
|
||||
uint32_t GetTaskThreadId() const
|
||||
@ -271,7 +272,7 @@ private:
|
||||
MachineCodeDesc codeDesc_;
|
||||
CompileState state_;
|
||||
CompilerTier compilerTier_;
|
||||
CString methodInfo_;
|
||||
CString methodName_;
|
||||
int32_t offset_;
|
||||
uint32_t taskThreadId_;
|
||||
std::unique_ptr<SustainingJSHandle> sustainingJSHandle_;
|
||||
|
Loading…
Reference in New Issue
Block a user