mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
Execute TranslateClasses in other thread
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IA7GHA?from=project-issue Test: Build & Boot devices Signed-off-by: wupengyong <wupengyong@huawei.com> Change-Id: I463165678ac1b3079e7e22fc19088deae70563a6
This commit is contained in:
parent
5237fdd0f4
commit
f032571cb7
@ -198,6 +198,7 @@ void EcmaVM::PreFork()
|
||||
heap_->AdjustSpaceSizeForAppSpawn();
|
||||
heap_->GetReadOnlySpace()->SetReadOnly();
|
||||
heap_->DisableParallelGC();
|
||||
SetPostForked(false);
|
||||
SharedHeap::GetInstance()->DisableParallelGC(thread_);
|
||||
}
|
||||
|
||||
@ -207,6 +208,7 @@ void EcmaVM::PostFork()
|
||||
heap_->SetHeapMode(HeapMode::SHARE);
|
||||
GetAssociatedJSThread()->PostFork();
|
||||
Taskpool::GetCurrentTaskpool()->Initialize();
|
||||
SetPostForked(true);
|
||||
LOG_ECMA(INFO) << "multi-thread check enabled: " << options_.EnableThreadCheck();
|
||||
#if defined(JIT_ESCAPE_ENABLE) || defined(AOT_ESCAPE_ENABLE)
|
||||
SignalAllReg();
|
||||
|
@ -131,6 +131,21 @@ public:
|
||||
return initialized_;
|
||||
}
|
||||
|
||||
void SetPostForked(bool isPostForked)
|
||||
{
|
||||
isPostForked_ = isPostForked;
|
||||
}
|
||||
|
||||
bool IsPostForked() const
|
||||
{
|
||||
return isPostForked_;
|
||||
}
|
||||
|
||||
bool IsAsynTranslateClasses()
|
||||
{
|
||||
return IsPostForked() && GetJSOptions().IsAsyncLoadAbc();
|
||||
}
|
||||
|
||||
ObjectFactory *GetFactory() const
|
||||
{
|
||||
return factory_;
|
||||
@ -838,6 +853,7 @@ private:
|
||||
JSRuntimeOptions options_;
|
||||
bool icEnabled_ {true};
|
||||
bool initialized_ {false};
|
||||
bool isPostForked_ {false};
|
||||
GCStats *gcStats_ {nullptr};
|
||||
GCKeyStats *gcKeyStats_ {nullptr};
|
||||
EcmaStringTable *stringTable_ {nullptr};
|
||||
|
@ -185,7 +185,8 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
|
||||
"--compiler-opt-induction-variable: Enable induciton variable analysis for aot compiler. Default: 'false'\n"
|
||||
"--compiler-trace-induction-variable: Enable tracing induction variable for aot compiler. Default: 'false'\n"
|
||||
"--compiler-memory-analysis: Enable memory analysis for aot compiler. Default: 'true'\n"
|
||||
"--compiler-enable-jit-fast-compile: Enable jit fast compile. Default: 'false'\n\n";
|
||||
"--compiler-enable-jit-fast-compile: Enable jit fast compile. Default: 'false'\n"
|
||||
"--async-load-abc: Enable asynchronous load abc. Default: 'true'\n\n";
|
||||
|
||||
bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
{
|
||||
@ -312,6 +313,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
{"compiler-baselinejit-hotness-threshold", required_argument, nullptr, OPTION_COMPILER_BASELINEJIT_HOTNESS_THRESHOLD},
|
||||
{"compiler-force-baselinejit-compile-main", required_argument, nullptr, OPTION_COMPILER_FORCE_BASELINEJIT_COMPILE_MAIN},
|
||||
{"compiler-enable-jit-fast-compile", required_argument, nullptr, OPTION_COMPILER_ENABLE_JIT_FAST_COMPILE},
|
||||
{"async-load-abc", required_argument, nullptr, OPTION_ASYNC_LOAD_ABC},
|
||||
{nullptr, 0, nullptr, 0},
|
||||
};
|
||||
|
||||
@ -1188,6 +1190,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OPTION_ASYNC_LOAD_ABC:
|
||||
ret = ParseBoolParam(&argBool);
|
||||
if (ret) {
|
||||
SetAsyncLoadAbc(argBool);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ECMA(ERROR) << "Invalid option\n";
|
||||
return false;
|
||||
|
@ -196,6 +196,7 @@ enum CommandValues {
|
||||
OPTION_ENABLE_AOT_CRASH_ESCAPE,
|
||||
OPTION_COMPILER_ENABLE_JIT_FAST_COMPILE,
|
||||
OPTION_COMPILER_BASELINE_PGO,
|
||||
OPTION_ASYNC_LOAD_ABC,
|
||||
};
|
||||
static_assert(OPTION_SPLIT_ONE == 64);
|
||||
|
||||
@ -1808,6 +1809,16 @@ public:
|
||||
return enableFrameworkAOT_;
|
||||
}
|
||||
|
||||
void SetAsyncLoadAbc(bool value)
|
||||
{
|
||||
asyncLoadAbc_ = value;
|
||||
}
|
||||
|
||||
bool IsAsyncLoadAbc() const
|
||||
{
|
||||
return asyncLoadAbc_;
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr int32_t MAX_APP_COMPILE_METHOD_SIZE = 1_KB;
|
||||
|
||||
@ -1974,6 +1985,7 @@ private:
|
||||
bool enableJitFrame_{false};
|
||||
bool disableCodeSign_{false};
|
||||
bool enableBaselinePgo_{false};
|
||||
bool asyncLoadAbc_ {true};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -131,6 +131,7 @@ uint32_t JSPandaFile::GetOrInsertConstantPool(ConstPoolType type, uint32_t offse
|
||||
void JSPandaFile::InitializeUnMergedPF()
|
||||
{
|
||||
Span<const uint32_t> classIndexes = pf_->GetClasses();
|
||||
numClasses_ = classIndexes.size();
|
||||
JSRecordInfo info;
|
||||
for (const uint32_t index : classIndexes) {
|
||||
panda_file::File::EntityId classId(index);
|
||||
@ -172,6 +173,7 @@ void JSPandaFile::InitializeUnMergedPF()
|
||||
void JSPandaFile::InitializeMergedPF()
|
||||
{
|
||||
Span<const uint32_t> classIndexes = pf_->GetClasses();
|
||||
numClasses_ = classIndexes.size();
|
||||
for (const uint32_t index : classIndexes) {
|
||||
panda_file::File::EntityId classId(index);
|
||||
if (pf_->IsExternal(classId)) {
|
||||
@ -449,4 +451,94 @@ void JSPandaFile::ClearNameMap()
|
||||
recordNameMap_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
size_t JSPandaFile::GetClassAndMethodIndex(size_t *methodIdx)
|
||||
{
|
||||
LockHolder lock(classIndexMutex_);
|
||||
size_t result = 0;
|
||||
Span<const uint32_t> classIndexes = GetClasses();
|
||||
uint32_t index = 0;
|
||||
do {
|
||||
result = classIndex_++;
|
||||
if (result >= numClasses_) {
|
||||
return result;
|
||||
}
|
||||
index = classIndexes[result];
|
||||
} while (IsExternal(panda_file::File::EntityId(index)));
|
||||
|
||||
*methodIdx = methodIndex_;
|
||||
panda_file::File::EntityId classId(classIndexes[result]);
|
||||
panda_file::ClassDataAccessor cda(*pf_, classId);
|
||||
methodIndex_ += cda.GetMethodsNumber();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool JSPandaFile::TranslateClassesTask::Run([[maybe_unused]] uint32_t threadIndex)
|
||||
{
|
||||
jsPandaFile_->TranslateClass(thread_, *methodNamePtr_);
|
||||
jsPandaFile_->ReduceTaskCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSPandaFile::TranslateClass(JSThread *thread, const CString &methodName)
|
||||
{
|
||||
size_t methodIdx = 0;
|
||||
size_t classIdx = GetClassAndMethodIndex(&methodIdx);
|
||||
while (classIdx < numClasses_) {
|
||||
PandaFileTranslator::TranslateClass(thread, this, methodName, methodIdx, classIdx);
|
||||
classIdx = GetClassAndMethodIndex(&methodIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void JSPandaFile::PostInitializeMethodTask(JSThread *thread, const std::shared_ptr<CString> &methodNamePtr)
|
||||
{
|
||||
IncreaseTaskCount();
|
||||
Taskpool::GetCurrentTaskpool()->PostTask(
|
||||
std::make_unique<TranslateClassesTask>(thread->GetThreadId(), thread, this, methodNamePtr));
|
||||
}
|
||||
|
||||
void JSPandaFile::IncreaseTaskCount()
|
||||
{
|
||||
LockHolder holder(waitTranslateClassFinishedMutex_);
|
||||
runningTaskCount_++;
|
||||
}
|
||||
|
||||
void JSPandaFile::WaitTranslateClassTaskFinished()
|
||||
{
|
||||
LockHolder holder(waitTranslateClassFinishedMutex_);
|
||||
while (runningTaskCount_ > 0) {
|
||||
waitTranslateClassFinishedCV_.Wait(&waitTranslateClassFinishedMutex_);
|
||||
}
|
||||
}
|
||||
|
||||
void JSPandaFile::ReduceTaskCount()
|
||||
{
|
||||
LockHolder holder(waitTranslateClassFinishedMutex_);
|
||||
runningTaskCount_--;
|
||||
if (runningTaskCount_ == 0) {
|
||||
waitTranslateClassFinishedCV_.SignalAll();
|
||||
}
|
||||
}
|
||||
|
||||
void JSPandaFile::SetAllMethodLiteralToMap()
|
||||
{
|
||||
// async to optimize SetAllMethodLiteralToMap later
|
||||
MethodLiteral *methodLiterals = GetMethodLiterals();
|
||||
size_t methodIdx = 0;
|
||||
while (methodIdx < numMethods_) {
|
||||
MethodLiteral *methodLiteral = methodLiterals + (methodIdx++);
|
||||
SetMethodLiteralToMap(methodLiteral);
|
||||
}
|
||||
}
|
||||
|
||||
void JSPandaFile::TranslateClasses(JSThread *thread, const CString &methodName)
|
||||
{
|
||||
const std::shared_ptr<CString> methodNamePtr = std::make_shared<CString>(methodName);
|
||||
for (int i = 0; i < Taskpool::GetCurrentTaskpool()->GetTotalThreadNum(); i++) {
|
||||
PostInitializeMethodTask(thread, methodNamePtr);
|
||||
}
|
||||
TranslateClass(thread, methodName);
|
||||
WaitTranslateClassTaskFinished();
|
||||
SetAllMethodLiteralToMap();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ecmascript/jspandafile/method_literal.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/mem/c_containers.h"
|
||||
#include "ecmascript/taskpool/task.h"
|
||||
|
||||
#include "libpandafile/file-inl.h"
|
||||
#include "libpandafile/file_items.h"
|
||||
@ -89,6 +90,23 @@ public:
|
||||
JSPandaFile(const panda_file::File *pf, const CString &descriptor);
|
||||
~JSPandaFile();
|
||||
|
||||
class TranslateClassesTask : public Task {
|
||||
public:
|
||||
TranslateClassesTask(int32_t id, JSThread *thread, JSPandaFile *jsPandaFile,
|
||||
const std::shared_ptr<CString> &methodNamePtr)
|
||||
: Task(id), thread_(thread), jsPandaFile_(jsPandaFile), methodNamePtr_(methodNamePtr) {};
|
||||
~TranslateClassesTask() override = default;
|
||||
bool Run(uint32_t threadIndex) override;
|
||||
|
||||
NO_COPY_SEMANTIC(TranslateClassesTask);
|
||||
NO_MOVE_SEMANTIC(TranslateClassesTask);
|
||||
|
||||
private:
|
||||
JSThread *thread_ {nullptr};
|
||||
JSPandaFile *jsPandaFile_ {nullptr};
|
||||
std::shared_ptr<CString> methodNamePtr_;
|
||||
};
|
||||
|
||||
const CString &GetJSPandaFileDesc() const
|
||||
{
|
||||
return desc_;
|
||||
@ -440,10 +458,29 @@ public:
|
||||
}
|
||||
|
||||
void ClearNameMap();
|
||||
|
||||
void TranslateClasses(JSThread *thread, const CString &methodName);
|
||||
|
||||
private:
|
||||
void InitializeUnMergedPF();
|
||||
void InitializeMergedPF();
|
||||
|
||||
void WaitTranslateClassTaskFinished();
|
||||
|
||||
void NotifyTranslateClassTaskCompleted();
|
||||
|
||||
void IncreaseTaskCount();
|
||||
|
||||
void TranslateClass(JSThread *thread, const CString &methodName);
|
||||
|
||||
void PostInitializeMethodTask(JSThread *thread, const std::shared_ptr<CString> &methodNamePtr);
|
||||
|
||||
void ReduceTaskCount();
|
||||
|
||||
void SetAllMethodLiteralToMap();
|
||||
|
||||
size_t GetClassAndMethodIndex(size_t *methodIdx);
|
||||
|
||||
static constexpr size_t VERSION_SIZE = 4;
|
||||
static constexpr std::array<uint8_t, VERSION_SIZE> OLD_VERSION {0, 0, 0, 2};
|
||||
|
||||
@ -457,9 +494,16 @@ private:
|
||||
CUnorderedMap<uint32_t, CString> recordNameMap_;
|
||||
Mutex methodNameMapMutex_;
|
||||
Mutex recordNameMapMutex_;
|
||||
Mutex waitTranslateClassFinishedMutex_;
|
||||
Mutex classIndexMutex_;
|
||||
ConditionVariable waitTranslateClassFinishedCV_;
|
||||
uint32_t runningTaskCount_ {0};
|
||||
size_t classIndex_ {0};
|
||||
size_t methodIndex_ {0};
|
||||
|
||||
CUnorderedMap<uint32_t, uint64_t> constpoolMap_;
|
||||
uint32_t numMethods_ {0};
|
||||
uint32_t numClasses_ {0};
|
||||
MethodLiteral *methodLiterals_ {nullptr};
|
||||
CString desc_;
|
||||
uint32_t anFileInfoIndex_ {INVALID_INDEX};
|
||||
|
@ -544,7 +544,11 @@ std::shared_ptr<JSPandaFile> JSPandaFileManager::GenerateJSPandaFile(JSThread *t
|
||||
methodName = JSPandaFile::ENTRY_FUNCTION_NAME;
|
||||
}
|
||||
}
|
||||
PandaFileTranslator::TranslateClasses(thread, newJsPandaFile.get(), methodName);
|
||||
if (newJsPandaFile->IsNewVersion() && vm->IsAsynTranslateClasses()) {
|
||||
newJsPandaFile->TranslateClasses(thread, methodName);
|
||||
} else {
|
||||
PandaFileTranslator::TranslateClasses(thread, newJsPandaFile.get(), methodName);
|
||||
}
|
||||
|
||||
{
|
||||
LockHolder lock(jsPandaFileLock_);
|
||||
|
@ -102,6 +102,47 @@ void PandaFileTranslator::TranslateClasses(const JSThread *thread, JSPandaFile *
|
||||
}
|
||||
}
|
||||
|
||||
void PandaFileTranslator::TranslateClass(const JSThread *thread, JSPandaFile *jsPandaFile,
|
||||
const CString &methodName, size_t methodIdx, size_t classIdx)
|
||||
{
|
||||
ASSERT(jsPandaFile != nullptr && jsPandaFile->GetMethodLiterals() != nullptr);
|
||||
MethodLiteral *methodLiterals = jsPandaFile->GetMethodLiterals();
|
||||
const panda_file::File *pf = jsPandaFile->GetPandaFile();
|
||||
Span<const uint32_t> classIndexes = jsPandaFile->GetClasses();
|
||||
const uint32_t index = classIndexes[classIdx];
|
||||
panda_file::File::EntityId classId(index);
|
||||
panda_file::ClassDataAccessor cda(*pf, classId);
|
||||
CString recordName = JSPandaFile::ParseEntryPoint(utf::Mutf8AsCString(cda.GetDescriptor()));
|
||||
bool isUpdateMainMethodIndex = false;
|
||||
cda.EnumerateMethods([thread, jsPandaFile, methodLiterals, &methodIdx, pf, &methodName,
|
||||
&recordName, &isUpdateMainMethodIndex]
|
||||
(panda_file::MethodDataAccessor &mda) {
|
||||
auto methodId = mda.GetMethodId();
|
||||
CString name = reinterpret_cast<const char *>(jsPandaFile->GetStringData(mda.GetNameId()).data);
|
||||
auto methodOffset = methodId.GetOffset();
|
||||
if (jsPandaFile->IsBundlePack()) {
|
||||
if (!isUpdateMainMethodIndex && name == methodName) {
|
||||
jsPandaFile->UpdateMainMethodIndex(methodOffset);
|
||||
isUpdateMainMethodIndex = true;
|
||||
}
|
||||
} else {
|
||||
if (!isUpdateMainMethodIndex && JSPandaFile::IsEntryOrPatch(name)) {
|
||||
jsPandaFile->UpdateMainMethodIndex(methodOffset, recordName);
|
||||
isUpdateMainMethodIndex = true;
|
||||
}
|
||||
}
|
||||
|
||||
MethodLiteral *methodLiteral = methodLiterals + (methodIdx++);
|
||||
InitializeMemory(methodLiteral, methodId);
|
||||
methodLiteral->Initialize(jsPandaFile, thread);
|
||||
// IsNewVersion
|
||||
panda_file::IndexAccessor indexAccessor(*pf, methodId);
|
||||
panda_file::FunctionKind funcKind = indexAccessor.GetFunctionKind();
|
||||
FunctionKind kind = JSPandaFile::GetFunctionKind(funcKind);
|
||||
methodLiteral->SetFunctionKind(kind);
|
||||
});
|
||||
}
|
||||
|
||||
JSHandle<Program> PandaFileTranslator::GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile,
|
||||
std::string_view entryPoint)
|
||||
{
|
||||
|
@ -38,6 +38,8 @@ public:
|
||||
static JSHandle<Program> GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile,
|
||||
std::string_view entryPoint);
|
||||
static void TranslateClasses(const JSThread *thread, JSPandaFile *jsPandaFile, const CString &methodName);
|
||||
static void TranslateClass(const JSThread *thread, JSPandaFile *jsPandaFile, const CString &methodName,
|
||||
size_t methodIdx, size_t classIdx);
|
||||
|
||||
private:
|
||||
static JSHandle<Program> GenerateProgramInternal(EcmaVM *vm, MethodLiteral *mainMethodLiteral,
|
||||
|
Loading…
Reference in New Issue
Block a user