[JIT] Set default options for concurrent jit compile

Change-Id: I64c028590421704e408affab581df52a71ab9579
Signed-off-by: xiaoweidong <xiaoweidong@huawei.com>
This commit is contained in:
xiaoweidong 2024-04-21 22:05:22 +08:00
parent 4d73659898
commit 420b5ec786
21 changed files with 111 additions and 66 deletions

View File

@ -36,6 +36,7 @@ BytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *j
pfDecoder_(pfDecoder),
snapshotCPData_(new SnapshotConstantPoolData(env->GetEcmaVM(), jsPandaFile, &pfDecoder))
{
ASSERT(env->IsAotCompiler());
ProcessClasses();
}
@ -43,10 +44,12 @@ BytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *j
PGOProfilerDecoder &pfDecoder)
: compilationEnv_(env),
jsPandaFile_(jsPandaFile),
bytecodeInfo_(1),
// refactor: jit max method size
bytecodeInfo_(env->GetJSOptions().GetMaxAotMethodSize()),
pfDecoder_(pfDecoder),
snapshotCPData_(nullptr) // jit no need
{
ASSERT(env->IsJitCompiler());
ProcessMethod();
}

View File

@ -69,7 +69,11 @@ JSTaggedValue JitCompilationEnv::FindConstpool([[maybe_unused]] const JSPandaFil
{
ASSERT(thread_->IsInRunningState());
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
return method->GetConstantPool();
JSTaggedValue constpool = method->GetConstantPool();
[[maybe_unused]] const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
ASSERT(taggedPool->GetJSPandaFile() == jsPandaFile);
ASSERT(method->GetMethodId() == id);
return constpool;
}
JSTaggedValue JitCompilationEnv::FindConstpool([[maybe_unused]] const JSPandaFile *jsPandaFile,
@ -77,25 +81,31 @@ JSTaggedValue JitCompilationEnv::FindConstpool([[maybe_unused]] const JSPandaFil
{
ASSERT(thread_->IsInRunningState());
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
return method->GetConstantPool();
JSTaggedValue constpool = method->GetConstantPool();
[[maybe_unused]] const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
ASSERT(taggedPool->GetJSPandaFile() == jsPandaFile);
ASSERT(taggedPool->GetSharedConstpoolId().GetInt() == index);
return constpool;
}
JSTaggedValue JitCompilationEnv::FindOrCreateUnsharedConstpool([[maybe_unused]] const uint32_t methodOffset) const
{
ASSERT(thread_->IsInRunningState());
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
ASSERT(method->GetMethodId().GetOffset() == methodOffset);
JSTaggedValue constpool = method->GetConstantPool();
if (!ConstantPool::CheckUnsharedConstpool(constpool)) {
constpool = hostThread_->GetCurrentEcmaContext()->FindUnsharedConstpool(constpool);
return constpool;
}
ASSERT(constpool.IsHole());
return constpool;
ASSERT(!ConstantPool::CheckUnsharedConstpool(constpool));
JSTaggedValue unSharedConstpool = hostThread_->GetCurrentEcmaContext()->FindUnsharedConstpool(constpool);
return unSharedConstpool;
}
JSTaggedValue JitCompilationEnv::FindOrCreateUnsharedConstpool([[maybe_unused]] JSTaggedValue sharedConstpool) const
{
return FindOrCreateUnsharedConstpool(0);
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
[[maybe_unused]] JSTaggedValue constpool = method->GetConstantPool();
ASSERT(constpool == sharedConstpool);
uint32_t methodOffset = method->GetMethodId().GetOffset();
return FindOrCreateUnsharedConstpool(methodOffset);
}
JSHandle<ConstantPool> JitCompilationEnv::FindOrCreateConstPool([[maybe_unused]] const JSPandaFile *jsPandaFile,
@ -109,6 +119,7 @@ JSTaggedValue JitCompilationEnv::GetConstantPoolByMethodOffset([[maybe_unused]]
{
ASSERT(thread_->IsInRunningState());
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
ASSERT(method->GetMethodId().GetOffset() == methodOffset);
return method->GetConstantPool();
}
@ -143,10 +154,11 @@ const GlobalEnvConstants *JitCompilationEnv::GlobalConstants() const
}
JSTaggedValue JitCompilationEnv::GetStringFromConstantPool([[maybe_unused]] const uint32_t methodOffset,
[[maybe_unused]] const uint16_t cpIdx) const
const uint16_t cpIdx) const
{
ASSERT(thread_->IsInRunningState());
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
ASSERT(method->GetMethodId().GetOffset() == methodOffset);
JSTaggedValue constpool = method->GetConstantPool();
return ConstantPool::GetStringFromCacheForJit(GetJSThread(), constpool, cpIdx);
}

View File

@ -43,6 +43,9 @@ JitCompilationOptions::JitCompilationOptions(JSRuntimeOptions runtimeOptions)
LOG_JIT(FATAL) << "jit unsupport arch";
UNREACHABLE();
#endif
// refactor: remove JitCompilationOptions, reuse CompilationOptions
bool isApp = runtimeOptions.IsEnableAPPJIT();
optLevel_ = runtimeOptions.GetOptLevel();
relocMode_ = runtimeOptions.GetRelocMode();
logOption_ = runtimeOptions.GetCompilerLogOption();
@ -52,11 +55,11 @@ JitCompilationOptions::JitCompilationOptions(JSRuntimeOptions runtimeOptions)
hotnessThreshold_ = runtimeOptions.GetPGOHotnessThreshold();
profilerIn_ = std::string(runtimeOptions.GetPGOProfilerPath());
isEnableArrayBoundsCheckElimination_ = runtimeOptions.IsEnableArrayBoundsCheckElimination();
isEnableTypeLowering_ = runtimeOptions.IsEnableTypeLowering();
isEnableTypeLowering_ = isApp ? false : runtimeOptions.IsEnableTypeLowering();
isEnableEarlyElimination_ = runtimeOptions.IsEnableEarlyElimination();
isEnableLaterElimination_ = runtimeOptions.IsEnableLaterElimination();
isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
isEnableOptInlining_ = false;
isEnableOptString_ = runtimeOptions.IsEnableOptString();
isEnableOptPGOType_ = runtimeOptions.IsEnableOptPGOType();
isEnableOptTrackField_ = runtimeOptions.IsEnableOptTrackField();

View File

@ -42,7 +42,7 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
std::string fileName = jsPandaFile->GetFileName();
collector_ = new BytecodeInfoCollector(compilationEnv_, const_cast<JSPandaFile*>(jsPandaFile),
profilerDecoder_, passOptions_->EnableCollectLiteralInfo());
profilerDecoder_);
gen.SetCurrentCompileFileName(jsPandaFile->GetNormalizedFileDesc());
lOptions_ = new LOptions(optLevel_, FPFlag::RESERVE_FP, relocMode_);
@ -126,17 +126,12 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
pipeline.RunPass<LoopOptimizationPass>();
pipeline.RunPass<RedundantPhiEliminationPass>();
}
// support when remove tsmanager in pass
const bool enablepass = false;
if (enablepass) {
{
Jit::JitLockHolder lock(compilationEnv_, "PGOTypeInferPass");
pipeline.RunPass<PGOTypeInferPass>();
}
{
Jit::JitLockHolder lock(compilationEnv_, "TSInlineLoweringPass");
pipeline.RunPass<TSInlineLoweringPass>();
}
if (passOptions_->EnableTypeLowering()) {
pipeline.RunPass<PGOTypeInferPass>();
}
{
Jit::JitLockHolder lock(compilationEnv_, "TSInlineLoweringPass");
pipeline.RunPass<TSInlineLoweringPass>();
}
pipeline.RunPass<RedundantPhiEliminationPass>();

View File

@ -544,9 +544,6 @@ void Deoptimizier::UpdateAndDumpDeoptInfo(kungfu::DeoptType type)
method->SetDeoptThreshold(--deoptThreshold);
} else {
method->ClearAOTStatusWhenDeopt();
if (func->GetMachineCode() != JSTaggedValue::Undefined()) {
func->SetMachineCode(thread_, JSTaggedValue::Undefined());
}
func->SetCodeEntry(reinterpret_cast<uintptr_t>(nullptr));
}
}

