!7177 [JIT] support lambda function reusing

Merge pull request !7177 from haizaibali/jit_performance
This commit is contained in:
openharmony_ci 2024-05-08 03:23:07 +00:00 committed by Gitee
commit 75bd9c345c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 168 additions and 79 deletions

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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);

View File

@ -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_;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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_;

View File

@ -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();

View File

@ -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_;