[JIT] refact jit code

1. support singleton jitcompiler, and submit compile task to jit compilertask
2. clear compiled code when deopt overflow
3. fix code align bug
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8Z9XW
Signed-off-by: xiaoweidong <xiaoweidong@huawei.com>

Change-Id: I07b43207d1be907267183f0c7b6c388dc6cdb6da
This commit is contained in:
xiaoweidong 2024-02-05 22:23:29 +08:00
parent 255e36255b
commit 5e561c4c20
16 changed files with 292 additions and 223 deletions

View File

@ -173,10 +173,7 @@ void BytecodeInfoCollector::ProcessMethod(JSHandle<JSFunction> &jsFunction)
const panda_file::File *pf = jsPandaFile_->GetPandaFile();
panda_file::File::EntityId methodIdx = method->GetMethodId();
panda_file::MethodDataAccessor mda(*pf, methodIdx);
panda_file::File::EntityId classIdx = panda_file::MethodDataAccessor::GetClassId(*pf, methodIdx);
panda_file::ClassDataAccessor cda(*pf, classIdx);
CString desc = utf::Mutf8AsCString(cda.GetDescriptor());
const CString recordName = JSPandaFile::ParseEntryPoint(desc);
const CString recordName = jsPandaFile_->GetRecordNameWithBundlePack(methodIdx);
recordNames.emplace_back(recordName);
auto methodId = mda.GetMethodId();
CollectFunctionTypeId(methodId);

View File