View File

@ -182,6 +182,7 @@ void EcmaVM::PostFork()
options_.SetEnableAPPJIT(true);
if (ohos::EnableAotListHelper::GetJitInstance()->IsEnableJit(bundleName) && options_.GetEnableAsmInterpreter()) {
Jit::GetInstance()->SetEnableOrDisable(options_, isEnableFastJit, isEnableBaselineJit);
options_.SetEnableAPPJIT(true);
if (isEnableFastJit || isEnableBaselineJit) {
EnableJit();
}
@ -272,9 +273,22 @@ bool EcmaVM::IsEnableBaselineJit() const
void EcmaVM::EnableJit()
{
// check enable aot pgo, if have enable aot pgo, thread installed pgo stubs
if (!IsEnablePGOProfiler() && pgoProfiler_ != nullptr) {
// only jit enable pgo, disable aot pgo dump
options_.SetEnableProfileDump(false);
// enable pgo profile
options_.SetEnablePGOProfiler(true);
pgoProfiler_->Reset(true);
thread_->SetPGOProfilerEnable(true);
thread_->CheckOrSwitchPGOStubs();
}
if (pgoProfiler_ != nullptr) {
pgoProfiler_->InitJITProfiler();
}
bool isApp = Jit::GetInstance()->IsAppJit();
options_.SetEnableAPPJIT(isApp);
GetJSThread()->SwitchJitProfileStubs();
#ifdef JIT_SWITCH_COMPILE_MODE
bool jitEnableLitecg = OHOS::system::GetBoolParameter("ark.jit.enable.litecg", true);

View File

@ -113,7 +113,7 @@ public:
EcmaVM();
virtual ~EcmaVM();
~EcmaVM();
void SetLoop(void *loop)
{

View File

@ -37,11 +37,6 @@ Jit *Jit::GetInstance()
void Jit::SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnableFastJit, bool isEnableBaselineJit)
{
LockHolder holder(setEnableLock_);
if (options.IsEnableAPPJIT()) {
// temporary for app jit options test.
LOG_JIT(DEBUG) << (isEnableFastJit ? "jit is enable" : "jit is disable");
return;
}
bool needInitialize = false;
if (!isEnableFastJit) {
@ -71,6 +66,7 @@ void Jit::SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnableFastJ
jitEnable = true;
}
if (jitEnable) {
isApp_ = options.IsEnableAPPJIT();
initJitCompiler_(options);
JitTaskpool::GetCurrentTaskpool()->Initialize();
}
@ -368,10 +364,10 @@ void Jit::ClearTask(const std::function<bool(Task *task)> &checkClear)
JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task);
if (checkClear(asyncTask)) {
asyncTask->Terminated();
}
if (asyncTask->IsRunning()) {
asyncTask->WaitFinish();
if (asyncTask->IsRunning()) {
asyncTask->WaitFinish();
}
asyncTask->ReleaseSustainingJSHandle();
}
});
}

