!10168 [JIT] Opt app cold start as jit load so

Merge pull request !10168 from xiaoweidong/lib_load
This commit is contained in:
openharmony_ci 2024-11-28 07:04:05 +00:00 committed by Gitee
commit 3116ed839f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 269 additions and 137 deletions

View File

@ -737,6 +737,7 @@ ecma_source = [
"ecmascript/jit/jit.cpp",
"ecmascript/jit/jit_dfx.cpp",
"ecmascript/jit/jit_task.cpp",
"ecmascript/jit/jit_resources.cpp",
"ecmascript/jit/jit_thread.cpp",
"ecmascript/jit/jit_profiler.cpp",
"ecmascript/jobs/micro_job_queue.cpp",

View File

@ -276,11 +276,11 @@ bool JitFinalize(void *compilerTask, JitTask *jitTask)
return jitCompilerTask->Finalize(jitTask);
}
void DeleteJitCompile(void *handle)
void DeleteJitCompilerTask(void *compilerTask)
{
if (handle == nullptr) {
if (compilerTask == nullptr) {
return;
}
delete reinterpret_cast<JitCompilerTask*>(handle);
delete reinterpret_cast<JitCompilerTask*>(compilerTask);
}
} // namespace panda::ecmascript::kungfu

View File

@ -30,7 +30,7 @@ PUBLIC_API void InitJitCompiler(JSRuntimeOptions options);
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);
PUBLIC_API void DeleteJitCompilerTask(void *handle);
};
struct JitCompilationOptions {

View File

@ -121,6 +121,8 @@ void EcmaVM::PreFork()
auto sHeap = SharedHeap::GetInstance();
sHeap->CompactHeapBeforeFork(thread_);
sHeap->DisableParallelGC(thread_);
Jit::GetInstance()->PreFork();
}
void EcmaVM::PostFork()

View File