@ -25,9 +25,23 @@
#include "ecmascript/platform/file.h"
namespace panda::ecmascript::kungfu {
JitCompilationOptions::JitCompilationOptions(JSRuntimeOptions &runtimeOptions, EcmaVM *vm)
JitCompiler *JitCompiler::GetInstance(EcmaVM *vm)
{
triple_ = runtimeOptions.GetTargetTriple();
static JitCompiler instance(vm);
return &instance;
}
JitCompilationOptions::JitCompilationOptions(EcmaVM *vm)
{
JSRuntimeOptions &runtimeOptions = vm->GetJSOptions();
#if defined(PANDA_TARGET_AMD64)
triple_ = TARGET_X64;
#elif defined(PANDA_TARGET_ARM64)
triple_ = TARGET_AARCH64;
#else
LOG_JIT(FATAL) << "jit unsupport arch";
UNREACHABLE();
#endif
optLevel_ = runtimeOptions.GetOptLevel();
relocMode_ = runtimeOptions.GetRelocMode();
logOption_ = runtimeOptions.GetCompilerLogOption();
@ -56,9 +70,14 @@ JitCompilationOptions::JitCompilationOptions(JSRuntimeOptions &runtimeOptions, E
isEnableLoweringBuiltin_ = runtimeOptions.IsEnableLoweringBuiltin();
}
void JitCompiler::Init()
void JitCompiler::Init(EcmaVM *vm)
{
log_.SetEnableCompilerLogTime(jitOptions_.compilerLogTime_);
BytecodeStubCSigns::Initialize();
CommonStubCSigns::Initialize();
RuntimeStubCSigns::Initialize();
JitCompilationOptions jitOptions(vm);
jitOptions_ = jitOptions;
PassOptions::Builder optionsBuilder;
passOptions_ =
optionsBuilder.EnableArrayBoundsCheckElimination(jitOptions_.isEnableArrayBoundsCheckElimination_)
@ -79,84 +98,96 @@ void JitCompiler::Init()
.EnableInlineNative(jitOptions_.isEnableNativeInline_)
.EnableLoweringBuiltin(jitOptions_.isEnableLoweringBuiltin_)
.Build();
passManager_ = new JitPassManager(vm_,
jitOptions_.triple_,
jitOptions_.optLevel_,
jitOptions_.relocMode_,
&log_,
&logList_,
profilerDecoder_,
&passOptions_);
aotFileGenerator_ = new AOTFileGenerator(&log_, &logList_, vm_, jitOptions_.triple_,
vm_->GetJSOptions().IsCompilerEnableLiteCG());
}
JitCompiler *JitCompiler::Create(EcmaVM *vm, JitTask *jitTask)
JitCompilerTask *JitCompilerTask::CreateJitCompilerTask(JitTask *jitTask)
{
BytecodeStubCSigns::Initialize();
CommonStubCSigns::Initialize();
RuntimeStubCSigns::Initialize();
TSManager *tsm = new TSManager(vm);
vm->GetJSThread()->GetCurrentEcmaContext()->SetTSManager(tsm);
vm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->Initialize();
auto jitCompiler = new JitCompiler(vm, jitTask->GetJsFunction());
return jitCompiler;
return new (std::nothrow) JitCompilerTask(jitTask);
}
JitCompiler::~JitCompiler()
bool JitCompilerTask::Compile()
{
if (passManager_ != nullptr) {
delete passManager_;
passManager_ = nullptr;
TSManager *tsm = new (std::nothrow) TSManager(vm_);
if (tsm == nullptr) {
return false;
}
if (aotFileGenerator_ != nullptr) {
delete aotFileGenerator_;
aotFileGenerator_ = nullptr;
vm_->GetJSThread()->GetCurrentEcmaContext()->SetTSManager(tsm);
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->Initialize();
JitCompiler *jitCompiler = JitCompiler::GetInstance();
auto jitPassManager = new (std::nothrow) JitPassManager(vm_,
jitCompiler->GetJitOptions().triple_,
jitCompiler->GetJitOptions().optLevel_,
jitCompiler->GetJitOptions().relocMode_,
&jitCompiler->GetCompilerLog(),
&jitCompiler->GetLogList(),
jitCompiler->GetProfilerDecoder(),
&jitCompiler->GetPassOptions());
if (jitPassManager == nullptr) {
return false;
}
passManager_.reset(jitPassManager);
auto aotFileGenerator = new (std::nothrow) AOTFileGenerator(&jitCompiler->GetCompilerLog(),
&jitCompiler->GetLogList(),
vm_, jitCompiler->GetJitOptions().triple_, vm_->GetJSOptions().IsCompilerEnableLiteCG());
if (aotFileGenerator == nullptr) {
return false;
}
jitCodeGenerator_.reset(aotFileGenerator);
return passManager_->Compile(jsFunction_, *jitCodeGenerator_);
}
bool JitCompiler::Compile()
bool JitCompilerTask::Finalize(JitTask *jitTask)
{
return passManager_->Compile(jsFunction_, *aotFileGenerator_);
}
bool JitCompiler::Finalize(JitTask *jitTask)
{
aotFileGenerator_->JitCreateLitecgModule();
if (jitTask == nullptr) {
return false;
}
jitCodeGenerator_->JitCreateLitecgModule();
passManager_->RunCg();
aotFileGenerator_->GetMemoryCodeInfos(jitTask->GetMachineCodeDesc());
jitCodeGenerator_->GetMemoryCodeInfos(jitTask->GetMachineCodeDesc());
return true;
}
void *CreateJitCompiler(EcmaVM *vm, JitTask *jitTask)
void InitJitCompiler(EcmaVM *vm)
{
auto jitCompiler = JitCompiler::Create(vm, jitTask);
return jitCompiler;
if (vm == nullptr) {
return;
}
JitCompiler *jitCompiler = JitCompiler::GetInstance(vm);
jitCompiler->Init(vm);
}
bool JitCompile(void *compiler, JitTask *jitTask [[maybe_unused]])
void *CreateJitCompilerTask(JitTask *jitTask)
{
ASSERT(jitTask != nullptr);
ASSERT(compiler != nullptr);
auto jitCompiler = reinterpret_cast<JitCompiler *>(compiler);
bool ret = jitCompiler->Compile();
return ret;
if (jitTask == nullptr) {
return nullptr;
}
return JitCompilerTask::CreateJitCompilerTask(jitTask);
}
bool JitFinalize(void *compiler, JitTask *jitTask)
bool JitCompile(void *compilerTask, JitTask *jitTask)
{
ASSERT(jitTask != nullptr);
ASSERT(compiler != nullptr);
auto jitCompiler = reinterpret_cast<JitCompiler *>(compiler);
bool ret = jitCompiler->Finalize(jitTask);
return ret;
if (jitTask == nullptr || compilerTask == nullptr) {
return false;
}
auto jitCompilerTask = reinterpret_cast<JitCompilerTask*>(compilerTask);
return jitCompilerTask->Compile();
}
bool JitFinalize(void *compilerTask, JitTask *jitTask)
{
if (jitTask == nullptr || compilerTask == nullptr) {
return false;
}
auto jitCompilerTask = reinterpret_cast<JitCompilerTask*>(compilerTask);
return jitCompilerTask->Finalize(jitTask);
}
void DeleteJitCompile(void *handle)
{
ASSERT(handle != nullptr);
delete reinterpret_cast<JitCompiler *>(handle);
if (handle == nullptr) {
return;
}
delete reinterpret_cast<JitCompilerTask*>(handle);
}
} // namespace panda::ecmascript::kungfu

View File

@ -22,14 +22,15 @@
namespace panda::ecmascript::kungfu {
extern "C" {
PUBLIC_API void *CreateJitCompiler(EcmaVM *vm, JitTask *jitTask);
PUBLIC_API void InitJitCompiler(EcmaVM *vm);
PUBLIC_API void *CreateJitCompilerTask(JitTask *jitTask);
PUBLIC_API bool JitCompile(void *compiler, JitTask *jitTask);
PUBLIC_API bool JitFinalize(void *compiler, JitTask *jitTask);
PUBLIC_API void DeleteJitCompile(void *handle);
};
struct JitCompilationOptions {
JitCompilationOptions(JSRuntimeOptions &runtimeOptions, EcmaVM *vm);
JitCompilationOptions(EcmaVM *vm);
JitCompilationOptions() = default;
std::string triple_;
@ -63,21 +64,12 @@ struct JitCompilationOptions {
bool isEnableLoweringBuiltin_;
};
class JitCompiler {
class JitCompilerTask final {
public:
static JitCompiler *Create(EcmaVM *vm, JitTask *jitTask);
explicit JitCompiler(EcmaVM *vm, JSHandle<JSFunction> jsFunction)
: vm_(vm),
jsFunction_(jsFunction),
jitOptions_(vm->GetJSOptions(), vm),
log_(jitOptions_.logOption_),
logList_(jitOptions_.logMethodsList_),
profilerDecoder_(jitOptions_.profilerIn_, jitOptions_.hotnessThreshold_)
{
Init();
}
~JitCompiler();
void Init();
JitCompilerTask(JitTask *jitTask) : vm_(jitTask->GetVM()), jsFunction_(jitTask->GetJsFunction()),
passManager_(nullptr), jitCodeGenerator_(nullptr) { };
static JitCompilerTask *CreateJitCompilerTask(JitTask *jitTask);
bool Compile();
bool Finalize(JitTask *jitTask);
@ -85,13 +77,51 @@ public:
private:
EcmaVM *vm_;
JSHandle<JSFunction> jsFunction_;
std::unique_ptr<JitPassManager> passManager_;
// need refact AOTFileGenerator to JitCodeGenerator
std::unique_ptr<AOTFileGenerator> jitCodeGenerator_;
};
class JitCompiler final {
public:
explicit JitCompiler(EcmaVM *vm) : jitOptions_(vm),
log_(jitOptions_.logOption_),
logList_(jitOptions_.logMethodsList_),
profilerDecoder_(jitOptions_.profilerIn_, jitOptions_.hotnessThreshold_) { }
~JitCompiler() = default;
void Init(EcmaVM *vm);
static JitCompiler *GetInstance(EcmaVM *vm = nullptr);
JitCompilationOptions &GetJitOptions()
{
return jitOptions_;
}
CompilerLog &GetCompilerLog()
{
return log_;
}
AotMethodLogList &GetLogList()
{
return logList_;
}
PGOProfilerDecoder &GetProfilerDecoder()
{
return profilerDecoder_;
}
PassOptions &GetPassOptions()
{
return passOptions_;
}
private:
JitCompilationOptions jitOptions_;
CompilerLog log_;
AotMethodLogList logList_;
PGOProfilerDecoder profilerDecoder_;
PassOptions passOptions_;
JitPassManager *passManager_;
AOTFileGenerator *aotFileGenerator_;
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_JIT_COMPILER_H

View File

@ -535,6 +535,9 @@ void Deoptimizier::UpdateAndDumpDeoptInfo(kungfu::DeoptType type)
method->SetDeoptThreshold(--deoptThreshold);
} else {
method->ClearAOTFlags();
if (method->GetMachineCode() != JSTaggedValue::Undefined()) {
method->SetMachineCode(thread_, JSTaggedValue::Undefined());
}
}
}
}

View File

@ -173,7 +173,6 @@ EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
icEnabled_ = options_.EnableIC();
optionalLogEnabled_ = options_.EnableOptionalLog();
options_.ParseAsmInterOption();
SetEnableJit(options_.IsEnableJIT() && options_.GetEnableAsmInterpreter());
}
void EcmaVM::InitializePGOProfiler()
@ -211,6 +210,25 @@ bool EcmaVM::IsEnableElementsKind() const
return options_.GetEnableAsmInterpreter() && options_.IsEnableElementsKind();
}
bool EcmaVM::IsEnableJit() const
{
if (options_.IsWorker()) {
return GetJit()->IsEnable();
}
return options_.GetEnableAsmInterpreter() && options_.IsEnableJIT();
}
void EcmaVM::EnableJit() const
{
Jit::GetInstance()->SetEnable(this);
GetJSThread()->SwitchJitProfileStubs();
}
Jit *EcmaVM::GetJit() const
{
return Jit::GetInstance();
}
bool EcmaVM::Initialize()
{
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "EcmaVM::Initialize");
@ -245,10 +263,8 @@ bool EcmaVM::Initialize()
callTimer_ = new FunctionCallTimer();
strategy_ = new ThroughputJSObjectResizingStrategy();
if (IsEnableJit()) {
jit_ = new Jit(this);
jit_->Initialize();
EnableJit();
}
initialized_ = true;
return true;
@ -296,13 +312,6 @@ EcmaVM::~EcmaVM()
}
}
if (IsEnableJit()) {
if (jit_ != nullptr) {
delete jit_;
jit_ = nullptr;
}
}
if (gcStats_ != nullptr) {
if (options_.EnableGCStatsPrint()) {
gcStats_->PrintStatisticResult();

View File

@ -561,25 +561,14 @@ public:
return strategy_;
}
Jit *GetJit()
{
return jit_;
}
bool IsEnableJit() const
{
return isEnableJit_;
}
CMap<uint32_t, EcmaVM *> GetWorkList() const
{
return workerList_;
}
void SetEnableJit(bool state)
{
isEnableJit_ = state;
}
Jit *GetJit() const;
bool IsEnableJit() const;
void EnableJit() const;
bool isOverLimit() const
{
@ -694,8 +683,6 @@ private:
friend class EcmaContext;
CMap<uint32_t, EcmaVM *> workerList_ {};
Mutex mutex_;
Jit *jit_ {nullptr};
bool isEnableJit_ {false};
bool overLimit_ {false};
};
} // namespace ecmascript

