mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
[JIT] support concurrent compile
Change-Id: I3d1db40eb479434875a9952c0f5f9279ff67cdaa Signed-off-by: xiaoweidong <xiaoweidong@huawei.com>
This commit is contained in:
parent
ecfcf3e49b
commit
b27afd924d
2
BUILD.gn
2
BUILD.gn
@ -693,6 +693,8 @@ ecma_source = [
|
||||
"ecmascript/intl/locale_helper.cpp",
|
||||
"ecmascript/jit/jit.cpp",
|
||||
"ecmascript/jit/jit_task.cpp",
|
||||
"ecmascript/jit/jit_thread.cpp",
|
||||
"ecmascript/jit/persistent_handles.cpp",
|
||||
"ecmascript/jobs/micro_job_queue.cpp",
|
||||
"ecmascript/jspandafile/js_pandafile.cpp",
|
||||
"ecmascript/jspandafile/js_pandafile_manager.cpp",
|
||||
|
@ -1142,4 +1142,57 @@ JSTaggedValue BuiltinsArkTools::ClearFunctionFeedback([[maybe_unused]] EcmaRunti
|
||||
LOG_ECMA(DEBUG) << "Enter ClearFunctionFeedback()";
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::JitCompileSync(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
JSThread *thread = info->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
|
||||
if (!thisValue->IsJSFunction()) {
|
||||
return JSTaggedValue::False();
|
||||
}
|
||||
JSHandle<JSFunction> jsFunction(thisValue);
|
||||
Jit::Compile(thread->GetEcmaVM(), jsFunction, MachineCode::INVALID_OSR_OFFSET, JitCompileMode::SYNC);
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::JitCompileAsync(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
JSThread *thread = info->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
|
||||
if (!thisValue->IsJSFunction()) {
|
||||
return JSTaggedValue::False();
|
||||
}
|
||||
JSHandle<JSFunction> jsFunction(thisValue);
|
||||
Jit::Compile(thread->GetEcmaVM(), jsFunction, MachineCode::INVALID_OSR_OFFSET, JitCompileMode::ASYNC);
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::WaitJitCompileFinish(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
JSThread *thread = info->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
|
||||
if (!thisValue->IsJSFunction()) {
|
||||
return JSTaggedValue::False();
|
||||
}
|
||||
JSHandle<JSFunction> jsFunction(thisValue);
|
||||
|
||||
auto jit = Jit::GetInstance();
|
||||
if (!jit->IsEnable()) {
|
||||
return JSTaggedValue::False();
|
||||
}
|
||||
if (jsFunction->GetMachineCode() == JSTaggedValue::Undefined()) {
|
||||
return JSTaggedValue::False();
|
||||
}
|
||||
while (jsFunction->GetMachineCode() == JSTaggedValue::Hole()) {
|
||||
// just spin check
|
||||
thread->CheckSafepoint();
|
||||
}
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
@ -121,6 +121,11 @@
|
||||
V("isBeingInterpreted", IsBeingInterpreted, 0, INVALID) \
|
||||
V("clearFunctionFeedback", ClearFunctionFeedback, 1, INVALID)
|
||||
|
||||
#define BUILTIN_ARK_TOOLS_FUNCTIONS_JITCOMPILE(V) \
|
||||
V("jitCompileSync", JitCompileSync, 1, INVALID) \
|
||||
V("jitCompileAsync", JitCompileAsync, 1, INVALID) \
|
||||
V("waitJitCompileFinish", WaitJitCompileFinish, 1, INVALID)
|
||||
|
||||
|
||||
#ifdef ECMASCRIPT_SUPPORT_CPUPROFILER
|
||||
#define BUILTIN_ARK_TOOLS_FUNCTIONS_CPUPROFILER(V) \
|
||||
@ -133,7 +138,8 @@
|
||||
#define BUILTIN_ARK_TOOLS_FUNCTIONS(V) \
|
||||
BUILTIN_ARK_TOOLS_FUNCTIONS_COMMON(V) \
|
||||
BUILTIN_ARK_TOOLS_FUNCTIONS_CPUPROFILER(V) \
|
||||
BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V)
|
||||
BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V) \
|
||||
BUILTIN_ARK_TOOLS_FUNCTIONS_JITCOMPILE(V)
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
class BuiltinsArkTools : public base::BuiltinsBase {
|
||||
@ -342,6 +348,10 @@ public:
|
||||
|
||||
static JSTaggedValue ClearFunctionFeedback(EcmaRuntimeCallInfo *info);
|
||||
|
||||
static JSTaggedValue JitCompileSync(EcmaRuntimeCallInfo *info);
|
||||
static JSTaggedValue JitCompileAsync(EcmaRuntimeCallInfo *info);
|
||||
static JSTaggedValue WaitJitCompileFinish(EcmaRuntimeCallInfo *info);
|
||||
|
||||
static Span<const base::BuiltinFunctionEntry> GetArkToolsFunctions()
|
||||
{
|
||||
return Span<const base::BuiltinFunctionEntry>(ARK_TOOLS_FUNCTIONS);
|
||||
|
@ -78,6 +78,7 @@ config("include_maple") {
|
||||
|
||||
libark_jsoptimizer_sources = [
|
||||
"access_object_stub_builder.cpp",
|
||||
"aot_compilation_env.cpp",
|
||||
"aot_compiler_preprocessor.cpp",
|
||||
"argument_accessor.cpp",
|
||||
"array_bounds_check_elimination.cpp",
|
||||
@ -114,6 +115,7 @@ libark_jsoptimizer_sources = [
|
||||
"combined_pass_visitor.cpp",
|
||||
"common_stubs.cpp",
|
||||
"compilation_driver.cpp",
|
||||
"compilation_env.cpp",
|
||||
"compiler_log.cpp",
|
||||
"constant_folding.cpp",
|
||||
"dead_code_elimination.cpp",
|
||||
@ -136,6 +138,7 @@ libark_jsoptimizer_sources = [
|
||||
"interpreter_stub.cpp",
|
||||
"ir_builder.cpp",
|
||||
"ir_module.cpp",
|
||||
"jit_compilation_env.cpp",
|
||||
"jit_compiler.cpp",
|
||||
"later_elimination.cpp",
|
||||
"lcr_circuit_builder.cpp",
|
||||
|
108
ecmascript/compiler/aot_compilation_env.cpp
Normal file
108
ecmascript/compiler/aot_compilation_env.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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/compiler/aot_compilation_env.h"
|
||||
#include "ecmascript/ecma_context.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/ts_types/ts_manager.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
AOTCompilationEnv::AOTCompilationEnv(EcmaVM *vm) : CompilationEnv(vm)
|
||||
{
|
||||
tsManager_ = thread_->GetCurrentEcmaContext()->GetTSManager(),
|
||||
ptManager_ = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
}
|
||||
|
||||
JSRuntimeOptions &AOTCompilationEnv::GetJSOptions()
|
||||
{
|
||||
return vm_->GetJSOptions();
|
||||
}
|
||||
|
||||
JSHandle<GlobalEnv> AOTCompilationEnv::GetGlobalEnv() const
|
||||
{
|
||||
return vm_->GetGlobalEnv();
|
||||
}
|
||||
|
||||
const CMap<ElementsKind, ConstantIndex> &AOTCompilationEnv::GetArrayHClassIndexMap() const
|
||||
{
|
||||
return thread_->GetArrayHClassIndexMap();
|
||||
}
|
||||
|
||||
const BuiltinHClassEntries &AOTCompilationEnv::GetBuiltinHClassEntries() const
|
||||
{
|
||||
return thread_->GetBuiltinHClassEntries();
|
||||
}
|
||||
|
||||
JSHClass *AOTCompilationEnv::GetBuiltinPrototypeHClass(BuiltinTypeId type) const
|
||||
{
|
||||
return thread_->GetBuiltinPrototypeHClass(type);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id) const
|
||||
{
|
||||
return thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile, id);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::FindConstpool(const JSPandaFile *jsPandaFile, int32_t index) const
|
||||
{
|
||||
return thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile, index);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::FindOrCreateUnsharedConstpool(const uint32_t methodOffset) const
|
||||
{
|
||||
JSTaggedValue cp = ptManager_->GetConstantPoolByMethodOffset(methodOffset);
|
||||
return thread_->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(cp);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool) const
|
||||
{
|
||||
return thread_->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(sharedConstpool);
|
||||
}
|
||||
|
||||
JSHandle<ConstantPool> AOTCompilationEnv::FindOrCreateConstPool(const JSPandaFile *jsPandaFile,
|
||||
panda_file::File::EntityId id)
|
||||
{
|
||||
return thread_->GetCurrentEcmaContext()->FindOrCreateConstPool(jsPandaFile, id);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::GetConstantPoolByMethodOffset(const uint32_t methodOffset) const
|
||||
{
|
||||
return ptManager_->GetConstantPoolByMethodOffset(methodOffset);
|
||||
}
|
||||
|
||||
const GlobalEnvConstants *AOTCompilationEnv::GlobalConstants() const
|
||||
{
|
||||
return thread_->GlobalConstants();
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::GetArrayLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const
|
||||
{
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::ARRAY_LITERAL>(thread_, constpool, index, entry);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::GetObjectLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const
|
||||
{
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::OBJECT_LITERAL>(thread_, constpool, index, entry);
|
||||
}
|
||||
|
||||
panda_file::File::EntityId AOTCompilationEnv::GetIdFromCache(JSTaggedValue constpool, uint32_t index) const
|
||||
{
|
||||
return ConstantPool::GetIdFromCache(constpool, index);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const
|
||||
{
|
||||
return ptManager_->GetStringFromConstantPool(methodOffset, cpIdx);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
60
ecmascript/compiler/aot_compilation_env.h
Normal file
60
ecmascript/compiler/aot_compilation_env.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_COMPILER_AOT_COMPILATION_ENV_H
|
||||
#define ECMASCRIPT_COMPILER_AOT_COMPILATION_ENV_H
|
||||
#include "ecmascript/compiler/compilation_env.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class AOTCompilationEnv final : public CompilationEnv {
|
||||
public:
|
||||
AOTCompilationEnv(EcmaVM *vm);
|
||||
~AOTCompilationEnv() = default;
|
||||
bool IsAotCompiler() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
JSRuntimeOptions &GetJSOptions() override;
|
||||
|
||||
// thread
|
||||
const CMap<ElementsKind, ConstantIndex> &GetArrayHClassIndexMap() const override;
|
||||
const BuiltinHClassEntries &GetBuiltinHClassEntries() const override;
|
||||
JSHClass *GetBuiltinPrototypeHClass(BuiltinTypeId type) const override;
|
||||
|
||||
// context
|
||||
JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id) const override;
|
||||
JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, int32_t index) const override;
|
||||
JSTaggedValue FindOrCreateUnsharedConstpool(const uint32_t methodOffset) const override;
|
||||
JSTaggedValue FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool) const override;
|
||||
JSHandle<ConstantPool> FindOrCreateConstPool(const JSPandaFile *jsPandaFile,
|
||||
panda_file::File::EntityId id) override;
|
||||
JSTaggedValue GetConstantPoolByMethodOffset(const uint32_t methodOffset) const override;
|
||||
|
||||
// ConstantPool
|
||||
JSTaggedValue GetArrayLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const override;
|
||||
JSTaggedValue GetObjectLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const override;
|
||||
panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index) const override;
|
||||
|
||||
// GlobalEnv
|
||||
JSHandle<GlobalEnv> GetGlobalEnv() const override;
|
||||
|
||||
// GlobalConstants
|
||||
const GlobalEnvConstants *GlobalConstants() const override;
|
||||
|
||||
JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const override;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_COMPILER_AOT_COMPILATION_ENV_H
|
@ -22,6 +22,7 @@
|
||||
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
||||
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
#include "ecmascript/compiler/aot_compilation_env.h"
|
||||
#include "ecmascript/ecma_string.h"
|
||||
#include "ecmascript/js_runtime_options.h"
|
||||
#include "ecmascript/log.h"
|
||||
@ -110,6 +111,7 @@ int Main(const int argc, const char **argv)
|
||||
}
|
||||
|
||||
{
|
||||
AOTCompilationEnv aotCompilationEnv(vm);
|
||||
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
|
||||
LocalScope scope(vm);
|
||||
arg_list_t pandaFileNames {};
|
||||
@ -170,7 +172,7 @@ int Main(const int argc, const char **argv)
|
||||
.EnableInductionVariableAnalysis(cOptions.isEnableInductionVariableAnalysis_)
|
||||
.Build();
|
||||
|
||||
PassManager passManager(vm,
|
||||
PassManager passManager(&aotCompilationEnv,
|
||||
cOptions.triple_,
|
||||
cOptions.optLevel_,
|
||||
cOptions.relocMode_,
|
||||
@ -193,7 +195,7 @@ int Main(const int argc, const char **argv)
|
||||
}
|
||||
vm->GetJSOptions().SetCompilerEnableLiteCG(isEnableLiteCG);
|
||||
|
||||
AOTFileGenerator generator(&log, &logList, vm, cOptions.triple_, isEnableLiteCG);
|
||||
AOTFileGenerator generator(&log, &logList, &aotCompilationEnv, cOptions.triple_, isEnableLiteCG);
|
||||
|
||||
CompileValidFiles(passManager, generator, ret, fileInfos);
|
||||
std::string appSignature = cPreprocessor.GetMainPkgArgsAppSignature();
|
||||
|
@ -250,7 +250,7 @@ void AotCompilerPreprocessor::RecordArrayElement(const CompilationOptions &cOpti
|
||||
JSPandaFile *jsPandaFile = fileInfo.jsPandaFile_.get();
|
||||
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
|
||||
ptManager->SetCurCompilationFile(jsPandaFile);
|
||||
BytecodeInfoCollector collector(vm_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
|
||||
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
|
||||
cOptions.isEnableCollectLiteralInfo_);
|
||||
BCInfo &bytecodeInfo = collector.GetBytecodeInfo();
|
||||
const PGOBCInfo *bcInfo = collector.GetPGOBCInfo();
|
||||
@ -284,7 +284,7 @@ void AotCompilerPreprocessor::GeneratePGOTypes(const CompilationOptions &cOption
|
||||
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
|
||||
for (const AbcFileInfo &fileInfo : fileInfos_) {
|
||||
JSPandaFile *jsPandaFile = fileInfo.jsPandaFile_.get();
|
||||
BytecodeInfoCollector collector(vm_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
|
||||
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
|
||||
cOptions.isEnableCollectLiteralInfo_);
|
||||
PGOTypeParser parser(profilerDecoder_, ptManager);
|
||||
parser.CreatePGOType(collector);
|
||||
@ -366,7 +366,7 @@ void AotCompilerPreprocessor::GenerateMethodMap(CompilationOptions &cOptions)
|
||||
jsPandaFileManager->EnumerateNonVirtualJSPandaFiles(
|
||||
[this, &cOptions] (std::shared_ptr<JSPandaFile> jsPandaFilePtr) {
|
||||
JSPandaFile *jsPandaFile = jsPandaFilePtr.get();
|
||||
BytecodeInfoCollector collector(vm_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
|
||||
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
|
||||
cOptions.isEnableCollectLiteralInfo_);
|
||||
BCInfo &bytecodeInfo = collector.GetBytecodeInfo();
|
||||
const auto &methodPcInfos = bytecodeInfo.GetMethodPcInfos();
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "macros.h"
|
||||
#include "ecmascript/compiler/aot_compilation_env.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class OhosPkgArgs;
|
||||
@ -99,7 +100,8 @@ public:
|
||||
runtimeOptions_(runtimeOptions),
|
||||
pkgsArgs_(pkgsArgs),
|
||||
profilerDecoder_(profilerDecoder),
|
||||
pandaFileNames_(pandaFileNames) {};
|
||||
pandaFileNames_(pandaFileNames),
|
||||
aotCompilationEnv_(vm) {};
|
||||
|
||||
~AotCompilerPreprocessor() = default;
|
||||
|
||||
@ -206,6 +208,7 @@ private:
|
||||
arg_list_t &pandaFileNames_;
|
||||
CVector<AbcFileInfo> fileInfos_;
|
||||
CallMethodFlagMap callMethodFlagMap_;
|
||||
AOTCompilationEnv aotCompilationEnv_;
|
||||
friend class OhosPkgArgs;
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -30,31 +30,31 @@ static T *InitializeMemory(T *mem, Args... args)
|
||||
return new (mem) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
BytecodeInfoCollector::BytecodeInfoCollector(EcmaVM *vm, JSPandaFile *jsPandaFile, PGOProfilerDecoder &pfDecoder,
|
||||
BytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
|
||||
PGOProfilerDecoder &pfDecoder,
|
||||
size_t maxAotMethodSize, bool enableCollectLiteralInfo)
|
||||
: vm_(vm),
|
||||
: compilationEnv_(env),
|
||||
jsPandaFile_(jsPandaFile),
|
||||
bytecodeInfo_(maxAotMethodSize),
|
||||
pfDecoder_(pfDecoder),
|
||||
snapshotCPData_(vm, jsPandaFile, &pfDecoder),
|
||||
snapshotCPData_(new SnapshotConstantPoolData(env->GetEcmaVM(), jsPandaFile, &pfDecoder)),
|
||||
enableCollectLiteralInfo_(enableCollectLiteralInfo)
|
||||
{
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->SetBytecodeInfoCollector(this);
|
||||
compilationEnv_->GetTSManager()->SetBytecodeInfoCollector(this);
|
||||
ProcessClasses();
|
||||
ProcessEnvs();
|
||||
}
|
||||
|
||||
BytecodeInfoCollector::BytecodeInfoCollector(EcmaVM *vm, JSPandaFile *jsPandaFile, JSHandle<JSFunction> &jsFunction,
|
||||
BytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
|
||||
PGOProfilerDecoder &pfDecoder, bool enableCollectLiteralInfo)
|
||||
: vm_(vm),
|
||||
: compilationEnv_(env),
|
||||
jsPandaFile_(jsPandaFile),
|
||||
bytecodeInfo_(1),
|
||||
pfDecoder_(pfDecoder),
|
||||
snapshotCPData_(vm, jsPandaFile, &pfDecoder),
|
||||
snapshotCPData_(nullptr), // jit no need
|
||||
enableCollectLiteralInfo_(enableCollectLiteralInfo)
|
||||
{
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->SetBytecodeInfoCollector(this);
|
||||
ProcessMethod(jsFunction);
|
||||
ProcessMethod();
|
||||
ProcessEnvs();
|
||||
}
|
||||
|
||||
@ -64,9 +64,12 @@ BytecodeInfoCollector::~BytecodeInfoCollector()
|
||||
delete envManager_;
|
||||
envManager_ = nullptr;
|
||||
}
|
||||
auto tsManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
|
||||
tsManager->PrintTypeInfo(jsPandaFile_);
|
||||
tsManager->SetBytecodeInfoCollector(nullptr);
|
||||
|
||||
if (compilationEnv_->IsAotCompiler()) {
|
||||
auto tsManager = compilationEnv_->GetTSManager();
|
||||
tsManager->PrintTypeInfo(jsPandaFile_);
|
||||
tsManager->SetBytecodeInfoCollector(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeInfoCollector::ProcessEnvs()
|
||||
@ -105,7 +108,7 @@ void BytecodeInfoCollector::ProcessClasses()
|
||||
CollectFunctionTypeId(methodId);
|
||||
|
||||
// Generate all constpool
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->FindOrCreateConstPool(jsPandaFile_, methodId);
|
||||
compilationEnv_->FindOrCreateConstPool(jsPandaFile_, methodId);
|
||||
|
||||
auto methodOffset = methodId.GetOffset();
|
||||
CString name = reinterpret_cast<const char *>(jsPandaFile_->GetStringData(mda.GetNameId()).data);
|
||||
@ -164,33 +167,23 @@ void BytecodeInfoCollector::ProcessClasses()
|
||||
<< methodIdx;
|
||||
}
|
||||
|
||||
void BytecodeInfoCollector::ProcessMethod(JSHandle<JSFunction> &jsFunction)
|
||||
void BytecodeInfoCollector::ProcessMethod()
|
||||
{
|
||||
auto &recordNames = bytecodeInfo_.GetRecordNames();
|
||||
auto &methodPcInfos = bytecodeInfo_.GetMethodPcInfos();
|
||||
MethodLiteral *methodLiteral = compilationEnv_->GetMethodLiteral();
|
||||
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
const panda_file::File *pf = jsPandaFile_->GetPandaFile();
|
||||
panda_file::File::EntityId methodIdx = method->GetMethodId();
|
||||
panda_file::File::EntityId methodIdx = methodLiteral->GetMethodId();
|
||||
panda_file::MethodDataAccessor mda(*pf, methodIdx);
|
||||
const CString recordName = jsPandaFile_->GetRecordNameWithBundlePack(methodIdx);
|
||||
recordNames.emplace_back(recordName);
|
||||
auto methodId = mda.GetMethodId();
|
||||
CollectFunctionTypeId(methodId);
|
||||
|
||||
// Generate all constpool
|
||||
[[maybe_unused]] JSTaggedValue constpool =
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, methodId);
|
||||
ASSERT(!constpool.IsHole());
|
||||
|
||||
auto methodOffset = methodId.GetOffset();
|
||||
CString name = reinterpret_cast<const char *>(jsPandaFile_->GetStringData(mda.GetNameId()).data);
|
||||
if (JSPandaFile::IsEntryOrPatch(name)) {
|
||||
}
|
||||
|
||||
MethodLiteral *methodLiteral = method->GetMethodLiteral();
|
||||
ASSERT(jsPandaFile_->IsNewVersion());
|
||||
|
||||
auto methodOffset = methodId.GetOffset();
|
||||
auto codeId = mda.GetCodeId();
|
||||
ASSERT(codeId.has_value());
|
||||
panda_file::CodeDataAccessor codeDataAccessor(*pf, codeId.value());
|
||||
@ -204,20 +197,13 @@ void BytecodeInfoCollector::ProcessMethod(JSHandle<JSFunction> &jsFunction)
|
||||
CollectMethodPcsFromBC(codeSize, insns, methodLiteral, classNameVec,
|
||||
recordName, methodOffset, classConstructIndexes);
|
||||
processedMethod[methodOffset] = std::make_pair(methodPcInfos.size() - 1, methodOffset);
|
||||
// collect className and literal offset for type infer
|
||||
if (EnableCollectLiteralInfo()) {
|
||||
CollectClassLiteralInfo(methodLiteral, classNameVec);
|
||||
}
|
||||
|
||||
SetMethodPcInfoIndex(methodOffset, processedMethod[methodOffset]);
|
||||
// class Construct need to use new target, can not fastcall
|
||||
if (method->GetFunctionKind() == FunctionKind::CLASS_CONSTRUCTOR) {
|
||||
if (methodLiteral->GetFunctionKind() == FunctionKind::CLASS_CONSTRUCTOR) {
|
||||
methodLiteral->SetIsFastCall(false);
|
||||
bytecodeInfo_.ModifyMethodOffsetToCanFastCall(methodIdx.GetOffset(), false);
|
||||
}
|
||||
// Collect import(infer-needed) and export relationship among all records.
|
||||
CollectRecordReferenceREL();
|
||||
RearrangeInnerMethods();
|
||||
}
|
||||
|
||||
void BytecodeInfoCollector::CollectClassLiteralInfo(const MethodLiteral *method,
|
||||
@ -228,7 +214,7 @@ void BytecodeInfoCollector::CollectClassLiteralInfo(const MethodLiteral *method,
|
||||
|
||||
if (classOffsetVec.size() == classNameVec.size()) {
|
||||
for (uint32_t i = 0; i < classOffsetVec.size(); i++) {
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->AddElementToClassNameMap(
|
||||
compilationEnv_->GetTSManager()->AddElementToClassNameMap(
|
||||
jsPandaFile_, classOffsetVec[i], classNameVec[i]);
|
||||
}
|
||||
}
|
||||
@ -322,8 +308,12 @@ void BytecodeInfoCollector::CollectMethodPcsFromBC(const uint32_t insSz, const u
|
||||
if (!fastCallFlag) {
|
||||
canFastCall = false;
|
||||
}
|
||||
CollectModuleInfoFromBC(bcIns, method, recordName);
|
||||
snapshotCPData_.Record(bcIns, bcIndex, recordName, method);
|
||||
if (compilationEnv_->IsAotCompiler()) {
|
||||
CollectModuleInfoFromBC(bcIns, method, recordName);
|
||||
}
|
||||
if (snapshotCPData_ != nullptr) {
|
||||
snapshotCPData_->Record(bcIns, bcIndex, recordName, method);
|
||||
}
|
||||
pgoBCInfo_.Record(bcIns, bcIndex, recordName, method);
|
||||
if (noGC && !bytecodes_.GetBytecodeMetaData(curPc).IsNoGC()) {
|
||||
noGC = false;
|
||||
@ -633,10 +623,11 @@ void BytecodeInfoCollector::CollectImportIndexs(uint32_t methodOffset, uint32_t
|
||||
|
||||
void BytecodeInfoCollector::CollectExportIndexs(const CString &recordName, uint32_t index)
|
||||
{
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
ASSERT(compilationEnv_->IsAotCompiler());
|
||||
JSThread *thread = compilationEnv_->GetJSThread();
|
||||
ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
CString exportLocalName = "*default*";
|
||||
ObjectFactory *objFactory = vm_->GetFactory();
|
||||
ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
JSHandle<SourceTextModule> currentModule = moduleManager->HostGetImportedModule(recordName);
|
||||
if (currentModule->GetLocalExportEntries().IsUndefined()) {
|
||||
@ -675,7 +666,8 @@ void BytecodeInfoCollector::CollectExportIndexs(const CString &recordName, uint3
|
||||
bool BytecodeInfoCollector::CheckExportNameAndClassType(const CString &recordName,
|
||||
const JSHandle<EcmaString> &exportStr)
|
||||
{
|
||||
auto tsManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
|
||||
ASSERT(compilationEnv_->IsAotCompiler());
|
||||
auto tsManager = compilationEnv_->GetTSManager();
|
||||
JSHandle<TaggedArray> exportTypeTable = tsManager->GetExportTableFromLiteral(jsPandaFile_, recordName);
|
||||
uint32_t length = exportTypeTable->GetLength();
|
||||
for (uint32_t i = 0; i < length; i = i + 2) { // 2: skip a pair of key and value
|
||||
@ -717,7 +709,8 @@ void BytecodeInfoCollector::CollectRecordReferenceREL()
|
||||
*/
|
||||
void BytecodeInfoCollector::CollectRecordImportInfo(const CString &recordName)
|
||||
{
|
||||
auto thread = vm_->GetJSThread();
|
||||
ASSERT(compilationEnv_->IsAotCompiler());
|
||||
auto thread = compilationEnv_->GetJSThread();
|
||||
ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
JSHandle<SourceTextModule> currentModule = moduleManager->HostGetImportedModule(recordName);
|
||||
@ -747,7 +740,8 @@ void BytecodeInfoCollector::CollectRecordImportInfo(const CString &recordName)
|
||||
// For type infer under retranmission (export * from "xxx"), we collect the star export records in this function.
|
||||
void BytecodeInfoCollector::CollectRecordExportInfo(const CString &recordName)
|
||||
{
|
||||
auto thread = vm_->GetJSThread();
|
||||
ASSERT(compilationEnv_->IsAotCompiler());
|
||||
auto thread = compilationEnv_->GetJSThread();
|
||||
ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
JSHandle<SourceTextModule> currentModule = moduleManager->HostGetImportedModule(recordName);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile.h"
|
||||
#include "ecmascript/jspandafile/method_literal.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
|
||||
#include "ecmascript/compiler/compilation_env.h"
|
||||
#include "libpandafile/bytecode_instruction-inl.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
@ -657,10 +658,10 @@ private:
|
||||
|
||||
class BytecodeInfoCollector {
|
||||
public:
|
||||
BytecodeInfoCollector(EcmaVM *vm, JSPandaFile *jsPandaFile, PGOProfilerDecoder &pfDecoder,
|
||||
BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile, PGOProfilerDecoder &pfDecoder,
|
||||
size_t maxAotMethodSize, bool enableCollectLiteralInfo);
|
||||
|
||||
BytecodeInfoCollector(EcmaVM *vm, JSPandaFile *jsPandaFile, JSHandle<JSFunction> &jsFunction,
|
||||
BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
|
||||
PGOProfilerDecoder &pfDecoder, bool enableCollectLiteralInfo);
|
||||
|
||||
~BytecodeInfoCollector();
|
||||
@ -694,7 +695,7 @@ public:
|
||||
|
||||
void StoreDataToGlobalData(SnapshotGlobalData &snapshotData)
|
||||
{
|
||||
snapshotCPData_.StoreDataToGlobalData(snapshotData, GetSkippedMethodSet());
|
||||
snapshotCPData_->StoreDataToGlobalData(snapshotData, GetSkippedMethodSet());
|
||||
}
|
||||
|
||||
const std::set<uint32_t>& GetSkippedMethodSet() const
|
||||
@ -723,9 +724,9 @@ public:
|
||||
return jsPandaFile_;
|
||||
}
|
||||
|
||||
EcmaVM *GetVM() const
|
||||
CompilationEnv *GetCompilationEnv() const
|
||||
{
|
||||
return vm_;
|
||||
return compilationEnv_;
|
||||
}
|
||||
|
||||
LexEnvManager* GetEnvManager() const
|
||||
@ -763,7 +764,7 @@ private:
|
||||
|
||||
const CString GetEntryFunName(const std::string_view &entryPoint) const;
|
||||
void ProcessClasses();
|
||||
void ProcessMethod(JSHandle<JSFunction> &jsFunction);
|
||||
void ProcessMethod();
|
||||
void RearrangeInnerMethods();
|
||||
void CollectMethodPcsFromBC(const uint32_t insSz, const uint8_t *insArr,
|
||||
MethodLiteral *method, std::vector<std::string> &classNameVec, const CString &recordName,
|
||||
@ -793,12 +794,12 @@ private:
|
||||
void CollectRecordExportInfo(const CString &recordName);
|
||||
void MarkMethodNamespace(const uint32_t methodOffset);
|
||||
|
||||
EcmaVM *vm_;
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
JSPandaFile *jsPandaFile_ {nullptr};
|
||||
BCInfo bytecodeInfo_;
|
||||
PGOProfilerDecoder &pfDecoder_;
|
||||
PGOBCInfo pgoBCInfo_ {};
|
||||
SnapshotConstantPoolData snapshotCPData_;
|
||||
std::unique_ptr<SnapshotConstantPoolData> snapshotCPData_;
|
||||
size_t methodInfoIndex_ {0};
|
||||
bool enableCollectLiteralInfo_ {false};
|
||||
std::set<int32_t> classDefBCIndexes_ {};
|
||||
|
@ -31,7 +31,7 @@ CompilationDriver::CompilationDriver(PGOProfilerDecoder &profilerDecoder,
|
||||
bool outputAsm,
|
||||
size_t maxMethodsInModule,
|
||||
const std::pair<uint32_t, uint32_t> &compilerMethodsRange)
|
||||
: vm_(collector->GetVM()),
|
||||
: compilationEnv_(collector->GetCompilationEnv()),
|
||||
jsPandaFile_(collector->GetJSPandaFile()),
|
||||
pfDecoder_(profilerDecoder),
|
||||
collector_(collector),
|
||||
@ -45,7 +45,9 @@ CompilationDriver::CompilationDriver(PGOProfilerDecoder &profilerDecoder,
|
||||
maxMethodsInModule_(maxMethodsInModule),
|
||||
optionMethodsRange_(compilerMethodsRange)
|
||||
{
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->SetCompilationDriver(this);
|
||||
if (compilationEnv_->IsAotCompiler()) {
|
||||
compilationEnv_->GetTSManager()->SetCompilationDriver(this);
|
||||
}
|
||||
|
||||
if (!optionSelectMethods.empty() && !optionSkipMethods.empty()) {
|
||||
LOG_COMPILER(FATAL) <<
|
||||
@ -63,7 +65,9 @@ CompilationDriver::CompilationDriver(PGOProfilerDecoder &profilerDecoder,
|
||||
|
||||
CompilationDriver::~CompilationDriver()
|
||||
{
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->SetCompilationDriver(nullptr);
|
||||
if (compilationEnv_->IsAotCompiler()) {
|
||||
compilationEnv_->GetTSManager()->SetCompilationDriver(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
Module *CompilationDriver::GetModule()
|
||||
@ -259,7 +263,7 @@ bool CompilationDriver::FilterOption(const std::map<std::string, std::vector<std
|
||||
|
||||
void CompilationDriver::SetCurrentCompilationFile() const
|
||||
{
|
||||
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
ptManager->SetCurCompilationFile(jsPandaFile_);
|
||||
}
|
||||
|
||||
@ -271,7 +275,7 @@ void CompilationDriver::StoreConstantPoolInfo() const
|
||||
bytecodeInfo_.AddSkippedMethod(x.first);
|
||||
}
|
||||
}
|
||||
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
ptManager->GetAOTSnapshot().StoreConstantPoolInfo(collector_);
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,7 @@ protected:
|
||||
|
||||
void StoreConstantPoolInfo() const;
|
||||
|
||||
EcmaVM *vm_ {nullptr};
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
const JSPandaFile *jsPandaFile_ {nullptr};
|
||||
PGOProfilerDecoder &pfDecoder_;
|
||||
BytecodeInfoCollector* collector_;
|
||||
@ -399,14 +399,12 @@ public:
|
||||
Module *GetModule();
|
||||
|
||||
template <class Callback>
|
||||
void CompileMethod(JSHandle<JSFunction> &jsFunction, const Callback &cb)
|
||||
void CompileMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral, const Callback &cb)
|
||||
{
|
||||
SetCurrentCompilationFile();
|
||||
for (auto mi : bytecodeInfo_.GetMethodList()) {
|
||||
bytecodeInfo_.AddSkippedMethod(mi.first);
|
||||
}
|
||||
const JSPandaFile *jsPandaFile = Method::Cast(jsFunction->GetMethod().GetTaggedObject())->GetJSPandaFile();
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
MethodLiteral *methodLiteral = method->GetMethodLiteral();
|
||||
const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, methodLiteral->GetMethodId()));
|
||||
|
||||
auto &methodList = bytecodeInfo_.GetMethodList();
|
||||
|
28
ecmascript/compiler/compilation_env.cpp
Normal file
28
ecmascript/compiler/compilation_env.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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/compiler/compilation_env.h"
|
||||
#include "ecmascript/ecma_context.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/ts_types/ts_manager.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
CompilationEnv::CompilationEnv(EcmaVM *vm) : vm_(vm), thread_(vm_->GetJSThread()),
|
||||
tsManager_(nullptr), ptManager_(nullptr) { }
|
||||
|
||||
NativeAreaAllocator *CompilationEnv::GetNativeAreaAllocator() const
|
||||
{
|
||||
return vm_->GetNativeAreaAllocator();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
116
ecmascript/compiler/compilation_env.h
Normal file
116
ecmascript/compiler/compilation_env.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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_COMPILER_COMPILATION_ENV_H
|
||||
#define ECMASCRIPT_COMPILER_COMPILATION_ENV_H
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
namespace kungfu {
|
||||
class PGOTypeManager;
|
||||
};
|
||||
class TSManager;
|
||||
class ConstantPool;
|
||||
namespace pgo {
|
||||
class PGOProfiler;
|
||||
};
|
||||
class CompilationEnv {
|
||||
public:
|
||||
CompilationEnv(EcmaVM *vm);
|
||||
virtual ~CompilationEnv() = default;
|
||||
virtual bool IsJitCompiler() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool IsAotCompiler() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
EcmaVM *GetEcmaVM() const
|
||||
{
|
||||
return vm_;
|
||||
}
|
||||
|
||||
JSThread *GetJSThread() const
|
||||
{
|
||||
return thread_;
|
||||
}
|
||||
|
||||
kungfu::PGOTypeManager *GetPTManager() const
|
||||
{
|
||||
return ptManager_;
|
||||
}
|
||||
|
||||
TSManager *GetTSManager() const
|
||||
{
|
||||
return tsManager_;
|
||||
}
|
||||
|
||||
NativeAreaAllocator *GetNativeAreaAllocator() const;
|
||||
virtual JSRuntimeOptions &GetJSOptions() = 0;
|
||||
|
||||
// thread
|
||||
virtual const CMap<ElementsKind, ConstantIndex> &GetArrayHClassIndexMap() const = 0;
|
||||
virtual const BuiltinHClassEntries &GetBuiltinHClassEntries() const = 0;
|
||||
virtual JSHClass *GetBuiltinPrototypeHClass(BuiltinTypeId type) const = 0;
|
||||
|
||||
// context
|
||||
virtual JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id) const = 0;
|
||||
virtual JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, int32_t index) const = 0;
|
||||
virtual JSTaggedValue FindOrCreateUnsharedConstpool(const uint32_t methodOffset) const = 0;
|
||||
virtual JSTaggedValue FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool) const = 0;
|
||||
virtual JSHandle<ConstantPool> FindOrCreateConstPool(const JSPandaFile *jsPandaFile,
|
||||
panda_file::File::EntityId id) = 0;
|
||||
virtual JSTaggedValue GetConstantPoolByMethodOffset(const uint32_t methodOffset) const = 0;
|
||||
|
||||
// ConstantPool
|
||||
virtual JSTaggedValue GetArrayLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const = 0;
|
||||
virtual JSTaggedValue GetObjectLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const = 0;
|
||||
virtual panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index) const = 0;
|
||||
virtual JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const = 0;
|
||||
|
||||
// GlobalEnv
|
||||
virtual JSHandle<GlobalEnv> GetGlobalEnv() const = 0;
|
||||
|
||||
// GlobalConstants
|
||||
virtual const GlobalEnvConstants *GlobalConstants() const = 0;
|
||||
|
||||
virtual JSThread *GetHostThread() const
|
||||
{
|
||||
ASSERT(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual JSPandaFile *GetJSPandaFile() const
|
||||
{
|
||||
ASSERT(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual MethodLiteral *GetMethodLiteral() const
|
||||
{
|
||||
ASSERT(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
EcmaVM *vm_ {nullptr};
|
||||
JSThread *thread_ {nullptr};
|
||||
TSManager *tsManager_ {nullptr};
|
||||
kungfu::PGOTypeManager *ptManager_ {nullptr};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_COMPILER_COMPILATION_ENV_H
|
@ -436,8 +436,9 @@ Module* AOTFileGenerator::AddModule(const std::string &name, const std::string &
|
||||
{
|
||||
#ifdef COMPILE_MAPLE
|
||||
if (useLiteCG_) {
|
||||
LMIRModule *irModule = new LMIRModule(vm_->GetNativeAreaAllocator(), name, logDebug, triple, isJit);
|
||||
LiteCGAssembler *ass = new LiteCGAssembler(*irModule, vm_->GetJSOptions().GetCompilerCodegenOptions());
|
||||
LMIRModule *irModule = new LMIRModule(compilationEnv_->GetNativeAreaAllocator(), name, logDebug, triple, isJit);
|
||||
LiteCGAssembler *ass = new LiteCGAssembler(*irModule,
|
||||
compilationEnv_->GetJSOptions().GetCompilerCodegenOptions());
|
||||
modulePackage_.emplace_back(Module(irModule, ass));
|
||||
if (stackMapInfo_ == nullptr) {
|
||||
stackMapInfo_ = new LiteCGStackMapInfo();
|
||||
@ -445,7 +446,7 @@ Module* AOTFileGenerator::AddModule(const std::string &name, const std::string &
|
||||
return &modulePackage_.back();
|
||||
}
|
||||
#endif
|
||||
LLVMModule *m = new LLVMModule(vm_->GetNativeAreaAllocator(), name, logDebug, triple);
|
||||
LLVMModule *m = new LLVMModule(compilationEnv_->GetNativeAreaAllocator(), name, logDebug, triple);
|
||||
LLVMAssembler *ass = new LLVMAssembler(m, option);
|
||||
modulePackage_.emplace_back(Module(m, ass));
|
||||
if (stackMapInfo_ == nullptr) {
|
||||
@ -500,7 +501,7 @@ void AOTFileGenerator::CompileLatestModuleThenDestroy()
|
||||
Module *latestModule = GetLatestModule();
|
||||
#ifdef COMPILE_MAPLE
|
||||
static uint32_t lastModulePC = 0;
|
||||
if (useLiteCG_ && vm_->IsEnableJit()) {
|
||||
if (useLiteCG_ && compilationEnv_->IsJitCompiler()) {
|
||||
lastModulePC = 0;
|
||||
}
|
||||
if (latestModule->GetModule()->GetModuleKind() != MODULE_LLVM) {
|
||||
@ -514,7 +515,7 @@ void AOTFileGenerator::CompileLatestModuleThenDestroy()
|
||||
uint32_t latestModuleIdx = GetModuleVecSize() - 1;
|
||||
{
|
||||
TimeScope timescope("LLVMIROpt", const_cast<CompilerLog *>(log_));
|
||||
bool fastCompileMode = vm_->GetJSOptions().GetFastAOTCompileMode();
|
||||
bool fastCompileMode = compilationEnv_->GetJSOptions().GetFastAOTCompileMode();
|
||||
latestModule->RunAssembler(*(log_), fastCompileMode);
|
||||
}
|
||||
{
|
||||
@ -655,10 +656,10 @@ bool AOTFileGenerator::isAArch64() const
|
||||
void AOTFileGenerator::SaveSnapshotFile()
|
||||
{
|
||||
TimeScope timescope("LLVMCodeGenPass-AI", const_cast<CompilerLog *>(log_));
|
||||
Snapshot snapshot(vm_);
|
||||
const CString snapshotPath(vm_->GetJSOptions().GetAOTOutputFile().c_str());
|
||||
Snapshot snapshot(compilationEnv_->GetEcmaVM());
|
||||
const CString snapshotPath(compilationEnv_->GetJSOptions().GetAOTOutputFile().c_str());
|
||||
const auto &methodToEntryIndexMap = aotInfo_.GetMethodToEntryIndexMap();
|
||||
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
ptManager->GetAOTSnapshot().ResolveSnapshotData(methodToEntryIndexMap);
|
||||
|
||||
CString aiPath = snapshotPath + AOTFileManager::FILE_EXTENSION_AI;
|
||||
|
@ -177,9 +177,9 @@ protected:
|
||||
|
||||
class AOTFileGenerator : public FileGenerator {
|
||||
public:
|
||||
AOTFileGenerator(const CompilerLog *log, const MethodLogList *logList, EcmaVM* vm, const std::string &triple,
|
||||
bool useLiteCG = false)
|
||||
: FileGenerator(log, logList), vm_(vm), cfg_(triple), useLiteCG_(useLiteCG) {}
|
||||
AOTFileGenerator(const CompilerLog *log, const MethodLogList *logList, CompilationEnv *env,
|
||||
const std::string &triple, bool useLiteCG = false)
|
||||
: FileGenerator(log, logList), compilationEnv_(env), cfg_(triple), useLiteCG_(useLiteCG) {}
|
||||
|
||||
~AOTFileGenerator() override = default;
|
||||
|
||||
@ -222,7 +222,7 @@ private:
|
||||
|
||||
AnFileInfo aotInfo_;
|
||||
CGStackMapInfo *stackMapInfo_ = nullptr;
|
||||
EcmaVM* vm_;
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
CompilationConfig cfg_;
|
||||
std::string curCompileFileName_;
|
||||
// MethodID->EntryIndex
|
||||
|
134
ecmascript/compiler/jit_compilation_env.cpp
Normal file
134
ecmascript/compiler/jit_compilation_env.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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/compiler/jit_compilation_env.h"
|
||||
#include "ecmascript/ecma_context.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/ts_types/ts_manager.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
// jit
|
||||
JitCompilationEnv::JitCompilationEnv(EcmaVM *jitVm, EcmaVM *jsVm, JSHandle<JSFunction> &jsFunction)
|
||||
: CompilationEnv(jitVm), hostThread_(jsVm->GetJSThread()), jsFunction_(jsFunction)
|
||||
{
|
||||
ptManager_ = hostThread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
jsPandaFile_ = const_cast<JSPandaFile*>(method->GetJSPandaFile());
|
||||
methodLiteral_ = method->GetMethodLiteral();
|
||||
}
|
||||
|
||||
JSRuntimeOptions &JitCompilationEnv::GetJSOptions()
|
||||
{
|
||||
return hostThread_->GetEcmaVM()->GetJSOptions();
|
||||
}
|
||||
|
||||
const CMap<ElementsKind, ConstantIndex> &JitCompilationEnv::GetArrayHClassIndexMap() const
|
||||
{
|
||||
return hostThread_->GetArrayHClassIndexMap();
|
||||
}
|
||||
|
||||
const BuiltinHClassEntries &JitCompilationEnv::GetBuiltinHClassEntries() const
|
||||
{
|
||||
return hostThread_->GetBuiltinHClassEntries();
|
||||
}
|
||||
|
||||
JSHClass *JitCompilationEnv::GetBuiltinPrototypeHClass(BuiltinTypeId type) const
|
||||
{
|
||||
return hostThread_->GetBuiltinPrototypeHClass(type);
|
||||
}
|
||||
|
||||
void JitCompilationEnv::SetTsManagerCompilationEnv()
|
||||
{
|
||||
auto pt = hostThread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
ptManager_ = pt;
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::FindConstpool([[maybe_unused]] const JSPandaFile *jsPandaFile,
|
||||
[[maybe_unused]] panda_file::File::EntityId id) const
|
||||
{
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
return method->GetConstantPool();
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::FindConstpool([[maybe_unused]] const JSPandaFile *jsPandaFile,
|
||||
[[maybe_unused]] int32_t index) const
|
||||
{
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
return method->GetConstantPool();
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::FindOrCreateUnsharedConstpool([[maybe_unused]] const uint32_t methodOffset) const
|
||||
{
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
JSTaggedValue constpool = method->GetConstantPool();
|
||||
if (!ConstantPool::CheckUnsharedConstpool(constpool)) {
|
||||
constpool = hostThread_->GetCurrentEcmaContext()->FindUnsharedConstpool(constpool);
|
||||
return constpool;
|
||||
}
|
||||
ASSERT(constpool.IsHole());
|
||||
return constpool;
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::FindOrCreateUnsharedConstpool([[maybe_unused]] JSTaggedValue sharedConstpool) const
|
||||
{
|
||||
return FindOrCreateUnsharedConstpool(0);
|
||||
}
|
||||
|
||||
JSHandle<ConstantPool> JitCompilationEnv::FindOrCreateConstPool([[maybe_unused]] const JSPandaFile *jsPandaFile,
|
||||
[[maybe_unused]] panda_file::File::EntityId id)
|
||||
{
|
||||
ASSERT_PRINT(0, "jit should unreachable");
|
||||
return JSHandle<ConstantPool>();
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::GetConstantPoolByMethodOffset([[maybe_unused]] const uint32_t methodOffset) const
|
||||
{
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
return method->GetConstantPool();
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::GetArrayLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const
|
||||
{
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::ARRAY_LITERAL>(constpool, index, entry);
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::GetObjectLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const
|
||||
{
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::OBJECT_LITERAL>(constpool, index, entry);
|
||||
}
|
||||
|
||||
panda_file::File::EntityId JitCompilationEnv::GetIdFromCache(JSTaggedValue constpool, uint32_t index) const
|
||||
{
|
||||
return ConstantPool::GetIdFromCache(constpool, index);
|
||||
}
|
||||
|
||||
JSHandle<GlobalEnv> JitCompilationEnv::GetGlobalEnv() const
|
||||
{
|
||||
return hostThread_->GetEcmaVM()->GetGlobalEnv();
|
||||
}
|
||||
|
||||
const GlobalEnvConstants *JitCompilationEnv::GlobalConstants() const
|
||||
{
|
||||
return hostThread_->GlobalConstants();
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::GetStringFromConstantPool([[maybe_unused]] const uint32_t methodOffset,
|
||||
[[maybe_unused]] const uint16_t cpIdx) const
|
||||
{
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
JSTaggedValue constpool = method->GetConstantPool();
|
||||
return ConstantPool::GetStringFromCacheForJit(GetJSThread(), constpool, cpIdx);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
80
ecmascript/compiler/jit_compilation_env.h
Normal file
80
ecmascript/compiler/jit_compilation_env.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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_COMPILER_JIT_COMPILATION_ENV_H
|
||||
#define ECMASCRIPT_COMPILER_JIT_COMPILATION_ENV_H
|
||||
#include "ecmascript/compiler/compilation_env.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JitCompilationEnv final : public CompilationEnv {
|
||||
public:
|
||||
JitCompilationEnv(EcmaVM *vm, EcmaVM *hVm, JSHandle<JSFunction> &jsFunction);
|
||||
~JitCompilationEnv() = default;
|
||||
bool IsJitCompiler() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
JSRuntimeOptions &GetJSOptions() override;
|
||||
// thread
|
||||
const CMap<ElementsKind, ConstantIndex> &GetArrayHClassIndexMap() const override;
|
||||
const BuiltinHClassEntries &GetBuiltinHClassEntries() const override;
|
||||
JSHClass *GetBuiltinPrototypeHClass(BuiltinTypeId type) const override;
|
||||
void SetTsManagerCompilationEnv();
|
||||
|
||||
// context
|
||||
JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id) const override;
|
||||
JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, int32_t index) const override;
|
||||
JSTaggedValue FindOrCreateUnsharedConstpool(const uint32_t methodOffset) const override;
|
||||
JSTaggedValue FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool) const override;
|
||||
JSHandle<ConstantPool> FindOrCreateConstPool(const JSPandaFile *jsPandaFile,
|
||||
panda_file::File::EntityId id) override;
|
||||
JSTaggedValue GetConstantPoolByMethodOffset(const uint32_t methodOffset) const override;
|
||||
|
||||
// ConstantPool
|
||||
JSTaggedValue GetArrayLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const override;
|
||||
JSTaggedValue GetObjectLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const override;
|
||||
panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index) const override;
|
||||
|
||||
// GlobalEnv
|
||||
JSHandle<GlobalEnv> GetGlobalEnv() const override;
|
||||
|
||||
// GlobalConstants
|
||||
const GlobalEnvConstants *GlobalConstants() const override;
|
||||
|
||||
JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const override;
|
||||
|
||||
JSThread *GetHostThread() const override
|
||||
{
|
||||
return hostThread_;
|
||||
}
|
||||
|
||||
JSPandaFile *GetJSPandaFile() const override
|
||||
{
|
||||
return jsPandaFile_;
|
||||
}
|
||||
|
||||
MethodLiteral *GetMethodLiteral() const override
|
||||
{
|
||||
return methodLiteral_;
|
||||
}
|
||||
|
||||
private:
|
||||
JSThread *hostThread_ {nullptr};
|
||||
JSHandle<JSFunction> jsFunction_;
|
||||
JSPandaFile *jsPandaFile_ {nullptr};
|
||||
MethodLiteral *methodLiteral_ {nullptr};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_COMPILER_JIT_COMPILATION_ENV_H
|
@ -108,15 +108,8 @@ JitCompilerTask *JitCompilerTask::CreateJitCompilerTask(JitTask *jitTask)
|
||||
|
||||
bool JitCompilerTask::Compile()
|
||||
{
|
||||
TSManager *tsm = new (std::nothrow) TSManager(vm_);
|
||||
if (tsm == nullptr) {
|
||||
return false;
|
||||
}
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->SetTSManager(tsm);
|
||||
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->Initialize();
|
||||
|
||||
JitCompiler *jitCompiler = JitCompiler::GetInstance();
|
||||
auto jitPassManager = new (std::nothrow) JitPassManager(vm_,
|
||||
auto jitPassManager = new (std::nothrow) JitPassManager(jitCompilationEnv_.get(),
|
||||
jitCompiler->GetJitOptions().triple_,
|
||||
jitCompiler->GetJitOptions().optLevel_,
|
||||
jitCompiler->GetJitOptions().relocMode_,
|
||||
@ -129,13 +122,21 @@ bool JitCompilerTask::Compile()
|
||||
}
|
||||
passManager_.reset(jitPassManager);
|
||||
auto aotFileGenerator = new (std::nothrow) AOTFileGenerator(&jitCompiler->GetCompilerLog(),
|
||||
&jitCompiler->GetLogList(),
|
||||
vm_, jitCompiler->GetJitOptions().triple_, vm_->GetJSOptions().IsCompilerEnableLiteCG());
|
||||
&jitCompiler->GetLogList(), jitCompilationEnv_.get(),
|
||||
jitCompiler->GetJitOptions().triple_, jitCompilationEnv_->GetJSOptions().IsCompilerEnableLiteCG());
|
||||
if (aotFileGenerator == nullptr) {
|
||||
return false;
|
||||
}
|
||||
jitCodeGenerator_.reset(aotFileGenerator);
|
||||
return passManager_->Compile(jsFunction_, *jitCodeGenerator_, offset_);
|
||||
return passManager_->Compile(*jitCodeGenerator_, offset_);
|
||||
}
|
||||
|
||||
void JitCompilerTask::ReleaseJitPassManager()
|
||||
{
|
||||
// release passManager before jitCompilerTask release,
|
||||
// in future release JitCompilerTask when compile finish
|
||||
JitPassManager *passManager = passManager_.release();
|
||||
delete passManager;
|
||||
}
|
||||
|
||||
bool JitCompilerTask::Finalize(JitTask *jitTask)
|
||||
@ -146,6 +147,7 @@ bool JitCompilerTask::Finalize(JitTask *jitTask)
|
||||
jitCodeGenerator_->JitCreateLitecgModule();
|
||||
passManager_->RunCg();
|
||||
jitCodeGenerator_->GetMemoryCodeInfos(jitTask->GetMachineCodeDesc());
|
||||
ReleaseJitPassManager();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,10 @@
|
||||
#define ECMASCRIPT_COMPILER_JIT_COMPILER_H
|
||||
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
#include "ecmascript/compiler/jit_compilation_env.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/jit/jit_task.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
extern "C" {
|
||||
@ -67,18 +69,21 @@ struct JitCompilationOptions {
|
||||
|
||||
class JitCompilerTask final {
|
||||
public:
|
||||
JitCompilerTask(JitTask *jitTask) : vm_(jitTask->GetVM()), jsFunction_(jitTask->GetJsFunction()),
|
||||
offset_(jitTask->GetOffset()), passManager_(nullptr), jitCodeGenerator_(nullptr) { };
|
||||
JitCompilerTask(JitTask *jitTask) : jsFunction_(jitTask->GetJsFunction()), offset_(jitTask->GetOffset()),
|
||||
jitCompilationEnv_(new JitCompilationEnv(jitTask->GetCompilerVM(), jitTask->GetHostVM(), jsFunction_)),
|
||||
passManager_(nullptr), jitCodeGenerator_(nullptr) { };
|
||||
|
||||
static JitCompilerTask *CreateJitCompilerTask(JitTask *jitTask);
|
||||
|
||||
bool Compile();
|
||||
bool Finalize(JitTask *jitTask);
|
||||
|
||||
void ReleaseJitPassManager();
|
||||
|
||||
private:
|
||||
EcmaVM *vm_;
|
||||
JSHandle<JSFunction> jsFunction_;
|
||||
int32_t offset_;
|
||||
std::unique_ptr<JitCompilationEnv> jitCompilationEnv_;
|
||||
std::unique_ptr<JitPassManager> passManager_;
|
||||
// need refact AOTFileGenerator to JitCodeGenerator
|
||||
std::unique_ptr<AOTFileGenerator> jitCodeGenerator_;
|
||||
|
@ -46,11 +46,11 @@ std::optional<std::pair<size_t, bool>> NativeInlineLowering::GetCallInfo(GateRef
|
||||
case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8:
|
||||
return {{3U, true}};
|
||||
case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8: {
|
||||
CallRangeTypeInfoAccessor tia(thread_, circuit_, gate);
|
||||
CallRangeTypeInfoAccessor tia(compilationEnv_, circuit_, gate);
|
||||
return {{tia.GetArgc(), false}};
|
||||
}
|
||||
case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8: {
|
||||
CallThisRangeTypeInfoAccessor tia(thread_, circuit_, gate);
|
||||
CallThisRangeTypeInfoAccessor tia(compilationEnv_, circuit_, gate);
|
||||
return {{tia.GetArgc(), true}};
|
||||
}
|
||||
default:
|
||||
@ -72,7 +72,7 @@ void NativeInlineLowering::RunNativeInlineLowering()
|
||||
continue;
|
||||
}
|
||||
auto [argc, skipThis] = optCallInfo.value();
|
||||
CallTypeInfoAccessor ctia(thread_, circuit_, gate);
|
||||
CallTypeInfoAccessor ctia(compilationEnv_, circuit_, gate);
|
||||
BuiltinsStubCSigns::ID id = ctia.TryGetPGOBuiltinMethodId();
|
||||
switch (id) {
|
||||
case BuiltinsStubCSigns::ID::StringFromCharCode:
|
||||
@ -257,7 +257,7 @@ void NativeInlineLowering::TryInlineStringFromCharCode(GateRef gate, size_t argc
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(),
|
||||
@ -281,7 +281,7 @@ void NativeInlineLowering::TryInlineNumberIsFinite(GateRef gate, size_t argc, bo
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(),
|
||||
@ -299,7 +299,7 @@ void NativeInlineLowering::TryInlineNumberIsInteger(GateRef gate, size_t argc, b
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(),
|
||||
@ -317,7 +317,7 @@ void NativeInlineLowering::TryInlineNumberIsNaN(GateRef gate, size_t argc, bool
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(),
|
||||
@ -335,7 +335,7 @@ void NativeInlineLowering::TryInlineNumberIsSafeInteger(GateRef gate, size_t arg
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(),
|
||||
@ -516,7 +516,7 @@ void NativeInlineLowering::TryInlineArrayBufferIsView(GateRef gate,
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(), builder_.IntPtr(static_cast<int64_t>(id)), {tacc.GetArg0()});
|
||||
|
@ -37,9 +37,9 @@ public:
|
||||
tsManager_(ctx->GetTSManager()),
|
||||
enableLog_(enableLog),
|
||||
methodName_(name),
|
||||
nocheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()),
|
||||
traceInline_(ctx->GetEcmaVM()->GetJSOptions().GetTraceInline()),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()) {}
|
||||
nocheck_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerNoCheck()),
|
||||
traceInline_(ctx->GetCompilationEnv()->GetJSOptions().GetTraceInline()),
|
||||
compilationEnv_(ctx->GetCompilationEnv()) {}
|
||||
~NativeInlineLowering() = default;
|
||||
void RunNativeInlineLowering();
|
||||
|
||||
@ -101,7 +101,7 @@ private:
|
||||
std::string methodName_;
|
||||
bool nocheck_;
|
||||
bool traceInline_;
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
};
|
||||
}
|
||||
#endif // ECMASCRIPT_COMPILER_BUILTIN_INLINE_H
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ecmascript/compiler/type_info_accessors.h"
|
||||
#include "ecmascript/dfx/vmstat/opt_code_profiler.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
|
||||
@ -56,8 +57,10 @@ void NTypeBytecodeLowering::Lower(GateRef gate)
|
||||
LowerNTypedCreateEmptyArray(gate);
|
||||
break;
|
||||
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
|
||||
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
|
||||
LowerNTypedCreateArrayWithBuffer(gate);
|
||||
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerNTypedCreateArrayWithBuffer");
|
||||
LowerNTypedCreateArrayWithBuffer(gate);
|
||||
}
|
||||
break;
|
||||
case EcmaOpcode::COPYRESTARGS_IMM8:
|
||||
case EcmaOpcode::WIDE_COPYRESTARGS_PREF_IMM16:
|
||||
@ -100,8 +103,10 @@ void NTypeBytecodeLowering::Lower(GateRef gate)
|
||||
LowerStModuleVar(gate);
|
||||
break;
|
||||
case EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOWNBYNAME_IMM16_ID16_V8:
|
||||
LowerNTypedStOwnByName(gate);
|
||||
case EcmaOpcode::STOWNBYNAME_IMM16_ID16_V8: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerNTypedStOwnByName");
|
||||
LowerNTypedStOwnByName(gate);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -206,7 +211,7 @@ void NTypeBytecodeLowering::LowerNTypedCreateArrayWithBuffer(GateRef gate)
|
||||
uint32_t cpIdx = static_cast<uint32_t>(acc_.GetConstantValue(index));
|
||||
auto methodOffset = acc_.TryGetMethodOffset(gate);
|
||||
uint32_t cpId = ptManager_->GetConstantPoolIDByMethodOffset(methodOffset);
|
||||
JSTaggedValue cp = ptManager_->GetConstantPoolByMethodOffset(methodOffset);
|
||||
JSTaggedValue cp = compilationEnv_->GetConstantPoolByMethodOffset(methodOffset);
|
||||
panda_file::File::EntityId id = ConstantPool::GetIdFromCache(cp, cpIdx);
|
||||
|
||||
int elementIndex = ptManager_->GetElementsIndexByEntityId(id);
|
||||
@ -351,10 +356,10 @@ void NTypeBytecodeLowering::LowerNTypedStOwnByName(GateRef gate)
|
||||
GateRef hclassGate = acc_.GetValueIn(receiver, 2); // 2: hclass offset
|
||||
JSTaggedValue taggedHClass(acc_.GetConstantValue(hclassGate));
|
||||
GateRef stringId = acc_.GetValueIn(gate, 0);
|
||||
JSTaggedValue key = TypeInfoAccessor::GetStringFromConstantPool(thread_, acc_.TryGetMethodOffset(gate),
|
||||
acc_.GetConstantValue(stringId));
|
||||
JSTaggedValue key = compilationEnv_->GetStringFromConstantPool(acc_.TryGetMethodOffset(gate),
|
||||
acc_.GetConstantValue(stringId));
|
||||
JSHClass *hclass = JSHClass::Cast(taggedHClass.GetTaggedObject());
|
||||
int entry = JSHClass::FindPropertyEntry(thread_, hclass, key);
|
||||
int entry = JSHClass::FindPropertyEntry(compilationEnv_->GetJSThread(), hclass, key);
|
||||
if (entry == -1) {
|
||||
return;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
methodName_(name),
|
||||
glue_(acc_.GetGlueFromArgList()),
|
||||
argAcc_(circuit),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()) {}
|
||||
compilationEnv_(ctx->GetCompilationEnv()) {}
|
||||
|
||||
~NTypeBytecodeLowering() = default;
|
||||
|
||||
@ -93,7 +93,7 @@ private:
|
||||
std::string methodName_;
|
||||
GateRef glue_ {Circuit::NullGate()};
|
||||
ArgumentAccessor argAcc_;
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
};
|
||||
} // panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_NTYPE_BYTECODE_LOWERING_H
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/compiler/ntype_hcr_lowering.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
GateRef NTypeHCRLowering::VisitGate(GateRef gate)
|
||||
@ -21,11 +22,15 @@ GateRef NTypeHCRLowering::VisitGate(GateRef gate)
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
auto op = acc_.GetOpCode(gate);
|
||||
switch (op) {
|
||||
case OpCode::CREATE_ARRAY:
|
||||
LowerCreateArray(gate, glue);
|
||||
case OpCode::CREATE_ARRAY: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerCreateArray");
|
||||
LowerCreateArray(gate, glue);
|
||||
}
|
||||
break;
|
||||
case OpCode::CREATE_ARRAY_WITH_BUFFER:
|
||||
LowerCreateArrayWithBuffer(gate, glue);
|
||||
case OpCode::CREATE_ARRAY_WITH_BUFFER: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerCreateArrayWithBuffer");
|
||||
LowerCreateArrayWithBuffer(gate, glue);
|
||||
}
|
||||
break;
|
||||
case OpCode::CREATE_ARGUMENTS:
|
||||
LowerCreateArguments(gate, glue);
|
||||
@ -89,7 +94,11 @@ void NTypeHCRLowering::LowerCreateArrayWithBuffer(GateRef gate, GateRef glue)
|
||||
GateRef literialElements = LoadFromConstPool(constpool, elementIndex, ConstantPool::AOT_ARRAY_INFO_INDEX);
|
||||
uint32_t cpIdVal = static_cast<uint32_t>(acc_.GetConstantValue(cpId));
|
||||
JSTaggedValue arr = GetArrayLiteralValue(cpIdVal, constPoolIndex);
|
||||
JSHandle<JSArray> arrayHandle(thread_, arr);
|
||||
if (arr.IsUndefined()) {
|
||||
return;
|
||||
}
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
JSArray *arrayHandle = JSArray::Cast(arr.GetTaggedObject());
|
||||
TaggedArray *arrayLiteral = TaggedArray::Cast(arrayHandle->GetElements());
|
||||
uint32_t literialLength = arrayLiteral->GetLength();
|
||||
uint32_t arrayLength = acc_.GetArraySize(gate);
|
||||
@ -168,14 +177,14 @@ GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef
|
||||
ElementsKind kind = acc_.GetArrayMetaDataAccessor(gate).GetElementsKind();
|
||||
GateRef hclass = Circuit::NullGate();
|
||||
if (!Elements::IsGeneric(kind)) {
|
||||
auto hclassIndex = thread_->GetArrayHClassIndexMap().at(kind);
|
||||
auto hclassIndex = compilationEnv_->GetArrayHClassIndexMap().at(kind);
|
||||
hclass = builder_.GetGlobalConstantValue(hclassIndex);
|
||||
} else {
|
||||
GateRef globalEnv = builder_.GetGlobalEnv();
|
||||
hclass = builder_.GetGlobalEnvObjHClass(globalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX);
|
||||
}
|
||||
|
||||
JSHandle<JSFunction> arrayFunc(thread_->GetEcmaVM()->GetGlobalEnv()->GetArrayFunction());
|
||||
JSHandle<JSFunction> arrayFunc(compilationEnv_->GetGlobalEnv()->GetArrayFunction());
|
||||
JSTaggedValue protoOrHClass = arrayFunc->GetProtoOrHClass();
|
||||
JSHClass *arrayHC = JSHClass::Cast(protoOrHClass.GetTaggedObject());
|
||||
size_t arraySize = arrayHC->GetObjectSize();
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
: PassVisitor(circuit, chunk, visitor),
|
||||
circuit_(circuit),
|
||||
acc_(circuit),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()),
|
||||
compilationEnv_(ctx->GetCompilationEnv()),
|
||||
builder_(circuit, ctx->GetCompilerConfig()),
|
||||
dependEntry_(circuit->GetDependRoot()),
|
||||
jsPandaFile_(ctx->GetJSPandaFile()),
|
||||
@ -64,20 +64,19 @@ private:
|
||||
|
||||
JSTaggedValue GetConstantpoolValue(uint32_t cpId)
|
||||
{
|
||||
return thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, cpId);
|
||||
return compilationEnv_->FindConstpool(jsPandaFile_, cpId);
|
||||
}
|
||||
|
||||
JSTaggedValue GetArrayLiteralValue(uint32_t cpId, uint32_t cpIdx)
|
||||
{
|
||||
JSTaggedValue cp = GetConstantpoolValue(cpId);
|
||||
JSTaggedValue unsharedCp = thread_->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(cp);
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::ARRAY_LITERAL>(
|
||||
thread_, unsharedCp, cpIdx, recordName_);
|
||||
JSTaggedValue unsharedCp = compilationEnv_->FindOrCreateUnsharedConstpool(cp);
|
||||
return compilationEnv_->GetArrayLiteralFromCache(unsharedCp, cpIdx, recordName_);
|
||||
}
|
||||
|
||||
Circuit *circuit_ {nullptr};
|
||||
GateAccessor acc_;
|
||||
JSThread *thread_ {nullptr};
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
CircuitBuilder builder_;
|
||||
GateRef dependEntry_;
|
||||
const JSPandaFile *jsPandaFile_ {nullptr};
|
||||
|
@ -21,6 +21,7 @@
|
||||
namespace panda::ecmascript::kungfu {
|
||||
bool ObjectAccessHelper::Compute(ChunkVector<ObjectAccessInfo> &infos)
|
||||
{
|
||||
ASSERT(compilationEnv_->IsAotCompiler());
|
||||
ASSERT(infos.empty());
|
||||
bool result = false;
|
||||
ObjectAccessInfo info(type_);
|
||||
@ -55,7 +56,7 @@ bool ObjectAccessHelper::ComputeForClassInstance(ObjectAccessInfo &info)
|
||||
return false;
|
||||
}
|
||||
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread_, hclass, key_);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(compilationEnv_->GetJSThread(), hclass, key_);
|
||||
info.Set(hclassIndex, plr);
|
||||
|
||||
if (IsLoading()) {
|
||||
@ -80,7 +81,7 @@ bool ObjectAccessHelper::ComputeForClassOrObject(ObjectAccessInfo &info)
|
||||
}
|
||||
|
||||
JSHClass *hclass = JSHClass::Cast(tsManager_->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread_, hclass, key_);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(compilationEnv_->GetJSThread(), hclass, key_);
|
||||
info.Set(hclassIndex, plr);
|
||||
|
||||
if (IsLoading()) {
|
||||
@ -128,7 +129,7 @@ bool ObjectAccessHelper::ComputePolymorphism(ChunkVector<ObjectAccessInfo> &info
|
||||
bool PGOObjectAccessHelper::ComputeForClassInstance(PGOObjectAccessInfo &info)
|
||||
{
|
||||
auto type = info.Type();
|
||||
PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(type));
|
||||
if (hclassIndex == -1) {
|
||||
return false;
|
||||
@ -136,7 +137,7 @@ bool PGOObjectAccessHelper::ComputeForClassInstance(PGOObjectAccessInfo &info)
|
||||
|
||||
JSHClass *hclass = JSHClass::Cast(ptManager->QueryHClass(type.first, type.second).GetTaggedObject());
|
||||
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(thread_, hclass, key_);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(compilationEnv_->GetJSThread(), hclass, key_);
|
||||
info.Set(hclassIndex, plr);
|
||||
|
||||
if (IsLoading()) {
|
||||
@ -149,7 +150,7 @@ bool PGOObjectAccessHelper::ComputeForClassInstance(PGOObjectAccessInfo &info)
|
||||
bool PGOObjectAccessHelper::ClassInstanceIsCallable(PGOObjectAccessInfo &info)
|
||||
{
|
||||
auto type = info.Type();
|
||||
PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(type));
|
||||
if (hclassIndex == -1) {
|
||||
return false;
|
||||
|
@ -99,10 +99,10 @@ public:
|
||||
STORE
|
||||
};
|
||||
|
||||
explicit ObjectAccessHelper(TSManager *tsManager, AccessMode mode, GateRef receiver, GateType type,
|
||||
explicit ObjectAccessHelper(CompilationEnv *env, AccessMode mode, GateRef receiver, GateType type,
|
||||
JSTaggedValue key, GateRef value)
|
||||
: tsManager_(tsManager),
|
||||
thread_(tsManager_->GetThread()),
|
||||
: tsManager_(env->GetTSManager()),
|
||||
compilationEnv_(env),
|
||||
mode_(mode),
|
||||
receiver_(receiver),
|
||||
type_(type),
|
||||
@ -139,7 +139,7 @@ private:
|
||||
bool ComputePolymorphism(ChunkVector<ObjectAccessInfo> &infos);
|
||||
|
||||
TSManager *tsManager_ {nullptr};
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
AccessMode mode_ {};
|
||||
GateRef receiver_ {Circuit::NullGate()};
|
||||
GateType type_ {GateType::AnyType()};
|
||||
@ -156,10 +156,10 @@ public:
|
||||
STORE
|
||||
};
|
||||
|
||||
explicit PGOObjectAccessHelper(TSManager *tsManager, AccessMode mode, GateRef receiver, ProfileTyper type,
|
||||
explicit PGOObjectAccessHelper(CompilationEnv *env, AccessMode mode, GateRef receiver, ProfileTyper type,
|
||||
JSTaggedValue key, GateRef value)
|
||||
: tsManager_(tsManager),
|
||||
thread_(tsManager_->GetThread()),
|
||||
: tsManager_(env->GetTSManager()),
|
||||
compilationEnv_(env),
|
||||
mode_(mode),
|
||||
receiver_(receiver),
|
||||
holder_(receiver),
|
||||
@ -204,7 +204,7 @@ public:
|
||||
private:
|
||||
|
||||
TSManager *tsManager_ {nullptr};
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
AccessMode mode_ {};
|
||||
GateRef receiver_ {Circuit::NullGate()};
|
||||
GateRef holder_ {Circuit::NullGate()};
|
||||
|
@ -16,6 +16,8 @@
|
||||
#ifndef ECMASCRIPT_COMPILER_PASS_H
|
||||
#define ECMASCRIPT_COMPILER_PASS_H
|
||||
|
||||
#include "ecmascript/compiler/aot_compilation_env.h"
|
||||
#include "ecmascript/compiler/jit_compilation_env.h"
|
||||
#include "ecmascript/compiler/async_function_lowering.h"
|
||||
#include "ecmascript/compiler/bytecode_circuit_builder.h"
|
||||
#include "ecmascript/compiler/codegen/llvm/llvm_codegen.h"
|
||||
@ -282,7 +284,8 @@ public:
|
||||
bool enableLog = data->GetLog()->GetEnableMethodLog() && data->GetLog()->OutputType();
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
PGOTypeInfer pgoTypeInfer(data->GetCircuit(), data->GetTSManager(), data->GetPTManager(), data->GetBuilder(),
|
||||
data->GetMethodName(), &chunk, enableLog);
|
||||
data->GetMethodName(), &chunk, enableLog,
|
||||
data->GetPassContext()->GetCompilationEnv());
|
||||
pgoTypeInfer.Run();
|
||||
return true;
|
||||
}
|
||||
@ -309,7 +312,7 @@ public:
|
||||
}
|
||||
TimeScope timescope("EscapeAnalysisPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetEcmaVM()->GetJSOptions();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetCompilationEnv()->GetJSOptions();
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
|
||||
EscapeAnalysis escapeAnalysis(data->GetCircuit(), &visitor, &chunk, runtimeOption.GetTraceEscapeAnalysis());
|
||||
@ -336,7 +339,7 @@ public:
|
||||
TimeScope timescope("InductionVariableAnalysisPass", data->GetMethodName(),
|
||||
data->GetMethodOffset(), data->GetLog());
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetEcmaVM()->GetJSOptions();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetCompilationEnv()->GetJSOptions();
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
InductionVariableAnalysis inductionVariableAnalysis(data->GetCircuit(), data->GetPassContext(), enableLog,
|
||||
data->GetMethodName(), &chunk,
|
||||
@ -442,6 +445,7 @@ public:
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
|
||||
TypedHCRLowering lowering(data->GetCircuit(),
|
||||
data->GetPassContext()->GetCompilationEnv(),
|
||||
&visitor,
|
||||
data->GetCompilerConfig(),
|
||||
data->GetTSManager(),
|
||||
@ -686,7 +690,7 @@ public:
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog() || data->GetLog()->EnableMethodASMLog();
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetEcmaVM()->GetJSOptions();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetCompilationEnv()->GetJSOptions();
|
||||
EarlyElimination earlyElimination(data->GetCircuit(), &visitor, &chunk, runtimeOption.IsEnableMemoryAnalysis());
|
||||
visitor.AddPass(&earlyElimination);
|
||||
visitor.VisitGraph();
|
||||
@ -724,7 +728,7 @@ public:
|
||||
if (!passOptions->EnableTypeLowering() || !passOptions->EnableValueNumbering()) {
|
||||
return false;
|
||||
}
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetEcmaVM()->GetJSOptions();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetCompilationEnv()->GetJSOptions();
|
||||
TimeScope timescope("ValueNumberingPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
@ -743,7 +747,7 @@ class InstructionCombinePass {
|
||||
public:
|
||||
bool Run(PassData *data)
|
||||
{
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetEcmaVM()->GetJSOptions();
|
||||
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetCompilationEnv()->GetJSOptions();
|
||||
if (runtimeOption.IsEnableInstrcutionCombine()) {
|
||||
TimeScope timescope("InstructionCombinePass", data->GetMethodName(), data->GetMethodOffset(),
|
||||
data->GetLog());
|
||||
@ -799,7 +803,7 @@ public:
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
bool licm = data->GetPassOptions()->EnableOptLoopInvariantCodeMotion();
|
||||
bool liteCG = data->GetPassContext()->GetEcmaVM()->GetJSOptions().IsCompilerEnableLiteCG();
|
||||
bool liteCG = data->GetPassContext()->GetCompilationEnv()->GetJSOptions().IsCompilerEnableLiteCG();
|
||||
GraphLinearizer(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk, false, licm, liteCG)
|
||||
.Run(data->GetCfg());
|
||||
PostSchedule(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk).Run(data->GetCfg());
|
||||
|
@ -22,27 +22,25 @@
|
||||
#include "ecmascript/log.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
using PGOProfilerManager = pgo::PGOProfilerManager;
|
||||
bool JitPassManager::Compile(JSHandle<JSFunction> &jsFunction, AOTFileGenerator &gen, int32_t osrOffset)
|
||||
bool JitPassManager::Compile(AOTFileGenerator &gen, int32_t osrOffset)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(vm_->GetJSThread());
|
||||
const JSPandaFile *jsPandaFile = Method::Cast(jsFunction->GetMethod().GetTaggedObject())->GetJSPandaFile();
|
||||
const JSPandaFile *jsPandaFile = compilationEnv_->GetJSPandaFile();
|
||||
MethodLiteral *methodLiteral = compilationEnv_->GetMethodLiteral();
|
||||
|
||||
collector_ = new BytecodeInfoCollector(vm_, const_cast<JSPandaFile*>(jsPandaFile),
|
||||
jsFunction, profilerDecoder_, passOptions_->EnableCollectLiteralInfo());
|
||||
collector_ = new BytecodeInfoCollector(compilationEnv_, const_cast<JSPandaFile*>(jsPandaFile),
|
||||
profilerDecoder_, passOptions_->EnableCollectLiteralInfo());
|
||||
std::string fileName = jsPandaFile->GetFileName();
|
||||
if (!IsReleasedPandaFile(jsPandaFile)) {
|
||||
LOG_COMPILER(ERROR) << "The input panda file [" << fileName << "] is debuggable version.";
|
||||
}
|
||||
|
||||
gen.SetCurrentCompileFileName(jsPandaFile->GetNormalizedFileDesc());
|
||||
lOptions_ = new LOptions(optLevel_, FPFlag::RESERVE_FP, relocMode_);
|
||||
cmpDriver_ = new JitCompilationDriver(profilerDecoder_,
|
||||
collector_,
|
||||
vm_->GetJSOptions().GetCompilerSelectMethods(),
|
||||
vm_->GetJSOptions().GetCompilerSkipMethods(),
|
||||
compilationEnv_->GetJSOptions().GetCompilerSelectMethods(),
|
||||
compilationEnv_->GetJSOptions().GetCompilerSkipMethods(),
|
||||
&gen,
|
||||
fileName,
|
||||
triple_,
|
||||
@ -50,15 +48,15 @@ bool JitPassManager::Compile(JSHandle<JSFunction> &jsFunction, AOTFileGenerator
|
||||
log_,
|
||||
log_->OutputASM(),
|
||||
maxMethodsInModule_,
|
||||
vm_->GetJSOptions().GetCompilerMethodsRange());
|
||||
cmpDriver_->CompileMethod(jsFunction, [this, &fileName, &osrOffset] (const CString recordName,
|
||||
compilationEnv_->GetJSOptions().GetCompilerMethodsRange());
|
||||
cmpDriver_->CompileMethod(jsPandaFile, methodLiteral, [this, &fileName, &osrOffset] (const CString recordName,
|
||||
const std::string &methodName,
|
||||
MethodLiteral *methodLiteral,
|
||||
uint32_t methodOffset,
|
||||
const MethodPcInfo &methodPCInfo,
|
||||
MethodInfo &methodInfo,
|
||||
Module *m) {
|
||||
if (vm_->GetJSOptions().GetTraceJIT()) {
|
||||
if (compilationEnv_->GetJSOptions().GetTraceJIT()) {
|
||||
LOG_COMPILER(INFO) << "JIT Compile Method Start: " << methodName << ", " << methodOffset << "\n";
|
||||
}
|
||||
ctx_ = new PassContext(triple_, log_, collector_, m->GetModule(), &profilerDecoder_);
|
||||
@ -79,13 +77,14 @@ bool JitPassManager::Compile(JSHandle<JSFunction> &jsFunction, AOTFileGenerator
|
||||
LOG_COMPILER(INFO) << "record: " << recordName << " has no types";
|
||||
}
|
||||
|
||||
circuit_ = new Circuit(vm_->GetNativeAreaAllocator(), ctx_->GetAOTModule()->GetDebugInfo(),
|
||||
circuit_ = new Circuit(compilationEnv_->GetNativeAreaAllocator(), ctx_->GetAOTModule()->GetDebugInfo(),
|
||||
fullName.c_str(), cmpCfg->Is64Bit(), FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||
PGOProfilerDecoder *decoder = passOptions_->EnableOptPGOType() ? &profilerDecoder_ : nullptr;
|
||||
|
||||
builder_ = new BytecodeCircuitBuilder(jsPandaFile, methodLiteral, methodPCInfo,
|
||||
circuit_, ctx_->GetByteCodes(), enableMethodLog && log_->OutputCIR(),
|
||||
passOptions_->EnableTypeLowering(), fullName, recordName, decoder, false);
|
||||
|
||||
builder_->SetOsrOffset(osrOffset);
|
||||
{
|
||||
TimeScope timeScope("BytecodeToCircuit", methodName, methodOffset, log_);
|
||||
@ -94,31 +93,38 @@ bool JitPassManager::Compile(JSHandle<JSFunction> &jsFunction, AOTFileGenerator
|
||||
|
||||
data_ = new PassData(builder_, circuit_, ctx_, log_, fullName, &methodInfo, hasTypes, recordName,
|
||||
methodLiteral, methodOffset, nullptr, CVector<AbcFileInfo> {},
|
||||
vm_->GetNativeAreaAllocator(), decoder, passOptions_);
|
||||
compilationEnv_->GetNativeAreaAllocator(), decoder, passOptions_);
|
||||
PassRunner<PassData> pipeline(data_);
|
||||
if (data_->GetMethodLiteral()->HasDebuggerStmt()) {
|
||||
data_->AbortCompilation();
|
||||
return;
|
||||
}
|
||||
|
||||
pipeline.RunPass<RunFlowCyclesVerifierPass>();
|
||||
pipeline.RunPass<RedundantPhiEliminationPass>();
|
||||
if (builder_->EnableLoopOptimization()) {
|
||||
pipeline.RunPass<LoopOptimizationPass>();
|
||||
pipeline.RunPass<RedundantPhiEliminationPass>();
|
||||
}
|
||||
pipeline.RunPass<PGOTypeInferPass>();
|
||||
pipeline.RunPass<TSClassAnalysisPass>();
|
||||
pipeline.RunPass<TSInlineLoweringPass>();
|
||||
// support when remove tsmanager in pass
|
||||
const bool enablepass = false;
|
||||
if (enablepass) {
|
||||
{
|
||||
Jit::JitLockHolder lock(compilationEnv_, "PGOTypeInferPass");
|
||||
pipeline.RunPass<PGOTypeInferPass>();
|
||||
}
|
||||
{
|
||||
Jit::JitLockHolder lock(compilationEnv_, "TSClassAnalysisPass");
|
||||
pipeline.RunPass<TSClassAnalysisPass>();
|
||||
}
|
||||
{
|
||||
Jit::JitLockHolder lock(compilationEnv_, "TSInlineLoweringPass");
|
||||
pipeline.RunPass<TSInlineLoweringPass>();
|
||||
}
|
||||
}
|
||||
|
||||
pipeline.RunPass<RedundantPhiEliminationPass>();
|
||||
pipeline.RunPass<AsyncFunctionLoweringPass>();
|
||||
pipeline.RunPass<TypeBytecodeLoweringPass>();
|
||||
pipeline.RunPass<InductionVariableAnalysisPass>();
|
||||
pipeline.RunPass<RedundantPhiEliminationPass>();
|
||||
pipeline.RunPass<NTypeBytecodeLoweringPass>();
|
||||
if (data_->IsTypeAbort()) {
|
||||
data_->AbortCompilation();
|
||||
return;
|
||||
}
|
||||
pipeline.RunPass<EarlyEliminationPass>();
|
||||
pipeline.RunPass<NumberSpeculativePass>();
|
||||
pipeline.RunPass<LaterEliminationPass>();
|
||||
@ -152,41 +158,41 @@ bool JitPassManager::RunCg()
|
||||
|
||||
JitPassManager::~JitPassManager()
|
||||
{
|
||||
if (collector_ != nullptr) {
|
||||
delete collector_;
|
||||
collector_ = nullptr;
|
||||
}
|
||||
if (lOptions_ != nullptr) {
|
||||
delete lOptions_;
|
||||
lOptions_ = nullptr;
|
||||
}
|
||||
if (cmpDriver_ != nullptr) {
|
||||
delete cmpDriver_;
|
||||
cmpDriver_ = nullptr;
|
||||
}
|
||||
if (ctx_ != nullptr) {
|
||||
delete ctx_;
|
||||
ctx_ = nullptr;
|
||||
}
|
||||
if (circuit_ != nullptr) {
|
||||
delete circuit_;
|
||||
circuit_ = nullptr;
|
||||
if (data_ != nullptr) {
|
||||
delete data_;
|
||||
data_ = nullptr;
|
||||
}
|
||||
if (builder_ != nullptr) {
|
||||
delete builder_;
|
||||
builder_ = nullptr;
|
||||
}
|
||||
if (data_ != nullptr) {
|
||||
delete data_;
|
||||
data_ = nullptr;
|
||||
if (circuit_ != nullptr) {
|
||||
delete circuit_;
|
||||
circuit_ = nullptr;
|
||||
}
|
||||
if (ctx_ != nullptr) {
|
||||
delete ctx_;
|
||||
ctx_ = nullptr;
|
||||
}
|
||||
if (cmpDriver_ != nullptr) {
|
||||
delete cmpDriver_;
|
||||
cmpDriver_ = nullptr;
|
||||
}
|
||||
if (lOptions_ != nullptr) {
|
||||
delete lOptions_;
|
||||
lOptions_ = nullptr;
|
||||
}
|
||||
if (collector_ != nullptr) {
|
||||
delete collector_;
|
||||
collector_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName, AOTFileGenerator &gen)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(vm_->GetJSThread());
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(compilationEnv_->GetJSThread());
|
||||
|
||||
BytecodeInfoCollector collector(vm_, jsPandaFile, profilerDecoder_,
|
||||
BytecodeInfoCollector collector(compilationEnv_, jsPandaFile, profilerDecoder_,
|
||||
maxAotMethodSize_, passOptions_->EnableCollectLiteralInfo());
|
||||
// Checking released/debuggable pandafile uses method literals, which are initialized in BytecodeInfoCollector,
|
||||
// should after it.
|
||||
@ -198,8 +204,8 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName,
|
||||
LOptions lOptions(optLevel_, FPFlag::RESERVE_FP, relocMode_);
|
||||
CompilationDriver cmpDriver(profilerDecoder_,
|
||||
&collector,
|
||||
vm_->GetJSOptions().GetCompilerSelectMethods(),
|
||||
vm_->GetJSOptions().GetCompilerSkipMethods(),
|
||||
compilationEnv_->GetJSOptions().GetCompilerSelectMethods(),
|
||||
compilationEnv_->GetJSOptions().GetCompilerSkipMethods(),
|
||||
&gen,
|
||||
fileName,
|
||||
triple_,
|
||||
@ -207,7 +213,7 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName,
|
||||
log_,
|
||||
log_->OutputASM(),
|
||||
maxMethodsInModule_,
|
||||
vm_->GetJSOptions().GetCompilerMethodsRange());
|
||||
compilationEnv_->GetJSOptions().GetCompilerMethodsRange());
|
||||
|
||||
cmpDriver.Run([this, &fileName, &collector](const CString recordName,
|
||||
const std::string &methodName,
|
||||
@ -233,7 +239,7 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName,
|
||||
LOG_COMPILER(INFO) << "record: " << recordName << " has no types";
|
||||
}
|
||||
|
||||
Circuit circuit(vm_->GetNativeAreaAllocator(), ctx.GetAOTModule()->GetDebugInfo(),
|
||||
Circuit circuit(compilationEnv_->GetNativeAreaAllocator(), ctx.GetAOTModule()->GetDebugInfo(),
|
||||
fullName.c_str(), cmpCfg->Is64Bit(), FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||
|
||||
PGOProfilerDecoder *decoder = passOptions_->EnableOptPGOType() ? &profilerDecoder_ : nullptr;
|
||||
@ -248,7 +254,7 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName,
|
||||
|
||||
PassData data(&builder, &circuit, &ctx, log_, fullName, &methodInfo, hasTypes, recordName,
|
||||
methodLiteral, methodOffset, callMethodFlagMap_, fileInfos_,
|
||||
vm_->GetNativeAreaAllocator(), decoder, passOptions_,
|
||||
compilationEnv_->GetNativeAreaAllocator(), decoder, passOptions_,
|
||||
optBCRange_);
|
||||
PassRunner<PassData> pipeline(&data);
|
||||
if (data.GetMethodLiteral()->HasDebuggerStmt()) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define ECMASCRIPT_COMPILER_PASS_MANAGER_H
|
||||
|
||||
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
||||
#include "ecmascript/compiler/jit_compilation_env.h"
|
||||
#include "ecmascript/compiler/bytecode_info_collector.h"
|
||||
#include "ecmascript/compiler/compiler_log.h"
|
||||
#include "ecmascript/compiler/file_generators.h"
|
||||
@ -34,17 +35,16 @@ class CompilationConfig;
|
||||
class PassData;
|
||||
class CallMethodFlagMap;
|
||||
struct AbcFileInfo;
|
||||
|
||||
class PassContext {
|
||||
public:
|
||||
PassContext(const std::string &triple, CompilerLog *log, BytecodeInfoCollector* collector, IRModule *aotModule,
|
||||
PGOProfilerDecoder *decoder)
|
||||
: vm_(collector->GetVM()),
|
||||
: compilationEnv_(collector->GetCompilationEnv()),
|
||||
bcInfoCollector_(collector),
|
||||
tsManager_(vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()),
|
||||
tsManager_(compilationEnv_->GetTSManager()),
|
||||
bytecodes_(collector->GetByteCodes()),
|
||||
lexEnvManager_(bcInfoCollector_->GetEnvManager()),
|
||||
cmpCfg_(triple, &vm_->GetJSOptions()),
|
||||
cmpCfg_(triple, &compilationEnv_->GetJSOptions()),
|
||||
log_(log),
|
||||
jsPandaFile_(collector->GetJSPandaFile()),
|
||||
aotModule_(aotModule),
|
||||
@ -59,7 +59,7 @@ public:
|
||||
|
||||
PGOTypeManager* GetPTManager() const
|
||||
{
|
||||
return vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
|
||||
return compilationEnv_->GetPTManager();
|
||||
}
|
||||
|
||||
Bytecodes* GetByteCodes()
|
||||
@ -114,12 +114,12 @@ public:
|
||||
|
||||
NativeAreaAllocator *GetNativeAreaAllocator() const
|
||||
{
|
||||
return vm_->GetNativeAreaAllocator();
|
||||
return compilationEnv_->GetNativeAreaAllocator();
|
||||
}
|
||||
|
||||
EcmaVM *GetEcmaVM() const
|
||||
CompilationEnv *GetCompilationEnv() const
|
||||
{
|
||||
return vm_;
|
||||
return compilationEnv_;
|
||||
}
|
||||
|
||||
PGOProfilerDecoder *GetPfDecoder() const
|
||||
@ -128,7 +128,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
EcmaVM *vm_ {nullptr};
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
BytecodeInfoCollector *bcInfoCollector_ {nullptr};
|
||||
TSManager *tsManager_ {nullptr};
|
||||
Bytecodes *bytecodes_ {nullptr};
|
||||
@ -142,15 +142,15 @@ private:
|
||||
|
||||
class PassManager {
|
||||
public:
|
||||
explicit PassManager(EcmaVM* vm, std::string &triple, size_t optLevel, size_t relocMode,
|
||||
explicit PassManager(CompilationEnv *env, std::string &triple, size_t optLevel, size_t relocMode,
|
||||
CompilerLog *log, AotMethodLogList *logList, size_t maxAotMethodSize, size_t maxMethodsInModule,
|
||||
PGOProfilerDecoder &profilerDecoder, PassOptions *passOptions,
|
||||
const CallMethodFlagMap *callMethodFlagMap, const CVector<AbcFileInfo> &fileInfos, std::string optBCRange)
|
||||
: vm_(vm), triple_(triple), optLevel_(optLevel), relocMode_(relocMode), log_(log),
|
||||
: compilationEnv_(env), triple_(triple), optLevel_(optLevel), relocMode_(relocMode), log_(log),
|
||||
logList_(logList), maxAotMethodSize_(maxAotMethodSize), maxMethodsInModule_(maxMethodsInModule),
|
||||
profilerDecoder_(profilerDecoder), passOptions_(passOptions),
|
||||
callMethodFlagMap_(callMethodFlagMap), fileInfos_(fileInfos), optBCRange_(optBCRange) {
|
||||
enableJITLog_ = vm_->GetJSOptions().GetTraceJIT();
|
||||
enableJITLog_ = compilationEnv_->GetJSOptions().GetTraceJIT();
|
||||
};
|
||||
|
||||
virtual ~PassManager() = default;
|
||||
@ -159,7 +159,7 @@ public:
|
||||
protected:
|
||||
bool IsReleasedPandaFile(const JSPandaFile *jsPandaFile) const;
|
||||
|
||||
EcmaVM *vm_ {nullptr};
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
std::string triple_ {};
|
||||
size_t optLevel_ {3}; // 3 : default backend optimization level
|
||||
size_t relocMode_ {2}; // 2 : default relocation mode-- PIC
|
||||
@ -177,13 +177,13 @@ protected:
|
||||
|
||||
class JitPassManager : public PassManager {
|
||||
public:
|
||||
JitPassManager(EcmaVM* vm, std::string &triple, size_t optLevel, size_t relocMode,
|
||||
JitPassManager(JitCompilationEnv *env, std::string &triple, size_t optLevel, size_t relocMode,
|
||||
CompilerLog *log, AotMethodLogList *logList,
|
||||
PGOProfilerDecoder &profilerDecoder, PassOptions *passOptions)
|
||||
: PassManager(vm, triple, optLevel, relocMode, log, logList, 1, 1, profilerDecoder, passOptions,
|
||||
: PassManager(env, triple, optLevel, relocMode, log, logList, 1, 1, profilerDecoder, passOptions,
|
||||
nullptr, CVector<AbcFileInfo> {}, "") { };
|
||||
|
||||
bool Compile(JSHandle<JSFunction> &jsFunction, AOTFileGenerator &gen, int32_t osrOffset = -1);
|
||||
bool Compile(AOTFileGenerator &gen, int32_t osrOffset = -1);
|
||||
bool RunCg();
|
||||
virtual ~JitPassManager();
|
||||
|
||||
|
@ -1544,7 +1544,7 @@ GateRef SlowPathLowering::LowerUpdateArrayHClass(GateRef gate, GateRef array)
|
||||
{
|
||||
ElementsKind kind = acc_.TryGetElementsKind(gate);
|
||||
if (!Elements::IsGeneric(kind)) {
|
||||
size_t hclassIndex = static_cast<size_t>(thread_->GetArrayHClassIndexMap().at(kind));
|
||||
size_t hclassIndex = static_cast<size_t>(compilationEnv_->GetArrayHClassIndexMap().at(kind));
|
||||
GateRef gConstAddr = builder_.Load(VariableType::JS_POINTER(), glue_,
|
||||
builder_.IntPtr(JSThread::GlueData::GetGlobalConstOffset(false)));
|
||||
GateRef constantIndex = builder_.IntPtr(JSTaggedValue::TaggedTypeSize() * hclassIndex);
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
SlowPathLowering(Circuit *circuit, CompilationConfig *cmpCfg,
|
||||
PassContext *ctx, const MethodLiteral *methodLiteral,
|
||||
bool enableLog, const std::string& name)
|
||||
: thread_(ctx->GetEcmaVM()->GetJSThread()), methodLiteral_(methodLiteral),
|
||||
: compilationEnv_(ctx->GetCompilationEnv()), methodLiteral_(methodLiteral),
|
||||
circuit_(circuit), acc_(circuit),
|
||||
argAcc_(circuit), builder_(circuit, cmpCfg),
|
||||
enableLog_(enableLog), methodName_(name), glue_(acc_.GetGlueFromArgList())
|
||||
@ -320,7 +320,7 @@ private:
|
||||
void LowerLdStr(GateRef gate);
|
||||
void LowerGetConstPool(GateRef gate);
|
||||
|
||||
JSThread *thread_;
|
||||
CompilationEnv *compilationEnv_;
|
||||
const MethodLiteral *methodLiteral_ {nullptr};
|
||||
Circuit *circuit_;
|
||||
GateAccessor acc_;
|
||||
|
@ -58,7 +58,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, LoadTypedArrayLength)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "LoadTypedArrayLength", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -88,7 +88,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int32ArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int32ArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -125,7 +125,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int32OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int32OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -157,7 +157,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Float64OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Float64OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -189,7 +189,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, FLOAT32OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "FLOAT32OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -224,7 +224,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int8OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int8OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -259,7 +259,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, UInt8OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "UInt8OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -294,7 +294,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int16OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int16OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -329,7 +329,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, UInt16OnHeapArrayLoadElement)
|
||||
builder.Return(convert);
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "UInt16OnHeapArrayLoadElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -363,7 +363,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int32ArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int32ArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -400,7 +400,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int32OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int32OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -432,7 +432,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Float64OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Float64OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -464,7 +464,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int8OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int8OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -498,7 +498,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, UInt8OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "UInt8OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -532,7 +532,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Int16OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Int16OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -566,7 +566,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, UInt16OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "UInt16OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
@ -600,7 +600,7 @@ HWTEST_F_L0(TypedArrayLoweringTests, Float32OnHeapArrayStoreElement)
|
||||
auto ret = builder.Return(builder.Undefined());
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
CombinedPassVisitor visitor(&circuit, false, "Float32OnHeapArrayStoreElement", &chunk);
|
||||
TypedHCRLowering lowering(&circuit, &visitor, nullptr, nullptr, &chunk, false);
|
||||
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, nullptr, &chunk, false);
|
||||
visitor.AddPass(&lowering);
|
||||
visitor.VisitGraph();
|
||||
EXPECT_TRUE(Verifier::Run(&circuit));
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/compiler/ts_hcr_opt_pass.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
|
||||
@ -41,8 +42,10 @@ GateRef TSHCROptPass::VisitStringBinOp(GateRef gate)
|
||||
{
|
||||
TypedBinOp op = acc_.GetTypedBinaryOp(gate);
|
||||
switch (op) {
|
||||
case TypedBinOp::TYPED_EQ:
|
||||
case TypedBinOp::TYPED_EQ: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "VisitStringEqual");
|
||||
return VisitStringEqual(gate);
|
||||
}
|
||||
default:
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
@ -79,10 +82,9 @@ GateRef TSHCROptPass::ConvertStringEqualToConst(GateRef left, GateRef right)
|
||||
|
||||
auto leftMethodOffset = acc_.TryGetMethodOffset(left);
|
||||
auto rightMethodOffset = acc_.TryGetMethodOffset(right);
|
||||
JSHandle<EcmaString> leftStr(thread_, GetStringFromConstantPool(leftMethodOffset, leftId));
|
||||
JSHandle<EcmaString> rightStr(thread_, GetStringFromConstantPool(rightMethodOffset, rightId));
|
||||
bool isEqual = EcmaStringAccessor::StringsAreEqual(thread_->GetEcmaVM(), leftStr, rightStr);
|
||||
if (isEqual) {
|
||||
JSTaggedValue leftStr = GetStringFromConstantPool(leftMethodOffset, leftId);
|
||||
JSTaggedValue rightStr = GetStringFromConstantPool(rightMethodOffset, rightId);
|
||||
if (leftStr == rightStr) {
|
||||
return builder_.Boolean(true);
|
||||
}
|
||||
return builder_.Boolean(false);
|
||||
|
@ -27,8 +27,7 @@ public:
|
||||
PassContext *ctx, bool enableLog, const std::string &name)
|
||||
: PassVisitor(circuit, chunk, visitor),
|
||||
builder_(circuit, ctx->GetCompilerConfig()),
|
||||
ptManager_(ctx->GetPTManager()),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()),
|
||||
compilationEnv_(ctx->GetCompilationEnv()),
|
||||
enableLog_(enableLog),
|
||||
methodName_(name) {}
|
||||
|
||||
@ -49,7 +48,7 @@ private:
|
||||
|
||||
JSTaggedValue GetStringFromConstantPool(uint32_t methodOffset, uint32_t cpIdx) const
|
||||
{
|
||||
return ptManager_->GetStringFromConstantPool(methodOffset, cpIdx);
|
||||
return compilationEnv_->GetStringFromConstantPool(methodOffset, cpIdx);
|
||||
}
|
||||
|
||||
GateRef VisitTypedBinaryOp(GateRef gate);
|
||||
@ -63,8 +62,7 @@ private:
|
||||
GateRef ConvertToSingleCharComparison(GateRef left, GateRef right);
|
||||
|
||||
CircuitBuilder builder_;
|
||||
PGOTypeManager *ptManager_ {nullptr};
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
bool enableLog_ {false};
|
||||
std::string methodName_;
|
||||
};
|
||||
|
@ -329,7 +329,7 @@ GateRef TSInlineLowering::BuildAccessor(InlineTypeInfoAccessor &info)
|
||||
ASSERT(pgoTypes->GetCount() == 1);
|
||||
auto pgoType = pgoTypes->GetObjectInfo(0);
|
||||
ProfileTyper holderType = std::make_pair(pgoType.GetHoldRootType(), pgoType.GetHoldType());
|
||||
PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
int holderHCIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(holderType));
|
||||
ASSERT(ptManager->QueryHClass(holderType.first, holderType.second).IsJSHClass());
|
||||
ArgumentAccessor argAcc(circuit_);
|
||||
@ -526,7 +526,7 @@ void TSInlineLowering::InlineAccessorCheck(const InlineTypeInfoAccessor &info)
|
||||
ASSERT(pgoTypes->GetCount() == 1);
|
||||
auto pgoType = pgoTypes->GetObjectInfo(0);
|
||||
ProfileTyper receiverType = std::make_pair(pgoType.GetReceiverRootType(), pgoType.GetReceiverType());
|
||||
PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
int receiverHCIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(receiverType));
|
||||
ASSERT(ptManager->QueryHClass(receiverType.first, receiverType.second).IsJSHClass());
|
||||
|
||||
@ -644,9 +644,9 @@ bool TSInlineLowering::IsRecursiveFunc(InlineTypeInfoAccessor &info, size_t call
|
||||
void TSInlineLowering::CandidateAccessor(GateRef gate, ChunkQueue<InlineTypeInfoAccessor> &workList, CallKind kind)
|
||||
{
|
||||
GateRef receiver = GetAccessorReceiver(gate);
|
||||
InlineTypeInfoAccessor tacc(thread_, circuit_, gate, receiver, kind);
|
||||
InlineTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, receiver, kind);
|
||||
if (tacc.IsEnableAccessorInline()) {
|
||||
workList.emplace(thread_, circuit_, gate, receiver, kind);
|
||||
workList.emplace(compilationEnv_, circuit_, gate, receiver, kind);
|
||||
lastCallId_ = acc_.GetId(gate);
|
||||
}
|
||||
}
|
||||
@ -655,7 +655,7 @@ void TSInlineLowering::CandidateNormalCall(GateRef gate, ChunkQueue<InlineTypeIn
|
||||
{
|
||||
size_t funcIndex = acc_.GetNumValueIn(gate) - 1;
|
||||
auto func = acc_.GetValueIn(gate, funcIndex);
|
||||
InlineTypeInfoAccessor tacc(thread_, circuit_, gate, func, kind);
|
||||
InlineTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, func, kind);
|
||||
if (tacc.IsEnableNormalInline()) {
|
||||
workList.push(tacc);
|
||||
lastCallId_ = acc_.GetId(gate);
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
TSInlineLowering(Circuit *circuit, PassContext *ctx, bool enableLog, const std::string& name,
|
||||
NativeAreaAllocator* nativeAreaAllocator, PassOptions *options, uint32_t methodOffset)
|
||||
: circuit_(circuit),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()),
|
||||
compilationEnv_(ctx->GetCompilationEnv()),
|
||||
acc_(circuit),
|
||||
glue_(acc_.GetGlueFromArgList()),
|
||||
builder_(circuit, ctx->GetCompilerConfig()),
|
||||
@ -55,11 +55,11 @@ public:
|
||||
passOptions_(options),
|
||||
enableLog_(enableLog),
|
||||
methodName_(name),
|
||||
enableTypeLowering_(ctx->GetEcmaVM()->GetJSOptions().IsEnableTypeLowering()),
|
||||
traceInline_(ctx->GetEcmaVM()->GetJSOptions().GetTraceInline()),
|
||||
maxInlineBytecodesCount_(ctx->GetEcmaVM()->GetJSOptions().GetMaxInlineBytecodes()),
|
||||
enableTypeLowering_(ctx->GetCompilationEnv()->GetJSOptions().IsEnableTypeLowering()),
|
||||
traceInline_(ctx->GetCompilationEnv()->GetJSOptions().GetTraceInline()),
|
||||
maxInlineBytecodesCount_(ctx->GetCompilationEnv()->GetJSOptions().GetMaxInlineBytecodes()),
|
||||
nativeAreaAllocator_(nativeAreaAllocator),
|
||||
noCheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()),
|
||||
noCheck_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerNoCheck()),
|
||||
chunk_(circuit->chunk()),
|
||||
inlinedCallMap_(circuit->chunk()),
|
||||
argAcc_(circuit),
|
||||
@ -138,7 +138,7 @@ private:
|
||||
uint32_t GetAccessorConstpoolId(InlineTypeInfoAccessor &info);
|
||||
|
||||
Circuit *circuit_ {nullptr};
|
||||
JSThread *thread_ {nullptr};
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
GateAccessor acc_;
|
||||
GateRef glue_;
|
||||
CircuitBuilder builder_;
|
||||
|
@ -262,7 +262,7 @@ void PGOTypeInfer::UpdateTypeForRWOp(GateRef gate, GateRef receiver, uint32_t pr
|
||||
JSTaggedValue prop = JSTaggedValue::Undefined();
|
||||
if (propIndex != INVALID_INDEX) {
|
||||
auto methodOffset = acc_.TryGetMethodOffset(gate);
|
||||
prop = ptManager_->GetStringFromConstantPool(methodOffset, propIndex);
|
||||
prop = compilationEnv_->GetStringFromConstantPool(methodOffset, propIndex);
|
||||
}
|
||||
ChunkSet<GateType> inferTypes = helper_.GetInferTypes(chunk_, types, prop);
|
||||
AddProfiler(gate, tsType, *pgoRwTypes, inferTypes);
|
||||
|
@ -26,10 +26,10 @@ struct CollectedType;
|
||||
class PGOTypeInfer {
|
||||
public:
|
||||
PGOTypeInfer(Circuit *circuit, TSManager *tsManager, PGOTypeManager *ptManager, BytecodeCircuitBuilder *builder,
|
||||
const std::string &name, Chunk *chunk, bool enableLog)
|
||||
const std::string &name, Chunk *chunk, bool enableLog, CompilationEnv *env)
|
||||
: circuit_(circuit), acc_(circuit), argAcc_(circuit), tsManager_(tsManager),
|
||||
ptManager_(ptManager), helper_(tsManager), builder_(builder), methodName_(name), chunk_(chunk),
|
||||
enableLog_(enableLog), profiler_(chunk) {}
|
||||
enableLog_(enableLog), profiler_(chunk), compilationEnv_(env) {}
|
||||
~PGOTypeInfer() = default;
|
||||
|
||||
void Run();
|
||||
@ -89,13 +89,14 @@ private:
|
||||
GateAccessor acc_;
|
||||
ArgumentAccessor argAcc_;
|
||||
TSManager *tsManager_ {nullptr};
|
||||
PGOTypeManager *ptManager_ {nullptr};
|
||||
[[maybe_unused]] PGOTypeManager *ptManager_ {nullptr};
|
||||
PGOTypeInferHelper helper_;
|
||||
BytecodeCircuitBuilder *builder_ {nullptr};
|
||||
const std::string &methodName_;
|
||||
Chunk *chunk_ {nullptr};
|
||||
bool enableLog_ {false};
|
||||
Profiler profiler_;
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
};
|
||||
} // panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_TYPE_INFERENCE_PGO_TYPE_INFER_H
|
||||
|
@ -23,11 +23,6 @@
|
||||
#include "ecmascript/ts_types/ts_type_accessor.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
JSTaggedValue TypeInfoAccessor::GetStringFromConstantPool(const JSThread *thread, uint32_t methodId, uint32_t index)
|
||||
{
|
||||
return thread->GetCurrentEcmaContext()->GetPTManager()->GetStringFromConstantPool(methodId, index);
|
||||
}
|
||||
|
||||
ParamType TypeInfoAccessor::PGOSampleTypeToParamType() const
|
||||
{
|
||||
if (pgoType_.IsPGOSampleType()) {
|
||||
@ -200,7 +195,7 @@ bool TypeInfoAccessor::IsTrustedNumberType(GateAccessor acc, GateRef gate)
|
||||
}
|
||||
|
||||
bool TypeInfoAccessor::IsTrustedStringType(
|
||||
const JSThread *thread, Circuit *circuit, Chunk *chunk, GateAccessor acc, GateRef gate)
|
||||
const CompilationEnv *env, Circuit *circuit, Chunk *chunk, GateAccessor acc, GateRef gate)
|
||||
{
|
||||
auto op = acc.GetOpCode(gate);
|
||||
if (op == OpCode::LOAD_ELEMENT) {
|
||||
@ -216,7 +211,7 @@ bool TypeInfoAccessor::IsTrustedStringType(
|
||||
return true;
|
||||
case EcmaOpcode::LDOBJBYVALUE_IMM8_V8:
|
||||
case EcmaOpcode::LDOBJBYVALUE_IMM16_V8: {
|
||||
LoadBulitinObjTypeInfoAccessor tacc(thread, circuit, gate, chunk);
|
||||
LoadBulitinObjTypeInfoAccessor tacc(env, circuit, gate, chunk);
|
||||
if (tacc.IsMono()) {
|
||||
return tacc.IsBuiltinsString();
|
||||
}
|
||||
@ -248,8 +243,8 @@ bool TypeOfTypeInfoAccessor::IsIllegalType() const
|
||||
return true;
|
||||
}
|
||||
|
||||
SuperCallTypeInfoAccessor::SuperCallTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate)
|
||||
: TypeInfoAccessor(thread, circuit, gate)
|
||||
SuperCallTypeInfoAccessor::SuperCallTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate)
|
||||
: TypeInfoAccessor(env, circuit, gate)
|
||||
{
|
||||
ctor_ = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC);
|
||||
}
|
||||
@ -266,56 +261,56 @@ BuiltinsStubCSigns::ID CallTypeInfoAccessor::TryGetPGOBuiltinMethodId() const
|
||||
return BuiltinsStubCSigns::ID::NONE;
|
||||
}
|
||||
|
||||
GetIteratorTypeInfoAccessor::GetIteratorTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
GetIteratorTypeInfoAccessor::GetIteratorTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 0; // 0: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 0); // 1: func
|
||||
}
|
||||
|
||||
CallArg0TypeInfoAccessor::CallArg0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallArg0TypeInfoAccessor::CallArg0TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 0; // 0: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 0); // 0: func
|
||||
}
|
||||
|
||||
CallArg1TypeInfoAccessor::CallArg1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallArg1TypeInfoAccessor::CallArg1TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 1; // 1: number of argc
|
||||
value_ = acc_.GetValueIn(gate, 0); // 0: value
|
||||
func_ = acc_.GetValueIn(gate, 1); // 1: func
|
||||
}
|
||||
|
||||
CallArg2TypeInfoAccessor::CallArg2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallArg2TypeInfoAccessor::CallArg2TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 2; // 2: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 2); // 2: func
|
||||
}
|
||||
|
||||
CallArg3TypeInfoAccessor::CallArg3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallArg3TypeInfoAccessor::CallArg3TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 3; // 3: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 3); // 3: func
|
||||
}
|
||||
|
||||
CallRangeTypeInfoAccessor::CallRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallRangeTypeInfoAccessor::CallRangeTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
size_t numArgs = acc_.GetNumValueIn(gate);
|
||||
constexpr size_t callTargetIndex = 1; // acc
|
||||
@ -339,38 +334,38 @@ bool CallThisTypeInfoAccessor::CanOptimizeAsFastCall()
|
||||
return false;
|
||||
}
|
||||
|
||||
CallThis0TypeInfoAccessor::CallThis0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallThis0TypeInfoAccessor::CallThis0TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 0; // 0: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 1); // 1: func
|
||||
}
|
||||
|
||||
CallThis1TypeInfoAccessor::CallThis1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallThis1TypeInfoAccessor::CallThis1TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 1; // 1: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 2); // 2: func
|
||||
a0_ = acc_.GetValueIn(gate, 1); // 1: arg0
|
||||
}
|
||||
|
||||
CallThis2TypeInfoAccessor::CallThis2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallThis2TypeInfoAccessor::CallThis2TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 2; // 2: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 3); // 3: func
|
||||
}
|
||||
|
||||
CallThis3TypeInfoAccessor::CallThis3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallThis3TypeInfoAccessor::CallThis3TypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
argc_ = 3; // 3: number of argc
|
||||
func_ = acc_.GetValueIn(gate, 4); // 4: func
|
||||
@ -379,10 +374,10 @@ CallThis3TypeInfoAccessor::CallThis3TypeInfoAccessor(const JSThread *thread, Cir
|
||||
a2_ = acc_.GetValueIn(gate, 3); // 3: arg2
|
||||
}
|
||||
|
||||
CallThisRangeTypeInfoAccessor::CallThisRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate,
|
||||
CallThisRangeTypeInfoAccessor::CallThisRangeTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
const CallMethodFlagMap *callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallThisTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
constexpr size_t fixedInputsNum = 1;
|
||||
constexpr size_t callTargetIndex = 1; // 1: acc
|
||||
@ -393,8 +388,8 @@ CallThisRangeTypeInfoAccessor::CallThisRangeTypeInfoAccessor(const JSThread *thr
|
||||
}
|
||||
|
||||
InlineTypeInfoAccessor::InlineTypeInfoAccessor(
|
||||
const JSThread *thread, Circuit *circuit, GateRef gate, GateRef receiver, CallKind kind)
|
||||
: TypeInfoAccessor(thread, circuit, gate), receiver_(receiver), kind_(kind)
|
||||
const CompilationEnv *env, Circuit *circuit, GateRef gate, GateRef receiver, CallKind kind)
|
||||
: TypeInfoAccessor(env, circuit, gate), receiver_(receiver), kind_(kind)
|
||||
{
|
||||
if (IsCallAccessor()) {
|
||||
plr_ = GetAccessorPlr();
|
||||
@ -411,7 +406,7 @@ GlobalTSTypeRef InlineTypeInfoAccessor::GetAccessorFuncGT() const
|
||||
GateRef constData = acc_.GetValueIn(gate_, 1);
|
||||
uint16_t propIndex = acc_.GetConstantValue(constData);
|
||||
auto methodOffset = acc_.TryGetMethodOffset(gate_);
|
||||
auto prop = tsManager_->GetStringFromConstantPool(methodOffset, propIndex);
|
||||
auto prop = compilationEnv_->GetStringFromConstantPool(methodOffset, propIndex);
|
||||
GlobalTSTypeRef funcGT = tsTypeAcc.GetAccessorGT(prop, IsCallSetter());
|
||||
return funcGT;
|
||||
}
|
||||
@ -421,7 +416,7 @@ PropertyLookupResult InlineTypeInfoAccessor::GetAccessorPlr() const
|
||||
GateRef constData = acc_.GetValueIn(gate_, 1);
|
||||
uint16_t propIndex = acc_.GetConstantValue(constData);
|
||||
auto methodOffset = acc_.TryGetMethodOffset(gate_);
|
||||
auto prop = ptManager_->GetStringFromConstantPool(methodOffset, propIndex);
|
||||
auto prop = compilationEnv_->GetStringFromConstantPool(methodOffset, propIndex);
|
||||
// PGO currently does not support call, so GT is still used to support inline operations.
|
||||
// However, the original GT solution cannot support accessing the property of prototype, so it is filtered here
|
||||
if (EcmaStringAccessor(prop).ToStdString() == "prototype") {
|
||||
@ -436,7 +431,7 @@ PropertyLookupResult InlineTypeInfoAccessor::GetAccessorPlr() const
|
||||
ProfileTyper receiverType = std::make_pair(pgoType.GetReceiverRootType(), pgoType.GetReceiverType());
|
||||
ProfileTyper holderType = std::make_pair(pgoType.GetHoldRootType(), pgoType.GetHoldType());
|
||||
|
||||
PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
|
||||
JSHClass *hclass = nullptr;
|
||||
if (receiverType == holderType) {
|
||||
int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(receiverType));
|
||||
@ -452,7 +447,7 @@ PropertyLookupResult InlineTypeInfoAccessor::GetAccessorPlr() const
|
||||
hclass = JSHClass::Cast(ptManager->QueryHClass(holderType.first, holderType.second).GetTaggedObject());
|
||||
}
|
||||
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(thread_, hclass, prop);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(compilationEnv_->GetJSThread(), hclass, prop);
|
||||
return plr;
|
||||
}
|
||||
|
||||
@ -480,7 +475,7 @@ JSTaggedValue ObjectAccessTypeInfoAccessor::GetKeyTaggedValue() const
|
||||
{
|
||||
uint16_t index = acc_.GetConstantValue(key_);
|
||||
auto methodOffset = acc_.TryGetMethodOffset(GetGate());
|
||||
return TypeInfoAccessor::GetStringFromConstantPool(thread_, methodOffset, index);
|
||||
return compilationEnv_->GetStringFromConstantPool(methodOffset, index);
|
||||
}
|
||||
|
||||
bool ObjAccByNameTypeInfoAccessor::GeneratePlr(ProfileTyper type, ObjectAccessInfo &info, JSTaggedValue key) const
|
||||
@ -490,7 +485,7 @@ bool ObjAccByNameTypeInfoAccessor::GeneratePlr(ProfileTyper type, ObjectAccessIn
|
||||
return false;
|
||||
}
|
||||
JSHClass *hclass = JSHClass::Cast(ptManager_->QueryHClass(type.first, type.second).GetTaggedObject());
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(thread_, hclass, key);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(compilationEnv_->GetJSThread(), hclass, key);
|
||||
info.Set(hclassIndex, plr);
|
||||
|
||||
if (mode_ == AccessMode::LOAD) {
|
||||
@ -500,9 +495,9 @@ bool ObjAccByNameTypeInfoAccessor::GeneratePlr(ProfileTyper type, ObjectAccessIn
|
||||
return (plr.IsFound() && !plr.IsFunction());
|
||||
}
|
||||
|
||||
LoadObjByNameTypeInfoAccessor::LoadObjByNameTypeInfoAccessor(const JSThread *thread, Circuit *circuit,
|
||||
LoadObjByNameTypeInfoAccessor::LoadObjByNameTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit,
|
||||
GateRef gate, Chunk *chunk)
|
||||
: ObjAccByNameTypeInfoAccessor(thread, circuit, gate, chunk, AccessMode::LOAD), types_(chunk_)
|
||||
: ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::LOAD), types_(chunk_)
|
||||
{
|
||||
key_ = acc_.GetValueIn(gate, 1); // 1: key
|
||||
receiver_ = acc_.GetValueIn(gate, 2); // 2: receiver
|
||||
@ -555,9 +550,9 @@ bool LoadObjByNameTypeInfoAccessor::GenerateObjectAccessInfo()
|
||||
return true;
|
||||
}
|
||||
|
||||
StoreObjByNameTypeInfoAccessor::StoreObjByNameTypeInfoAccessor(const JSThread *thread, Circuit *circuit,
|
||||
StoreObjByNameTypeInfoAccessor::StoreObjByNameTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit,
|
||||
GateRef gate, Chunk *chunk)
|
||||
: ObjAccByNameTypeInfoAccessor(thread, circuit, gate, chunk, AccessMode::STORE), types_(chunk_)
|
||||
: ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::STORE), types_(chunk_)
|
||||
{
|
||||
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
|
||||
switch (ecmaOpcode) {
|
||||
@ -640,9 +635,9 @@ bool StoreObjByNameTypeInfoAccessor::GenerateObjectAccessInfo()
|
||||
return true;
|
||||
}
|
||||
|
||||
InstanceOfTypeInfoAccessor::InstanceOfTypeInfoAccessor(const JSThread *thread, Circuit *circuit,
|
||||
InstanceOfTypeInfoAccessor::InstanceOfTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit,
|
||||
GateRef gate, Chunk *chunk)
|
||||
: ObjAccByNameTypeInfoAccessor(thread, circuit, gate, chunk, AccessMode::LOAD), types_(chunk_)
|
||||
: ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::LOAD), types_(chunk_)
|
||||
{
|
||||
receiver_ = acc_.GetValueIn(gate, 1); // 2: receiver
|
||||
target_ = acc_.GetValueIn(gate, 2); // 2: the third parameter
|
||||
@ -653,7 +648,7 @@ InstanceOfTypeInfoAccessor::InstanceOfTypeInfoAccessor(const JSThread *thread, C
|
||||
|
||||
JSTaggedValue InstanceOfTypeInfoAccessor::GetKeyTaggedValue() const
|
||||
{
|
||||
JSHandle<GlobalEnv> globalEnv = thread_->GetEcmaVM()->GetGlobalEnv();
|
||||
JSHandle<GlobalEnv> globalEnv = compilationEnv_->GetGlobalEnv();
|
||||
auto hasInstanceEnvIndex = static_cast<size_t>(GlobalEnvField::HASINSTANCE_SYMBOL_INDEX);
|
||||
return globalEnv->GetGlobalEnvObjectByIndex(hasInstanceEnvIndex).GetTaggedValue();
|
||||
}
|
||||
@ -710,9 +705,9 @@ bool InstanceOfTypeInfoAccessor::GenerateObjectAccessInfo()
|
||||
return true;
|
||||
}
|
||||
|
||||
LoadBulitinObjTypeInfoAccessor::LoadBulitinObjTypeInfoAccessor(const JSThread *thread, Circuit *circuit,
|
||||
LoadBulitinObjTypeInfoAccessor::LoadBulitinObjTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit,
|
||||
GateRef gate, Chunk *chunk)
|
||||
: AccBuiltinObjTypeInfoAccessor(thread, circuit, gate, chunk, AccessMode::LOAD)
|
||||
: AccBuiltinObjTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::LOAD)
|
||||
{
|
||||
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
|
||||
switch (ecmaOpcode) {
|
||||
@ -795,9 +790,9 @@ bool AccBuiltinObjTypeInfoAccessor::CheckDuplicatedBuiltinType(ProfileType newTy
|
||||
return false;
|
||||
}
|
||||
|
||||
StoreBulitinObjTypeInfoAccessor::StoreBulitinObjTypeInfoAccessor(const JSThread *thread, Circuit *circuit,
|
||||
StoreBulitinObjTypeInfoAccessor::StoreBulitinObjTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit,
|
||||
GateRef gate, Chunk *chunk)
|
||||
: AccBuiltinObjTypeInfoAccessor(thread, circuit, gate, chunk, AccessMode::STORE)
|
||||
: AccBuiltinObjTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::STORE)
|
||||
{
|
||||
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
|
||||
switch (ecmaOpcode) {
|
||||
@ -824,35 +819,36 @@ StoreBulitinObjTypeInfoAccessor::StoreBulitinObjTypeInfoAccessor(const JSThread
|
||||
FetchBuiltinsTypes();
|
||||
}
|
||||
|
||||
CreateObjWithBufferTypeInfoAccessor::CreateObjWithBufferTypeInfoAccessor(const JSThread *thread, Circuit *circuit,
|
||||
CreateObjWithBufferTypeInfoAccessor::CreateObjWithBufferTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit,
|
||||
GateRef gate, const CString &recordName)
|
||||
: TypeInfoAccessor(thread, circuit, gate), recordName_(recordName), objHandle_(thread, JSTaggedValue::Undefined())
|
||||
: TypeInfoAccessor(env, circuit, gate), recordName_(recordName)
|
||||
{
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: number of value ins
|
||||
index_ = acc_.GetValueIn(gate, 0);
|
||||
Init();
|
||||
}
|
||||
|
||||
void CreateObjWithBufferTypeInfoAccessor::Init()
|
||||
JSTaggedValue CreateObjWithBufferTypeInfoAccessor::GetObject() const
|
||||
{
|
||||
auto imm = acc_.GetConstantValue(index_);
|
||||
auto methodOffset = acc_.TryGetMethodOffset(GetGate());
|
||||
JSTaggedValue cp = ptManager_->GetConstantPoolByMethodOffset(methodOffset);
|
||||
JSTaggedValue unsharedCp = thread_->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(cp);
|
||||
JSTaggedValue obj = ConstantPool::GetLiteralFromCache<ConstPoolType::OBJECT_LITERAL>(
|
||||
tsManager_->GetEcmaVM()->GetJSThread(), unsharedCp, imm, recordName_);
|
||||
objHandle_ = JSHandle<JSObject>(thread_, obj);
|
||||
JSTaggedValue unsharedCp = compilationEnv_->FindOrCreateUnsharedConstpool(methodOffset);
|
||||
return compilationEnv_->GetObjectLiteralFromCache(unsharedCp, imm, recordName_);
|
||||
}
|
||||
|
||||
JSTaggedValue CreateObjWithBufferTypeInfoAccessor::GetHClass() const
|
||||
{
|
||||
JSTaggedValue obj = GetObject();
|
||||
if (obj.IsUndefined()) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
auto sampleType = acc_.TryGetPGOType(gate_).GetPGODefineOpType();
|
||||
auto type = std::make_pair(sampleType->GetProfileType(), sampleType->GetProfileType());
|
||||
int hclassIndex = static_cast<int>(ptManager_->GetHClassIndexByProfileType(type));
|
||||
|
||||
JSHClass *oldClass = objHandle_->GetClass();
|
||||
JSObject *jsObj = JSObject::Cast(obj);
|
||||
JSHClass *oldClass = jsObj->GetClass();
|
||||
if (hclassIndex == -1) {
|
||||
if (objHandle_->ElementsAndPropertiesIsEmpty()) {
|
||||
if (jsObj->ElementsAndPropertiesIsEmpty()) {
|
||||
return JSTaggedValue(oldClass);
|
||||
}
|
||||
return JSTaggedValue::Undefined();
|
||||
|
@ -28,16 +28,16 @@
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class TypeInfoAccessor {
|
||||
public:
|
||||
TypeInfoAccessor(const JSThread *thread, Circuit* circuit, GateRef gate)
|
||||
: thread_(thread),
|
||||
TypeInfoAccessor(const CompilationEnv *env, Circuit* circuit, GateRef gate)
|
||||
: compilationEnv_(env),
|
||||
acc_(circuit),
|
||||
argAcc_(circuit),
|
||||
gate_(gate)
|
||||
{
|
||||
pgoType_ = acc_.TryGetPGOType(gate);
|
||||
// NOTICE-PGO: wx delete in part3
|
||||
tsManager_ = thread_->GetCurrentEcmaContext()->GetTSManager();
|
||||
ptManager_ = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
tsManager_ = compilationEnv_->GetTSManager();
|
||||
ptManager_ = compilationEnv_->GetPTManager();
|
||||
}
|
||||
|
||||
inline GateRef GetGate() const
|
||||
@ -50,15 +50,13 @@ public:
|
||||
static bool IsTrustedNumberType(GateAccessor acc, GateRef gate);
|
||||
|
||||
static bool IsTrustedStringType(
|
||||
const JSThread *thread, Circuit *circuit, Chunk *chunk, GateAccessor acc, GateRef gate);
|
||||
|
||||
static JSTaggedValue GetStringFromConstantPool(const JSThread *thread, uint32_t methodId, uint32_t index);
|
||||
const CompilationEnv *env, Circuit *circuit, Chunk *chunk, GateAccessor acc, GateRef gate);
|
||||
|
||||
protected:
|
||||
ParamType PGOSampleTypeToParamType() const;
|
||||
static ParamType PGOBuiltinTypeToParamType(ProfileType pgoType);
|
||||
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
GateAccessor acc_;
|
||||
ArgumentAccessor argAcc_;
|
||||
GateRef gate_;
|
||||
@ -70,10 +68,10 @@ protected:
|
||||
|
||||
class BinOpTypeInfoAccessor final : public TypeInfoAccessor {
|
||||
public:
|
||||
BinOpTypeInfoAccessor(const JSThread *thread,
|
||||
BinOpTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: TypeInfoAccessor(thread, circuit, gate)
|
||||
: TypeInfoAccessor(env, circuit, gate)
|
||||
{
|
||||
left_ = acc_.GetValueIn(gate, 0); // 0: left
|
||||
right_ = acc_.GetValueIn(gate, 1); // 1: right
|
||||
@ -118,10 +116,10 @@ private:
|
||||
|
||||
class UnOpTypeInfoAccessor : public TypeInfoAccessor {
|
||||
public:
|
||||
UnOpTypeInfoAccessor(const JSThread *thread,
|
||||
UnOpTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: TypeInfoAccessor(thread, circuit, gate)
|
||||
: TypeInfoAccessor(env, circuit, gate)
|
||||
{
|
||||
value_ = acc_.GetValueIn(gate, 0); // 0: value
|
||||
}
|
||||
@ -159,10 +157,10 @@ protected:
|
||||
|
||||
class ConditionJumpTypeInfoAccessor final : public UnOpTypeInfoAccessor {
|
||||
public:
|
||||
ConditionJumpTypeInfoAccessor(const JSThread *thread,
|
||||
ConditionJumpTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: UnOpTypeInfoAccessor(thread, circuit, gate) {}
|
||||
: UnOpTypeInfoAccessor(env, circuit, gate) {}
|
||||
NO_COPY_SEMANTIC(ConditionJumpTypeInfoAccessor);
|
||||
NO_MOVE_SEMANTIC(ConditionJumpTypeInfoAccessor);
|
||||
|
||||
@ -174,10 +172,10 @@ public:
|
||||
|
||||
class NewObjRangeTypeInfoAccessor final : public UnOpTypeInfoAccessor {
|
||||
public:
|
||||
NewObjRangeTypeInfoAccessor(const JSThread *thread,
|
||||
NewObjRangeTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: UnOpTypeInfoAccessor(thread, circuit, gate), hclassIndex_(-1) {}
|
||||
: UnOpTypeInfoAccessor(env, circuit, gate), hclassIndex_(-1) {}
|
||||
NO_COPY_SEMANTIC(NewObjRangeTypeInfoAccessor);
|
||||
NO_MOVE_SEMANTIC(NewObjRangeTypeInfoAccessor);
|
||||
|
||||
@ -194,10 +192,10 @@ private:
|
||||
|
||||
class NewBuiltinCtorTypeInfoAccessor final : public UnOpTypeInfoAccessor {
|
||||
public:
|
||||
NewBuiltinCtorTypeInfoAccessor(const JSThread *thread,
|
||||
NewBuiltinCtorTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: UnOpTypeInfoAccessor(thread, circuit, gate) {}
|
||||
: UnOpTypeInfoAccessor(env, circuit, gate) {}
|
||||
NO_COPY_SEMANTIC(NewBuiltinCtorTypeInfoAccessor);
|
||||
NO_MOVE_SEMANTIC(NewBuiltinCtorTypeInfoAccessor);
|
||||
|
||||
@ -208,6 +206,9 @@ public:
|
||||
|
||||
bool IsBuiltinConstructor(BuiltinTypeId type)
|
||||
{
|
||||
if (compilationEnv_->IsJitCompiler()) {
|
||||
return false;
|
||||
}
|
||||
return tsManager_->IsBuiltinConstructor(type, GetCtorGT());
|
||||
}
|
||||
|
||||
@ -220,10 +221,10 @@ private:
|
||||
|
||||
class TypeOfTypeInfoAccessor final : public UnOpTypeInfoAccessor {
|
||||
public:
|
||||
TypeOfTypeInfoAccessor(const JSThread *thread,
|
||||
TypeOfTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: UnOpTypeInfoAccessor(thread, circuit, gate) {}
|
||||
: UnOpTypeInfoAccessor(env, circuit, gate) {}
|
||||
NO_COPY_SEMANTIC(TypeOfTypeInfoAccessor);
|
||||
NO_MOVE_SEMANTIC(TypeOfTypeInfoAccessor);
|
||||
|
||||
@ -232,7 +233,7 @@ public:
|
||||
|
||||
class SuperCallTypeInfoAccessor final : public TypeInfoAccessor {
|
||||
public:
|
||||
SuperCallTypeInfoAccessor(const JSThread *thread,
|
||||
SuperCallTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate);
|
||||
NO_COPY_SEMANTIC(SuperCallTypeInfoAccessor);
|
||||
@ -240,6 +241,9 @@ public:
|
||||
|
||||
bool IsClassTypeKind() const
|
||||
{
|
||||
if (compilationEnv_->IsJitCompiler()) {
|
||||
return false;
|
||||
}
|
||||
return tsManager_->IsClassTypeKind(acc_.GetGateType(ctor_));
|
||||
}
|
||||
|
||||
@ -259,12 +263,12 @@ private:
|
||||
|
||||
class CallTypeInfoAccessor : public TypeInfoAccessor {
|
||||
public:
|
||||
CallTypeInfoAccessor(const JSThread *thread,
|
||||
CallTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
const CallMethodFlagMap *callMethodFlagMap = nullptr)
|
||||
: TypeInfoAccessor(thread, circuit, gate),
|
||||
: TypeInfoAccessor(env, circuit, gate),
|
||||
argc_(0),
|
||||
func_(Circuit::NullGate()),
|
||||
jsPandaFile_(jsPandaFile),
|
||||
@ -348,8 +352,8 @@ public:
|
||||
panda_file::IndexAccessor indexAccessor(*(jsPandaFile_->GetPandaFile()),
|
||||
panda_file::File::EntityId(methodId));
|
||||
uint32_t cpId = static_cast<uint32_t>(indexAccessor.GetHeaderIndex());
|
||||
JSHandle<ConstantPool> constpoolHandle(thread_,
|
||||
thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, cpId));
|
||||
ConstantPool *constpoolHandle =
|
||||
ConstantPool::Cast(compilationEnv_->FindConstpool(jsPandaFile_, cpId).GetTaggedObject());
|
||||
return constpoolHandle->GetMethodIndexByEntityId(panda_file::File::EntityId(methodId));
|
||||
}
|
||||
return 0;
|
||||
@ -403,7 +407,7 @@ protected:
|
||||
|
||||
class GetIteratorTypeInfoAccessor final : public CallTypeInfoAccessor {
|
||||
public:
|
||||
GetIteratorTypeInfoAccessor(const JSThread *thread,
|
||||
GetIteratorTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -419,7 +423,7 @@ public:
|
||||
|
||||
class CallArg0TypeInfoAccessor final : public CallTypeInfoAccessor {
|
||||
public:
|
||||
CallArg0TypeInfoAccessor(const JSThread *thread,
|
||||
CallArg0TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -430,7 +434,7 @@ public:
|
||||
|
||||
class CallArg1TypeInfoAccessor final : public CallTypeInfoAccessor {
|
||||
public:
|
||||
CallArg1TypeInfoAccessor(const JSThread *thread,
|
||||
CallArg1TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -454,7 +458,7 @@ private:
|
||||
|
||||
class CallArg2TypeInfoAccessor final : public CallTypeInfoAccessor {
|
||||
public:
|
||||
CallArg2TypeInfoAccessor(const JSThread *thread,
|
||||
CallArg2TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -465,7 +469,7 @@ public:
|
||||
|
||||
class CallArg3TypeInfoAccessor final : public CallTypeInfoAccessor {
|
||||
public:
|
||||
CallArg3TypeInfoAccessor(const JSThread *thread,
|
||||
CallArg3TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -476,7 +480,7 @@ public:
|
||||
|
||||
class CallRangeTypeInfoAccessor final : public CallTypeInfoAccessor {
|
||||
public:
|
||||
CallRangeTypeInfoAccessor(const JSThread *thread,
|
||||
CallRangeTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -487,12 +491,12 @@ public:
|
||||
|
||||
class CallThisTypeInfoAccessor : public CallTypeInfoAccessor {
|
||||
public:
|
||||
CallThisTypeInfoAccessor(const JSThread *thread,
|
||||
CallThisTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
const CallMethodFlagMap *callMethodFlagMap = nullptr)
|
||||
: CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
: CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
|
||||
{
|
||||
thisObj_ = acc_.GetValueIn(gate, 0);
|
||||
}
|
||||
@ -511,7 +515,7 @@ protected:
|
||||
|
||||
class CallThis0TypeInfoAccessor final : public CallThisTypeInfoAccessor {
|
||||
public:
|
||||
CallThis0TypeInfoAccessor(const JSThread *thread,
|
||||
CallThis0TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -522,7 +526,7 @@ public:
|
||||
|
||||
class CallThis1TypeInfoAccessor final : public CallThisTypeInfoAccessor {
|
||||
public:
|
||||
CallThis1TypeInfoAccessor(const JSThread *thread,
|
||||
CallThis1TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -546,7 +550,7 @@ private:
|
||||
|
||||
class CallThis2TypeInfoAccessor final : public CallThisTypeInfoAccessor {
|
||||
public:
|
||||
CallThis2TypeInfoAccessor(const JSThread *thread,
|
||||
CallThis2TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -557,7 +561,7 @@ public:
|
||||
|
||||
class CallThis3TypeInfoAccessor final : public CallThisTypeInfoAccessor {
|
||||
public:
|
||||
CallThis3TypeInfoAccessor(const JSThread *thread,
|
||||
CallThis3TypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -578,7 +582,7 @@ private:
|
||||
|
||||
class CallThisRangeTypeInfoAccessor final : public CallThisTypeInfoAccessor {
|
||||
public:
|
||||
CallThisRangeTypeInfoAccessor(const JSThread *thread,
|
||||
CallThisRangeTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const JSPandaFile *jsPandaFile = nullptr,
|
||||
@ -598,7 +602,7 @@ enum CallKind : uint8_t {
|
||||
|
||||
class InlineTypeInfoAccessor final : public TypeInfoAccessor {
|
||||
public:
|
||||
InlineTypeInfoAccessor(const JSThread *thread,
|
||||
InlineTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
GateRef receiver,
|
||||
@ -623,6 +627,9 @@ public:
|
||||
|
||||
bool IsClassInstanceTypeKind() const
|
||||
{
|
||||
if (compilationEnv_->IsJitCompiler()) {
|
||||
return false;
|
||||
}
|
||||
return tsManager_->IsClassInstanceTypeKind(acc_.GetGateType(receiver_));
|
||||
}
|
||||
|
||||
@ -733,12 +740,12 @@ public:
|
||||
STORE
|
||||
};
|
||||
|
||||
ObjectAccessTypeInfoAccessor(const JSThread *thread,
|
||||
ObjectAccessTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk,
|
||||
AccessMode mode)
|
||||
: TypeInfoAccessor(thread, circuit, gate),
|
||||
: TypeInfoAccessor(env, circuit, gate),
|
||||
chunk_(chunk),
|
||||
mode_(mode),
|
||||
key_(Circuit::NullGate()),
|
||||
@ -761,6 +768,9 @@ public:
|
||||
|
||||
GateType GetReceiverGateType() const
|
||||
{
|
||||
if (compilationEnv_->IsJitCompiler()) {
|
||||
return acc_.GetGateType(receiver_);
|
||||
}
|
||||
return tsManager_->TryNarrowUnionType(acc_.GetGateType(receiver_));
|
||||
}
|
||||
|
||||
@ -773,12 +783,12 @@ protected:
|
||||
|
||||
class ObjAccByNameTypeInfoAccessor : public ObjectAccessTypeInfoAccessor {
|
||||
public:
|
||||
ObjAccByNameTypeInfoAccessor(const JSThread *thread,
|
||||
ObjAccByNameTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk,
|
||||
AccessMode mode)
|
||||
: ObjectAccessTypeInfoAccessor(thread, circuit, gate, chunk, mode),
|
||||
: ObjectAccessTypeInfoAccessor(env, circuit, gate, chunk, mode),
|
||||
hasIllegalType_(false),
|
||||
accessInfos_(chunk),
|
||||
checkerInfos_(chunk)
|
||||
@ -814,7 +824,7 @@ protected:
|
||||
|
||||
class LoadObjByNameTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
|
||||
public:
|
||||
LoadObjByNameTypeInfoAccessor(const JSThread *thread,
|
||||
LoadObjByNameTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk);
|
||||
@ -852,7 +862,7 @@ private:
|
||||
|
||||
class StoreObjByNameTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
|
||||
public:
|
||||
StoreObjByNameTypeInfoAccessor(const JSThread *thread,
|
||||
StoreObjByNameTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk);
|
||||
@ -905,7 +915,7 @@ private:
|
||||
|
||||
class InstanceOfTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
|
||||
public:
|
||||
InstanceOfTypeInfoAccessor(const JSThread *thread,
|
||||
InstanceOfTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk);
|
||||
@ -947,12 +957,12 @@ private:
|
||||
|
||||
class AccBuiltinObjTypeInfoAccessor : public ObjectAccessTypeInfoAccessor {
|
||||
public:
|
||||
AccBuiltinObjTypeInfoAccessor(const JSThread *thread,
|
||||
AccBuiltinObjTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk,
|
||||
AccessMode mode)
|
||||
: ObjectAccessTypeInfoAccessor(thread, circuit, gate, chunk, mode), types_(chunk_)
|
||||
: ObjectAccessTypeInfoAccessor(env, circuit, gate, chunk, mode), types_(chunk_)
|
||||
{}
|
||||
NO_COPY_SEMANTIC(AccBuiltinObjTypeInfoAccessor);
|
||||
NO_MOVE_SEMANTIC(AccBuiltinObjTypeInfoAccessor);
|
||||
@ -1047,6 +1057,9 @@ public:
|
||||
|
||||
bool IsBuiltinInstanceType(BuiltinTypeId type) const
|
||||
{
|
||||
if (compilationEnv_->IsJitCompiler()) {
|
||||
return false;
|
||||
}
|
||||
return tsManager_->IsBuiltinInstanceType(type, GetReceiverGateType());
|
||||
}
|
||||
|
||||
@ -1085,7 +1098,7 @@ protected:
|
||||
|
||||
class LoadBulitinObjTypeInfoAccessor final : public AccBuiltinObjTypeInfoAccessor {
|
||||
public:
|
||||
LoadBulitinObjTypeInfoAccessor(const JSThread *thread,
|
||||
LoadBulitinObjTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk);
|
||||
@ -1095,7 +1108,7 @@ public:
|
||||
|
||||
class StoreBulitinObjTypeInfoAccessor final : public AccBuiltinObjTypeInfoAccessor {
|
||||
public:
|
||||
StoreBulitinObjTypeInfoAccessor(const JSThread *thread,
|
||||
StoreBulitinObjTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
Chunk *chunk);
|
||||
@ -1118,11 +1131,11 @@ private:
|
||||
|
||||
class GlobalObjAccTypeInfoAccessor : public ObjectAccessTypeInfoAccessor {
|
||||
public:
|
||||
GlobalObjAccTypeInfoAccessor(const JSThread *thread,
|
||||
GlobalObjAccTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
AccessMode mode)
|
||||
: ObjectAccessTypeInfoAccessor(thread, circuit, gate, nullptr, mode) {}
|
||||
: ObjectAccessTypeInfoAccessor(env, circuit, gate, nullptr, mode) {}
|
||||
|
||||
NO_COPY_SEMANTIC(GlobalObjAccTypeInfoAccessor);
|
||||
NO_MOVE_SEMANTIC(GlobalObjAccTypeInfoAccessor);
|
||||
@ -1130,10 +1143,10 @@ public:
|
||||
|
||||
class LoadGlobalObjByNameTypeInfoAccessor final : public GlobalObjAccTypeInfoAccessor {
|
||||
public:
|
||||
LoadGlobalObjByNameTypeInfoAccessor(const JSThread *thread,
|
||||
LoadGlobalObjByNameTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate)
|
||||
: GlobalObjAccTypeInfoAccessor(thread, circuit, gate, AccessMode::LOAD)
|
||||
: GlobalObjAccTypeInfoAccessor(env, circuit, gate, AccessMode::LOAD)
|
||||
{
|
||||
key_ = acc_.GetValueIn(gate, 1);
|
||||
}
|
||||
@ -1143,7 +1156,7 @@ public:
|
||||
|
||||
class CreateObjWithBufferTypeInfoAccessor : public TypeInfoAccessor {
|
||||
public:
|
||||
CreateObjWithBufferTypeInfoAccessor(const JSThread *thread,
|
||||
CreateObjWithBufferTypeInfoAccessor(const CompilationEnv *env,
|
||||
Circuit *circuit,
|
||||
GateRef gate,
|
||||
const CString &recordName);
|
||||
@ -1153,10 +1166,7 @@ public:
|
||||
|
||||
JSTaggedValue GetHClass() const;
|
||||
|
||||
JSHandle<JSObject> GetObjHandle() const
|
||||
{
|
||||
return objHandle_;
|
||||
}
|
||||
JSTaggedValue GetObject() const;
|
||||
|
||||
GateRef GetIndex() const
|
||||
{
|
||||
@ -1165,8 +1175,13 @@ public:
|
||||
|
||||
bool CanOptimize() const
|
||||
{
|
||||
TaggedArray *properties = TaggedArray::Cast(objHandle_->GetProperties());
|
||||
TaggedArray *elements = TaggedArray::Cast(objHandle_->GetElements());
|
||||
JSTaggedValue obj = GetObject();
|
||||
if (obj.IsUndefined()) {
|
||||
return false;
|
||||
}
|
||||
JSObject *jsObj = JSObject::Cast(obj);
|
||||
TaggedArray *properties = TaggedArray::Cast(jsObj->GetProperties());
|
||||
TaggedArray *elements = TaggedArray::Cast(jsObj->GetElements());
|
||||
return properties->GetLength() == 0 && elements->GetLength() == 0;
|
||||
}
|
||||
|
||||
@ -1174,7 +1189,6 @@ private:
|
||||
void Init();
|
||||
|
||||
const CString &recordName_;
|
||||
JSHandle<JSObject> objHandle_;
|
||||
GateRef index_;
|
||||
};
|
||||
} // panda::ecmascript::kungfu
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
bool TypedBytecodeLowering::RunTypedBytecodeLowering()
|
||||
@ -51,7 +52,7 @@ bool TypedBytecodeLowering::RunTypedBytecodeLowering()
|
||||
auto allTypedOpCount = allJSBcCount_ - allNonTypedOpCount_;
|
||||
if (allTypedOpCount != 0) {
|
||||
typeHitRate = static_cast<double>(hitTypedOpCount_) / static_cast<double>(allTypedOpCount);
|
||||
auto typeThreshold = tsManager_->GetTypeThreshold();
|
||||
auto typeThreshold = const_cast<CompilationEnv*>(compilationEnv_)->GetJSOptions().GetTypeThreshold();
|
||||
if (typeHitRate <= typeThreshold) {
|
||||
success = false;
|
||||
}
|
||||
@ -141,8 +142,10 @@ void TypedBytecodeLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::GETITERATOR_IMM16:
|
||||
LowerGetIterator(gate);
|
||||
break;
|
||||
case EcmaOpcode::CREATEEMPTYOBJECT:
|
||||
LowerCreateEmptyObject(gate);
|
||||
case EcmaOpcode::CREATEEMPTYOBJECT: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerCreateEmptyObject");
|
||||
LowerCreateEmptyObject(gate);
|
||||
}
|
||||
break;
|
||||
case EcmaOpcode::CALLTHIS0_IMM8_V8:
|
||||
LowerTypedCallthis0(gate);
|
||||
@ -154,13 +157,17 @@ void TypedBytecodeLowering::Lower(GateRef gate)
|
||||
LowerTypedCallthis2(gate);
|
||||
break;
|
||||
case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM8_ID16:
|
||||
case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM16_ID16:
|
||||
LowerCreateObjectWithBuffer(gate);
|
||||
case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerCreateObjectWithBuffer");
|
||||
LowerCreateObjectWithBuffer(gate);
|
||||
}
|
||||
break;
|
||||
case EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8:
|
||||
case EcmaOpcode::NEWOBJRANGE_IMM16_IMM8_V8:
|
||||
case EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8:
|
||||
LowerTypedNewObjRange(gate);
|
||||
case EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerTypedNewObjRange");
|
||||
LowerTypedNewObjRange(gate);
|
||||
}
|
||||
break;
|
||||
case EcmaOpcode::ADD2_IMM8_V8:
|
||||
LowerTypedBinOp<TypedBinOp::TYPED_ADD>(gate);
|
||||
@ -272,15 +279,19 @@ void TypedBytecodeLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::LDOBJBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::LDOBJBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::LDTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::LDTHISBYNAME_IMM16_ID16:
|
||||
LowerTypedLdObjByName(gate);
|
||||
case EcmaOpcode::LDTHISBYNAME_IMM16_ID16: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerTypedLdObjByName");
|
||||
LowerTypedLdObjByName(gate);
|
||||
}
|
||||
break;
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
LowerTypedStObjByName(gate);
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8: {
|
||||
Jit::JitLockHolder lock(compilationEnv_, "LowerTypedStObjByName");
|
||||
LowerTypedStObjByName(gate);
|
||||
}
|
||||
break;
|
||||
case EcmaOpcode::LDOBJBYVALUE_IMM8_V8:
|
||||
case EcmaOpcode::LDOBJBYVALUE_IMM16_V8:
|
||||
@ -358,7 +369,7 @@ int32_t TypedBytecodeLowering::GetEcmaOpCodeListIndex(EcmaOpcode ecmaOpCode)
|
||||
template<TypedBinOp Op>
|
||||
void TypedBytecodeLowering::LowerTypedBinOp(GateRef gate)
|
||||
{
|
||||
BinOpTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
BinOpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (tacc.HasNumberType()) {
|
||||
SpeculateNumbers<Op>(tacc);
|
||||
} else if (tacc.IsStringType()) {
|
||||
@ -369,7 +380,7 @@ void TypedBytecodeLowering::LowerTypedBinOp(GateRef gate)
|
||||
template<TypedUnOp Op>
|
||||
void TypedBytecodeLowering::LowerTypedUnOp(GateRef gate)
|
||||
{
|
||||
UnOpTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
UnOpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
// NOTICE-PGO: wx add support for PrimitiveNumberType
|
||||
if (tacc.HasNumberType()) {
|
||||
SpeculateNumber<Op>(tacc);
|
||||
@ -379,7 +390,7 @@ void TypedBytecodeLowering::LowerTypedUnOp(GateRef gate)
|
||||
template<TypedBinOp Op>
|
||||
void TypedBytecodeLowering::LowerTypedEqOrNotEq(GateRef gate)
|
||||
{
|
||||
BinOpTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
BinOpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (tacc.LeftOrRightIsUndefinedOrNull()) {
|
||||
AddProfiling(gate);
|
||||
GateRef left = tacc.GetLeftGate();
|
||||
@ -398,10 +409,10 @@ void TypedBytecodeLowering::SpeculateStrings(const BinOpTypeInfoAccessor &tacc)
|
||||
AddProfiling(tacc.GetGate());
|
||||
GateRef left = tacc.GetLeftGate();
|
||||
GateRef right = tacc.GetReightGate();
|
||||
if (!TypeInfoAccessor::IsTrustedStringType(thread_, circuit_, chunk_, acc_, left)) {
|
||||
if (!TypeInfoAccessor::IsTrustedStringType(compilationEnv_, circuit_, chunk_, acc_, left)) {
|
||||
builder_.EcmaStringCheck(left);
|
||||
}
|
||||
if (!TypeInfoAccessor::IsTrustedStringType(thread_, circuit_, chunk_, acc_, right)) {
|
||||
if (!TypeInfoAccessor::IsTrustedStringType(compilationEnv_, circuit_, chunk_, acc_, right)) {
|
||||
builder_.EcmaStringCheck(right);
|
||||
}
|
||||
GateRef result = builder_.TypedBinaryOp<Op>(left, right, tacc.GetParamType());
|
||||
@ -431,7 +442,7 @@ void TypedBytecodeLowering::SpeculateNumber(const UnOpTypeInfoAccessor &tacc)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypeToNumeric(GateRef gate)
|
||||
{
|
||||
UnOpTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
UnOpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (tacc.HasNumberType()) {
|
||||
AddProfiling(gate);
|
||||
LowerPrimitiveTypeToNumber(tacc);
|
||||
@ -446,7 +457,7 @@ void TypedBytecodeLowering::LowerPrimitiveTypeToNumber(const UnOpTypeInfoAccesso
|
||||
|
||||
void TypedBytecodeLowering::LowerConditionJump(GateRef gate, bool flag)
|
||||
{
|
||||
ConditionJumpTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
ConditionJumpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (TypeInfoAccessor::IsTrustedBooleanType(acc_, tacc.GetValue())) {
|
||||
AddProfiling(gate);
|
||||
SpeculateConditionJump(tacc, flag);
|
||||
@ -479,7 +490,7 @@ void TypedBytecodeLowering::DeleteConstDataIfNoUser(GateRef gate)
|
||||
void TypedBytecodeLowering::LowerTypedLdObjByName(GateRef gate)
|
||||
{
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
LoadObjByNameTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
LoadObjByNameTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
|
||||
if (TryLowerTypedLdobjBynameFromGloablBuiltin(gate)) {
|
||||
return;
|
||||
@ -579,7 +590,7 @@ void TypedBytecodeLowering::LowerTypedLdObjByName(GateRef gate)
|
||||
void TypedBytecodeLowering::LowerTypedStObjByName(GateRef gate)
|
||||
{
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
StoreObjByNameTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
StoreObjByNameTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
if (tacc.TypesIsEmpty() || tacc.HasIllegalType()) {
|
||||
return;
|
||||
}
|
||||
@ -778,7 +789,7 @@ GateRef TypedBytecodeLowering::BuildNamedPropertyAccess(
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltin(GateRef gate)
|
||||
{
|
||||
LoadBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
LoadBulitinObjTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
// Just supported mono.
|
||||
if (tacc.IsMono()) {
|
||||
if (tacc.IsBuiltinsType()) {
|
||||
@ -808,7 +819,8 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltin(const LoadBulitin
|
||||
{
|
||||
EcmaString *propString = EcmaString::Cast(tacc.GetKeyTaggedValue().GetTaggedObject());
|
||||
// (1) get length
|
||||
EcmaString *lengthString = EcmaString::Cast(thread_->GlobalConstants()->GetLengthString().GetTaggedObject());
|
||||
EcmaString *lengthString =
|
||||
EcmaString::Cast(compilationEnv_->GlobalConstants()->GetLengthString().GetTaggedObject());
|
||||
if (propString == lengthString) {
|
||||
if (tacc.IsBuiltinsArray()) {
|
||||
LowerTypedLdArrayLength(tacc);
|
||||
@ -836,9 +848,9 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForGlobalsId(const LoadBulit
|
||||
GateRef frameState = acc_.FindNearestFrameState(gate);
|
||||
if (globalsId.IsGlobalConstId()) {
|
||||
ConstantIndex index = static_cast<ConstantIndex>(globalsId.GetGlobalConstId());
|
||||
JSHClass *hclass = JSHClass::Cast(thread_->GlobalConstants()->GetGlobalConstantObject(
|
||||
JSHClass *hclass = JSHClass::Cast(compilationEnv_->GlobalConstants()->GetGlobalConstantObject(
|
||||
static_cast<size_t>(index)).GetTaggedObject());
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(thread_, hclass, key);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(compilationEnv_->GetJSThread(), hclass, key);
|
||||
if (!plr.IsFound() || plr.IsAccessor()) {
|
||||
return false;
|
||||
}
|
||||
@ -857,9 +869,9 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForGlobalsId(const LoadBulit
|
||||
return true;
|
||||
} else if (globalsId.IsGlobalEnvId()) { // ctor Hclass
|
||||
GlobalEnvField index = static_cast<GlobalEnvField>(globalsId.GetGlobalEnvId());
|
||||
JSHClass *hclass = JSHClass::Cast(thread_->GetGlobalEnv()->GetGlobalEnvObjectByIndex(
|
||||
JSHClass *hclass = JSHClass::Cast(compilationEnv_->GetGlobalEnv()->GetGlobalEnvObjectByIndex(
|
||||
static_cast<size_t>(index))->GetTaggedObject()->GetClass());
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(thread_, hclass, key);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(compilationEnv_->GetJSThread(), hclass, key);
|
||||
if (!plr.IsFound() || plr.IsAccessor()) {
|
||||
return false;
|
||||
}
|
||||
@ -881,19 +893,19 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForGlobalsId(const LoadBulit
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate)
|
||||
{
|
||||
LoadBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
LoadBulitinObjTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
GateRef receiver = tacc.GetReceiver();
|
||||
if (acc_.GetOpCode(receiver) != OpCode::LOAD_BUILTIN_OBJECT) {
|
||||
return false;
|
||||
}
|
||||
JSHandle<GlobalEnv> globalEnv = thread_->GetEcmaVM()->GetGlobalEnv();
|
||||
JSHandle<GlobalEnv> globalEnv = compilationEnv_->GetGlobalEnv();
|
||||
uint64_t index = acc_.TryGetValue(receiver);
|
||||
BuiltinType type = static_cast<BuiltinType>(index);
|
||||
if (type == BuiltinType::BT_MATH) {
|
||||
auto math = globalEnv->GetMathFunction();
|
||||
JSHClass *hclass = math.GetTaggedValue().GetTaggedObject()->GetClass();
|
||||
JSTaggedValue key = tacc.GetKeyTaggedValue();
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(thread_, hclass, key);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(compilationEnv_->GetJSThread(), hclass, key);
|
||||
if (!plr.IsFound() || plr.IsAccessor()) {
|
||||
return false;
|
||||
}
|
||||
@ -959,9 +971,10 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(const LoadB
|
||||
return false;
|
||||
}
|
||||
size_t protoFieldIndex = static_cast<size_t>(*protoField);
|
||||
JSHandle<GlobalEnv> globalEnv = thread_->GetEcmaVM()->GetGlobalEnv();
|
||||
JSHandle<GlobalEnv> globalEnv = compilationEnv_->GetGlobalEnv();
|
||||
JSHClass *prototypeHClass = globalEnv->GetGlobalEnvObjectByIndex(protoFieldIndex)->GetTaggedObject()->GetClass();
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinPrototypeHClass(thread_, prototypeHClass, key);
|
||||
PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinPrototypeHClass(compilationEnv_->GetJSThread(),
|
||||
prototypeHClass, key);
|
||||
bool isPrototypeOfPrototype = false;
|
||||
// Unable to handle accessor at the moment
|
||||
if (!plr.IsFound() || plr.IsAccessor()) {
|
||||
@ -972,7 +985,8 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(const LoadB
|
||||
}
|
||||
protoFieldIndex = static_cast<size_t>(*protoField);
|
||||
prototypeHClass = globalEnv->GetGlobalEnvObjectByIndex(protoFieldIndex)->GetTaggedObject()->GetClass();
|
||||
plr = JSHClass::LookupPropertyInBuiltinPrototypeHClass(thread_, prototypeHClass, key);
|
||||
plr = JSHClass::LookupPropertyInBuiltinPrototypeHClass(compilationEnv_->GetJSThread(),
|
||||
prototypeHClass, key);
|
||||
if (!plr.IsFound() || plr.IsAccessor()) {
|
||||
return false;
|
||||
} else {
|
||||
@ -1007,7 +1021,7 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(const LoadB
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedLdObjByIndexForBuiltin(GateRef gate)
|
||||
{
|
||||
LoadBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
LoadBulitinObjTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
GateRef result = Circuit::NullGate();
|
||||
// Just supported mono.
|
||||
if (tacc.IsMono()) {
|
||||
@ -1030,7 +1044,7 @@ void TypedBytecodeLowering::LowerTypedLdObjByIndex(GateRef gate)
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedStObjByIndexForBuiltin(GateRef gate)
|
||||
{
|
||||
StoreBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
StoreBulitinObjTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
if (tacc.GetBuiltinsJSType() != JSType::JS_FLOAT32_ARRAY) {
|
||||
return false;
|
||||
}
|
||||
@ -1062,7 +1076,7 @@ void TypedBytecodeLowering::LowerTypedStObjByIndex(GateRef gate)
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedLdObjByValueForBuiltin(GateRef gate)
|
||||
{
|
||||
LoadBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
LoadBulitinObjTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
GateRef result = Circuit::NullGate();
|
||||
// Just supported mono.
|
||||
if (tacc.IsMono()) {
|
||||
@ -1249,7 +1263,7 @@ void TypedBytecodeLowering::StoreTypedArrayByIndex(const StoreBulitinObjTypeInfo
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerTypedStObjByValueForBuiltin(GateRef gate)
|
||||
{
|
||||
StoreBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
StoreBulitinObjTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
// Just supported mono.
|
||||
if (tacc.IsMono()) {
|
||||
if (tacc.IsBuiltinsArray()) {
|
||||
@ -1277,7 +1291,7 @@ void TypedBytecodeLowering::LowerTypedStObjByValue(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedIsTrueOrFalse(GateRef gate, bool flag)
|
||||
{
|
||||
UnOpTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
UnOpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
ParamType paramType;
|
||||
if (TypeInfoAccessor::IsTrustedBooleanType(acc_, tacc.GetValue())) {
|
||||
paramType = ParamType::BooleanType();
|
||||
@ -1302,7 +1316,7 @@ void TypedBytecodeLowering::LowerTypedNewObjRange(GateRef gate)
|
||||
if (TryLowerNewBuiltinConstructor(gate)) {
|
||||
return;
|
||||
}
|
||||
NewObjRangeTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
NewObjRangeTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (!tacc.FindHClass()) {
|
||||
return;
|
||||
}
|
||||
@ -1328,7 +1342,7 @@ void TypedBytecodeLowering::LowerTypedNewObjRange(GateRef gate)
|
||||
|
||||
bool TypedBytecodeLowering::TryLowerNewBuiltinConstructor(GateRef gate)
|
||||
{
|
||||
NewBuiltinCtorTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
NewBuiltinCtorTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (!tacc.IsBuiltinModule()) {
|
||||
return false;
|
||||
}
|
||||
@ -1358,7 +1372,7 @@ bool TypedBytecodeLowering::TryLowerNewBuiltinConstructor(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedSuperCall(GateRef gate)
|
||||
{
|
||||
SuperCallTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
SuperCallTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (!tacc.IsClassTypeKind() && !tacc.IsValidCallMethodId()) {
|
||||
return;
|
||||
}
|
||||
@ -1600,7 +1614,7 @@ const JSPandaFile* TypedBytecodeLowering::GetCalleePandaFile(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallArg0(GateRef gate)
|
||||
{
|
||||
CallArg0TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallArg0TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
if (!tacc.IsValidCallMethodId()) {
|
||||
return;
|
||||
}
|
||||
@ -1609,7 +1623,7 @@ void TypedBytecodeLowering::LowerTypedCallArg0(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallArg1(GateRef gate)
|
||||
{
|
||||
CallArg1TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallArg1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
GateRef func = tacc.GetFunc();
|
||||
GateRef a0Value = tacc.GetValue();
|
||||
BuiltinsStubCSigns::ID id = tacc.TryGetPGOBuiltinMethodId();
|
||||
@ -1626,7 +1640,7 @@ void TypedBytecodeLowering::LowerTypedCallArg1(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallArg2(GateRef gate)
|
||||
{
|
||||
CallArg2TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallArg2TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
if (!tacc.IsValidCallMethodId()) {
|
||||
return;
|
||||
}
|
||||
@ -1635,7 +1649,7 @@ void TypedBytecodeLowering::LowerTypedCallArg2(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallArg3(GateRef gate)
|
||||
{
|
||||
CallArg3TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallArg3TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
if (!tacc.IsValidCallMethodId()) {
|
||||
return;
|
||||
}
|
||||
@ -1644,7 +1658,7 @@ void TypedBytecodeLowering::LowerTypedCallArg3(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallrange(GateRef gate)
|
||||
{
|
||||
CallRangeTypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallRangeTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
if (!tacc.IsValidCallMethodId()) {
|
||||
return;
|
||||
}
|
||||
@ -1717,7 +1731,7 @@ void TypedBytecodeLowering::LowerTypedThisCall(const TypeAccessor &tacc)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallthis0(GateRef gate)
|
||||
{
|
||||
CallThis0TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallThis0TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
BuiltinsStubCSigns::ID pgoFuncId = tacc.TryGetPGOBuiltinMethodId();
|
||||
if (IS_TYPED_BUILTINS_ID_CALL_THIS0(pgoFuncId)) {
|
||||
AddProfiling(gate);
|
||||
@ -1732,7 +1746,7 @@ void TypedBytecodeLowering::LowerTypedCallthis0(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallthis1(GateRef gate)
|
||||
{
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
BuiltinsStubCSigns::ID pgoFuncId = tacc.TryGetPGOBuiltinMethodId();
|
||||
if (IS_TYPED_BUILTINS_ID_CALL_THIS1(pgoFuncId)) {
|
||||
AddProfiling(gate);
|
||||
@ -1747,7 +1761,7 @@ void TypedBytecodeLowering::LowerTypedCallthis1(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallthis2(GateRef gate)
|
||||
{
|
||||
CallThis2TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallThis2TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
if (!tacc.CanOptimizeAsFastCall()) {
|
||||
return;
|
||||
}
|
||||
@ -1756,7 +1770,7 @@ void TypedBytecodeLowering::LowerTypedCallthis2(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallthis3(GateRef gate)
|
||||
{
|
||||
CallThis3TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallThis3TypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
BuiltinsStubCSigns::ID pgoFuncId = tacc.TryGetPGOBuiltinMethodId();
|
||||
if (IS_TYPED_BUILTINS_ID_CALL_THIS3(pgoFuncId)) {
|
||||
AddProfiling(gate);
|
||||
@ -1771,7 +1785,7 @@ void TypedBytecodeLowering::LowerTypedCallthis3(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedCallthisrange(GateRef gate)
|
||||
{
|
||||
CallThisRangeTypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
CallThisRangeTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
if (!tacc.CanOptimizeAsFastCall()) {
|
||||
return;
|
||||
}
|
||||
@ -1862,7 +1876,7 @@ void TypedBytecodeLowering::AddHitBytecodeCount()
|
||||
|
||||
void TypedBytecodeLowering::LowerTypedTypeOf(GateRef gate)
|
||||
{
|
||||
TypeOfTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
TypeOfTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
if (tacc.IsIllegalType()) {
|
||||
return;
|
||||
}
|
||||
@ -1876,7 +1890,7 @@ void TypedBytecodeLowering::LowerTypedTypeOf(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerGetIterator(GateRef gate)
|
||||
{
|
||||
GetIteratorTypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
GetIteratorTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
|
||||
BuiltinsStubCSigns::ID id = tacc.TryGetPGOBuiltinMethodId();
|
||||
if (id == BuiltinsStubCSigns::ID::NONE) {
|
||||
return;
|
||||
@ -1892,7 +1906,7 @@ void TypedBytecodeLowering::LowerTypedTryLdGlobalByName(GateRef gate)
|
||||
return;
|
||||
}
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
LoadGlobalObjByNameTypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
LoadGlobalObjByNameTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
|
||||
JSTaggedValue key = tacc.GetKeyTaggedValue();
|
||||
|
||||
BuiltinIndex& builtin = BuiltinIndex::GetInstance();
|
||||
@ -1908,7 +1922,7 @@ void TypedBytecodeLowering::LowerTypedTryLdGlobalByName(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerInstanceOf(GateRef gate)
|
||||
{
|
||||
InstanceOfTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_);
|
||||
InstanceOfTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, chunk_);
|
||||
if (tacc.TypesIsEmpty() || tacc.HasIllegalType()) {
|
||||
return;
|
||||
}
|
||||
@ -1939,7 +1953,7 @@ void TypedBytecodeLowering::LowerCreateEmptyObject(GateRef gate)
|
||||
GateRef globalEnv = builder_.GetGlobalEnv();
|
||||
GateRef hclass = builder_.GetGlobalEnvObjHClass(globalEnv, GlobalEnv::OBJECT_FUNCTION_INDEX);
|
||||
|
||||
JSHandle<JSFunction> objectFunc(tsManager_->GetEcmaVM()->GetGlobalEnv()->GetObjectFunction());
|
||||
JSHandle<JSFunction> objectFunc(compilationEnv_->GetGlobalEnv()->GetObjectFunction());
|
||||
JSTaggedValue protoOrHClass = objectFunc->GetProtoOrHClass();
|
||||
JSHClass *objectHC = JSHClass::Cast(protoOrHClass.GetTaggedObject());
|
||||
size_t objectSize = objectHC->GetObjectSize();
|
||||
@ -1976,7 +1990,8 @@ void TypedBytecodeLowering::LowerTypedStOwnByValue(GateRef gate)
|
||||
|
||||
void TypedBytecodeLowering::LowerCreateObjectWithBuffer(GateRef gate)
|
||||
{
|
||||
CreateObjWithBufferTypeInfoAccessor tacc(thread_, circuit_, gate, recordName_);
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
CreateObjWithBufferTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, recordName_);
|
||||
if (!tacc.CanOptimize()) {
|
||||
return;
|
||||
}
|
||||
@ -1984,9 +1999,9 @@ void TypedBytecodeLowering::LowerCreateObjectWithBuffer(GateRef gate)
|
||||
if (hclassVal.IsUndefined()) {
|
||||
return;
|
||||
}
|
||||
JSHandle<JSHClass> newClass(thread_, hclassVal);
|
||||
JSHClass *newClass = JSHClass::Cast(hclassVal.GetTaggedObject());
|
||||
GateRef index = tacc.GetIndex();
|
||||
JSHandle<JSObject> objhandle = tacc.GetObjHandle();
|
||||
JSObject *objhandle = JSObject::Cast(tacc.GetObject());
|
||||
std::vector<uint64_t> inlinedProps;
|
||||
auto layout = LayoutInfo::Cast(newClass->GetLayout().GetTaggedObject());
|
||||
for (uint32_t i = 0; i < newClass->GetInlinedProperties(); i++) {
|
||||
@ -2009,7 +2024,7 @@ void TypedBytecodeLowering::LowerCreateObjectWithBuffer(GateRef gate)
|
||||
std::vector<GateRef> valueIn;
|
||||
valueIn.emplace_back(builder_.IntPtr(size));
|
||||
valueIn.emplace_back(index);
|
||||
valueIn.emplace_back(builder_.Int64(newClass.GetTaggedValue().GetRawData()));
|
||||
valueIn.emplace_back(builder_.Int64(JSTaggedValue(newClass).GetRawData()));
|
||||
valueIn.emplace_back(acc_.GetValueIn(gate, 1));
|
||||
for (uint32_t i = 0; i < newClass->GetInlinedProperties(); i++) {
|
||||
auto attr = layout->GetAttr(i);
|
||||
|
@ -57,8 +57,8 @@ public:
|
||||
glue_(acc_.GetGlueFromArgList()),
|
||||
argAcc_(circuit),
|
||||
pgoTypeLog_(circuit),
|
||||
noCheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()),
|
||||
noCheck_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerNoCheck()),
|
||||
compilationEnv_(ctx->GetCompilationEnv()),
|
||||
enableLoweringBuiltin_(enableLoweringBuiltin),
|
||||
recordName_(recordName),
|
||||
callMethodFlagMap_(callMethodFlagMap),
|
||||
@ -248,7 +248,7 @@ private:
|
||||
std::unordered_map<EcmaOpcode, uint32_t> bytecodeMap_;
|
||||
std::unordered_map<EcmaOpcode, uint32_t> bytecodeHitTimeMap_;
|
||||
bool noCheck_ {false};
|
||||
const JSThread *thread_ {nullptr};
|
||||
const CompilationEnv *compilationEnv_ {nullptr};
|
||||
bool enableLoweringBuiltin_ {false};
|
||||
const CString &recordName_;
|
||||
const CallMethodFlagMap *callMethodFlagMap_;
|
||||
|
@ -540,10 +540,9 @@ void TypedHCRLowering::BuiltinInstanceHClassCheck(Environment *env, GateRef gate
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
GateRef ihcMatches = Circuit::NullGate();
|
||||
JSThread *thread = tsManager_->GetThread();
|
||||
if (type == BuiltinTypeId::ARRAY) {
|
||||
if (Elements::IsGeneric(kind)) {
|
||||
auto arrayHClassIndexMap = thread->GetArrayHClassIndexMap();
|
||||
auto arrayHClassIndexMap = compilationEnv_->GetArrayHClassIndexMap();
|
||||
auto iter = arrayHClassIndexMap.find(kind);
|
||||
ASSERT(iter != arrayHClassIndexMap.end());
|
||||
GateRef initialIhcAddress = builder_.GetGlobalConstantValue(iter->second);
|
||||
@ -582,9 +581,8 @@ void TypedHCRLowering::BuiltinPrototypeHClassCheck(Environment *env, GateRef gat
|
||||
GateRef frameState = GetFrameState(gate);
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
JSThread *thread = tsManager_->GetThread();
|
||||
// Only HClasses recorded in the JSThread during builtin initialization are available
|
||||
[[maybe_unused]] JSHClass *initialPrototypeHClass = thread->GetBuiltinPrototypeHClass(type);
|
||||
[[maybe_unused]] JSHClass *initialPrototypeHClass = compilationEnv_->GetBuiltinPrototypeHClass(type);
|
||||
ASSERT(initialPrototypeHClass != nullptr);
|
||||
|
||||
// Phc = PrototypeHClass
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ecmascript/compiler/circuit_builder-inl.h"
|
||||
#include "ecmascript/compiler/combined_pass_visitor.h"
|
||||
#include "ecmascript/compiler/type_info_accessors.h"
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
// TypeHCRLowering Process
|
||||
@ -100,13 +101,15 @@ namespace panda::ecmascript::kungfu {
|
||||
class TypedHCRLowering : public PassVisitor {
|
||||
public:
|
||||
TypedHCRLowering(Circuit* circuit,
|
||||
RPOVisitor* visitor,
|
||||
CompilationConfig* cmpCfg,
|
||||
TSManager* tsManager,
|
||||
Chunk* chunk,
|
||||
bool enableLoweringBuiltin)
|
||||
CompilationEnv *env,
|
||||
RPOVisitor* visitor,
|
||||
CompilationConfig* cmpCfg,
|
||||
TSManager* tsManager,
|
||||
Chunk* chunk,
|
||||
bool enableLoweringBuiltin)
|
||||
: PassVisitor(circuit, chunk, visitor),
|
||||
circuit_(circuit),
|
||||
compilationEnv_(env),
|
||||
acc_(circuit),
|
||||
builder_(circuit, cmpCfg),
|
||||
dependEntry_(circuit->GetDependRoot()),
|
||||
@ -267,6 +270,7 @@ private:
|
||||
}
|
||||
|
||||
Circuit *circuit_;
|
||||
CompilationEnv *compilationEnv_ {nullptr};
|
||||
GateAccessor acc_;
|
||||
CircuitBuilder builder_;
|
||||
GateRef dependEntry_;
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
circuit_(circuit),
|
||||
acc_(circuit),
|
||||
builder_(circuit, cmpCfg),
|
||||
isLiteCG_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerEnableLiteCG()) {}
|
||||
isLiteCG_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerEnableLiteCG()) {}
|
||||
~TypedNativeInlineLowering() = default;
|
||||
GateRef VisitGate(GateRef gate) override;
|
||||
private:
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "ecmascript/snapshot/mem/snapshot.h"
|
||||
#include "ecmascript/platform/log.h"
|
||||
#include "ecmascript/global_index_map.h"
|
||||
#include "ecmascript/jit/persistent_handles.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using PathHelper = base::PathHelper;
|
||||
@ -130,6 +131,8 @@ bool EcmaContext::Initialize()
|
||||
if (vm_->GetJSOptions().GetTypedOpProfiler()) {
|
||||
typedOpProfiler_ = new TypedOpProfiler();
|
||||
}
|
||||
|
||||
persistentHandlesList_ = new PersistentHandlesList();
|
||||
initialized_ = true;
|
||||
return true;
|
||||
}
|
||||
@ -197,6 +200,12 @@ EcmaContext::~EcmaContext()
|
||||
currentHandleStorageIndex_ = -1;
|
||||
handleScopeCount_ = 0;
|
||||
handleScopeStorageNext_ = handleScopeStorageEnd_ = nullptr;
|
||||
|
||||
if (vm_->IsEnableJit()) {
|
||||
// clear jit task
|
||||
vm_->GetJit()->ClearTask(this);
|
||||
}
|
||||
|
||||
ClearBufferData();
|
||||
// clear c_address: c++ pointer delete
|
||||
if (!vm_->IsBundlePack()) {
|
||||
@ -244,6 +253,10 @@ EcmaContext::~EcmaContext()
|
||||
delete propertiesCache_;
|
||||
propertiesCache_ = nullptr;
|
||||
}
|
||||
if (persistentHandlesList_ != nullptr) {
|
||||
delete persistentHandlesList_;
|
||||
persistentHandlesList_ = nullptr;
|
||||
}
|
||||
// clear join stack
|
||||
joinStack_.clear();
|
||||
|
||||
@ -445,15 +458,25 @@ void EcmaContext::CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValu
|
||||
}
|
||||
}
|
||||
|
||||
JSTaggedValue EcmaContext::FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool)
|
||||
JSTaggedValue EcmaContext::FindUnsharedConstpool(JSTaggedValue sharedConstpool)
|
||||
{
|
||||
ConstantPool *shareCp = ConstantPool::Cast(sharedConstpool.GetTaggedObject());
|
||||
int32_t constpoolIndex = shareCp->GetUnsharedConstpoolIndex();
|
||||
// unshared constpool index is default INT32_MAX.
|
||||
ASSERT(0 <= constpoolIndex && constpoolIndex != ConstantPool::CONSTPOOL_TYPE_FLAG &&
|
||||
constpoolIndex < UNSHARED_CONSTANTPOOL_COUNT);
|
||||
JSTaggedValue unsharedConstpool = unsharedConstpools_[constpoolIndex];
|
||||
return unsharedConstpools_[constpoolIndex];
|
||||
}
|
||||
|
||||
JSTaggedValue EcmaContext::FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool)
|
||||
{
|
||||
JSTaggedValue unsharedConstpool = FindUnsharedConstpool(sharedConstpool);
|
||||
if (unsharedConstpool.IsHole()) {
|
||||
ConstantPool *shareCp = ConstantPool::Cast(sharedConstpool.GetTaggedObject());
|
||||
int32_t constpoolIndex = shareCp->GetUnsharedConstpoolIndex();
|
||||
// unshared constpool index is default INT32_MAX.
|
||||
ASSERT(0 <= constpoolIndex && constpoolIndex != ConstantPool::CONSTPOOL_TYPE_FLAG &&
|
||||
constpoolIndex < UNSHARED_CONSTANTPOOL_COUNT);
|
||||
ASSERT(constpoolIndex != INT32_MAX);
|
||||
JSHandle<ConstantPool> unshareCp =
|
||||
ConstantPool::CreateUnSharedConstPoolBySharedConstpool(vm_, shareCp->GetJSPandaFile(), shareCp);
|
||||
@ -901,6 +924,10 @@ void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
}
|
||||
}
|
||||
|
||||
if (persistentHandlesList_) {
|
||||
persistentHandlesList_->Iterate(rv);
|
||||
}
|
||||
|
||||
if (!joinStack_.empty()) {
|
||||
rv(Root::ROOT_VM, ObjectSlot(ToUintPtr(&joinStack_.front())),
|
||||
ObjectSlot(ToUintPtr(&joinStack_.back()) + JSTaggedValue::TaggedTypeSize()));
|
||||
@ -1084,4 +1111,18 @@ std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> EcmaContext:
|
||||
callSiteInfo = thread_->GetEcmaVM()->GetHeap()->CalCallSiteInfo(retAddr);
|
||||
return callSiteInfo;
|
||||
}
|
||||
|
||||
void EcmaContext::AddPersistentHandles(PersistentHandles *persistentHandle)
|
||||
{
|
||||
if (persistentHandlesList_) {
|
||||
persistentHandlesList_->AddPersistentHandles(persistentHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaContext::RemovePersistentHandles(PersistentHandles *persistentHandle)
|
||||
{
|
||||
if (persistentHandlesList_) {
|
||||
persistentHandlesList_->RemovePersistentHandles(persistentHandle);
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -49,6 +49,8 @@ class JSPromise;
|
||||
class RegExpExecResultCache;
|
||||
class EcmaHandleScope;
|
||||
class GlobalIndexMap;
|
||||
class PersistentHandlesList;
|
||||
class PersistentHandles;
|
||||
enum class PromiseRejectionEvent : uint8_t;
|
||||
|
||||
template<typename T>
|
||||
@ -269,6 +271,7 @@ public:
|
||||
// For new version instruction.
|
||||
JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id);
|
||||
JSTaggedValue PUBLIC_API FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool);
|
||||
JSTaggedValue PUBLIC_API FindUnsharedConstpool(JSTaggedValue sharedConstpool);
|
||||
JSHandle<ConstantPool> CreateConstpoolPair(JSPandaFile *jsPandaFile, EntityId methodId);
|
||||
JSTaggedValue FindConstpoolWithAOT(const JSPandaFile *jsPandaFile, int32_t index);
|
||||
void EraseUnusedConstpool(const JSPandaFile *jsPandaFile, int32_t index, int32_t constpoolIndex);
|
||||
@ -506,6 +509,9 @@ public:
|
||||
}
|
||||
|
||||
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
|
||||
|
||||
void AddPersistentHandles(PersistentHandles*);
|
||||
void RemovePersistentHandles(PersistentHandles*);
|
||||
private:
|
||||
void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint);
|
||||
@ -620,6 +626,9 @@ private:
|
||||
std::array<CVector<std::pair<CString, int>>, STRINGIFY_CACHE_SIZE> stringifyCache_ {};
|
||||
bool isAotEntry_ { false };
|
||||
|
||||
// PersistentHandlesList for jit compile hold ref
|
||||
PersistentHandlesList *persistentHandlesList_ {nullptr};
|
||||
|
||||
friend class EcmaHandleScope;
|
||||
friend class JSPandaFileExecutor;
|
||||
friend class ObjectFactory;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "ecmascript/ecma_handle_scope.h"
|
||||
|
||||
#include "ecmascript/ecma_context.h"
|
||||
#include "ecmascript/mem/assert_scope.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
EcmaHandleScope::EcmaHandleScope(JSThread *thread) : thread_(thread)
|
||||
@ -48,6 +49,7 @@ EcmaHandleScope::~EcmaHandleScope()
|
||||
|
||||
uintptr_t EcmaHandleScope::NewHandle(JSThread *thread, JSTaggedType value)
|
||||
{
|
||||
CHECK_NO_HANDLE_ALLOC;
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
// Each Handle must be managed by HandleScope, otherwise it may cause Handle leakage.
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
SHARED_HEAP
|
||||
};
|
||||
|
||||
EcmaParamConfiguration() = default;
|
||||
EcmaParamConfiguration(HeapType heapType, size_t poolSize, size_t heapSize = 1_MB)
|
||||
{
|
||||
switch (heapType) {
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "ecmascript/compiler/common_stubs.h"
|
||||
#include "ecmascript/compiler/interpreter_stub.h"
|
||||
#include "ecmascript/compiler/rt_call_signature.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
#include "ecmascript/jit/jit_task.h"
|
||||
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
||||
#include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
|
||||
#endif
|
||||
@ -193,6 +193,22 @@ EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
|
||||
SetEnableOsr(options_.IsEnableOSR() && options_.IsEnableJIT() && options_.GetEnableAsmInterpreter());
|
||||
}
|
||||
|
||||
// for jit
|
||||
EcmaVM::EcmaVM()
|
||||
: nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
|
||||
heapRegionAllocator_(nullptr),
|
||||
chunk_(nativeAreaAllocator_.get()) {}
|
||||
|
||||
void EcmaVM::InitializeForJit(JitThread *jitThread)
|
||||
{
|
||||
thread_ = jitThread;
|
||||
stringTable_ = Runtime::GetInstance()->GetEcmaStringTable();
|
||||
ASSERT(stringTable_);
|
||||
// ObjectFactory only sypport alloc string in sharedheap
|
||||
factory_ = chunk_.New<ObjectFactory>(thread_, nullptr, SharedHeap::GetInstance());
|
||||
SetIsJitCompileVM(true);
|
||||
}
|
||||
|
||||
void EcmaVM::InitializePGOProfiler()
|
||||
{
|
||||
bool isEnablePGOProfiler = IsEnablePGOProfiler();
|
||||
@ -290,6 +306,15 @@ bool EcmaVM::Initialize()
|
||||
|
||||
EcmaVM::~EcmaVM()
|
||||
{
|
||||
if (isJitCompileVM_) {
|
||||
if (factory_ != nullptr) {
|
||||
delete factory_;
|
||||
factory_ = nullptr;
|
||||
}
|
||||
stringTable_ = nullptr;
|
||||
thread_ = nullptr;
|
||||
return;
|
||||
}
|
||||
ASSERT(thread_->IsInRunningStateOrProfiling());
|
||||
initialized_ = false;
|
||||
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
||||
@ -304,6 +329,9 @@ EcmaVM::~EcmaVM()
|
||||
#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
|
||||
DeleteHeapProfile();
|
||||
#endif
|
||||
if (IsEnableJit()) {
|
||||
GetJit()->ClearTaskWithVm(this);
|
||||
}
|
||||
heap_->WaitAllTasksFinished();
|
||||
Taskpool::GetCurrentTaskpool()->Destroy(thread_->GetThreadId());
|
||||
|
||||
|
@ -91,6 +91,7 @@ class FunctionCallTimer;
|
||||
class EcmaStringTable;
|
||||
class JSObjectResizingStrategy;
|
||||
class Jit;
|
||||
class JitThread;
|
||||
|
||||
using NativePtrGetter = void* (*)(void* info);
|
||||
using SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
|
||||
@ -113,7 +114,7 @@ public:
|
||||
|
||||
EcmaVM();
|
||||
|
||||
~EcmaVM();
|
||||
virtual ~EcmaVM();
|
||||
|
||||
void SetLoop(void *loop)
|
||||
{
|
||||
@ -142,6 +143,7 @@ public:
|
||||
bool PUBLIC_API IsEnableElementsKind() const;
|
||||
|
||||
bool Initialize();
|
||||
void InitializeForJit(JitThread *thread);
|
||||
|
||||
GCStats *GetEcmaGCStats() const
|
||||
{
|
||||
@ -670,6 +672,16 @@ public:
|
||||
return nativePointerCallbacks_;
|
||||
}
|
||||
|
||||
void SetIsJitCompileVM(bool isJitCompileVM)
|
||||
{
|
||||
isJitCompileVM_ = isJitCompileVM;
|
||||
}
|
||||
|
||||
bool IsJitCompileVM() const
|
||||
{
|
||||
return isJitCompileVM_;
|
||||
}
|
||||
|
||||
static void InitializeIcuData(const JSRuntimeOptions &options);
|
||||
|
||||
std::vector<std::pair<DeleteEntryPoint, std::pair<void *, void *>>> &GetSharedNativePointerCallbacks()
|
||||
@ -800,9 +812,11 @@ private:
|
||||
friend class panda::JSNApi;
|
||||
friend class JSPandaFileExecutor;
|
||||
friend class EcmaContext;
|
||||
friend class JitVM;
|
||||
CMap<uint32_t, EcmaVM *> workerList_ {};
|
||||
Mutex mutex_;
|
||||
bool isEnableOsr_ {false};
|
||||
bool isJitCompileVM_ {false};
|
||||
bool overLimit_ {false};
|
||||
void *env_ = nullptr;
|
||||
};
|
||||
|
@ -111,6 +111,15 @@ JSTaggedValue FrameIterator::GetFunction() const
|
||||
|
||||
AOTFileInfo::CallSiteInfo FrameIterator::CalCallSiteInfo(uintptr_t retAddr) const
|
||||
{
|
||||
JSTaggedValue func = GetFunction();
|
||||
if (func.IsJSFunction()) {
|
||||
JSFunction *jsfunc = JSFunction::Cast(func.GetTaggedObject());
|
||||
JSTaggedValue machineCode = jsfunc->GetMachineCode();
|
||||
if (machineCode.IsMachineCodeObject() && MachineCode::Cast(machineCode.GetTaggedObject())->IsInText(retAddr)) {
|
||||
return MachineCode::Cast(machineCode.GetTaggedObject())->CalCallSiteInfo(retAddr);
|
||||
}
|
||||
}
|
||||
|
||||
return const_cast<JSThread *>(thread_)->GetCurrentEcmaContext()->CalCallSiteInfo(retAddr);
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include "ecmascript/platform/file.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
std::deque<JitTask*> Jit::asyncCompileJitTasks_;
|
||||
Mutex Jit::asyncCompileJitTasksMtx_;
|
||||
void (*Jit::initJitCompiler_)(JSRuntimeOptions options) = nullptr;
|
||||
bool(*Jit::jitCompile_)(void*, JitTask*) = nullptr;
|
||||
bool(*Jit::jitFinalize_)(void*, JitTask*) = nullptr;
|
||||
@ -36,6 +34,7 @@ Jit *Jit::GetInstance()
|
||||
|
||||
void Jit::SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnable)
|
||||
{
|
||||
LockHolder holder(setEnableLock_);
|
||||
if (options.IsEnableAPPJIT()) {
|
||||
// temporary for app jit options test.
|
||||
LOG_JIT(DEBUG) << (isEnable ? "jit is enable" : "jit is disable");
|
||||
@ -51,6 +50,24 @@ void Jit::SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnable)
|
||||
if (initialized_ && !jitEnable_) {
|
||||
jitEnable_ = true;
|
||||
initJitCompiler_(options);
|
||||
JitTaskpool::GetCurrentTaskpool()->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::Destroy()
|
||||
{
|
||||
if (!initialized_) {
|
||||
return;
|
||||
}
|
||||
|
||||
LockHolder holder(setEnableLock_);
|
||||
|
||||
JitTaskpool::GetCurrentTaskpool()->Destroy();
|
||||
initialized_ = false;
|
||||
jitEnable_ = false;
|
||||
if (libHandle_ != nullptr) {
|
||||
CloseLib(libHandle_);
|
||||
libHandle_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,10 +126,6 @@ void Jit::Initialize()
|
||||
|
||||
Jit::~Jit()
|
||||
{
|
||||
if (libHandle_ != nullptr) {
|
||||
CloseLib(libHandle_);
|
||||
libHandle_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Jit::SupportJIT(Method *method)
|
||||
@ -146,93 +159,71 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, int32_t offset,
|
||||
|
||||
Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject());
|
||||
CString fileDesc = method->GetJSPandaFile()->GetJSPandaFileDesc();
|
||||
FunctionKind kind = method->GetFunctionKind();
|
||||
CString methodName = method->GetRecordNameStr() + "." + CString(method->GetMethodName()) + ", at:" + fileDesc;
|
||||
if (!jit->SupportJIT(method)) {
|
||||
LOG_JIT(INFO) << "method does not support jit:" << methodName << ", kind:" << static_cast<int>(kind);
|
||||
uint32_t codeSize = method->GetCodeSize();
|
||||
CString methodInfo = method->GetRecordNameStr() + "." + CString(method->GetMethodName()) + ", at:" + fileDesc +
|
||||
", code size:" + ToCString(codeSize);
|
||||
|
||||
constexpr uint32_t maxSize = 9000;
|
||||
if (codeSize > maxSize) {
|
||||
LOG_JIT(DEBUG) << "skip jit task, as too large:" << methodInfo;
|
||||
return;
|
||||
}
|
||||
if (vm->GetJSThread()->IsMachineCodeLowMemory()) {
|
||||
LOG_JIT(DEBUG) << "skip jit task, as low code memory:" << methodInfo;
|
||||
return;
|
||||
}
|
||||
bool isJSSharedFunction = jsFunction.GetTaggedValue().IsJSSharedFunction();
|
||||
if (!jit->SupportJIT(method) || jsFunction.GetTaggedValue().IsJSSharedFunction()) {
|
||||
FunctionKind kind = method->GetFunctionKind();
|
||||
LOG_JIT(DEBUG) << "method does not support jit:" << methodInfo << ", kind:" << static_cast<int>(kind)
|
||||
<<", JSSharedFunction:" << isJSSharedFunction;
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsFunction->GetMachineCode() == JSTaggedValue::Hole()) {
|
||||
LOG_JIT(DEBUG) << "skip method, as it compiling:" << methodName;
|
||||
LOG_JIT(DEBUG) << "skip method, as it compiling:" << methodInfo;
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsFunction->GetMachineCode() != JSTaggedValue::Undefined()) {
|
||||
MachineCode *machineCode = MachineCode::Cast(jsFunction->GetMachineCode().GetTaggedObject());
|
||||
if (machineCode->GetOSROffset() == MachineCode::INVALID_OSR_OFFSET) {
|
||||
LOG_JIT(DEBUG) << "skip method, as it has been jit compiled:" << methodName;
|
||||
LOG_JIT(DEBUG) << "skip method, as it has been jit compiled:" << methodInfo;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// using hole value to indecate compiling. todo: reset when failed
|
||||
jsFunction->SetMachineCode(vm->GetJSThread(), JSTaggedValue::Hole());
|
||||
|
||||
LOG_JIT(DEBUG) << "start compile:" << methodName << ", kind:" << static_cast<int>(kind) <<
|
||||
", mode:" << ((mode == SYNC) ? "sync" : "async") <<
|
||||
(offset == MachineCode::INVALID_OSR_OFFSET ? "" : ", OSR offset: " + std::to_string(offset));
|
||||
|
||||
{
|
||||
CString msg = "compile method:" + methodName + ", in work thread";
|
||||
Scope scope(msg);
|
||||
|
||||
JitTask *jitTask = new JitTask(vm, jit, jsFunction, methodName, offset, vm->GetJSThread()->GetThreadId());
|
||||
CString msg = "compile method:" + methodInfo + ", in work thread";
|
||||
TimeScope scope(msg);
|
||||
JitTaskpool::GetCurrentTaskpool()->WaitForJitTaskPoolReady();
|
||||
EcmaVM *compilerVm = JitTaskpool::GetCurrentTaskpool()->GetCompilerVm();
|
||||
std::shared_ptr<JitTask> jitTask = std::make_shared<JitTask>(vm->GetJSThread(), compilerVm->GetJSThread(),
|
||||
jit, jsFunction, methodInfo, offset, vm->GetJSThread()->GetThreadId(), mode);
|
||||
|
||||
jitTask->PrepareCompile();
|
||||
|
||||
jitTask->Optimize();
|
||||
|
||||
JitTaskpool::GetCurrentTaskpool()->PostTask(
|
||||
std::make_unique<JitTask::AsyncTask>(jitTask, vm->GetJSThread()->GetThreadId()));
|
||||
if (mode == SYNC) {
|
||||
// cg
|
||||
jitTask->Finalize();
|
||||
// sync mode, also compile in taskpool as litecg unsupport parallel compile,
|
||||
// wait task compile finish then install code
|
||||
jitTask->WaitFinish();
|
||||
jitTask->InstallCode();
|
||||
// free
|
||||
delete jitTask;
|
||||
} else {
|
||||
jit->AddAsyncCompileTask(jitTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JitTask *Jit::GetAsyncCompileTask()
|
||||
{
|
||||
LockHolder holder(asyncCompileJitTasksMtx_);
|
||||
if (asyncCompileJitTasks_.empty()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
auto jitTask = asyncCompileJitTasks_.front();
|
||||
return jitTask;
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::AddAsyncCompileTask(JitTask *jitTask)
|
||||
{
|
||||
LockHolder holder(asyncCompileJitTasksMtx_);
|
||||
if (asyncCompileJitTasks_.empty()) {
|
||||
Taskpool::GetCurrentTaskpool()->PostTask(
|
||||
std::make_unique<JitTask::AsyncTask>(jitTask, jitTask->GetVM()->GetJSThread()->GetThreadId()));
|
||||
}
|
||||
asyncCompileJitTasks_.push_back(jitTask);
|
||||
}
|
||||
|
||||
void Jit::RemoveAsyncCompileTask([[maybe_unused]] JitTask *jitTask)
|
||||
{
|
||||
LockHolder holder(asyncCompileJitTasksMtx_);
|
||||
ASSERT(!asyncCompileJitTasks_.empty());
|
||||
ASSERT(asyncCompileJitTasks_.front() == jitTask);
|
||||
asyncCompileJitTasks_.pop_front();
|
||||
}
|
||||
|
||||
void Jit::RequestInstallCode(JitTask *jitTask)
|
||||
void Jit::RequestInstallCode(std::shared_ptr<JitTask> jitTask)
|
||||
{
|
||||
LockHolder holder(installJitTasksDequeMtx_);
|
||||
auto &taskQueue = installJitTasks_[jitTask->GetTaskThreadId()];
|
||||
taskQueue.push_back(jitTask);
|
||||
|
||||
// set
|
||||
jitTask->GetVM()->GetJSThread()->SetInstallMachineCode(true);
|
||||
jitTask->GetVM()->GetJSThread()->SetCheckSafePointStatus();
|
||||
jitTask->GetHostThread()->SetInstallMachineCode(true);
|
||||
jitTask->GetHostThread()->SetCheckSafePointStatus();
|
||||
}
|
||||
|
||||
void Jit::InstallTasks(uint32_t threadId)
|
||||
@ -240,10 +231,9 @@ void Jit::InstallTasks(uint32_t threadId)
|
||||
LockHolder holder(installJitTasksDequeMtx_);
|
||||
auto &taskQueue = installJitTasks_[threadId];
|
||||
for (auto it = taskQueue.begin(); it != taskQueue.end(); it++) {
|
||||
JitTask *task = *it;
|
||||
std::shared_ptr<JitTask> task = *it;
|
||||
// check task state
|
||||
task->InstallCode();
|
||||
delete task;
|
||||
}
|
||||
taskQueue.clear();
|
||||
}
|
||||
@ -266,8 +256,54 @@ void *Jit::CreateJitCompilerTask(JitTask *jitTask)
|
||||
return createJitCompilerTask_(jitTask);
|
||||
}
|
||||
|
||||
Jit::Scope::~Scope()
|
||||
void Jit::ClearTask(const std::function<bool(Task *task)> &checkClear)
|
||||
{
|
||||
LOG_JIT(INFO) << message_ << ": " << TotalSpentTime() << "ms";
|
||||
JitTaskpool::GetCurrentTaskpool()->ForEachTask([&checkClear](Task *task) {
|
||||
JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task);
|
||||
if (checkClear(asyncTask)) {
|
||||
asyncTask->Terminated();
|
||||
}
|
||||
|
||||
if (asyncTask->IsRunning()) {
|
||||
asyncTask->WaitFinish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Jit::ClearTask(EcmaContext *ecmaContext)
|
||||
{
|
||||
ClearTask([ecmaContext](Task *task) {
|
||||
JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task);
|
||||
return ecmaContext == asyncTask->GetEcmaContext();
|
||||
});
|
||||
}
|
||||
|
||||
void Jit::ClearTaskWithVm(EcmaVM *vm)
|
||||
{
|
||||
ClearTask([vm](Task *task) {
|
||||
JitTask::AsyncTask *asyncTask = static_cast<JitTask::AsyncTask*>(task);
|
||||
return vm == asyncTask->GetHostVM();
|
||||
});
|
||||
|
||||
LockHolder holder(installJitTasksDequeMtx_);
|
||||
auto &taskQueue = installJitTasks_[vm->GetJSThread()->GetThreadId()];
|
||||
taskQueue.clear();
|
||||
}
|
||||
|
||||
void Jit::CheckMechineCodeSpaceMemory(JSThread *thread, int remainSize)
|
||||
{
|
||||
if (!thread->IsMachineCodeLowMemory()) {
|
||||
return;
|
||||
}
|
||||
if (remainSize > MIN_CODE_SPACE_SIZE) {
|
||||
thread->SetMachineCodeLowMemory(false);
|
||||
}
|
||||
}
|
||||
|
||||
Jit::TimeScope::~TimeScope()
|
||||
{
|
||||
if (outPutLog_) {
|
||||
LOG_JIT(INFO) << message_ << ": " << TotalSpentTime() << "ms";
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/mem/clock_scope.h"
|
||||
#include "ecmascript/compiler/compiler_log.h"
|
||||
#include "ecmascript/jit/jit_thread.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JitTask;
|
||||
@ -32,9 +33,9 @@ class Jit {
|
||||
public:
|
||||
Jit() {}
|
||||
~Jit();
|
||||
static Jit *GetInstance();
|
||||
static PUBLIC_API Jit *GetInstance();
|
||||
void SetEnableOrDisable(const JSRuntimeOptions &options, bool isEnable);
|
||||
bool IsEnable();
|
||||
bool PUBLIC_API IsEnable();
|
||||
void Initialize();
|
||||
|
||||
static void Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction,
|
||||
@ -49,22 +50,91 @@ public:
|
||||
|
||||
void DeleteJitCompile(void *compiler);
|
||||
|
||||
void RequestInstallCode(JitTask *jitTask);
|
||||
void RequestInstallCode(std::shared_ptr<JitTask> jitTask);
|
||||
void InstallTasks(uint32_t threadId);
|
||||
|
||||
JitTask *GetAsyncCompileTask();
|
||||
void AddAsyncCompileTask(JitTask *jitTask);
|
||||
void RemoveAsyncCompileTask(JitTask *jitTask);
|
||||
void ClearTask(const std::function<bool(Task *task)> &checkClear);
|
||||
void ClearTask(EcmaContext *ecmaContext);
|
||||
void ClearTaskWithVm(EcmaVM *vm);
|
||||
void Destroy();
|
||||
void CheckMechineCodeSpaceMemory(JSThread *thread, int remainSize);
|
||||
|
||||
NO_COPY_SEMANTIC(Jit);
|
||||
NO_MOVE_SEMANTIC(Jit);
|
||||
|
||||
class Scope : public ClockScope {
|
||||
class TimeScope : public ClockScope {
|
||||
public:
|
||||
Scope(CString message) : message_(message) {}
|
||||
~Scope();
|
||||
explicit TimeScope(CString message, bool outPutLog = true) : message_(message), outPutLog_(outPutLog) {}
|
||||
explicit TimeScope() : message_(""), outPutLog_(false) {}
|
||||
PUBLIC_API ~TimeScope();
|
||||
private:
|
||||
CString message_;
|
||||
bool outPutLog_;
|
||||
};
|
||||
|
||||
class JitLockHolder {
|
||||
public:
|
||||
explicit JitLockHolder(const CompilationEnv *env) : thread_(nullptr), scope_()
|
||||
{
|
||||
if (env->IsJitCompiler()) {
|
||||
JSThread *thread = env->GetJSThread();
|
||||
ASSERT(thread->IsJitThread());
|
||||
thread_ = static_cast<JitThread*>(thread);
|
||||
thread_->ManagedCodeBegin();
|
||||
thread_->GetHostThread()->GetJitLock()->Lock();
|
||||
}
|
||||
}
|
||||
|
||||
explicit JitLockHolder(const CompilationEnv *env, CString message) : thread_(nullptr),
|
||||
scope_("Jit Compile Pass: " + message + ", Time:", false)
|
||||
{
|
||||
if (env->IsJitCompiler()) {
|
||||
JSThread *thread = env->GetJSThread();
|
||||
ASSERT(thread->IsJitThread());
|
||||
thread_ = static_cast<JitThread*>(thread);
|
||||
thread_->ManagedCodeBegin();
|
||||
thread_->GetHostThread()->GetJitLock()->Lock();
|
||||
}
|
||||
}
|
||||
|
||||
~JitLockHolder()
|
||||
{
|
||||
if (thread_ != nullptr) {
|
||||
thread_->GetHostThread()->GetJitLock()->Unlock();
|
||||
thread_->ManagedCodeEnd();
|
||||
}
|
||||
}
|
||||
JitThread *thread_ {nullptr};
|
||||
TimeScope scope_;
|
||||
ALLOW_HEAP_ACCESS
|
||||
NO_COPY_SEMANTIC(JitLockHolder);
|
||||
NO_MOVE_SEMANTIC(JitLockHolder);
|
||||
};
|
||||
|
||||
class JitGCLockHolder {
|
||||
public:
|
||||
explicit JitGCLockHolder(JSThread *thread) : thread_(thread)
|
||||
{
|
||||
ASSERT(!thread->IsJitThread());
|
||||
if (Jit::GetInstance()->IsEnable()) {
|
||||
thread_->GetJitLock()->Lock();
|
||||
locked_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
~JitGCLockHolder()
|
||||
{
|
||||
if (locked_) {
|
||||
thread_->GetJitLock()->Unlock();
|
||||
locked_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
JSThread *thread_;
|
||||
bool locked_ { false };
|
||||
|
||||
NO_COPY_SEMANTIC(JitGCLockHolder);
|
||||
NO_MOVE_SEMANTIC(JitGCLockHolder);
|
||||
};
|
||||
|
||||
private:
|
||||
@ -72,10 +142,10 @@ private:
|
||||
bool initialized_ { false };
|
||||
bool jitEnable_ { false };
|
||||
|
||||
std::unordered_map<uint32_t, std::deque<JitTask*>> installJitTasks_;
|
||||
static std::deque<JitTask*> asyncCompileJitTasks_;
|
||||
std::unordered_map<uint32_t, std::deque<std::shared_ptr<JitTask>>> installJitTasks_;
|
||||
Mutex installJitTasksDequeMtx_;
|
||||
static Mutex asyncCompileJitTasksMtx_;
|
||||
Mutex setEnableLock_;
|
||||
static constexpr int MIN_CODE_SPACE_SIZE = 1_KB;
|
||||
|
||||
static void (*initJitCompiler_)(JSRuntimeOptions);
|
||||
static bool(*jitCompile_)(void*, JitTask*);
|
||||
|
@ -18,12 +18,53 @@
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/compiler/aot_file/func_entry_des.h"
|
||||
#include "ecmascript/ic/profile_type_info.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
JitTaskpool *JitTaskpool::GetCurrentTaskpool()
|
||||
{
|
||||
static JitTaskpool *taskpool = new JitTaskpool();
|
||||
return taskpool;
|
||||
}
|
||||
|
||||
uint32_t JitTaskpool::TheMostSuitableThreadNum([[maybe_unused]]uint32_t threadNum) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
JitTask::JitTask(JSThread *hostThread, JSThread *compilerThread, Jit *jit, JSHandle<JSFunction> &jsFunction,
|
||||
CString &methodName, int32_t offset, uint32_t taskThreadId, JitCompileMode mode)
|
||||
: hostThread_(hostThread),
|
||||
compilerThread_(compilerThread),
|
||||
jit_(jit),
|
||||
jsFunction_(jsFunction),
|
||||
compilerTask_(nullptr),
|
||||
state_(CompileState::SUCCESS),
|
||||
methodInfo_(methodName),
|
||||
offset_(offset),
|
||||
taskThreadId_(taskThreadId),
|
||||
ecmaContext_(nullptr),
|
||||
jitCompileMode_(mode),
|
||||
runState_(RunState::INIT)
|
||||
{
|
||||
ecmaContext_ = hostThread->GetCurrentEcmaContext();
|
||||
persistentHandles_ = std::make_unique<PersistentHandles>(hostThread->GetEcmaVM());
|
||||
}
|
||||
|
||||
void JitTask::PrepareCompile()
|
||||
{
|
||||
CloneProfileTypeInfo();
|
||||
PersistentHandle();
|
||||
compilerTask_ = jit_->CreateJitCompilerTask(this);
|
||||
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
JSTaggedValue constpool = method->GetConstantPool();
|
||||
if (!ConstantPool::CheckUnsharedConstpool(constpool)) {
|
||||
hostThread_->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpool);
|
||||
}
|
||||
|
||||
SetRunState(RunState::INIT);
|
||||
}
|
||||
|
||||
void JitTask::Optimize()
|
||||
@ -55,30 +96,29 @@ void JitTask::InstallOsrCode(JSHandle<Method> &method, JSHandle<MachineCode> &co
|
||||
}
|
||||
FuncEntryDes *funcEntryDes = reinterpret_cast<FuncEntryDes*>(codeObj->GetFuncEntryDes());
|
||||
method->SetIsFastCall(funcEntryDes->isFastCall_);
|
||||
JSThread* thread = vm_->GetJSThread();
|
||||
JSHandle<ProfileTypeInfo> profileInfoHandle =
|
||||
JSHandle<ProfileTypeInfo>::Cast(JSHandle<JSTaggedValue>(thread, profile));
|
||||
JSHandle<ProfileTypeInfo>::Cast(JSHandle<JSTaggedValue>(hostThread_, profile));
|
||||
uint32_t slotId = profileInfoHandle->GetCacheLength() - 1; // 1 : get last slot
|
||||
auto profileData = profileInfoHandle->Get(slotId);
|
||||
auto factory = vm_->GetFactory();
|
||||
auto factory = hostThread_->GetEcmaVM()->GetFactory();
|
||||
if (!profileData.IsTaggedArray()) {
|
||||
const uint32_t initLen = 1;
|
||||
JSHandle<TaggedArray> newArr = factory->NewTaggedArray(initLen);
|
||||
newArr->Set(thread, 0, codeObj.GetTaggedValue());
|
||||
profileInfoHandle->Set(thread, slotId, newArr.GetTaggedValue());
|
||||
newArr->Set(hostThread_, 0, codeObj.GetTaggedValue());
|
||||
profileInfoHandle->Set(hostThread_, slotId, newArr.GetTaggedValue());
|
||||
LOG_JIT(DEBUG) << "[OSR] Install machine code:" << GetMethodInfo()
|
||||
<< ", code address: " << reinterpret_cast<void*>(codeObj->GetFuncAddr())
|
||||
<< ", index: " << newArr->GetLength() - 1;
|
||||
return;
|
||||
}
|
||||
JSHandle<TaggedArray> arr(thread, profileData);
|
||||
JSHandle<TaggedArray> arr(hostThread_, profileData);
|
||||
JSHandle<TaggedArray> newArr = factory->NewTaggedArray(arr->GetLength() + 1); // 1 : added for current codeObj
|
||||
uint32_t i = 0;
|
||||
for (; i < arr->GetLength(); i++) {
|
||||
newArr->Set(thread, i, arr->Get(i));
|
||||
newArr->Set(hostThread_, i, arr->Get(i));
|
||||
}
|
||||
newArr->Set(thread, i, codeObj.GetTaggedValue());
|
||||
profileInfoHandle->Set(thread, slotId, newArr.GetTaggedValue());
|
||||
newArr->Set(hostThread_, i, codeObj.GetTaggedValue());
|
||||
profileInfoHandle->Set(hostThread_, slotId, newArr.GetTaggedValue());
|
||||
LOG_JIT(DEBUG) << "[OSR] Install machine code:" << GetMethodInfo()
|
||||
<< ", code address: " << reinterpret_cast<void*>(codeObj->GetFuncAddr())
|
||||
<< ", index: " << newArr->GetLength() - 1;
|
||||
@ -90,7 +130,9 @@ void JitTask::InstallCode()
|
||||
if (!IsCompileSuccess()) {
|
||||
return;
|
||||
}
|
||||
JSHandle<Method> methodHandle(vm_->GetJSThread(), Method::Cast(jsFunction_->GetMethod().GetTaggedObject()));
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(hostThread_);
|
||||
|
||||
JSHandle<Method> methodHandle(hostThread_, Method::Cast(jsFunction_->GetMethod().GetTaggedObject()));
|
||||
|
||||
size_t funcEntryDesSizeAlign = AlignUp(codeDesc_.funcEntryDesSize, MachineCode::TEXT_ALIGN);
|
||||
|
||||
@ -103,35 +145,68 @@ void JitTask::InstallCode()
|
||||
size_t size = funcEntryDesSizeAlign + rodataSizeBeforeTextAlign + codeSizeAlign + rodataSizeAfterTextAlign +
|
||||
stackMapSizeAlign;
|
||||
|
||||
JSHandle<MachineCode> machineCodeObj = vm_->GetFactory()->NewMachineCodeObject(size, &codeDesc_, methodHandle);
|
||||
methodHandle = hostThread_->GetEcmaVM()->GetFactory()->CloneMethod(methodHandle);
|
||||
jsFunction_->SetMethod(hostThread_, methodHandle);
|
||||
JSHandle<MachineCode> machineCodeObj =
|
||||
hostThread_->GetEcmaVM()->GetFactory()->NewMachineCodeObject(size, &codeDesc_, methodHandle);
|
||||
machineCodeObj->SetOSROffset(offset_);
|
||||
|
||||
if (hostThread_->HasPendingException()) {
|
||||
// check is oom exception
|
||||
hostThread_->SetMachineCodeLowMemory(true);
|
||||
hostThread_->ClearException();
|
||||
}
|
||||
|
||||
if (IsOsrTask()) {
|
||||
InstallOsrCode(methodHandle, machineCodeObj);
|
||||
return;
|
||||
}
|
||||
// oom?
|
||||
|
||||
uintptr_t codeAddr = machineCodeObj->GetFuncAddr();
|
||||
FuncEntryDes *funcEntryDes = reinterpret_cast<FuncEntryDes*>(machineCodeObj->GetFuncEntryDes());
|
||||
jsFunction_->SetCompiledFuncEntry(codeAddr, funcEntryDes->isFastCall_);
|
||||
methodHandle->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
||||
jsFunction_->SetMachineCode(vm_->GetJSThread(), machineCodeObj);
|
||||
methodHandle->SetDeoptThreshold(hostThread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold());
|
||||
jsFunction_->SetMachineCode(hostThread_, machineCodeObj);
|
||||
|
||||
LOG_JIT(DEBUG) << "Install machine code:" << GetMethodInfo();
|
||||
}
|
||||
|
||||
void JitTask::PersistentHandle()
|
||||
{
|
||||
// transfer to global ref
|
||||
GlobalHandleCollection globalHandleCollection(vm_->GetJSThread());
|
||||
JSHandle<JSFunction> persistentHandle =
|
||||
globalHandleCollection.NewHandle<JSFunction>(jsFunction_.GetTaggedType());
|
||||
SetJsFunction(persistentHandle);
|
||||
// transfer to persistent handle
|
||||
JSHandle<JSFunction> persistentJsFunctionHandle = persistentHandles_->NewHandle(jsFunction_);
|
||||
SetJsFunction(persistentJsFunctionHandle);
|
||||
|
||||
JSHandle<ProfileTypeInfo> profileTypeInfo = persistentHandles_->NewHandle(profileTypeInfo_);
|
||||
SetProfileTypeInfo(profileTypeInfo);
|
||||
}
|
||||
|
||||
void JitTask::ReleasePersistentHandle()
|
||||
{
|
||||
GlobalHandleCollection globalHandleCollection(vm_->GetJSThread());
|
||||
globalHandleCollection.Dispose(jsFunction_);
|
||||
}
|
||||
|
||||
void JitTask::CloneProfileTypeInfo()
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(hostThread_);
|
||||
|
||||
Method *method = Method::Cast(jsFunction_->GetMethod().GetTaggedObject());
|
||||
uint32_t slotSize = method->GetSlotSize();
|
||||
JSTaggedValue profileTypeInfoVal = jsFunction_->GetProfileTypeInfo();
|
||||
JSHandle<ProfileTypeInfo> newProfileTypeInfo;
|
||||
ObjectFactory *factory = hostThread_->GetEcmaVM()->GetFactory();
|
||||
if (profileTypeInfoVal.IsUndefined() || slotSize == 0) {
|
||||
slotSize = slotSize == 0 ? 1 : slotSize; // there's no profiletypeinfo, just generate a temp profiletypeinfo
|
||||
newProfileTypeInfo = factory->NewProfileTypeInfo(slotSize);
|
||||
} else {
|
||||
JSHandle<ProfileTypeInfo> profileTypeInfo(hostThread_,
|
||||
ProfileTypeInfo::Cast(profileTypeInfoVal.GetTaggedObject()));
|
||||
newProfileTypeInfo = factory->NewProfileTypeInfo(slotSize);
|
||||
for (uint32_t i = 0; i < slotSize; i++) {
|
||||
JSTaggedValue value = profileTypeInfo->Get(i);
|
||||
newProfileTypeInfo->Set(hostThread_, i, value);
|
||||
}
|
||||
}
|
||||
SetProfileTypeInfo(newProfileTypeInfo);
|
||||
}
|
||||
|
||||
JitTask::~JitTask()
|
||||
@ -140,23 +215,47 @@ JitTask::~JitTask()
|
||||
jit_->DeleteJitCompile(compilerTask_);
|
||||
}
|
||||
|
||||
void JitTask::WaitFinish()
|
||||
{
|
||||
LockHolder lock(runStateMutex_);
|
||||
if (!IsFinish()) {
|
||||
runStateCondition_.Wait(&runStateMutex_);
|
||||
}
|
||||
}
|
||||
|
||||
bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
|
||||
{
|
||||
CString info = jitTask_->GetMethodInfo() + ", in task pool, id:" + ToCString(threadIndex) + ", time:";
|
||||
Jit::Scope scope(info);
|
||||
|
||||
jitTask_->Finalize();
|
||||
|
||||
// info main thread compile complete
|
||||
jitTask_->RequestInstallCode();
|
||||
|
||||
// as now litecg has global value, so only compile one task at a time
|
||||
jitTask_->GetJit()->RemoveAsyncCompileTask(jitTask_);
|
||||
JitTask *jitTask = jitTask_->GetJit()->GetAsyncCompileTask();
|
||||
if (jitTask != nullptr) {
|
||||
Taskpool::GetCurrentTaskpool()->PostTask(
|
||||
std::make_unique<JitTask::AsyncTask>(jitTask, jitTask->GetVM()->GetJSThread()->GetThreadId()));
|
||||
if (IsTerminate()) {
|
||||
return false;
|
||||
}
|
||||
DISALLOW_HEAP_ACCESS;
|
||||
|
||||
// JitCompileMode ASYNC
|
||||
// check init ok
|
||||
jitTask_->SetRunState(RunState::RUNNING);
|
||||
|
||||
JSThread *compilerThread = jitTask_->GetCompilerThread();
|
||||
ASSERT(compilerThread->IsJitThread());
|
||||
JitThread *jitThread = static_cast<JitThread*>(compilerThread);
|
||||
JitVM *jitvm = jitThread->GetJitVM();
|
||||
jitvm->SetHostVM(jitTask_->GetHostThread());
|
||||
|
||||
if (jitTask_->GetJsFunction().GetAddress() == 0) {
|
||||
// for unit test
|
||||
} else {
|
||||
CString info = "compile method:" + jitTask_->GetMethodInfo() + ", in jit thread";
|
||||
Jit::TimeScope scope(info);
|
||||
|
||||
jitTask_->Optimize();
|
||||
jitTask_->Finalize();
|
||||
|
||||
if (jitTask_->IsAsyncTask()) {
|
||||
// info main thread compile complete
|
||||
jitTask_->jit_->RequestInstallCode(jitTask_);
|
||||
}
|
||||
}
|
||||
jitvm->ReSetHostVM();
|
||||
jitTask_->SetRunStateFinish();
|
||||
return true;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
|
||||
#include "ecmascript/jit/jit.h"
|
||||
#include "ecmascript/jit/jit_thread.h"
|
||||
#include "ecmascript/jit/persistent_handles.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
enum CompileState : uint8_t {
|
||||
@ -28,18 +30,71 @@ enum CompileState : uint8_t {
|
||||
FAIL,
|
||||
};
|
||||
|
||||
enum RunState : uint8_t {
|
||||
INIT = 0,
|
||||
RUNNING,
|
||||
FINISH
|
||||
};
|
||||
|
||||
class JitTaskpool : public Taskpool {
|
||||
public:
|
||||
PUBLIC_API static JitTaskpool *GetCurrentTaskpool();
|
||||
JitTaskpool() = default;
|
||||
NO_COPY_SEMANTIC(JitTaskpool);
|
||||
NO_MOVE_SEMANTIC(JitTaskpool);
|
||||
|
||||
EcmaVM *GetCompilerVm()
|
||||
{
|
||||
return compilerVm_;
|
||||
}
|
||||
|
||||
void SetCompilerVm(EcmaVM *vm)
|
||||
{
|
||||
LockHolder lock(jitTaskPoolMutex_);
|
||||
compilerVm_ = vm;
|
||||
jitTaskPoolCV_.SignalAll();
|
||||
}
|
||||
|
||||
void WaitForJitTaskPoolReady()
|
||||
{
|
||||
LockHolder lock(jitTaskPoolMutex_);
|
||||
if (compilerVm_ == nullptr) {
|
||||
jitTaskPoolCV_.Wait(&jitTaskPoolMutex_);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
RegisterRunnerHook([](os::thread::native_handle_type thread) {
|
||||
os::thread::SetThreadName(thread, "OS_JIT_Thread");
|
||||
auto jitVm = JitVM::Create();
|
||||
JitTaskpool::GetCurrentTaskpool()->SetCompilerVm(jitVm);
|
||||
}, []([[maybe_unused]] os::thread::native_handle_type thread) {
|
||||
EcmaVM *compilerVm = JitTaskpool::GetCurrentTaskpool()->GetCompilerVm();
|
||||
JitVM::Destroy(compilerVm);
|
||||
});
|
||||
Taskpool::Initialize();
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
Taskpool::Destroy(compilerVm_->GetJSThread()->GetThreadId());
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t TheMostSuitableThreadNum(uint32_t threadNum) const override;
|
||||
EcmaVM *compilerVm_;
|
||||
Mutex jitTaskPoolMutex_;
|
||||
ConditionVariable jitTaskPoolCV_;
|
||||
};
|
||||
|
||||
class JitTask {
|
||||
public:
|
||||
JitTask(EcmaVM *vm, Jit *jit, JSHandle<JSFunction> &jsFunction, CString &methodName, int32_t offset,
|
||||
uint32_t taskThreadId)
|
||||
: vm_(vm),
|
||||
jit_(jit),
|
||||
jsFunction_(jsFunction),
|
||||
compilerTask_(nullptr),
|
||||
state_(CompileState::SUCCESS),
|
||||
methodInfo_(methodName),
|
||||
offset_(offset),
|
||||
taskThreadId_(taskThreadId) { }
|
||||
JitTask(JSThread *hostThread, JSThread *compilerThread, Jit *jit,
|
||||
JSHandle<JSFunction> &jsFunction, CString &methodName, int32_t offset,
|
||||
uint32_t taskThreadId, JitCompileMode mode);
|
||||
// for ut
|
||||
JitTask(EcmaVM *hVm, EcmaVM *cVm, Jit *jit, uint32_t taskThreadId, JitCompileMode mode);
|
||||
~JitTask();
|
||||
void Optimize();
|
||||
void Finalize();
|
||||
@ -62,11 +117,6 @@ public:
|
||||
return offset_;
|
||||
}
|
||||
|
||||
void RequestInstallCode()
|
||||
{
|
||||
jit_->RequestInstallCode(this);
|
||||
}
|
||||
|
||||
bool IsCompileSuccess() const
|
||||
{
|
||||
return state_ == CompileState::SUCCESS;
|
||||
@ -87,9 +137,24 @@ public:
|
||||
return jit_;
|
||||
}
|
||||
|
||||
EcmaVM *GetVM()
|
||||
JSThread *GetHostThread()
|
||||
{
|
||||
return vm_;
|
||||
return hostThread_;
|
||||
}
|
||||
|
||||
EcmaVM *GetHostVM()
|
||||
{
|
||||
return hostThread_->GetEcmaVM();
|
||||
}
|
||||
|
||||
JSThread *GetCompilerThread()
|
||||
{
|
||||
return compilerThread_;
|
||||
}
|
||||
|
||||
JitVM *GetCompilerVM()
|
||||
{
|
||||
return static_cast<JitVM*>(compilerThread_->GetEcmaVM());
|
||||
}
|
||||
|
||||
CString GetMethodInfo() const
|
||||
@ -106,32 +171,106 @@ public:
|
||||
{
|
||||
return taskThreadId_;
|
||||
}
|
||||
|
||||
EcmaContext *GetEcmaContext() const
|
||||
{
|
||||
return ecmaContext_;
|
||||
}
|
||||
|
||||
void SetRunState(RunState s)
|
||||
{
|
||||
runState_.store(s, std::memory_order_release);
|
||||
}
|
||||
|
||||
void SetRunStateFinish()
|
||||
{
|
||||
LockHolder lock(runStateMutex_);
|
||||
runState_.store(RunState::FINISH);
|
||||
runStateCondition_.SignalAll();
|
||||
}
|
||||
|
||||
bool IsFinish() const
|
||||
{
|
||||
return runState_.load(std::memory_order_acquire) == RunState::FINISH;
|
||||
}
|
||||
bool IsRunning() const
|
||||
{
|
||||
return runState_.load(std::memory_order_acquire) == RunState::RUNNING;
|
||||
}
|
||||
void WaitFinish();
|
||||
bool IsAsyncTask() const
|
||||
{
|
||||
return jitCompileMode_ == JitCompileMode::ASYNC;
|
||||
}
|
||||
|
||||
void Terminated()
|
||||
{
|
||||
persistentHandles_->SetTerminated();
|
||||
}
|
||||
|
||||
class AsyncTask : public Task {
|
||||
public:
|
||||
explicit AsyncTask(JitTask *jitTask, int32_t id) : Task(id), jitTask_(jitTask) { }
|
||||
explicit AsyncTask(std::shared_ptr<JitTask>jitTask, int32_t id) : Task(id), jitTask_(jitTask) { }
|
||||
virtual ~AsyncTask() override = default;
|
||||
|
||||
bool Run(uint32_t threadIndex) override;
|
||||
EcmaContext *GetEcmaContext() const
|
||||
{
|
||||
return jitTask_->GetEcmaContext();
|
||||
}
|
||||
EcmaVM *GetHostVM() const
|
||||
{
|
||||
return jitTask_->GetHostThread()->GetEcmaVM();
|
||||
}
|
||||
bool IsRunning() const
|
||||
{
|
||||
return jitTask_->IsRunning();
|
||||
}
|
||||
void WaitFinish() const
|
||||
{
|
||||
jitTask_->WaitFinish();
|
||||
}
|
||||
|
||||
void Terminated()
|
||||
{
|
||||
Task::Terminated();
|
||||
jitTask_->Terminated();
|
||||
}
|
||||
private:
|
||||
JitTask *jitTask_;
|
||||
std::shared_ptr<JitTask> jitTask_ { nullptr };
|
||||
};
|
||||
private:
|
||||
void PersistentHandle();
|
||||
void ReleasePersistentHandle();
|
||||
void CloneProfileTypeInfo();
|
||||
void SetJsFunction(JSHandle<JSFunction> &jsFunction)
|
||||
{
|
||||
jsFunction_ = jsFunction;
|
||||
}
|
||||
|
||||
EcmaVM *vm_;
|
||||
void SetProfileTypeInfo(JSHandle<ProfileTypeInfo> &profileTypeInfo)
|
||||
{
|
||||
profileTypeInfo_ = profileTypeInfo;
|
||||
}
|
||||
|
||||
JSThread *hostThread_;
|
||||
JSThread *compilerThread_;
|
||||
Jit *jit_;
|
||||
JSHandle<JSFunction> jsFunction_;
|
||||
JSHandle<ProfileTypeInfo> profileTypeInfo_;
|
||||
void *compilerTask_;
|
||||
MachineCodeDesc codeDesc_;
|
||||
CompileState state_;
|
||||
CString methodInfo_;
|
||||
int32_t offset_;
|
||||
uint32_t taskThreadId_;
|
||||
std::unique_ptr<PersistentHandles> persistentHandles_;
|
||||
EcmaContext *ecmaContext_;
|
||||
JitCompileMode jitCompileMode_;
|
||||
|
||||
std::atomic<RunState> runState_;
|
||||
Mutex runStateMutex_;
|
||||
ConditionVariable runStateCondition_;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_JIT_TASK_H
|
||||
|
75
ecmascript/jit/jit_thread.cpp
Normal file
75
ecmascript/jit/jit_thread.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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_thread.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
JitThread::JitThread(JitVM *jitVM) : JSThread(jitVM, true) {};
|
||||
|
||||
JSThread *JitThread::GetHostThread() const
|
||||
{
|
||||
return hostThread_;
|
||||
}
|
||||
|
||||
void JitThread::SetHostThread(JSThread *thread)
|
||||
{
|
||||
hostThread_ = thread;
|
||||
}
|
||||
|
||||
JitVM *JitThread::GetJitVM() const
|
||||
{
|
||||
return static_cast<JitVM*>(JSThread::GetEcmaVM());
|
||||
}
|
||||
|
||||
JitVM *JitVM::Create()
|
||||
{
|
||||
auto vm = new JitVM();
|
||||
JitThread *thread = new JitThread(vm);
|
||||
vm->jitThread_ = thread;
|
||||
|
||||
// super ecmavm
|
||||
vm->InitializeForJit(thread);
|
||||
return vm;
|
||||
}
|
||||
|
||||
void JitVM::Destroy(EcmaVM *compilerVm)
|
||||
{
|
||||
JitVM *jitVM = static_cast<JitVM*>(compilerVm);
|
||||
delete jitVM->jitThread_;
|
||||
jitVM->jitThread_ = nullptr;
|
||||
|
||||
delete jitVM;
|
||||
}
|
||||
|
||||
void JitVM::SetHostVM(JSThread *hostThread)
|
||||
{
|
||||
hostVm_ = hostThread->GetEcmaVM();
|
||||
jitThread_->SetHostThread(hostThread);
|
||||
|
||||
const GlobalEnvConstants *constants = hostThread->GlobalConstants();
|
||||
jitThread_->SetGlobalConstants(constants);
|
||||
}
|
||||
|
||||
void JitVM::ReSetHostVM()
|
||||
{
|
||||
hostVm_ = nullptr;
|
||||
jitThread_->SetHostThread(nullptr);
|
||||
jitThread_->SetGlobalConstants(nullptr);
|
||||
}
|
||||
|
||||
} // namespace panda::ecmascript
|
56
ecmascript/jit/jit_thread.h
Normal file
56
ecmascript/jit/jit_thread.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_JIT_THREAD_H
|
||||
#define ECMASCRIPT_JIT_JIT_THREAD_H
|
||||
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/mem/heap.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JitVM;
|
||||
class JitThread final : public JSThread {
|
||||
public:
|
||||
JitThread(JitVM *jitVM);
|
||||
EcmaVM *GetEcmaVM() const;
|
||||
JSThread * PUBLIC_API GetHostThread() const;
|
||||
void SetHostThread(JSThread *thread);
|
||||
JitVM *GetJitVM() const;
|
||||
|
||||
private:
|
||||
JSThread *hostThread_ {nullptr};
|
||||
};
|
||||
|
||||
class JitVM final : public EcmaVM {
|
||||
public:
|
||||
JitVM() : EcmaVM() {}
|
||||
static JitVM *Create();
|
||||
static void Destroy(EcmaVM *jitvm);
|
||||
|
||||
EcmaVM *GetHostVm() const
|
||||
{
|
||||
return hostVm_;
|
||||
}
|
||||
|
||||
void SetHostVM(JSThread *hostThread);
|
||||
void ReSetHostVM();
|
||||
|
||||
private:
|
||||
EcmaVM *hostVm_ {nullptr};
|
||||
JitThread *jitThread_ {nullptr};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_JIT_TASK_H
|
115
ecmascript/jit/persistent_handles.cpp
Normal file
115
ecmascript/jit/persistent_handles.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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/persistent_handles.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void PersistentHandles::Init()
|
||||
{
|
||||
EcmaContext *context = vm_->GetJSThread()->GetCurrentEcmaContext();
|
||||
context->AddPersistentHandles(this);
|
||||
}
|
||||
|
||||
PersistentHandles::~PersistentHandles()
|
||||
{
|
||||
if (!isTerminate_) {
|
||||
EcmaContext *context = vm_->GetJSThread()->GetCurrentEcmaContext();
|
||||
context->RemovePersistentHandles(this);
|
||||
}
|
||||
for (auto block : handleBlocks_) {
|
||||
delete block;
|
||||
}
|
||||
handleBlocks_.clear();
|
||||
}
|
||||
|
||||
uintptr_t PersistentHandles::GetJsHandleSlot(JSTaggedType value)
|
||||
{
|
||||
if (blockNext_ == blockLimit_) {
|
||||
Expand();
|
||||
}
|
||||
ASSERT(blockNext_ != blockLimit_);
|
||||
|
||||
*blockNext_ = value;
|
||||
uintptr_t slot = reinterpret_cast<uintptr_t>(blockNext_);
|
||||
blockNext_++;
|
||||
return slot;
|
||||
}
|
||||
|
||||
uintptr_t PersistentHandles::Expand()
|
||||
{
|
||||
auto block = new std::array<JSTaggedType, BLOCK_SIZE>();
|
||||
handleBlocks_.push_back(block);
|
||||
|
||||
blockNext_ = &block->data()[0];
|
||||
blockLimit_ = &block->data()[BLOCK_SIZE];
|
||||
return reinterpret_cast<uintptr_t>(blockNext_);
|
||||
}
|
||||
|
||||
void PersistentHandles::Iterate(const RootRangeVisitor &rv)
|
||||
{
|
||||
size_t size = handleBlocks_.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
auto block = handleBlocks_.at(i);
|
||||
auto start = block->data();
|
||||
auto end = (i != (size - 1)) ? &(block->data()[BLOCK_SIZE]) : blockNext_;
|
||||
rv(ecmascript::Root::ROOT_HANDLE, ObjectSlot(ToUintPtr(start)), ObjectSlot(ToUintPtr(end)));
|
||||
}
|
||||
}
|
||||
|
||||
void PersistentHandlesList::AddPersistentHandles(PersistentHandles *persistentHandles)
|
||||
{
|
||||
LockHolder lock(mutex_);
|
||||
if (persistentHandles == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (listHead_ == nullptr) {
|
||||
listHead_ = persistentHandles;
|
||||
return;
|
||||
}
|
||||
persistentHandles->next_ = listHead_;
|
||||
listHead_->pre_ = persistentHandles;
|
||||
listHead_ = persistentHandles;
|
||||
}
|
||||
|
||||
void PersistentHandlesList::RemovePersistentHandles(PersistentHandles *persistentHandles)
|
||||
{
|
||||
LockHolder lock(mutex_);
|
||||
if (persistentHandles == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto next = persistentHandles->next_;
|
||||
auto pre = persistentHandles->pre_;
|
||||
if (pre != nullptr) {
|
||||
pre->next_ = next;
|
||||
}
|
||||
if (next != nullptr) {
|
||||
next->pre_ = pre;
|
||||
}
|
||||
|
||||
if (listHead_ == persistentHandles) {
|
||||
listHead_ = persistentHandles->next_;
|
||||
}
|
||||
}
|
||||
|
||||
void PersistentHandlesList::Iterate(const RootRangeVisitor &rv)
|
||||
{
|
||||
LockHolder lock(mutex_);
|
||||
for (auto handles = listHead_; handles != nullptr; handles = handles->next_) {
|
||||
handles->Iterate(rv);
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
79
ecmascript/jit/persistent_handles.h
Normal file
79
ecmascript/jit/persistent_handles.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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_PERSISTENT_HANDLES_H
|
||||
#define ECMASCRIPT_PERSISTENT_HANDLES_H
|
||||
|
||||
#include "ecmascript/common.h"
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
class PersistentHandles {
|
||||
public:
|
||||
PersistentHandles(EcmaVM *vm) : vm_(vm)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
~PersistentHandles();
|
||||
template <typename T>
|
||||
JSHandle<T> NewHandle(JSHandle<T> value)
|
||||
{
|
||||
return JSHandle<T>(GetJsHandleSlot(value.GetTaggedType()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
JSHandle<T> NewHandle(JSTaggedType value)
|
||||
{
|
||||
return JSHandle<T>(GetJsHandleSlot(value));
|
||||
}
|
||||
|
||||
void Iterate(const RootRangeVisitor &rv);
|
||||
|
||||
void SetTerminated()
|
||||
{
|
||||
isTerminate_ = true;
|
||||
}
|
||||
private:
|
||||
void Init();
|
||||
uintptr_t GetJsHandleSlot(JSTaggedType value);
|
||||
uintptr_t Expand();
|
||||
|
||||
EcmaVM *vm_ { nullptr };
|
||||
|
||||
JSTaggedType *blockNext_ { nullptr };
|
||||
JSTaggedType *blockLimit_ { nullptr };
|
||||
PersistentHandles *pre_ { nullptr };
|
||||
PersistentHandles *next_ { nullptr };
|
||||
std::atomic_bool isTerminate_ {false};
|
||||
|
||||
static constexpr uint32_t BLOCK_SIZE = 256L;
|
||||
std::vector<std::array<JSTaggedType, BLOCK_SIZE>*> handleBlocks_;
|
||||
friend class PersistentHandlesList;
|
||||
};
|
||||
|
||||
class PersistentHandlesList {
|
||||
public:
|
||||
void AddPersistentHandles(PersistentHandles *persistentHandles);
|
||||
void RemovePersistentHandles(PersistentHandles *persistentHandles);
|
||||
void Iterate(const RootRangeVisitor &rv);
|
||||
|
||||
private:
|
||||
PersistentHandles *listHead_ { nullptr };
|
||||
Mutex mutex_;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_PERSISTENT_HANDLES_H
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "ecmascript/ecma_handle_scope.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/mem/assert_scope.h"
|
||||
|
||||
/*
|
||||
* JSHandle: A JSHandle provides a reference to an object that survives relocation by the garbage collector.
|
||||
@ -107,6 +108,7 @@ public:
|
||||
|
||||
inline JSTaggedValue GetTaggedValue() const
|
||||
{
|
||||
CHECK_NO_DEREF_HANDLE;
|
||||
if (GetAddress() == 0U) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
@ -115,6 +117,7 @@ public:
|
||||
|
||||
inline JSTaggedType GetTaggedType() const
|
||||
{
|
||||
CHECK_NO_DEREF_HANDLE;
|
||||
if (GetAddress() == 0U) {
|
||||
return JSTaggedValue::Undefined().GetRawData();
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "ecmascript/platform/file.h"
|
||||
#include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h"
|
||||
#include "ecmascript/builtin_entries.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using CommonStubCSigns = panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
@ -56,6 +57,30 @@ JSThread *JSThread::GetCurrent()
|
||||
return currentThread;
|
||||
}
|
||||
|
||||
// static
|
||||
void JSThread::RegisterThread(JSThread *jsThread)
|
||||
{
|
||||
Runtime::GetInstance()->RegisterThread(jsThread);
|
||||
// If it is not true, we created a new thread for future fork
|
||||
if (currentThread == nullptr) {
|
||||
currentThread = jsThread;
|
||||
jsThread->UpdateState(ThreadState::NATIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void JSThread::UnregisterThread(JSThread *jsThread)
|
||||
{
|
||||
if (currentThread == jsThread) {
|
||||
jsThread->UpdateState(ThreadState::TERMINATED);
|
||||
currentThread = nullptr;
|
||||
} else {
|
||||
// We have created this JSThread instance but hadn't forked it.
|
||||
ASSERT(jsThread->GetState() == ThreadState::CREATED);
|
||||
jsThread->UpdateState(ThreadState::TERMINATED);
|
||||
}
|
||||
Runtime::GetInstance()->UnregisterThread(jsThread);
|
||||
}
|
||||
|
||||
// static
|
||||
JSThread *JSThread::Create(EcmaVM *vm)
|
||||
{
|
||||
@ -78,12 +103,7 @@ JSThread *JSThread::Create(EcmaVM *vm)
|
||||
jsThread->glueData_.stackLimit_ = GetAsmStackLimit();
|
||||
jsThread->glueData_.stackStart_ = GetCurrentStackPosition();
|
||||
|
||||
Runtime::GetInstance()->RegisterThread(jsThread);
|
||||
// If it is not true, we created a new thread for future fork
|
||||
if (currentThread == nullptr) {
|
||||
currentThread = jsThread;
|
||||
jsThread->UpdateState(ThreadState::NATIVE);
|
||||
}
|
||||
RegisterThread(jsThread);
|
||||
return jsThread;
|
||||
}
|
||||
|
||||
@ -115,6 +135,12 @@ JSThread::JSThread(EcmaVM *vm) : id_(os::thread::GetCurrentThreadId()), vm_(vm)
|
||||
SetBCStubStatus(BCStubStatus::NORMAL_BC_STUB);
|
||||
}
|
||||
|
||||
JSThread::JSThread(EcmaVM *vm, bool isJit) : id_(os::thread::GetCurrentThreadId()), vm_(vm), isJitThread_(isJit)
|
||||
{
|
||||
ASSERT(isJit);
|
||||
RegisterThread(this);
|
||||
};
|
||||
|
||||
JSThread::~JSThread()
|
||||
{
|
||||
readyForGCIterating_ = false;
|
||||
@ -144,15 +170,7 @@ JSThread::~JSThread()
|
||||
delete vmThreadControl_;
|
||||
vmThreadControl_ = nullptr;
|
||||
}
|
||||
if (currentThread == this) {
|
||||
UpdateState(ThreadState::TERMINATED);
|
||||
currentThread = nullptr;
|
||||
} else {
|
||||
// We have created this JSThread instance but hadn't forked it.
|
||||
ASSERT(GetState() == ThreadState::CREATED);
|
||||
UpdateState(ThreadState::TERMINATED);
|
||||
}
|
||||
Runtime::GetInstance()->UnregisterThread(this);
|
||||
UnregisterThread(this);
|
||||
}
|
||||
|
||||
void JSThread::SetException(JSTaggedValue exception)
|
||||
@ -684,7 +702,7 @@ bool JSThread::CheckSafepoint()
|
||||
interruptMutex_.Unlock();
|
||||
}
|
||||
|
||||
if (vm_->IsEnableJit() && HasInstallMachineCode()) {
|
||||
if (HasInstallMachineCode()) {
|
||||
vm_->GetJit()->InstallTasks(GetThreadId());
|
||||
SetInstallMachineCode(false);
|
||||
}
|
||||
|
@ -128,6 +128,8 @@ public:
|
||||
};
|
||||
|
||||
explicit JSThread(EcmaVM *vm);
|
||||
// only used in jit thread
|
||||
explicit JSThread(EcmaVM *vm, bool isJit);
|
||||
|
||||
PUBLIC_API ~JSThread();
|
||||
|
||||
@ -264,6 +266,11 @@ public:
|
||||
return glueData_.globalConst_;
|
||||
}
|
||||
|
||||
void SetGlobalConstants(const GlobalEnvConstants *constants)
|
||||
{
|
||||
glueData_.globalConst_ = const_cast<GlobalEnvConstants*>(constants);
|
||||
}
|
||||
|
||||
const BuiltinEntries GetBuiltinEntries() const
|
||||
{
|
||||
return glueData_.builtinEntries_;
|
||||
@ -1236,6 +1243,28 @@ public:
|
||||
{
|
||||
finalizeTaskCallback_ = callback;
|
||||
}
|
||||
|
||||
static void RegisterThread(JSThread *jsThread);
|
||||
static void UnregisterThread(JSThread *jsThread);
|
||||
bool IsJitThread() const
|
||||
{
|
||||
return isJitThread_;
|
||||
}
|
||||
|
||||
RecursiveMutex *GetJitLock()
|
||||
{
|
||||
return &jitMutex_;
|
||||
}
|
||||
|
||||
void SetMachineCodeLowMemory(bool isLow)
|
||||
{
|
||||
machineCodeLowMemory_ = isLow;
|
||||
}
|
||||
|
||||
bool IsMachineCodeLowMemory()
|
||||
{
|
||||
return machineCodeLowMemory_;
|
||||
}
|
||||
private:
|
||||
NO_COPY_SEMANTIC(JSThread);
|
||||
NO_MOVE_SEMANTIC(JSThread);
|
||||
@ -1336,6 +1365,9 @@ private:
|
||||
int32_t suspendCount_ {0};
|
||||
ConditionVariable suspendCondVar_;
|
||||
|
||||
bool isJitThread_ {false};
|
||||
RecursiveMutex jitMutex_;
|
||||
bool machineCodeLowMemory_ {false};
|
||||
#ifndef NDEBUG
|
||||
MutatorLock::MutatorLockState mutatorLockState_ = MutatorLock::MutatorLockState::UNLOCKED;
|
||||
#endif
|
||||
@ -1343,6 +1375,7 @@ private:
|
||||
friend class GlobalHandleCollection;
|
||||
friend class EcmaVM;
|
||||
friend class EcmaContext;
|
||||
friend class JitVM;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_JS_THREAD_H
|
||||
|
@ -438,7 +438,7 @@ public:
|
||||
static FunctionKind PUBLIC_API GetFunctionKind(panda_file::FunctionKind funcKind);
|
||||
static FunctionKind GetFunctionKind(ConstPoolType type);
|
||||
|
||||
bool IsFirstMergedAbc() const;
|
||||
bool PUBLIC_API IsFirstMergedAbc() const;
|
||||
const void *GetBase() const
|
||||
{
|
||||
return static_cast<const void *>(pf_->GetBase());
|
||||
|
@ -616,6 +616,20 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
template <ConstPoolType type>
|
||||
static JSTaggedValue GetLiteralFromCache(JSTaggedValue constpool, uint32_t index, [[maybe_unused]] CString entry)
|
||||
{
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
auto val = taggedPool->GetObjectFromCache(index);
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
if (isLoadedAOT && val.IsAOTLiteralInfo()) {
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
return val.IsHole() ? JSTaggedValue::Undefined() : val;
|
||||
}
|
||||
|
||||
static panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index)
|
||||
{
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
@ -631,6 +645,24 @@ public:
|
||||
return GetLiteralFromCache<type>(thread, constpool, index, entry);
|
||||
}
|
||||
|
||||
static JSTaggedValue PUBLIC_API GetStringFromCacheForJit(JSThread *thread, JSTaggedValue constpool, uint32_t index)
|
||||
{
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
auto val = taggedPool->Get(index);
|
||||
if (val.IsHole()) {
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
panda_file::File::EntityId id = taggedPool->GetEntityId(index);
|
||||
auto foundStr = jsPandaFile->GetStringData(id);
|
||||
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto string = factory->GetRawStringFromStringTable(foundStr, MemSpaceType::SHARED_OLD_SPACE,
|
||||
jsPandaFile->IsFirstMergedAbc(), id.GetOffset());
|
||||
val = JSTaggedValue(string);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static JSTaggedValue PUBLIC_API GetStringFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index)
|
||||
{
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
|
@ -109,6 +109,11 @@ inline int LayoutInfo::FindElementWithCache(const JSThread *thread, JSHClass *cl
|
||||
return -1;
|
||||
}
|
||||
|
||||
// jit compile thread not use cache
|
||||
if (thread->IsJitThread()) {
|
||||
return BinarySearch(key, propertiesNumber);
|
||||
}
|
||||
|
||||
PropertiesCache *cache = thread->GetPropertiesCache();
|
||||
int index = cache->Get(cls, key);
|
||||
if (index == PropertiesCache::NOT_FOUND) {
|
||||
|
@ -26,6 +26,8 @@ static thread_local size_t currentAssertData(~0);
|
||||
|
||||
using AssertGarbageCollectBit = panda::BitField<bool, 0, 1>;
|
||||
using AssertHeapAllocBit = AssertGarbageCollectBit::NextFlag;
|
||||
using AssertHandleAllocBit = AssertHeapAllocBit::NextFlag;
|
||||
using AssertDeRefHandleBit = AssertHandleAllocBit::NextFlag;
|
||||
|
||||
#ifndef NDEBUG
|
||||
constexpr bool IS_ALLOW_CHECK = true;
|
||||
@ -33,7 +35,13 @@ constexpr bool IS_ALLOW_CHECK = true;
|
||||
constexpr bool IS_ALLOW_CHECK = false;
|
||||
#endif
|
||||
|
||||
enum class AssertType : uint8_t { GARBAGE_COLLECTION_ASSERT = 0, HEAP_ALLOC_ASSERT, LAST_ASSERT_TYPE };
|
||||
enum class AssertType : uint8_t {
|
||||
GARBAGE_COLLECTION_ASSERT = 0,
|
||||
HEAP_ALLOC_ASSERT,
|
||||
HANDLE_ALLOC_ASSERT,
|
||||
DEREF_HANDLE_ASSERT,
|
||||
LAST_ASSERT_TYPE
|
||||
};
|
||||
|
||||
template<AssertType type, bool isAllow, bool IsDebug = IS_ALLOW_CHECK>
|
||||
class AssertScopeT {
|
||||
@ -56,6 +64,12 @@ public:
|
||||
case AssertType::HEAP_ALLOC_ASSERT:
|
||||
currentAssertData = AssertHeapAllocBit::Update(oldData_.value(), isAllow);
|
||||
break;
|
||||
case AssertType::HANDLE_ALLOC_ASSERT:
|
||||
currentAssertData = AssertHandleAllocBit::Update(oldData_.value(), isAllow);
|
||||
break;
|
||||
case AssertType::DEREF_HANDLE_ASSERT:
|
||||
currentAssertData = AssertDeRefHandleBit::Update(oldData_.value(), isAllow);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -78,6 +92,12 @@ public:
|
||||
return AssertGarbageCollectBit::Decode(currentAssertData);
|
||||
case AssertType::HEAP_ALLOC_ASSERT:
|
||||
return AssertHeapAllocBit::Decode(currentAssertData);
|
||||
case AssertType::HANDLE_ALLOC_ASSERT:
|
||||
return AssertHandleAllocBit::Decode(currentAssertData);
|
||||
break;
|
||||
case AssertType::DEREF_HANDLE_ASSERT:
|
||||
return AssertDeRefHandleBit::Decode(currentAssertData);
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@ -94,7 +114,10 @@ using DisallowGarbageCollection = AssertScopeT<AssertType::GARBAGE_COLLECTION_AS
|
||||
using AllowGarbageCollection = AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, true, IS_ALLOW_CHECK>;
|
||||
using DisAllowHeapAlloc = AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
|
||||
using AllowHeapAlloc = AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
|
||||
|
||||
using DisAllowHandleAllocation = AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
|
||||
using AllowHandleAllocation = AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
|
||||
using DisAllowDeRefHandle = AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, false, IS_ALLOW_CHECK>;
|
||||
using AllowDeRefHandle = AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, true, IS_ALLOW_CHECK>;
|
||||
#if (!defined NDEBUG) || (defined RUN_TEST)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define DISALLOW_GARBAGE_COLLECTION [[maybe_unused]] DisallowGarbageCollection noGc
|
||||
@ -104,18 +127,48 @@ using AllowHeapAlloc = AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, true, IS_ALLO
|
||||
#define DISALLOW_HEAP_ALLOC [[maybe_unused]] DisAllowHeapAlloc noHeapAlloc
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ALLOW_HEAP_ALLOC [[maybe_unused]] AllowHeapAlloc allowHeapAlloc
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define DISALLOW_HANDLE_ALLOC [[maybe_unused]] DisAllowHandleAllocation disAllowHandleAlloc
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ALLOW_HANDLE_ALLOC [[maybe_unused]] AllowHandleAllocation allowHandleAlloc
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define DISALLOW_DEREF_HANDLE [[maybe_unused]] DisAllowDeRefHandle disAllowDeRefHandle
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ALLOW_DEREF_HANDLE [[maybe_unused]] AllowDeRefHandle allowDeRefHandle
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define DISALLOW_HEAP_ACCESS \
|
||||
DISALLOW_HEAP_ALLOC; \
|
||||
DISALLOW_HANDLE_ALLOC; \
|
||||
DISALLOW_DEREF_HANDLE;
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ALLOW_HEAP_ACCESS \
|
||||
ALLOW_HEAP_ALLOC; \
|
||||
ALLOW_HANDLE_ALLOC; \
|
||||
ALLOW_DEREF_HANDLE;
|
||||
#else
|
||||
#define DISALLOW_GARBAGE_COLLECTION
|
||||
#define ALLOW_GARBAGE_COLLECTION
|
||||
#define DISALLOW_HEAP_ALLOC
|
||||
#define ALLOW_HEAP_ALLOC
|
||||
#define DISALLOW_HANDLE_ALLOC
|
||||
#define ALLOW_HANDLE_ALLOC
|
||||
#define DISALLOW_HEAP_ACCESS
|
||||
#define ALLOW_HEAP_ACCESS
|
||||
#define DISALLOW_DEREF_HANDLE
|
||||
#define ALLOW_DEREF_HANDLE
|
||||
#endif
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define CHECK_NO_GC ASSERT_PRINT(AllowGarbageCollection::IsAllowed(), "disallow execute garbage collection.");
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define CHECK_NO_HEAP_ALLOC (AllowHeapAlloc::IsAllowed(), "disallow execute heap alloc.");
|
||||
#define CHECK_NO_HEAP_ALLOC ASSERT_PRINT(AllowHeapAlloc::IsAllowed(), "disallow execute heap alloc.");
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define CHECK_NO_HANDLE_ALLOC ASSERT_PRINT(AllowHandleAllocation::IsAllowed(), "disallow execute handle alloc.");
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define CHECK_NO_DEREF_HANDLE ASSERT_PRINT(AllowDeRefHandle::IsAllowed(), "disallow execute deref handle.");
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_MEM_ASSERT_SCOPE_H
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "ecmascript/mem/gc_key_stats.h"
|
||||
#include "ecmascript/runtime_call_id.h"
|
||||
#include "ecmascript/runtime_lock.h"
|
||||
#include "ecmascript/jit/jit.h"
|
||||
#if !WIN_OR_MAC_OR_IOS_PLATFORM
|
||||
#include "ecmascript/dfx/hprof/heap_profiler_interface.h"
|
||||
#include "ecmascript/dfx/hprof/heap_profiler.h"
|
||||
@ -637,6 +638,7 @@ TriggerGCType Heap::SelectGCType() const
|
||||
|
||||
void Heap::CollectGarbage(TriggerGCType gcType, GCReason reason)
|
||||
{
|
||||
Jit::JitGCLockHolder lock(GetEcmaVM()->GetJSThread());
|
||||
{
|
||||
ASSERT(thread_->IsInRunningStateOrProfiling());
|
||||
RecursionScope recurScope(this);
|
||||
@ -800,6 +802,12 @@ void Heap::CollectGarbage(TriggerGCType gcType, GCReason reason)
|
||||
#endif
|
||||
ASSERT(thread_->IsPropertyCacheCleared());
|
||||
ProcessGCListeners();
|
||||
|
||||
if (GetEcmaVM()->IsEnableJit()) {
|
||||
// check machine code space if enough
|
||||
int remainSize = config_.GetDefaultMachineCodeSpaceSize() - GetMachineCodeSpace()->GetHeapObjectSize();
|
||||
Jit::GetInstance()->CheckMechineCodeSpaceMemory(GetEcmaVM()->GetJSThread(), remainSize);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseHeap::ThrowOutOfMemoryError(JSThread *thread, size_t size, std::string functionName,
|
||||
|
@ -146,7 +146,10 @@ std::tuple<uint64_t, uint8_t*, int, kungfu::CalleeRegAndOffsetVec> MachineCode::
|
||||
}
|
||||
tmpFuncEntryDes++;
|
||||
}
|
||||
ASSERT(funcEntryDes != nullptr);
|
||||
|
||||
if (funcEntryDes == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
int delta = funcEntryDes->fpDeltaPrevFrameSp_;
|
||||
kungfu::CalleeRegAndOffsetVec calleeRegInfo;
|
||||
|
@ -64,8 +64,10 @@ uintptr_t SharedSparseSpace::Allocate(JSThread *thread, size_t size, bool allowG
|
||||
{
|
||||
ASSERT(thread->IsInRunningStateOrProfiling());
|
||||
thread->CheckSafepointIfSuspended();
|
||||
auto localHeap = const_cast<Heap*>(thread->GetEcmaVM()->GetHeap());
|
||||
// jit thread no heap
|
||||
allowGC = allowGC && (localHeap != nullptr);
|
||||
if (allowGC) {
|
||||
auto localHeap = const_cast<Heap*>(thread->GetEcmaVM()->GetHeap());
|
||||
localHeap->TryTriggerFullMarkBySharedSize(size);
|
||||
}
|
||||
uintptr_t object = TryAllocate(thread, size);
|
||||
@ -505,7 +507,9 @@ void SharedHugeObjectSpace::CheckAndTriggerLocalFullMark(JSThread *thread, size_
|
||||
reinterpret_cast<SharedHeap*>(heap_)->TryTriggerLocalConcurrentMarking(thread);
|
||||
} else {
|
||||
auto localHeap = const_cast<Heap*>(thread->GetEcmaVM()->GetHeap());
|
||||
localHeap->TryTriggerFullMarkBySharedSize(size);
|
||||
if (localHeap != nullptr) {
|
||||
localHeap->TryTriggerFullMarkBySharedSize(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -224,8 +224,7 @@ public:
|
||||
|
||||
bool IsOOMDumpSpace()
|
||||
{
|
||||
return spaceType_ == OLD_SPACE || spaceType_ == NON_MOVABLE || spaceType_ == HUGE_OBJECT_SPACE ||
|
||||
spaceType_ == MACHINE_CODE_SPACE;
|
||||
return spaceType_ == OLD_SPACE || spaceType_ == NON_MOVABLE || spaceType_ == HUGE_OBJECT_SPACE;
|
||||
}
|
||||
|
||||
// methods for allocation inspector
|
||||
|
@ -3254,6 +3254,7 @@ JSHandle<BigInt> ObjectFactory::NewBigInt(uint32_t length)
|
||||
// static
|
||||
void ObjectFactory::NewObjectHook() const
|
||||
{
|
||||
CHECK_NO_HEAP_ALLOC;
|
||||
#ifndef NDEBUG
|
||||
if (vm_->GetJSOptions().EnableForceGC() && vm_->IsInitialized() && thread_->IsAllContextsInitialized()) {
|
||||
if (vm_->GetJSOptions().ForceFullGC()) {
|
||||
@ -5109,4 +5110,20 @@ void ObjectFactory::FillFreeMemoryRange(uintptr_t start, uintptr_t end)
|
||||
start += sizeof(JSTaggedType);
|
||||
}
|
||||
}
|
||||
|
||||
JSHandle<Method> ObjectFactory::CloneMethod(JSHandle<Method> method)
|
||||
{
|
||||
TaggedObject *header = nullptr;
|
||||
header = heap_->AllocateOldOrHugeObject(
|
||||
JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
|
||||
JSHandle<Method> newmethod(thread_, header);
|
||||
|
||||
newmethod->SetCallField(method->GetCallField());
|
||||
newmethod->SetLiteralInfo(method->GetLiteralInfo());
|
||||
newmethod->SetNativePointerOrBytecodeArray(method->GetNativePointerOrBytecodeArray());
|
||||
newmethod->SetExtraLiteralInfo(method->GetExtraLiteralInfo());
|
||||
newmethod->SetCodeEntryOrLiteral(method->GetCodeEntryOrLiteral());
|
||||
newmethod->SetConstantPool(thread_, method->GetConstantPool());
|
||||
return newmethod;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -863,6 +863,7 @@ public:
|
||||
JSHandle<JSSymbol> NewSWellKnownSymbolWithChar(std::string_view description);
|
||||
JSHandle<JSSymbol> NewSPublicSymbolWithChar(std::string_view description);
|
||||
JSHandle<JSSymbol> NewSPublicSymbol(const JSHandle<JSTaggedValue> &name);
|
||||
JSHandle<Method> CloneMethod(JSHandle<Method> method);
|
||||
|
||||
private:
|
||||
friend class GlobalEnv;
|
||||
|
@ -67,8 +67,6 @@ void Runtime::CreateIfFirstVm(const JSRuntimeOptions &options)
|
||||
MemMapAllocator::GetInstance()->Initialize(ecmascript::DEFAULT_REGION_SIZE);
|
||||
PGOProfilerManager::GetInstance()->Initialize(options.GetPGOProfilerPath(),
|
||||
options.GetPGOHotnessThreshold());
|
||||
bool isEnableJit = options.IsEnableJIT() && options.GetEnableAsmInterpreter();
|
||||
Jit::GetInstance()->SetEnableOrDisable(options, isEnableJit);
|
||||
ASSERT(instance_ == nullptr);
|
||||
instance_ = new Runtime();
|
||||
firstVmCreated_ = true;
|
||||
@ -82,6 +80,8 @@ void Runtime::InitializeIfFirstVm(EcmaVM *vm)
|
||||
if (++vmCount_ == 1) {
|
||||
ThreadManagedScope managedScope(vm->GetAssociatedJSThread());
|
||||
PreInitialization(vm);
|
||||
bool isEnableJit = vm->GetJSOptions().IsEnableJIT() && vm->GetJSOptions().GetEnableAsmInterpreter();
|
||||
Jit::GetInstance()->SetEnableOrDisable(vm->GetJSOptions(), isEnableJit);
|
||||
vm->Initialize();
|
||||
PostInitialization(vm);
|
||||
}
|
||||
|
@ -22,7 +22,11 @@
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
Runner::Runner(uint32_t threadNum) : totalThreadNum_(threadNum)
|
||||
Runner::Runner(uint32_t threadNum, const std::function<void(os::thread::native_handle_type)> prologueHook,
|
||||
const std::function<void(os::thread::native_handle_type)> epilogueHook)
|
||||
: totalThreadNum_(threadNum),
|
||||
prologueHook_(prologueHook),
|
||||
epilogueHook_(epilogueHook)
|
||||
{
|
||||
for (uint32_t i = 0; i < threadNum; i++) {
|
||||
// main thread is 0;
|
||||
@ -65,6 +69,17 @@ void Runner::TerminateThread()
|
||||
threadPool_.clear();
|
||||
}
|
||||
|
||||
void Runner::ForEachTask(const std::function<void(Task*)> &f)
|
||||
{
|
||||
taskQueue_.ForEachTask(f);
|
||||
LockHolder holder(mtx_);
|
||||
for (uint32_t i = 0; i < runningTask_.size(); i++) {
|
||||
if (runningTask_[i] != nullptr) {
|
||||
f(runningTask_[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Runner::SetQosPriority([[maybe_unused]] bool isForeground)
|
||||
{
|
||||
#ifdef ENABLE_QOS
|
||||
@ -96,11 +111,13 @@ void Runner::Run(uint32_t threadId)
|
||||
{
|
||||
os::thread::native_handle_type thread = os::thread::GetNativeHandle();
|
||||
os::thread::SetThreadName(thread, "OS_GC_Thread");
|
||||
PrologueHook(thread);
|
||||
RecordThreadId();
|
||||
while (std::unique_ptr<Task> task = taskQueue_.PopTask()) {
|
||||
SetRunTask(threadId, task.get());
|
||||
task->Run(threadId);
|
||||
SetRunTask(threadId, nullptr);
|
||||
}
|
||||
EpilogueHook(thread);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -20,10 +20,12 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "ecmascript/common.h"
|
||||
#include "ecmascript/taskpool/task_queue.h"
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
#include "libpandabase/os/thread.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
static constexpr uint32_t MIN_TASKPOOL_THREAD_NUM = 3;
|
||||
@ -32,7 +34,8 @@ static constexpr uint32_t DEFAULT_TASKPOOL_THREAD_NUM = 0;
|
||||
|
||||
class Runner {
|
||||
public:
|
||||
explicit Runner(uint32_t threadNum);
|
||||
explicit Runner(uint32_t threadNum, const std::function<void(os::thread::native_handle_type)> prologueHook,
|
||||
const std::function<void(os::thread::native_handle_type)> epilogueHook);
|
||||
~Runner() = default;
|
||||
|
||||
NO_COPY_SEMANTIC(Runner);
|
||||
@ -64,6 +67,20 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrologueHook(os::thread::native_handle_type thread)
|
||||
{
|
||||
if (prologueHook_ != nullptr) {
|
||||
prologueHook_(thread);
|
||||
}
|
||||
}
|
||||
void EpilogueHook(os::thread::native_handle_type thread)
|
||||
{
|
||||
if (epilogueHook_ != nullptr) {
|
||||
epilogueHook_(thread);
|
||||
}
|
||||
}
|
||||
void ForEachTask(const std::function<void(Task*)> &f);
|
||||
|
||||
private:
|
||||
void Run(uint32_t threadId);
|
||||
void SetRunTask(uint32_t threadId, Task *task);
|
||||
@ -75,6 +92,9 @@ private:
|
||||
std::vector<uint32_t> gcThreadId_ {};
|
||||
Mutex mtx_;
|
||||
Mutex mtxPool_;
|
||||
|
||||
std::function<void(os::thread::native_handle_type)> prologueHook_;
|
||||
std::function<void(os::thread::native_handle_type)> epilogueHook_;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_TASKPOOL_RUNNER_H
|
||||
|
@ -61,4 +61,14 @@ void TaskQueue::Terminate()
|
||||
terminate_ = true;
|
||||
cv_.SignalAll();
|
||||
}
|
||||
|
||||
void TaskQueue::ForEachTask(const std::function<void(Task*)> &f)
|
||||
{
|
||||
LockHolder holder(mtx_);
|
||||
for (auto &task : tasks_) {
|
||||
if (task.get() != nullptr) {
|
||||
f(task.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "ecmascript/taskpool/task.h"
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
@ -38,6 +39,7 @@ public:
|
||||
|
||||
void Terminate();
|
||||
void TerminateTask(int32_t id, TaskType type);
|
||||
void ForEachTask(const std::function<void(Task*)> &f);
|
||||
|
||||
private:
|
||||
std::deque<std::unique_ptr<Task>> tasks_;
|
||||
|
@ -28,7 +28,8 @@ void Taskpool::Initialize(int threadNum)
|
||||
{
|
||||
LockHolder lock(mutex_);
|
||||
if (isInitialized_++ <= 0) {
|
||||
runner_ = std::make_unique<Runner>(TheMostSuitableThreadNum(threadNum));
|
||||
runner_ = std::make_unique<Runner>(TheMostSuitableThreadNum(threadNum),
|
||||
prologueRunnerHook_, epilogueRunnerHook_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,4 +63,12 @@ uint32_t Taskpool::TheMostSuitableThreadNum(uint32_t threadNum) const
|
||||
uint32_t numOfThreads = std::min<uint32_t>(NumberOfCpuCore() / 2, MAX_TASKPOOL_THREAD_NUM);
|
||||
return std::max<uint32_t>(numOfThreads, MIN_TASKPOOL_THREAD_NUM);
|
||||
}
|
||||
|
||||
void Taskpool::ForEachTask(const std::function<void(Task*)> &f)
|
||||
{
|
||||
if (isInitialized_ <= 0) {
|
||||
return;
|
||||
}
|
||||
runner_->ForEachTask(f);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class Taskpool {
|
||||
class PUBLIC_API Taskpool {
|
||||
public:
|
||||
PUBLIC_API static Taskpool *GetCurrentTaskpool();
|
||||
|
||||
@ -66,12 +66,23 @@ public:
|
||||
runner_->SetQosPriority(isForeground);
|
||||
}
|
||||
|
||||
void RegisterRunnerHook(const std::function<void(os::thread::native_handle_type)> &prologueHook,
|
||||
const std::function<void(os::thread::native_handle_type)> &epilogueHook)
|
||||
{
|
||||
prologueRunnerHook_ = prologueHook;
|
||||
epilogueRunnerHook_ = epilogueHook;
|
||||
}
|
||||
void ForEachTask(const std::function<void(Task*)> &f);
|
||||
|
||||
private:
|
||||
uint32_t TheMostSuitableThreadNum(uint32_t threadNum) const;
|
||||
virtual uint32_t TheMostSuitableThreadNum(uint32_t threadNum) const;
|
||||
|
||||
std::unique_ptr<Runner> runner_;
|
||||
volatile int isInitialized_ = 0;
|
||||
Mutex mutex_;
|
||||
|
||||
std::function<void(os::thread::native_handle_type)> prologueRunnerHook_ { nullptr };
|
||||
std::function<void(os::thread::native_handle_type)> epilogueRunnerHook_ { nullptr };
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_PALTFORM_PLATFORM_H
|
||||
|
@ -10,6 +10,7 @@
|
||||
vtable?for?panda::ecmascript::kungfu::MethodSnapshotInfo;
|
||||
vtable?for?panda::ecmascript::kungfu::ObjectLiteralSnapshotInfo;
|
||||
vtable?for?panda::ecmascript::kungfu::StringSnapshotInfo;
|
||||
vtable?for?panda::ecmascript::Taskpool;
|
||||
|
||||
panda::ecmascript::COMMON_HELP_HEAD_MSG*;
|
||||
panda::ecmascript::HELP_OPTION_MSG*;
|
||||
@ -119,6 +120,7 @@
|
||||
panda::ecmascript::EcmaContext::FindConstpool*;
|
||||
panda::ecmascript::EcmaContext::FindOrCreateConstPool*;
|
||||
panda::ecmascript::EcmaContext::FindOrCreateUnsharedConstpool*;
|
||||
panda::ecmascript::EcmaContext::FindUnsharedConstpool*;
|
||||
panda::ecmascript::EcmaContext::SetTSManager*;
|
||||
panda::ecmascript::EcmaRuntimeStat::StartCount*;
|
||||
panda::ecmascript::EcmaRuntimeStat::StopCount*;
|
||||
@ -178,9 +180,12 @@
|
||||
panda::ecmascript::JSPandaFile::GetFunctionKind*;
|
||||
panda::ecmascript::JSPandaFile::GetNormalizedFileDesc*;
|
||||
panda::ecmascript::JSPandaFile::GetRecordNameWithBundlePack*;
|
||||
panda::ecmascript::JSPandaFile::IsFirstMergedAbc*;
|
||||
panda::ecmascript::JSProxy::IsArray*;
|
||||
panda::ecmascript::JSTaggedValue::IsJSCOWArray*;
|
||||
panda::ecmascript::JSTaggedValue::IsInSharedHeap*;
|
||||
panda::ecmascript::JitThread::GetHostThread*;
|
||||
panda::ecmascript::Jit::TimeScope::~TimeScope*;
|
||||
panda::ecmascript::Heap::AddGCListener*;
|
||||
panda::ecmascript::Heap::RemoveGCListener*;
|
||||
panda::ecmascript::JSTaggedValue::SetProperty*;
|
||||
@ -236,6 +241,7 @@
|
||||
panda::ecmascript::ObjectFactory::NewSharedOldSpaceJSObjectWithInit*;
|
||||
panda::ecmascript::ObjectFactory::NewSTaggedArray*;
|
||||
panda::ecmascript::ObjectFactory::NewSEcmaHClassDictMode*;
|
||||
panda::ecmascript::ObjectFactory::GetRawStringFromStringTable*;
|
||||
panda::ecmascript::SendableClassDefiner::AddFieldTypeToHClass*;
|
||||
panda::ecmascript::ObjectFactory::NewJSSArray*;
|
||||
panda::ecmascript::ObjectFactory::NewSJsonFixedArray*;
|
||||
|
Loading…
Reference in New Issue
Block a user