mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 18:20:04 +00:00
[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:
parent
255e36255b
commit
5e561c4c20
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -312,7 +312,7 @@ public:
|
||||
|
||||
void PUBLIC_API CheckSwitchDebuggerBCStub();
|
||||
void CheckOrSwitchPGOStubs();
|
||||
void SwitchJitProfileStubsIfNeeded();
|
||||
void SwitchJitProfileStubs();
|
||||
|
||||
ThreadId GetThreadId() const
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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*;
|
||||
|
Loading…
Reference in New Issue
Block a user