!6907 Remove TSManager and TSTypes

Merge pull request !6907 from huoqingyi/remove_tsmanager
This commit is contained in:
openharmony_ci 2024-04-20 10:46:18 +00:00 committed by Gitee
commit 9363d1718e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
126 changed files with 120 additions and 11242 deletions

View File

@ -103,7 +103,6 @@ group("ark_js_unittest") {
"ecmascript/serializer/tests:unittest",
"ecmascript/snapshot/tests:unittest",
"ecmascript/tests:unittest",
"ecmascript/ts_types/tests:unittest",
]
if (is_ohos && is_standard_system) {
deps += [ "test/fuzztest:fuzztest" ]
@ -140,7 +139,6 @@ group("ark_unittest") {
"ecmascript/serializer/tests:host_unittest",
"ecmascript/snapshot/tests:host_unittest",
"ecmascript/tests:host_unittest",
"ecmascript/ts_types/tests:host_unittest",
]
if (!run_with_asan) {
if (!(ark_standalone_build && current_os == "ohos")) {
@ -152,29 +150,6 @@ group("ark_unittest") {
}
}
_builtins_dts_path_ = rebase_path("./ecmascript/ts_types/lib_ark_builtins.d.ts")
_es2abc_builtins_d_abc_path_ =
"$target_out_dir/lib_ark_builtins/es2abc/lib_ark_builtins.d.abc"
es2abc_gen_abc("es2abc_gen_builtins_d_abc") {
extra_visibility = [ "*" ]
# extra_dependencies = _deps_
src_js = rebase_path(_builtins_dts_path_)
dst_file = rebase_path(_es2abc_builtins_d_abc_path_)
extension = "ts"
extra_args = [
"--module",
"--merge-abc",
"--type-extractor",
"--type-dts-builtin",
]
in_puts = [ _builtins_dts_path_ ]
out_puts = [ _es2abc_builtins_d_abc_path_ ]
}
group("ark_runtime_host_unittest") {
testonly = true
deps = []
@ -703,7 +678,6 @@ ecma_source = [
"ecmascript/jspandafile/class_info_extractor.cpp",
"ecmascript/jspandafile/debug_info_extractor.cpp",
"ecmascript/jspandafile/literal_data_extractor.cpp",
"ecmascript/jspandafile/type_literal_extractor.cpp",
"ecmascript/jspandafile/accessor/module_data_accessor.cpp",
"ecmascript/jspandafile/panda_file_translator.cpp",
"ecmascript/jspandafile/js_pandafile_executor.cpp",
@ -857,7 +831,6 @@ ecma_source = [
"ecmascript/stackmap/litecg/litecg_stackmap_type.cpp",
"ecmascript/stackmap/llvm/llvm_stackmap_parser.cpp",
"ecmascript/stackmap/llvm/llvm_stackmap_type.cpp",
"ecmascript/subtyping_operator.cpp",
"ecmascript/sustaining_js_handle.cpp",
"ecmascript/taskpool/taskpool.cpp",
"ecmascript/taskpool/runner.cpp",
@ -881,13 +854,6 @@ ecma_source = [
"ecmascript/waiter_list.cpp",
"ecmascript/weak_vector.cpp",
"ecmascript/stubs/runtime_stubs.cpp",
"ecmascript/ts_types/ts_type.cpp",
"ecmascript/ts_types/ts_type_accessor.cpp",
"ecmascript/ts_types/ts_type_table.cpp",
"ecmascript/ts_types/ts_manager.cpp",
"ecmascript/ts_types/ts_obj_layout_info.cpp",
"ecmascript/ts_types/ts_type_parser.cpp",
"ecmascript/ts_types/ts_type_table_generator.cpp",
"ecmascript/stubs/test_runtime_stubs.cpp",
"ecmascript/builtins/builtins_cjs_module.cpp",
"ecmascript/builtins/builtins_cjs_require.cpp",
@ -1100,9 +1066,6 @@ ohos_source_set("libark_jsruntime_test_set") {
rebase_path("$root_gen_dir/arkcompiler/ets_runtime/stub.an")
}
defines += [ "STUB_AN_FILE=\"${stub_an_file_path}\"" ]
target_builtins_dts_path =
"/system/lib64/${arkcompiler_relative_lib_path}/lib_ark_builtins.d.abc"
defines += [ "TARGET_BUILTINS_DTS_PATH=\"${target_builtins_dts_path}\"" ]
deps = []
external_deps = [ "zlib:libz" ]

View File

@ -390,7 +390,7 @@ used time is: 0:01:04.439642
1. 通过方舟前端生成hello-world.abc文件编译命令
```
/your_code_path/out/rk3568/clang_x64/arkcompiler/ets_frontend/es2abc --module --type-extractor --merge-abc hello-world.ts
/your_code_path/out/rk3568/clang_x64/arkcompiler/ets_frontend/es2abc --module --merge-abc hello-world.ts
```
2. 设置搜索路径:

View File

@ -156,7 +156,6 @@ libark_jsoptimizer_sources = [
"number_speculative_lowering.cpp",
"number_speculative_retype.cpp",
"number_speculative_runner.cpp",
"object_access_helper.cpp",
"operations_stub_builder.cpp",
"pass_manager.cpp",
"post_schedule.cpp",
@ -179,15 +178,11 @@ libark_jsoptimizer_sources = [
"trampoline/x64/common_call.cpp",
"trampoline/x64/optimized_call.cpp",
"trampoline/x64/optimized_fast_call.cpp",
"ts_class_analysis.cpp",
"ts_hclass_generator.cpp",
"ts_hcr_opt_pass.cpp",
"ts_inline_lowering.cpp",
"type.cpp",
"type_inference/pgo_type_infer.cpp",
"type_inference/pgo_type_infer_helper.cpp",
"type_info_accessors.cpp",
"type_recorder.cpp",
"typed_bytecode_lowering.cpp",
"typed_hcr_lowering.cpp",
"typed_native_inline_lowering.cpp",
@ -516,10 +511,7 @@ ohos_executable("ark_aot_compiler") {
"$js_root:ark_jsruntime_public_config",
]
deps = [
":lib_ark_builtins.d.abc",
":libark_mock_stub_set",
]
deps = [ ":libark_mock_stub_set" ]
if (is_ohos) {
deps += [
@ -645,20 +637,3 @@ action("build_stub_to_cpp") {
outputs = [ "$root_gen_dir/arkcompiler/ets_runtime/stub_an.cpp" ]
}
ohos_copy("lib_ark_builtins.d.abc") {
deps = [ "$js_root:es2abc_gen_builtins_d_abc" ]
sources = [ rebase_path(root_out_dir) + "/obj/arkcompiler/ets_runtime/lib_ark_builtins/es2abc/lib_ark_builtins.d.abc" ]
# Set the output directory
outputs = [ "$target_out_dir/lib_ark_builtins.d.abc" ]
# Set the install directory
install_enable = true
module_type = "lib"
relative_install_dir = arkcompiler_relative_lib_path
# Set the subsystem name
part_name = "ets_runtime"
subsystem_name = "arkcompiler"
}

View File

@ -13,14 +13,13 @@
* limitations under the License.
*/
#include "ecmascript/compiler/aot_compilation_env.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.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();
}

View File

@ -116,7 +116,7 @@ int Main(const int argc, const char **argv)
LocalScope scope(vm);
arg_list_t pandaFileNames {};
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
CompilationOptions cOptions(vm, runtimeOptions);
CompilationOptions cOptions(runtimeOptions);
CompilerLog log(cOptions.logOption_);
log.SetEnableCompilerLogTime(cOptions.compilerLogTime_);
@ -134,7 +134,6 @@ int Main(const int argc, const char **argv)
profilerDecoder.SetHotnessThreshold(cOptions.hotnessThreshold_);
profilerDecoder.SetInPath(cOptions.profilerIn_);
cPreprocessor.AOTInitialize();
cPreprocessor.SetShouldCollectLiteralInfo(cOptions, &log);
uint32_t checksum = cPreprocessor.GenerateAbcFileInfos();
// Notice: lx move load pandaFileHead and verify before GeneralAbcFileInfos.
// need support muilt abc
@ -155,14 +154,12 @@ int Main(const int argc, const char **argv)
.EnableEarlyElimination(cOptions.isEnableEarlyElimination_)
.EnableLaterElimination(cOptions.isEnableLaterElimination_)
.EnableValueNumbering(cOptions.isEnableValueNumbering_)
.EnableTypeInfer(cOptions.isEnableTypeInfer_)
.EnableOptInlining(cOptions.isEnableOptInlining_)
.EnableOptString(cOptions.isEnableOptString_)
.EnableOptPGOType(cOptions.isEnableOptPGOType_)
.EnableOptTrackField(cOptions.isEnableOptTrackField_)
.EnableOptLoopPeeling(cOptions.isEnableOptLoopPeeling_)
.EnableOptLoopInvariantCodeMotion(cOptions.isEnableOptLoopInvariantCodeMotion_)
.EnableCollectLiteralInfo(cOptions.isEnableCollectLiteralInfo_)
.EnableOptConstantFolding(cOptions.isEnableOptConstantFolding_)
.EnableLexenvSpecialization(cOptions.isEnableLexenvSpecialization_)
.EnableInlineNative(cOptions.isEnableNativeInline_)

View File

@ -26,7 +26,7 @@ constexpr int32_t DEFAULT_OPT_LEVEL = 3; // 3: default opt level
} // namespace
using PGOProfilerManager = pgo::PGOProfilerManager;
CompilationOptions::CompilationOptions(EcmaVM *vm, JSRuntimeOptions &runtimeOptions)
CompilationOptions::CompilationOptions(JSRuntimeOptions &runtimeOptions)
{
triple_ = runtimeOptions.GetTargetTriple();
if (runtimeOptions.GetAOTOutputFile().empty()) {
@ -51,14 +51,11 @@ CompilationOptions::CompilationOptions(EcmaVM *vm, JSRuntimeOptions &runtimeOpti
isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
isEnableOptString_ = runtimeOptions.IsEnableOptString();
isEnableTypeInfer_ = isEnableTypeLowering_ ||
vm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->AssertTypes();
isEnableOptPGOType_ = runtimeOptions.IsEnableOptPGOType();
isEnableOptTrackField_ = runtimeOptions.IsEnableOptTrackField();
isEnableOptLoopPeeling_ = runtimeOptions.IsEnableOptLoopPeeling();
isEnableOptLoopInvariantCodeMotion_ = runtimeOptions.IsEnableOptLoopInvariantCodeMotion();
isEnableOptConstantFolding_ = runtimeOptions.IsEnableOptConstantFolding();
isEnableCollectLiteralInfo_ = false;
isEnableLexenvSpecialization_ = runtimeOptions.IsEnableLexenvSpecialization();
isEnableNativeInline_ = runtimeOptions.IsEnableNativeInline();
isEnableLoweringBuiltin_ = runtimeOptions.IsEnableLoweringBuiltin();
@ -166,14 +163,6 @@ void AotCompilerPreprocessor::AOTInitialize()
CommonStubCSigns::Initialize();
BuiltinsStubCSigns::Initialize();
RuntimeStubCSigns::Initialize();
vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->Initialize();
}
void AotCompilerPreprocessor::SetShouldCollectLiteralInfo(CompilationOptions &cOptions, const CompilerLog *log)
{
TSManager *tsManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
cOptions.isEnableCollectLiteralInfo_ = cOptions.isEnableTypeInfer_ &&
(profilerDecoder_.IsLoaded() || tsManager->AssertTypes() || log->OutputType());
}
uint32_t AotCompilerPreprocessor::GenerateAbcFileInfos()
@ -250,8 +239,8 @@ void AotCompilerPreprocessor::RecordArrayElement(const CompilationOptions &cOpti
JSPandaFile *jsPandaFile = fileInfo.jsPandaFile_.get();
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
ptManager->SetCurCompilationFile(jsPandaFile);
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
cOptions.isEnableCollectLiteralInfo_);
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_,
cOptions.maxAotMethodSize_);
BCInfo &bytecodeInfo = collector.GetBytecodeInfo();
const PGOBCInfo *bcInfo = collector.GetPGOBCInfo();
auto &methodList = bytecodeInfo.GetMethodList();
@ -284,8 +273,8 @@ void AotCompilerPreprocessor::GeneratePGOTypes(const CompilationOptions &cOption
PGOTypeManager *ptManager = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager();
for (const AbcFileInfo &fileInfo : fileInfos_) {
JSPandaFile *jsPandaFile = fileInfo.jsPandaFile_.get();
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
cOptions.isEnableCollectLiteralInfo_);
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_,
cOptions.maxAotMethodSize_);
PGOTypeParser parser(profilerDecoder_, ptManager);
parser.CreatePGOType(collector);
}
@ -366,8 +355,8 @@ void AotCompilerPreprocessor::GenerateMethodMap(CompilationOptions &cOptions)
jsPandaFileManager->EnumerateNonVirtualJSPandaFiles(
[this, &cOptions] (std::shared_ptr<JSPandaFile> jsPandaFilePtr) {
JSPandaFile *jsPandaFile = jsPandaFilePtr.get();
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_,
cOptions.isEnableCollectLiteralInfo_);
BytecodeInfoCollector collector(&aotCompilationEnv_, jsPandaFile, profilerDecoder_,
cOptions.maxAotMethodSize_);
BCInfo &bytecodeInfo = collector.GetBytecodeInfo();
const auto &methodPcInfos = bytecodeInfo.GetMethodPcInfos();
auto &methodList = bytecodeInfo.GetMethodList();

View File

@ -49,7 +49,7 @@ private:
};
struct CompilationOptions {
explicit CompilationOptions(EcmaVM *vm, JSRuntimeOptions &runtimeOptions);
explicit CompilationOptions(JSRuntimeOptions &runtimeOptions);
void ParseOption(const std::string &option, std::map<std::string, std::vector<std::string>> &optionMap) const;
std::vector<std::string> SplitString(const std::string &str, const char ch) const;
std::string triple_;
@ -73,12 +73,10 @@ struct CompilationOptions {
bool isEnableValueNumbering_;
bool isEnableOptInlining_;
bool isEnableOptString_;
bool isEnableTypeInfer_;
bool isEnableOptPGOType_;
bool isEnableOptTrackField_;
bool isEnableOptLoopPeeling_;
bool isEnableOptLoopInvariantCodeMotion_;
bool isEnableCollectLiteralInfo_;
bool isEnableOptConstantFolding_;
bool isEnableLexenvSpecialization_;
bool isEnableNativeInline_;
@ -111,8 +109,6 @@ public:
void AOTInitialize();
void SetShouldCollectLiteralInfo(CompilationOptions &cOptions, const CompilerLog *log);
uint32_t GenerateAbcFileInfos();
bool HandleMergedPgoFile(uint32_t checksum);

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "ecmascript/compiler/aot_file/an_file_data_manager.h"
#include "ecmascript/compiler/aot_snapshot/snapshot_global_data.h"
#include "ecmascript/js_file_path.h"
#include "ecmascript/platform/file.h"

View File

@ -49,6 +49,7 @@
namespace panda::ecmascript {
using CommonStubCSigns = kungfu::CommonStubCSigns;
using BytecodeStubCSigns = kungfu::BytecodeStubCSigns;
using SnapshotGlobalData = kungfu::SnapshotGlobalData;
void AOTFileManager::Iterate(const RootVisitor &v)
{

View File

@ -16,12 +16,11 @@
#include "ecmascript/compiler/aot_snapshot/aot_snapshot.h"
#include "ecmascript/common.h"
#include "ecmascript/compiler/aot_snapshot/aot_snapshot_constants.h"
#include "ecmascript/global_env_constants-inl.h"
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/log_wrapper.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "ecmascript/global_env_constants-inl.h"
#include "ecmascript/compiler/aot_snapshot/aot_snapshot_constants.h"
namespace panda::ecmascript::kungfu {
void AOTSnapshot::InitSnapshot(uint32_t compileFilesCount)

View File

@ -57,21 +57,6 @@ bool ArgumentAccessor::ArgGateNotExisted(const size_t currentVreg)
return false;
}
GateRef ArgumentAccessor::GetTypedArgGate(const size_t argIndex) const
{
if (argIndex == static_cast<size_t>(TypedArgIdx::FUNC)) {
return GetCommonArgGate(CommonArgIdx::FUNC);
}
if (argIndex == static_cast<size_t>(TypedArgIdx::NEW_TARGET)) {
return GetCommonArgGate(CommonArgIdx::NEW_TARGET);
}
if (argIndex == static_cast<size_t>(TypedArgIdx::THIS_OBJECT)) {
return GetCommonArgGate(CommonArgIdx::THIS_OBJECT);
}
return args_.at(argIndex - static_cast<size_t>(TypedArgIdx::NUM_OF_TYPED_ARGS) +
static_cast<size_t>(CommonArgIdx::NUM_OF_ARGS));
}
GateRef ArgumentAccessor::GetCommonArgGate(const CommonArgIdx arg) const
{
return args_.at(static_cast<size_t>(arg));
@ -117,21 +102,6 @@ size_t ArgumentAccessor::GetFunctionArgIndex(const size_t currentVreg, const boo
return currentVreg - numCommonArgs + static_cast<size_t>(CommonArgIdx::NUM_OF_ARGS);
}
void ArgumentAccessor::FillArgsGateType(const TypeRecorder *typeRecorder)
{
ASSERT(method_ != nullptr);
GateAccessor gateAcc(circuit_);
const size_t numOfTypedArgs = method_->GetNumArgsWithCallField() +
static_cast<size_t>(TypedArgIdx::NUM_OF_TYPED_ARGS);
for (uint32_t argIndex = 0; argIndex < numOfTypedArgs; argIndex++) {
auto argType = typeRecorder->GetArgType(argIndex);
if (!argType.IsAnyType()) {
auto gate = GetTypedArgGate(argIndex);
gateAcc.SetGateType(gate, argType);
}
}
}
void ArgumentAccessor::CollectArgs()
{
if (args_.size() == 0) {

View File

@ -19,7 +19,6 @@
#include "ecmascript/compiler/circuit.h"
#include "ecmascript/compiler/gate.h"
#include "ecmascript/compiler/gate_accessor.h"
#include "ecmascript/compiler/type_recorder.h"
#include "ecmascript/method.h"
namespace panda::ecmascript::kungfu {
@ -77,7 +76,6 @@ public:
{
return args_.size();
}
void FillArgsGateType(const TypeRecorder *typeRecorder);
void CollectArgs();
static size_t GetFixArgsNum()
{
@ -105,7 +103,6 @@ private:
GateRef GetCommonArgGate(const CommonArgIdx arg) const;
size_t GetFunctionArgIndex(const size_t currentVreg, const bool haveFunc,
const bool haveNewTarget, const bool haveThis) const;
GateRef GetTypedArgGate(const size_t argIndex) const;
Circuit *circuit_ {nullptr};
const MethodLiteral *method_ {nullptr};

View File

@ -18,7 +18,6 @@
#include "ecmascript/base/number_helper.h"
#include "ecmascript/compiler/gate_accessor.h"
#include "ecmascript/deoptimizer/deoptimizer.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "libpandafile/bytecode_instruction-inl.h"
namespace panda::ecmascript::kungfu {

View File

@ -15,12 +15,9 @@
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/compiler/type_recorder.h"
#include "ecmascript/interpreter/interpreter-inl.h"
#include "ecmascript/jspandafile/type_literal_extractor.h"
#include "ecmascript/module/module_path_helper.h"
#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
#include "ecmascript/ts_types/ts_type_parser.h"
#include "libpandafile/code_data_accessor.h"
namespace panda::ecmascript::kungfu {
@ -32,51 +29,25 @@ static T *InitializeMemory(T *mem, Args... args)
BytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
PGOProfilerDecoder &pfDecoder,
size_t maxAotMethodSize, bool enableCollectLiteralInfo)
size_t maxAotMethodSize)
: compilationEnv_(env),
jsPandaFile_(jsPandaFile),
bytecodeInfo_(maxAotMethodSize),
pfDecoder_(pfDecoder),
snapshotCPData_(new SnapshotConstantPoolData(env->GetEcmaVM(), jsPandaFile, &pfDecoder)),
enableCollectLiteralInfo_(enableCollectLiteralInfo)
snapshotCPData_(new SnapshotConstantPoolData(env->GetEcmaVM(), jsPandaFile, &pfDecoder))
{
compilationEnv_->GetTSManager()->SetBytecodeInfoCollector(this);
ProcessClasses();
ProcessEnvs();
}
BytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
PGOProfilerDecoder &pfDecoder, bool enableCollectLiteralInfo)
PGOProfilerDecoder &pfDecoder)
: compilationEnv_(env),
jsPandaFile_(jsPandaFile),
bytecodeInfo_(1),
pfDecoder_(pfDecoder),
snapshotCPData_(nullptr), // jit no need
enableCollectLiteralInfo_(enableCollectLiteralInfo)
snapshotCPData_(nullptr) // jit no need
{
ProcessMethod();
ProcessEnvs();
}
BytecodeInfoCollector::~BytecodeInfoCollector()
{
if (envManager_ != nullptr) {
delete envManager_;
envManager_ = nullptr;
}
if (compilationEnv_->IsAotCompiler()) {
auto tsManager = compilationEnv_->GetTSManager();
tsManager->PrintTypeInfo(jsPandaFile_);
tsManager->SetBytecodeInfoCollector(nullptr);
}
}
void BytecodeInfoCollector::ProcessEnvs()
{
if (envManager_ == nullptr) {
envManager_ = new LexEnvManager(bytecodeInfo_);
}
}
void BytecodeInfoCollector::ProcessClasses()
@ -105,7 +76,6 @@ void BytecodeInfoCollector::ProcessClasses()
&methodIndexes, &classConstructIndexes] (panda_file::MethodDataAccessor &mda) {
auto methodId = mda.GetMethodId();
methodIndexes.emplace_back(methodId);
CollectFunctionTypeId(methodId);
// Generate all constpool
compilationEnv_->FindOrCreateConstPool(jsPandaFile_, methodId);
@ -134,14 +104,9 @@ void BytecodeInfoCollector::ProcessClasses()
const uint8_t *insns = codeDataAccessor.GetInstructions();
auto it = processedMethod.find(methodOffset);
if (it == processedMethod.end()) {
std::vector<std::string> classNameVec;
CollectMethodPcsFromBC(codeSize, insns, methodLiteral, classNameVec,
CollectMethodPcsFromBC(codeSize, insns, methodLiteral,
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]);
@ -179,7 +144,6 @@ void BytecodeInfoCollector::ProcessMethod()
const CString recordName = jsPandaFile_->GetRecordNameWithBundlePack(methodIdx);
recordNames.emplace_back(recordName);
auto methodId = mda.GetMethodId();
CollectFunctionTypeId(methodId);
ASSERT(jsPandaFile_->IsNewVersion());
@ -192,12 +156,10 @@ void BytecodeInfoCollector::ProcessMethod()
std::map<uint32_t, std::pair<size_t, uint32_t>> processedMethod;
std::vector<panda_file::File::EntityId> classConstructIndexes;
std::vector<std::string> classNameVec;
CollectMethodPcsFromBC(codeSize, insns, methodLiteral, classNameVec,
CollectMethodPcsFromBC(codeSize, insns, methodLiteral,
recordName, methodOffset, classConstructIndexes);
processedMethod[methodOffset] = std::make_pair(methodPcInfos.size() - 1, methodOffset);
SetMethodPcInfoIndex(methodOffset, processedMethod[methodOffset]);
// class Construct need to use new target, can not fastcall
if (methodLiteral->GetFunctionKind() == FunctionKind::CLASS_CONSTRUCTOR) {
@ -206,90 +168,9 @@ void BytecodeInfoCollector::ProcessMethod()
}
}
void BytecodeInfoCollector::CollectClassLiteralInfo(const MethodLiteral *method,
const std::vector<std::string> &classNameVec)
{
std::vector<uint32_t> classOffsetVec;
IterateLiteral(method, classOffsetVec);
if (classOffsetVec.size() == classNameVec.size()) {
for (uint32_t i = 0; i < classOffsetVec.size(); i++) {
compilationEnv_->GetTSManager()->AddElementToClassNameMap(
jsPandaFile_, classOffsetVec[i], classNameVec[i]);
}
}
}
void BytecodeInfoCollector::CollectFunctionTypeId(panda_file::File::EntityId fieldId)
{
uint32_t offset = fieldId.GetOffset();
TypeAnnotationExtractor annoExtractor(jsPandaFile_, offset);
uint32_t typeId = annoExtractor.GetMethodTypeOffset();
if (typeId != 0) {
bytecodeInfo_.SetFunctionTypeIDAndMethodOffset(typeId, offset);
}
if (annoExtractor.IsNamespace()) {
MarkMethodNamespace(offset);
}
}
void BytecodeInfoCollector::CollectInnerFuncType(const MethodLiteral *method, uint32_t innerMethodId, int32_t bcIndex)
{
auto &methodList = bytecodeInfo_.GetMethodList();
auto methodId = method->GetMethodId().GetOffset();
auto methodIter = methodList.find(methodId);
if (methodIter == methodList.end()) {
return;
}
TypeAnnotationExtractor annoExtractor(jsPandaFile_, innerMethodId);
uint32_t innerFuncType = annoExtractor.GetMethodTypeOffset();
if (innerFuncType != 0) {
methodIter->second.AddBcToTypeId(bcIndex, innerFuncType);
}
}
void BytecodeInfoCollector::IterateLiteral(const MethodLiteral *method,
std::vector<uint32_t> &classOffsetVector)
{
panda_file::File::EntityId fieldId = method->GetMethodId();
uint32_t defineMethodOffset = fieldId.GetOffset();
TypeAnnotationExtractor annoExtractor(jsPandaFile_, defineMethodOffset);
std::map<int32_t, uint32_t> offsetTypeMap;
annoExtractor.EnumerateInstsAndTypes(
[this, &offsetTypeMap, defineMethodOffset](const int32_t bcOffset, const uint32_t typeOffset) {
if (classDefBCIndexes_.find(bcOffset) != classDefBCIndexes_.end() ||
classDefBCIndexes_.find(bcOffset - 1) != classDefBCIndexes_.end()) { // for getter setter
bytecodeInfo_.SetClassTypeOffsetAndDefMethod(typeOffset, defineMethodOffset);
}
if (bcOffset != TypeRecorder::METHOD_ANNOTATION_THIS_TYPE_OFFSET &&
TSTypeParser::IsUserDefinedType(typeOffset)) {
offsetTypeMap.insert(std::make_pair(bcOffset, typeOffset));
}
});
for (auto item : offsetTypeMap) {
uint32_t typeOffset = item.second;
StoreClassTypeOffset(typeOffset, classOffsetVector);
}
classDefBCIndexes_.clear();
}
void BytecodeInfoCollector::StoreClassTypeOffset(const uint32_t typeOffset, std::vector<uint32_t> &classOffsetVector)
{
TypeLiteralExtractor typeLiteralExtractor(jsPandaFile_, typeOffset);
if (typeLiteralExtractor.GetTypeKind() != TSTypeKind::CLASS) {
return;
}
if (classOffsetVector.empty() || typeOffset != classOffsetVector.back()) {
classOffsetVector.emplace_back(typeOffset);
}
}
void BytecodeInfoCollector::CollectMethodPcsFromBC(const uint32_t insSz, const uint8_t *insArr,
MethodLiteral *method, std::vector<std::string> &classNameVec, const CString &recordName,
uint32_t methodOffset, std::vector<panda_file::File::EntityId> &classConstructIndexes)
MethodLiteral *method, const CString &recordName, uint32_t methodOffset,
std::vector<panda_file::File::EntityId> &classConstructIndexes)
{
auto bcIns = BytecodeInst(insArr);
auto bcInsLast = bcIns.JumpTo(insSz);
@ -304,7 +185,7 @@ void BytecodeInfoCollector::CollectMethodPcsFromBC(const uint32_t insSz, const u
while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
bool fastCallFlag = true;
CollectMethodInfoFromBC(bcIns, method, classNameVec, bcIndex, classConstructIndexes, &fastCallFlag);
CollectMethodInfoFromBC(bcIns, method, bcIndex, classConstructIndexes, &fastCallFlag);
if (!fastCallFlag) {
canFastCall = false;
}
@ -338,8 +219,6 @@ void BytecodeInfoCollector::SetMethodPcInfoIndex(uint32_t methodOffset,
{
auto processedMethodPcInfoIndex = processedMethodInfo.first;
auto processedMethodOffset = processedMethodInfo.second;
uint32_t numOfLexVars = 0;
LexicalEnvStatus status = LexicalEnvStatus::VIRTUAL_LEXENV;
auto &methodList = bytecodeInfo_.GetMethodList();
std::set<uint32_t> indexSet{};
// Methods with the same instructions in abc files have the same static information. Since
@ -348,8 +227,6 @@ void BytecodeInfoCollector::SetMethodPcInfoIndex(uint32_t methodOffset,
auto processedIter = methodList.find(processedMethodOffset);
if (processedIter != methodList.end()) {
const MethodInfo &processedMethod = processedIter->second;
numOfLexVars = processedMethod.GetNumOfLexVars();
status = processedMethod.GetLexEnvStatus();
indexSet = processedMethod.GetImportIndexes();
}
@ -357,14 +234,12 @@ void BytecodeInfoCollector::SetMethodPcInfoIndex(uint32_t methodOffset,
if (iter != methodList.end()) {
MethodInfo &methodInfo = iter->second;
methodInfo.SetMethodPcInfoIndex(processedMethodPcInfoIndex);
methodInfo.SetNumOfLexVars(numOfLexVars);
methodInfo.SetLexEnvStatus(status);
// if these methods have the same bytecode, their import indexs must be the same.
methodInfo.CopyImportIndex(indexSet);
return;
}
MethodInfo info(GetMethodInfoID(), processedMethodPcInfoIndex, LexEnv::DEFAULT_ROOT,
MethodInfo::DEFAULT_OUTMETHOD_OFFSET, numOfLexVars, status);
MethodInfo info(GetMethodInfoID(), processedMethodPcInfoIndex,
MethodInfo::DEFAULT_OUTMETHOD_OFFSET);
info.CopyImportIndex(indexSet);
methodList.emplace(methodOffset, info);
}
@ -388,7 +263,7 @@ void BytecodeInfoCollector::CollectInnerMethods(uint32_t methodId, uint32_t inne
methodInfo.AddInnerMethod(innerMethodOffset, isConstructor);
} else {
methodInfoId = GetMethodInfoID();
MethodInfo info(methodInfoId, 0, LexEnv::DEFAULT_ROOT);
MethodInfo info(methodInfoId, 0);
methodList.emplace(methodId, info);
methodList.at(methodId).AddInnerMethod(innerMethodOffset, isConstructor);
}
@ -403,20 +278,6 @@ void BytecodeInfoCollector::CollectInnerMethods(uint32_t methodId, uint32_t inne
methodList.emplace(innerMethodOffset, innerInfo);
}
void BytecodeInfoCollector::MarkMethodNamespace(const uint32_t methodOffset)
{
auto &methodList = bytecodeInfo_.GetMethodList();
auto iter = methodList.find(methodOffset);
if (iter != methodList.end()) {
MethodInfo &methodInfo = iter->second;
methodInfo.MarkMethodNamespace();
return;
}
MethodInfo info(GetMethodInfoID(), 0, LexEnv::DEFAULT_ROOT, MethodInfo::DEFAULT_OUTMETHOD_OFFSET,
0, LexicalEnvStatus::VIRTUAL_LEXENV, true);
methodList.emplace(methodOffset, info);
}
void BytecodeInfoCollector::CollectInnerMethodsFromLiteral(const MethodLiteral *method, uint64_t index)
{
std::vector<uint32_t> methodOffsets;
@ -426,22 +287,6 @@ void BytecodeInfoCollector::CollectInnerMethodsFromLiteral(const MethodLiteral *
}
}
void BytecodeInfoCollector::NewLexEnvWithSize(const MethodLiteral *method, uint64_t numOfLexVars)
{
auto &methodList = bytecodeInfo_.GetMethodList();
auto methodOffset = method->GetMethodId().GetOffset();
auto iter = methodList.find(methodOffset);
if (iter != methodList.end()) {
MethodInfo &methodInfo = iter->second;
methodInfo.SetNumOfLexVars(numOfLexVars);
methodInfo.SetLexEnvStatus(LexicalEnvStatus::REALITY_LEXENV);
return;
}
MethodInfo info(GetMethodInfoID(), 0, LexEnv::DEFAULT_ROOT, MethodInfo::DEFAULT_OUTMETHOD_OFFSET,
numOfLexVars, LexicalEnvStatus::REALITY_LEXENV);
methodList.emplace(methodOffset, info);
}
void BytecodeInfoCollector::CollectInnerMethodsFromNewLiteral(const MethodLiteral *method,
panda_file::File::EntityId literalId)
{
@ -452,9 +297,8 @@ void BytecodeInfoCollector::CollectInnerMethodsFromNewLiteral(const MethodLitera
}
}
void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &bcIns,
const MethodLiteral *method, std::vector<std::string> &classNameVec, int32_t bcIndex,
std::vector<panda_file::File::EntityId> &classConstructIndexes, bool *canFastCall)
void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method,
int32_t bcIndex, std::vector<panda_file::File::EntityId> &classConstructIndexes, bool *canFastCall)
{
if (!(bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) &&
BytecodeInstruction::HasId(BytecodeInstruction::GetFormat(bcIns.GetOpcode()), 0))) {
@ -466,7 +310,6 @@ void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &b
methodId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
static_cast<uint16_t>(bcIns.GetId().AsRawValue())).GetOffset();
CollectInnerMethods(method, methodId);
CollectInnerFuncType(method, methodId, bcIndex);
break;
}
case BytecodeInstruction::Opcode::DEFINEMETHOD_IMM8_ID16_IMM8:
@ -480,7 +323,6 @@ void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &b
auto entityId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
(bcIns.GetId <BytecodeInstruction::Format::IMM8_ID16_ID16_IMM16_V8, 0>()).AsRawValue());
classConstructIndexes.emplace_back(entityId);
classNameVec.emplace_back(GetClassName(entityId));
classDefBCIndexes_.insert(bcIndex);
methodId = entityId.GetOffset();
CollectInnerMethods(method, methodId, true);
@ -493,7 +335,6 @@ void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &b
auto entityId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
(bcIns.GetId <BytecodeInstruction::Format::IMM16_ID16_ID16_IMM16_V8, 0>()).AsRawValue());
classConstructIndexes.emplace_back(entityId);
classNameVec.emplace_back(GetClassName(entityId));
classDefBCIndexes_.insert(bcIndex);
methodId = entityId.GetOffset();
CollectInnerMethods(method, methodId, true);
@ -526,26 +367,6 @@ void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &b
CollectInnerMethodsFromLiteral(method, imm);
break;
}
case BytecodeInstruction::Opcode::NEWLEXENV_IMM8: {
auto imm = bcIns.GetImm<BytecodeInstruction::Format::IMM8>();
NewLexEnvWithSize(method, imm);
break;
}
case BytecodeInstruction::Opcode::NEWLEXENVWITHNAME_IMM8_ID16: {
auto imm = bcIns.GetImm<BytecodeInstruction::Format::IMM8_ID16>();
NewLexEnvWithSize(method, imm);
break;
}
case BytecodeInstruction::Opcode::WIDE_NEWLEXENV_PREF_IMM16: {
auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_IMM16>();
NewLexEnvWithSize(method, imm);
break;
}
case BytecodeInstruction::Opcode::WIDE_NEWLEXENVWITHNAME_PREF_IMM16_ID16: {
auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_IMM16_ID16>();
NewLexEnvWithSize(method, imm);
break;
}
case EcmaOpcode::RESUMEGENERATOR:
case EcmaOpcode::SUSPENDGENERATOR_V8:
case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
@ -616,7 +437,7 @@ void BytecodeInfoCollector::CollectImportIndexs(uint32_t methodOffset, uint32_t
methodInfo.AddImportIndex(index);
return;
}
MethodInfo info(GetMethodInfoID(), 0, LexEnv::DEFAULT_ROOT);
MethodInfo info(GetMethodInfoID(), 0);
info.AddImportIndex(index);
methodList.emplace(methodOffset, info);
}
@ -653,41 +474,8 @@ void BytecodeInfoCollector::CollectExportIndexs(const CString &recordName, uint3
exportName = localName;
}
JSHandle<EcmaString> exportNameStr(thread, EcmaString::Cast(exportName->GetTaggedObject()));
// In order to reduce redundant compilation, when a export element satisfies one of the following conditions,
// it will be added to the ExportRecordInfo of this record.
// 1) its name is not recorded in exportTypeTable, or
// 2) its type is classType or any.
if (!CheckExportNameAndClassType(recordName, exportNameStr)) {
bytecodeInfo_.AddExportIndexToRecord(recordName, index);
}
}
bool BytecodeInfoCollector::CheckExportNameAndClassType(const CString &recordName,
const JSHandle<EcmaString> &exportStr)
{
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
EcmaString *valueString = EcmaString::Cast(exportTypeTable->Get(i).GetTaggedObject());
if (!EcmaStringAccessor::StringsAreEqual(*exportStr, valueString)) {
continue;
}
uint32_t typeId = static_cast<uint32_t>(exportTypeTable->Get(i + 1).GetInt());
if (TSTypeParser::IsUserDefinedType(typeId)) {
TypeLiteralExtractor typeExtractor(jsPandaFile_, typeId);
if (typeExtractor.GetTypeKind() == TSTypeKind::CLASS) {
return false;
}
}
if (typeId != 0) {
return true;
}
}
return false;
}
void BytecodeInfoCollector::CollectRecordReferenceREL()
{
@ -778,45 +566,4 @@ void BytecodeInfoCollector::RearrangeInnerMethods()
methodInfo.RearrangeInnerMethods();
}
}
LexEnvManager::LexEnvManager(BCInfo &bcInfo)
: lexEnvs_(bcInfo.GetMethodList().size())
{
const auto &methodList = bcInfo.GetMethodList();
for (const auto &it : methodList) {
const MethodInfo &methodInfo = it.second;
lexEnvs_[methodInfo.GetMethodInfoIndex()].Inilialize(methodInfo.GetOutMethodId(),
methodInfo.GetNumOfLexVars(),
methodInfo.GetLexEnvStatus());
}
}
void LexEnvManager::SetLexEnvElementType(uint32_t methodId, uint32_t level, uint32_t slot, const GateType &type)
{
uint32_t offset = GetTargetLexEnv(methodId, level);
lexEnvs_[offset].SetLexVarType(slot, type);
}
GateType LexEnvManager::GetLexEnvElementType(uint32_t methodId, uint32_t level, uint32_t slot) const
{
uint32_t offset = GetTargetLexEnv(methodId, level);
return lexEnvs_[offset].GetLexVarType(slot);
}
uint32_t LexEnvManager::GetTargetLexEnv(uint32_t methodId, uint32_t level) const
{
auto offset = methodId;
auto status = GetLexEnvStatus(offset);
while (!HasDefaultRoot(offset) && ((level > 0) || (status != LexicalEnvStatus::REALITY_LEXENV))) {
offset = GetOutMethodId(offset);
if (HasDefaultRoot(offset)) {
break;
}
if (status == LexicalEnvStatus::REALITY_LEXENV && level != 0) {
--level;
}
status = GetLexEnvStatus(offset);
}
return offset;
}
} // namespace panda::ecmascript::kungfu

View File

@ -25,90 +25,8 @@
#include "libpandafile/bytecode_instruction-inl.h"
namespace panda::ecmascript::kungfu {
/* ts source code
* let a:number = 1;
* function f() {
* let b:number = 1;
* function g() {
* return a + b;
* }
* return g();
* }
*
* The structure of Lexical Environment
*
* Lexical Environment Lexical Environment
* Global Environment of function f of function g
* +-------------------+ <----+ +-------------------+ <----+ +-------------------+
* null <----| Outer Reference | +----| Outer Reference | +----| Outer Reference |
* +-------------------+ +-------------------+ +-------------------+
* |Environment Recoder| |Environment Recoder| |Environment Recoder|
* +-------------------+ +-------------------+ +-------------------+
*
* We only record the type of the variable in Environment Recoder.
* In the design of the Ark bytecode, if a method does not have any
* lex-env variable in its Lexical Environment, then there will be
* no EcmaOpcode::NEWLEXENV in it which leads to ARK runtime will
* not create a Lexical Environment when the method is executed.
* In order to simulate the state of the runtime as much as possible,
* a field named 'status' will be added into the class LexEnv to
* measure this state. Take the above code as an example, although in
* static analysis, we will create LexEnv for each method, only Lexenvs
* of global and function f will be created when methods are executed.
*/
using PGOProfilerDecoder = pgo::PGOProfilerDecoder;
enum class LexicalEnvStatus : uint8_t {
VIRTUAL_LEXENV,
REALITY_LEXENV
};
class LexEnv {
public:
LexEnv() = default;
~LexEnv() = default;
static constexpr uint32_t DEFAULT_ROOT = std::numeric_limits<uint32_t>::max();
inline void Inilialize(uint32_t outMethodId, uint32_t numOfLexVars, LexicalEnvStatus status)
{
outerMethodId_ = outMethodId;
lexVarTypes_.resize(numOfLexVars, GateType::AnyType());
status_ = status;
}
inline uint32_t GetOutMethodId() const
{
return outerMethodId_;
}
inline LexicalEnvStatus GetLexEnvStatus() const
{
return status_;
}
inline GateType GetLexVarType(uint32_t slot) const
{
if (slot < lexVarTypes_.size()) {
return lexVarTypes_[slot];
}
return GateType::AnyType();
}
inline void SetLexVarType(uint32_t slot, const GateType &type)
{
if (slot < lexVarTypes_.size()) {
lexVarTypes_[slot] = type;
}
}
private:
uint32_t outerMethodId_ { DEFAULT_ROOT };
std::vector<GateType> lexVarTypes_ {};
LexicalEnvStatus status_ { LexicalEnvStatus::VIRTUAL_LEXENV };
};
// each method in the abc file corresponds to one MethodInfo and
// methods with the same instructions share one common MethodPcInfo
struct MethodPcInfo {
@ -193,17 +111,17 @@ private:
class MethodInfo {
public:
MethodInfo(uint32_t methodInfoIndex, uint32_t methodPcInfoIndex, uint32_t outMethodIdx,
uint32_t outMethodOffset = MethodInfo::DEFAULT_OUTMETHOD_OFFSET, uint32_t num = 0,
LexicalEnvStatus lexEnvStatus = LexicalEnvStatus::VIRTUAL_LEXENV, bool isNamespace = false)
MethodInfo(uint32_t methodInfoIndex, uint32_t methodPcInfoIndex, uint32_t outMethodIdx = MethodInfo::DEFAULT_ROOT,
uint32_t outMethodOffset = MethodInfo::DEFAULT_OUTMETHOD_OFFSET)
: methodInfoIndex_(methodInfoIndex), methodPcInfoIndex_(methodPcInfoIndex), outerMethodId_(outMethodIdx),
outerMethodOffset_(outMethodOffset), numOfLexVars_(num), status_(lexEnvStatus), isNamespace_(isNamespace)
outerMethodOffset_(outMethodOffset)
{
}
~MethodInfo() = default;
static constexpr uint32_t DEFAULT_OUTMETHOD_OFFSET = 0;
static constexpr uint32_t DEFAULT_ROOT = std::numeric_limits<uint32_t>::max();
inline uint32_t GetOutMethodId() const
{
@ -225,28 +143,6 @@ public:
outerMethodOffset_ = outMethodOffset;
}
inline uint32_t GetNumOfLexVars() const
{
return numOfLexVars_;
}
inline void SetNumOfLexVars(uint32_t numOfLexVars)
{
if (numOfLexVars > numOfLexVars_) {
numOfLexVars_ = numOfLexVars;
}
}
inline LexicalEnvStatus GetLexEnvStatus() const
{
return status_;
}
inline void SetLexEnvStatus(LexicalEnvStatus status)
{
status_ = status;
}
inline uint32_t GetMethodPcInfoIndex() const
{
return methodPcInfoIndex_;
@ -291,16 +187,6 @@ public:
return bcToFuncTypeId_;
}
inline void MarkMethodNamespace()
{
isNamespace_ = true;
}
inline bool IsNamespace() const
{
return isNamespace_;
}
inline const std::vector<uint32_t> &GetInnerMethods() const
{
return innerMethods_;
@ -387,13 +273,10 @@ private:
std::vector<uint32_t> innerMethods_ {};
std::vector<uint32_t> constructorMethods_ {};
std::unordered_map<int32_t, uint32_t> bcToFuncTypeId_ {};
uint32_t outerMethodId_ { LexEnv::DEFAULT_ROOT };
uint32_t outerMethodId_ { MethodInfo::DEFAULT_ROOT };
uint32_t outerMethodOffset_ { MethodInfo::DEFAULT_OUTMETHOD_OFFSET };
uint32_t numOfLexVars_ { 0 };
LexicalEnvStatus status_ { LexicalEnvStatus::VIRTUAL_LEXENV };
std::set<uint32_t> importIndex_ {};
CompileStateBit compileState_ { 0 };
bool isNamespace_ {false};
};
struct FastCallInfo {
@ -625,54 +508,18 @@ private:
std::unordered_map<uint32_t, FastCallInfo> methodOffsetToFastCallInfos_ {};
};
class LexEnvManager {
public:
explicit LexEnvManager(BCInfo &bcInfo);
~LexEnvManager() = default;
NO_COPY_SEMANTIC(LexEnvManager);
NO_MOVE_SEMANTIC(LexEnvManager);
void SetLexEnvElementType(uint32_t methodId, uint32_t level, uint32_t slot, const GateType &type);
GateType GetLexEnvElementType(uint32_t methodId, uint32_t level, uint32_t slot) const;
private:
uint32_t GetTargetLexEnv(uint32_t methodId, uint32_t level) const;
inline uint32_t GetOutMethodId(uint32_t methodId) const
{
return lexEnvs_[methodId].GetOutMethodId();
}
inline LexicalEnvStatus GetLexEnvStatus(uint32_t methodId) const
{
return lexEnvs_[methodId].GetLexEnvStatus();
}
inline bool HasDefaultRoot(uint32_t methodId) const
{
return GetOutMethodId(methodId) == LexEnv::DEFAULT_ROOT;
}
std::vector<LexEnv> lexEnvs_ {};
};
class BytecodeInfoCollector {
public:
BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile, PGOProfilerDecoder &pfDecoder,
size_t maxAotMethodSize, bool enableCollectLiteralInfo);
size_t maxAotMethodSize);
BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
PGOProfilerDecoder &pfDecoder, bool enableCollectLiteralInfo);
PGOProfilerDecoder &pfDecoder);
~BytecodeInfoCollector();
~BytecodeInfoCollector() = default;;
NO_COPY_SEMANTIC(BytecodeInfoCollector);
NO_MOVE_SEMANTIC(BytecodeInfoCollector);
bool EnableCollectLiteralInfo() const
{
return enableCollectLiteralInfo_;
}
Bytecodes* GetByteCodes()
{
return &bytecodes_;
@ -729,11 +576,6 @@ public:
return compilationEnv_;
}
LexEnvManager* GetEnvManager() const
{
return envManager_;
}
template <class Callback>
void IterateAllMethods(const Callback &cb)
{
@ -745,54 +587,34 @@ public:
}
private:
void ProcessEnvs();
inline size_t GetMethodInfoID()
{
return methodInfoIndex_++;
}
inline std::string GetClassName(const EntityId entityId)
{
std::string className(MethodLiteral::GetMethodName(jsPandaFile_, entityId));
if (LIKELY(className.find('#') != std::string::npos)) {
size_t poiIndex = className.find_last_of('#');
className = className.substr(poiIndex + 1);
}
return className;
}
const CString GetEntryFunName(const std::string_view &entryPoint) const;
void ProcessClasses();
void ProcessMethod();
void RearrangeInnerMethods();
void CollectMethodPcsFromBC(const uint32_t insSz, const uint8_t *insArr,
MethodLiteral *method, std::vector<std::string> &classNameVec, const CString &recordName,
uint32_t methodOffset, std::vector<panda_file::File::EntityId> &classConstructIndexes);
MethodLiteral *method, const CString &recordName, uint32_t methodOffset,
std::vector<panda_file::File::EntityId> &classConstructIndexes);
void SetMethodPcInfoIndex(uint32_t methodOffset, const std::pair<size_t, uint32_t> &processedMethodInfo);
void CollectInnerMethods(const MethodLiteral *method, uint32_t innerMethodOffset, bool isConstructor = false);
void CollectInnerMethods(uint32_t methodId, uint32_t innerMethodOffset, bool isConstructor = false);
void CollectInnerMethodsFromLiteral(const MethodLiteral *method, uint64_t index);
void CollectInnerFuncType(const MethodLiteral *method, uint32_t innerMethodOffset, int32_t bcIndex);
void NewLexEnvWithSize(const MethodLiteral *method, uint64_t numOfLexVars);
void CollectInnerMethodsFromNewLiteral(const MethodLiteral *method, panda_file::File::EntityId literalId);
void CollectMethodInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method,
std::vector<std::string> &classNameVec, int32_t bcIndex,
std::vector<panda_file::File::EntityId> &classConstructIndexes,
bool *canFastCall);
void CollectMethodInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method, int32_t bcIndex,
std::vector<panda_file::File::EntityId> &classConstructIndexes, bool *canFastCall);
void CollectModuleInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method,
const CString &recordName);
void IterateLiteral(const MethodLiteral *method, std::vector<uint32_t> &classOffsetVector);
void StoreClassTypeOffset(const uint32_t typeOffset, std::vector<uint32_t> &classOffsetVector);
void CollectClassLiteralInfo(const MethodLiteral *method, const std::vector<std::string> &classNameVec);
void CollectFunctionTypeId(panda_file::File::EntityId fieldId);
void CollectImportIndexs(uint32_t methodOffset, uint32_t index);
void CollectExportIndexs(const CString &recordName, uint32_t index);
bool CheckExportNameAndClassType(const CString &recordName, const JSHandle<EcmaString> &exportStr);
void CollectRecordReferenceREL();
void CollectRecordImportInfo(const CString &recordName);
void CollectRecordExportInfo(const CString &recordName);
void MarkMethodNamespace(const uint32_t methodOffset);
CompilationEnv *compilationEnv_ {nullptr};
JSPandaFile *jsPandaFile_ {nullptr};
@ -801,9 +623,7 @@ private:
PGOBCInfo pgoBCInfo_ {};
std::unique_ptr<SnapshotConstantPoolData> snapshotCPData_;
size_t methodInfoIndex_ {0};
bool enableCollectLiteralInfo_ {false};
std::set<int32_t> classDefBCIndexes_ {};
LexEnvManager* envManager_ {nullptr};
Bytecodes bytecodes_;
};
} // namespace panda::ecmascript::kungfu

View File

@ -28,6 +28,7 @@
#include "ecmascript/compiler/rt_call_signature.h"
#include "ecmascript/deoptimizer/deoptimizer.h"
#include "ecmascript/frames.h"
#include "ecmascript/js_function.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/method.h"
#include "triple.h"

View File

@ -14,9 +14,10 @@
*/
#include "ecmascript/compiler/compilation_driver.h"
#include "ecmascript/compiler/file_generators.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/jspandafile/method_literal.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
CompilationDriver::CompilationDriver(PGOProfilerDecoder &profilerDecoder,
@ -45,10 +46,6 @@ CompilationDriver::CompilationDriver(PGOProfilerDecoder &profilerDecoder,
maxMethodsInModule_(maxMethodsInModule),
optionMethodsRange_(compilerMethodsRange)
{
if (compilationEnv_->IsAotCompiler()) {
compilationEnv_->GetTSManager()->SetCompilationDriver(this);
}
if (!optionSelectMethods.empty() && !optionSkipMethods.empty()) {
LOG_COMPILER(FATAL) <<
"--compiler-select-methods and --compiler-skip-methods should not be set at the same time";
@ -63,13 +60,6 @@ CompilationDriver::CompilationDriver(PGOProfilerDecoder &profilerDecoder,
}
}
CompilationDriver::~CompilationDriver()
{
if (compilationEnv_->IsAotCompiler()) {
compilationEnv_->GetTSManager()->SetCompilationDriver(nullptr);
}
}
Module *CompilationDriver::GetModule()
{
return IsCurModuleFull() ? fileGenerator_->AddModule(fileName_, triple_, *lOptions_, outputAsm_)

View File

@ -38,7 +38,7 @@ public:
bool outputAsm,
size_t maxMethodsInModule,
const std::pair<uint32_t, uint32_t> &compilerMethodsRange);
virtual ~CompilationDriver();
~CompilationDriver() = default;
NO_COPY_SEMANTIC(CompilationDriver);
NO_MOVE_SEMANTIC(CompilationDriver);

View File

@ -15,12 +15,11 @@
#include "ecmascript/compiler/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 {
CompilationEnv::CompilationEnv(EcmaVM *vm) : vm_(vm), thread_(vm_->GetJSThread()),
tsManager_(nullptr), ptManager_(nullptr) { }
ptManager_(nullptr) { }
NativeAreaAllocator *CompilationEnv::GetNativeAreaAllocator() const
{

View File

@ -24,7 +24,6 @@ namespace panda::ecmascript {
namespace kungfu {
class PGOTypeManager;
};
class TSManager;
class ConstantPool;
namespace pgo {
class PGOProfiler;
@ -56,11 +55,6 @@ public:
return ptManager_;
}
TSManager *GetTSManager() const
{
return tsManager_;
}
NativeAreaAllocator *GetNativeAreaAllocator() const;
virtual JSRuntimeOptions &GetJSOptions() = 0;
virtual std::shared_ptr<pgo::PGOProfiler> GetPGOProfiler() const;
@ -124,7 +118,6 @@ public:
protected:
EcmaVM *vm_ {nullptr};
JSThread *thread_ {nullptr};
TSManager *tsManager_ {nullptr};
kungfu::PGOTypeManager *ptManager_ {nullptr};
};
} // namespace panda::ecmascript

View File

@ -17,6 +17,7 @@
#include "ecmascript/common.h"
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#include "ecmascript/platform/code_sign.h"
#include "ecmascript/platform/directory.h"

View File

@ -24,6 +24,7 @@
#include "ecmascript/compiler/codegen/llvm/llvm_ir_builder.h"
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/compiler/ir_module.h"
#include "ecmascript/compiler/jit_compilation_env.h"
#include "ecmascript/stackmap/cg_stackmap.h"
#include "ecmascript/mem/machine_code.h"

View File

@ -17,7 +17,8 @@
#include "ecmascript/compiler/circuit_builder.h"
#include "ecmascript/compiler/gate_accessor.h"
#include "ecmascript/compiler/graph_editor.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/mem/assert_scope.h"
namespace panda::ecmascript::kungfu {
using UseIterator = GateAccessor::UseIterator;

View File

@ -15,7 +15,6 @@
#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 {

View File

@ -56,14 +56,11 @@ JitCompilationOptions::JitCompilationOptions(JSRuntimeOptions runtimeOptions)
isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
isEnableOptString_ = runtimeOptions.IsEnableOptString();
isEnableTypeInfer_ =
isEnableTypeLowering_ || runtimeOptions.AssertTypes();
isEnableOptPGOType_ = runtimeOptions.IsEnableOptPGOType();
isEnableOptTrackField_ = runtimeOptions.IsEnableOptTrackField();
isEnableOptLoopPeeling_ = runtimeOptions.IsEnableOptLoopPeeling();
isEnableOptOnHeapCheck_ = runtimeOptions.IsEnableOptOnHeapCheck();
isEnableOptLoopInvariantCodeMotion_ = runtimeOptions.IsEnableOptLoopInvariantCodeMotion();
isEnableCollectLiteralInfo_ = false;
isEnableOptConstantFolding_ = runtimeOptions.IsEnableOptConstantFolding();
isEnableLexenvSpecialization_ = runtimeOptions.IsEnableLexenvSpecialization();
isEnableNativeInline_ = runtimeOptions.IsEnableNativeInline();
@ -86,14 +83,12 @@ void JitCompiler::Init(JSRuntimeOptions runtimeOptions)
.EnableEarlyElimination(jitOptions_.isEnableEarlyElimination_)
.EnableLaterElimination(jitOptions_.isEnableLaterElimination_)
.EnableValueNumbering(jitOptions_.isEnableValueNumbering_)
.EnableTypeInfer(jitOptions_.isEnableTypeInfer_)
.EnableOptInlining(jitOptions_.isEnableOptInlining_)
.EnableOptString(jitOptions_.isEnableOptString_)
.EnableOptPGOType(jitOptions_.isEnableOptPGOType_)
.EnableOptTrackField(jitOptions_.isEnableOptTrackField_)
.EnableOptLoopPeeling(jitOptions_.isEnableOptLoopPeeling_)
.EnableOptLoopInvariantCodeMotion(jitOptions_.isEnableOptLoopInvariantCodeMotion_)
.EnableCollectLiteralInfo(jitOptions_.isEnableCollectLiteralInfo_)
.EnableOptConstantFolding(jitOptions_.isEnableOptConstantFolding_)
.EnableLexenvSpecialization(jitOptions_.isEnableLexenvSpecialization_)
.EnableInlineNative(jitOptions_.isEnableNativeInline_)

View File

@ -54,13 +54,11 @@ struct JitCompilationOptions {
bool isEnableValueNumbering_;
bool isEnableOptInlining_;
bool isEnableOptString_;
bool isEnableTypeInfer_;
bool isEnableOptPGOType_;
bool isEnableOptTrackField_;
bool isEnableOptLoopPeeling_;
bool isEnableOptOnHeapCheck_;
bool isEnableOptLoopInvariantCodeMotion_;
bool isEnableCollectLiteralInfo_;
bool isEnableOptConstantFolding_;
bool isEnableLexenvSpecialization_;
bool isEnableNativeInline_;

View File

@ -24,7 +24,6 @@
#include "ecmascript/compiler/share_gate_meta_data.h"
#include "ecmascript/compiler/type_info_accessors.h"
#include "ecmascript/js_dataview.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class NativeInlineLowering {
@ -35,7 +34,6 @@ public:
builder_(circuit, cmpCfg),
acc_(circuit),
glue_(acc_.GetGlueFromArgList()),
tsManager_(ctx->GetTSManager()),
enableLog_(enableLog),
methodName_(name),
nocheck_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerNoCheck()),
@ -103,7 +101,6 @@ private:
CircuitBuilder builder_;
GateAccessor acc_;
GateRef glue_;
TSManager *tsManager_;
bool enableLog_;
std::string methodName_;
bool nocheck_;

View File

@ -22,7 +22,6 @@
#include "ecmascript/compiler/number_gate_info.h"
#include "ecmascript/compiler/type.h"
#include "ecmascript/mem/chunk_containers.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class NumberSpeculativeLowering {

View File

@ -23,7 +23,6 @@
#include "ecmascript/compiler/number_gate_info.h"
#include "ecmascript/compiler/type.h"
#include "ecmascript/mem/chunk_containers.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class NumberSpeculativeRetype {

View File

@ -20,7 +20,6 @@
#include "ecmascript/compiler/pass_manager.h"
#include "ecmascript/compiler/number_speculative_retype.h"
#include "ecmascript/compiler/range_guard.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class NumberSpeculativeRunner {

View File

@ -1,163 +0,0 @@
/*
* Copyright (c) 2023 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/object_access_helper.h"
#include "ecmascript/js_hclass-inl.h"
#include "ecmascript/ts_types/ts_type.h"
namespace panda::ecmascript::kungfu {
bool ObjectAccessHelper::Compute(ChunkVector<ObjectAccessInfo> &infos)
{
ASSERT(compilationEnv_->IsAotCompiler());
ASSERT(infos.empty());
bool result = false;
ObjectAccessInfo info(type_);
TSTypeKind kind = tsManager_->GetTypeKind(type_.GetGTRef());
switch (kind) {
case TSTypeKind::CLASS_INSTANCE:
result = ComputeForClassInstance(info);
break;
case TSTypeKind::CLASS:
case TSTypeKind::OBJECT:
result = ComputeForClassOrObject(info);
break;
case TSTypeKind::UNION:
return ComputePolymorphism(infos);
default:
return false;
}
infos.emplace_back(info);
return result;
}
bool ObjectAccessHelper::ComputeForClassInstance(ObjectAccessInfo &info)
{
int hclassIndex = tsManager_->GetHClassIndexByInstanceGateType(info.Type());
if (hclassIndex == -1) {
return false;
}
JSHClass *hclass = JSHClass::Cast(tsManager_->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
if (!hclass->HasTSSubtyping()) {
return false;
}
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(compilationEnv_->GetJSThread(), hclass, key_);
info.Set(hclassIndex, plr);
if (IsLoading()) {
return plr.IsFound();
}
return (plr.IsFound() && !plr.IsFunction());
}
bool ObjectAccessHelper::ComputeForClassOrObject(ObjectAccessInfo &info)
{
GateType type = info.Type();
int hclassIndex = -1;
if (tsManager_->IsClassTypeKind(type)) {
hclassIndex = tsManager_->GetConstructorHClassIndexByClassGateType(type);
} else if (tsManager_->IsObjectTypeKind(type)) {
hclassIndex = tsManager_->GetHClassIndexByObjectType(type);
}
if (hclassIndex == -1) {
return false;
}
JSHClass *hclass = JSHClass::Cast(tsManager_->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(compilationEnv_->GetJSThread(), hclass, key_);
info.Set(hclassIndex, plr);
if (IsLoading()) {
return (plr.IsFound() && plr.IsLocal() && !plr.IsAccessor());
}
return (plr.IsFound() && plr.IsLocal() && !plr.IsAccessor() && plr.IsWritable());
}
bool ObjectAccessHelper::ComputePolymorphism(ChunkVector<ObjectAccessInfo> &infos)
{
DISALLOW_GARBAGE_COLLECTION;
ASSERT(tsManager_->IsUnionTypeKind(type_));
JSHandle<TSUnionType> unionType(tsManager_->GetTSType(type_.GetGTRef()));
TaggedArray *components = TaggedArray::Cast(unionType->GetComponents().GetTaggedObject());
uint32_t length = components->GetLength();
for (uint32_t i = 0; i < length; ++i) {
GlobalTSTypeRef gt(components->Get(i).GetInt());
GateType type = GateType(gt);
ObjectAccessInfo info(type);
TSTypeKind kind = tsManager_->GetTypeKind(gt);
switch (kind) {
case TSTypeKind::CLASS_INSTANCE: {
if (!ComputeForClassInstance(info)) {
return false;
}
break;
}
case TSTypeKind::CLASS:
case TSTypeKind::OBJECT: {
if (!ComputeForClassOrObject(info)) {
return false;
}
break;
}
default:
return false;
}
infos.emplace_back(info);
}
return infos.size() <= POLYMORPHIC_MAX_SIZE;
}
bool PGOObjectAccessHelper::ComputeForClassInstance(PGOObjectAccessInfo &info)
{
auto type = info.Type();
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(type));
if (hclassIndex == -1) {
return false;
}
JSHClass *hclass = JSHClass::Cast(ptManager->QueryHClass(type.first, type.second).GetTaggedObject());
PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(compilationEnv_->GetJSThread(), hclass, key_);
info.Set(hclassIndex, plr);
if (IsLoading()) {
return plr.IsFound();
}
return (plr.IsFound() && !plr.IsFunction());
}
bool PGOObjectAccessHelper::ClassInstanceIsCallable(PGOObjectAccessInfo &info)
{
auto type = info.Type();
PGOTypeManager *ptManager = compilationEnv_->GetPTManager();
int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(type));
if (hclassIndex == -1) {
return false;
}
JSHClass *hclass = JSHClass::Cast(ptManager->QueryHClass(type.first, type.second).GetTaggedObject());
return hclass->IsCallable();
}
} // namespace panda::ecmascript::kungfu

View File

@ -1,216 +0,0 @@
/*
* Copyright (c) 2023 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_OBJECT_ACCESS_HELPER_H
#define ECMASCRIPT_COMPILER_OBJECT_ACCESS_HELPER_H
#include "ecmascript/compiler/pgo_type/pgo_type_location.h"
#include "ecmascript/compiler/share_gate_meta_data.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class ObjectAccessInfo final {
public:
explicit ObjectAccessInfo(GateType type, int hclassIndex = -1, PropertyLookupResult plr = PropertyLookupResult())
: type_(type), hclassIndex_(hclassIndex), plr_(plr) {}
~ObjectAccessInfo() = default;
void Set(int hclassIndex, PropertyLookupResult plr)
{
hclassIndex_ = hclassIndex;
plr_ = plr;
}
GateType Type() const
{
return type_;
}
int HClassIndex() const
{
return hclassIndex_;
}
PropertyLookupResult Plr() const
{
return plr_;
}
private:
GateType type_ {GateType::AnyType()};
int hclassIndex_ {-1};
PropertyLookupResult plr_ {};
};
class PGOObjectAccessInfo final {
public:
explicit PGOObjectAccessInfo(
ProfileTyper type, int hclassIndex = -1, PropertyLookupResult plr = PropertyLookupResult())
: type_(type), hclassIndex_(hclassIndex), plr_(plr) {}
~PGOObjectAccessInfo() = default;
void Set(int hclassIndex, PropertyLookupResult plr)
{
hclassIndex_ = hclassIndex;
plr_ = plr;
}
ProfileTyper Type() const
{
return type_;
}
int HClassIndex() const
{
return hclassIndex_;
}
PropertyLookupResult Plr() const
{
return plr_;
}
private:
ProfileTyper type_ {ProfileTyper()};
int hclassIndex_ {-1};
PropertyLookupResult plr_ {};
};
// An auxiliary class serving TypedBytecodeLowering, used for named object property access,
// invoking TSManager and HClass.
class ObjectAccessHelper final {
public:
static constexpr size_t POLYMORPHIC_MAX_SIZE = 4;
enum AccessMode : uint8_t {
LOAD = 0,
STORE
};
explicit ObjectAccessHelper(CompilationEnv *env, AccessMode mode, GateRef receiver, GateType type,
JSTaggedValue key, GateRef value)
: tsManager_(env->GetTSManager()),
compilationEnv_(env),
mode_(mode),
receiver_(receiver),
type_(type),
key_(key),
value_(value) {}
~ObjectAccessHelper() = default;
bool Compute(ChunkVector<ObjectAccessInfo> &infos);
AccessMode GetAccessMode() const
{
return mode_;
}
bool IsLoading() const
{
return mode_ == AccessMode::LOAD;
}
GateRef GetReceiver() const
{
return receiver_;
}
GateRef GetValue() const
{
return value_;
}
private:
bool ComputeForClassInstance(ObjectAccessInfo &info);
bool ComputeForClassOrObject(ObjectAccessInfo &info);
bool ComputePolymorphism(ChunkVector<ObjectAccessInfo> &infos);
TSManager *tsManager_ {nullptr};
const CompilationEnv *compilationEnv_ {nullptr};
AccessMode mode_ {};
GateRef receiver_ {Circuit::NullGate()};
GateType type_ {GateType::AnyType()};
JSTaggedValue key_ {JSTaggedValue::Hole()};
GateRef value_ {Circuit::NullGate()};
};
class PGOObjectAccessHelper final {
public:
static constexpr size_t POLYMORPHIC_MAX_SIZE = 4;
enum AccessMode : uint8_t {
LOAD = 0,
STORE
};
explicit PGOObjectAccessHelper(CompilationEnv *env, AccessMode mode, GateRef receiver, ProfileTyper type,
JSTaggedValue key, GateRef value)
: tsManager_(env->GetTSManager()),
compilationEnv_(env),
mode_(mode),
receiver_(receiver),
holder_(receiver),
type_(type),
key_(key),
value_(value) {}
~PGOObjectAccessHelper() = default;
AccessMode GetAccessMode() const
{
return mode_;
}
bool IsLoading() const
{
return mode_ == AccessMode::LOAD;
}
GateRef GetReceiver() const
{
return receiver_;
}
GateRef GetHolder() const
{
return holder_;
}
void SetHolder(GateRef holder)
{
holder_ = holder;
}
GateRef GetValue() const
{
return value_;
}
bool ComputeForClassInstance(PGOObjectAccessInfo &info);
bool ClassInstanceIsCallable(PGOObjectAccessInfo &info);
private:
TSManager *tsManager_ {nullptr};
const CompilationEnv *compilationEnv_ {nullptr};
AccessMode mode_ {};
GateRef receiver_ {Circuit::NullGate()};
GateRef holder_ {Circuit::NullGate()};
ProfileTyper type_ {ProfileTyper()};
JSTaggedValue key_ {JSTaggedValue::Hole()};
GateRef value_ {Circuit::NullGate()};
};
} // panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_OBJECT_ACCESS_HELPER_H

View File

@ -45,7 +45,6 @@
#include "ecmascript/compiler/string_builder_optimizer.h"
#include "ecmascript/compiler/slowpath_lowering.h"
#include "ecmascript/compiler/state_split_linearizer.h"
#include "ecmascript/compiler/ts_class_analysis.h"
#include "ecmascript/compiler/ts_inline_lowering.h"
#include "ecmascript/compiler/typed_bytecode_lowering.h"
#include "ecmascript/compiler/ts_hcr_opt_pass.h"
@ -115,11 +114,6 @@ public:
return ctx_->GetCompilerConfig();
}
TSManager* GetTSManager() const
{
return ctx_->GetTSManager();
}
PGOTypeManager* GetPTManager() const
{
return ctx_->GetPTManager();
@ -213,13 +207,6 @@ public:
if (methodInfo_->IsTypeInferAbort() && !methodInfo_->IsResolvedMethod()) {
return true;
}
} else {
// For js method, type infer pass will be skipped and it don't have a type percent.
// If we set an non zero type threshold, js method will be skipped from full compilation.
// The default Type threshold is -1.
if (ctx_->GetTSManager()->GetTypeThreshold() >= 0) {
return true;
}
}
// when a method will be full compiled, we should confirm its TypeInferAbortBit to be false
// maybe it used to be true in the first round of compilation.
@ -283,25 +270,12 @@ public:
TimeScope timescope("PGOTypeInferPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
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->GetPassContext()->GetCompilationEnv());
PGOTypeInfer pgoTypeInfer(data->GetCircuit(), data->GetBuilder(), data->GetMethodName(), &chunk, enableLog);
pgoTypeInfer.Run();
return true;
}
};
class TSClassAnalysisPass {
public:
bool Run(PassData *data)
{
TimeScope timescope("TSClassAnalysisPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
TSClassAnalysis analyzer(data->GetPassContext()->GetTSManager());
analyzer.Run();
return true;
}
};
class EscapeAnalysisPass {
public:
bool Run(PassData *data)
@ -371,10 +345,7 @@ public:
data->GetCallMethodFlagMap(),
data->GetPGOProfilerDecoder(),
data->GetOptBCRange());
bool success = lowering.RunTypedBytecodeLowering();
if (!success) {
data->MarkAsTypeAbort();
}
lowering.RunTypedBytecodeLowering();
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
DeadCodeElimination deadCodeElimination(data->GetCircuit(), &visitor, &chunk);
TSHCROptPass optimization(data->GetCircuit(), &visitor, &chunk, data->GetPassContext(), enableLog,
@ -448,7 +419,6 @@ public:
data->GetPassContext()->GetCompilationEnv(),
&visitor,
data->GetCompilerConfig(),
data->GetTSManager(),
&chunk,
passOptions->EnableLoweringBuiltin());
visitor.AddPass(&lowering);

View File

@ -26,7 +26,6 @@
#include "ecmascript/pgo_profiler/pgo_profiler.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#include "ecmascript/pgo_profiler/pgo_utils.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "ecmascript/jit/jit.h"
#include "jsnapi_expo.h"
@ -134,10 +133,6 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
Jit::JitLockHolder lock(compilationEnv_, "PGOTypeInferPass");
pipeline.RunPass<PGOTypeInferPass>();
}
{
Jit::JitLockHolder lock(compilationEnv_, "TSClassAnalysisPass");
pipeline.RunPass<TSClassAnalysisPass>();
}
{
Jit::JitLockHolder lock(compilationEnv_, "TSInlineLoweringPass");
pipeline.RunPass<TSInlineLoweringPass>();
@ -217,8 +212,7 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName,
{
[[maybe_unused]] EcmaHandleScope handleScope(compilationEnv_->GetJSThread());
BytecodeInfoCollector collector(compilationEnv_, jsPandaFile, profilerDecoder_,
maxAotMethodSize_, passOptions_->EnableCollectLiteralInfo());
BytecodeInfoCollector collector(compilationEnv_, jsPandaFile, profilerDecoder_, maxAotMethodSize_);
// Checking released/debuggable pandafile uses method literals, which are initialized in BytecodeInfoCollector,
// should after it.
if (!IsReleasedPandaFile(jsPandaFile)) {

View File

@ -19,6 +19,7 @@
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
#include "ecmascript/compiler/jit_compilation_env.h"
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/compiler/compilation_driver.h"
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/compiler/file_generators.h"
#include "ecmascript/compiler/ir_module.h"
@ -27,11 +28,9 @@
#include "ecmascript/ecma_vm.h"
#include "ecmascript/jit/jit_profiler.h"
#include "ecmascript/jspandafile/method_literal.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class Bytecodes;
class LexEnvManager;
class CompilationConfig;
class PassData;
class CallMethodFlagMap;
@ -42,9 +41,7 @@ public:
PGOProfilerDecoder *decoder)
: compilationEnv_(collector->GetCompilationEnv()),
bcInfoCollector_(collector),
tsManager_(compilationEnv_->GetTSManager()),
bytecodes_(collector->GetByteCodes()),
lexEnvManager_(bcInfoCollector_->GetEnvManager()),
cmpCfg_(triple, &compilationEnv_->GetJSOptions()),
log_(log),
jsPandaFile_(collector->GetJSPandaFile()),
@ -53,11 +50,6 @@ public:
{
}
TSManager* GetTSManager() const
{
return tsManager_;
}
PGOTypeManager* GetPTManager() const
{
return compilationEnv_->GetPTManager();
@ -68,11 +60,6 @@ public:
return bytecodes_;
}
LexEnvManager* GetLexEnvManager() const
{
return lexEnvManager_;
}
CompilationConfig* GetCompilerConfig()
{
return &cmpCfg_;
@ -131,9 +118,7 @@ public:
private:
CompilationEnv *compilationEnv_ {nullptr};
BytecodeInfoCollector *bcInfoCollector_ {nullptr};
TSManager *tsManager_ {nullptr};
Bytecodes *bytecodes_ {nullptr};
LexEnvManager *lexEnvManager_ {nullptr};
CompilationConfig cmpCfg_;
CompilerLog *log_ {nullptr};
const JSPandaFile *jsPandaFile_ {nullptr};

View File

@ -23,7 +23,6 @@ namespace panda::ecmascript::kungfu {
V(EarlyElimination, true) \
V(LaterElimination, true) \
V(ValueNumbering, false) \
V(TypeInfer, false) \
V(OptInlining, false) \
V(OptNoGCCall, false) \
V(OptPGOType, false) \

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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, 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, nullptr, &visitor, nullptr, nullptr, &chunk, false);
TypedHCRLowering lowering(&circuit, nullptr, &visitor, nullptr, &chunk, false);
visitor.AddPass(&lowering);
visitor.VisitGraph();
EXPECT_TRUE(Verifier::Run(&circuit));

View File

@ -1,156 +0,0 @@
/*
* Copyright (c) 2023 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/ts_class_analysis.h"
#include "ecmascript/js_hclass-inl.h"
#include "ecmascript/layout_info.h"
#include "ecmascript/ts_types/ts_type_accessor.h"
namespace panda::ecmascript::kungfu {
void TSClassAnalysis::Run() const
{
const JSThread *thread = tsManager_->GetThread();
std::set<GlobalTSTypeRef> &collectedGT = GetCollectedGT();
for (auto iter = collectedGT.begin(); iter != collectedGT.end();) {
JSHandle<JSTaggedValue> tsType = tsManager_->GetTSType(*iter);
if (tsType->IsUndefined()) {
++iter;
continue;
}
ASSERT(tsType->IsTSClassType());
JSHandle<TSClassType> classType(tsType);
if (CheckInitInfoOnInheritanceChain(*classType)) {
AnalyzeProperties(thread, *classType);
collectedGT.erase(iter++);
} else {
++iter;
}
}
}
bool TSClassAnalysis::CheckInitInfoOnInheritanceChain(const TSClassType *classType) const
{
DISALLOW_GARBAGE_COLLECTION;
if (!tsManager_->HasTSHClass(classType)) {
return false;
}
// All extended class types and itself have completed initialization analysis.
if (classType->IsBaseClassType()) {
return classType->GetHasAnalysedInitialization();
}
while (true) {
if (!classType->GetHasAnalysedInitialization()) {
return false;
}
if (classType->IsBaseClassType()) {
break;
}
classType = tsManager_->GetExtendedClassType(classType);
}
return true;
}
bool TSClassAnalysis::HasEscapedThisOnSuper(const TSClassType *classType) const
{
DISALLOW_GARBAGE_COLLECTION;
if (classType->IsBaseClassType()) {
return false;
}
while (true) {
classType = tsManager_->GetExtendedClassType(classType);
if (classType->GetHasEscapedThisInConstructor()) {
return true;
}
if (classType->IsBaseClassType()) {
break;
}
}
return false;
}
void TSClassAnalysis::AnalyzeProperties(const JSThread *thread, const TSClassType *classType) const
{
DISALLOW_GARBAGE_COLLECTION;
// Using this in self constructor will not mark flag in initialization analysis.
if (HasEscapedThisOnSuper(classType)) {
return;
}
if (!classType->GetHasPassedSubtypingCheck()) {
return;
}
GlobalTSTypeRef classGT = classType->GetGT();
int hclassIndex = tsManager_->GetHClassIndex(classGT);
ASSERT(hclassIndex != -1);
JSHClass *hclass = JSHClass::Cast(tsManager_->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
if (UNLIKELY(hclass->IsDictionaryMode())) {
return;
}
LayoutInfo *layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
for (uint32_t index = 0; index < hclass->NumberOfProps(); ++index) {
JSTaggedValue key = layout->GetKey(index);
if (AnalyzePropertyOnSelf(thread, classType, key) || AnalyzePropertyOnSupers(thread, classType, key)) {
layout->SetIsNotHole(thread, index);
}
}
}
bool TSClassAnalysis::AnalyzePropertyOnSelf(const JSThread *thread, const TSClassType *classType,
JSTaggedValue key) const
{
DISALLOW_GARBAGE_COLLECTION;
JSHandle<TSObjectType> instanceType(thread, classType->GetInstanceType());
JSHandle<TSObjLayoutInfo> tsLayout(thread, instanceType->GetObjLayoutInfo());
int index = tsLayout->GetElementIndexByKey(key);
if (!TSObjLayoutInfo::IsValidIndex(index)) {
return false;
}
TSFieldAttributes tsAttr(tsLayout->GetAttribute(index).GetInt());
return tsAttr.GetInitializedFlag();
}
bool TSClassAnalysis::AnalyzePropertyOnSupers(const JSThread *thread, const TSClassType *classType,
JSTaggedValue key) const
{
DISALLOW_GARBAGE_COLLECTION;
if (classType->IsBaseClassType()) {
return false;
}
TSClassType *type = tsManager_->GetExtendedClassType(classType);
while (true) {
if (AnalyzePropertyOnSelf(thread, type, key)) {
return true;
}
if (type->IsBaseClassType()) {
break;
}
type = tsManager_->GetExtendedClassType(type);
}
return false;
}
} // namespace panda::ecmascript::kungfu

View File

@ -1,48 +0,0 @@
/*
* Copyright (c) 2023 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_TS_CLASS_ANALYSIS_H
#define ECMASCRIPT_COMPILER_TS_CLASS_ANALYSIS_H
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class TSClassAnalysis {
public:
TSClassAnalysis(TSManager *tsManager): tsManager_(tsManager) {}
~TSClassAnalysis() = default;
void Run() const;
private:
bool CheckInitInfoOnInheritanceChain(const TSClassType *classType) const;
bool HasEscapedThisOnSuper(const TSClassType *classType) const;
void AnalyzeProperties(const JSThread *thread, const TSClassType *classType) const;
bool AnalyzePropertyOnSelf(const JSThread *thread, const TSClassType *classType, JSTaggedValue key) const;
bool AnalyzePropertyOnSupers(const JSThread *thread, const TSClassType *classType, JSTaggedValue key) const;
inline std::set<GlobalTSTypeRef>& GetCollectedGT() const
{
return tsManager_->GetCollectedGT();
}
TSManager *tsManager_ {nullptr};
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_TS_CLASS_ANALYSIS_H

View File

@ -1,307 +0,0 @@
/*
* Copyright (c) 2023 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/ts_hclass_generator.h"
#include "ecmascript/global_env_constants-inl.h"
#include "ecmascript/layout_info-inl.h"
#include "ecmascript/js_function.h"
#include "ecmascript/jspandafile/class_info_extractor.h"
#include "ecmascript/subtyping_operator.h"
namespace panda::ecmascript::kungfu {
using ClassInfoExtractor = panda::ecmascript::ClassInfoExtractor;
void TSHClassGenerator::GenerateTSHClasses() const
{
const JSThread *thread = tsManager_->GetThread();
const std::set<GlobalTSTypeRef> &collectedGT = GetCollectedGT();
for (const auto &gt : collectedGT) {
JSHandle<JSTaggedValue> tsType = tsManager_->GetTSType(gt);
if (tsType->IsUndefined()) {
continue;
}
ASSERT(tsType->IsTSClassType());
JSHandle<TSClassType> classType(tsType);
if (tsManager_->HasTSHClass(classType)) {
continue;
} else if (tsManager_->IsUserDefinedClassTypeKind(gt)) {
RecursiveGenerate(classType);
} else if (!classType->GetHasLinked()) {
SubtypingOperator::MergeClassField(thread, classType);
}
}
}
void TSHClassGenerator::RecursiveGenerate(const JSHandle<TSClassType> &classType) const
{
if (!classType->IsBaseClassType()) {
JSHandle<TSClassType> extendedClassType(tsManager_->GetExtendedClassType(classType));
if (!tsManager_->HasTSHClass(extendedClassType)) {
RecursiveGenerate(extendedClassType);
}
}
JSThread *thread = tsManager_->GetThread();
bool passed = false;
if (classType->IsBaseClassType()) {
passed = SubtypingOperator::CheckBaseClass(thread, classType);
} else {
passed = SubtypingOperator::CheckSubtyping(thread, classType);
}
classType->SetHasPassedSubtypingCheck(passed);
if (passed) {
if (!classType->IsBaseClassType()) {
SubtypingOperator::MergeClassField(thread, classType);
}
JSHandle<JSHClass> ihclass = Generate(classType);
SubtypingOperator::FillTSInheritInfo(thread, classType, ihclass);
return;
}
Generate(classType);
}
JSHandle<JSHClass> TSHClassGenerator::Generate(const JSHandle<TSClassType> &classType) const
{
const JSThread *thread = tsManager_->GetThread();
JSHandle<JSHClass> ihclass = CreateHClass(thread, classType, Kind::INSTANCE);
JSHandle<JSHClass> phclass = CreateHClass(thread, classType, Kind::PROTOTYPE);
JSHandle<JSHClass> chclass = CreateHClass(thread, classType, Kind::CONSTRUCTOR);
JSHandle<JSObject> prototype = thread->GetEcmaVM()->GetFactory()->NewJSObject(phclass);
ihclass->SetProto(thread, prototype);
GlobalTSTypeRef gt = classType->GetGT();
tsManager_->AddInstanceTSHClass(gt, ihclass);
tsManager_->AddConstructorTSHClass(gt, chclass);
return ihclass;
}
JSHandle<JSHClass> TSHClassGenerator::CreateHClass(const JSThread *thread, const JSHandle<TSClassType> &classType,
Kind kind) const
{
JSHandle<JSHClass> hclass(thread->GlobalConstants()->GetHandledUndefined());
switch (kind) {
case Kind::INSTANCE: {
hclass = CreateIHClass(thread, classType);
break;
}
case Kind::PROTOTYPE: {
hclass = CreatePHClass(thread, classType);
break;
}
case Kind::CONSTRUCTOR: {
hclass = CreateCHClass(thread, classType);
break;
}
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
return hclass;
}
JSHandle<JSHClass> TSHClassGenerator::CreateIHClass(const JSThread *thread,
const JSHandle<TSClassType> &classType) const
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<TSObjectType> instanceType(thread, classType->GetInstanceType());
JSHandle<TSObjLayoutInfo> tsLayout(thread, instanceType->GetObjLayoutInfo());
uint32_t numOfProps = tsLayout->GetNumOfProperties();
JSHandle<JSHClass> hclass;
if (LIKELY(numOfProps <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(numOfProps);
for (uint32_t index = 0; index < numOfProps; ++index) {
JSTaggedValue tsPropKey = tsLayout->GetKey(index);
key.Update(tsPropKey);
ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
PropertyAttributes attributes = PropertyAttributes::Default();
attributes.SetIsInlinedProps(true);
attributes.SetRepresentation(Representation::NONE);
attributes.SetOffset(index);
layout->AddKey(thread, index, key.GetTaggedValue(), attributes);
}
hclass = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, numOfProps);
hclass->SetLayout(thread, layout);
hclass->SetNumberOfProps(numOfProps);
} else {
// dictionary mode
hclass = factory->NewEcmaHClass(JSFunction::SIZE, JSType::JS_OBJECT, 0); // without in-obj
hclass->SetIsDictionaryMode(true);
hclass->SetNumberOfProps(0);
}
hclass->SetTS(true);
return hclass;
}
JSHandle<JSHClass> TSHClassGenerator::CreatePHClass(const JSThread *thread,
const JSHandle<TSClassType> &classType) const
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<TSObjectType> prototypeType(thread, classType->GetPrototypeType());
JSHandle<TSObjLayoutInfo> tsLayout(thread, prototypeType->GetObjLayoutInfo());
uint32_t numOfProps = tsLayout->GetNumOfProperties();
JSHandle<JSHClass> hclass;
// There is only function information in abc, which needs to be brought up to the front for processing.
// Other fields should be collected first and then optimized to the end.
// Please note that there may be a problem with order in this way
if (LIKELY(numOfProps <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
JSHandle<JSTaggedValue> ctor = globalConst->GetHandledConstructorString();
CVector<std::pair<JSHandle<JSTaggedValue>, GlobalTSTypeRef>> sortedPrototype {{ctor, GlobalTSTypeRef()}};
CUnorderedMap<std::string, uint32_t> keysMap;
for (uint32_t index = 0; index < numOfProps; ++index) {
JSHandle<JSTaggedValue> key(thread, tsLayout->GetKey(index));
auto value = GlobalTSTypeRef(tsLayout->GetTypeId(index).GetInt());
// Usually, abstract methods in abstract class have no specific implementation,
// and method signatures will be added after class scope.
// Strategy: ignore abstract method, and rearrange the order of method signature to be at the end.
bool isSame = JSTaggedValue::SameValue(key, ctor);
bool isAbs = tsManager->IsAbstractMethod(value);
if (!isSame && !isAbs) {
bool isSign = tsManager->IsMethodSignature(value);
if (isSign) {
continue;
}
std::string keyStr = EcmaStringAccessor(key.GetTaggedValue()).ToStdString();
auto it = keysMap.find(keyStr);
if (it != keysMap.end()) {
sortedPrototype[it->second] = std::make_pair(key, value);
continue;
}
keysMap[keyStr] = sortedPrototype.size();
sortedPrototype.emplace_back(std::make_pair(key, value));
}
}
uint32_t keysLen = sortedPrototype.size();
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(keysLen);
for (uint32_t index = 0; index < keysLen; ++index) {
key.Update(sortedPrototype[index].first);
ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
if (tsManager->IsGetterSetterFunc(sortedPrototype[index].second)) {
attributes.SetIsAccessor(true);
}
attributes.SetIsInlinedProps(true);
attributes.SetRepresentation(Representation::NONE);
attributes.SetOffset(index);
layout->AddKey(thread, index, key.GetTaggedValue(), attributes);
}
hclass = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, keysLen);
hclass->SetLayout(thread, layout);
hclass->SetNumberOfProps(keysLen);
} else {
// dictionary mode
hclass = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, 0); // without in-obj
hclass->SetIsDictionaryMode(true);
hclass->SetNumberOfProps(0);
}
hclass->SetTS(true);
hclass->SetClassPrototype(true);
hclass->SetIsPrototype(true);
return hclass;
}
JSHandle<JSHClass> TSHClassGenerator::CreateCHClass(const JSThread *thread,
const JSHandle<TSClassType> &classType) const
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<TSObjectType> constructorType(thread, classType->GetConstructorType());
JSHandle<TSObjLayoutInfo> tsLayout(thread, constructorType->GetObjLayoutInfo());
uint32_t numOfProps = tsLayout->GetNumOfProperties() + ClassInfoExtractor::STATIC_RESERVED_LENGTH;
JSHandle<JSHClass> hclass;
if (LIKELY(numOfProps <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(numOfProps);
std::vector<JSHandle<JSTaggedValue>> noFunc;
int functionCount = -1;
for (uint32_t index = 0; index < numOfProps; ++index) {
JSTaggedValue tsPropKey;
PropertyAttributes attributes;
switch (index) {
case ClassInfoExtractor::LENGTH_INDEX:
attributes = PropertyAttributes::Default(false, false, true);
tsPropKey = globalConst->GetLengthString();
functionCount++;
break;
case ClassInfoExtractor::NAME_INDEX:
attributes = PropertyAttributes::Default(false, false, true);
tsPropKey = globalConst->GetNameString();
functionCount++;
break;
case ClassInfoExtractor::PROTOTYPE_INDEX:
attributes = PropertyAttributes::DefaultAccessor(false, false, false);
tsPropKey = globalConst->GetPrototypeString();
functionCount++;
break;
default:
attributes = PropertyAttributes::Default(true, false, true);
tsPropKey = tsLayout->GetKey(index - ClassInfoExtractor::STATIC_RESERVED_LENGTH);
JSTaggedValue typeId = tsLayout->GetTypeId(index - ClassInfoExtractor::STATIC_RESERVED_LENGTH);
GlobalTSTypeRef gt(static_cast<uint32_t>(typeId.GetNumber()));
if (!tsManager->IsFunctionTypeKind(gt)) {
noFunc.emplace_back(JSHandle<JSTaggedValue>(thread, tsPropKey));
continue;
}
if (tsManager->IsGetterSetterFunc(gt)) {
attributes.SetIsAccessor(true);
}
functionCount++;
break;
}
ASSERT_PRINT(JSTaggedValue::IsPropertyKey(JSHandle<JSTaggedValue>(thread, tsPropKey)),
"Key is not a property key");
attributes.SetIsInlinedProps(true);
attributes.SetRepresentation(Representation::NONE);
attributes.SetOffset(functionCount);
layout->AddKey(thread, functionCount, tsPropKey, attributes);
}
for (uint32_t index = 1; index <= noFunc.size(); index++) {
PropertyAttributes attributes = PropertyAttributes::Default();
attributes.SetIsInlinedProps(true);
attributes.SetRepresentation(Representation::NONE);
attributes.SetOffset(index + functionCount);
layout->AddKey(thread, index + functionCount, noFunc[index - 1].GetTaggedValue(), attributes);
}
hclass = factory->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, numOfProps);
hclass->SetLayout(thread, layout);
hclass->SetNumberOfProps(numOfProps);
} else {
// dictionary mode
hclass = factory->NewEcmaHClass(JSFunction::SIZE, JSType::JS_FUNCTION, 0); // without in-obj
hclass->SetIsDictionaryMode(true);
hclass->SetNumberOfProps(0);
}
hclass->SetTS(true);
hclass->SetClassConstructor(true);
hclass->SetConstructor(true);
return hclass;
}
} // namespace panda::ecmascript::kungfu

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2023 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_TS_HCLASS_GENERATOR_H
#define ECMASCRIPT_COMPILER_TS_HCLASS_GENERATOR_H
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
class TSHClassGenerator {
public:
explicit TSHClassGenerator(TSManager *tsManager): tsManager_(tsManager) {};
~TSHClassGenerator() = default;
void GenerateTSHClasses() const;
private:
void RecursiveGenerate(const JSHandle<TSClassType> &classType) const;
JSHandle<JSHClass> Generate(const JSHandle<TSClassType> &classType) const;
enum class Kind : uint8_t {
INSTANCE = 0,
PROTOTYPE,
CONSTRUCTOR,
};
JSHandle<JSHClass> CreateHClass(const JSThread *thread, const JSHandle<TSClassType> &classType, Kind kind) const;
JSHandle<JSHClass> CreateIHClass(const JSThread *thread, const JSHandle<TSClassType> &classType) const;
JSHandle<JSHClass> CreatePHClass(const JSThread *thread, const JSHandle<TSClassType> &classType) const;
JSHandle<JSHClass> CreateCHClass(const JSThread *thread, const JSHandle<TSClassType> &classType) const;
inline const std::set<GlobalTSTypeRef>& GetCollectedGT() const
{
return tsManager_->GetCollectedGT();
}
TSManager *tsManager_ {nullptr};
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_TS_HCLASS_GENERATOR_H

View File

@ -18,6 +18,7 @@
#include "ecmascript/compiler/combined_pass_visitor.h"
#include "ecmascript/compiler/pass_manager.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/ecma_string-inl.h"
namespace panda::ecmascript::kungfu {

View File

@ -1,336 +0,0 @@
/*
* Copyright (c) 2023 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/type_inference/initialization_analysis.h"
#include "ecmascript/ts_types/ts_type_accessor.h"
namespace panda::ecmascript::kungfu {
void InitializationAnalysis::Run()
{
if (classType_.IsAnyType()) {
return;
}
CollectThisEscapedInfo(thisObject_);
std::vector<GateRef> gateList;
circuit_->GetAllGates(gateList);
for (const auto &gate : gateList) {
auto op = acc_.GetOpCode(gate);
if (op == OpCode::JS_BYTECODE) {
Analyse(gate);
}
}
MarkHasAnalysedInitialization();
if (IsLogEnabled()) {
Print();
}
}
void InitializationAnalysis::Analyse(GateRef gate)
{
ASSERT(acc_.GetOpCode(gate) == OpCode::JS_BYTECODE);
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8: {
CollectInitializationType(gate, ThisUsage::INDEFINITE_THIS);
CollectInitializationInfo(gate, ThisUsage::INDEFINITE_THIS);
break;
}
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
case EcmaOpcode::STTHISBYNAME_IMM16_ID16: {
CollectInitializationType(gate, ThisUsage::DEFINITE_THIS);
CollectInitializationInfo(gate, ThisUsage::DEFINITE_THIS);
break;
}
case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8:
case EcmaOpcode::SUPERCALLARROWRANGE_IMM8_IMM8_V8:
case EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8:
case EcmaOpcode::SUPERCALLSPREAD_IMM8_V8: {
MarkSuperClass();
CollectThisEscapedInfo(gate);
break;
}
default: {
break;
}
}
}
void InitializationAnalysis::CollectInitializationType(GateRef gate, ThisUsage thisUsage)
{
GateRef value = acc_.GetValueIn(gate, 3); // 3: index of value
GateType valueType = acc_.GetGateType(value);
if (valueType.IsAnyType()) {
return;
}
if (thisUsage == ThisUsage::INDEFINITE_THIS) {
GateRef receiver = acc_.GetValueIn(gate, 2); // 2: index of receiver
GateType receiverType = acc_.GetGateType(receiver);
auto receiverGT = receiverType.GetGTRef();
if (tsManager_->IsClassInstanceTypeKind(receiverType)) {
receiverGT = tsManager_->GetClassType(receiverType);
}
if (!CheckIsThisObject(receiver) && receiverGT != classType_.GetGTRef()) {
return;
}
}
uint16_t index = acc_.GetConstantValue(acc_.GetValueIn(gate, 1)); // 1: stringId
auto methodOffset = acc_.TryGetMethodOffset(gate);
JSTaggedValue propKey = tsManager_->GetStringFromConstantPool(methodOffset, index);
if (valueType.IsNumberType()) {
valueType = GateType::NumberType();
}
TSTypeAccessor typeAccessor(tsManager_, classType_);
typeAccessor.UpdateNonStaticProp(propKey, valueType.GetGTRef());
}
void InitializationAnalysis::CollectInitializationInfo(GateRef gate, ThisUsage thisUsage)
{
if (thisUsage == ThisUsage::INDEFINITE_THIS) {
GateRef receiver = acc_.GetValueIn(gate, 2); // 2: index of receiver
if (!CheckIsThisObject(receiver)) {
return;
}
}
uint16_t index = acc_.GetConstantValue(acc_.GetValueIn(gate, 1)); // 1: stringId
if (!CheckSimpleCFG(gate, index)) {
return;
}
auto methodOffset = acc_.TryGetMethodOffset(gate);
JSTaggedValue propKey = tsManager_->GetStringFromConstantPool(methodOffset, index);
TSTypeAccessor typeAccessor(tsManager_, classType_);
typeAccessor.MarkPropertyInitialized(propKey);
}
bool InitializationAnalysis::CheckIsThisObject(GateRef receiver) const
{
return IsThisFromArg(receiver) || IsThisFromSuperCall(receiver);
}
bool InitializationAnalysis::IsThisFromSuperCall(GateRef gate) const
{
auto op = acc_.GetOpCode(gate);
if (op != OpCode::JS_BYTECODE) {
return false;
}
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8:
case EcmaOpcode::SUPERCALLARROWRANGE_IMM8_IMM8_V8:
case EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8:
case EcmaOpcode::SUPERCALLSPREAD_IMM8_V8: {
return true;
}
default: {
break;
}
}
return false;
}
bool InitializationAnalysis::CheckSimpleCFG(GateRef gate, const uint16_t index) const
{
while (!acc_.IsStateRoot(gate)) {
if (CheckSimpleGate(gate, index)) {
return false;
}
gate = acc_.GetState(gate);
}
return true;
}
bool InitializationAnalysis::CheckSimpleGate(GateRef gate, const uint16_t index) const
{
OpCode opCode = acc_.GetOpCode(gate);
switch (opCode) {
case OpCode::IF_TRUE:
case OpCode::IF_FALSE: {
return true;
}
case OpCode::JS_BYTECODE: {
return CheckSimpleJSGate(gate, index);
}
default: {
break;
}
}
return false;
}
bool InitializationAnalysis::CheckSimpleJSGate(GateRef gate, const uint16_t index) const
{
ASSERT(acc_.GetOpCode(gate) == OpCode::JS_BYTECODE);
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
case EcmaOpcode::LDOBJBYNAME_IMM8_ID16:
case EcmaOpcode::LDOBJBYNAME_IMM16_ID16: {
return CheckLdObjByName(gate, index, ThisUsage::INDEFINITE_THIS);
}
case EcmaOpcode::LDTHISBYNAME_IMM8_ID16:
case EcmaOpcode::LDTHISBYNAME_IMM16_ID16: {
return CheckLdObjByName(gate, index, ThisUsage::DEFINITE_THIS);
}
case EcmaOpcode::LDTHISBYVALUE_IMM8:
case EcmaOpcode::LDTHISBYVALUE_IMM16: {
return true;
}
case EcmaOpcode::LDOBJBYVALUE_IMM8_V8:
case EcmaOpcode::LDOBJBYVALUE_IMM16_V8:
case EcmaOpcode::LDOBJBYINDEX_IMM8_IMM16:
case EcmaOpcode::LDOBJBYINDEX_IMM16_IMM16:
case EcmaOpcode::WIDE_LDOBJBYINDEX_PREF_IMM32: {
return CheckLdObjByIndexOrValue(gate);
}
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8:
case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM16: {
return false;
}
default: {
return CheckThisAsValueIn(gate);
}
}
return false;
}
bool InitializationAnalysis::CheckLdObjByName(GateRef gate, const uint16_t index, ThisUsage thisUsage) const
{
if (thisUsage == ThisUsage::INDEFINITE_THIS) {
GateRef receiver = acc_.GetValueIn(gate, 2); // 2: index of receiver
if (!CheckIsThisObject(receiver)) {
return false;
}
}
auto constData = acc_.GetValueIn(gate, 1); // 1: stringId
uint16_t stringId = acc_.GetConstantValue(constData);
return stringId == index;
}
bool InitializationAnalysis::CheckLdObjByIndexOrValue(GateRef gate) const
{
GateRef receiver = acc_.GetValueIn(gate, 1); // 1: index of receiver
return CheckIsThisObject(receiver);
}
void InitializationAnalysis::MarkSuperClass()
{
TSTypeAccessor typeAccessor(tsManager_, classType_);
typeAccessor.MarkClassHasSuperCallInConstructor();
}
void InitializationAnalysis::StoreThisObject()
{
ArgumentAccessor argAcc(circuit_);
thisObject_ = argAcc.GetCommonArgGate(CommonArgIdx::THIS_OBJECT);
auto type = acc_.GetGateType(thisObject_);
if (tsManager_->IsClassInstanceTypeKind(type)) {
classType_ = GateType(tsManager_->GetClassType(type));
}
}
bool InitializationAnalysis::CheckThisAsValueIn(GateRef gate) const
{
ASSERT(acc_.GetOpCode(gate) == OpCode::JS_BYTECODE);
uint32_t numIns = acc_.GetNumValueIn(gate);
for (uint32_t i = 0; i < numIns; ++i) {
if (CheckIsThisObject(acc_.GetValueIn(gate, i))) {
return true;
}
}
return false;
}
void InitializationAnalysis::CollectThisEscapedInfo(GateRef gate)
{
ASSERT(gate != Circuit::NullGate());
std::vector<GateRef> valueUses;
acc_.GetValueUses(gate, valueUses);
for (const auto useGate : valueUses) {
if (!HasEscapedThis(useGate)) {
continue;
}
TSTypeAccessor typeAccessor(tsManager_, classType_);
typeAccessor.MarkClassHasEscapedThisInConstructor();
return;
}
}
bool InitializationAnalysis::HasEscapedThis(GateRef gate) const
{
if (acc_.GetOpCode(gate) != OpCode::JS_BYTECODE) {
return false;
}
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8:
case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM16: {
return false;
}
default: {
break;
}
}
return true;
}
void InitializationAnalysis::MarkHasAnalysedInitialization()
{
TSTypeAccessor typeAccessor(tsManager_, classType_);
typeAccessor.MarkClassHasAnalysedInitialization();
}
bool InitializationAnalysis::CheckCall() const
{
TSTypeAccessor typeAccessor(tsManager_, classType_);
return typeAccessor.ClassHasEscapedThisInConstructor();
}
void InitializationAnalysis::Print() const
{
LOG_COMPILER(INFO) << " ";
LOG_COMPILER(INFO) << "\033[34m" << "================="
<< " After initialization analysis "
<< "[" << GetMethodName() << "] "
<< "=================" << "\033[0m";
TSTypeAccessor typeAccessor(tsManager_, classType_);
LOG_COMPILER(INFO) << "In the constructor of class " << typeAccessor.GetClassTypeName()
<< " of record " << std::string(recordName_)
<< ", the following propertiess will be initialized.";
LOG_COMPILER(INFO) << (typeAccessor.GetInitializedProperties());
if (typeAccessor.ClassHasEscapedThisInConstructor()) {
LOG_COMPILER(INFO) << "This-object will be called by some functions in the constructor.";
}
LOG_COMPILER(INFO) << "\033[34m" << "=========================== End ===========================" << "\033[0m";
}
} // namespace panda::ecmascript

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2023 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_TYPE_INFERENCE_INITIALIZATION_ANALYSIS_H
#define ECMASCRIPT_COMPILER_TYPE_INFERENCE_INITIALIZATION_ANALYSIS_H
#include "ecmascript/compiler/argument_accessor.h"
#include "ecmascript/compiler/circuit.h"
#include "ecmascript/compiler/gate_accessor.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
enum class ThisUsage : uint8_t {
INDEFINITE_THIS = 0,
DEFINITE_THIS,
};
class InitializationAnalysis {
public:
InitializationAnalysis(Circuit *circuit, TSManager *tsManager, const CString &recordName,
const std::string &name, bool enableLog)
: tsManager_(tsManager), circuit_(circuit), acc_(circuit), recordName_(recordName),
methodName_(name), enableLog_(enableLog)
{
StoreThisObject();
}
~InitializationAnalysis() = default;
void Run();
private:
inline bool IsLogEnabled() const
{
return enableLog_;
}
inline const std::string &GetMethodName() const
{
return methodName_;
}
inline bool IsThisFromArg(GateRef gate) const
{
return gate == thisObject_;
}
void Analyse(GateRef gate);
void CollectInitializationInfo(GateRef gate, ThisUsage thisUsage);
void CollectInitializationType(GateRef gate, ThisUsage thisUsage);
bool CheckIsThisObject(GateRef receiver) const;
void MarkSuperClass();
bool CheckSimpleCFG(GateRef gate, const uint16_t index) const;
bool CheckSimpleGate(GateRef gate, const uint16_t index) const;
bool CheckSimpleJSGate(GateRef gate, const uint16_t index) const;
bool CheckLdObjByName(GateRef gate, const uint16_t index, ThisUsage thisUsage) const;
bool CheckLdObjByIndexOrValue(GateRef gate) const;
bool CheckCall() const;
void StoreThisObject();
bool CheckThisAsValueIn(GateRef gate) const;
void CollectThisEscapedInfo(GateRef gate);
bool HasEscapedThis(GateRef gate) const;
void MarkHasAnalysedInitialization();
bool IsThisFromSuperCall(GateRef gate) const;
void Print() const;
TSManager *tsManager_ {nullptr};
Circuit *circuit_ {nullptr};
GateAccessor acc_;
GateRef thisObject_ {Circuit::NullGate()};
GateType classType_ {GateType::AnyType()};
const CString &recordName_;
const std::string &methodName_;
bool enableLog_ {false};
};
} // panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_TYPE_INFERENCE_INITIALIZATION_ANALYSIS_H

View File

@ -14,7 +14,6 @@
*/
#include "ecmascript/compiler/type_inference/pgo_type_infer.h"
#include "ecmascript/ts_types/ts_type_accessor.h"
#include "ecmascript/compiler/bytecode_circuit_builder.h"
namespace panda::ecmascript::kungfu {
@ -28,10 +27,6 @@ void PGOTypeInfer::Run()
RunTypeInfer(gate);
}
}
if (IsLogEnabled()) {
Print();
}
}
void PGOTypeInfer::RunTypeInfer(GateRef gate)
@ -45,19 +40,6 @@ void PGOTypeInfer::RunTypeInfer(GateRef gate)
case EcmaOpcode::LDTHISBYNAME_IMM16_ID16:
InferLdObjByName(gate);
break;
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
InferStObjByName(gate, false);
break;
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
InferStObjByName(gate, true);
break;
case EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8:
case EcmaOpcode::STOWNBYNAME_IMM16_ID16_V8:
InferStOwnByName(gate);
break;
case EcmaOpcode::STOWNBYINDEX_IMM8_V8_IMM16:
case EcmaOpcode::STOWNBYINDEX_IMM16_V8_IMM16:
InferStOwnByIndex(gate);
@ -83,112 +65,20 @@ void PGOTypeInfer::RunTypeInfer(GateRef gate)
}
}
void PGOTypeInfer::Print() const
{
LOG_COMPILER(INFO) << " ";
LOG_COMPILER(INFO) << "\033[34m" << "================="
<< " After pgo type infer "
<< "[" << GetMethodName() << "] "
<< "=================" << "\033[0m";
for (const auto &value : profiler_.datas) {
std::string log("\"id\"=" + std::to_string(acc_.GetId(value.gate)) +
", \"bytecode\"=\"" + GetEcmaOpcodeStr(acc_.GetByteCodeOpcode(value.gate)) + "\", ");
log += "TSType: [type:" + tsManager_->GetTypeStr(value.tsType) + ", "
+ "moduleId: " + std::to_string(value.tsType.GetGTRef().GetModuleId()) + ", "
+ "localId: " + std::to_string(value.tsType.GetGTRef().GetLocalId()) + "], ";
log += "PGOTypes: [";
for (auto pgoType : value.pgoTypes) {
log += "[type:" + tsManager_->GetTypeStr(pgoType) + ", "
+ "moduleId: " + std::to_string(pgoType.GetGTRef().GetModuleId()) + ", "
+ "localId: " + std::to_string(pgoType.GetGTRef().GetLocalId()) + "], ";
}
log += "] InferTypes: [";
for (auto type : value.inferTypes) {
log += "[type:" + tsManager_->GetTypeStr(type) + ", "
+ "moduleId: " + std::to_string(type.GetGTRef().GetModuleId()) + ", "
+ "localId: " + std::to_string(type.GetGTRef().GetLocalId()) + "]";
}
log += "]";
LOG_COMPILER(INFO) << std::dec << log;
}
LOG_COMPILER(INFO) << "\033[34m" << "=========================== End ===========================" << "\033[0m";
}
void PGOTypeInfer::AddProfiler(GateRef gate, GateType tsType, PGORWOpType pgoType, ChunkSet<GateType>& inferTypes)
{
if (enableLog_) {
Profiler::Value value;
value.gate = gate;
value.tsType = tsType;
for (uint32_t i = 0; i < pgoType.GetCount(); i++) {
value.pgoTypes.emplace_back(tsManager_->GetGateTypeByPt(pgoType.GetObjectInfo(i).GetProfileType()));
}
for (GateType type : inferTypes) {
value.inferTypes.emplace_back(type);
}
profiler_.datas.emplace_back(value);
}
}
void PGOTypeInfer::InferLdObjByName(GateRef gate)
{
if (!builder_->ShouldPGOTypeInfer(gate)) {
return;
}
GateRef constData = acc_.GetValueIn(gate, 1); // 1: valueIn 1
uint16_t propIndex = acc_.GetConstantValue(constData);
GateRef receiver = acc_.GetValueIn(gate, 2); // 2: acc or this object
UpdateTypeForRWOp(gate, receiver, propIndex);
TrySetElementsKind(gate);
}
void PGOTypeInfer::InferStObjByName(GateRef gate, bool isThis)
{
if (!builder_->ShouldPGOTypeInfer(gate)) {
return;
}
GateRef constData = acc_.GetValueIn(gate, 1); // 1: valueIn 1
uint16_t propIndex = acc_.GetConstantValue(constData);
GateRef receiver = Circuit::NullGate();
if (isThis) {
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
receiver = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT);
} else {
// 4: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 4);
receiver = acc_.GetValueIn(gate, 2); // 2: receiver
}
UpdateTypeForRWOp(gate, receiver, propIndex);
}
void PGOTypeInfer::InferStOwnByName(GateRef gate)
{
if (!builder_->ShouldPGOTypeInfer(gate)) {
return;
}
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
GateRef constData = acc_.GetValueIn(gate, 0);
uint16_t propIndex = acc_.GetConstantValue(constData);
GateRef receiver = acc_.GetValueIn(gate, 1);
UpdateTypeForRWOp(gate, receiver, propIndex);
}
void PGOTypeInfer::InferStOwnByIndex(GateRef gate)
{
if (!builder_->ShouldPGOTypeInfer(gate)) {
return;
}
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
GateRef receiver = acc_.GetValueIn(gate, 0);
UpdateTypeForRWOp(gate, receiver);
TrySetElementsKind(gate);
TrySetTransitionElementsKind(gate);
TrySetOnHeapMode(gate);
@ -214,7 +104,6 @@ void PGOTypeInfer::InferAccessObjByValue(GateRef gate)
if (!builder_->ShouldPGOTypeInfer(gate)) {
return;
}
GateRef receiver = Circuit::NullGate();
GateRef propKey = Circuit::NullGate();
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
switch (ecmaOpcode) {
@ -222,57 +111,24 @@ void PGOTypeInfer::InferAccessObjByValue(GateRef gate)
case EcmaOpcode::LDOBJBYVALUE_IMM16_V8:
case EcmaOpcode::STOBJBYVALUE_IMM8_V8_V8:
case EcmaOpcode::STOBJBYVALUE_IMM16_V8_V8:
receiver = acc_.GetValueIn(gate, 1); // 1: receiver
propKey = acc_.GetValueIn(gate, 2); // 2: the third parameter
break;
case EcmaOpcode::LDTHISBYVALUE_IMM8:
case EcmaOpcode::LDTHISBYVALUE_IMM16:
case EcmaOpcode::STTHISBYVALUE_IMM8_V8:
case EcmaOpcode::STTHISBYVALUE_IMM16_V8:
receiver = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT);
propKey = acc_.GetValueIn(gate, 1);
break;
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
UpdateTypeForRWOp(gate, receiver);
TrySetPropKeyKind(gate, propKey);
TrySetElementsKind(gate);
TrySetTransitionElementsKind(gate);
TrySetOnHeapMode(gate);
}
void PGOTypeInfer::UpdateTypeForRWOp(GateRef gate, GateRef receiver, uint32_t propIndex)
{
GateType tsType = acc_.GetGateType(receiver);
auto pgoTypes = acc_.TryGetPGOType(gate);
const PGORWOpType *pgoRwTypes = pgoTypes.GetPGORWOpType();
CollectedType types(chunk_);
helper_.CollectGateType(types, tsType, *pgoRwTypes);
// polymorphism is not currently supported,
// all types must in the same kind
if (!types.AllInSameKind()) {
return;
}
// polymorphism is not currently supported
JSTaggedValue prop = JSTaggedValue::Undefined();
if (propIndex != INVALID_INDEX) {
auto methodOffset = acc_.TryGetMethodOffset(gate);
prop = compilationEnv_->GetStringFromConstantPool(methodOffset, propIndex);
}
ChunkSet<GateType> inferTypes = helper_.GetInferTypes(chunk_, types, prop);
AddProfiler(gate, tsType, *pgoRwTypes, inferTypes);
if (!IsMonoTypes(inferTypes)) {
return;
}
acc_.SetGateType(receiver, *inferTypes.begin());
}
void PGOTypeInfer::TrySetElementsKind(GateRef gate)
{
auto kinds = builder_->GetElementsKindsForUser(gate);

View File

@ -16,20 +16,17 @@
#ifndef ECMASCRIPT_COMPILER_TYPE_INFERENCE_PGO_TYPE_INFER_H
#define ECMASCRIPT_COMPILER_TYPE_INFERENCE_PGO_TYPE_INFER_H
#include "ecmascript/compiler/type_inference/pgo_type_infer_helper.h"
#include "ecmascript/compiler/gate_accessor.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "ecmascript/compiler/argument_accessor.h"
#include "ecmascript/compiler/gate_accessor.h"
namespace panda::ecmascript::kungfu {
struct CollectedType;
class PGOTypeInfer {
public:
PGOTypeInfer(Circuit *circuit, TSManager *tsManager, PGOTypeManager *ptManager, BytecodeCircuitBuilder *builder,
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), compilationEnv_(env) {}
PGOTypeInfer(Circuit *circuit, BytecodeCircuitBuilder *builder, const std::string &name,
Chunk *chunk, bool enableLog)
: circuit_(circuit), acc_(circuit), argAcc_(circuit), builder_(builder), methodName_(name),
enableLog_(enableLog), profiler_(chunk) {}
~PGOTypeInfer() = default;
void Run();
@ -70,33 +67,22 @@ private:
void RunTypeInfer(GateRef gate);
void InferLdObjByName(GateRef gate);
void InferStObjByName(GateRef gate, bool isThis);
void InferStOwnByName(GateRef gate);
void InferStOwnByIndex(GateRef gate);
void InferAccessObjByValue(GateRef gate);
void InferCreateArray(GateRef gate);
void UpdateTypeForRWOp(GateRef gate, GateRef receiver, uint32_t propIdx = INVALID_INDEX);
void TrySetElementsKind(GateRef gate);
void TrySetTransitionElementsKind(GateRef gate);
void TrySetPropKeyKind(GateRef gate, GateRef propKey);
void TrySetOnHeapMode(GateRef gate);
void Print() const;
void AddProfiler(GateRef gate, GateType tsType, PGORWOpType pgoType, ChunkSet<GateType>& inferTypes);
Circuit *circuit_ {nullptr};
GateAccessor acc_;
ArgumentAccessor argAcc_;
TSManager *tsManager_ {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

@ -1,251 +0,0 @@
/*
* Copyright (c) 2023 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/type_inference/pgo_type_infer_helper.h"
#include "ecmascript/js_hclass-inl.h"
#include "ecmascript/ts_types/ts_type_accessor.h"
namespace panda::ecmascript::kungfu {
bool ClassTypeStrategy::CheckAndInsert(CollectedType &types, const GateType &type, TSManager *tsManager)
{
if (tsManager->IsUserDefinedClassTypeKind(type)) {
int hclassIndex = tsManager->GetConstructorHClassIndexByClassGateType(type);
if (hclassIndex == -1) {
return true;
}
types.classTypes.insert(type);
return true;
}
return false;
}
void ClassTypeStrategy::Merge(ChunkSet<GateType> &inferTypes, CollectedType &types,
[[maybe_unused]] TSManager *tsManager)
{
for (GateType type : types.classTypes) {
inferTypes.insert(type);
}
}
bool ClassInstanceTypeStrategy::CheckAndInsert(CollectedType &types, const GateType &type, TSManager *tsManager)
{
if (tsManager->IsClassInstanceTypeKind(type) &&
tsManager->IsUserDefinedClassTypeKind(tsManager->GetClassType(type))) {
int hclassIndex = tsManager->GetHClassIndexByInstanceGateType(type);
if (hclassIndex == -1) {
return true;
}
JSHClass *hclass = JSHClass::Cast(tsManager->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
if (hclass->HasTSSubtyping()) {
GlobalTSTypeRef instanceGT = type.GetGTRef();
GateType classType = GateType(tsManager->GetClassType(instanceGT));
types.classInstanceTypes.insert(classType);
}
return true;
}
return false;
}
void ClassInstanceTypeStrategy::Merge(ChunkSet<GateType> &inferTypes, CollectedType &types, TSManager *tsManager)
{
for (GateType type : types.classInstanceTypes) {
GlobalTSTypeRef gt = type.GetGTRef();
GlobalTSTypeRef instanceGT = tsManager->CreateClassInstanceType(gt);
inferTypes.insert(GateType(instanceGT));
}
}
bool BuiltinTypeStrategy::CheckAndInsert(CollectedType &types, const GateType &type, TSManager *tsManager)
{
if (tsManager->IsValidTypedArrayType(type)) {
types.builtinTypes.insert(type);
return true;
}
return false;
}
void BuiltinTypeStrategy::Merge(ChunkSet<GateType> &inferTypes, CollectedType &types,
[[maybe_unused]] TSManager *tsManager)
{
for (GateType type : types.builtinTypes) {
inferTypes.insert(type);
}
}
bool OtherTypeStrategy::CheckAndInsert(CollectedType &types, const GateType &type, [[maybe_unused]]TSManager *tsManager)
{
if (!type.IsAnyType()) {
types.otherTypes.insert(type);
return true;
}
return false;
}
void OtherTypeStrategy::Merge(ChunkSet<GateType> &inferTypes, CollectedType &types,
[[maybe_unused]] TSManager *tsManager)
{
for (GateType type : types.otherTypes) {
inferTypes.insert(type);
}
}
void PGOTypeInferHelper::CollectGateType(CollectedType &types, GateType tsType, PGORWOpType pgoTypes)
{
// for static TS uinon type
if (tsManager_->IsUnionTypeKind(tsType)) {
JSHandle<TSUnionType> unionType(tsManager_->GetTSType(tsType.GetGTRef()));
TaggedArray *components = TaggedArray::Cast(unionType->GetComponents().GetTaggedObject());
uint32_t length = components->GetLength();
for (uint32_t i = 0; i < length; ++i) {
GlobalTSTypeRef gt(components->Get(i).GetInt());
CheckAndInsert(types, GateType(gt));
}
} else {
CheckAndInsert(types, tsType);
}
// for pgo type
for (uint32_t i = 0; i < pgoTypes.GetCount(); i++) {
ProfileType profileType = pgoTypes.GetObjectInfo(i).GetProfileType();
GateType pgoType = tsManager_->GetGateTypeByPt(profileType);
if (tsManager_->IsClassTypeKind(pgoType) && !pgoTypes.GetObjectInfo(i).InConstructor()) {
pgoType = GateType(tsManager_->CreateClassInstanceType(pgoType));
}
CheckAndInsert(types, pgoType);
}
}
ChunkSet<GateType> PGOTypeInferHelper::GetInferTypes(Chunk *chunk, CollectedType &types, JSTaggedValue prop)
{
if (!prop.IsUndefined()) {
UpdateType(types, prop);
}
ChunkSet<GateType> inferTypes(chunk);
for (auto &strategy : strategies_) {
strategy->Merge(inferTypes, types, tsManager_);
}
return inferTypes;
}
void PGOTypeInferHelper::CheckAndInsert(CollectedType &types, GateType type)
{
for (auto &strategy : strategies_) {
if (strategy->CheckAndInsert(types, type, tsManager_)) {
return;
}
}
}
void PGOTypeInferHelper::UpdateType(CollectedType &types, JSTaggedValue prop)
{
ChunkSet<GateType> &classTypes = types.classTypes;
InferTypeForClass(classTypes, prop);
ChunkSet<GateType> &classInstanceTypes = types.classInstanceTypes;
InferTypeForClass(classInstanceTypes, prop);
ChunkSet<GateType> &builtinTypes = types.builtinTypes;
InferTypeForBuiltin(builtinTypes);
}
void PGOTypeInferHelper::InferTypeForClass(ChunkSet<GateType> &types, JSTaggedValue prop)
{
if (NoNeedUpdate(types)) {
return;
}
EliminateSubclassTypes(types);
ComputeCommonSuperClassTypes(types, prop);
}
void PGOTypeInferHelper::InferTypeForBuiltin(ChunkSet<GateType> &types)
{
if (NoNeedUpdate(types)) {
return;
}
std::set<GateType> deletedGates;
std::set<GlobalTSTypeRef> builtinGTSet;
for (GateType type : types) {
GlobalTSTypeRef classGT = tsManager_->GetClassType(type);
auto it = builtinGTSet.find(classGT);
if (it != builtinGTSet.end()) {
deletedGates.insert(type);
continue;
}
builtinGTSet.insert(classGT);
}
for (GateType gateType : deletedGates) {
types.erase(gateType);
}
}
void PGOTypeInferHelper::EliminateSubclassTypes(ChunkSet<GateType> &types)
{
std::set<GateType> deletedGates;
for (GateType type : types) {
if (deletedGates.find(type) != deletedGates.end()) {
continue;
}
std::stack<GateType> ancestors;
GateType curType = type;
do {
if (types.find(curType) != types.end()) {
ancestors.push(curType);
}
} while (tsManager_->GetSuperGateType(curType));
ancestors.pop(); // top type is alive
while (!ancestors.empty()) {
curType = ancestors.top();
ancestors.pop();
auto it = deletedGates.find(curType);
if (it != deletedGates.end()) {
deletedGates.insert(curType);
}
}
}
for (GateType gateType : deletedGates) {
types.erase(gateType);
}
}
void PGOTypeInferHelper::ComputeCommonSuperClassTypes(ChunkSet<GateType> &types, JSTaggedValue prop)
{
JSThread *thread = tsManager_->GetEcmaVM()->GetJSThread();
std::map<GateType, GateType> removeTypes;
for (GateType type : types) {
GateType curType = type;
GateType preType = type;
while (tsManager_->GetSuperGateType(curType)) {
JSHClass *ihc = JSHClass::Cast(tsManager_->GetTSHClass(curType).GetTaggedObject());
PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread, ihc, prop);
if (!plr.IsFound()) {
break;
}
preType = curType;
}
if (type != preType) {
removeTypes[type] = preType;
}
}
for (auto item : removeTypes) {
types.erase(item.first);
types.insert(item.second);
}
}
} // namespace panda::ecmascript

View File

@ -1,102 +0,0 @@
/*
* Copyright (c) 2023 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_TYPE_INFERENCE_PGO_TYPE_INFER_HELPER_H
#define ECMASCRIPT_COMPILER_TYPE_INFERENCE_PGO_TYPE_INFER_HELPER_H
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
#define TYPE_LIST(V) \
V(Class, class) \
V(ClassInstance, classInstance) \
V(Builtin, builtin) \
V(Other, other)
struct CollectedType {
explicit CollectedType(Chunk *chunk) : classTypes(chunk),
classInstanceTypes(chunk),
builtinTypes(chunk),
otherTypes(chunk) {}
bool AllInSameKind() const
{
uint8_t kind = classTypes.empty() ? 0 : 1;
kind += classInstanceTypes.empty() ? 0 : 1;
kind += builtinTypes.empty() ? 0 : 1;
kind += otherTypes.empty() ? 0 : 1;
return kind == 1;
}
#define DEFINE_TYPE_SET(V, name) \
ChunkSet<GateType> name##Types;
TYPE_LIST(DEFINE_TYPE_SET)
#undef DEFINE_TYPE_SET
};
class TypeStrategy {
public:
TypeStrategy() = default;
virtual ~TypeStrategy() = default;
virtual bool CheckAndInsert(CollectedType &types, const GateType &type, TSManager *tsManager) = 0;
virtual void Merge(ChunkSet<GateType> &inferTypes, CollectedType &types, TSManager *tsManager) = 0;
};
#define DEFINE_TYPE_STRATEGY_DERIVED_CLASS(name, ...) \
class name##TypeStrategy : public TypeStrategy { \
public: \
virtual bool CheckAndInsert(CollectedType &types, const GateType &type, TSManager *tsManager) override; \
virtual void Merge(ChunkSet<GateType> &inferTypes, CollectedType &types, TSManager *tsManager) override; \
};
TYPE_LIST(DEFINE_TYPE_STRATEGY_DERIVED_CLASS)
#undef DEFINE_TYPE_STRATEGY_DERIVED_CLASS
class PGOTypeInferHelper {
public:
PGOTypeInferHelper(TSManager *tsManager) : tsManager_(tsManager)
{
#define ADD_STRATEGY(name, ...) \
strategies_.push_back(std::make_unique<name##TypeStrategy>());
TYPE_LIST(ADD_STRATEGY)
#undef ADD_STRATEGY
}
~PGOTypeInferHelper() = default;
void CollectGateType(CollectedType &types, GateType tsType, PGORWOpType pgoTypes);
ChunkSet<GateType> GetInferTypes(Chunk *chunk, CollectedType &types, JSTaggedValue prop);
private:
inline bool NoNeedUpdate(const ChunkSet<GateType> &types) const
{
return types.size() <= 1;
}
void CheckAndInsert(CollectedType &types, GateType type);
void UpdateType(CollectedType &types, JSTaggedValue prop);
void InferTypeForClass(ChunkSet<GateType> &types, JSTaggedValue prop);
void EliminateSubclassTypes(ChunkSet<GateType> &types);
void ComputeCommonSuperClassTypes(ChunkSet<GateType> &types, JSTaggedValue prop);
void InferTypeForBuiltin(ChunkSet<GateType> &types);
TSManager *tsManager_ {nullptr};
std::vector<std::unique_ptr<TypeStrategy>> strategies_ {};
};
#undef TYPE_LIST
} // panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_TYPE_INFERENCE_PGO_TYPE_INFER_HELPER_H

View File

@ -20,7 +20,6 @@
#include "ecmascript/global_env.h"
#include "ecmascript/global_env_fields.h"
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/ts_types/ts_type_accessor.h"
namespace panda::ecmascript::kungfu {
ParamType TypeInfoAccessor::PGOSampleTypeToParamType() const
@ -397,21 +396,6 @@ InlineTypeInfoAccessor::InlineTypeInfoAccessor(
}
}
GlobalTSTypeRef InlineTypeInfoAccessor::GetAccessorFuncGT() const
{
GateType receiverType = acc_.GetGateType(receiver_);
receiverType = tsManager_->TryNarrowUnionType(receiverType);
GlobalTSTypeRef classInstanceGT = receiverType.GetGTRef();
GlobalTSTypeRef classGT = tsManager_->GetClassType(classInstanceGT);
TSTypeAccessor tsTypeAcc(tsManager_, classGT);
GateRef constData = acc_.GetValueIn(gate_, 1);
uint16_t propIndex = acc_.GetConstantValue(constData);
auto methodOffset = acc_.TryGetMethodOffset(gate_);
auto prop = compilationEnv_->GetStringFromConstantPool(methodOffset, propIndex);
GlobalTSTypeRef funcGT = tsTypeAcc.GetAccessorGT(prop, IsCallSetter());
return funcGT;
}
PropertyLookupResult InlineTypeInfoAccessor::GetAccessorPlr() const
{
GateRef constData = acc_.GetValueIn(gate_, 1);

View File

@ -22,7 +22,6 @@
#include "ecmascript/enum_conversion.h"
#include "ecmascript/global_index.h"
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "libpandafile/index_accessor.h"
namespace panda::ecmascript::kungfu {
@ -36,7 +35,6 @@ public:
{
pgoType_ = acc_.TryGetPGOType(gate);
// NOTICE-PGO: wx delete in part3
tsManager_ = compilationEnv_->GetTSManager();
ptManager_ = compilationEnv_->GetPTManager();
}
@ -62,7 +60,6 @@ protected:
GateRef gate_;
PGOTypeRef pgoType_;
// NOTICE-PGO: wx delete in part3
TSManager *tsManager_ {nullptr};
PGOTypeManager *ptManager_ {nullptr};
};
@ -204,12 +201,9 @@ public:
return GetCtorGT().IsBuiltinModule();
}
bool IsBuiltinConstructor(BuiltinTypeId type)
bool IsBuiltinConstructor([[maybe_unused]] BuiltinTypeId type)
{
if (compilationEnv_->IsJitCompiler()) {
return false;
}
return tsManager_->IsBuiltinConstructor(type, GetCtorGT());
return false; // NOTICE-PGO:: tsManager_->IsBuiltinConstructor(type, GetCtorGT());
}
private:
@ -239,14 +233,6 @@ public:
NO_COPY_SEMANTIC(SuperCallTypeInfoAccessor);
NO_MOVE_SEMANTIC(SuperCallTypeInfoAccessor);
bool IsClassTypeKind() const
{
if (compilationEnv_->IsJitCompiler()) {
return false;
}
return tsManager_->IsClassTypeKind(acc_.GetGateType(ctor_));
}
bool IsValidCallMethodId() const
{
return pgoType_.IsValidCallMethodId();
@ -625,14 +611,6 @@ public:
return false;
}
bool IsClassInstanceTypeKind() const
{
if (compilationEnv_->IsJitCompiler()) {
return false;
}
return tsManager_->IsClassInstanceTypeKind(acc_.GetGateType(receiver_));
}
bool IsValidCallMethodId() const
{
return pgoType_.IsValidCallMethodId();
@ -700,7 +678,6 @@ public:
private:
PropertyLookupResult GetAccessorPlr() const;
GlobalTSTypeRef GetAccessorFuncGT() const;
GateRef receiver_;
CallKind kind_ {CallKind::INVALID};
@ -766,14 +743,6 @@ public:
return receiver_;
}
GateType GetReceiverGateType() const
{
if (compilationEnv_->IsJitCompiler()) {
return acc_.GetGateType(receiver_);
}
return tsManager_->TryNarrowUnionType(acc_.GetGateType(receiver_));
}
protected:
Chunk *chunk_;
AccessMode mode_;
@ -1060,14 +1029,6 @@ public:
return types_[0].GetGlobalsId();
}
bool IsBuiltinInstanceType(BuiltinTypeId type) const
{
if (compilationEnv_->IsJitCompiler()) {
return false;
}
return tsManager_->IsBuiltinInstanceType(type, GetReceiverGateType());
}
OnHeapMode TryGetHeapMode() const
{
return acc_.TryGetOnHeapMode(gate_);

View File

@ -1,322 +0,0 @@
/*
* Copyright (c) 2022 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/type_recorder.h"
#include "ecmascript/compiler/ts_hclass_generator.h"
#include "ecmascript/jspandafile/type_literal_extractor.h"
#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
#include "ecmascript/pgo_profiler/pgo_profiler_layout.h"
#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
#include "ecmascript/ts_types/ts_type_parser.h"
namespace panda::ecmascript::kungfu {
using PGOHClassTreeDesc = pgo::PGOHClassTreeDesc;
using PGOType = pgo::PGOType;
using PGOObjectInfo = pgo::PGOObjectInfo;
TypeRecorder::TypeRecorder(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
TSManager *tsManager, const CString &recordName, PGOProfilerDecoder *decoder,
const MethodPcInfo &methodPCInfo, const Bytecodes *bytecodes, bool enableOptTrackField)
: argTypes_(methodLiteral->GetNumArgsWithCallField() + static_cast<size_t>(TypedArgIdx::NUM_OF_TYPED_ARGS),
GateType::AnyType()), decoder_(decoder), enableOptTrackField_(enableOptTrackField),
pcOffsets_(methodPCInfo.pcOffsets), bytecodes_(bytecodes)
{
TSHClassGenerator generator(tsManager);
if (jsPandaFile->HasTSTypes(recordName)) {
LoadTypes(jsPandaFile, methodLiteral, tsManager, recordName);
}
LoadTypesFromPGO(jsPandaFile, methodLiteral, recordName);
CreateTypesForPGO(jsPandaFile, methodLiteral, tsManager, recordName);
generator.GenerateTSHClasses();
}
void TypeRecorder::LoadTypes(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
TSManager *tsManager, const CString &recordName)
{
TSTypeParser typeParser(tsManager);
panda_file::File::EntityId fieldId = methodLiteral->GetMethodId();
uint32_t methodOffset = fieldId.GetOffset();
TypeAnnotationExtractor annoExtractor(jsPandaFile, methodOffset);
GlobalTSTypeRef funcGT = typeParser.CreateGT(jsPandaFile, recordName, annoExtractor.GetMethodTypeOffset());
GlobalTSTypeRef thisGT;
annoExtractor.EnumerateInstsAndTypes([this, &typeParser, &jsPandaFile, &recordName,
&thisGT, tsManager, methodOffset](const int32_t bcIdx, const uint32_t typeId) {
GlobalTSTypeRef gt = typeParser.CreateGT(jsPandaFile, recordName, typeId);
if (TypeNeedFilter(gt)) {
return;
}
TypeLocation loc(jsPandaFile, methodOffset, bcIdx);
CollectLiteralGT(tsManager, loc, gt);
// The type of a function is recorded as (-1, funcTypeId). If the function is a member of a class,
// the type of the class or its instance is is recorded as (-2, classTypeId). If it is a static
// member, the type id refers to the type of the class; otherwise, it links to the type of the
// instances of the class.
if (bcIdx == METHOD_ANNOTATION_THIS_TYPE_OFFSET) {
thisGT = gt;
return;
}
auto type = GateType(gt);
bcOffsetGtMap_.emplace(bcIdx, type);
});
const auto &methodList = typeParser.GetMethodList();
auto methodIter = methodList.find(methodOffset);
if (methodIter != methodList.end()) {
const auto &methodInfo = methodIter->second;
const auto &bcTypes = methodInfo.GetBCAndTypes();
for (const auto &pair : bcTypes) {
GlobalTSTypeRef gt = typeParser.CreateGT(jsPandaFile, recordName, pair.second);
// if the function type has already recorded in the next pc, we should skip it.
if (CheckTypeMarkForDefineFunc(pair.first)) {
continue;
}
bcOffsetGtMap_.emplace(pair.first, GateType(gt));
}
}
LoadArgTypes(tsManager, funcGT, thisGT);
}
void TypeRecorder::CollectLiteralGT(TSManager *tsManager, TypeLocation &loc, GlobalTSTypeRef gt)
{
int32_t bcIdx = loc.GetBcIdx();
if (bcIdx < 0 || bcIdx >= static_cast<int32_t>(pcOffsets_.size())) {
return;
}
while (bytecodes_->GetOpcode(pcOffsets_[bcIdx]) == EcmaOpcode::STA_V8) {
// bcIndex of literal marked in es2abc maybe in the next bc whose opcode should be sta.
bcIdx--;
loc.SetBcIdx(bcIdx);
}
EcmaOpcode ecmaOpcode = bytecodes_->GetOpcode(pcOffsets_[bcIdx]);
switch (ecmaOpcode) {
case BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8:
case BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8: {
if (tsManager->IsUserDefinedClassTypeKind(gt)) {
tsManager->InsertLiteralGTMap(loc, gt);
}
return;
}
case BytecodeInstruction::Opcode::CREATEOBJECTWITHBUFFER_IMM8_ID16:
case BytecodeInstruction::Opcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: {
if (tsManager->IsObjectTypeKind(gt)) {
tsManager->InsertLiteralGTMap(loc, gt);
}
return;
}
default:
return;
}
}
bool TypeRecorder::CheckTypeMarkForDefineFunc(uint32_t checkBc) const
{
// bcOffset of definefunc marked in es2abc maybe in the next bc whose opcode should be sta.
uint32_t staBc = checkBc + 1;
return bcOffsetGtMap_.find(staBc) != bcOffsetGtMap_.end() &&
staBc < pcOffsets_.size() && bytecodes_->GetOpcode(pcOffsets_[staBc]) == EcmaOpcode::STA_V8;
}
void TypeRecorder::LoadTypesFromPGO(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
const CString &recordName)
{
auto callback = [this] (uint32_t offset, const PGOType *type) {
if (type->IsScalarOpType()) {
bcOffsetPGOOpTypeMap_[offset] = reinterpret_cast<const PGOSampleType *>(type);
} else if (type->IsRwOpType()) {
bcOffsetPGORwTypeMap_[offset] = reinterpret_cast<const PGORWOpType *>(type);
} else if (type->IsDefineOpType()) {
bcOffsetPGODefOpTypeMap_[offset] = reinterpret_cast<const PGODefineOpType *>(type);
} else {
UNREACHABLE();
}
};
if (decoder_ != nullptr) {
decoder_->GetTypeInfo(jsPandaFile, recordName, methodLiteral, callback);
}
}
void TypeRecorder::CreateTypesForPGO(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
TSManager *tsManager, const CString &recordName)
{
TSTypeParser typeParser(tsManager);
uint32_t methodOffset = methodLiteral->GetMethodId().GetOffset();
const PGOBCInfo *bcInfo = tsManager->GetBytecodeInfoCollector()->GetPGOBCInfo();
bcInfo->IterateInfoAndType(methodOffset, [this, &typeParser, methodOffset, &recordName, &jsPandaFile, tsManager]
(const PGOBCInfo::Type type, const uint32_t bcIdx, const uint32_t bcOffset, const uint32_t cpIdx) {
EcmaOpcode ecmaOpcode = bytecodes_->GetOpcode(pcOffsets_[bcIdx]);
if (jsPandaFile->HasTSTypes(recordName) && Bytecodes::IsCallOp(ecmaOpcode)) {
auto it = bcOffsetPGOOpTypeMap_.find(bcOffset);
if (it == bcOffsetPGOOpTypeMap_.end()) {
return;
}
uint32_t callTargetMethodOffset = it->second->GetProfileType().GetId();
if (callTargetMethodOffset == 0) {
return;
}
// Recompiling the application ABC changes the content, and there may be a calltargetMethodOffset
// that does not exist in ABC. Type resolution should be skipped when it does not exist,
// or parsing pandafile will fail
if (jsPandaFile->GetMethodLiteralByIndex(callTargetMethodOffset) == nullptr) {
return;
}
TypeAnnotationExtractor annoExtractor(jsPandaFile, callTargetMethodOffset);
GlobalTSTypeRef funcGT =
typeParser.CreateGT(jsPandaFile, recordName, annoExtractor.GetMethodTypeOffset());
if (funcGT.IsDefault()) {
return;
}
// Target method was not compiled by AOT.
if (!decoder_->Match(jsPandaFile, recordName, pgo::PGOMethodId(callTargetMethodOffset))) {
tsManager->SetHotnessFunc(funcGT, false);
}
GateType callTargetType = GateType(funcGT);
bcOffsetCallTargetGtMap_.emplace(bcIdx, callTargetType);
return;
}
auto it = bcOffsetPGODefOpTypeMap_.find(bcOffset);
if (it == bcOffsetPGODefOpTypeMap_.end()) {
return;
}
TypeLocation loc(jsPandaFile, methodOffset, bcIdx);
if (!tsManager->GetLiteralGT(loc).IsDefault()) {
return;
}
GlobalTSTypeRef gt = typeParser.CreatePGOGT(TSTypeParser::PGOInfo { jsPandaFile, recordName, methodOffset,
cpIdx, PGOSampleType(it->second->GetProfileType()), type, decoder_, enableOptTrackField_ });
if (TypeNeedFilter(gt)) {
return;
}
CollectLiteralGT(tsManager, loc, gt);
});
}
void TypeRecorder::BindPgoTypeToGateType(const JSPandaFile *jsPandaFile, TSManager *tsManager,
const MethodLiteral *methodLiteral) const
{
uint32_t methodOffset = methodLiteral->GetMethodId().GetOffset();
const PGOBCInfo *bcInfo = tsManager->GetBytecodeInfoCollector()->GetPGOBCInfo();
bcInfo->IterateInfoAndType(methodOffset, [this, methodOffset, &jsPandaFile, tsManager]
(const PGOBCInfo::Type, const uint32_t bcIdx, const uint32_t bcOffset, const uint32_t) {
auto it = bcOffsetPGODefOpTypeMap_.find(bcOffset);
if (it == bcOffsetPGODefOpTypeMap_.end()) {
return;
}
TypeLocation loc(jsPandaFile, methodOffset, bcIdx);
if (!tsManager->GetLiteralGT(loc).IsDefault()) {
GlobalTSTypeRef gt = tsManager->GetLiteralGT(loc);
PGOHClassTreeDesc *desc;
if (decoder_->GetHClassTreeDesc(PGOSampleType(it->second->GetProfileType()), &desc)) {
GateType gateType(gt);
tsManager->InsertPtToGtMap(desc->GetProfileType(), gateType);
}
}
});
}
void TypeRecorder::LoadArgTypes(const TSManager *tsManager, GlobalTSTypeRef funcGT, GlobalTSTypeRef thisGT)
{
argTypes_[static_cast<size_t>(TypedArgIdx::FUNC)] = TryGetFuncType(funcGT);
argTypes_[static_cast<size_t>(TypedArgIdx::NEW_TARGET)] = TryGetNewTargetType(tsManager, thisGT);
argTypes_[static_cast<size_t>(TypedArgIdx::THIS_OBJECT)] = TryGetThisType(tsManager, funcGT, thisGT);
if (funcGT.IsDefault()) {
return;
}
size_t extraParasNum = static_cast<size_t>(TypedArgIdx::NUM_OF_TYPED_ARGS);
uint32_t numExplicitArgs = tsManager->GetFunctionTypeLength(funcGT);
for (uint32_t explicitArgId = 0; explicitArgId < numExplicitArgs; explicitArgId++) {
argTypes_[extraParasNum++] = GateType(tsManager->GetFuncParameterTypeGT(funcGT, explicitArgId));
}
}
GateType TypeRecorder::TryGetThisType(const TSManager *tsManager, GlobalTSTypeRef funcGT, GlobalTSTypeRef thisGT) const
{
// The parameter 'this' may be declared explicitly, e.g. foo(this: Person, num: number). In this case, the type
// of 'this' is recorded in the type of the function. And this type is preferred over the type derived from
// 'thisGT' if both are given.
if (!funcGT.IsDefault()) {
auto gt = tsManager->GetFuncThisGT(funcGT);
if (!gt.IsDefault()) {
return GateType(gt);
}
}
return GateType(thisGT);
}
GateType TypeRecorder::TryGetNewTargetType(const TSManager *tsManager, GlobalTSTypeRef thisGT) const
{
if (thisGT.IsDefault()) {
return GateType::AnyType();
}
GateType thisType(thisGT);
if (tsManager->IsClassInstanceTypeKind(thisType)) {
return GateType(tsManager->GetClassType(thisGT));
} else {
return thisType;
}
}
GateType TypeRecorder::TryGetFuncType(GlobalTSTypeRef funcGT) const
{
if (funcGT.IsDefault()) {
return GateType::AnyType();
}
return GateType(funcGT);
}
GateType TypeRecorder::GetType(const int32_t offset) const
{
if (bcOffsetGtMap_.find(offset) != bcOffsetGtMap_.end()) {
return bcOffsetGtMap_.at(offset);
}
return GateType::AnyType();
}
GateType TypeRecorder::GetArgType(const uint32_t argIndex) const
{
ASSERT(argIndex < argTypes_.size());
return argTypes_[argIndex];
}
GateType TypeRecorder::UpdateType(const int32_t offset, const GateType &type) const
{
auto tempType = GetType(offset);
if (!tempType.IsAnyType()) {
ASSERT(type.IsAnyType());
return tempType;
}
return type;
}
GateType TypeRecorder::GetCallTargetType(int32_t offset) const
{
if (bcOffsetCallTargetGtMap_.find(offset) != bcOffsetCallTargetGtMap_.end()) {
return bcOffsetCallTargetGtMap_.at(offset);
}
return GateType::AnyType();
}
bool TypeRecorder::TypeNeedFilter(GlobalTSTypeRef gt) const
{
return gt.IsDefault() || gt.IsGenericsModule();
}
} // namespace panda::ecmascript

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2022 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_TYPE_RECORDER_H
#define ECMASCRIPT_COMPILER_TYPE_RECORDER_H
#include "ecmascript/compiler/type.h"
#include "ecmascript/jspandafile/js_pandafile.h"
#include "ecmascript/method.h"
#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript::kungfu {
using PGODefineOpType = pgo::PGODefineOpType;
enum class TypedArgIdx : uint8_t {
FUNC = 0,
NEW_TARGET,
THIS_OBJECT,
NUM_OF_TYPED_ARGS,
};
class TypeRecorder {
public:
TypeRecorder(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
TSManager *tsManager, const CString &recordName, PGOProfilerDecoder *decoder,
const MethodPcInfo &methodPCInfo, const Bytecodes *bytecodes, bool enableOptTrackField);
~TypeRecorder() = default;
GateType GetType(const int32_t offset) const;
GateType GetArgType(const uint32_t argIndex) const;
GateType UpdateType(const int32_t offset, const GateType &type) const;
GateType GetCallTargetType(int32_t offset) const;
void BindPgoTypeToGateType(const JSPandaFile *jsPandaFile, TSManager *tsManager,
const MethodLiteral *methodLiteral) const;
static constexpr int METHOD_ANNOTATION_THIS_TYPE_OFFSET = -2;
private:
void LoadTypes(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
TSManager *tsManager, const CString &recordName);
void CreateTypesForPGO(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
TSManager *tsManager, const CString &recordName);
void LoadTypesFromPGO(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral,
const CString &recordName);
void LoadArgTypes(const TSManager *tsManager, GlobalTSTypeRef funcGT, GlobalTSTypeRef thisGT);
// This function tries to get the type of 'this'. In success, the type of the class is returned if the function is
// a static member, or the type of instances of the class is returned. Otherwise the type 'any' is returned.
GateType TryGetThisType(const TSManager *tsManager, GlobalTSTypeRef funcGT, GlobalTSTypeRef thisGT) const;
// This function tries to get the type of 'newTarget'. In success, the type of the class is returned. Otherwise,
// the type 'any' is returned.
GateType TryGetNewTargetType(const TSManager *tsManager, GlobalTSTypeRef thisGT) const;
// This function tries to get the type of the function. On failure, the type 'any' is returned.
GateType TryGetFuncType(GlobalTSTypeRef funcGT) const;
bool TypeNeedFilter(GlobalTSTypeRef gt) const;
bool CheckTypeMarkForDefineFunc(uint32_t checkBc) const;
void CollectLiteralGT(TSManager *tsManager, TypeLocation &tLoc, GlobalTSTypeRef gt);
std::unordered_map<int32_t, GateType> bcOffsetGtMap_ {};
std::unordered_map<int32_t, GateType> bcOffsetCallTargetGtMap_ {};
std::unordered_map<int32_t, const PGOSampleType*> bcOffsetPGOOpTypeMap_ {};
std::unordered_map<int32_t, const PGODefineOpType*> bcOffsetPGODefOpTypeMap_ {};
std::unordered_map<int32_t, const PGORWOpType*> bcOffsetPGORwTypeMap_ {};
std::vector<GateType> argTypes_;
PGOProfilerDecoder *decoder_ {nullptr};
bool enableOptTrackField_ {false};
const std::vector<const uint8_t*> &pcOffsets_;
const Bytecodes *bytecodes_ {nullptr};
};
} // panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_TYPE_RECORDER_H

View File

@ -34,7 +34,7 @@
#include "ecmascript/jit/jit.h"
namespace panda::ecmascript::kungfu {
bool TypedBytecodeLowering::RunTypedBytecodeLowering()
void TypedBytecodeLowering::RunTypedBytecodeLowering()
{
std::vector<GateRef> gateList;
circuit_->GetAllGates(gateList);
@ -43,18 +43,6 @@ bool TypedBytecodeLowering::RunTypedBytecodeLowering()
auto op = acc_.GetOpCode(gate);
if (op == OpCode::JS_BYTECODE) {
Lower(gate);
allJSBcCount_++;
}
}
bool success = true;
double typeHitRate = 0.0;
auto allTypedOpCount = allJSBcCount_ - allNonTypedOpCount_;
if (allTypedOpCount != 0) {
typeHitRate = static_cast<double>(hitTypedOpCount_) / static_cast<double>(allTypedOpCount);
auto typeThreshold = const_cast<CompilationEnv*>(compilationEnv_)->GetJSOptions().GetTypeThreshold();
if (typeHitRate <= typeThreshold) {
success = false;
}
}
@ -70,10 +58,6 @@ bool TypedBytecodeLowering::RunTypedBytecodeLowering()
<< "[" << GetMethodName() << "]"
<< "===================="
<< "\033[0m";
circuit_->PrintAllGatesWithBytecode();
LOG_COMPILER(INFO) << "\033[34m" << " =========================== End typeHitRate: "
<< std::to_string(typeHitRate)
<< " ===========================" << "\033[0m";
for (auto a : bytecodeMap_) {
if (bytecodeHitTimeMap_.find(a.first) != bytecodeHitTimeMap_.end()) {
double rate = static_cast<double>(bytecodeHitTimeMap_[a.first]) / static_cast<double>(a.second);
@ -91,8 +75,6 @@ bool TypedBytecodeLowering::RunTypedBytecodeLowering()
}
}
}
return success;
}
void TypedBytecodeLowering::ParseOptBytecodeRange()
@ -1419,7 +1401,7 @@ bool TypedBytecodeLowering::TryLowerNewBuiltinConstructor(GateRef gate)
void TypedBytecodeLowering::LowerTypedSuperCall(GateRef gate)
{
SuperCallTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
if (!tacc.IsClassTypeKind() && !tacc.IsValidCallMethodId()) {
if (!tacc.IsValidCallMethodId()) {
return;
}
AddProfiling(gate);

View File

@ -22,7 +22,6 @@
#include "ecmascript/compiler/builtins/builtins_call_signature.h"
#include "ecmascript/compiler/bytecode_circuit_builder.h"
#include "ecmascript/compiler/circuit_builder-inl.h"
#include "ecmascript/compiler/object_access_helper.h"
#include "ecmascript/compiler/pass_manager.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/compiler/type_info_accessors.h"
@ -46,7 +45,6 @@ public:
acc_(circuit),
builder_(circuit, ctx->GetCompilerConfig()),
dependEntry_(circuit->GetDependRoot()),
tsManager_(ctx->GetTSManager()),
chunk_(chunk),
enableLog_(enableLog),
enableTypeLog_(enableTypeLog),
@ -69,7 +67,7 @@ public:
~TypedBytecodeLowering() = default;
bool RunTypedBytecodeLowering();
void RunTypedBytecodeLowering();
private:
bool IsLogEnabled() const
@ -121,7 +119,6 @@ private:
GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder, PropertyLookupResult plr);
GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder,
GateRef value, PropertyLookupResult plr, uint32_t receiverHClassIndex = 0);
using AccessMode = PGOObjectAccessHelper::AccessMode;
bool TryLowerTypedLdObjByNameForBuiltin(GateRef gate);
bool TryLowerTypedLdObjByNameForBuiltinsId(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
bool TryLowerTypedLdObjByNameForBuiltin(const LoadBulitinObjTypeInfoAccessor &tacc);
@ -231,7 +228,6 @@ private:
GateAccessor acc_;
CircuitBuilder builder_;
GateRef dependEntry_ {Gate::InvalidGateRef};
TSManager *tsManager_ {nullptr};
Chunk *chunk_ {nullptr};
bool enableLog_ {false};
bool enableTypeLog_ {false};

View File

@ -14,10 +14,12 @@
*/
#include "ecmascript/compiler/typed_hcr_lowering.h"
#include "ecmascript/compiler/builtins_lowering.h"
#include "ecmascript/compiler/builtins/builtins_string_stub_builder.h"
#include "ecmascript/compiler/mcr_gate_meta_data.h"
#include "ecmascript/compiler/new_object_stub_builder.h"
#include "ecmascript/compiler/builtins/builtins_string_stub_builder.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/compiler/rt_call_signature.h"
#include "ecmascript/compiler/share_gate_meta_data.h"
#include "ecmascript/compiler/variable_type.h"
@ -31,7 +33,6 @@
#include "ecmascript/js_primitive_ref.h"
#include "ecmascript/linked_hash_table.h"
#include "ecmascript/message_string.h"
#include "ecmascript/subtyping_operator.h"
#include "ecmascript/vtable.h"
namespace panda::ecmascript::kungfu {

View File

@ -104,7 +104,6 @@ public:
CompilationEnv *env,
RPOVisitor* visitor,
CompilationConfig* cmpCfg,
TSManager* tsManager,
Chunk* chunk,
bool enableLoweringBuiltin)
: PassVisitor(circuit, chunk, visitor),
@ -113,7 +112,6 @@ public:
acc_(circuit),
builder_(circuit, cmpCfg),
dependEntry_(circuit->GetDependRoot()),
tsManager_(tsManager),
enableLoweringBuiltin_(enableLoweringBuiltin)
{
if (cmpCfg != nullptr) {
@ -276,7 +274,6 @@ private:
GateAccessor acc_;
CircuitBuilder builder_;
GateRef dependEntry_;
[[maybe_unused]] TSManager *tsManager_ {nullptr};
bool enableLoweringBuiltin_ {false};
bool typedOpProfiling_ {false};
};

View File

@ -35,7 +35,6 @@ foreach(file, test_js_files) {
dst_file = rebase_path(test_abc)
extra_args = [ "--module" ]
extra_args += [ "--merge-abc" ]
extra_args += [ "--type-extractor" ]
in_puts = [ test_js ]
out_puts = [ test_abc ]

View File

@ -19,6 +19,7 @@
#include "ecmascript/base/aligned_struct.h"
#include "ecmascript/compiler/argument_accessor.h"
#include "ecmascript/deoptimizer/calleeReg.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/js_handle.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/stackmap/llvm/llvm_stackmap_type.h"

View File

@ -602,20 +602,6 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
return GetString("MachineCode");
case JSType::CLASS_INFO_EXTRACTOR:
return GetString("ClassInfoExtractor");
case JSType::TS_OBJECT_TYPE:
return GetString("TSObjectType");
case JSType::TS_INTERFACE_TYPE:
return GetString("TSInterfaceType");
case JSType::TS_CLASS_TYPE:
return GetString("TSClassType");
case JSType::TS_UNION_TYPE:
return GetString("TSUnionType");
case JSType::TS_CLASS_INSTANCE_TYPE:
return GetString("TSClassInstanceType");
case JSType::TS_FUNCTION_TYPE:
return GetString("TSFunctionType");
case JSType::TS_ARRAY_TYPE:
return GetString("TSArrayType");
default:
break;
}

View File

@ -31,7 +31,6 @@ foreach(file, test_js_files) {
dst_file = rebase_path(test_abc)
extra_args = [ "--module" ]
extra_args += [ "--merge-abc" ]
extra_args += [ "--type-extractor" ]
in_puts = [ test_js ]
out_puts = [ test_abc ]

View File

@ -127,7 +127,6 @@
#include "ecmascript/tagged_tree.h"
#include "ecmascript/template_map.h"
#include "ecmascript/transitions_dictionary.h"
#include "ecmascript/ts_types/ts_type.h"
#include "ecmascript/js_displaynames.h"
#include "ecmascript/js_list_format.h"
#include "js_hclass.h"
@ -436,24 +435,6 @@ CString JSHClass::DumpJSType(JSType type)
return "ClassInfoExtractor";
case JSType::JS_API_ARRAY_LIST:
return "ArrayList";
case JSType::TS_OBJECT_TYPE:
return "TSObjectType";
case JSType::TS_CLASS_TYPE:
return "TSClassType";
case JSType::TS_INTERFACE_TYPE:
return "TSInterfaceType";
case JSType::TS_CLASS_INSTANCE_TYPE:
return "TSClassInstanceType";
case JSType::TS_UNION_TYPE:
return "TSUnionType";
case JSType::TS_FUNCTION_TYPE:
return "TSFunctionType";
case JSType::TS_ARRAY_TYPE:
return "TSArrayType";
case JSType::TS_ITERATOR_INSTANCE_TYPE:
return "TSIteratorInstanceType";
case JSType::TS_NAMESPACE_TYPE:
return "TSNamespaceType";
case JSType::JS_API_ARRAYLIST_ITERATOR:
return "JSArraylistIterator";
case JSType::LINKED_NODE:
@ -1203,33 +1184,6 @@ static void DumpObject(TaggedObject *obj, std::ostream &os)
case JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR:
JSAPILightWeightSetIterator::Cast(obj)->Dump(os);
break;
case JSType::TS_OBJECT_TYPE:
TSObjectType::Cast(obj)->Dump(os);
break;
case JSType::TS_CLASS_TYPE:
TSClassType::Cast(obj)->Dump(os);
break;
case JSType::TS_INTERFACE_TYPE:
TSInterfaceType::Cast(obj)->Dump(os);
break;
case JSType::TS_CLASS_INSTANCE_TYPE:
TSClassInstanceType::Cast(obj)->Dump(os);
break;
case JSType::TS_UNION_TYPE:
TSUnionType::Cast(obj)->Dump(os);
break;
case JSType::TS_FUNCTION_TYPE:
TSFunctionType::Cast(obj)->Dump(os);
break;
case JSType::TS_ARRAY_TYPE:
TSArrayType::Cast(obj)->Dump(os);
break;
case JSType::TS_ITERATOR_INSTANCE_TYPE:
TSIteratorInstanceType::Cast(obj)->Dump(os);
break;
case JSType::TS_NAMESPACE_TYPE:
TSNamespaceType::Cast(obj)->Dump(os);
break;
case JSType::LINKED_NODE:
LinkedNode::Cast(obj)->Dump(os);
break;
@ -3649,274 +3603,6 @@ void ClassInfoExtractor::Dump(std::ostream &os) const
os << "\n";
}
void TSObjectType::Dump(std::ostream &os) const
{
os << " - TSObjectType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSObjectType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSObjectType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - ObjLayoutInfo: ";
DumpArrayClass(TaggedArray::Cast(GetObjLayoutInfo().GetTaggedObject()), os);
os << " - Index signature: ";
if (GetIndexSigns().IsUndefined()) {
os << " no index signature type " << "\n";
} else {
DumpArrayClass(TaggedArray::Cast(GetIndexSigns().GetTaggedObject()), os);
}
}
void TSClassType::Dump(std::ostream &os) const
{
os << " - Dump TSClassType - " << "\n";
os << " - TSClassType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSClassType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSClassType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - ExtensionTypeGT: ";
GlobalTSTypeRef extensionGT = GetExtensionGT();
if (extensionGT.IsDefault()) {
os << " (base class type) ";
} else {
os << extensionGT.GetType();
}
os << "\n";
CString hasLinked = GetHasLinked() ? "true" : "false";
os << " - HasLinked: " << hasLinked << "\n";
os << " - InstanceType: " << "\n";
if (GetInstanceType().IsTSObjectType()) {
TSObjectType *instanceType = TSObjectType::Cast(GetInstanceType().GetTaggedObject());
instanceType->Dump(os);
os << "\n";
}
os << " - ConstructorType: " << "\n";
if (GetConstructorType().IsTSObjectType()) {
TSObjectType *constructorType = TSObjectType::Cast(GetConstructorType().GetTaggedObject());
constructorType->Dump(os);
os << "\n";
}
os << " - PrototypeType: " << "\n";
if (GetPrototypeType().IsTSObjectType()) {
TSObjectType *prototypeType = TSObjectType::Cast(GetPrototypeType().GetTaggedObject());
prototypeType->Dump(os);
os << "\n";
}
os << " - Index signature: ";
if (GetIndexSigns().IsUndefined()) {
os << " no index signature type " << "\n";
} else {
DumpArrayClass(TaggedArray::Cast(GetIndexSigns().GetTaggedObject()), os);
}
os << "\n";
}
void TSInterfaceType::Dump(std::ostream &os) const
{
os << " - Dump Interface Type - " << "\n";
os << " - TSInterfaceType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSInterfaceType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSInterfaceType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - Extends TypeId: " << "\n";
if (TaggedArray::Cast(GetExtends().GetTaggedObject())->GetLength() == 0) {
os << " (base interface type) "<< "\n";
}
DumpArrayClass(TaggedArray::Cast(GetExtends().GetTaggedObject()), os);
os << " - Fields: " << "\n";
if (GetFields().IsTSObjectType()) {
TSObjectType *fieldsType = TSObjectType::Cast(GetFields().GetTaggedObject());
fieldsType->Dump(os);
os << "\n";
}
os << " - Index signature: ";
if (GetIndexSigns().IsUndefined()) {
os << " no index signature type " << "\n";
} else {
DumpArrayClass(TaggedArray::Cast(GetIndexSigns().GetTaggedObject()), os);
}
os << "\n";
}
void TSClassInstanceType::Dump(std::ostream &os) const
{
os << " - Dump ClassInstance Type - " << "\n";
os << " - TSClassInstanceType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSClassInstanceType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSClassInstanceType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - createClassType GT: ";
GlobalTSTypeRef createClassTypeGT = GetClassGT();
os << createClassTypeGT.GetType();
os << "\n";
}
void TSUnionType::Dump(std::ostream &os) const
{
os << " - Dump UnionType Type - " << "\n";
os << " - TSUnionType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSUnionType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSUnionType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - TSUnionType TypeId: " << "\n";
DumpArrayClass(TaggedArray::Cast(GetComponents().GetTaggedObject()), os);
}
void TSFunctionType::Dump(std::ostream &os) const
{
os << " - Dump TSFunctionType - " << "\n";
os << " - TSFunctionType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSFunctionType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSFunctionType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - TSFunctionType Name: ";
JSTaggedValue name = GetName();
if (name.IsString()) {
os << ConvertToString(EcmaString::Cast(name.GetTaggedObject()));
}
os << "\n";
os << " - TSFunctionType ParameterTypeIds: " << "\n";
DumpArrayClass(TaggedArray::Cast(GetParameterTypes().GetTaggedObject()), os);
os << " - TSFunctionType ReturnType: " << GetReturnGT().GetType() << "\n";
os << " - TSFunctionType ThisType: " << GetThisGT().GetType() << "\n";
TSFunctionType::Visibility visibility = GetVisibility();
switch (visibility) {
case TSFunctionType::Visibility::PUBLIC:
os << " - Visibility: public";
break;
case TSFunctionType::Visibility::PRIVATE:
os << " - Visibility: private";
break;
case TSFunctionType::Visibility::PROTECTED:
os << " - Visibility: protected";
break;
}
os << " | IsStatic: " << std::boolalpha << GetStatic();
os << " | IsAsync: " << std::boolalpha << GetAsync();
os << " | IsGenerator: " << std::boolalpha << GetGenerator();
os << " | IsGetterSetter: " << std::boolalpha << GetIsGetterSetter();
os << "\n";
}
void TSArrayType::Dump(std::ostream &os) const
{
os << " - Dump TSArrayType - " << "\n";
os << " - TSArrayType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
os << gt.GetType();
os << "\n";
os << " - TSArrayType ElementGT: ";
os << GetElementGT().GetType();
os << "\n";
}
void TSIteratorInstanceType::Dump(std::ostream &os) const
{
os << " - Dump IteratorInstance Type - " << "\n";
os << " - TSIteratorInstanceType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSIteratorInstanceType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSIteratorInstanceType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - TSIteratorInstanceType KindGT: ";
os << GetKindGT().GetType();
os << "\n";
os << " - TSIteratorInstanceType ElementGT: ";
os << GetElementGT().GetType();
os << "\n";
}
void TSNamespaceType::Dump(std::ostream &os) const
{
os << " - Dump Namespace Type - " << "\n";
os << " - TSNamespaceType globalTSTypeRef: ";
GlobalTSTypeRef gt = GetGT();
uint64_t globalTSTypeRef = gt.GetType();
os << globalTSTypeRef;
os << "\n";
os << " - TSNamespaceType moduleId: ";
uint32_t moduleId = gt.GetModuleId();
os << moduleId;
os << "\n";
os << " - TSNamespaceType localTypeId: ";
uint32_t localTypeId = gt.GetLocalId();
os << localTypeId;
os << "\n";
os << " - Properties: ";
DumpArrayClass(TaggedArray::Cast(GetPropertyType().GetTaggedObject()), os);
}
void SourceTextModule::Dump(std::ostream &os) const
{
os << " - Environment: ";
@ -4737,33 +4423,6 @@ static void DumpObject(TaggedObject *obj, std::vector<Reference> &vec, bool isVm
case JSType::CLASS_INFO_EXTRACTOR:
ClassInfoExtractor::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_OBJECT_TYPE:
TSObjectType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_CLASS_TYPE:
TSClassType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_INTERFACE_TYPE:
TSInterfaceType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_CLASS_INSTANCE_TYPE:
TSClassInstanceType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_UNION_TYPE:
TSUnionType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_FUNCTION_TYPE:
TSFunctionType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_ARRAY_TYPE:
TSArrayType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_ITERATOR_INSTANCE_TYPE:
TSIteratorInstanceType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::TS_NAMESPACE_TYPE:
TSNamespaceType::Cast(obj)->DumpForSnapshot(vec);
return;
case JSType::METHOD:
Method::Cast(obj)->DumpForSnapshot(vec);
return;
@ -6258,79 +5917,6 @@ void ClassInfoExtractor::DumpForSnapshot(std::vector<Reference> &vec) const
vec.emplace_back(CString("BitField"), JSTaggedValue(GetBitField()));
}
void TSObjectType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("ObjLayoutInfo"), GetObjLayoutInfo());
vec.emplace_back(CString("IndexSigns"), GetIndexSigns());
}
void TSClassType::DumpForSnapshot(std::vector<Reference> &vec) const
{
// please update the NUM_OF_ITEMS if you change the items below
constexpr int16_t NUM_OF_ITEMS = 5;
vec.reserve(vec.size() + NUM_OF_ITEMS);
vec.emplace_back(CString("InstanceType"), GetInstanceType());
vec.emplace_back(CString("ConstructorType"), GetConstructorType());
vec.emplace_back(CString("PrototypeType"), GetPrototypeType());
vec.emplace_back(CString("ExtensionGT"), JSTaggedValue(GetExtensionGT().GetType()));
vec.emplace_back(CString("HasLinked"), JSTaggedValue(GetHasLinked()));
vec.emplace_back(CString("Name"), JSTaggedValue(GetName()));
if (!GetIndexSigns().IsUndefined()) {
DumpArrayClass(TaggedArray::Cast(GetIndexSigns().GetTaggedObject()), vec);
}
}
void TSInterfaceType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("Fields"), GetFields());
vec.emplace_back(CString("Extends"), GetExtends());
DumpArrayClass(TaggedArray::Cast(GetExtends().GetTaggedObject()), vec);
if (!GetIndexSigns().IsUndefined()) {
DumpArrayClass(TaggedArray::Cast(GetIndexSigns().GetTaggedObject()), vec);
}
}
void TSClassInstanceType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("ClassGT"), JSTaggedValue(GetClassGT().GetType()));
}
void TSUnionType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("ComponentTypes"), GetComponents());
DumpArrayClass(TaggedArray::Cast(GetComponents().GetTaggedObject()), vec);
}
void TSFunctionType::DumpForSnapshot(std::vector<Reference> &vec) const
{
// please update the NUM_OF_ITEMS if you change the items below
constexpr int16_t NUM_OF_ITEMS = 5;
vec.reserve(vec.size() + NUM_OF_ITEMS);
vec.emplace_back(CString("Name"), GetName());
vec.emplace_back(CString("ParameterTypes"), GetParameterTypes());
DumpArrayClass(TaggedArray::Cast(GetParameterTypes().GetTaggedObject()), vec);
vec.emplace_back(CString("ReturnGT"), JSTaggedValue(GetReturnGT().GetType()));
vec.emplace_back(CString("ThisGT"), JSTaggedValue(GetThisGT().GetType()));
vec.emplace_back(CString("BitField"), JSTaggedValue(GetBitField()));
}
void TSArrayType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("ParameterTypeRef"), JSTaggedValue(GetElementGT().GetType()));
}
void TSIteratorInstanceType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("kindGT"), JSTaggedValue(GetKindGT().GetType()));
vec.emplace_back(CString("elementGT"), JSTaggedValue(GetElementGT().GetType()));
}
void TSNamespaceType::DumpForSnapshot(std::vector<Reference> &vec) const
{
vec.emplace_back(CString("PropertyType"), GetPropertyType());
DumpArrayClass(TaggedArray::Cast(GetPropertyType().GetTaggedObject()), vec);
}
void SourceTextModule::DumpForSnapshot(std::vector<Reference> &vec) const
{
// please update the NUM_OF_ITEMS if you change the items below

View File

@ -23,6 +23,7 @@
#include "ecmascript/builtins/builtins_string.h"
#include "ecmascript/compiler/aot_file/an_file_data_manager.h"
#include "ecmascript/compiler/common_stubs.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/ecma_string_table.h"
#include "ecmascript/ecma_vm.h"
@ -83,14 +84,6 @@ bool EcmaContext::Destroy(EcmaContext *context)
return false;
}
void EcmaContext::SetTSManager(TSManager *set)
{
if (tsManager_ != nullptr) {
delete tsManager_;
}
tsManager_ = set;
}
bool EcmaContext::Initialize()
{
LOG_ECMA(DEBUG) << "EcmaContext::Initialize";
@ -125,7 +118,6 @@ bool EcmaContext::Initialize()
SetupStringToListResultCache();
microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue();
moduleManager_ = new ModuleManager(vm_);
tsManager_ = new TSManager(vm_);
ptManager_ = new kungfu::PGOTypeManager(vm_);
optCodeProfiler_ = new OptCodeProfiler();
if (vm_->GetJSOptions().GetTypedOpProfiler()) {
@ -234,10 +226,6 @@ EcmaContext::~EcmaContext()
delete moduleManager_;
moduleManager_ = nullptr;
}
if (tsManager_ != nullptr) {
delete tsManager_;
tsManager_ = nullptr;
}
if (ptManager_ != nullptr) {
delete ptManager_;
ptManager_ = nullptr;
@ -903,9 +891,6 @@ void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
if (moduleManager_) {
moduleManager_->Iterate(v);
}
if (tsManager_) {
tsManager_->Iterate(v);
}
if (ptManager_) {
ptManager_->Iterate(v);
}

View File

@ -61,7 +61,6 @@ class JSPromise;
class JSTaggedValue;
class EcmaVM;
class ModuleManager;
class TSManager;
class AOTFileManager;
class QuickFixManager;
class OptCodeProfiler;
@ -135,18 +134,11 @@ public:
return moduleManager_;
}
TSManager *GetTSManager() const
{
return tsManager_;
}
kungfu::PGOTypeManager *GetPTManager() const
{
return ptManager_;
}
void PUBLIC_API SetTSManager(TSManager *set);
ARK_INLINE JSThread *GetJSThread() const
{
return thread_;
@ -570,7 +562,6 @@ private:
// VM resources.
ModuleManager *moduleManager_ {nullptr};
TSManager *tsManager_ {nullptr};
kungfu::PGOTypeManager *ptManager_ {nullptr};
AOTFileManager *aotFileManager_ {nullptr};

View File

@ -91,7 +91,6 @@
#include "ecmascript/tagged_queue.h"
#include "ecmascript/taskpool/task.h"
#include "ecmascript/taskpool/taskpool.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "ecmascript/ohos/enable_aot_list_helper.h"

View File

@ -81,7 +81,6 @@ class JSArrayBuffer;
class JSFunction;
class SourceTextModule;
class Program;
class TSManager;
class AOTFileManager;
class SlowRuntimeStub;
class RequireManager;

View File

@ -80,9 +80,8 @@
#include "ecmascript/shared_objects/js_shared_map_iterator.h"
#include "ecmascript/shared_objects/js_shared_set.h"
#include "ecmascript/shared_objects/js_shared_set_iterator.h"
#include "ecmascript/subtyping_operator.h"
#include "ecmascript/tagged_node.h"
#include "ecmascript/ts_types/ts_type.h"
#include "ecmascript/vtable.h"
namespace panda::ecmascript {
void GlobalEnvConstants::Init(JSThread *thread)
@ -231,26 +230,6 @@ void GlobalEnvConstants::InitSharedRootsClasses(ObjectFactory *factory)
SetConstant(ConstantIndex::CLASS_INFO_EXTRACTOR_HCLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, ClassInfoExtractor::SIZE,
JSType::CLASS_INFO_EXTRACTOR));
SetConstant(ConstantIndex::TS_OBJECT_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSObjectType::SIZE, JSType::TS_OBJECT_TYPE));
SetConstant(ConstantIndex::TS_CLASS_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSClassType::SIZE, JSType::TS_CLASS_TYPE));
SetConstant(ConstantIndex::TS_UNION_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSUnionType::SIZE, JSType::TS_UNION_TYPE));
SetConstant(ConstantIndex::TS_INTERFACE_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSInterfaceType::SIZE, JSType::TS_INTERFACE_TYPE));
SetConstant(ConstantIndex::TS_CLASS_INSTANCE_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSClassInstanceType::SIZE,
JSType::TS_CLASS_INSTANCE_TYPE));
SetConstant(ConstantIndex::TS_FUNCTION_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSFunctionType::SIZE, JSType::TS_FUNCTION_TYPE));
SetConstant(ConstantIndex::TS_ARRAY_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSArrayType::SIZE, JSType::TS_ARRAY_TYPE));
SetConstant(ConstantIndex::TS_ITERATOR_INSTANCE_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSIteratorInstanceType::SIZE,
JSType::TS_ITERATOR_INSTANCE_TYPE));
SetConstant(ConstantIndex::TS_NAMESPACE_TYPE_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, TSNamespaceType::SIZE, JSType::TS_NAMESPACE_TYPE));
SetConstant(ConstantIndex::CELL_RECORD_CLASS_INDEX,
factory->NewSEcmaReadOnlyHClass(hClass, CellRecord::SIZE, JSType::CELL_RECORD));
SetConstant(ConstantIndex::METHOD_CLASS_INDEX,
@ -383,7 +362,7 @@ void GlobalEnvConstants::InitMiscellanious(JSThread *thread, ObjectFactory *fact
SetConstant(ConstantIndex::EMPTY_LAYOUT_INFO_OBJECT_INDEX, factory->CreateLayoutInfo(0));
SetConstant(ConstantIndex::EMPTY_TAGGED_QUEUE_OBJECT_INDEX, factory->NewTaggedQueue(0));
SetConstant(ConstantIndex::DEFAULT_SUPERS_INDEX,
WeakVector::Create(thread, SubtypingOperator::DEFAULT_SUPERS_CAPACITY, MemSpaceType::NON_MOVABLE));
WeakVector::Create(thread, VTable::DEFAULT_SUPERS_CAPACITY, MemSpaceType::NON_MOVABLE));
// non ECMA standard jsapi containers iterators, init to Undefined first
InitJSAPIContainers();

View File

@ -85,15 +85,6 @@ class ObjectFactory;
V(JSTaggedValue, ResolvedIndexBindingClass, RESOLVED_INDEX_BINDING_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, MachineCodeClass, MACHINE_CODE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, ClassInfoExtractorHClass, CLASS_INFO_EXTRACTOR_HCLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSObjectTypeClass, TS_OBJECT_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSClassTypeClass, TS_CLASS_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSUnionTypeClass, TS_UNION_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSInterfaceTypeClass, TS_INTERFACE_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSClassInstanceTypeClass, TS_CLASS_INSTANCE_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSFunctionTypeClass, TS_FUNCTION_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSArrayTypeClass, TS_ARRAY_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSIteratorInstanceTypeClass, TS_ITERATOR_INSTANCE_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, TSNamespaceTypeClass, TS_NAMESPACE_TYPE_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, CellRecordClass, CELL_RECORD_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, AOTLiteralInfoClass, AOT_LITERAL_INFO_CLASS_INDEX, ecma_roots_class) \
V(JSTaggedValue, MethodClass, METHOD_CLASS_INDEX, ecma_roots_class) \

View File

@ -15,6 +15,7 @@
#include "ecmascript/jit/jit.h"
#include "ecmascript/jit/jit_task.h"
#include "ecmascript/js_function.h"
#include "ecmascript/platform/mutex.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/dfx/vmstat/jit_preheat_profiler.h"

View File

@ -17,9 +17,11 @@
#define ECMASCRIPT_JIT_H
#include "ecmascript/common.h"
#include "ecmascript/compiler/compilation_env.h"
#include "ecmascript/platform/mutex.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/mem/clock_scope.h"
#include "ecmascript/mem/machine_code.h"
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/jit/jit_thread.h"

View File

@ -19,6 +19,7 @@
#include <memory>
#include "ecmascript/compiler/codegen/maple/maple_util/include/profile_type.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/elements.h"
#include "ecmascript/enum_conversion.h"
#include "ecmascript/ic/ic_handler.h"

View File

@ -17,6 +17,7 @@
#include "ecmascript/object_factory.h"
#include "ecmascript/global_env.h"
#include "ecmascript/compiler/aot_file/func_entry_des.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/ic/profile_type_info.h"
#include "ecmascript/patch/patch_loader.h"
#include "ecmascript/jspandafile/program_object.h"

View File

@ -30,12 +30,13 @@
#include "ecmascript/js_object-inl.h"
#include "ecmascript/js_symbol.h"
#include "ecmascript/mem/c_containers.h"
#include "ecmascript/subtyping_operator.h"
#include "ecmascript/tagged_array-inl.h"
#include "ecmascript/tagged_dictionary.h"
#include "ecmascript/weak_vector.h"
namespace panda::ecmascript {
using ProfileType = pgo::ProfileType;
JSHandle<TransitionsDictionary> TransitionsDictionary::PutIfAbsent(const JSThread *thread,
const JSHandle<TransitionsDictionary> &dictionary,
const JSHandle<JSTaggedValue> &key,
@ -336,11 +337,6 @@ void JSHClass::AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj
obj->SynchronizedSetClass(thread, *newJsHClass);
// Because we currently only supports Fast ElementsKind
TryRestoreElementsKind(thread, newJsHClass, obj);
// Maintaining subtyping is no longer required when transition succeeds.
if (jshclass->HasTSSubtyping()) {
SubtypingOperator::TryMaintainTSSubtyping(thread, jshclass, newJsHClass, key);
}
}
void JSHClass::TryRestoreElementsKind(const JSThread *thread, JSHandle<JSHClass> newJsHClass,
@ -920,8 +916,7 @@ JSHandle<ProtoChangeDetails> JSHClass::GetProtoChangeDetails(const JSThread *thr
return GetProtoChangeDetails(thread, jshclass);
}
void JSHClass::MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
JSTaggedValue addedKey)
void JSHClass::MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass)
{
DISALLOW_GARBAGE_COLLECTION;
ASSERT(jshclass->IsPrototype() || jshclass->HasTSSubtyping());
@ -932,12 +927,6 @@ void JSHClass::MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass>
}
if (jshclass->HasTSSubtyping()) {
if (addedKey.IsString()) {
JSHandle<JSTaggedValue> key(thread, addedKey);
if (SubtypingOperator::TryMaintainTSSubtypingOnPrototype(thread, jshclass, key)) {
return;
}
}
jshclass->InitTSInheritInfo(thread);
}
}
@ -946,7 +935,7 @@ void JSHClass::NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClas
JSTaggedValue addedKey)
{
DISALLOW_GARBAGE_COLLECTION;
MarkProtoChanged(thread, jshclass, addedKey);
MarkProtoChanged(thread, jshclass);
JSTaggedValue protoDetailsValue = jshclass->GetProtoChangeDetails();
if (!protoDetailsValue.IsProtoChangeDetails()) {
return;

View File

@ -292,15 +292,6 @@ struct Reference;
COMPLETION_RECORD, /* JS_RECORD_LAST ////////////////////////////////////////////////////////////////////// */ \
MACHINE_CODE_OBJECT, \
CLASS_INFO_EXTRACTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_ARRAY_TYPE, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_UNION_TYPE, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_FUNCTION_TYPE, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_OBJECT_TYPE, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_CLASS_TYPE, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_CLASS_INSTANCE_TYPE, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
TS_INTERFACE_TYPE, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
TS_ITERATOR_INSTANCE_TYPE, /* //////////////////////////////////////////////////////////////////-PADDING */ \
TS_NAMESPACE_TYPE, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
\
VTABLE, /* //////////////////////////////////////////////////////////////////-PADDING */ \
AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
@ -336,9 +327,6 @@ struct Reference;
MODULE_RECORD_FIRST = MODULE_RECORD, /* ///////////////////////////////////////////////////////////-PADDING */ \
MODULE_RECORD_LAST = SOURCE_TEXT_MODULE_RECORD, /* ////////////////////////////////////////////////-PADDING */ \
\
TS_TYPE_FIRST = TS_ARRAY_TYPE, /* /////////////////////////////////////////////////////////////////-PADDING */ \
TS_TYPE_LAST = TS_NAMESPACE_TYPE, /* //////////////////////////////////////////////////////////////-PADDING */ \
\
STRING_FIRST = LINE_STRING, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
STRING_LAST = TREE_STRING /* /////////////////////////////////////////////////////////////////////-PADDING */
@ -489,8 +477,7 @@ public:
inline void UpdatePropertyMetaData(const JSThread *thread, const JSTaggedValue &key,
const PropertyAttributes &metaData);
static void MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
JSTaggedValue addedKey = JSTaggedValue::Undefined());
static void MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
static void NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
JSTaggedValue addedKey = JSTaggedValue::Undefined());
@ -1628,57 +1615,6 @@ public:
return GetObjectType() == JSType::MACHINE_CODE_OBJECT;
}
inline bool IsTSType() const
{
JSType jsType = GetObjectType();
return jsType >= JSType::TS_TYPE_FIRST && jsType <= JSType::TS_TYPE_LAST;
}
inline bool IsTSObjectType() const
{
return GetObjectType() == JSType::TS_OBJECT_TYPE;
}
inline bool IsTSClassType() const
{
return GetObjectType() == JSType::TS_CLASS_TYPE;
}
inline bool IsTSInterfaceType() const
{
return GetObjectType() == JSType::TS_INTERFACE_TYPE;
}
inline bool IsTSUnionType() const
{
return GetObjectType() == JSType::TS_UNION_TYPE;
}
inline bool IsTSClassInstanceType() const
{
return GetObjectType() == JSType::TS_CLASS_INSTANCE_TYPE;
}
inline bool IsTSFunctionType() const
{
return GetObjectType() == JSType::TS_FUNCTION_TYPE;
}
inline bool IsTSArrayType() const
{
return GetObjectType() == JSType::TS_ARRAY_TYPE;
}
inline bool IsTSIteratorInstanceType() const
{
return GetObjectType() == JSType::TS_ITERATOR_INSTANCE_TYPE;
}
inline bool IsTSNamespaceType() const
{
return GetObjectType() == JSType::TS_NAMESPACE_TYPE;
}
inline bool IsAOTLiteralInfo() const
{
return GetObjectType() == JSType::AOT_LITERAL_INFO;

View File

@ -46,8 +46,6 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
"--ark-bundle-name: Set ark bundle name\n"
"--asm-interpreter: Enable asm interpreter. Default: 'true'\n"
"--asm-opcode-disable-range: Opcode range when asm interpreter is enabled.\n"
"--compiler-assert-types: Enable type assertion for type inference tests. Default: 'false'\n"
"--builtins-dts: Builtins.d.abc file path for AOT.\n"
"--builtins-lazy: Load some builtins function later.This option is only valid in workervm.\n"
"--compiler-log: Log Option For aot compiler and stub compiler,\n"
" 'none': no log,\n"
@ -65,7 +63,6 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
"Default: 'none'\n"
"--compiler-type-threshold: enable to skip methods whose type is no more than threshold. Default: -1\n"
"--compiler-log-snapshot: Enable to print snapshot information. Default: 'false'\n"
"--compiler-opt-global-typeinfer: Enable global typeinfer for aot compiler: Default: 'false'\n"
"--compiler-log-time: Enable to print pass compiler time. Default: 'false'\n"
"--enable-ark-tools: Enable ark tools to debug. Default: 'false'\n"
"--compiler-trace-bc: Enable tracing bytecode for aot runtime. Default: 'false'\n"
@ -127,7 +124,6 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
"--merge-abc: ABC file is merge abc. Default: 'false'\n"
"--compiler-opt-level: Optimization level configuration of aot compiler. Default: '3'\n"
"--options: Print compiler and runtime options\n"
"--compiler-print-type-info: Enable print type info. Default: 'false'\n"
"--serializer-buffer-size-limit: Max serializer buffer size used by the VM in Byte. Default size is 2GB\n"
"--snapshot-file: Snapshot file. Default: '/system/etc/snapshot'\n"
"--startup-time: Print the start time of command execution. Default: 'false'\n"
@ -191,14 +187,11 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
{"ark-bundleName", required_argument, nullptr, OPTION_ARK_BUNDLENAME},
{"asm-interpreter", required_argument, nullptr, OPTION_ENABLE_ASM_INTERPRETER},
{"asm-opcode-disable-range", required_argument, nullptr, OPTION_ASM_OPCODE_DISABLE_RANGE},
{"compiler-assert-types", required_argument, nullptr, OPTION_COMPILER_ASSERT_TYPES},
{"builtins-dts", required_argument, nullptr, OPTION_BUILTINS_DTS},
{"builtins-lazy", required_argument, nullptr, OPTION_ENABLE_BUILTINS_LAZY},
{"compiler-log", required_argument, nullptr, OPTION_COMPILER_LOG_OPT},
{"compiler-log-methods", required_argument, nullptr, OPTION_COMPILER_LOG_METHODS},
{"compiler-log-snapshot", required_argument, nullptr, OPTION_COMPILER_LOG_SNAPSHOT},
{"compiler-log-time", required_argument, nullptr, OPTION_COMPILER_LOG_TIME},
{"compiler-opt-global-typeinfer", required_argument, nullptr, OPTION_COMPILER_OPT_GLOBAL_TYPEINFER},
{"compiler-type-threshold", required_argument, nullptr, OPTION_COMPILER_TYPE_THRESHOLD},
{"enable-ark-tools", required_argument, nullptr, OPTION_ENABLE_ARK_TOOLS},
{"compiler-trace-bc", required_argument, nullptr, OPTION_COMPILER_TRACE_BC},
@ -251,7 +244,6 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
{"merge-abc", required_argument, nullptr, OPTION_MERGE_ABC},
{"enable-context", required_argument, nullptr, OPTION_ENABLE_CONTEXT},
{"compiler-opt-level", required_argument, nullptr, OPTION_ASM_OPT_LEVEL},
{"compiler-print-type-info", required_argument, nullptr, OPTION_COMPILER_PRINT_TYPE_INFO},
{"reloc-mode", required_argument, nullptr, OPTION_RELOCATION_MODE},
{"serializer-buffer-size-limit", required_argument, nullptr, OPTION_SERIALIZER_BUFFER_SIZE_LIMIT},
{"startup-time", required_argument, nullptr, OPTION_STARTUP_TIME},
@ -372,17 +364,6 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
case OPTION_ASM_OPCODE_DISABLE_RANGE:
SetAsmOpcodeDisableRange(optarg);
break;
case OPTION_COMPILER_ASSERT_TYPES:
ret = ParseBoolParam(&argBool);
if (ret) {
SetAssertTypes(argBool);
} else {
return false;
}
break;
case OPTION_BUILTINS_DTS:
SetBuiltinsDTS(optarg);
break;
case OPTION_ENABLE_BUILTINS_LAZY:
ret = ParseBoolParam(&argBool);
if (ret) {
@ -655,14 +636,6 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
return false;
}
break;
case OPTION_COMPILER_PRINT_TYPE_INFO:
ret = ParseBoolParam(&argBool);
if (ret) {
SetPrintTypeInfo(argBool);
} else {
return false;
}
break;
case OPTION_PRINT_EXECUTE_TIME:
ret = ParseBoolParam(&argBool);
if (ret) {
@ -846,14 +819,6 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
return false;
}
break;
case OPTION_COMPILER_OPT_GLOBAL_TYPEINFER:
ret = ParseBoolParam(&argBool);
if (ret) {
SetEnableGlobalTypeInfer(argBool);
} else {
return false;
}
break;
case OPTION_COMPILER_VERIFY_VTABLE:
ret = ParseBoolParam(&argBool);
if (ret) {
@ -1241,17 +1206,9 @@ void JSRuntimeOptions::ParseListArgParam(const std::string &option, arg_list_t *
return;
}
void JSRuntimeOptions::SetTargetBuiltinsDtsPath()
{
WasSet(CommandValues::OPTION_BUILTINS_DTS);
std::string builtinsDtsPath = TARGET_BUILTINS_DTS_PATH;
SetBuiltinsDTS(builtinsDtsPath);
}
void JSRuntimeOptions::SetOptionsForTargetCompilation()
{
if (IsTargetCompilerMode()) {
SetTargetBuiltinsDtsPath();
SetTargetTriple("aarch64-unknown-linux-gnu");
SetEnableOptTrackField(false);
SetEnableOptInlining(false);

View File

@ -93,12 +93,9 @@ enum CommandValues {
OPTION_COMPILER_LOG_METHODS,
OPTION_COMPILER_TYPE_THRESHOLD,
OPTION_ENABLE_RUNTIME_STAT,
OPTION_COMPILER_ASSERT_TYPES,
OPTION_COMPILER_PRINT_TYPE_INFO,
OPTION_COMPILER_LOG_SNAPSHOT,
OPTION_COMPILER_LOG_TIME,
OPTION_ENABLE_WORKER,
OPTION_BUILTINS_DTS,
OPTION_COMPILER_TRACE_BC,
OPTION_COMPILER_TRACE_DEOPT,
OPTION_COMPILER_TRACE_INLINE,
@ -127,13 +124,12 @@ enum CommandValues {
OPTION_COMPILER_OPT_INLINING,
OPTION_COMPILER_OPT_PGOTYPE,
OPTION_COMPILER_OPT_TRACK_FIELD,
OPTION_COMPILER_OPT_GLOBAL_TYPEINFER,
OPTION_COMPILER_PGO_PROFILER_PATH,
OPTION_SPLIT_ONE,
OPTION_COMPILER_PGO_HOTNESS_THRESHOLD,
OPTION_COMPILER_PGO_SAVE_MIN_INTERVAL,
OPTION_ENABLE_PGO_PROFILER,
OPTION_PRINT_EXECUTE_TIME,
OPTION_SPLIT_ONE,
OPTION_COMPILER_DEVICE_STATE,
OPTION_COMPILER_VERIFY_VTABLE,
OPTION_COMPILER_SELECT_METHODS,
@ -771,41 +767,6 @@ public:
return WasOptionSet(OPTION_STARTUP_TIME);
}
bool AssertTypes() const
{
return assertTypes_;
}
void SetAssertTypes(bool value)
{
assertTypes_ = value;
}
bool PrintTypeInfo() const
{
return printTypeInfo_;
}
void SetPrintTypeInfo(bool value)
{
printTypeInfo_ = value;
}
void SetBuiltinsDTS(const std::string& value)
{
builtinsDTS_ = panda::os::file::File::GetExtendedFilePath(value);
}
bool WasSetBuiltinsDTS() const
{
return WasOptionSet(OPTION_BUILTINS_DTS);
}
std::string GetBuiltinsDTS() const
{
return builtinsDTS_;
}
void SetTraceBc(bool value)
{
traceBc_ = value;
@ -1217,16 +1178,6 @@ public:
return enableOptTrackField_;
}
void SetEnableGlobalTypeInfer(bool value)
{
enableGlobalTypeInfer_ = value;
}
bool IsEnableGlobalTypeInfer() const
{
return enableGlobalTypeInfer_;
}
uint32_t GetCompilerModuleMethods() const
{
return compilerModuleMethods_;
@ -1452,8 +1403,6 @@ public:
return compilerNoCheck_;
}
void SetTargetBuiltinsDtsPath();
void SetOptionsForTargetCompilation();
void SetFastAOTCompileMode(bool value)
@ -1760,10 +1709,7 @@ private:
bool compilerLogSnapshot_ {false};
bool compilerLogTime_ {false};
bool enableRuntimeStat_ {false};
bool assertTypes_ {false};
bool printTypeInfo_ {false};
bool isWorker_ {false};
std::string builtinsDTS_ {""};
bool traceBc_ {false};
std::string logLevel_ {"error"};
arg_list_t logDebug_ {{"all"}};
@ -1794,7 +1740,6 @@ private:
uint16_t jitHotnessThreshold_ {2};
uint16_t osrHotnessThreshold_ {2};
bool forceJitCompileMain_{false};
bool enableGlobalTypeInfer_ {false};
bool enableOptTrackField_ {true};
uint32_t compilerModuleMethods_ {100};
uint64_t wasSetPartOne_ {0};

View File

@ -1511,36 +1511,6 @@ inline bool JSTaggedValue::IsClassInfoExtractor() const
return IsHeapObject() && GetTaggedObject()->GetClass()->IsClassInfoExtractor();
}
inline bool JSTaggedValue::IsTSType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSType();
}
inline bool JSTaggedValue::IsTSObjectType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSObjectType();
}
inline bool JSTaggedValue::IsTSClassType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSClassType();
}
inline bool JSTaggedValue::IsTSInterfaceType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSInterfaceType();
}
inline bool JSTaggedValue::IsTSUnionType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSUnionType();
}
inline bool JSTaggedValue::IsTSClassInstanceType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSClassInstanceType();
}
inline bool JSTaggedValue::IsCjsExports() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsCjsExports();
@ -1556,26 +1526,6 @@ inline bool JSTaggedValue::IsCjsRequire() const
return IsHeapObject() && GetTaggedObject()->GetClass()->IsCjsRequire();
}
inline bool JSTaggedValue::IsTSFunctionType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSFunctionType();
}
inline bool JSTaggedValue::IsTSArrayType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSArrayType();
}
inline bool JSTaggedValue::IsTSIteratorInstanceType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSIteratorInstanceType();
}
inline bool JSTaggedValue::IsTSNamespaceType() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSNamespaceType();
}
inline bool JSTaggedValue::IsModuleRecord() const
{
return IsHeapObject() && GetTaggedObject()->GetClass()->IsModuleRecord();

View File

@ -659,16 +659,6 @@ public:
bool IsRegularObject() const;
bool IsMachineCodeObject() const;
bool IsClassInfoExtractor() const;
bool IsTSType() const;
bool IsTSObjectType() const;
bool IsTSClassType() const;
bool IsTSUnionType() const;
bool IsTSInterfaceType() const;
bool IsTSClassInstanceType() const;
bool IsTSFunctionType() const;
bool IsTSArrayType() const;
bool IsTSIteratorInstanceType() const;
bool IsTSNamespaceType() const;
bool IsCjsExports() const;
bool IsCjsModule() const;

View File

@ -19,7 +19,6 @@
#include "ecmascript/jspandafile/js_pandafile.h"
#include "ecmascript/jspandafile/panda_file_translator.h"
#include "ecmascript/jspandafile/debug_info_extractor.h"
#include "ecmascript/ts_types/ts_type_table.h"
#include "ecmascript/platform/mutex.h"
namespace panda {
@ -81,9 +80,6 @@ public:
{
LockHolder lock(jsPandaFileLock_);
for (const auto &item : loadedJSPandaFiles_) {
if (item.first == panda::ecmascript::TSTypeTable::DEFAULT_TYPE_VIRTUAL_NAME) {
continue;
}
if (!cb(item.second)) {
return;
}

View File

@ -1,378 +0,0 @@
/*
* Copyright (c) 2023 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/jspandafile/type_literal_extractor.h"
#include <iomanip>
#include "libpandafile/literal_data_accessor-inl.h"
#include "libpandafile/method_data_accessor-inl.h"
namespace panda::ecmascript {
using LiteralTag = panda_file::LiteralTag;
using LiteralValue = panda_file::LiteralDataAccessor::LiteralValue;
using StringData = panda_file::StringData;
using EntityId = panda_file::File::EntityId;
using LiteralDataAccessor = panda_file::LiteralDataAccessor;
static constexpr const char *TYPE_ANNO_RECORD_NAME = "L_ESTypeAnnotation;";
static bool IsLegalOffset(uint32_t offset)
{
return offset != 0U;
}
static uint32_t GetMethodAnnoOffset(const JSPandaFile *jsPandaFile, uint32_t methodOffset, const char *annoName)
{
const panda_file::File &pf = *jsPandaFile->GetPandaFile();
EntityId methodId(methodOffset);
panda_file::MethodDataAccessor mda(pf, methodId);
uint32_t annoOffset = 0;
mda.EnumerateAnnotations([&jsPandaFile, &annoName, &pf, &annoOffset](EntityId annotationId) {
panda_file::AnnotationDataAccessor ada(pf, annotationId);
auto *annotationName = reinterpret_cast<const char *>(jsPandaFile->GetStringData(ada.GetClassId()).data);
ASSERT(annotationName != nullptr);
if (::strcmp(TYPE_ANNO_RECORD_NAME, annotationName) != 0) {
return;
}
uint32_t length = ada.GetCount();
for (uint32_t i = 0; i < length; i++) {
panda_file::AnnotationDataAccessor::Elem adae = ada.GetElement(i);
auto *elemName = reinterpret_cast<const char *>(jsPandaFile->GetStringData(adae.GetNameId()).data);
ASSERT(elemName != nullptr);
if (::strcmp(annoName, elemName) != 0) {
continue;
}
panda_file::ScalarValue sv = adae.GetScalarValue();
annoOffset = sv.GetValue();
}
});
return annoOffset;
}
TypeLiteralExtractor::TypeLiteralExtractor(const JSPandaFile *jsPandaFile, const uint32_t typeOffset)
: typeOffset_(typeOffset)
{
ProcessTypeLiteral(jsPandaFile, typeOffset);
}
void TypeLiteralExtractor::ProcessTypeLiteral(const JSPandaFile *jsPandaFile, const uint32_t typeOffset)
{
EntityId literalId(typeOffset);
LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
bool isFirst = true;
lda.EnumerateLiteralVals(literalId,
[this, &jsPandaFile, &isFirst](const LiteralValue &value, const LiteralTag &tag) {
if (isFirst) {
uint32_t kindValue = std::get<uint32_t>(value);
if (UNLIKELY(!IsVaildKind(kindValue))) {
LOG_COMPILER(FATAL) << "Load type literal failure.";
return;
}
kind_ = static_cast<TSTypeKind>(std::get<uint32_t>(value));
isFirst = false;
return;
}
switch (tag) {
case LiteralTag::INTEGER: {
uint32_t valueValue = std::get<uint32_t>(value);
if (static_cast<int32_t>(valueValue) < 0) {
isGenerics_ = true;
}
array_.emplace_back(valueValue);
break;
}
case LiteralTag::LITERALARRAY: {
array_.emplace_back(std::get<uint32_t>(value));
break;
}
case LiteralTag::BUILTINTYPEINDEX: {
array_.emplace_back(static_cast<uint32_t>(std::get<uint8_t>(value)));
break;
}
case LiteralTag::STRING: {
StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
CString stringValue = utf::Mutf8AsCString(sd.data);
array_.emplace_back(stringValue);
break;
}
default: {
LOG_COMPILER(FATAL) << "TypeLiteral should not exist LiteralTag: " << static_cast<uint32_t>(tag);
break;
}
}
});
}
void TypeLiteralExtractor::Print() const
{
std::string log("[TypeLiteral] TypeOffset: ");
log += (std::to_string(typeOffset_) + ", " + PrintTypeKind(kind_));
if (isGenerics_) {
log += ", generics";
}
uint32_t length = array_.size();
log += ", [";
for (uint32_t i = 0; i < length; ++i) {
if (std::holds_alternative<uint32_t>(array_[i])) {
log += std::to_string(std::get<uint32_t>(array_[i]));
} else if (std::holds_alternative<CString>(array_[i])) {
log += std::get<CString>(array_[i]);
}
if (i == length - 1) {
log += "]";
} else {
log += ", ";
}
}
LOG_COMPILER(INFO) << log;
}
std::string TypeLiteralExtractor::PrintTypeKind(TSTypeKind typeKind) const
{
switch (typeKind) {
case TSTypeKind::CLASS:
return "class";
case TSTypeKind::CLASS_INSTANCE:
return "class_instance";
case TSTypeKind::FUNCTION:
return "function";
case TSTypeKind::UNION:
return "union";
case TSTypeKind::ARRAY:
return "array";
case TSTypeKind::OBJECT:
return "object";
case TSTypeKind::IMPORT:
return "import";
case TSTypeKind::INTERFACE:
return "interface";
case TSTypeKind::BUILTIN_INSTANCE:
return "builtin_instance";
case TSTypeKind::GENERIC_INSTANCE:
return "generic_instance";
case TSTypeKind::INDEXSIG:
return "index_signature";
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
}
TypeSummaryExtractor::TypeSummaryExtractor(const JSPandaFile *jsPandaFile, const CString &recordName)
: jsPandaFile_(jsPandaFile)
{
ProcessTypeSummary(jsPandaFile, jsPandaFile->GetTypeSummaryOffset(recordName));
}
void TypeSummaryExtractor::ProcessTypeSummary(const JSPandaFile *jsPandaFile, const uint32_t summaryOffset)
{
EntityId summaryId(summaryOffset);
LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
bool isFirstIndex = true;
lda.EnumerateLiteralVals(summaryId,
[this, &isFirstIndex, &jsPandaFile](const LiteralValue &value, const LiteralTag &tag) {
switch (tag) {
case LiteralTag::LITERALARRAY: {
typeOffsets_.emplace_back(std::get<uint32_t>(value));
break;
}
case LiteralTag::BUILTINTYPEINDEX: {
typeOffsets_.emplace_back(static_cast<uint32_t>(std::get<uint8_t>(value)));
break;
}
case LiteralTag::INTEGER: {
if (isFirstIndex) {
numOfTypes_ = std::get<uint32_t>(value);
typeOffsets_.emplace_back(numOfTypes_);
isFirstIndex = false;
} else {
numOfRedirects_ = std::get<uint32_t>(value);
}
break;
}
case LiteralTag::STRING: {
StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
CString stringValue = utf::Mutf8AsCString(sd.data);
reDirects_.emplace_back(stringValue);
break;
}
default: {
LOG_COMPILER(FATAL) << "TypeSummary should not exist LiteralTag: " << static_cast<uint32_t>(tag);
break;
}
}
});
ASSERT(typeOffsets_.size() == numOfTypes_ + 1);
ASSERT(reDirects_.size() == numOfRedirects_);
}
void TypeSummaryExtractor::Print() const
{
for (uint32_t i = 1; i <= numOfTypes_; ++i) { // 1: start index of typeOffsets
TypeLiteralExtractor(jsPandaFile_, typeOffsets_[i]).Print();
}
}
TypeAnnotationExtractor::TypeAnnotationExtractor(const JSPandaFile *jsPandaFile, const uint32_t methodOffset)
{
ProcessTypeAnnotation(jsPandaFile, methodOffset);
CollectTSMethodKind();
}
void TypeAnnotationExtractor::ProcessTypeAnnotation(const JSPandaFile *jsPandaFile, const uint32_t methodOffset)
{
uint32_t annoOffset = GetMethodAnnoOffset(jsPandaFile, methodOffset, TYPE_ANNO_ELEMENT_NAME);
if (!IsLegalOffset(annoOffset)) {
return;
}
EntityId annoId(annoOffset);
LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
lda.EnumerateLiteralVals(annoId, [this](const LiteralValue &value, const LiteralTag &tag) {
switch (tag) {
case LiteralTag::INTEGER: {
int32_t valueValue = base::bit_cast<int32_t>(std::get<uint32_t>(value));
bcOffsets_.emplace_back(valueValue);
break;
}
case LiteralTag::LITERALARRAY: {
typeIds_.emplace_back(std::get<uint32_t>(value));
tags_.emplace_back(tag);
break;
}
case LiteralTag::BUILTINTYPEINDEX: {
typeIds_.emplace_back(static_cast<uint32_t>(std::get<uint8_t>(value)));
tags_.emplace_back(tag);
break;
}
default: {
LOG_COMPILER(FATAL) << "TypeAnnotation should not exist LiteralTag: " << static_cast<uint32_t>(tag);
break;
}
}
});
ASSERT(bcOffsets_.size() == typeIds_.size());
ASSERT(tags_.size() == typeIds_.size());
}
void TypeAnnotationExtractor::CollectTSMethodKind()
{
ASSERT(bcOffsets_.size() == typeIds_.size());
uint32_t length = bcOffsets_.size();
for (uint32_t i = 0; i < length; ++i) {
if (bcOffsets_[i] != METHOD_ANNOTATION_FUNCTION_TYPE_OFFSET) {
continue;
}
if (tags_[i] != LiteralTag::BUILTINTYPEINDEX) {
methodTypeOffset_ = typeIds_[i];
return;
}
if (typeIds_[i] == METHOD_ANNOTATION_NAMESPACE) {
isNamespace_ = true;
}
typeIds_[i] = 0; // set default value
}
}
void TypeAnnotationExtractor::Print() const
{
const uint32_t typeRightAdjustment = 6;
ASSERT(bcOffsets_.size() == typeIds_.size());
ASSERT(tags_.size() == typeIds_.size());
LOG_COMPILER(INFO) << "====================================================================";
LOG_COMPILER(INFO) << "[TypeAnnotation]";
uint32_t length = bcOffsets_.size();
for (uint32_t i = 0; i < length; ++i) {
LOG_COMPILER(INFO) << "Order of bytecodes: " << std::setw(typeRightAdjustment) << bcOffsets_[i] << ", "
<< "typeId: " << std::setw(typeRightAdjustment) << typeIds_[i] << ", "
<< "tag of typeId: " << PrintTag(tags_[i]);
}
}
std::string TypeAnnotationExtractor::PrintTag(LiteralTag tag) const
{
switch (tag) {
case LiteralTag::LITERALARRAY: {
return "type literal offset";
}
case LiteralTag::BUILTINTYPEINDEX: {
return "builtin type index";
}
default: {
return "none";
}
}
}
ExportTypeTableExtractor::ExportTypeTableExtractor(const JSPandaFile *jsPandaFile,
const CString &recordName,
bool isBuiltinTable)
{
ProcessExportTable(jsPandaFile, recordName, isBuiltinTable);
}
void ExportTypeTableExtractor::ProcessExportTable(const JSPandaFile *jsPandaFile,
const CString &recordName,
bool isBuiltinTable)
{
const char *name = isBuiltinTable ? DECLARED_SYMBOL_TYPES : EXPORTED_SYMBOL_TYPES;
uint32_t methodOffset = jsPandaFile->GetMainMethodIndex(recordName);
uint32_t annoOffset = GetMethodAnnoOffset(jsPandaFile, methodOffset, name);
if (!IsLegalOffset(annoOffset)) {
return;
}
EntityId annoId(annoOffset);
LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
lda.EnumerateLiteralVals(annoId, [this, &jsPandaFile](const LiteralValue &value, const LiteralTag &tag) {
switch (tag) {
case LiteralTag::LITERALARRAY: {
typeIds_.emplace_back(std::get<uint32_t>(value));
break;
}
case LiteralTag::BUILTINTYPEINDEX: {
typeIds_.emplace_back(static_cast<uint32_t>(std::get<uint8_t>(value)));
break;
}
case LiteralTag::STRING: {
StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
exportVars_.emplace_back(utf::Mutf8AsCString(sd.data));
break;
}
default: {
LOG_COMPILER(FATAL) << "TypeExportTable should not exist LiteralTag: " << static_cast<uint32_t>(tag);
break;
}
}
});
ASSERT(exportVars_.size() == typeIds_.size());
}
void ExportTypeTableExtractor::Print() const
{
ASSERT(exportVars_.size() == typeIds_.size());
LOG_COMPILER(INFO) << "[ExportTypeTable]";
uint32_t length = typeIds_.size();
for (uint32_t i = 0; i < length; ++i) {
LOG_COMPILER(INFO) << "Export variable: " << exportVars_[i] << ", "
<< "typeId: " << typeIds_[i];
}
}
} // namespace panda::ecmascript

View File

@ -1,248 +0,0 @@
/*
* Copyright (c) 2023 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_JSPANDAFILE_TYPE_LITERAL_EXTRACTOR_H
#define ECMASCRIPT_JSPANDAFILE_TYPE_LITERAL_EXTRACTOR_H
#include "ecmascript/jspandafile/js_pandafile.h"
namespace panda::ecmascript {
class TypeLiteralExtractor {
using TypeLiteralValue = std::variant<uint32_t, CString>;
public:
explicit PUBLIC_API TypeLiteralExtractor(const JSPandaFile *jsPandaFile, const uint32_t typeOffset);
~TypeLiteralExtractor() = default;
NO_COPY_SEMANTIC(TypeLiteralExtractor);
NO_MOVE_SEMANTIC(TypeLiteralExtractor);
inline bool IsVaildTypeLiteral() const
{
return !array_.empty();
}
inline TSTypeKind GetTypeKind() const
{
return kind_;
}
inline bool IsGenerics() const
{
return isGenerics_;
}
inline uint32_t GetIntValue(const uint32_t index) const
{
ASSERT(index < array_.size());
auto t = array_[index];
ASSERT(std::holds_alternative<uint32_t>(t));
return std::get<uint32_t>(t);
}
inline const CString &GetStringValue(const uint32_t index) const
{
ASSERT(index < array_.size());
const auto &t = array_[index];
ASSERT(std::holds_alternative<CString>(t));
return std::get<CString>(t);
}
inline uint32_t GetTypeOffset() const
{
return typeOffset_;
}
template <class Callback>
void EnumerateElements(const uint32_t numIndex, const Callback &callback)
{
ASSERT(numIndex < array_.size());
uint32_t length = std::get<uint32_t>(array_[numIndex]);
ASSERT(numIndex + length < array_.size());
for (uint32_t i = 1; i <= length; i++) {
uint32_t value = GetIntValue(numIndex + i);
callback(value);
}
}
template <class Callback>
void EnumerateTypesWithIntKey(const uint32_t numIndex, const Callback &callback)
{
ASSERT(numIndex < array_.size());
const uint32_t gap = 2;
uint32_t length = std::get<uint32_t>(array_[numIndex]);
ASSERT(numIndex + length * gap < array_.size());
for (uint32_t i = 0; i < length; i++) {
uint32_t keyIndex = numIndex + i * gap + KEY_OFFSET;
uint32_t valueIndex = numIndex + i * gap + VALUE_OFFSET;
uint32_t key = GetIntValue(keyIndex);
uint32_t value = GetIntValue(valueIndex);
callback(key, value);
}
}
template <class Callback>
void EnumerateProperties(const uint32_t numIndex, const uint32_t gap, const Callback &callback)
{
ASSERT(numIndex < array_.size());
ASSERT(gap >= VALUE_OFFSET);
uint32_t length = std::get<uint32_t>(array_[numIndex]);
ASSERT(numIndex + length * gap < array_.size());
for (uint32_t i = 0; i < length; i++) {
uint32_t keyIndex = numIndex + i * gap + KEY_OFFSET;
uint32_t valueIndex = numIndex + i * gap + VALUE_OFFSET;
const CString &key = GetStringValue(keyIndex);
uint32_t value = GetIntValue(valueIndex);
callback(key, value);
}
}
void Print() const;
private:
static constexpr uint32_t KEY_OFFSET = 1;
static constexpr uint32_t VALUE_OFFSET = 2;
inline bool IsVaildKind(const uint32_t kindValue) const
{
return (static_cast<uint32_t>(TSTypeKind::TYPEKIND_FIRST) <= kindValue) &&
(kindValue <= static_cast<uint32_t>(TSTypeKind::TYPEKIND_LAST));
}
void ProcessTypeLiteral(const JSPandaFile *jsPandaFile, const uint32_t typeOffset);
std::string PrintTypeKind(TSTypeKind typeKind) const;
std::vector<TypeLiteralValue> array_;
uint32_t typeOffset_ { 0 };
TSTypeKind kind_ { TSTypeKind::UNKNOWN };
bool isGenerics_ { false };
};
class TypeSummaryExtractor {
public:
explicit TypeSummaryExtractor(const JSPandaFile *jsPandaFile, const CString &recordName);
~TypeSummaryExtractor() = default;
NO_COPY_SEMANTIC(TypeSummaryExtractor);
NO_MOVE_SEMANTIC(TypeSummaryExtractor);
template <class Callback>
void EnumerateTypeOffsets(const uint32_t lastIndex, const Callback &callback)
{
ASSERT(lastIndex < typeOffsets_.size());
for (uint32_t i = 0; i <= lastIndex; i++) {
callback(typeOffsets_[i]);
}
}
inline uint32_t GetNumOfTypes() const
{
return numOfTypes_;
}
void Print() const;
private:
void ProcessTypeSummary(const JSPandaFile *jsPandaFile, const uint32_t summaryOffset);
const JSPandaFile *jsPandaFile_ {nullptr};
std::vector<uint32_t> typeOffsets_ {};
std::vector<CString> reDirects_ {};
uint32_t numOfTypes_ { 0 };
uint32_t numOfRedirects_ { 0 };
};
class TypeAnnotationExtractor {
using LiteralTag = panda_file::LiteralTag;
public:
explicit PUBLIC_API TypeAnnotationExtractor(const JSPandaFile *jsPandaFile, const uint32_t methodOffset);
~TypeAnnotationExtractor() = default;
NO_COPY_SEMANTIC(TypeAnnotationExtractor);
NO_MOVE_SEMANTIC(TypeAnnotationExtractor);
template <class Callback>
void EnumerateInstsAndTypes(const Callback &callback)
{
ASSERT(bcOffsets_.size() == typeIds_.size());
uint32_t length = bcOffsets_.size();
for (uint32_t i = 0; i < length; i++) {
callback(bcOffsets_[i], typeIds_[i]);
}
}
uint32_t GetMethodTypeOffset() const
{
return methodTypeOffset_;
}
bool IsNamespace() const
{
return isNamespace_;
}
void PUBLIC_API Print() const;
private:
static constexpr const char *TYPE_ANNO_ELEMENT_NAME = "_TypeOfInstruction";
static constexpr int METHOD_ANNOTATION_FUNCTION_TYPE_OFFSET = -1;
static constexpr int METHOD_ANNOTATION_NAMESPACE = 255;
static constexpr int METHOD_ANNOTATION_ENUM = 254;
void ProcessTypeAnnotation(const JSPandaFile *jsPandaFile, const uint32_t methodOffset);
void CollectTSMethodKind();
std::string PrintTag(LiteralTag tag) const;
uint32_t methodTypeOffset_ {0};
std::vector<int32_t> bcOffsets_ {};
std::vector<uint32_t> typeIds_ {};
std::vector<LiteralTag> tags_ {};
bool isNamespace_ {false};
};
class ExportTypeTableExtractor {
public:
explicit ExportTypeTableExtractor(const JSPandaFile *jsPandaFile, const CString &recordName, bool isBuiltinTable);
~ExportTypeTableExtractor() = default;
NO_COPY_SEMANTIC(ExportTypeTableExtractor);
NO_MOVE_SEMANTIC(ExportTypeTableExtractor);
inline uint32_t GetLength() const
{
ASSERT(exportVars_.size() == typeIds_.size());
return exportVars_.size() + typeIds_.size();
}
template <class Callback>
void EnumerateModuleTypes(const Callback &callback)
{
ASSERT(exportVars_.size() == typeIds_.size());
uint32_t length = exportVars_.size();
for (uint32_t i = 0; i < length; i++) {
callback(exportVars_[i], typeIds_[i]);
}
}
void Print() const;
private:
static constexpr const char *DECLARED_SYMBOL_TYPES = "declaredSymbolTypes";
static constexpr const char *EXPORTED_SYMBOL_TYPES = "exportedSymbolTypes";
void ProcessExportTable(const JSPandaFile *jsPandaFile, const CString &recordName, bool isBuiltinTable);
std::vector<CString> exportVars_ {};
std::vector<uint32_t> typeIds_ {};
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JSPANDAFILE_TYPE_LITERAL_EXTRACTOR_H

View File

@ -17,6 +17,7 @@
#define ECMASCRIPT_LEXICALENV_H
#include "ecmascript/js_object.h"
#include "ecmascript/tagged_array-inl.h"
namespace panda::ecmascript {
class LexicalEnv : public TaggedArray {

View File

@ -116,8 +116,6 @@
#include "ecmascript/shared_objects/js_shared_set_iterator.h"
#include "ecmascript/shared_objects/js_shared_typed_array.h"
#include "ecmascript/tagged_node.h"
#include "ecmascript/ts_types/ts_type.h"
#include "ecmascript/ts_types/ts_type_table.h"
#include "ecmascript/require/js_cjs_module.h"
#include "ecmascript/require/js_cjs_require.h"
#include "ecmascript/require/js_cjs_exports.h"
@ -616,36 +614,6 @@ public:
case JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR:
JSAPILightWeightSetIterator::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::TS_OBJECT_TYPE:
TSObjectType::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::TS_CLASS_TYPE:
TSClassType::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::TS_UNION_TYPE:
TSUnionType::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::TS_INTERFACE_TYPE:
TSInterfaceType::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::TS_CLASS_INSTANCE_TYPE:
break;
case JSType::TS_FUNCTION_TYPE:
TSFunctionType::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::TS_ARRAY_TYPE:
if (visitType == VisitType::ALL_VISIT) {
TSArrayType::Cast(object)->VisitRangeSlot<visitType>(visitor);
}
break;
case JSType::TS_ITERATOR_INSTANCE_TYPE:
if (visitType == VisitType::ALL_VISIT) {
TSIteratorInstanceType::Cast(object)->VisitRangeSlot<visitType>(visitor);
}
break;
case JSType::TS_NAMESPACE_TYPE:
TSNamespaceType::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;
case JSType::RB_TREENODE:
RBTreeNode::Cast(object)->VisitRangeSlot<visitType>(visitor);
break;

View File

@ -139,9 +139,6 @@
#include "ecmascript/tagged_node.h"
#include "ecmascript/tagged_tree.h"
#include "ecmascript/template_map.h"
#include "ecmascript/ts_types/ts_obj_layout_info.h"
#include "ecmascript/ts_types/ts_type.h"
#include "ecmascript/ts_types/ts_type_table.h"
#include "ecmascript/vtable.h"
#ifdef ARK_SUPPORT_INTL
#include "ecmascript/js_collator.h"
@ -3916,193 +3913,6 @@ JSHandle<ClassInfoExtractor> ObjectFactory::NewClassInfoExtractor(JSHandle<JSTag
return obj;
}
// ----------------------------------- new TSType ----------------------------------------
JSHandle<TSObjLayoutInfo> ObjectFactory::CreateTSObjLayoutInfo(int propNum, JSTaggedValue initVal)
{
uint32_t arrayLength = TSObjLayoutInfo::ComputeArrayLength(propNum);
JSHandle<TSObjLayoutInfo> tsPropInfoHandle = JSHandle<TSObjLayoutInfo>::Cast(NewTaggedArray(arrayLength, initVal));
tsPropInfoHandle->SetNumOfProperties(thread_, 0);
return tsPropInfoHandle;
}
JSHandle<TSObjectType> ObjectFactory::NewTSObjectType(uint32_t numOfKeys)
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSObjectTypeClass().GetTaggedObject()));
JSHandle<TSObjectType> objectType(thread_, header);
objectType->SetObjLayoutInfo(thread_, JSTaggedValue::Undefined());
objectType->SetIndexSigns(thread_, JSTaggedValue::Undefined());
objectType->SetGT(GlobalTSTypeRef::Default());
JSHandle<TSObjLayoutInfo> tsPropInfo = CreateTSObjLayoutInfo(numOfKeys);
objectType->SetObjLayoutInfo(thread_, tsPropInfo);
return objectType;
}
JSHandle<TSClassType> ObjectFactory::NewTSClassType()
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSClassTypeClass().GetTaggedObject()));
JSHandle<TSClassType> classType(thread_, header);
classType->SetGT(GlobalTSTypeRef::Default());
classType->SetInstanceType(thread_, JSTaggedValue::Undefined());
classType->SetConstructorType(thread_, JSTaggedValue::Undefined());
classType->SetPrototypeType(thread_, JSTaggedValue::Undefined());
classType->SetName(thread_, JSTaggedValue::Undefined());
classType->SetIndexSigns(thread_, JSTaggedValue::Undefined());
classType->SetExtensionGT(GlobalTSTypeRef::Default());
classType->ClearBitField();
return classType;
}
JSHandle<TSInterfaceType> ObjectFactory::NewTSInterfaceType()
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSInterfaceTypeClass().GetTaggedObject()));
JSHandle<TSInterfaceType> interfaceType(thread_, header);
JSHandle<TaggedArray> extends = EmptyArray();
interfaceType->SetGT(GlobalTSTypeRef::Default());
interfaceType->SetExtends(thread_, extends);
interfaceType->SetFields(thread_, JSTaggedValue::Undefined());
interfaceType->SetIndexSigns(thread_, JSTaggedValue::Undefined());
return interfaceType;
}
JSHandle<TSUnionType> ObjectFactory::NewTSUnionType(uint32_t length)
{
NewObjectHook();
ASSERT(length > 0);
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSUnionTypeClass().GetTaggedObject()));
JSHandle<TSUnionType> unionType(thread_, header);
unionType->SetGT(GlobalTSTypeRef::Default());
unionType->SetComponents(thread_, JSTaggedValue::Undefined());
JSHandle<TaggedArray> componentTypes = NewTaggedArray(length, JSTaggedValue::Undefined());
unionType->SetComponents(thread_, componentTypes);
return unionType;
}
JSHandle<TSClassInstanceType> ObjectFactory::NewTSClassInstanceType()
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSClassInstanceTypeClass().GetTaggedObject()));
JSHandle<TSClassInstanceType> classInstanceType(thread_, header);
classInstanceType->SetGT(GlobalTSTypeRef::Default());
classInstanceType->SetClassGT(GlobalTSTypeRef::Default());
return classInstanceType;
}
JSHandle<TSFunctionType> ObjectFactory::NewTSFunctionType(uint32_t length)
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSFunctionTypeClass().GetTaggedObject()));
JSHandle<TSFunctionType> functionType(thread_, header);
functionType->SetGT(GlobalTSTypeRef::Default());
functionType->SetName(thread_, JSTaggedValue::Undefined());
functionType->SetParameterTypes(thread_, JSTaggedValue::Undefined());
functionType->SetReturnGT(GlobalTSTypeRef::Default());
functionType->SetThisGT(GlobalTSTypeRef::Default());
functionType->ClearBitField();
functionType->SetMethodOffset(0);
JSHandle<TaggedArray> parameterTypes = NewTaggedArray(length, JSTaggedValue::Undefined());
functionType->SetParameterTypes(thread_, parameterTypes);
return functionType;
}
JSHandle<TSArrayType> ObjectFactory::NewTSArrayType()
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSArrayTypeClass().GetTaggedObject()));
JSHandle<TSArrayType> arrayType(thread_, header);
arrayType->SetElementGT(GlobalTSTypeRef::Default());
return arrayType;
}
JSHandle<TSTypeTable> ObjectFactory::NewTSTypeTable(uint32_t length)
{
NewObjectHook();
size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length + TSTypeTable::RESERVE_TABLE_LENGTH);
JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
auto header = heap_->AllocateOldOrHugeObject(arrayClass, size);
JSHandle<TSTypeTable> table(thread_, header);
table->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length + TSTypeTable::RESERVE_TABLE_LENGTH);
table->SetNumberOfTypes(thread_);
return table;
}
JSHandle<TSModuleTable> ObjectFactory::NewTSModuleTable(uint32_t length)
{
NewObjectHook();
ASSERT(length > 0);
size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
auto header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
JSHandle<TSModuleTable> array(thread_, header);
array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
array->SetNumberOfTSTypeTables(thread_, 0);
return array;
}
JSHandle<TSIteratorInstanceType> ObjectFactory::NewTSIteratorInstanceType()
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSIteratorInstanceTypeClass().GetTaggedObject()));
JSHandle<TSIteratorInstanceType> iteratorInstanceType(thread_, header);
iteratorInstanceType->SetGT(GlobalTSTypeRef::Default());
iteratorInstanceType->SetKindGT(GlobalTSTypeRef::Default());
iteratorInstanceType->SetElementGT(GlobalTSTypeRef::Default());
return iteratorInstanceType;
}
JSHandle<TSNamespaceType> ObjectFactory::NewTSNamespaceType()
{
NewObjectHook();
TaggedObject *header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetTSNamespaceTypeClass().GetTaggedObject()));
JSHandle<TSNamespaceType> namespaceType(thread_, header);
namespaceType->SetPropertyType(thread_, JSTaggedValue::Undefined());
JSHandle<TSObjLayoutInfo> tsPropInfo = CreateTSObjLayoutInfo(TSObjLayoutInfo::DEFAULT_CAPACITY);
namespaceType->SetPropertyType(thread_, tsPropInfo);
return namespaceType;
}
// ----------------------------------- new string ----------------------------------------
JSHandle<EcmaString> ObjectFactory::NewFromASCII(std::string_view data)
{

View File

@ -106,19 +106,6 @@ class LayoutInfo;
class JSIntlBoundFunction;
class FreeObject;
class JSNativePointer;
class TSModuleTable;
class TSTypeTable;
class TSObjLayoutInfo;
class TSType;
class TSObjectType;
class TSClassType;
class TSUnionType;
class TSInterfaceType;
class TSClassInstanceType;
class TSFunctionType;
class TSArrayType;
class TSIteratorInstanceType;
class TSNamespaceType;
class JSAPIArrayList;
class JSAPIArrayListIterator;
class JSAPIDeque;
@ -571,20 +558,6 @@ public:
JSHandle<ClassInfoExtractor> NewClassInfoExtractor(JSHandle<JSTaggedValue> method);
JSHandle<ClassLiteral> NewClassLiteral();
// ----------------------------------- new TSType ----------------------------------------
JSHandle<TSObjLayoutInfo> CreateTSObjLayoutInfo(int propNum, JSTaggedValue initVal = JSTaggedValue::Hole());
JSHandle<TSObjectType> NewTSObjectType(uint32_t numOfKeys);
JSHandle<TSClassType> NewTSClassType();
JSHandle<TSUnionType> NewTSUnionType(uint32_t length);
JSHandle<TSInterfaceType> NewTSInterfaceType();
JSHandle<TSClassInstanceType> NewTSClassInstanceType();
JSHandle<TSTypeTable> NewTSTypeTable(uint32_t length);
JSHandle<TSModuleTable> NewTSModuleTable(uint32_t length);
JSHandle<TSFunctionType> NewTSFunctionType(uint32_t length);
JSHandle<TSArrayType> NewTSArrayType();
JSHandle<TSIteratorInstanceType> NewTSIteratorInstanceType();
JSHandle<TSNamespaceType> NewTSNamespaceType();
// ----------------------------------- new string ----------------------------------------
JSHandle<EcmaString> PUBLIC_API NewFromASCII(std::string_view data);
JSHandle<EcmaString> PUBLIC_API NewFromUtf8(std::string_view data);
@ -877,7 +850,6 @@ private:
friend class GlobalEnvConstants;
friend class EcmaString;
friend class SnapshotProcessor;
friend class TSManager;
friend class SingleCharTable;
void InitObjectFields(const TaggedObject *object);

View File

@ -147,7 +147,7 @@ HWTEST_F_L0(OhosTest, OhosPkgArgsParse)
runtimeOptions_.SetPGOProfilerPath(runtimeAp);
runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(""));
CompilationOptions cOptions(vm_, runtimeOptions_);
CompilationOptions cOptions(runtimeOptions_);
AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
OhosPkgArgs::ParseArgs(preProcessor, cOptions);
@ -169,7 +169,7 @@ HWTEST_F_L0(OhosTest, OhosPkgArgsParsePgoDir)
arg_list_t pandaFileNames {};
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
PGOProfilerDecoder decoder;
CompilationOptions cOptions(vm_, runtimeOptions_);
CompilationOptions cOptions(runtimeOptions_);
AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
OhosPkgArgs::ParseArgs(preProcessor, cOptions);
@ -192,7 +192,7 @@ HWTEST_F_L0(OhosTest, UseBaselineApFromPgoDir)
arg_list_t pandaFileNames {};
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
PGOProfilerDecoder decoder;
CompilationOptions cOptions(vm_, runtimeOptions_);
CompilationOptions cOptions(runtimeOptions_);
AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
// Input format is correct, but there is no available ap file for pgoDir, return success.
@ -220,7 +220,7 @@ HWTEST_F_L0(OhosTest, UseRuntimeApWhenOnlyRuntimeExits)
arg_list_t pandaFileNames {};
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
PGOProfilerDecoder decoder;
CompilationOptions cOptions(vm_, runtimeOptions_);
CompilationOptions cOptions(runtimeOptions_);
AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
ASSERT_TRUE(FileExist(runtimeAp.c_str()));
@ -250,7 +250,7 @@ HWTEST_F_L0(OhosTest, UseMergedApWhenOnlyMergedExist)
arg_list_t pandaFileNames {};
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
PGOProfilerDecoder decoder;
CompilationOptions cOptions(vm_, runtimeOptions_);
CompilationOptions cOptions(runtimeOptions_);
AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
ASSERT_TRUE(preProcessor.HandleTargetCompilerMode(cOptions));
@ -280,7 +280,7 @@ HWTEST_F_L0(OhosTest, UseMergedApWhenBothRuntimeAndMergedExist)
arg_list_t pandaFileNames {};
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
PGOProfilerDecoder decoder;
CompilationOptions cOptions(vm_, runtimeOptions_);
CompilationOptions cOptions(runtimeOptions_);
AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
ASSERT_TRUE(OhosPkgArgs::ParseArgs(preProcessor, cOptions));

View File

@ -46,7 +46,6 @@ foreach(file, test_js_files) {
extra_args = []
extra_args += [ "--module" ]
extra_args += [ "--merge-abc" ]
extra_args += [ "--type-extractor" ]
in_puts = [ test_js ]
out_puts = [ test_abc ]
}

View File

@ -18,6 +18,7 @@
#include <cerrno>
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/global_env.h"
#include "ecmascript/jobs/micro_job_queue.h"

View File

@ -25,7 +25,6 @@
#include "ecmascript/snapshot/mem/snapshot.h"
#include "ecmascript/snapshot/mem/snapshot_processor.h"
#include "ecmascript/snapshot/tests/snapshot_mock.h"
#include "ecmascript/ts_types/ts_manager.h"
using namespace panda::ecmascript;

View File

@ -46,7 +46,6 @@
#include "ecmascript/runtime.h"
#include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h"
#include "ecmascript/template_string.h"
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript {
using ArrayHelper = base::ArrayHelper;

View File

@ -74,10 +74,8 @@
#include "ecmascript/object_factory.h"
#include "ecmascript/pgo_profiler/pgo_profiler.h"
#include "ecmascript/stubs/runtime_stubs.h"
#include "ecmascript/subtyping_operator.h"
#include "ecmascript/tagged_dictionary.h"
#include "ecmascript/tagged_node.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "ecmascript/linked_hash_table.h"
#include "ecmascript/builtins/builtins_object.h"
#include "libpandafile/bytecode_instruction-inl.h"
@ -541,9 +539,6 @@ DEF_RUNTIME_STUBS(UpdateLayOutAndAddTransition)
JSHClass::AddPropertyToNewHClass(thread, oldHClassHandle, newHClassHandle, keyHandle, attrValue);
if (oldHClassHandle->HasTSSubtyping()) {
SubtypingOperator::TryMaintainTSSubtyping(thread, oldHClassHandle, newHClassHandle, keyHandle);
}
return JSTaggedValue::Hole().GetRawData();
}

View File

@ -1,131 +0,0 @@
/*
* Copyright (c) 2023 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_SUBTYPING_OPERATOR_INL_H
#define ECMASCRIPT_SUBTYPING_OPERATOR_INL_H
#include "ecmascript/subtyping_operator.h"
namespace panda::ecmascript {
template<class T>
int SubtypingOperator::GetElementByKey(const JSThread *thread, T *obj, JSTaggedValue key)
{
if constexpr(std::is_same_v<T, TSObjLayoutInfo>) {
return obj->GetElementIndexByKey(key);
} else if constexpr(std::is_same_v<T, VTable>) {
return obj->GetTupleIndexByName(key);
} else if constexpr(std::is_same_v<T, JSHClass>) {
LayoutInfo *objLayout = LayoutInfo::Cast(obj->GetLayout().GetTaggedObject());
return objLayout->FindElementWithCache(thread, obj, key, obj->NumberOfProps());
}
return -1;
}
template<class T>
bool SubtypingOperator::IsLegalElement(const JSThread *thread, T *obj, JSTaggedValue key, JSTaggedValue expectedType)
{
// when the property of the subtyping does not exist on the parent class,
// or exists and has the same type, the property is considered legal
if constexpr(std::is_same_v<T, TSObjLayoutInfo>) {
int index = obj->GetElementIndexByKey(key);
if (index != -1 && obj->GetTypeId(index) != expectedType) {
return false;
}
} else if constexpr(std::is_same_v<T, VTable>) {
int index = obj->GetTupleIndexByName(key);
if (index != -1) {
// type: ture --> isAccessor, false --> normal function
ASSERT(expectedType.IsBoolean());
bool isAccessor = expectedType.IsTrue();
if (obj->IsAccessor(index) != isAccessor) {
return false;
}
}
} else if constexpr(std::is_same_v<T, JSHClass>) {
LayoutInfo *objLayout = LayoutInfo::Cast(obj->GetLayout().GetTaggedObject());
int index = objLayout->FindElementWithCache(thread, obj, key, obj->NumberOfProps());
if (index != -1) {
// type: ture --> isAccessor, false --> normal function
ASSERT(expectedType.IsBoolean());
PropertyAttributes attr(objLayout->GetAttr(index));
bool isAccessor = expectedType.IsTrue();
if (attr.IsAccessor() != isAccessor) {
return false;
}
}
}
return true;
}
template<class T>
uint32_t SubtypingOperator::GetLength(T *obj)
{
if constexpr(std::is_same_v<T, TSObjLayoutInfo>) {
return obj->GetNumOfProperties();
} else {
return 0;
}
}
template<class T>
JSTaggedValue SubtypingOperator::GetKey(T *obj, uint32_t index)
{
if constexpr(std::is_same_v<T, TSObjLayoutInfo>) {
return obj->GetKey(index);
} else {
return JSTaggedValue::Undefined();
}
}
template<class T>
JSTaggedValue SubtypingOperator::GetType(const JSThread *thread, T *obj, uint32_t index, ConditionType ConditionType)
{
if constexpr(std::is_same_v<T, TSObjLayoutInfo>) {
if (ConditionType == ConditionType::SUB_LOCAL_CONTAIN_SUP_LOCAL) {
return obj->GetTypeId(index);
} else if (ConditionType == ConditionType::SUB_VTABLE_CONTAIN_SUP_VTABLE) {
TSManager *tsManager = const_cast<JSThread*>(thread)->GetCurrentEcmaContext()->GetTSManager();
GlobalTSTypeRef typeGT = GlobalTSTypeRef(obj->GetTypeId(index).GetInt());
return JSTaggedValue(tsManager->IsGetterSetterFunc(typeGT));
}
}
return JSTaggedValue::Undefined();
}
template<class Suber, class Super>
bool SubtypingOperator::SubtypingCondition(const JSThread *thread, Suber *suber, Super *super,
ConditionType ConditionType)
{
uint32_t len = GetLength(suber);
for (uint32_t index = 0; index < len; ++index) {
JSTaggedValue key = GetKey(suber, index);
ASSERT(!key.IsUndefined());
if (ConditionType == ConditionType::SUB_LOCAL_CONTAIN_SUP_LOCAL ||
ConditionType == ConditionType::SUB_VTABLE_CONTAIN_SUP_VTABLE) {
JSTaggedValue type = GetType(thread, suber, index, ConditionType);
ASSERT(!type.IsUndefined());
if (!IsLegalElement(thread, super, key, type)) {
return false;
}
} else {
if (GetElementByKey(thread, super, key) != -1) {
return false;
}
}
}
return true;
}
} // namespace panda::ecmascript
#endif // ECMASCRIPT_SUBTYPING_OPERATOR_INL_H

View File

@ -1,266 +0,0 @@
/*
* Copyright (c) 2023 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/global_env.h"
#include "ecmascript/ic/proto_change_details.h"
#include "ecmascript/subtyping_operator-inl.h"
#include "ecmascript/vtable.h"
namespace panda::ecmascript {
bool SubtypingOperator::CheckBaseClass(const JSThread *thread, const JSHandle<TSClassType> &classType)
{
// the base class type does not need to check rules 2 and 4, because Object has no local properties
TSObjectType *it = TSObjectType::Cast(classType->GetInstanceType().GetTaggedObject());
TSObjLayoutInfo *itLayout = TSObjLayoutInfo::Cast(it->GetObjLayoutInfo().GetTaggedObject());
TSObjectType *pt = TSObjectType::Cast(classType->GetPrototypeType().GetTaggedObject());
TSObjLayoutInfo *ptLayout = TSObjLayoutInfo::Cast(pt->GetObjLayoutInfo().GetTaggedObject());
// itLayout -> local, ptLayout -> vtable
if (!SubtypingCondition(thread, itLayout, ptLayout, ConditionType::NO_OVERLAP_SUB_LOCAL_SUB_VTABLE)) {
return false;
}
JSHandle<panda::ecmascript::GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
JSHClass *oProtoHClass = JSHClass::Cast(env->GetObjectFunctionPrototypeClass()->GetTaggedObject());
if (!SubtypingCondition(thread, ptLayout, oProtoHClass, ConditionType::SUB_VTABLE_CONTAIN_SUP_VTABLE) ||
!SubtypingCondition(thread, itLayout, oProtoHClass, ConditionType::NO_OVERLAP_SUP_VTABLE_SUB_LOCAL)) {
return false;
}
return true;
}
bool SubtypingOperator::CheckSubtyping(const JSThread *thread, const JSHandle<TSClassType> &classType)
{
TSManager *tsManager = const_cast<JSThread*>(thread)->GetCurrentEcmaContext()->GetTSManager();
JSHandle<TSClassType> eClassType = tsManager->GetExtendedClassType(classType);
JSHClass *eIhc = JSHClass::Cast(tsManager->GetInstanceTSHClass(eClassType).GetTaggedObject());
WeakVector *eSupers = WeakVector::Cast(eIhc->GetSupers().GetTaggedObject());
// if the supers of extended IHClass is empty, means the chain is broken
// will be overwritten by IsTSChainInfoFilled() in PR Part2.
if (eSupers->Empty() || eIhc->GetLevel() + 1 == MAX_LEVEL) {
return false;
}
TSObjectType *it = TSObjectType::Cast(classType->GetInstanceType().GetTaggedObject());
TSObjLayoutInfo *itLayout = TSObjLayoutInfo::Cast(it->GetObjLayoutInfo().GetTaggedObject());
TSObjectType *pt = TSObjectType::Cast(classType->GetPrototypeType().GetTaggedObject());
TSObjLayoutInfo *ptLayout = TSObjLayoutInfo::Cast(pt->GetObjLayoutInfo().GetTaggedObject());
TSObjectType *eIt = TSObjectType::Cast(eClassType->GetInstanceType().GetTaggedObject());
TSObjLayoutInfo *eItLayout = TSObjLayoutInfo::Cast(eIt->GetObjLayoutInfo().GetTaggedObject());
VTable *eVtable = VTable::Cast(eIhc->GetVTable().GetTaggedObject());
// itLayout -> local, eItLayout -> extended local
// ptLayout -> vtable, eVtable -> extended vtable
if (!SubtypingCondition(thread, itLayout, ptLayout, ConditionType::NO_OVERLAP_SUB_LOCAL_SUB_VTABLE) ||
!SubtypingCondition(thread, itLayout, eItLayout, ConditionType::SUB_LOCAL_CONTAIN_SUP_LOCAL) ||
!SubtypingCondition(thread, ptLayout, eVtable, ConditionType::SUB_VTABLE_CONTAIN_SUP_VTABLE) ||
!SubtypingCondition(thread, ptLayout, eItLayout, ConditionType::NO_OVERLAP_SUP_LOCAL_SUB_VTABLE) ||
!SubtypingCondition(thread, itLayout, eVtable, ConditionType::NO_OVERLAP_SUP_VTABLE_SUB_LOCAL)) {
return false;
}
return true;
}
void SubtypingOperator::MergeClassField(const JSThread *thread, const JSHandle<TSClassType> &classType)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
TSManager *tsManager = const_cast<JSThread*>(thread)->GetCurrentEcmaContext()->GetTSManager();
JSHandle<TSClassType> eClassType = tsManager->GetExtendedClassType(classType);
JSHandle<TSObjectType> field(thread, classType->GetInstanceType());
TSObjectType *eField = TSObjectType::Cast(eClassType->GetInstanceType());
JSHandle<TSObjLayoutInfo> layout(thread, field->GetObjLayoutInfo());
JSHandle<TSObjLayoutInfo> eLayout(thread, eField->GetObjLayoutInfo());
uint32_t numSelfTypes = layout->GetNumOfProperties();
uint32_t numExtendTypes = eLayout->GetNumOfProperties();
uint32_t numTypes = numSelfTypes + numExtendTypes;
JSHandle<TSObjLayoutInfo> newLayout = factory->CreateTSObjLayoutInfo(numTypes);
for (uint32_t index = 0; index < numExtendTypes; index++) {
JSTaggedValue key = eLayout->GetKey(index);
JSTaggedValue type = eLayout->GetTypeId(index);
JSTaggedValue attribute = eLayout->GetAttribute(index);
newLayout->AddProperty(thread, key, type, attribute);
}
for (uint32_t index = 0; index < numSelfTypes; index++) {
JSTaggedValue key = layout->GetKey(index);
if (eLayout->Find(key)) {
continue;
}
JSTaggedValue type = layout->GetTypeId(index);
JSTaggedValue attribute = layout->GetAttribute(index);
newLayout->AddProperty(thread, key, type, attribute);
}
field->SetObjLayoutInfo(thread, newLayout);
classType->SetHasLinked(true);
}
void SubtypingOperator::FillTSInheritInfo(JSThread *thread, const JSHandle<TSClassType> &classType,
const JSHandle<JSHClass> &ihcHandle)
{
TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
JSObject *prototype = JSObject::Cast(ihcHandle->GetProto());
JSHandle<JSHClass> phcHandle(thread, prototype->GetJSHClass());
JSHandle<JSHClass> eIhcHandle(thread, JSTaggedValue::Undefined());
if (classType->IsBaseClassType()) {
GenVTable(thread, ihcHandle, phcHandle, eIhcHandle);
ihcHandle->SetLevel(0);
AddSuper(thread, ihcHandle, eIhcHandle);
} else {
// get extended instance TSHclass
JSHandle<TSClassType> eClassType = tsManager->GetExtendedClassType(classType);
JSTaggedValue eIhc = tsManager->GetInstanceTSHClass(eClassType);
eIhcHandle = JSHandle<JSHClass>(thread, eIhc);
uint8_t eIhcLevel = eIhcHandle->GetLevel();
JSHandle<JSObject> ePrototype(thread, eIhcHandle->GetProto());
GenVTable(thread, ihcHandle, phcHandle, eIhcHandle);
ihcHandle->SetLevel(eIhcLevel + 1);
AddSuper(thread, ihcHandle, eIhcHandle);
}
}
void SubtypingOperator::GenVTable(const JSThread *thread, const JSHandle<JSHClass> &ihcHandle,
const JSHandle<JSHClass> &phcHandle, const JSHandle<JSHClass> &eIhcHandle)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSTaggedValue> owner(thread, ihcHandle->GetProto());
uint32_t propNumber = phcHandle->NumberOfProps();
JSMutableHandle<VTable> eVTable(thread, JSTaggedValue::Undefined());
uint32_t ePropNumber = 0;
if (!eIhcHandle.GetTaggedValue().IsUndefined()) {
eVTable.Update(eIhcHandle->GetVTable());
ePropNumber = eVTable->GetNumberOfTuples();
}
uint32_t loc = 0;
uint32_t finalLength = propNumber + ePropNumber;
JSHandle<VTable> vtable = factory->NewVTable(finalLength);
for (uint32_t index = 0; index < ePropNumber; ++index) {
VTable::Tuple tuple = eVTable->GetTuple(thread, index);
vtable->SetByIndex(thread, loc++, tuple);
}
for (uint32_t index = 0; index < propNumber; ++index) {
VTable::Tuple tuple = VTable::CreateTuple(thread, phcHandle.GetTaggedValue(), owner, index);
JSTaggedValue nameVal = tuple.GetItem(VTable::TupleItem::NAME).GetTaggedValue();
// When the vtable and the parent class vtable have the same name attribute,
// the attribute of the parent class vtable should be overwritten
int tIndex = vtable->GetTupleIndexByName(nameVal);
if (tIndex == -1) {
vtable->SetByIndex(thread, loc++, tuple);
} else {
vtable->SetByIndex(thread, tIndex, tuple);
}
}
if (loc != finalLength) {
vtable->Trim(thread, loc);
}
ihcHandle->SetVTable(thread, vtable);
}
void SubtypingOperator::AddSuper(const JSThread *thread, const JSHandle<JSHClass> &iHClass,
const JSHandle<JSHClass> &superHClass)
{
JSHandle<WeakVector> old;
if (superHClass.GetTaggedValue().IsUndefined()) {
old = JSHandle<WeakVector>(thread, iHClass->GetSupers());
} else {
old = JSHandle<WeakVector>(thread, superHClass->GetSupers());
}
JSHandle<WeakVector> supersHandle = WeakVector::Copy(thread, old, old->Full());
JSHandle<JSTaggedValue> iHClassVal(iHClass);
JSHandle<WeakVector> newSupers = WeakVector::Append(thread, supersHandle,
iHClassVal, WeakVector::ElementType::WEAK);
iHClass->SetSupers(thread, newSupers);
}
// when add property in local, try maintain.
void SubtypingOperator::TryMaintainTSSubtyping(const JSThread *thread, const JSHandle<JSHClass> &oldHClass,
JSHandle<JSHClass> &newHClass, const JSHandle<JSTaggedValue> &key)
{
if (!key->IsString()) { // symbol
return;
}
ASSERT(!oldHClass->IsPrototype()); // normal object hclass
JSHandle<VTable> vtable(thread, oldHClass->GetVTable());
ASSERT(!vtable.GetTaggedValue().IsUndefined());
ASSERT(vtable->GetNumberOfTuples() > 0); // there have default key 'constructor' at least
if (vtable->Find(key.GetTaggedValue())) { // new key shadows vtable property
LOG_ECMA(DEBUG) << "TryMaintainTSSubtyping failed, key: "
<< ConvertToString(EcmaString::Cast(key->GetTaggedObject()));
return;
}
// Add newHClass to phc's listeners
JSHandle<JSTaggedValue> prototype(thread, oldHClass->GetPrototype());
ASSERT(prototype->IsClassPrototype());
JSHandle<JSHClass> phc(thread, prototype->GetTaggedObject()->GetClass());
// If hclass has inherit info, it had been registered on proto chain, details and listeners must not be Undefined.
JSHandle<ProtoChangeDetails> details(thread, phc->GetProtoChangeDetails());
JSHandle<ChangeListener> listeners(thread, details->GetChangeListener());
uint32_t registerIndex = 0;
JSHandle<ChangeListener> newListeners = ChangeListener::Add(thread, listeners, newHClass, &registerIndex);
if (UNLIKELY(registerIndex == TaggedArray::MAX_ARRAY_INDEX)) {
return;
}
// maintaining succeeds
details->SetChangeListener(thread, newListeners);
JSHClass::CopyTSInheritInfo(thread, oldHClass, newHClass);
}
// when add property on prototype, try maintain.
bool SubtypingOperator::TryMaintainTSSubtypingOnPrototype(const JSThread *thread, const JSHandle<JSHClass> &hclass,
const JSHandle<JSTaggedValue> &key)
{
ASSERT(key->IsString());
JSHandle<VTable> vtable(thread, hclass->GetVTable());
ASSERT(vtable->GetNumberOfTuples() > 0); // there have default key 'constructor' at least
if (vtable->Find(key.GetTaggedValue())) { // new key shadows vtable property
LOG_ECMA(DEBUG) << "TryMaintainTSSubtypingOnPrototype failed, key: "
<< ConvertToString(EcmaString::Cast(key->GetTaggedObject()));
return false;
}
int entry = JSHClass::FindPropertyEntry(thread, *hclass, key.GetTaggedValue());
if (entry != -1) { // new key shadows loacl property
LOG_ECMA(DEBUG) << "TryMaintainTSSubtypingOnPrototype failed, key: "
<< ConvertToString(EcmaString::Cast(key->GetTaggedObject()));
return false;
}
return true;
}
} // namespace panda::ecmascript

View File

@ -1,92 +0,0 @@
/*
* Copyright (c) 2023 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_SUBTYPING_OPERATOR_H
#define ECMASCRIPT_SUBTYPING_OPERATOR_H
#include "ecmascript/ts_types/ts_type.h"
namespace panda::ecmascript {
class SubtypingOperator {
public:
static constexpr uint32_t DEFAULT_SUPERS_CAPACITY = 4;
PUBLIC_API static bool CheckBaseClass(const JSThread *thread, const JSHandle<TSClassType> &classType);
PUBLIC_API static bool CheckSubtyping(const JSThread *thread, const JSHandle<TSClassType> &classType);
PUBLIC_API static void MergeClassField(const JSThread *thread, const JSHandle<TSClassType> &classType);
PUBLIC_API static void FillTSInheritInfo(JSThread *thread, const JSHandle<TSClassType> &classType,
const JSHandle<JSHClass> &ihcHandle);
static void GenVTable(const JSThread *thread, const JSHandle<JSHClass> &ihcHandle,
const JSHandle<JSHClass> &phcHandle, const JSHandle<JSHClass> &eIhcHandle);
static void TryMaintainTSSubtyping(const JSThread *thread, const JSHandle<JSHClass> &oldHClass,
JSHandle<JSHClass> &newHClass, const JSHandle<JSTaggedValue> &key);
static bool TryMaintainTSSubtypingOnPrototype(const JSThread *thread, const JSHandle<JSHClass> &hclass,
const JSHandle<JSTaggedValue> &key);
private:
static constexpr uint8_t MAX_LEVEL = 1 << JSHClass::LEVEL_BTTFIELD_NUM;
/* rule check operations will check whether the properties in the Local and Vtable
* of TSHClass meet the requirements for establishing a TSHClass chain.The local
* properties refer to the properties that exists on the object instance, and the
* vtable properties refers to the properties of its ancestor prototype objects
* (such as accessor, method, and ordinary property in special cases)
*
* if B extends A
* specific requirements are as follows (N: name, T: type):
* 1. local_N(B) vtable_N(B) =
* 2. local(A) local(B)
* 3. vtable_NT(A) vtable_NT(B)
* 4. local_N(A) vtable_N(B) =
* 5. vtable_N(A) local_N(B) =
*/
enum class ConditionType : uint8_t {
NO_OVERLAP_SUB_LOCAL_SUB_VTABLE = 0,
SUB_LOCAL_CONTAIN_SUP_LOCAL,
SUB_VTABLE_CONTAIN_SUP_VTABLE,
NO_OVERLAP_SUP_LOCAL_SUB_VTABLE,
NO_OVERLAP_SUP_VTABLE_SUB_LOCAL,
};
template<class T>
static int GetElementByKey(const JSThread *thread, T *obj, JSTaggedValue key);
template<class T>
static bool IsLegalElement(const JSThread *thread, T *obj, JSTaggedValue key, JSTaggedValue expectedType);
template<class T>
static uint32_t GetLength(T *obj);
template<class T>
static JSTaggedValue GetKey(T *obj, uint32_t index);
template<class T>
static JSTaggedValue GetType(const JSThread *thread, T *obj, uint32_t index, ConditionType ConditionType);
template<class Suber, class Super>
static bool SubtypingCondition(const JSThread *thread, Suber *suber, Super *super, ConditionType ConditionType);
static void AddSuper(const JSThread *thread, const JSHandle<JSHClass> &iHClass,
const JSHandle<JSHClass> &extendHClass);
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_SUBTYPING_OPERATOR_H

View File

@ -130,7 +130,6 @@
#include "ecmascript/template_map.h"
#include "ecmascript/tests/test_helper.h"
#include "ecmascript/transitions_dictionary.h"
#include "ecmascript/ts_types/ts_type.h"
#include "ecmascript/require/js_cjs_module.h"
#include "ecmascript/require/js_cjs_require.h"
#include "ecmascript/require/js_cjs_exports.h"
@ -1183,60 +1182,6 @@ HWTEST_F_L0(EcmaDumpTest, HeapProfileDump)
DUMP_FOR_HANDLE(classInfoExtractor);
break;
}
case JSType::TS_OBJECT_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSObjectType::SIZE, 3U);
JSHandle<TSObjectType> objectType = factory->NewTSObjectType(0);
DUMP_FOR_HANDLE(objectType);
break;
}
case JSType::TS_CLASS_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSClassType::SIZE, 7U);
JSHandle<TSClassType> classType = factory->NewTSClassType();
DUMP_FOR_HANDLE(classType);
break;
}
case JSType::TS_INTERFACE_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSInterfaceType::SIZE, 4U);
JSHandle<TSInterfaceType> interfaceType = factory->NewTSInterfaceType();
DUMP_FOR_HANDLE(interfaceType);
break;
}
case JSType::TS_CLASS_INSTANCE_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSClassInstanceType::SIZE, 2U);
JSHandle<TSClassInstanceType> classInstanceType = factory->NewTSClassInstanceType();
DUMP_FOR_HANDLE(classInstanceType);
break;
}
case JSType::TS_UNION_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSUnionType::SIZE, 2U);
JSHandle<TSUnionType> unionType = factory->NewTSUnionType(1);
DUMP_FOR_HANDLE(unionType);
break;
}
case JSType::TS_FUNCTION_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSFunctionType::SIZE, 5U);
JSHandle<TSFunctionType> functionType = factory->NewTSFunctionType(1);
DUMP_FOR_HANDLE(functionType);
break;
}
case JSType::TS_ARRAY_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSArrayType::SIZE, 2U);
JSHandle<TSArrayType> arrayType = factory->NewTSArrayType();
DUMP_FOR_HANDLE(arrayType);
break;
}
case JSType::TS_ITERATOR_INSTANCE_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSIteratorInstanceType::SIZE, 2U);
JSHandle<TSIteratorInstanceType> iteratorInstanceType = factory->NewTSIteratorInstanceType();
DUMP_FOR_HANDLE(iteratorInstanceType);
break;
}
case JSType::TS_NAMESPACE_TYPE: {
CHECK_DUMP_FIELDS(TaggedObject::TaggedObjectSize(), TSNamespaceType::SIZE, 2U);
JSHandle<TSNamespaceType> namespaceType = factory->NewTSNamespaceType();
DUMP_FOR_HANDLE(namespaceType);
break;
}
case JSType::JS_API_ARRAY_LIST: {
// 1 : 1 dump fileds number
CHECK_DUMP_FIELDS(JSObject::SIZE, JSAPIArrayList::SIZE, 1U);

View File

@ -1,63 +0,0 @@
# Copyright (c) 2021 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.
import("//arkcompiler/ets_runtime/js_runtime_config.gni")
import("//arkcompiler/ets_runtime/test/test_helper.gni")
module_output_path = "arkcompiler/ets_runtime"
host_unittest_action("TSTypeTest") {
module_out_path = module_output_path
sources = [
# test file
"ts_type_parser_test.cpp",
"ts_type_table_generator_test.cpp",
]
configs = [
"//arkcompiler/ets_runtime:ecma_test_config",
"$ark_root/assembler:arkassembler_public_config",
"$ark_root/libpandafile:arkfile_public_config",
]
deps = [
"$ark_third_party_root/icu/icu4c:shared_icui18n",
"$ark_third_party_root/icu/icu4c:shared_icuuc",
"//arkcompiler/ets_runtime:libark_jsruntime_test",
"//arkcompiler/runtime_core/assembler:libarkassembler_static",
sdk_libc_secshared_dep,
]
# hiviewdfx libraries
external_deps = hiviewdfx_ext_deps
deps += hiviewdfx_deps
}
group("unittest") {
testonly = true
# deps file
deps = [ ":TSTypeTest" ]
}
group("host_unittest") {
testonly = true
# deps file
deps = [ ":TSTypeTestAction" ]
if (is_mac) {
deps -= [ ":TSTypeTestAction" ]
}
}

View File

@ -1,428 +0,0 @@
/*
* Copyright (c) 2022 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 <thread>
#include "ecmascript/ecma_vm.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/ts_types/tests/ts_type_test_helper.h"
#include "ecmascript/ts_types/ts_type_parser.h"
namespace panda::test {
using namespace panda::ecmascript;
using namespace panda::panda_file;
using namespace panda::pandasm;
using LiteralValueType = std::variant<uint8_t, uint32_t, std::string>;
static constexpr uint16_t FIRST_USER_DEFINE_MODULE_ID = static_cast<uint32_t>(ModuleTableIdx::NUM_OF_DEFAULT_TABLES);
static constexpr uint16_t FIRST_USER_DEFINE_LOCAL_ID = 1;
class TSTypeParserTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
}
void TearDown() override
{
TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
}
EcmaVM *ecmaVm {nullptr};
EcmaHandleScope *scope {nullptr};
JSThread *thread {nullptr};
};
HWTEST_F_L0(TSTypeParserTest, TestPrimetiveType)
{
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
JSPandaFile *jsPandaFile = nullptr;
const CString recordName("");
uint32_t primetiveTypeId = 0U;
GlobalTSTypeRef resultGT = tsTypeParser.CreateGT(jsPandaFile, recordName, primetiveTypeId);
EXPECT_EQ(resultGT, GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE), primetiveTypeId));
}
HWTEST_F_L0(TSTypeParserTest, TestBuiltinType)
{
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
JSPandaFile *jsPandaFile = nullptr;
const CString recordName("");
uint32_t builtinTypeId = 50U;
GlobalTSTypeRef builtinGT = tsTypeParser.CreateGT(jsPandaFile, recordName, builtinTypeId);
EXPECT_EQ(builtinGT, GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::BUILTIN), builtinTypeId));
}
HWTEST_F_L0(TSTypeParserTest, TestTSClassType)
{
const char *source = R"(
.language ECMAScript
.record test {}
.function void foo() {}
)";
pandasm::Parser parser;
auto res = parser.Parse(source);
EXPECT_EQ(parser.ShowError().err, Error::ErrorType::ERR_NONE);
auto &program = res.Value();
const std::string classId("test_1");
const std::string valueStr("value");
std::vector<panda_file::LiteralTag> classTags { panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::BUILTINTYPEINDEX,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::STRING,
panda_file::LiteralTag::BUILTINTYPEINDEX,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER };
std::vector<LiteralValueType> classValues { static_cast<uint32_t>(1),
static_cast<uint32_t>(0),
static_cast<uint8_t>(0),
static_cast<uint32_t>(0),
static_cast<uint32_t>(0),
static_cast<uint32_t>(0),
static_cast<uint32_t>(1),
valueStr,
static_cast<uint8_t>(1),
static_cast<uint32_t>(0),
static_cast<uint32_t>(0),
static_cast<uint32_t>(0) };
TSTypeTestHelper::AddLiteral(program, classId, classTags, classValues);
const std::string abcFileName("TSClassTypeTest.abc");
TSTypeTestHelper::AddTypeSummary(program, { classId });
TSTypeTestHelper::AddCommonJsField(program);
std::map<std::string, size_t> *statp = nullptr;
pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {};
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = &maps;
EXPECT_TRUE(pandasm::AsmEmitter::Emit(abcFileName, program, statp, mapsp, false));
std::unique_ptr<const panda_file::File> pfPtr = panda_file::File::Open(abcFileName);
EXPECT_NE(pfPtr.get(), nullptr);
Span<const uint32_t> literalArrays = pfPtr.get()->GetLiteralArrays();
EXPECT_TRUE(literalArrays.size() >= 2);
// typeIds in order from largest to smallest and the last one is typeSummary literal
uint32_t testTypeIndex = literalArrays.size() - 2;
uint32_t testTypeOffset = literalArrays[testTypeIndex];
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
const CString fileName(abcFileName.c_str());
const auto jsPandaFile = pfManager->NewJSPandaFile(pfPtr.release(), fileName);
EXPECT_NE(jsPandaFile, nullptr);
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
const CString recordName("test");
GlobalTSTypeRef resultGT = tsTypeParser.CreateGT(jsPandaFile.get(), recordName, testTypeOffset);
EXPECT_EQ(resultGT, GlobalTSTypeRef(FIRST_USER_DEFINE_MODULE_ID, FIRST_USER_DEFINE_LOCAL_ID));
EXPECT_TRUE(tsManager->IsClassTypeKind(resultGT));
JSHandle<JSTaggedValue> type = tsManager->GetTSType(resultGT);
EXPECT_TRUE(type->IsTSClassType());
JSHandle<TSClassType> classType(type);
EXPECT_EQ(resultGT, classType->GetGT());
auto factory = ecmaVm->GetFactory();
JSHandle<JSTaggedValue> propertyName(factory->NewFromStdString(valueStr));
GlobalTSTypeRef propGT = TSClassType::GetPropTypeGT(thread, classType, propertyName);
EXPECT_EQ(propGT, GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::NUMBER)));
}
HWTEST_F_L0(TSTypeParserTest, TestTSFunctionType)
{
const char *source = R"(
.language ECMAScript
.record test {}
.function void foo() {}
)";
pandasm::Parser parser;
auto res = parser.Parse(source);
EXPECT_EQ(parser.ShowError().err, Error::ErrorType::ERR_NONE);
auto &program = res.Value();
const std::string functionId("test_1");
const std::string functionName("foo");
const uint32_t numOfParas = 2;
std::vector<panda_file::LiteralTag> functionTags { panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::STRING,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::BUILTINTYPEINDEX,
panda_file::LiteralTag::BUILTINTYPEINDEX,
panda_file::LiteralTag::BUILTINTYPEINDEX };
std::vector<LiteralValueType> functionValues { static_cast<uint32_t>(3),
static_cast<uint32_t>(0),
functionName,
static_cast<uint32_t>(0),
numOfParas,
static_cast<uint8_t>(1),
static_cast<uint8_t>(4),
static_cast<uint8_t>(2) };
TSTypeTestHelper::AddLiteral(program, functionId, functionTags, functionValues);
const std::string abcFileName("TSFunctionTypeTest.abc");
TSTypeTestHelper::AddTypeSummary(program, { functionId });
TSTypeTestHelper::AddCommonJsField(program);
std::map<std::string, size_t> *statp = nullptr;
pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {};
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = &maps;
EXPECT_TRUE(pandasm::AsmEmitter::Emit(abcFileName, program, statp, mapsp, false));
std::unique_ptr<const panda_file::File> pfPtr = panda_file::File::Open(abcFileName);
EXPECT_NE(pfPtr.get(), nullptr);
Span<const uint32_t> literalArrays = pfPtr.get()->GetLiteralArrays();
EXPECT_TRUE(literalArrays.size() >= 2);
// typeIds in order from largest to smallest and the last one is typeSummary literal
uint32_t testTypeIndex = literalArrays.size() - 2;
uint32_t testTypeOffset = literalArrays[testTypeIndex];
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
const CString fileName(abcFileName.c_str());
const auto jsPandaFile = pfManager->NewJSPandaFile(pfPtr.release(), fileName);
EXPECT_NE(jsPandaFile, nullptr);
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
const CString recordName("test");
GlobalTSTypeRef resultGT = tsTypeParser.CreateGT(jsPandaFile.get(), recordName, testTypeOffset);
EXPECT_EQ(resultGT, GlobalTSTypeRef(FIRST_USER_DEFINE_MODULE_ID, FIRST_USER_DEFINE_LOCAL_ID));
EXPECT_TRUE(tsManager->IsFunctionTypeKind(resultGT));
JSHandle<JSTaggedValue> type = tsManager->GetTSType(resultGT);
EXPECT_TRUE(type->IsTSFunctionType());
JSHandle<TSFunctionType> functionType(type);
EXPECT_EQ(resultGT, functionType->GetGT());
EXPECT_EQ(functionType->GetLength(), numOfParas);
EXPECT_EQ(functionType->GetParameterTypeGT(0), GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::NUMBER)));
EXPECT_EQ(functionType->GetParameterTypeGT(1), GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::STRING)));
EXPECT_EQ(functionType->GetReturnGT(), GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::BOOLEAN)));
}
HWTEST_F_L0(TSTypeParserTest, TestTSUnionType)
{
const char *source = R"(
.language ECMAScript
.record test {}
.function void foo() {}
)";
pandasm::Parser parser;
auto res = parser.Parse(source);
EXPECT_EQ(parser.ShowError().err, Error::ErrorType::ERR_NONE);
auto &program = res.Value();
const std::string unionId("test_1");
const uint32_t numOfTypes = 2;
std::vector<panda_file::LiteralTag> unionTags { panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::BUILTINTYPEINDEX,
panda_file::LiteralTag::BUILTINTYPEINDEX };
std::vector<LiteralValueType> unionValues { static_cast<uint32_t>(4),
numOfTypes,
static_cast<uint8_t>(1),
static_cast<uint8_t>(4) };
TSTypeTestHelper::AddLiteral(program, unionId, unionTags, unionValues);
const std::string abcFileName("TSUnionTypeTest.abc");
TSTypeTestHelper::AddTypeSummary(program, { unionId });
TSTypeTestHelper::AddCommonJsField(program);
std::map<std::string, size_t> *statp = nullptr;
pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {};
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = &maps;
EXPECT_TRUE(pandasm::AsmEmitter::Emit(abcFileName, program, statp, mapsp, false));
std::unique_ptr<const panda_file::File> pfPtr = panda_file::File::Open(abcFileName);
EXPECT_NE(pfPtr.get(), nullptr);
Span<const uint32_t> literalArrays = pfPtr.get()->GetLiteralArrays();
EXPECT_TRUE(literalArrays.size() >= 2);
// typeIds in order from largest to smallest and the last one is typeSummary literal
uint32_t testTypeIndex = literalArrays.size() - 2;
uint32_t testTypeOffset = literalArrays[testTypeIndex];
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
const CString fileName(abcFileName.c_str());
const auto jsPandaFile = pfManager->NewJSPandaFile(pfPtr.release(), fileName);
EXPECT_NE(jsPandaFile, nullptr);
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
const CString recordName("test");
GlobalTSTypeRef resultGT = tsTypeParser.CreateGT(jsPandaFile.get(), recordName, testTypeOffset);
EXPECT_EQ(resultGT, GlobalTSTypeRef(FIRST_USER_DEFINE_MODULE_ID, FIRST_USER_DEFINE_LOCAL_ID));
EXPECT_TRUE(tsManager->IsUnionTypeKind(resultGT));
JSHandle<JSTaggedValue> type = tsManager->GetTSType(resultGT);
EXPECT_TRUE(type->IsTSUnionType());
JSHandle<TSUnionType> unionType(type);
EXPECT_EQ(resultGT, unionType->GetGT());
EXPECT_EQ(tsManager->GetUnionTypeLength(resultGT), numOfTypes);
EXPECT_EQ(tsManager->GetUnionTypeByIndex(resultGT, 0),
GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::NUMBER)));
EXPECT_EQ(tsManager->GetUnionTypeByIndex(resultGT, 1),
GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::STRING)));
}
HWTEST_F_L0(TSTypeParserTest, TestTSArrayType)
{
const char *source = R"(
.language ECMAScript
.record test {}
.function void foo() {}
)";
pandasm::Parser parser;
auto res = parser.Parse(source);
EXPECT_EQ(parser.ShowError().err, Error::ErrorType::ERR_NONE);
auto &program = res.Value();
const std::string arrayId("test_1");
std::vector<panda_file::LiteralTag> arrayTags { panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::BUILTINTYPEINDEX };
std::vector<LiteralValueType> arrayValues { static_cast<uint32_t>(5),
static_cast<uint8_t>(1) };
TSTypeTestHelper::AddLiteral(program, arrayId, arrayTags, arrayValues);
const std::string abcFileName("TSArrayTypeTest.abc");
TSTypeTestHelper::AddTypeSummary(program, { arrayId });
TSTypeTestHelper::AddCommonJsField(program);
std::map<std::string, size_t> *statp = nullptr;
pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {};
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = &maps;
EXPECT_TRUE(pandasm::AsmEmitter::Emit(abcFileName, program, statp, mapsp, false));
std::unique_ptr<const panda_file::File> pfPtr = panda_file::File::Open(abcFileName);
EXPECT_NE(pfPtr.get(), nullptr);
Span<const uint32_t> literalArrays = pfPtr.get()->GetLiteralArrays();
EXPECT_TRUE(literalArrays.size() >= 2);
// typeIds in order from largest to smallest and the last one is typeSummary literal
uint32_t testTypeIndex = literalArrays.size() - 2;
uint32_t testTypeOffset = literalArrays[testTypeIndex];
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
const CString fileName(abcFileName.c_str());
const auto jsPandaFile = pfManager->NewJSPandaFile(pfPtr.release(), fileName);
EXPECT_NE(jsPandaFile, nullptr);
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
const CString recordName("test");
GlobalTSTypeRef resultGT = tsTypeParser.CreateGT(jsPandaFile.get(), recordName, testTypeOffset);
EXPECT_EQ(resultGT, GlobalTSTypeRef(FIRST_USER_DEFINE_MODULE_ID, FIRST_USER_DEFINE_LOCAL_ID));
EXPECT_TRUE(tsManager->IsArrayTypeKind(resultGT));
JSHandle<JSTaggedValue> type = tsManager->GetTSType(resultGT);
EXPECT_TRUE(type->IsTSArrayType());
JSHandle<TSArrayType> arrayType(type);
EXPECT_EQ(resultGT, arrayType->GetGT());
EXPECT_EQ(arrayType->GetElementGT(), GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::NUMBER)));
}
HWTEST_F_L0(TSTypeParserTest, TestTSObjectType)
{
const char *source = R"(
.language ECMAScript
.record test {}
.function void foo() {}
)";
pandasm::Parser parser;
auto res = parser.Parse(source);
EXPECT_EQ(parser.ShowError().err, Error::ErrorType::ERR_NONE);
auto &program = res.Value();
const std::string objectId("test_1");
const std::string ageStr("age");
const std::string funStr("fun");
std::vector<panda_file::LiteralTag> objectTags { panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::INTEGER,
panda_file::LiteralTag::STRING,
panda_file::LiteralTag::BUILTINTYPEINDEX,
panda_file::LiteralTag::STRING,
panda_file::LiteralTag::BUILTINTYPEINDEX };
std::vector<LiteralValueType> objectValues { static_cast<uint32_t>(6),
static_cast<uint32_t>(2),
ageStr,
static_cast<uint8_t>(1),
funStr,
static_cast<uint8_t>(1) };
TSTypeTestHelper::AddLiteral(program, objectId, objectTags, objectValues);
const std::string abcFileName("TSObjectTypeTest.abc");
TSTypeTestHelper::AddTypeSummary(program, { objectId });
TSTypeTestHelper::AddCommonJsField(program);
std::map<std::string, size_t> *statp = nullptr;
pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {};
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = &maps;
EXPECT_TRUE(pandasm::AsmEmitter::Emit(abcFileName, program, statp, mapsp, false));
std::unique_ptr<const panda_file::File> pfPtr = panda_file::File::Open(abcFileName);
EXPECT_NE(pfPtr.get(), nullptr);
Span<const uint32_t> literalArrays = pfPtr.get()->GetLiteralArrays();
EXPECT_TRUE(literalArrays.size() >= 2);
// typeIds in order from largest to smallest and the last one is typeSummary literal
uint32_t testTypeIndex = literalArrays.size() - 2;
uint32_t testTypeOffset = literalArrays[testTypeIndex];
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
const CString fileName(abcFileName.c_str());
const auto jsPandaFile = pfManager->NewJSPandaFile(pfPtr.release(), fileName);
EXPECT_NE(jsPandaFile, nullptr);
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeParser tsTypeParser(tsManager);
const CString recordName("test");
GlobalTSTypeRef resultGT = tsTypeParser.CreateGT(jsPandaFile.get(), recordName, testTypeOffset);
EXPECT_EQ(resultGT, GlobalTSTypeRef(FIRST_USER_DEFINE_MODULE_ID, FIRST_USER_DEFINE_LOCAL_ID));
EXPECT_TRUE(tsManager->IsObjectTypeKind(resultGT));
JSHandle<JSTaggedValue> type = tsManager->GetTSType(resultGT);
EXPECT_TRUE(type->IsTSObjectType());
JSHandle<TSObjectType> objectType(type);
EXPECT_EQ(resultGT, objectType->GetGT());
auto factory = ecmaVm->GetFactory();
JSHandle<JSTaggedValue> propName(factory->NewFromStdString(ageStr));
GlobalTSTypeRef propGT = TSObjectType::GetPropTypeGT(thread, objectType, propName);
EXPECT_EQ(propGT, GlobalTSTypeRef(static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE),
static_cast<uint32_t>(TSPrimitiveType::NUMBER)));
}
} // namespace panda::test

View File

@ -1,122 +0,0 @@
/*
* Copyright (c) 2023 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 <thread>
#include "ecmascript/ecma_vm.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/ts_types/tests/ts_type_test_helper.h"
#include "ecmascript/ts_types/ts_type_table_generator.h"
namespace panda::test {
using namespace panda::ecmascript;
using namespace panda::panda_file;
using namespace panda::pandasm;
static constexpr uint16_t FIRST_USER_DEFINE_MODULE_ID = static_cast<uint32_t>(ModuleTableIdx::NUM_OF_DEFAULT_TABLES);
class TSTypeTableGeneratorTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
}
void TearDown() override
{
TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
}
EcmaVM *ecmaVm {nullptr};
EcmaHandleScope *scope {nullptr};
JSThread *thread {nullptr};
};
HWTEST_F_L0(TSTypeTableGeneratorTest, TestTryGetModuleId)
{
const auto *abcName = TSTypeTable::DEFAULT_TYPE_VIRTUAL_NAME;
auto *tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeTableGenerator tableGenerator(tsManager);
uint32_t primitiveTableId = tableGenerator.TryGetModuleId(abcName, TSTypeTable::PRIMITIVE_TABLE_NAME);
uint32_t builtinTableId = tableGenerator.TryGetModuleId(abcName, TSTypeTable::BUILTINS_TABLE_NAME);
uint32_t inferTableId = tableGenerator.TryGetModuleId(abcName, TSTypeTable::INFER_TABLE_NAME);
uint32_t runtimeTableId = tableGenerator.TryGetModuleId(abcName, TSTypeTable::RUNTIME_TABLE_NAME);
uint32_t genericsTableId = tableGenerator.TryGetModuleId(abcName, TSTypeTable::GENERICS_TABLE_NAME);
uint32_t firstUserModuleId = tableGenerator.TryGetModuleId(abcName, "test");
EXPECT_EQ(primitiveTableId, static_cast<uint32_t>(ModuleTableIdx::PRIMITIVE));
EXPECT_EQ(builtinTableId, static_cast<uint32_t>(ModuleTableIdx::BUILTIN));
EXPECT_EQ(inferTableId, static_cast<uint32_t>(ModuleTableIdx::INFERRED));
EXPECT_EQ(runtimeTableId, static_cast<uint32_t>(ModuleTableIdx::RUNTIME));
EXPECT_EQ(genericsTableId, static_cast<uint32_t>(ModuleTableIdx::GENERICS));
EXPECT_EQ(firstUserModuleId, FIRST_USER_DEFINE_MODULE_ID);
}
HWTEST_F_L0(TSTypeTableGeneratorTest, TestTryGetLocalId)
{
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeTableGenerator tableGenerator(tsManager);
JSHandle<TSTypeTable> table = ecmaVm->GetFactory()->NewTSTypeTable(0);
table->SetNumberOfTypes(ecmaVm->GetJSThread());
uint32_t localId = tableGenerator.TryGetLocalId(table);
EXPECT_EQ(localId, 1U);
}
HWTEST_F_L0(TSTypeTableGeneratorTest, GetOrGenerateTSTypeTable)
{
const char *source = R"(
.language ECMAScript
.record test {}
.function void foo() {}
)";
pandasm::Parser parser;
auto res = parser.Parse(source);
EXPECT_EQ(parser.ShowError().err, Error::ErrorType::ERR_NONE);
auto &program = res.Value();
const std::string abcFileName("TSTypeTableTest.abc");
TSTypeTestHelper::AddTypeSummary(program, {});
TSTypeTestHelper::AddCommonJsField(program);
std::map<std::string, size_t> *statp = nullptr;
pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {};
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = &maps;
EXPECT_TRUE(pandasm::AsmEmitter::Emit(abcFileName, program, statp, mapsp, false));
std::unique_ptr<const panda_file::File> pfPtr = panda_file::File::Open(abcFileName);
EXPECT_NE(pfPtr.get(), nullptr);
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
const CString fileName(abcFileName.c_str());
std::shared_ptr<JSPandaFile> jsPandaFile = pfManager->NewJSPandaFile(pfPtr.release(), fileName);
EXPECT_NE(jsPandaFile, nullptr);
auto tsManager = ecmaVm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager();
tsManager->Initialize();
TSTypeTableGenerator tableGenerator(tsManager);
[[maybe_unused]] JSHandle<TSTypeTable> table =
tableGenerator.GetOrGenerateTSTypeTable(jsPandaFile.get(), "test", 0U);
ASSERT(table->GetNumberOfTypes() == 0U);
}
} // namespace panda::test

View File

@ -1,132 +0,0 @@
/*
* Copyright (c) 2023 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_TS_TYPES_TESTS_TS_TYPE_TEST_HELPER_H
#define ECMASCRIPT_TS_TYPES_TESTS_TS_TYPE_TEST_HELPER_H
#include "assembler/assembly-parser.h"
#include "ecmascript/tests/test_helper.h"
namespace panda::test {
using namespace panda::ecmascript;
using namespace panda::panda_file;
using namespace panda::pandasm;
using LiteralValueType = std::variant<uint8_t, uint32_t, std::string>;
class TSTypeTestHelper {
public:
static void AddLiteral(pandasm::Program &program, const std::string &literalId,
const std::vector<panda_file::LiteralTag> &tags,
const std::vector<LiteralValueType> &values)
{
EXPECT_EQ(tags.size(), values.size());
std::vector<pandasm::LiteralArray::Literal> literal {};
for (uint32_t i = 0; i < tags.size(); i++) {
AddTagValue(literal, tags[i], values[i]);
}
pandasm::LiteralArray literalArray(literal);
program.literalarray_table.emplace(literalId, literalArray);
}
static void AddTypeSummary(pandasm::Program &program, const std::vector<std::string> &typeIds)
{
const std::string typeSummaryId("test_0");
AddSummaryLiteral(program, typeSummaryId, typeIds);
const std::string testStr("test");
auto iter = program.record_table.find(testStr);
EXPECT_NE(iter, program.record_table.end());
if (iter != program.record_table.end()) {
auto &rec = iter->second;
auto typeSummaryIndexField = pandasm::Field(pandasm::extensions::Language::ECMASCRIPT);
typeSummaryIndexField.name = "typeSummaryOffset";
typeSummaryIndexField.type = pandasm::Type("u32", 0);
typeSummaryIndexField.metadata->SetValue(
pandasm::ScalarValue::Create<pandasm::Value::Type::LITERALARRAY>(typeSummaryId));
rec.field_list.emplace_back(std::move(typeSummaryIndexField));
}
}
static void AddCommonJsField(pandasm::Program &program)
{
const std::string testStr("test");
auto iter = program.record_table.find(testStr);
EXPECT_NE(iter, program.record_table.end());
if (iter != program.record_table.end()) {
auto &rec = iter->second;
auto isCommonJsField = pandasm::Field(pandasm::extensions::Language::ECMASCRIPT);
isCommonJsField.name = "isCommonjs";
isCommonJsField.type = pandasm::Type("u8", 0);
isCommonJsField.metadata->SetValue(
pandasm::ScalarValue::Create<pandasm::Value::Type::U8>(static_cast<uint8_t>(false)));
rec.field_list.emplace_back(std::move(isCommonJsField));
}
}
private:
static void AddTagValue(std::vector<LiteralArray::Literal> &literalArray,
const panda_file::LiteralTag tag,
const LiteralValueType &value)
{
pandasm::LiteralArray::Literal literalTag;
literalTag.tag_ = panda_file::LiteralTag::TAGVALUE;
literalTag.value_ = static_cast<uint8_t>(tag);
literalArray.emplace_back(std::move(literalTag));
pandasm::LiteralArray::Literal literalValue;
literalValue.tag_ = tag;
switch (tag) {
case panda_file::LiteralTag::INTEGER: {
literalValue.value_ = std::get<uint32_t>(value);
break;
}
case panda_file::LiteralTag::BUILTINTYPEINDEX: {
literalValue.value_ = std::get<uint8_t>(value);
break;
}
case panda_file::LiteralTag::STRING: {
literalValue.value_ = std::get<std::string>(value);
break;
}
case panda_file::LiteralTag::LITERALARRAY: {
literalValue.value_ = std::get<std::string>(value);
break;
}
default: {
EXPECT_FALSE(true);
}
}
literalArray.emplace_back(std::move(literalValue));
}
static void AddSummaryLiteral(pandasm::Program &program, const std::string &typeSummaryId,
const std::vector<std::string> &typeIds)
{
uint32_t numOfTypes = typeIds.size();
std::vector<panda_file::LiteralTag> typeSummaryTags { panda_file::LiteralTag::INTEGER };
std::vector<LiteralValueType> typeSummaryValues { numOfTypes };
for (uint32_t i = 0; i < numOfTypes; i++) {
typeSummaryTags.emplace_back(panda_file::LiteralTag::LITERALARRAY);
typeSummaryValues.emplace_back(typeIds[i]);
}
typeSummaryTags.emplace_back(panda_file::LiteralTag::INTEGER);
typeSummaryValues.emplace_back(static_cast<uint32_t>(0U));
AddLiteral(program, typeSummaryId, typeSummaryTags, typeSummaryValues);
}
};
} // namespace panda::test
#endif // ECMASCRIPT_TS_TYPES_TESTS_TS_TYPE_TEST_HELPER_H

File diff suppressed because it is too large Load Diff

View File

@ -1,767 +0,0 @@
/*
* Copyright (c) 2021 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_TS_TYPES_TS_MANAGER_H
#define ECMASCRIPT_TS_TYPES_TS_MANAGER_H
#include "ecmascript/compiler/aot_snapshot/aot_snapshot.h"
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/compiler/compilation_driver.h"
#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
#include "ecmascript/js_handle.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/ts_types/builtin_type_id.h"
#include "ecmascript/ts_types/global_ts_type_ref.h"
#include "ecmascript/ts_types/global_type_info.h"
#include "ecmascript/ts_types/ts_obj_layout_info.h"
namespace panda::ecmascript {
using ProfileType = pgo::ProfileType;
using SnapshotGlobalData = kungfu::SnapshotGlobalData;
enum class PropertyType : uint8_t {
NORMAL = 0,
STATIC,
OTHERS,
};
struct ModuleInfo {
const JSPandaFile *jsPandaFile {nullptr}; // there may be serval merged abc files.
const CString recordName {""}; // distinguish different files which are all merged to one abc file.
uint32_t index {0}; // bytecode "stmoudlevar index", exportVar index is unique in the same record.
bool operator < (const ModuleInfo &moduleInfo) const
{
if (index < moduleInfo.index) {
return true;
}
if (index == moduleInfo.index && recordName < moduleInfo.recordName) {
return true;
}
if (index == moduleInfo.index && recordName == moduleInfo.recordName &&
jsPandaFile < moduleInfo.jsPandaFile) {
return true;
}
return false;
}
};
class TSModuleTable : public TaggedArray {
public:
// Each TSTypeTable occupies three positions
static constexpr int ELEMENTS_LENGTH = 4;
static constexpr int MODULE_REQUEST_OFFSET = 1;
static constexpr int SORT_ID_OFFSET = 2;
static constexpr int TYPE_TABLE_OFFSET = 3;
static constexpr int ABC_ID_OFFSET = 4;
// Reserve a position which is used to store the number of TSTypeTables and a TSTypeTable storage space
static constexpr int INITIAL_CAPACITY = ELEMENTS_LENGTH + 1;
static constexpr int NUMBER_OF_TABLES_INDEX = 0;
static constexpr int INCREASE_CAPACITY_RATE = 2;
static constexpr int NOT_FOUND = -1;
static TSModuleTable *Cast(TaggedObject *object)
{
ASSERT(JSTaggedValue(object).IsTaggedArray());
return static_cast<TSModuleTable *>(object);
}
JSHandle<EcmaString> GetModuleRequestByModuleId(JSThread *thread, int entry) const;
JSHandle<EcmaString> GetAbcRequestByModuleId(JSThread *thread, int entry) const;
int GetGlobalModuleID(JSThread *thread, JSHandle<EcmaString> amiPath, JSHandle<EcmaString> abcPath) const;
inline int GetNumberOfTSTypeTables() const
{
return Get(NUMBER_OF_TABLES_INDEX).GetInt();
}
inline void SetNumberOfTSTypeTables(JSThread *thread, int num)
{
Set(thread, NUMBER_OF_TABLES_INDEX, JSTaggedValue(num));
}
static uint32_t GetTSTypeTableOffset(int entry)
{
return entry * ELEMENTS_LENGTH + TYPE_TABLE_OFFSET;
}
static int GetModuleRequestOffset(int entry)
{
return entry * ELEMENTS_LENGTH + MODULE_REQUEST_OFFSET;
}
static int GetSortIdOffset(int entry)
{
return entry * ELEMENTS_LENGTH + SORT_ID_OFFSET;
}
static uint32_t GetAbcRequestOffset(int entry)
{
return entry * ELEMENTS_LENGTH + ABC_ID_OFFSET;
}
};
class PUBLIC_API TSManager {
public:
explicit TSManager(EcmaVM *vm);
~TSManager() = default;
void Initialize();
void Dump();
void Iterate(const RootVisitor &v);
JSHandle<TSModuleTable> GetTSModuleTable() const
{
return JSHandle<TSModuleTable>(reinterpret_cast<uintptr_t>(&globalModuleTable_));
}
void SetTSModuleTable(JSHandle<TSModuleTable> table)
{
globalModuleTable_ = table.GetTaggedValue();
}
JSHandle<TSTypeTable> GetTSTypeTable(int entry) const;
void SetTSTypeTable(const JSHandle<TSTypeTable> &table, int tableId) const;
void GenerateBuiltinSummary();
inline uint32_t GetBuiltinOffset(uint32_t index) const
{
if (index == static_cast<uint32_t>(BuiltinTypeId::NUM_INDEX_IN_SUMMARY)) {
return builtinOffsets_[index];
}
return builtinOffsets_[index - static_cast<uint32_t>(BuiltinTypeId::BUILTIN_OFFSET)];
}
inline GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSTaggedValue propertyName) const
{
return GetPropType(gt, JSHandle<JSTaggedValue>(thread_, propertyName));
}
GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, const uint64_t key) const;
GlobalTSTypeRef PUBLIC_API GetIndexSignType(GlobalTSTypeRef objType, kungfu::GateType indexType) const;
inline GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(kungfu::GateType gateType)
{
GlobalTSTypeRef gt = gateType.GetGTRef();
return CreateClassInstanceType(gt);
}
GlobalTSTypeRef PUBLIC_API CreateClassInstanceType(GlobalTSTypeRef gt);
inline GlobalTSTypeRef PUBLIC_API GetClassType(kungfu::GateType gateType)
{
GlobalTSTypeRef gt = gateType.GetGTRef();
return GetClassType(gt);
}
GlobalTSTypeRef PUBLIC_API GetClassType(GlobalTSTypeRef classInstanceGT) const;
JSHandle<TSClassType> GetExtendedClassType(JSHandle<TSClassType> classType) const;
TSClassType* GetExtendedClassType(const TSClassType *classType) const;
uint32_t PUBLIC_API GetUnionTypeLength(GlobalTSTypeRef gt) const;
GlobalTSTypeRef PUBLIC_API GetUnionTypeByIndex(GlobalTSTypeRef gt, int index) const;
GlobalTSTypeRef PUBLIC_API GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTypeVec);
uint32_t PUBLIC_API GetFunctionTypeLength(GlobalTSTypeRef gt) const;
GlobalTSTypeRef PUBLIC_API GetOrCreateTSIteratorInstanceType(TSRuntimeType runtimeType, GlobalTSTypeRef elementGt);
GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(GlobalTSTypeRef gt) const;
inline GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(kungfu::GateType gateType) const
{
GlobalTSTypeRef gt = GlobalTSTypeRef(gateType.GetGTRef());
return GetIteratorInstanceElementGt(gt);
}
bool PUBLIC_API IsStaticFunc(GlobalTSTypeRef gt) const;
bool PUBLIC_API IsHotnessFunc(GlobalTSTypeRef gt) const;
void PUBLIC_API SetHotnessFunc(GlobalTSTypeRef gt, bool isHotness) const;
bool PUBLIC_API GetSuperGateType(kungfu::GateType &gateType) const;
GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt,
JSHandle<JSTaggedValue> propertyName,
PropertyType propType) const;
inline GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt,
JSTaggedValue propertyName,
PropertyType propType) const
{
return GetSuperPropType(gt, JSHandle<JSTaggedValue>(vm_->GetJSThread(), propertyName),
propType);
}
GlobalTSTypeRef PUBLIC_API GetSuperPropType(GlobalTSTypeRef gt,
const uint64_t key,
PropertyType propType) const;
GlobalTSTypeRef PUBLIC_API GetFuncParameterTypeGT(GlobalTSTypeRef gt, int index) const;
GlobalTSTypeRef PUBLIC_API GetFuncThisGT(GlobalTSTypeRef gt) const;
void PUBLIC_API SetFuncMethodOffset(GlobalTSTypeRef gt, uint32_t methodOffset);
uint32_t PUBLIC_API GetFuncMethodOffset(GlobalTSTypeRef gt) const;
bool PUBLIC_API IsGetterSetterFunc(GlobalTSTypeRef gt) const;
bool IsAbstractMethod(GlobalTSTypeRef gt) const;
bool IsMethodSignature(GlobalTSTypeRef gt) const;
bool CanFastCall(GlobalTSTypeRef gt) const;
bool IsNoGC(GlobalTSTypeRef gt) const;
bool MethodOffsetIsVaild(GlobalTSTypeRef gt) const;
bool FastCallFlagIsVaild(GlobalTSTypeRef gt) const;
inline GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(kungfu::GateType gateType) const
{
GlobalTSTypeRef gt = gateType.GetGTRef();
return GetFuncReturnValueTypeGT(gt);
}
GlobalTSTypeRef PUBLIC_API GetFuncReturnValueTypeGT(GlobalTSTypeRef gt) const;
std::string PUBLIC_API GetFuncName(kungfu::GateType gt) const;
int PUBLIC_API GetMethodIndex(GlobalTSTypeRef gt) const;
inline GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(kungfu::GateType gateType) const
{
GlobalTSTypeRef gt = gateType.GetGTRef();
return GetArrayParameterTypeGT(gt);
}
GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(GlobalTSTypeRef gt) const;
bool PUBLIC_API AssertTypes() const
{
return assertTypes_;
}
double PUBLIC_API GetTypeThreshold() const
{
return typeThreshold_;
}
bool IsBuiltinsDTSEnabled() const
{
return vm_->GetJSOptions().WasSetBuiltinsDTS();
}
CString GetBuiltinsDTS() const
{
std::string fileName = vm_->GetJSOptions().GetBuiltinsDTS();
return CString(fileName);
}
void AddInstanceTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &ihclass);
void AddConstructorTSHClass(GlobalTSTypeRef gt, JSHandle<JSHClass> &constructorHClass);
JSTaggedValue GetInstanceTSHClass(const JSHandle<TSClassType> &classType) const;
bool HasTSHClass(const JSHandle<TSClassType> &classType) const;
bool HasTSHClass(const TSClassType *classType) const;
JSHandle<JSTaggedValue> GetTSType(const GlobalTSTypeRef &gt) const;
std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const;
int PUBLIC_API GetHClassIndexByObjectType(const kungfu::GateType &gateType);
int PUBLIC_API GetHClassIndexByInstanceGateType(const kungfu::GateType &gateType);
int PUBLIC_API GetConstructorHClassIndexByClassGateType(const kungfu::GateType &gateType);
int PUBLIC_API GetHClassIndexByClassGateType(const kungfu::GateType &gateType);
JSTaggedValue GetTSHClass(const kungfu::GateType &gateType) const;
JSTaggedValue PUBLIC_API GetAOTHClassInfoByIndex(uint32_t index);
GlobalTSTypeRef PUBLIC_API CreateArrayType();
GlobalTSTypeRef PUBLIC_API CreateNamespaceType();
bool AddNamespacePropType(kungfu::GateType objType, JSTaggedValue name, kungfu::GateType valueType);
inline bool IsUserDefinedClassTypeKind(const kungfu::GateType &gateType) const
{
GlobalTSTypeRef gt = gateType.GetGTRef();
return IsUserDefinedClassTypeKind(gt);
}
inline bool IsUserDefinedClassTypeKind(const GlobalTSTypeRef &gt) const
{
return IsClassTypeKind(gt) && (!gt.IsBuiltinModule());
}
inline void StoreNamespaceType(const uint32_t methodOffset, const kungfu::GateType type)
{
methodOffsetToType_.insert(std::make_pair(methodOffset, type));
}
inline kungfu::GateType GetNamespaceObjType(const uint32_t methodOffset) const
{
ASSERT(HasInferredNamespaceType(methodOffset));
return methodOffsetToType_.at(methodOffset);
}
inline bool HasInferredNamespaceType(const uint32_t methodOffset) const
{
return methodOffsetToType_.find(methodOffset) != methodOffsetToType_.end();
}
EcmaVM *GetEcmaVM() const
{
return vm_;
}
JSThread *GetThread() const
{
return thread_;
}
#define IS_TSTYPEKIND_METHOD_LIST(V) \
V(Primitive, TSTypeKind::PRIMITIVE) \
V(Class, TSTypeKind::CLASS) \
V(ClassInstance, TSTypeKind::CLASS_INSTANCE) \
V(Function, TSTypeKind::FUNCTION) \
V(Union, TSTypeKind::UNION) \
V(Array, TSTypeKind::ARRAY) \
V(Object, TSTypeKind::OBJECT) \
V(Import, TSTypeKind::IMPORT) \
V(Interface, TSTypeKind::INTERFACE) \
V(IteratorInstance, TSTypeKind::ITERATOR_INSTANCE) \
V(Namespace, TSTypeKind::NAMESPACE)
#define IS_TSTYPEKIND(NAME, TSTYPEKIND) \
inline bool PUBLIC_API Is##NAME##TypeKind(const kungfu::GateType &gateType) const \
{ \
GlobalTSTypeRef gt = gateType.GetGTRef(); \
return GetTypeKind(gt) == (TSTYPEKIND); \
} \
\
inline bool PUBLIC_API Is##NAME##TypeKind(const GlobalTSTypeRef &gt) const \
{ \
return GetTypeKind(gt) == (TSTYPEKIND); \
}
IS_TSTYPEKIND_METHOD_LIST(IS_TSTYPEKIND)
#undef IS_TSTYPEKIND
bool PUBLIC_API IsBuiltinClassType(BuiltinTypeId id, kungfu::GateType gateType) const;
bool PUBLIC_API IsBuiltinInstanceType(BuiltinTypeId id, kungfu::GateType gateType) const;
bool PUBLIC_API IsTypedArrayType(kungfu::GateType gateType) const;
bool PUBLIC_API IsValidTypedArrayType(kungfu::GateType gateType) const;
inline bool PUBLIC_API IsBuiltinObjectType(kungfu::GateType gateType) const
{
return gateType.GetGTRef().IsBuiltinModule() && IsClassTypeKind(gateType);
}
bool PUBLIC_API IsIntTypedArrayType(kungfu::GateType gateType) const;
bool PUBLIC_API IsDoubleTypedArrayType(kungfu::GateType gateType) const;
BuiltinTypeId PUBLIC_API GetTypedArrayBuiltinId(kungfu::GateType gateType) const;
static const std::vector<BuiltinTypeId> &GetValidTypedArrayIds();
inline void AddElementToIdGTMap(const GlobalTypeID &id, GlobalTSTypeRef gt,
const CString &recordName = "", bool isImportType = false)
{
auto it = idGTMap_.find(id);
if (it != idGTMap_.end()) {
it->second = gt;
} else {
idGTMap_.emplace(id, gt);
}
if (!isImportType && !id.IsPGOType()) {
auto value = std::make_tuple(id.GetJSPandaFile()->GetNormalizedFileDesc(), recordName, id.GetTypeId());
gtLiteralOffsetMap_.emplace(gt, value);
}
}
inline bool HasCreatedGT(const GlobalTypeID &id) const
{
return idGTMap_.find(id) != idGTMap_.end();
}
inline GlobalTSTypeRef GetGTByGlobalTypeID(const GlobalTypeID &id) const
{
return idGTMap_.at(id);
}
inline bool HasOffsetFromGT(GlobalTSTypeRef gt) const
{
return gtLiteralOffsetMap_.find(gt) != gtLiteralOffsetMap_.end();
}
inline std::tuple<CString, CString, uint32_t> GetOffsetFromGt(GlobalTSTypeRef gt) const
{
return gtLiteralOffsetMap_.at(gt);
}
inline void AddTypeToModuleVarGtMap(const JSPandaFile *jsPandaFile, const CString &recordName,
uint32_t index, GlobalTSTypeRef gt)
{
ModuleInfo key = {jsPandaFile, recordName, index};
if (moduleVarGtMap_.find(key) == moduleVarGtMap_.end()) {
moduleVarGtMap_.emplace(key, gt);
} else {
moduleVarGtMap_[key] = gt;
}
}
inline bool HasExportGT(const JSPandaFile *jsPandaFile, const CString &recordName,
uint32_t index) const
{
ModuleInfo key = {jsPandaFile, recordName, index};
return moduleVarGtMap_.find(key) != moduleVarGtMap_.end();
}
inline GlobalTSTypeRef GetGTFromModuleMap(const JSPandaFile *jsPandaFile, const CString &recordName,
uint32_t index) const
{
ModuleInfo key = {jsPandaFile, recordName, index};
return moduleVarGtMap_.at(key);
}
inline void AddResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName,
JSTaggedValue exportTable)
{
auto key = std::make_pair(jsPandaFile, recordName);
if (resolvedExportTable_.find(key) == resolvedExportTable_.end()) {
resolvedExportTable_.emplace(key, exportTable);
} else {
resolvedExportTable_[key] = exportTable;
}
}
inline bool HasResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const
{
auto key = std::make_pair(jsPandaFile, recordName);
return resolvedExportTable_.find(key) != resolvedExportTable_.end();
}
inline JSTaggedValue GetResolvedExportTable(const JSPandaFile *jsPandaFile, const CString &recordName) const
{
auto key = std::make_pair(jsPandaFile, recordName);
return resolvedExportTable_.at(key);
}
bool IsTSIterator(GlobalTSTypeRef gt) const
{
uint32_t l = gt.GetLocalId();
return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR));
}
bool IsTSIteratorResult(GlobalTSTypeRef gt) const
{
uint32_t l = gt.GetLocalId();
return gt.IsRuntimeModule() && (l == static_cast<uint32_t>(TSRuntimeType::ITERATOR_RESULT));
}
void PUBLIC_API SetCurConstantPool(const JSPandaFile *jsPandaFile, uint32_t methodOffset);
int32_t PUBLIC_API GetConstantPoolIDByMethodOffset(const JSPandaFile *jsPandaFile, uint32_t methodOffset);
uint32_t GetConstantPoolId(uint32_t methodId) const;
JSTaggedValue GetConstantPool(uint32_t methodId) const;
JSHandle<JSTaggedValue> PUBLIC_API GetConstantPool() const
{
return JSHandle<JSTaggedValue>(uintptr_t(&curCP_));
}
JSTaggedValue PUBLIC_API GetStringFromConstantPool(uint32_t methodId, const uint16_t stringId) const;
inline std::string PUBLIC_API GetStdStringFromConstantPool(uint32_t methodId, const uint16_t stringId) const
{
JSTaggedValue str = GetStringFromConstantPool(methodId, stringId);
return EcmaStringAccessor(str).ToStdString(StringConvertedUsage::LOGICOPERATION);
}
bool PUBLIC_API IsBuiltinObjectMethod(BuiltinTypeId id, kungfu::GateType funcType) const;
bool PUBLIC_API IsBuiltinConstructor(BuiltinTypeId id, GlobalTSTypeRef ctorType) const;
inline const JSPandaFile *GetBuiltinPandaFile() const
{
return builtinPandaFile_;
}
inline const CString &GetBuiltinRecordName() const
{
return builtinsRecordName_;
}
inline kungfu::BytecodeInfoCollector *GetBytecodeInfoCollector() const
{
return bcInfoCollector_;
}
inline void SetBytecodeInfoCollector(kungfu::BytecodeInfoCollector *bcInfoCollector)
{
bcInfoCollector_ = bcInfoCollector;
}
class IHClassData {
public:
explicit IHClassData(JSTaggedType ihc) : ihc_(ihc) {}
void Iterate(const RootVisitor &v)
{
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&ihc_)));
}
std::unordered_map<int32_t, uint32_t>& GetCPIndexMap()
{
return cpIndexMap_;
}
JSTaggedType GetIHC() const
{
return ihc_;
}
private:
JSTaggedType ihc_ {0};
std::unordered_map<int32_t, uint32_t> cpIndexMap_ {};
};
void SetCompilationDriver(kungfu::CompilationDriver *cmpDriver)
{
cmpDriver_ = cmpDriver;
}
kungfu::CompilationDriver *GetCompilationDriver() const
{
return cmpDriver_;
}
void AddElementToClassNameMap(const JSPandaFile *jsPandaFile, uint32_t offset, std::string className)
{
literalOffsetClassNameMap_.emplace(std::make_pair(jsPandaFile, offset), className);
}
const std::string GetClassNameByOffset(const JSPandaFile *jsPandaFile, uint32_t typeId) const
{
std::pair<const JSPandaFile *, uint32_t> pair = std::make_pair(jsPandaFile, typeId);
std::string name = "";
if (literalOffsetClassNameMap_.find(pair) != literalOffsetClassNameMap_.end()) {
name = literalOffsetClassNameMap_.at(pair);
}
return name;
}
inline void CollectGT(GlobalTSTypeRef gt)
{
if (IsClassTypeKind(gt)) {
collectedGT_.insert(gt);
}
}
inline std::set<GlobalTSTypeRef>& GetCollectedGT()
{
return collectedGT_;
}
inline void InsertLiteralGTMap(TypeLocation &loc, GlobalTSTypeRef gt)
{
literalGTMap_[loc] = gt;
}
inline GlobalTSTypeRef GetLiteralGT(TypeLocation &loc)
{
auto it = literalGTMap_.find(loc);
if (it != literalGTMap_.end()) {
return it->second;
}
return GlobalTSTypeRef::Default();
}
inline void InsertPtToGtMap(ProfileType pgoType, const kungfu::GateType &gateType)
{
ptToGtMap_.emplace(pgoType, gateType);
}
inline const kungfu::GateType GetGateTypeByPt(ProfileType pgoType)
{
if (pgoType.IsBuiltinsType()) {
return GetBuiltinsGateTypeByPt(pgoType);
}
auto it = ptToGtMap_.find(pgoType);
if (it != ptToGtMap_.end()) {
return it->second;
}
return kungfu::GateType::AnyType();
}
void PrintNumOfTypes() const;
void PrintTypeInfo(const JSPandaFile *jsPandaFile) const;
kungfu::GateType TryNarrowUnionType(kungfu::GateType gateType);
JSHandle<TaggedArray> GetExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName);
int GetHClassIndex(GlobalTSTypeRef classGT, bool isConstructor = false);
uint32_t GetPGOGTCountByRecordName(const CString &recordName) const
{
if (bcInfoCollector_ == nullptr) {
return 0;
}
const kungfu::PGOBCInfo *bcInfo = bcInfoCollector_->GetPGOBCInfo();
return bcInfo->GetPGOExtendGTCount(recordName);
}
inline std::string GetBuiltinsName(GlobalTSTypeRef builtinGT) const
{
uint32_t index = GetBuiltinIndex(builtinGT);
return GetBuiltinsName(index);
}
TSTypeKind PUBLIC_API GetTypeKind(const GlobalTSTypeRef &gt) const;
#define TSTYPETABLE_ACCESSOR_LIST(V) \
V(Builtin, ModuleTableIdx::BUILTIN) \
V(Inferred, ModuleTableIdx::INFERRED) \
V(Runtime, ModuleTableIdx::RUNTIME) \
V(Generics, ModuleTableIdx::GENERICS)
#define TSTYPETABLE_ACCESSOR(NAME, MODULEID) \
inline GlobalTSTypeRef AddTSTypeTo##NAME##Table(const JSHandle<TSType> &type) const \
{ \
return AddTSTypeToTypeTable(type, static_cast<uint32_t>(MODULEID)); \
} \
\
inline JSHandle<TSTypeTable> Get##NAME##Table() const \
{ \
return GetTSTypeTable(static_cast<uint32_t>(MODULEID)); \
} \
\
inline void Set##NAME##Table(const JSHandle<TSTypeTable> &table) \
{ \
SetTSTypeTable(table, static_cast<uint32_t>(MODULEID)); \
}
TSTYPETABLE_ACCESSOR_LIST(TSTYPETABLE_ACCESSOR)
#undef TSTYPETABLE_ACCESSOR
private:
NO_COPY_SEMANTIC(TSManager);
NO_MOVE_SEMANTIC(TSManager);
GlobalTSTypeRef AddTSTypeToTypeTable(const JSHandle<TSType> &type, int tableId) const;
JSHandle<TaggedArray> GenerateExportTableFromLiteral(const JSPandaFile *jsPandaFile, const CString &recordName);
GlobalTSTypeRef FindUnionInTypeTable(JSHandle<TSTypeTable> table, JSHandle<TSUnionType> unionType) const;
GlobalTSTypeRef FindIteratorInstanceInInferTable(GlobalTSTypeRef kindGt, GlobalTSTypeRef elementGt) const;
GlobalTSTypeRef PUBLIC_API GetPropType(GlobalTSTypeRef gt, JSHandle<JSTaggedValue> propertyName) const;
std::string GetClassTypeStr(GlobalTSTypeRef gt) const;
std::string GetClassInstanceTypeStr(GlobalTSTypeRef gt) const;
std::string GetFunctionTypeStr(GlobalTSTypeRef gt) const;
std::string GetArrayTypeStr(GlobalTSTypeRef gt) const;
std::string GetPrimitiveStr(const GlobalTSTypeRef &gt) const;
uint32_t RecordIhcToVecAndIndexMap(IHClassData &ihcData);
uint32_t GetBuiltinIndex(GlobalTSTypeRef builtinGT) const;
std::string GetBuiltinsName(uint32_t index) const;
inline void SetBuiltinPandaFile(JSPandaFile *jsPandaFile)
{
builtinPandaFile_ = jsPandaFile;
}
inline void SetBuiltinRecordName(CString &builtinsRecordName)
{
builtinsRecordName_ = builtinsRecordName;
}
// for jsarray
void TryGetElmsKind(panda_file::File::EntityId id, JSHandle<JSTaggedValue> &ekd);
const kungfu::GateType GetBuiltinsGateTypeByPt(ProfileType pgoType);
BuiltinTypeId GetBuiltinTypeIdByJSType(JSType jsType);
EcmaVM *vm_ {nullptr};
JSThread *thread_ {nullptr};
ObjectFactory *factory_ {nullptr};
// kungfu::PGOTypeManager ptManager_;
JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()};
CMap<ProfileType, const kungfu::GateType> ptToGtMap_ {};
std::map<GlobalTSTypeRef, IHClassData> gtIhcMap_ {};
std::map<GlobalTSTypeRef, IHClassData> gtConstructorhcMap_ {};
std::unordered_map<TypeLocation, GlobalTSTypeRef, HashTypeLocation> literalGTMap_ {};
std::map<JSType, GlobalTSTypeRef> pgoBuiltinGTCache_ {};
bool assertTypes_ {false};
double typeThreshold_ {-1};
// when the passmanager iterates each method, the curCP_ and curCPID_ should be updated
// so that subsequent passes (type_infer, type_bytecode_lowering) can obtain the correct constpool.
JSTaggedValue curCP_ {JSTaggedValue::Hole()};
int32_t curCPID_ {0};
const JSPandaFile *curJSPandaFile_ {nullptr};
std::unordered_map<GlobalTypeID, GlobalTSTypeRef, HashGlobalTypeID> idGTMap_ {};
std::map<GlobalTSTypeRef, std::tuple<CString, CString, uint32_t>> gtLiteralOffsetMap_ {};
std::vector<uint32_t> builtinOffsets_ {};
JSPandaFile *builtinPandaFile_ {nullptr};
CString builtinsRecordName_ {""};
std::map<ModuleInfo, GlobalTSTypeRef> moduleVarGtMap_{};
kungfu::CompilationDriver *cmpDriver_ {nullptr};
std::set<GlobalTSTypeRef> collectedGT_ {}; // use for storing types that need to generate hclasses
friend class EcmaVM;
friend class TSTypeAccessor;
std::map<std::pair<const JSPandaFile *, uint32_t>, std::string> literalOffsetClassNameMap_ {};
kungfu::BytecodeInfoCollector *bcInfoCollector_ {nullptr};
// use for collect the literal of export type table.
CMap<std::pair<const JSPandaFile *, CString>, JSTaggedValue> resolvedExportTable_ {};
CMap<uint32_t, kungfu::GateType> methodOffsetToType_ {};
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_TS_TYPES_TS_MANAGER_H

Some files were not shown because too many files have changed in this diff Show More