@ -20,12 +20,6 @@
#include "ecmascript/checkpoint/thread_state_transition.h"
namespace panda::ecmascript {
void (*Jit::initJitCompiler_)(JSRuntimeOptions options) = 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()
{
@ -33,6 +27,27 @@ Jit *Jit::GetInstance()
return &instance_;
}
void Jit::CreateJitResources()
{
if (jitResources_ == nullptr) {
jitResources_ = std::make_unique<JitResources>();
jitResources_->ResolveLib();
}
}
bool Jit::IsLibResourcesResolved() const
{
if (jitResources_ != nullptr) {
return jitResources_->IsLibResolved();
}
return false;
}
void Jit::PreFork()
{
CreateJitResources();
}
void Jit::SetJitEnablePostFork(EcmaVM *vm, const std::string &bundleName)
{
JSRuntimeOptions &options = vm->GetJSOptions();
@ -46,10 +61,12 @@ void Jit::SetJitEnablePostFork(EcmaVM *vm, const std::string &bundleName)
options.SetEnableJitFrame(ohos::JitTools::GetJitFrameEnable());
options.SetEnableAPPJIT(true);
isApp_ = true;
// for app threshold
uint32_t defaultSize = 3000;
uint32_t threshold = ohos::JitTools::GetJitHotnessThreshold(defaultSize);
options.SetJitHotnessThreshold(threshold);
hotnessThreshold_ = threshold;
bundleName_ = bundleName;
isEnableAppPGO_ = pgo::PGOProfilerManager::GetInstance()->IsEnable();
@ -135,70 +152,36 @@ void Jit::ConfigJitFortOptions(EcmaVM *vm)
void Jit::SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnableFastJit, bool isEnableBaselineJit)
{
LockHolder holder(setEnableLock_);
bool enableJit = isEnableFastJit || isEnableBaselineJit;
if (enableJit) {
CreateJitResources();
}
bool needInitialize = false;
if (!isEnableFastJit) {
fastJitEnable_ = false;
} else {
needInitialize = true;
}
if (!isEnableBaselineJit) {
baselineJitEnable_ = false;
} else {
needInitialize = true;
}
if (!needInitialize) {
return;
}
if (!initialized_) {
Initialize();
if (IsLibResourcesResolved()) {
jitDfx_ = JitDfx::GetInstance();
jitDfx_->Init(options, bundleName_);
jitResources_->InitJitEnv(options);
initialized_ = true;
}
if (initialized_) {
bool jitEnable = false;
if (isEnableFastJit && !fastJitEnable_) {
fastJitEnable_ = true;
jitEnable = true;
}
if (isEnableBaselineJit && !baselineJitEnable_) {
baselineJitEnable_ = true;
jitEnable = true;
}
if (jitEnable) {
jitDfx_ = JitDfx::GetInstance();
jitDfx_->Init(options, bundleName_);
isApp_ = options.IsEnableAPPJIT();
hotnessThreshold_ = options.GetJitHotnessThreshold();
if (initJitCompiler_ != nullptr) {
initJitCompiler_(options);
}
bool enableCodeSign = !ohos::JitTools::GetCodeSignDisable(options.GetDisableCodeSign());
bool shouldCompileMain =
options.IsEnableForceJitCompileMain() || options.IsEnableForceBaselineCompileMain();
if (enableCodeSign && shouldCompileMain) {
JitFort::InitJitFortResource();
}
JitTaskpool::GetCurrentTaskpool()->Initialize(enableCodeSign && !shouldCompileMain);
}
fastJitEnable_ = isEnableFastJit;
baselineJitEnable_ = isEnableBaselineJit;
}
}
void Jit::Destroy()
{
LockHolder holder(setEnableLock_);
if (!initialized_) {
return;
}
LockHolder holder(setEnableLock_);
JitTaskpool::GetCurrentTaskpool()->Destroy();
initialized_ = false;
fastJitEnable_ = false;
baselineJitEnable_ = false;
if (libHandle_ != nullptr) {
CloseLib(libHandle_);
libHandle_ = nullptr;
}
jitResources_->Destroy();
jitResources_ = nullptr;
}
bool Jit::IsEnableFastJit() const
@ -241,70 +224,10 @@ void Jit::SetEnableAsyncCopyToFort(bool isEnableAsyncCopyToFort)
isEnableAsyncCopyToFort_ = isEnableAsyncCopyToFort;
}
void Jit::Initialize()
{
#if defined(OHOS_UNIT_TEST)
#else
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";
static const std::string LIBARK_JSOPTIMIZER = "libark_jsoptimizer.so";
libHandle_ = LoadLib(LIBARK_JSOPTIMIZER);
if (libHandle_ == nullptr) {
char *error = LoadLibError();
LOG_JIT(ERROR) << "jit dlopen libark_jsoptimizer.so failed, as:" <<
((error == nullptr) ? "unknown error" : error);
return;
}
initJitCompiler_ = reinterpret_cast<void(*)(JSRuntimeOptions)>(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";
return;
}
jitFinalize_ = reinterpret_cast<bool(*)(void*, JitTask*)>(FindSymbol(libHandle_, JITFINALIZE.c_str()));
if (jitFinalize_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol jitFinalize";
return;
}
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 (deleteJitCompile_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol deleteJitCompile";
return;
}
#endif
initialized_= true;
return;
}
Jit::~Jit()
{
}
void Jit::DeleteJitCompile(void *compiler)
{
if (deleteJitCompile_ != nullptr) {
deleteJitCompile_(compiler);
}
}
void Jit::CountInterpExecFuncs(JSHandle<JSFunction> &jsFunction)
{
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
@ -424,22 +347,22 @@ void Jit::InstallTasks(JSThread *jsThread)
bool Jit::JitCompile(void *compiler, JitTask *jitTask)
{
ASSERT(jitCompile_ != nullptr);
return jitCompile_(compiler, jitTask);
return jitResources_->Compile(compiler, jitTask);
}
bool Jit::JitFinalize(void *compiler, JitTask *jitTask)
{
ASSERT(jitFinalize_ != nullptr);
return jitFinalize_(compiler, jitTask);
return jitResources_->Finalize(compiler, jitTask);
}
void *Jit::CreateJitCompilerTask(JitTask *jitTask)
{
if (createJitCompilerTask_ == nullptr) {
return nullptr;
}
return createJitCompilerTask_(jitTask);
return jitResources_->CreateJitCompilerTask(jitTask);
}
void Jit::DeleteJitCompilerTask(void *compiler)
{
jitResources_->DeleteJitCompilerTask(compiler);
}
void Jit::ClearTask(const std::function<bool(Task *task)> &checkClear)

View File

@ -26,6 +26,7 @@
#include "ecmascript/jit/jit_thread.h"
#include "ecmascript/jit/jit_dfx.h"
#include "ecmascript/jit/compile_decision.h"
#include "ecmascript/jit/jit_resources.h"
namespace panda::ecmascript {
class JitTask;
@ -44,6 +45,7 @@ public:
~Jit();
static PUBLIC_API Jit *GetInstance();
void SetJitEnablePostFork(EcmaVM *vm, const std::string &bundleName);
void PreFork();
void ConfigJit(EcmaVM *vm);
void SwitchProfileStubs(EcmaVM *vm);
void ConfigOptions(EcmaVM *vm) const;
@ -57,7 +59,6 @@ public:
void SetDisableCodeSign(bool isEnableCodeSign);
bool PUBLIC_API IsEnableAsyncCopyToFort() const;
void SetEnableAsyncCopyToFort(bool isEnableiAsyncCopyToFort);
void Initialize();
static void Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction,
CompilerTier::Tier tier = CompilerTier::Tier::FAST,
@ -75,7 +76,7 @@ public:
return initialized_;
}
void DeleteJitCompile(void *compiler);
void DeleteJitCompilerTask(void *compiler);
void RequestInstallCode(std::shared_ptr<JitTask> jitTask);
void InstallTasks(JSThread *jsThread);
@ -231,6 +232,8 @@ private:
void Compile(EcmaVM *vm, const CompileDecision &decision);
static void Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tier,
int32_t offset, JitCompileMode mode);
void CreateJitResources();
bool IsLibResourcesResolved() const;
bool initialized_ { false };
bool fastJitEnable_ { false };
bool baselineJitEnable_ { false };
@ -249,14 +252,8 @@ private:
Mutex setEnableLock_;
JitDfx *jitDfx_ { nullptr };
std::unique_ptr<JitResources> jitResources_;
static constexpr int MIN_CODE_SPACE_SIZE = 1_KB;
static void (*initJitCompiler_)(JSRuntimeOptions);
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

@ -0,0 +1,113 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/jit/jit_resources.h"
#include "ecmascript/jit/jit_task.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/taskpool/taskpool.h"
#include "ecmascript/ohos/jit_tools.h"
namespace panda::ecmascript {
void JitResources::Destroy()
{
JitTaskpool::GetCurrentTaskpool()->Destroy();
if (libHandle_ != nullptr) {
CloseLib(libHandle_);
libHandle_ = nullptr;
initJitCompiler_ = nullptr;
jitCompile_ = nullptr;
jitFinalize_ = nullptr;
createJitCompilerTask_ = nullptr;
deleteJitCompilerTask_ = nullptr;
}
}
bool JitResources::InitJitEnv(const JSRuntimeOptions &options)
{
jsRuntimeOptions_ = options;
InitCompiler();
InitJitTaskpool();
return true;
}
bool JitResources::ResolveLib()
{
#if defined(OHOS_UNIT_TEST)
#else
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 DELETEJITCOMPILERTASK = "DeleteJitCompilerTask";
static const std::string LIBARK_JSOPTIMIZER = "libark_jsoptimizer.so";
libHandle_ = LoadLib(LIBARK_JSOPTIMIZER);
if (libHandle_ == nullptr) {
char *error = LoadLibError();
LOG_JIT(ERROR) << "jit dlopen libark_jsoptimizer.so failed, as:" <<
((error == nullptr) ? "unknown error" : error);
return false;
}
initJitCompiler_ = reinterpret_cast<InitJitCompilerFuncType>(FindSymbol(libHandle_, JITCOMPILEINIT.c_str()));
if (initJitCompiler_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol initJitCompiler";
return false;
}
jitCompile_ = reinterpret_cast<JitCompileFuncType>(FindSymbol(libHandle_, JITCOMPILE.c_str()));
if (jitCompile_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol jitCompile";
return false;
}
jitFinalize_ = reinterpret_cast<JitFinalizeFuncType>(FindSymbol(libHandle_, JITFINALIZE.c_str()));
if (jitFinalize_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol jitFinalize";
return false;
}
createJitCompilerTask_ = reinterpret_cast<CreateJitCompilerTaskFuncType>(FindSymbol(libHandle_,
CREATEJITCOMPILETASK.c_str()));
if (createJitCompilerTask_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol createJitCompilertask";
return false;
}
deleteJitCompilerTask_ = reinterpret_cast<DeleteJitCompilerTaskFuncType>(FindSymbol(libHandle_,
DELETEJITCOMPILERTASK.c_str()));
if (deleteJitCompilerTask_ == nullptr) {
LOG_JIT(ERROR) << "jit can't find symbol deleteJitCompile";
return false;
}
#endif
libResolved_ = true;
return true;
}
void JitResources::InitCompiler()
{
if (initJitCompiler_ == nullptr) {
return;
}
initJitCompiler_(jsRuntimeOptions_);
}
void JitResources::InitJitTaskpool()
{
bool enableCodeSign = !ohos::JitTools::GetCodeSignDisable(jsRuntimeOptions_.GetDisableCodeSign());
JitTaskpool::GetCurrentTaskpool()->Initialize(enableCodeSign);
}
} // namespace panda::ecmascript

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMASCRIPT_JIT_RESOURCES_H
#define ECMASCRIPT_JIT_RESOURCES_H
#include "ecmascript/ecma_vm.h"
#include "ecmascript/taskpool/taskpool.h"
namespace panda::ecmascript {
class JitTask;
using InitJitCompilerFuncType = void (*)(JSRuntimeOptions options);
using JitCompileFuncType = bool(*)(void*, JitTask*);
using JitFinalizeFuncType = bool(*)(void*, JitTask*);
using CreateJitCompilerTaskFuncType = void*(*)(JitTask*);
using DeleteJitCompilerTaskFuncType = void(*)(void*);
class JitResources {
public:
JitResources() = default;
~JitResources() = default;
void Resolve();
void Destroy();
bool IsLibResolved() const
{
return libResolved_;
}
bool Compile(void *compiler, JitTask *jitTask)
{
if (jitCompile_ == nullptr) {
return false;
}
return jitCompile_(compiler, jitTask);
}
bool Finalize(void *compiler, JitTask *jitTask)
{
if (jitFinalize_ == nullptr) {
return false;
}
return jitFinalize_(compiler, jitTask);
}
void *CreateJitCompilerTask(JitTask *jitTask)
{
if (createJitCompilerTask_ == nullptr) {
return nullptr;
}
return createJitCompilerTask_(jitTask);
}
void DeleteJitCompilerTask(void *compilerTask)
{
if (deleteJitCompilerTask_ == nullptr) {
return;
}
deleteJitCompilerTask_(compilerTask);
}
bool ResolveLib();
bool InitJitEnv(const JSRuntimeOptions &options);
private:
void DoResolve();
void InitCompiler();
void InitJitTaskpool();
JSRuntimeOptions jsRuntimeOptions_;
bool libResolved_ {false};
InitJitCompilerFuncType initJitCompiler_ {nullptr};
JitCompileFuncType jitCompile_ {nullptr};
JitFinalizeFuncType jitFinalize_ {nullptr};
CreateJitCompilerTaskFuncType createJitCompilerTask_ {nullptr};
DeleteJitCompilerTaskFuncType deleteJitCompilerTask_ {nullptr};
void *libHandle_ {nullptr};
NO_COPY_SEMANTIC(JitResources);
NO_MOVE_SEMANTIC(JitResources);
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JIT_RESOURCES_H

View File

@ -376,7 +376,7 @@ void JitTask::CloneProfileTypeInfo()
JitTask::~JitTask()
{
ReleaseSustainingJSHandle();
jit_->DeleteJitCompile(compilerTask_);
jit_->DeleteJitCompilerTask(compilerTask_);
jit_->DecJitTaskCnt(hostThread_);
}