View File

@ -70,6 +70,10 @@ public:
// dfx for jit preheat compile
static void CountInterpExecFuncs(JSHandle<JSFunction> &jsFunction);
bool IsAppJit()
{
return isApp_;
}
NO_COPY_SEMANTIC(Jit);
NO_MOVE_SEMANTIC(Jit);
@ -156,6 +160,7 @@ private:
bool initialized_ { false };
bool fastJitEnable_ { false };
bool baselineJitEnable_ { false };
bool isApp_ { false };
std::unordered_map<uint32_t, std::deque<std::shared_ptr<JitTask>>> installJitTasks_;
Mutex installJitTasksDequeMtx_;

View File

@ -217,6 +217,8 @@ void JitTask::SustainingJSHandles()
void JitTask::ReleaseSustainingJSHandle()
{
// in abort case, vm exit before task finish, release by explict
sustainingJSHandle_ = nullptr;
}
void JitTask::CloneProfileTypeInfo()

View File

@ -212,11 +212,6 @@ public:
return jitCompileMode_ == JitCompileMode::ASYNC;
}
void Terminated()
{
sustainingJSHandle_->SetTerminated();
}
class AsyncTask : public Task {
public:
explicit AsyncTask(std::shared_ptr<JitTask>jitTask, int32_t id) : Task(id), jitTask_(jitTask) { }
@ -243,8 +238,13 @@ public:
void Terminated()
{
Task::Terminated();
jitTask_->Terminated();
}
void ReleaseSustainingJSHandle()
{
jitTask_->ReleaseSustainingJSHandle();
}
private:
std::shared_ptr<JitTask> jitTask_ { nullptr };
};