View File

@ -21,12 +21,36 @@
namespace panda::ecmascript {
std::deque<JitTask*> Jit::asyncCompileJitTasks_;
Mutex Jit::asyncCompileJitTasksMtx_;
void (*Jit::initJitCompiler_)(EcmaVM *vm) = nullptr;
bool(*Jit::jitCompile_)(void*, JitTask*) = nullptr;
bool(*Jit::jitFinalize_)(void*, JitTask*) = nullptr;
void*(*Jit::createJitCompilerTask_)(JitTask*) = nullptr;
void(*Jit::deleteJitCompile_)(void*) = nullptr;
void *Jit::libHandle_ = nullptr;
Jit *Jit::GetInstance()
{
static Jit instance_;
return &instance_;
}
void Jit::SetEnable(const EcmaVM *vm)
{
if (initialized_ && !jitEnable_) {
jitEnable_ = true;
initJitCompiler_(const_cast<EcmaVM*>(vm));
}
}
bool Jit::IsEnable()
{
return jitEnable_;
}
void Jit::Initialize()
{
if (!vm_->IsEnableJit()) {
return;
}
static const std::string CREATEJITCOMPILE = "CreateJitCompiler";
static const std::string CREATEJITCOMPILETASK = "CreateJitCompilerTask";
static const std::string JITCOMPILEINIT = "InitJitCompiler";
static const std::string JITCOMPILE = "JitCompile";
static const std::string JITFINALIZE = "JitFinalize";
static const std::string DELETEJITCOMPILE = "DeleteJitCompile";
@ -38,6 +62,11 @@ void Jit::Initialize()
return;
}
initJitCompiler_ = reinterpret_cast<void(*)(EcmaVM*)>(FindSymbol(libHandle_, JITCOMPILEINIT.c_str()));
if (initJitCompiler_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol initJitCompiler";
return;
}
jitCompile_ = reinterpret_cast<bool(*)(void*, JitTask*)>(FindSymbol(libHandle_, JITCOMPILE.c_str()));
if (jitCompile_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol jitCompile";
@ -50,20 +79,19 @@ void Jit::Initialize()
return;
}
createJitCompiler_ = reinterpret_cast<void*(*)(EcmaVM*, JitTask*)>(FindSymbol(libHandle_,
CREATEJITCOMPILE.c_str()));
if (createJitCompiler_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol createJitCompiler";
createJitCompilerTask_ = reinterpret_cast<void*(*)(JitTask*)>(FindSymbol(libHandle_,
CREATEJITCOMPILETASK.c_str()));
if (createJitCompilerTask_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol createJitCompilertask";
return;
}
deleteJitCompile_ = reinterpret_cast<void(*)(void*)>(FindSymbol(libHandle_, DELETEJITCOMPILE.c_str()));
if (createJitCompiler_ == nullptr) {
if (deleteJitCompile_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol deleteJitCompile";
return;
}
initialized_= true;
vm_->GetJSThread()->SwitchJitProfileStubsIfNeeded();
return;
}
@ -95,11 +123,8 @@ void Jit::DeleteJitCompile(void *compiler)
void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, JitCompileMode mode)
{
if (!vm->IsEnableJit()) {
return;
}
auto jit = vm->GetJit();
if (!jit->IsInitialized()) {
auto jit = Jit::GetInstance();
if (!jit->IsEnable()) {
return;
}
@ -111,32 +136,25 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, JitCompileMode m
LOG_JIT(INFO) << "method does not support jit:" << methodName << ", kind:" << static_cast<int>(kind);
return;
}
if (method->GetMachineCode() == JSTaggedValue::Hole()) {
LOG_JIT(DEBUG) << "skip method, as it compiling:" << methodName;
return;
}
if (method->GetMachineCode() != JSTaggedValue::Undefined()) {
LOG_JIT(DEBUG) << "skip method, as it has been jit compiled:" << methodName;
return;
}
if (jit->IsCompiling(jsFunction)) {
LOG_JIT(DEBUG) << "skip method, as it compiling:" << methodName;
return;
}
LOG_JIT(DEBUG) << "start compile:" << methodName << ", kind:" << static_cast<int>(kind) <<
", mode:" << ((mode == SYNC) ? "sync" : "async");
// using hole value to indecate compiling. todo: reset when failed
method->SetMachineCode(vm->GetJSThread(), JSTaggedValue::Hole());
{
CString msg = "compile method:" + methodName + ", in work thread";
Scope scope(msg);
ASSERT(jit->createJitCompiler_ != nullptr);
ASSERT(jit->deleteJitCompile_ != nullptr);
JitTask *jitTask = new JitTask(vm, jit, jsFunction, methodName, vm->GetJSThread()->GetThreadId());
JitTask *jitTask = new JitTask(vm, jit, jsFunction);
jitTask->SetMethodInfo(methodName);
jit->AddCompilingTask(jitTask);
void *compiler = jit->createJitCompiler_(vm, jitTask);
jitTask->SetCompiler(compiler);
jitTask->PrepareCompile();
jitTask->Optimize();
@ -144,7 +162,6 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, JitCompileMode m
// cg
jitTask->Finalize();
jitTask->InstallCode();
jit->RemoveCompilingTask(jitTask);
// free
delete jitTask;
} else {
@ -153,18 +170,6 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, JitCompileMode m
}
}
void Jit::AddCompilingTask(JitTask *jitTask)
{
compilingJitTasks_.push_back(jitTask);
}
void Jit::RemoveCompilingTask(JitTask *jitTask)
{
auto findIt = std::find(compilingJitTasks_.begin(), compilingJitTasks_.end(), jitTask);
ASSERT(findIt != compilingJitTasks_.end());
compilingJitTasks_.erase(findIt);
}
JitTask *Jit::GetAsyncCompileTask()
{
LockHolder holder(asyncCompileJitTasksMtx_);
@ -181,7 +186,7 @@ void Jit::AddAsyncCompileTask(JitTask *jitTask)
LockHolder holder(asyncCompileJitTasksMtx_);
if (asyncCompileJitTasks_.empty()) {
Taskpool::GetCurrentTaskpool()->PostTask(
std::make_unique<JitTask::AsyncTask>(jitTask, vm_->GetJSThread()->GetThreadId()));
std::make_unique<JitTask::AsyncTask>(jitTask, jitTask->GetVM()->GetJSThread()->GetThreadId()));
}
asyncCompileJitTasks_.push_back(jitTask);
}
@ -197,44 +202,25 @@ void Jit::RemoveAsyncCompileTask([[maybe_unused]] JitTask *jitTask)
void Jit::RequestInstallCode(JitTask *jitTask)
{
LockHolder holder(installJitTasksDequeMtx_);
installJitTasks_.push_back(jitTask);
auto &taskQueue = installJitTasks_[jitTask->GetTaskThreadId()];
taskQueue.push_back(jitTask);
// set
vm_->GetJSThread()->SetInstallMachineCode(true);
vm_->GetJSThread()->SetCheckSafePointStatus();
jitTask->GetVM()->GetJSThread()->SetInstallMachineCode(true);
jitTask->GetVM()->GetJSThread()->SetCheckSafePointStatus();
}
bool Jit::IsCompiling(JSHandle<JSFunction> &jsFunction)
{
Method *srcMethod = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
for (auto it = compilingJitTasks_.begin(); it != compilingJitTasks_.end(); it++) {
JitTask *task = *it;
Method *compilingMethod = Method::Cast(task->GetJsFunction()->GetMethod().GetTaggedObject());
if (srcMethod == compilingMethod) {
return true;
}
}
return false;
}
void Jit::InstallTasksWithoutClearFlag()
void Jit::InstallTasks(uint32_t threadId)
{
LockHolder holder(installJitTasksDequeMtx_);
for (auto it = installJitTasks_.begin(); it != installJitTasks_.end(); it++) {
auto &taskQueue = installJitTasks_[threadId];
for (auto it = taskQueue.begin(); it != taskQueue.end(); it++) {
JitTask *task = *it;
// check task state
task->InstallCode();
RemoveCompilingTask(task);
delete task;
}
installJitTasks_.clear();
}
void Jit::InstallTasks()
{
InstallTasksWithoutClearFlag();
// clear flag
vm_->GetJSThread()->SetInstallMachineCode(false);
taskQueue.clear();
}
bool Jit::JitCompile(void *compiler, JitTask *jitTask)
@ -249,6 +235,12 @@ bool Jit::JitFinalize(void *compiler, JitTask *jitTask)
return jitFinalize_(compiler, jitTask);
}
void *Jit::CreateJitCompilerTask(JitTask *jitTask)
{
ASSERT(createJitCompilerTask_ != nullptr);
return createJitCompilerTask_(jitTask);
}
Jit::Scope::~Scope()
{
LOG_JIT(INFO) << message_ << ": " << TotalSpentTime() << "ms";

View File

@ -30,14 +30,20 @@ enum JitCompileMode {
};
class Jit {
public:
Jit(EcmaVM *vm) : vm_(vm), initialized_(false), jitCompile_(nullptr), jitFinalize_(nullptr),
createJitCompiler_(nullptr), deleteJitCompile_(nullptr), libHandle_(nullptr) {};
Jit()
{
Initialize();
}
~Jit();
static Jit *GetInstance();
void SetEnable(const EcmaVM *vm);
bool IsEnable();
void Initialize();
static void Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, JitCompileMode mode = SYNC);
bool JitCompile(void *compiler, JitTask *jitTask);
bool JitFinalize(void *compiler, JitTask *jitTask);
void *CreateJitCompilerTask(JitTask *jitTask);
bool IsInitialized() const
{
return initialized_;
@ -46,11 +52,7 @@ public:
void DeleteJitCompile(void *compiler);
void RequestInstallCode(JitTask *jitTask);
void InstallTasks();
void InstallTasksWithoutClearFlag();
bool IsCompiling(JSHandle<JSFunction> &jsFunction);
void AddCompilingTask(JitTask *jitTask);
void RemoveCompilingTask(JitTask *jitTask);
void InstallTasks(uint32_t threadId);
JitTask *GetAsyncCompileTask();
void AddAsyncCompileTask(JitTask *jitTask);
@ -69,19 +71,20 @@ public:
private:
bool SupportJIT(Method *method);
EcmaVM *vm_;
bool initialized_;
bool(*jitCompile_)(void*, JitTask*);
bool(*jitFinalize_)(void*, JitTask*);
void*(*createJitCompiler_)(EcmaVM*, JitTask*);
void(*deleteJitCompile_)(void*);
void *libHandle_;
bool initialized_ { false };
bool jitEnable_ { false };
std::deque<JitTask*> compilingJitTasks_;
std::deque<JitTask*> installJitTasks_;
std::unordered_map<uint32_t, std::deque<JitTask*>> installJitTasks_;
static std::deque<JitTask*> asyncCompileJitTasks_;
Mutex installJitTasksDequeMtx_;
static Mutex asyncCompileJitTasksMtx_;
static void (*initJitCompiler_)(EcmaVM *vm);
static bool(*jitCompile_)(void*, JitTask*);
static bool(*jitFinalize_)(void*, JitTask*);
static void*(*createJitCompilerTask_)(JitTask*);
static void(*deleteJitCompile_)(void*);
static void *libHandle_;
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JIT_H

View File

@ -19,9 +19,15 @@
#include "ecmascript/compiler/aot_file/func_entry_des.h"
namespace panda::ecmascript {
void JitTask::PrepareCompile()
{
PersistentHandle();
compilerTask_ = jit_->CreateJitCompilerTask(this);
}
void JitTask::Optimize()
{
bool res = jit_->JitCompile(compiler_, this);
bool res = jit_->JitCompile(compilerTask_, this);
if (!res) {
SetCompileFailed();
}
@ -33,7 +39,7 @@ void JitTask::Finalize()
return;
}
bool res = jit_->JitFinalize(compiler_, this);
bool res = jit_->JitFinalize(compilerTask_, this);
if (!res) {
SetCompileFailed();
}
@ -46,7 +52,7 @@ void JitTask::InstallCode()
}
JSHandle<Method> methodHandle(vm_->GetJSThread(), Method::Cast(jsFunction_->GetMethod().GetTaggedObject()));
size_t funcEntryDesSizeAlign = AlignUp(codeDesc_.funcEntryDesSize, MachineCode::DATA_ALIGN);
size_t funcEntryDesSizeAlign = AlignUp(codeDesc_.funcEntryDesSize, MachineCode::TEXT_ALIGN);
size_t rodataSizeBeforeTextAlign = AlignUp(codeDesc_.rodataSizeBeforeText, MachineCode::TEXT_ALIGN);
size_t codeSizeAlign = AlignUp(codeDesc_.codeSize, MachineCode::DATA_ALIGN);
@ -86,7 +92,7 @@ void JitTask::ReleasePersistentHandle()
JitTask::~JitTask()
{
ReleasePersistentHandle();
jit_->DeleteJitCompile(compiler_);
jit_->DeleteJitCompile(compilerTask_);
}
bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)

View File

@ -30,13 +30,18 @@ enum CompileState : uint8_t {
class JitTask {
public:
JitTask(EcmaVM *vm, Jit *jit, JSHandle<JSFunction> &jsFunction) : vm_(vm), jit_(jit),
jsFunction_(jsFunction), compiler_(nullptr), state_(CompileState::SUCCESS) {
PersistentHandle();
}
JitTask(EcmaVM *vm, Jit *jit, JSHandle<JSFunction> &jsFunction, CString &methodName, uint32_t taskThreadId)
: vm_(vm),
jit_(jit),
jsFunction_(jsFunction),
compilerTask_(nullptr),
state_(CompileState::SUCCESS),
methodInfo_(methodName),
taskThreadId_(taskThreadId) { }
~JitTask();
void Optimize();
void Finalize();
void PrepareCompile();
void InstallCode();
MachineCodeDesc *GetMachineCodeDesc()
@ -49,11 +54,6 @@ public:
return jsFunction_;
}
void SetCompiler(void *compiler)
{
compiler_ = compiler;
}
void RequestInstallCode()
{
jit_->RequestInstallCode(this);
@ -89,6 +89,10 @@ public:
methodInfo_ = methodInfo;
}
uint32_t GetTaskThreadId() const
{
return taskThreadId_;
}
class AsyncTask : public Task {
public:
explicit AsyncTask(JitTask *jitTask, int32_t id) : Task(id), jitTask_(jitTask) { }
@ -109,10 +113,11 @@ private:
EcmaVM *vm_;
Jit *jit_;
JSHandle<JSFunction> jsFunction_;
void *compiler_;
void *compilerTask_;
MachineCodeDesc codeDesc_;
CompileState state_;
CString methodInfo_;
uint32_t taskThreadId_;
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JIT_TASK_H

View File

@ -504,15 +504,12 @@ void JSThread::CheckOrSwitchPGOStubs()
}
}
void JSThread::SwitchJitProfileStubsIfNeeded()
void JSThread::SwitchJitProfileStubs()
{
bool isSwitch = false;
bool isEnableJit = vm_->IsEnableJit();
if (isEnableJit) {
if (GetBCStubStatus() == BCStubStatus::NORMAL_BC_STUB) {
SetBCStubStatus(BCStubStatus::JIT_PROFILE_BC_STUB);
isSwitch = true;
}
if (GetBCStubStatus() == BCStubStatus::NORMAL_BC_STUB) {
SetBCStubStatus(BCStubStatus::JIT_PROFILE_BC_STUB);
isSwitch = true;
}
if (isSwitch) {
Address curAddress;
@ -544,12 +541,6 @@ bool JSThread::CheckSafepoint()
SetTerminationRequestWithoutLock(false);
}
if (vm_->IsEnableJit() && HasInstallMachineCodeWithoutLock()) {
vm_->GetJit()->InstallTasksWithoutClearFlag();
// jit 's thread_ is current JSThread's this.
SetInstallMachineCodeWithoutLock(false);
}
// vmThreadControl_ 's thread_ is current JSThread's this.
if (VMNeedSuspensionWithoutLock()) {
interruptMutex_.Unlock();
@ -558,6 +549,11 @@ bool JSThread::CheckSafepoint()
interruptMutex_.Unlock();
}
if (vm_->IsEnableJit() && HasInstallMachineCode()) {
vm_->GetJit()->InstallTasks(GetThreadId());
SetInstallMachineCode(false);
}
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
if (needProfiling_.load() && !isProfiling_) {
DFXJSNApi::StartCpuProfilerForFile(vm_, profileName_, CpuProfiler::INTERVAL_OF_INNER_START);

View File

@ -312,7 +312,7 @@ public:
void PUBLIC_API CheckSwitchDebuggerBCStub();
void CheckOrSwitchPGOStubs();
void SwitchJitProfileStubsIfNeeded();
void SwitchJitProfileStubs();
ThreadId GetThreadId() const
{

View File

@ -414,6 +414,14 @@ CString JSPandaFile::GetRecordName(EntityId methodId)
return name;
}
CString JSPandaFile::GetRecordNameWithBundlePack(EntityId methodIdx)
{
CString recordName = IsBundlePack() ? ENTRY_FUNCTION_NAME : GetRecordName(methodIdx);
ASSERT(HasRecord(recordName));
return recordName;
}
void JSPandaFile::ClearNameMap()
{
{

View File

@ -124,6 +124,7 @@ public:
const char *GetMethodName(EntityId methodId);
const char *GetCpuProfilerMethodName(EntityId methodId);
CString GetRecordName(EntityId methodId);
CString PUBLIC_API GetRecordNameWithBundlePack(EntityId methodIdx);
MethodLiteral* GetMethodLiterals() const
{

View File

@ -29,7 +29,7 @@ void MachineCode::SetData(const MachineCodeDesc *desc, JSHandle<Method> &method,
size_t codeSizeAlign = AlignUp(desc->codeSize, MachineCode::DATA_ALIGN);
size_t rodataSizeAfterTextAlign = AlignUp(desc->rodataSizeAfterText, MachineCode::DATA_ALIGN);
size_t funcEntryDesSizeAlign = desc->funcEntryDesSize;
size_t funcEntryDesSizeAlign = AlignUp(desc->funcEntryDesSize, MachineCode::TEXT_ALIGN);
SetFuncEntryDesSize(funcEntryDesSizeAlign);
size_t instrSize = rodataSizeBeforeTextAlign + codeSizeAlign + rodataSizeAfterTextAlign;

View File

@ -165,6 +165,7 @@
panda::ecmascript::JSPandaFile::FindMethodLiteral*;
panda::ecmascript::JSPandaFile::GetFunctionKind*;
panda::ecmascript::JSPandaFile::GetNormalizedFileDesc*;
panda::ecmascript::JSPandaFile::GetRecordNameWithBundlePack*;
panda::ecmascript::JSProxy::IsArray*;
panda::ecmascript::JSTaggedValue::IsJSCOWArray*;
panda::ecmascript::JSTaggedValue::SetProperty*;