[JIT] support concurrent compile

Change-Id: I3d1db40eb479434875a9952c0f5f9279ff67cdaa
Signed-off-by: xiaoweidong <xiaoweidong@huawei.com>
This commit is contained in:
xiaoweidong 2024-04-13 14:35:50 +08:00
parent ecfcf3e49b
commit b27afd924d
84 changed files with 2311 additions and 631 deletions

View File

@ -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",

View File

@ -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

View File

@ -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);

View File

@ -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",

View 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

View 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

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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_ {};

View File

@ -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_);
}

View File

@ -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();

View 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

View 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

View File

@ -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;

View File

@ -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

View 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

View 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

View File

@ -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;
}

View File

@ -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_;

View File

@ -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()});

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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();

View File

@ -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};

View File

@ -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;

View File

@ -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()};

View File

@ -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());

View File

@ -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()) {

View File

@ -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();

View File

@ -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);

View File

@ -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_;

View File

@ -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));

View File

@ -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);

View File

@ -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_;
};

View File

@ -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);

View File

@ -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_;

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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_;

View File

@ -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

View File

@ -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_;

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -36,6 +36,7 @@ public:
SHARED_HEAP
};
EcmaParamConfiguration() = default;
EcmaParamConfiguration(HeapType heapType, size_t poolSize, size_t heapSize = 1_MB)
{
switch (heapType) {

View File

@ -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());

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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

View File

@ -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*);

View File

@ -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

View File

@ -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

View 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

View 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

View 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

View 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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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

View File

@ -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());

View File

@ -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());

View File

@ -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) {

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_;

View File

@ -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

View File

@ -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

View File

@ -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*;