View File

@ -47,6 +47,12 @@ JitVM *JitVM::Create()
return vm;
}
JitVM::~JitVM()
{
// explict invoke ~EcmaVM
EcmaVM::~EcmaVM();
}
void JitVM::Destroy(EcmaVM *compilerVm)
{
JitVM *jitVM = static_cast<JitVM*>(compilerVm);

View File

@ -37,6 +37,7 @@ private:
class JitVM final : public EcmaVM {
public:
JitVM() : EcmaVM() {}
~JitVM();
static JitVM *Create();
static void Destroy(EcmaVM *jitvm);

View File

@ -1783,7 +1783,7 @@ private:
bool enableContext_ {false};
bool enablePrintExecuteTime_ {false};
bool enablePGOProfiler_ {false};
bool enableJITPGO_ {false};
bool enableJITPGO_ {true};
bool enableAOTPGO_ {true};
bool enableProfileDump_ {true};
bool reportModuleResolvingFailure_ {true};

View File

@ -51,6 +51,15 @@ namespace panda::ecmascript {
(object) = reinterpret_cast<TaggedObject *>((space)->Allocate(thread, size)); \
}
#define CHECK_MACHINE_CODE_OBJ_AND_SET_OOM_ERROR(object, size, space, message) \
if (UNLIKELY((object) == nullptr)) { \
EcmaVM *vm = GetEcmaVM(); \
size_t oomOvershootSize = vm->GetEcmaParamConfiguration().GetOutOfMemoryOvershootSize(); \
(space)->IncreaseOutOfMemoryOvershootSize(oomOvershootSize); \
SetMachineCodeOutOfMemoryError(GetJSThread(), size, message); \
(object) = reinterpret_cast<TaggedObject *>((space)->Allocate(size)); \
}
template<class Callback>
void SharedHeap::EnumerateOldSpaceRegions(const Callback &cb) const
{
@ -374,7 +383,7 @@ TaggedObject *Heap::AllocateMachineCodeObject(JSHClass *hclass, size_t size)
auto object = (size > MAX_REGULAR_HEAP_OBJECT_SIZE) ?
reinterpret_cast<TaggedObject *>(AllocateHugeMachineCodeObject(size)) :
reinterpret_cast<TaggedObject *>(machineCodeSpace_->Allocate(size));
CHECK_OBJ_AND_THROW_OOM_ERROR(object, size, machineCodeSpace_, "Heap::AllocateMachineCodeObject");
CHECK_MACHINE_CODE_OBJ_AND_SET_OOM_ERROR(object, size, machineCodeSpace_, "Heap::AllocateMachineCodeObject");
object->SetClass(thread_, hclass);
OnAllocateEvent(GetEcmaVM(), object, size);
return object;

View File

@ -826,6 +826,19 @@ void BaseHeap::ThrowOutOfMemoryError(JSThread *thread, size_t size, std::string
THROW_OOM_ERROR(thread, oss.str().c_str());
}
void BaseHeap::SetMachineCodeOutOfMemoryError(JSThread *thread, size_t size, std::string functionName)
{
std::ostringstream oss;
oss << "OutOfMemory when trying to allocate " << size << " bytes" << " function name: "
<< functionName.c_str();
LOG_ECMA_MEM(ERROR) << oss.str().c_str();
EcmaVM *ecmaVm = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVm->GetFactory();
JSHandle<JSObject> error = factory->GetJSError(ErrorType::OOM_ERROR, oss.str().c_str());
thread->SetException(error.GetTaggedValue());
}
void BaseHeap::ThrowOutOfMemoryErrorForDefault(JSThread *thread, size_t size, std::string functionName,
bool NonMovableObjNearOOM)
{

View File

@ -281,6 +281,7 @@ public:
void WaitClearTaskFinished();
void ThrowOutOfMemoryError(JSThread *thread, size_t size, std::string functionName,
bool NonMovableObjNearOOM = false);
void SetMachineCodeOutOfMemoryError(JSThread *thread, size_t size, std::string functionName);
protected:
void FatalOutOfMemoryError(size_t size, std::string functionName);

View File

@ -448,14 +448,13 @@ private:
public:
static ApEntityId PUBLIC_API GetMethodAbcId(JSFunction *jsFunction);
static ApEntityId PUBLIC_API GetMethodAbcId(JSTaggedValue jsMethod);
void Reset(bool isEnable);
private:
ProfileType GetRecordProfileType(JSFunction *jsFunction, const CString &recordName);
ProfileType GetRecordProfileType(ApEntityId abcId, const CString &recordName);
ProfileType GetRecordProfileType(const std::shared_ptr<JSPandaFile> &pf, ApEntityId abcId,
const CString &recordName);
void Reset(bool isEnable);
bool IsSkippableObjectType(ProfileType type)
{
if (type.IsClassType() || type.IsConstructor() || type.IsPrototype()) {

View File

@ -16,18 +16,15 @@
#include "ecmascript/sustaining_js_handle.h"
namespace panda::ecmascript {
void SustainingJSHandle::Init()
SustainingJSHandle::SustainingJSHandle(EcmaVM *vm) : vm_(vm)
{
EcmaContext *context = vm_->GetJSThread()->GetCurrentEcmaContext();
context->AddSustainingJSHandle(this);
context_ = vm_->GetJSThread()->GetCurrentEcmaContext();
context_->AddSustainingJSHandle(this);
}
SustainingJSHandle::~SustainingJSHandle()
{
if (!isTerminate_) {
EcmaContext *context = vm_->GetJSThread()->GetCurrentEcmaContext();
context->RemoveSustainingJSHandle(this);
}
context_->RemoveSustainingJSHandle(this);
for (auto block : handleBlocks_) {
delete block;
}

View File

@ -24,10 +24,7 @@ namespace panda::ecmascript {
class SustainingJSHandle {
public:
SustainingJSHandle(EcmaVM *vm) : vm_(vm)
{
Init();
}
SustainingJSHandle(EcmaVM *vm);
~SustainingJSHandle();
template <typename T>
JSHandle<T> NewHandle(JSHandle<T> value)
@ -43,12 +40,7 @@ public:
void Iterate(const RootRangeVisitor &rv);
void SetTerminated()
{
isTerminate_ = true;
}
private:
void Init();
uintptr_t GetJsHandleSlot(JSTaggedType value);
uintptr_t Expand();
@ -58,7 +50,7 @@ private:
JSTaggedType *blockLimit_ { nullptr };
SustainingJSHandle *pre_ { nullptr };
SustainingJSHandle *next_ { nullptr };
std::atomic_bool isTerminate_ {false};
EcmaContext *context_ { nullptr };
static constexpr uint32_t BLOCK_SIZE = 256L;
std::vector<std::array<JSTaggedType, BLOCK_SIZE>*> handleBlocks_;

View File

@ -317,9 +317,9 @@
panda::ecmascript::pgo::PGOMethodInfo::CalcChecksum*;
panda::ecmascript::pgo::PGOProfiler::ProfileCreateObject*;
panda::ecmascript::pgo::PGOProfiler::GetMethodAbcId*;
panda::ecmascript::pgo::JITProfiler::ProfileBytecode*;
panda::ecmascript::pgo::PGOProfilerManager::GetInstance*;
panda::ecmascript::pgo::PGOProfilerManager::MergeApFiles*;
panda::ecmascript::JITProfiler::ProfileBytecode*;
panda::panda_file::ClassDataAccessor::ClassDataAccessor*;
panda::panda_file::CodeDataAccessor::CatchBlock::CatchBlock*;
panda::panda_file::CodeDataAccessor::CodeDataAccessor*;