From bd2d400232752f21a8ac1dee41fb271a292d3b3d Mon Sep 17 00:00:00 2001 From: huyunhui Date: Fri, 11 Jul 2025 11:45:27 +0800 Subject: [PATCH 1/8] Add perf-dump for project building Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLMTE Signed-off-by: huyunhui --- ets2panda/driver/build_system/src/build/base_mode.ts | 4 ++++ ets2panda/public/es2panda_lib.cpp | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index 4294c512ee..516652b301 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -117,6 +117,7 @@ export abstract class BaseMode { public byteCodeHar: boolean; public es2pandaMode: number; public skipDeclCheck: boolean; + public dumpPerf: boolean = false; constructor(buildConfig: BuildConfig) { this.buildConfig = buildConfig; @@ -354,6 +355,9 @@ export abstract class BaseMode { ets2pandaCmd.push('--debug-info'); ets2pandaCmd.push('--opt-level=0'); } + if (this.dumpPerf) { + ets2pandaCmd.push('--dump-perf-metrics'); + } ets2pandaCmd.push(this.buildConfig.compileFiles[0]); this.logger.printInfo('ets2pandaCmd: ' + ets2pandaCmd.join(' ')); diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index f9295c138b..f6213a4d1e 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -19,6 +19,7 @@ #include #include "util/diagnostic.h" +#include "util/perfMetrics.h" #include "varbinder/varbinder.h" #include "varbinder/scope.h" #include "public/public.h" @@ -253,6 +254,9 @@ extern "C" void DestroyConfig(es2panda_Config *config) return; } + if (cfg->options->IsDumpPerfMetrics()) { + util::DumpPerfMetrics(); + } delete cfg->options; cfg->diagnosticEngine->FlushDiagnostic(); delete cfg->diagnosticEngine; @@ -531,6 +535,7 @@ __attribute__((unused)) static Context *Parse(Context *ctx) } ctx->phaseManager->Reset(); + ES2PANDA_PERF_SCOPE("@Parser"); if (ctx->isExternal && ctx->allocator != ctx->globalContext->stdLibAllocator) { ctx->sourceFileNames.emplace_back(ctx->sourceFileName); @@ -599,6 +604,7 @@ __attribute__((unused)) static Context *Check(Context *ctx) if (phase->Name() == "plugins-after-check") { break; } + ES2PANDA_PERF_EVENT_SCOPE("@phases/" + std::string(phase->Name())); phase->Apply(ctx, ctx->parserProgram); } ctx->phaseManager->SetCurrentPhaseIdToAfterCheck(); @@ -639,6 +645,7 @@ __attribute__((unused)) static Context *Lower(Context *ctx) ES2PANDA_ASSERT(ctx->state == ES2PANDA_STATE_CHECKED); while (auto phase = ctx->phaseManager->NextPhase()) { + ES2PANDA_PERF_EVENT_SCOPE("@phases/" + std::string(phase->Name())); phase->Apply(ctx, ctx->parserProgram); } ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_LOWERED : ES2PANDA_STATE_ERROR; @@ -669,6 +676,7 @@ __attribute__((unused)) static Context *GenerateAsm(Context *ctx) ES2PANDA_ASSERT(ctx->state == ES2PANDA_STATE_LOWERED); + ES2PANDA_PERF_SCOPE("@EmitProgram"); auto *emitter = ctx->emitter; emitter->GenAnnotation(); @@ -1071,6 +1079,7 @@ extern "C" es2panda_Scope *AstNodeRebind(es2panda_Context *ctx, es2panda_AstNode extern "C" void AstNodeRecheck(es2panda_Context *ctx, es2panda_AstNode *node) { + ES2PANDA_PERF_SCOPE("@Recheck"); auto E2pNode = reinterpret_cast(node); auto context = reinterpret_cast(ctx); auto varbinder = context->parserProgram->VarBinder()->AsETSBinder(); -- Gitee From d20ba6efdcc47164cdbfd232f18353e61adec37f Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Fri, 11 Jul 2025 19:06:22 +0800 Subject: [PATCH 2/8] add perf point 4 check Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLTI6?from=project-issue Signed-off-by: wanmingxiang --- ets2panda/checker/ETSAnalyzer.cpp | 77 +++++++ ets2panda/checker/ETSchecker.cpp | 5 +- ets2panda/compiler/lowering/util.cpp | 3 + .../build_system/src/build/base_mode.ts | 2 +- ets2panda/util/perfMetrics.cpp | 215 +++++++++++++++--- ets2panda/util/perfMetrics.h | 16 +- 6 files changed, 284 insertions(+), 34 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index e611b5aef7..e9f582ed90 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -29,6 +29,7 @@ #include "types/type.h" #include "checker/types/typeError.h" #include "util/es2pandaMacros.h" +#include "util/perfMetrics.h" #include @@ -44,6 +45,7 @@ ETSChecker *ETSAnalyzer::GetETSChecker() const // from base folder checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const { + ES2PANDA_PERF_SCOPE("@Check-CatchClause"); ETSChecker *checker = GetETSChecker(); checker::Type *exceptionType = checker->GlobalTypeError(); @@ -83,6 +85,7 @@ checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const { + ES2PANDA_PERF_SCOPE("@Check-ClassDefinition"); ETSChecker *checker = GetETSChecker(); if (node->TsType() == nullptr) { @@ -98,6 +101,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const { + ES2PANDA_PERF_SCOPE("@Check-ClassProperty"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -150,6 +154,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const { + ES2PANDA_PERF_SCOPE("@Check-StaticBlock"); ETSChecker *checker = GetETSChecker(); if (checker->HasStatus(checker::CheckerStatus::INNER_CLASS)) { @@ -218,6 +223,7 @@ static bool IsInitializerBlockTransfer(std::string_view str) checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const { + ES2PANDA_PERF_SCOPE("@Check-MethodDefinition"); ETSChecker *checker = GetETSChecker(); auto *scriptFunc = node->Function(); @@ -366,6 +372,7 @@ static void CheckOverloadSameNameMethod(ETSChecker *const checker, ir::OverloadD checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const { + ES2PANDA_PERF_SCOPE("@Check-OverloadDeclaration"); ETSChecker *checker = GetETSChecker(); ES2PANDA_ASSERT(node != nullptr); ES2PANDA_ASSERT(node->Key()); @@ -394,12 +401,14 @@ checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const { + ES2PANDA_PERF_SCOPE("@Check-Property"); ETSChecker *checker = GetETSChecker(); return checker->GlobalTypeError(); } checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const { + ES2PANDA_PERF_SCOPE("@Check-SpreadElement"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -429,6 +438,7 @@ checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const { + ES2PANDA_PERF_SCOPE("@Check-SpreadElement"); ETSChecker *checker = GetETSChecker(); expr->SetTsType(checker->CreateETSStringLiteralType(expr->Raw())); return expr->TsType(); @@ -436,6 +446,7 @@ checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ETSClassLiteral"); ETSChecker *checker = GetETSChecker(); auto *const literal = expr->Expr(); @@ -462,6 +473,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSFunctionType"); if (node->TsType() != nullptr) { return node->TsType(); } @@ -538,6 +550,7 @@ static bool NeedCreateETSResizableArrayType(ETSChecker *checker, Type *type) checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ETSNewArrayInstanceExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -602,6 +615,7 @@ static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewCl checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ETSNewClassInstanceExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -630,6 +644,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ETSNewMultiDimArrayInstanceExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -662,11 +677,13 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *exp checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-ETSPackageDeclaration"); return ReturnTypeForStatement(st); } checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ETSParameterExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -687,12 +704,14 @@ checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPrimitiveType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSPrimitiveType"); ETSChecker *checker = GetETSChecker(); return node->GetType(checker); } checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSStructDeclaration"); ETSChecker *checker = GetETSChecker(); node->Definition()->Check(checker); return ReturnTypeForStatement(node); @@ -700,6 +719,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSTypeReference"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->GetType(checker); @@ -707,12 +727,14 @@ checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const checker::Type *ETSAnalyzer::Check(ir::ETSTypeReferencePart *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSTypeReferencePart"); ETSChecker *checker = GetETSChecker(); return node->GetType(checker); } checker::Type *ETSAnalyzer::Check(ir::ETSNonNullishTypeNode *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSNonNullishTypeNode"); if (node->TsType() != nullptr) { return node->TsType(); } @@ -722,6 +744,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNonNullishTypeNode *node) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSNullType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->SetTsType(checker->GlobalETSNullType()); @@ -729,6 +752,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSUndefinedType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->SetTsType(checker->GlobalETSUndefinedType()); @@ -736,12 +760,14 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) c checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSNeverType"); ETSChecker *checker = GetETSChecker(); return checker->GlobalETSNeverType(); } checker::Type *ETSAnalyzer::Check(ir::ETSStringLiteralType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSStringLiteralType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->GetType(checker); @@ -749,6 +775,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSStringLiteralType *node) const checker::Type *ETSAnalyzer::Check(ir::ETSKeyofType *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSKeyofType"); ETSChecker *checker = GetETSChecker(); return node->GetType(checker); } @@ -968,6 +995,7 @@ static Type *GetAppropriatePreferredType(Type *originalType, std::functionTsType() != nullptr) { return expr->TsType(); @@ -1036,6 +1064,7 @@ void TryInferPreferredType(ir::ArrowFunctionExpression *expr, checker::Type *pre checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ArrowFunctionExpession"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(expr->Annotations()); if (expr->TsType() != nullptr) { @@ -1231,6 +1260,7 @@ bool ETSAnalyzer::SetAssignmentExpressionTarget(ir::AssignmentExpression *const checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const { + ES2PANDA_PERF_SCOPE("@Check-AssignmentExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1359,6 +1389,7 @@ static bool IsPromiseType(checker::Type *type, ETSChecker *checker) checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-AwaitExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -1420,6 +1451,7 @@ checker::Type *ETSAnalyzer::UnwrapPromiseType(checker::Type *type) const checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-BinaryExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1461,6 +1493,7 @@ checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const { + ES2PANDA_PERF_SCOPE("@Check-BlockExpression"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -1711,6 +1744,7 @@ static void CheckOverloadCall(ETSChecker *checker, ir::CallExpression *expr) checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-CallExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -1799,6 +1833,7 @@ static Type *BiggerNumericType(ETSChecker *checker, Type *t1, Type *t2) checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-ConditionalExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1902,6 +1937,7 @@ static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const { + ES2PANDA_PERF_SCOPE("@Check-Identifier"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -2760,6 +2796,7 @@ static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argT checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-TypeofExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -2772,6 +2809,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) c checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-UnaryExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { @@ -2822,6 +2860,7 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-UpdateExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -2868,6 +2907,7 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const // compile methods for LITERAL EXPRESSIONS in alphabetical order checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-BigIntLiteral"); ETSChecker *checker = GetETSChecker(); expr->SetTsType(checker->CreateETSBigIntLiteralType(expr->Str())); return expr->TsType(); @@ -2875,6 +2915,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) cons checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-BooleanLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { auto type = checker->GlobalETSBooleanBuiltinType()->Clone(GetChecker()); @@ -2886,6 +2927,7 @@ checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-CharLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { auto type = checker->GlobalCharBuiltinType()->Clone(GetChecker()); @@ -2897,6 +2939,7 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-NullLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { expr->SetTsType(checker->GlobalETSNullType()); @@ -2942,6 +2985,7 @@ static bool CheckIfLiteralValueIsAppropriate(ETSChecker *checker, Type *type, ir checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-NumberLiteral"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -2976,6 +3020,7 @@ checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const { + ES2PANDA_PERF_SCOPE("@Check-StringLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { expr->SetTsType(checker->CreateETSStringLiteralType(expr->Str())); @@ -2985,6 +3030,7 @@ checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSIntrinsicNode *node) const { + ES2PANDA_PERF_SCOPE("@Check-ETSIntrinsicNode"); ETSChecker *checker = GetETSChecker(); for (auto *arg : node->Arguments()) { arg->Check(checker); @@ -3004,6 +3050,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSIntrinsicNode *node) const checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-ImportDeclaration"); ETSChecker *checker = GetETSChecker(); checker::Type *type = nullptr; for (auto *spec : st->Specifiers()) { @@ -3017,6 +3064,7 @@ checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const { + ES2PANDA_PERF_SCOPE("@Check-ImportNamespaceSpecifier"); ETSChecker *checker = GetETSChecker(); if (st->Local()->Name().Empty()) { return ReturnTypeForStatement(st); @@ -3047,11 +3095,13 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const // compile methods for STATEMENTS in alphabetical order checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::AssertStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-AssertStement"); ES2PANDA_UNREACHABLE(); } checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-BlockStement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3103,6 +3153,7 @@ checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-BreakStatement"); ETSChecker *checker = GetETSChecker(); if (!st->HasTarget()) { @@ -3120,6 +3171,7 @@ checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-ClassDeclaration"); ETSChecker *checker = GetETSChecker(); st->Definition()->Check(checker); return ReturnTypeForStatement(st); @@ -3127,6 +3179,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-AnnotationDeclaration"); if (st->Expr()->TsType() != nullptr) { return ReturnTypeForStatement(st); } @@ -3174,6 +3227,7 @@ static void ProcessRequiredFields(ArenaUnorderedMapExpr()->TsType() != nullptr) { return ReturnTypeForStatement(st); } @@ -3219,6 +3273,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-ContinueStatement"); ETSChecker *checker = GetETSChecker(); if (!st->HasTarget()) { @@ -3249,6 +3304,7 @@ checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-DoWhileStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3264,11 +3320,13 @@ checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::EmptyStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-EmptyStatement"); return ReturnTypeForStatement(st); } checker::Type *ETSAnalyzer::Check(ir::ExpressionStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-ExpressionStatement"); ETSChecker *checker = GetETSChecker(); return st->GetExpression()->Check(checker); } @@ -3308,6 +3366,7 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const { + ES2PANDA_PERF_SCOPE("@Check-ForOfStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3344,6 +3403,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-ForUpdateStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3370,6 +3430,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-IfStatement"); ETSChecker *const checker = GetETSChecker(); SmartCastArray smartCasts = checker->Context().EnterTestExpression(); @@ -3423,6 +3484,7 @@ checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const checker::Type *ETSAnalyzer::Check(ir::LabelledStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-LabeledStatement"); ETSChecker *checker = GetETSChecker(); st->body_->Check(checker); return ReturnTypeForStatement(st); @@ -3541,6 +3603,7 @@ checker::Type *ETSAnalyzer::GetFunctionReturnType(ir::ReturnStatement *st, ir::S checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-ReturnStatement"); ETSChecker *checker = GetETSChecker(); ir::AstNode *ancestor = util::Helpers::FindAncestorGivenByType(st, ir::AstNodeType::SCRIPT_FUNCTION); @@ -3575,6 +3638,7 @@ checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-SwitchStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(checker->Relation(), @@ -3622,6 +3686,7 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-ThrowStatement"); ETSChecker *checker = GetETSChecker(); const auto *arg = st->argument_; checker::Type *argType = st->argument_->Check(checker); @@ -3644,6 +3709,7 @@ checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-TryStatement"); ETSChecker *checker = GetETSChecker(); std::vector exceptions {}; @@ -3687,6 +3753,7 @@ checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const { + ES2PANDA_PERF_SCOPE("@Check-VariableDeclarator"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -3733,6 +3800,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-VariableDeclaration"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(st->Annotations()); @@ -3746,6 +3814,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const { + ES2PANDA_PERF_SCOPE("@Check-WhileStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3772,6 +3841,7 @@ checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const { + ES2PANDA_PERF_SCOPE("@Check-TSArrayType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); node->elementType_->Check(checker); @@ -3784,6 +3854,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-TSAsExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { @@ -3829,12 +3900,15 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-TSEnumDeclaration"); + // Some invalid TSEnumDeclaration will not be transformed to class. return ReturnTypeForStatement(st); } checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-TSInterfaceDeclaration"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -3865,6 +3939,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const { + ES2PANDA_PERF_SCOPE("@Check-TSNonNullExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -3945,6 +4020,7 @@ static varbinder::Variable *FindNameForImportNamespace(ETSChecker *checker, util checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const { + ES2PANDA_PERF_SCOPE("@Check-TSQualifiedName"); ETSChecker *checker = GetETSChecker(); checker::Type *baseType = expr->Left()->Check(checker)->MaybeBaseTypeOfGradualType(); if (baseType->IsETSObjectType()) { @@ -3978,6 +4054,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const { + ES2PANDA_PERF_SCOPE("@Check-TSTypeAliasDeclaration"); ETSChecker *checker = GetETSChecker(); auto checkerContext = SavedCheckerContext(checker, CheckerStatus::NO_OPTS, checker->Context().ContainingClass()); diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 3cde016475..b17a377527 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -391,7 +391,10 @@ void ETSChecker::CheckProgram(parser::Program *program, bool runAnalysis) ES2PANDA_ASSERT(Program()->Ast()->IsProgram()); - Program()->Ast()->Check(this); + { + ES2PANDA_PERF_SCOPE("@Check-AST"); + Program()->Ast()->Check(this); + } if (runAnalysis && !IsAnyError()) { AliveAnalyzer aliveAnalyzer(Program()->Ast(), this); diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 84e9ccb559..45bd4f631f 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -21,6 +21,7 @@ #include "checker/ETSAnalyzer.h" #include "checker/types/gradualType.h" #include "parser/JsdocHelper.h" +#include "util/perfMetrics.h" namespace ark::es2panda::compiler { @@ -275,12 +276,14 @@ void Recheck(PhaseManager *phaseManager, varbinder::ETSBinder *varBinder, checke } for (auto *phase : phaseManager->RecheckPhases()) { + ES2PANDA_PERF_EVENT_SCOPE("@Recheck-Prog-" + std::string(phase->Name())); phase->Apply(ctx, program); } phaseManager->SetCurrentPhaseIdToAfterCheck(); return; } + ES2PANDA_PERF_SCOPE("@Recheck-Prog-None"); auto *scope = Rebind(phaseManager, varBinder, node); // NOTE(gogabr: should determine checker status more finely. diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index 516652b301..0985ccb4ee 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -117,7 +117,7 @@ export abstract class BaseMode { public byteCodeHar: boolean; public es2pandaMode: number; public skipDeclCheck: boolean; - public dumpPerf: boolean = false; + public dumpPerf: boolean = true; constructor(buildConfig: BuildConfig) { this.buildConfig = buildConfig; diff --git a/ets2panda/util/perfMetrics.cpp b/ets2panda/util/perfMetrics.cpp index 981ec934c4..911a31ce5e 100644 --- a/ets2panda/util/perfMetrics.cpp +++ b/ets2panda/util/perfMetrics.cpp @@ -14,14 +14,17 @@ */ #include "util/perfMetrics.h" +#include "util/es2pandaMacros.h" #include "libpandabase/utils/logger.h" #include "libpandabase/utils/type_converter.h" #include "libpandabase/mem/mem.h" #include #include +#include #include #include +#include #ifdef PANDA_TARGET_UNIX #include "sys/resource.h" @@ -72,6 +75,14 @@ public: return Combine(acc, diff, true); } + static PerfMetricValue Accumulate(PerfMetricValue const &acc, PerfMetricValue const &begin, + PerfMetricValue const &end, PerfMetricValue const &other) + { + PerfMetricValue diff = Combine(end, begin, false); + PerfMetricValue preciseDiff = Combine(diff, other, false); + return Combine(acc, preciseDiff, true); + } + int64_t GetTimeNanoseconds() const { return time_; @@ -81,14 +92,6 @@ public: { return mem_; } - - DEFAULT_COPY_SEMANTIC(PerfMetricValue); - DEFAULT_MOVE_SEMANTIC(PerfMetricValue); - ~PerfMetricValue() = default; - -private: - PerfMetricValue() = default; - static PerfMetricValue Combine(PerfMetricValue const &st1, PerfMetricValue const &st2, bool sum) { int mult = sum ? 1 : -1; @@ -98,6 +101,13 @@ private: return res; } + DEFAULT_COPY_SEMANTIC(PerfMetricValue); + DEFAULT_MOVE_SEMANTIC(PerfMetricValue); + ~PerfMetricValue() = default; + +private: + PerfMetricValue() = default; + int64_t time_ {}; int64_t mem_ {}; }; @@ -110,7 +120,18 @@ public: { return acc_; } - + PerfMetricValue const &GetMin() const + { + return min_; + } + PerfMetricValue const &GetMax() const + { + return max_; + } + PerfMetricValue const &GetLast() const + { + return last_; + } std::string const &GetName() const { return name_; @@ -134,6 +155,57 @@ public: } } + void BeginTrace(PerfMetricRecord *rec) + { + auto now = PerfMetricValue::Now(); + std::vector arr; + callStack.push(now); + calleeStack.push(arr); + calleeArr = &calleeStack.top(); + callerStack.push(rec); + caller = rec; + + ++nesting_; + invokationsCount_++; + begin_ = now; + } + + void EndTrace(PerfMetricValue &other) + { + begin_ = callStack.top(); + calleeArr = &calleeStack.top(); + caller = callerStack.top(); + + for (size_t idx = 0; idx < calleeArr->size(); ++idx) { + auto item = (*calleeArr)[idx]; + other = PerfMetricValue::Combine(other, item, true); + } + PerfMetricValue curr = PerfMetricValue::Now(); + last_ = PerfMetricValue::Combine(curr, begin_, false); + acc_ = PerfMetricValue::Accumulate(acc_, begin_, curr, other); + auto preciseLast = PerfMetricValue::Combine(last_, other, false); + ES2PANDA_ASSERT(last_.GetTimeNanoseconds() >= other.GetTimeNanoseconds()); + if (preciseLast.GetTimeNanoseconds() > max_.GetTimeNanoseconds()) { + max_ = preciseLast; + } + if (invokationsCount_ == 1 || preciseLast.GetTimeNanoseconds() < min_.GetTimeNanoseconds()) { + min_ = preciseLast; + } + + callStack.pop(); + calleeStack.pop(); + callerStack.pop(); + calleeArr = nullptr; + if (!calleeStack.empty()) { + calleeArr = &calleeStack.top(); + } + --nesting_; + } + + size_t GetNesting() const + { + return nesting_; + } size_t GetMaxNesting() const { return maxNesting_; @@ -148,13 +220,22 @@ public: DEFAULT_MOVE_SEMANTIC(PerfMetricRecord); ~PerfMetricRecord() = default; + PerfMetricValue begin_ = PerfMetricValue::Zero(); + PerfMetricRecord *caller; + std::vector *calleeArr; + std::stack> calleeStack; + std::stack callerStack; + private: size_t nesting_ {}; size_t maxNesting_ {}; size_t invokationsCount_ {}; std::string name_; PerfMetricValue acc_ = PerfMetricValue::Zero(); - PerfMetricValue begin_ = PerfMetricValue::Zero(); + PerfMetricValue last_ = PerfMetricValue::Zero(); + PerfMetricValue min_ = PerfMetricValue::Zero(); + PerfMetricValue max_ = PerfMetricValue::Zero(); + std::stack callStack; }; PerfMetricScope::PerfMetricScope(PerfMetricRecord *record) : record_(record) @@ -168,6 +249,7 @@ PerfMetricScope::~PerfMetricScope() } // NOLINTBEGIN(fuchsia-statically-constructed-objects) +static std::forward_list>> g_perfMetricsStackList; static std::forward_list>> g_perfMetricsLists; static std::mutex g_perfMetricsListsMtx; // NOLINTEND(fuchsia-statically-constructed-objects) @@ -183,6 +265,70 @@ std::forward_list *GetTLSPerfMetricsData() return tls; } +std::stack *GetTLSPerfMetricsStack() +{ + thread_local auto tls = ([]() { + std::lock_guard lk(g_perfMetricsListsMtx); + g_perfMetricsStackList.push_front({os::thread::GetCurrentThreadId(), std::stack()}); + return &g_perfMetricsStackList.begin()->second; + })(); + + return tls; +} + +PrecisePerfMetricScope::PrecisePerfMetricScope(PerfMetricRecord *record) : record_(record) +{ + PerfMetricRecord *caller = nullptr; + if (!GetTLSPerfMetricsStack()->empty()) { + caller = GetTLSPerfMetricsStack()->top(); + } + record_->BeginTrace(caller); + GetTLSPerfMetricsStack()->push(record); + // if (caller) { + // std::cout << std::left << std::setw(16) << "[stack dep]: " << GetTLSPerfMetricsStack()->size() << + // std::left + // << std::setw(20) << " [scope begin] : " << std::setw(25) << record_->GetName() << ", " + // << std::setw(12) << record_ << ", " << record_->GetNesting() << std::setw(10) + // << " [parent]: " << caller->GetName() << ", " << caller << ", " << caller->GetNesting() << + // std::endl; + // + // } else { + // std::cout << std::left << std::setw(16) << "[stack dep]: " << GetTLSPerfMetricsStack()->size() << + // std::left + // << std::setw(20) << " [scope begin] : " << std::setw(25) << record_->GetName() << ", " + // << std::setw(12) << record_ << ", " << record_->GetNesting() << " ,parent: NULL" + // << std::endl; + // } +} + +PrecisePerfMetricScope::~PrecisePerfMetricScope() +{ + auto *tlStack = GetTLSPerfMetricsStack(); + auto childCost = PerfMetricValue::Zero(); + + record_->EndTrace(childCost); + + tlStack->pop(); + if (record_->caller != nullptr) { + record_->caller->calleeArr->push_back(record_->GetLast()); + // auto caller = record_->caller; + // std::cout << std::left << std::setw(16) << "[stack dep]: " << GetTLSPerfMetricsStack()->size() << + // std::left + // << std::setw(20) << " [scope end] : " << std::setw(25) << record_->GetName() << ", " << + // std::setw(12) + // << record_ << ", " << record_->GetNesting() << std::setw(10) << " [parent]: " << + // caller->GetName() + // << ", " << caller << ", " << caller->GetNesting() << std::endl; + + } else { + // std::cout << std::left << std::setw(16) << "[stack dep]: " << GetTLSPerfMetricsStack()->size() << + // std::left + // << std::setw(20) << " [scope end] : " << std::setw(25) << record_->GetName() << ", " << + // std::setw(12) + // << record_ << ", nesting: " << record_->GetNesting() << " parent: NULL" << std::endl; + } +} + PerfMetricRecord *RegisterPerfMetricRecord(std::string_view name) { auto *tls = GetTLSPerfMetricsData(); @@ -190,30 +336,36 @@ PerfMetricRecord *RegisterPerfMetricRecord(std::string_view name) return &tls->front(); } -static std::string PrettyTimeNs(uint64_t duration) +static std::string PrettyTimeNs(uint64_t duration, bool pretty = true) { - // CC-OFF(G.NAM.03-CPP) project code style - constexpr std::array TIME_UNITS = {"ns", "us", "ms", "s"}; - // CC-OFF(G.NAM.03-CPP) project code style - constexpr double K_SCALE = 1E3; - - if (duration == 0) { - return "0s"; - } + if (pretty) { + // CC-OFF(G.NAM.03-CPP) project code style + constexpr std::array TIME_UNITS = {"ns", "us", "ms", "s"}; + // CC-OFF(G.NAM.03-CPP) project code style + constexpr double K_SCALE = 1E3; + + if (duration == 0) { + return "0s"; + } - double val = duration; - size_t unitIdx = 0; + double val = duration; + size_t unitIdx = 0; - for (;; ++unitIdx) { - double nextVal = val / K_SCALE; - if (unitIdx == TIME_UNITS.size() || nextVal < 1.0) { - break; + for (;; ++unitIdx) { + double nextVal = val / K_SCALE; + if (unitIdx == TIME_UNITS.size() || nextVal < 1.0) { + break; + } + val = nextVal; } - val = nextVal; - } + std::stringstream ss; + ss << std::setprecision(3U) << val << TIME_UNITS[unitIdx]; + return ss.str(); + } + double val = duration; std::stringstream ss; - ss << std::setprecision(3U) << val << TIME_UNITS[unitIdx]; + ss << std::setprecision(3U) << val; return ss.str(); } @@ -234,8 +386,11 @@ static void DumpPerfMetricRecord(std::stringstream &ss, PerfMetricRecord const * if (rec->GetInvokationsCount() > 1) { metric("count", 8U) << rec->GetInvokationsCount(); } - metric("time", 10U) << PrettyTimeNs(stats.GetTimeNanoseconds()); - auto memValue = ark::helpers::MemoryConverter(stats.GetMemorySize()); + metric("all", 10U) << PrettyTimeNs(stats.GetTimeNanoseconds(), false); + metric("avg", 10U) << PrettyTimeNs(stats.GetTimeNanoseconds() / rec->GetInvokationsCount(), false); + metric("min", 10U) << PrettyTimeNs(rec->GetMin().GetTimeNanoseconds()); + metric("max", 10U) << PrettyTimeNs(rec->GetMax().GetTimeNanoseconds()); + auto memValue = ark::helpers::MemoryConverter(stats.GetMemorySize() / rec->GetInvokationsCount()); metric("mem", 10U) << (std::to_string(static_cast(memValue.GetDoubleValue())) + std::string(memValue.GetLiteral())); // NOLINTEND(readability-magic-numbers) diff --git a/ets2panda/util/perfMetrics.h b/ets2panda/util/perfMetrics.h index 37f72ffbca..37ef2a373e 100644 --- a/ets2panda/util/perfMetrics.h +++ b/ets2panda/util/perfMetrics.h @@ -31,7 +31,7 @@ namespace ark::es2panda::util { #define ES2PANDA_PERF_SCOPE(name) \ thread_local auto ES2PANDA_PERF_CONCAT2(e2pPerfRecord, __LINE__) = \ ark::es2panda::util::RegisterPerfMetricRecord(name); \ - ark::es2panda::util::PerfMetricScope ES2PANDA_PERF_CONCAT2(e2pPerfScope, __LINE__)( \ + ark::es2panda::util::PrecisePerfMetricScope ES2PANDA_PERF_CONCAT2(e2pPerfScope, __LINE__)( \ ES2PANDA_PERF_CONCAT2(e2pPerfRecord, __LINE__)) // Similar to ES2PANDA_PERF_SCOPE, the current functions name is assigned to the performance record. @@ -42,7 +42,7 @@ namespace ark::es2panda::util { // a new performance record. Do not use it if scope is created frequently. // CC-OFFNXT(G.PRE.02-CPP) macro definition #define ES2PANDA_PERF_EVENT_SCOPE(name) \ - ark::es2panda::util::PerfMetricScope e2pPerfScope(ark::es2panda::util::RegisterPerfMetricRecord(name)) + ark::es2panda::util::PrecisePerfMetricScope e2pPerfScope(ark::es2panda::util::RegisterPerfMetricRecord(name)) // NOLINTEND(cppcoreguidelines-macro-usage) // Dump all the collected performance records. Should not be called if there are active threads using the profile. @@ -63,6 +63,18 @@ private: PerfMetricRecord *record_; }; +class PrecisePerfMetricScope { +public: + explicit PrecisePerfMetricScope(PerfMetricRecord *record); + ~PrecisePerfMetricScope(); + + NO_COPY_SEMANTIC(PrecisePerfMetricScope); + NO_MOVE_SEMANTIC(PrecisePerfMetricScope); + +private: + PerfMetricRecord *record_; +}; + } // namespace ark::es2panda::util #endif -- Gitee From e18dc7a36a4f24d39094019057c323ef1b67be93 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Tue, 22 Jul 2025 19:14:19 +0800 Subject: [PATCH 3/8] add scope less perf point --- ets2panda/checker/ETSAnalyzer.cpp | 150 +++++++++++++-------------- ets2panda/checker/ETSchecker.cpp | 2 +- ets2panda/compiler/lowering/util.cpp | 1 - ets2panda/util/perfMetrics.h | 8 +- 4 files changed, 83 insertions(+), 78 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index e9f582ed90..b142ddbe1d 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -45,7 +45,7 @@ ETSChecker *ETSAnalyzer::GetETSChecker() const // from base folder checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const { - ES2PANDA_PERF_SCOPE("@Check-CatchClause"); + ES2PANDA_PERF_SCOPELESS("@Check-CatchClause"); ETSChecker *checker = GetETSChecker(); checker::Type *exceptionType = checker->GlobalTypeError(); @@ -85,7 +85,7 @@ checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const { - ES2PANDA_PERF_SCOPE("@Check-ClassDefinition"); + ES2PANDA_PERF_SCOPELESS("@Check-ClassDefinition"); ETSChecker *checker = GetETSChecker(); if (node->TsType() == nullptr) { @@ -101,7 +101,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const { - ES2PANDA_PERF_SCOPE("@Check-ClassProperty"); + ES2PANDA_PERF_SCOPELESS("@Check-ClassProperty"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -154,7 +154,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const { - ES2PANDA_PERF_SCOPE("@Check-StaticBlock"); + ES2PANDA_PERF_SCOPELESS("@Check-StaticBlock"); ETSChecker *checker = GetETSChecker(); if (checker->HasStatus(checker::CheckerStatus::INNER_CLASS)) { @@ -223,7 +223,7 @@ static bool IsInitializerBlockTransfer(std::string_view str) checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const { - ES2PANDA_PERF_SCOPE("@Check-MethodDefinition"); + ES2PANDA_PERF_SCOPELESS("@Check-MethodDefinition"); ETSChecker *checker = GetETSChecker(); auto *scriptFunc = node->Function(); @@ -372,7 +372,7 @@ static void CheckOverloadSameNameMethod(ETSChecker *const checker, ir::OverloadD checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const { - ES2PANDA_PERF_SCOPE("@Check-OverloadDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-OverloadDeclaration"); ETSChecker *checker = GetETSChecker(); ES2PANDA_ASSERT(node != nullptr); ES2PANDA_ASSERT(node->Key()); @@ -401,14 +401,14 @@ checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const { - ES2PANDA_PERF_SCOPE("@Check-Property"); + ES2PANDA_PERF_SCOPELESS("@Check-Property"); ETSChecker *checker = GetETSChecker(); return checker->GlobalTypeError(); } checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const { - ES2PANDA_PERF_SCOPE("@Check-SpreadElement"); + ES2PANDA_PERF_SCOPELESS("@Check-SpreadElement"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -438,7 +438,7 @@ checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const { - ES2PANDA_PERF_SCOPE("@Check-SpreadElement"); + ES2PANDA_PERF_SCOPELESS("@Check-SpreadElement"); ETSChecker *checker = GetETSChecker(); expr->SetTsType(checker->CreateETSStringLiteralType(expr->Raw())); return expr->TsType(); @@ -446,7 +446,7 @@ checker::Type *ETSAnalyzer::Check(ir::TemplateElement *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ETSClassLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSClassLiteral"); ETSChecker *checker = GetETSChecker(); auto *const literal = expr->Expr(); @@ -473,7 +473,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSFunctionType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSFunctionType"); if (node->TsType() != nullptr) { return node->TsType(); } @@ -550,7 +550,7 @@ static bool NeedCreateETSResizableArrayType(ETSChecker *checker, Type *type) checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ETSNewArrayInstanceExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSNewArrayInstanceExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -615,7 +615,7 @@ static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewCl checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ETSNewClassInstanceExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSNewClassInstanceExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -644,7 +644,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ETSNewMultiDimArrayInstanceExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSNewMultiDimArrayInstanceExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -677,13 +677,13 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *exp checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-ETSPackageDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSPackageDeclaration"); return ReturnTypeForStatement(st); } checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ETSParameterExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSParameterExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -704,14 +704,14 @@ checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPrimitiveType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSPrimitiveType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSPrimitiveType"); ETSChecker *checker = GetETSChecker(); return node->GetType(checker); } checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSStructDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSStructDeclaration"); ETSChecker *checker = GetETSChecker(); node->Definition()->Check(checker); return ReturnTypeForStatement(node); @@ -719,7 +719,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSTypeReference"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSTypeReference"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->GetType(checker); @@ -727,14 +727,14 @@ checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const checker::Type *ETSAnalyzer::Check(ir::ETSTypeReferencePart *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSTypeReferencePart"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSTypeReferencePart"); ETSChecker *checker = GetETSChecker(); return node->GetType(checker); } checker::Type *ETSAnalyzer::Check(ir::ETSNonNullishTypeNode *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSNonNullishTypeNode"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSNonNullishTypeNode"); if (node->TsType() != nullptr) { return node->TsType(); } @@ -744,7 +744,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNonNullishTypeNode *node) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSNullType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSNullType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->SetTsType(checker->GlobalETSNullType()); @@ -752,7 +752,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSUndefinedType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSUndefinedType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->SetTsType(checker->GlobalETSUndefinedType()); @@ -760,14 +760,14 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) c checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSNeverType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSNeverType"); ETSChecker *checker = GetETSChecker(); return checker->GlobalETSNeverType(); } checker::Type *ETSAnalyzer::Check(ir::ETSStringLiteralType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSStringLiteralType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSStringLiteralType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); return node->GetType(checker); @@ -775,7 +775,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSStringLiteralType *node) const checker::Type *ETSAnalyzer::Check(ir::ETSKeyofType *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSKeyofType"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSKeyofType"); ETSChecker *checker = GetETSChecker(); return node->GetType(checker); } @@ -995,7 +995,7 @@ static Type *GetAppropriatePreferredType(Type *originalType, std::functionTsType() != nullptr) { return expr->TsType(); @@ -1064,7 +1064,7 @@ void TryInferPreferredType(ir::ArrowFunctionExpression *expr, checker::Type *pre checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ArrowFunctionExpession"); + ES2PANDA_PERF_SCOPELESS("@Check-ArrowFunctionExpession"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(expr->Annotations()); if (expr->TsType() != nullptr) { @@ -1260,7 +1260,7 @@ bool ETSAnalyzer::SetAssignmentExpressionTarget(ir::AssignmentExpression *const checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const { - ES2PANDA_PERF_SCOPE("@Check-AssignmentExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-AssignmentExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1389,7 +1389,7 @@ static bool IsPromiseType(checker::Type *type, ETSChecker *checker) checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-AwaitExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-AwaitExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -1451,7 +1451,7 @@ checker::Type *ETSAnalyzer::UnwrapPromiseType(checker::Type *type) const checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-BinaryExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-BinaryExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1493,7 +1493,7 @@ checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const { - ES2PANDA_PERF_SCOPE("@Check-BlockExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-BlockExpression"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -1744,7 +1744,7 @@ static void CheckOverloadCall(ETSChecker *checker, ir::CallExpression *expr) checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-CallExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-CallExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -1833,7 +1833,7 @@ static Type *BiggerNumericType(ETSChecker *checker, Type *t1, Type *t2) checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-ConditionalExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-ConditionalExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1937,7 +1937,7 @@ static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const { - ES2PANDA_PERF_SCOPE("@Check-Identifier"); + ES2PANDA_PERF_SCOPELESS("@Check-Identifier"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -2796,7 +2796,7 @@ static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argT checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-TypeofExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-TypeofExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -2809,7 +2809,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TypeofExpression *expr) c checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-UnaryExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-UnaryExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { @@ -2860,7 +2860,7 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-UpdateExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-UpdateExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { return expr->TsType(); @@ -2907,7 +2907,7 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const // compile methods for LITERAL EXPRESSIONS in alphabetical order checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-BigIntLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-BigIntLiteral"); ETSChecker *checker = GetETSChecker(); expr->SetTsType(checker->CreateETSBigIntLiteralType(expr->Str())); return expr->TsType(); @@ -2915,7 +2915,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::BigIntLiteral *expr) cons checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-BooleanLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-BooleanLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { auto type = checker->GlobalETSBooleanBuiltinType()->Clone(GetChecker()); @@ -2927,7 +2927,7 @@ checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-CharLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-CharLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { auto type = checker->GlobalCharBuiltinType()->Clone(GetChecker()); @@ -2939,7 +2939,7 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-NullLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-NullLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { expr->SetTsType(checker->GlobalETSNullType()); @@ -2985,7 +2985,7 @@ static bool CheckIfLiteralValueIsAppropriate(ETSChecker *checker, Type *type, ir checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-NumberLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-NumberLiteral"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -3020,7 +3020,7 @@ checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const { - ES2PANDA_PERF_SCOPE("@Check-StringLiteral"); + ES2PANDA_PERF_SCOPELESS("@Check-StringLiteral"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { expr->SetTsType(checker->CreateETSStringLiteralType(expr->Str())); @@ -3030,7 +3030,7 @@ checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::ETSIntrinsicNode *node) const { - ES2PANDA_PERF_SCOPE("@Check-ETSIntrinsicNode"); + ES2PANDA_PERF_SCOPELESS("@Check-ETSIntrinsicNode"); ETSChecker *checker = GetETSChecker(); for (auto *arg : node->Arguments()) { arg->Check(checker); @@ -3050,7 +3050,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSIntrinsicNode *node) const checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-ImportDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-ImportDeclaration"); ETSChecker *checker = GetETSChecker(); checker::Type *type = nullptr; for (auto *spec : st->Specifiers()) { @@ -3064,7 +3064,7 @@ checker::Type *ETSAnalyzer::Check(ir::ImportDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const { - ES2PANDA_PERF_SCOPE("@Check-ImportNamespaceSpecifier"); + ES2PANDA_PERF_SCOPELESS("@Check-ImportNamespaceSpecifier"); ETSChecker *checker = GetETSChecker(); if (st->Local()->Name().Empty()) { return ReturnTypeForStatement(st); @@ -3095,13 +3095,13 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const // compile methods for STATEMENTS in alphabetical order checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::AssertStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-AssertStement"); + ES2PANDA_PERF_SCOPELESS("@Check-AssertStement"); ES2PANDA_UNREACHABLE(); } checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-BlockStement"); + ES2PANDA_PERF_SCOPELESS("@Check-BlockStement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3153,7 +3153,7 @@ checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-BreakStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-BreakStatement"); ETSChecker *checker = GetETSChecker(); if (!st->HasTarget()) { @@ -3171,7 +3171,7 @@ checker::Type *ETSAnalyzer::Check(ir::BreakStatement *st) const checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-ClassDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-ClassDeclaration"); ETSChecker *checker = GetETSChecker(); st->Definition()->Check(checker); return ReturnTypeForStatement(st); @@ -3179,7 +3179,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-AnnotationDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-AnnotationDeclaration"); if (st->Expr()->TsType() != nullptr) { return ReturnTypeForStatement(st); } @@ -3227,7 +3227,7 @@ static void ProcessRequiredFields(ArenaUnorderedMapExpr()->TsType() != nullptr) { return ReturnTypeForStatement(st); } @@ -3273,7 +3273,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-ContinueStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-ContinueStatement"); ETSChecker *checker = GetETSChecker(); if (!st->HasTarget()) { @@ -3304,7 +3304,7 @@ checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-DoWhileStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-DoWhileStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3320,13 +3320,13 @@ checker::Type *ETSAnalyzer::Check(ir::DoWhileStatement *st) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::EmptyStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-EmptyStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-EmptyStatement"); return ReturnTypeForStatement(st); } checker::Type *ETSAnalyzer::Check(ir::ExpressionStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-ExpressionStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-ExpressionStatement"); ETSChecker *checker = GetETSChecker(); return st->GetExpression()->Check(checker); } @@ -3366,7 +3366,7 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const { - ES2PANDA_PERF_SCOPE("@Check-ForOfStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-ForOfStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3403,7 +3403,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-ForUpdateStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-ForUpdateStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3430,7 +3430,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForUpdateStatement *st) const checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-IfStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-IfStatement"); ETSChecker *const checker = GetETSChecker(); SmartCastArray smartCasts = checker->Context().EnterTestExpression(); @@ -3484,7 +3484,7 @@ checker::Type *ETSAnalyzer::Check(ir::IfStatement *st) const checker::Type *ETSAnalyzer::Check(ir::LabelledStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-LabeledStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-LabeledStatement"); ETSChecker *checker = GetETSChecker(); st->body_->Check(checker); return ReturnTypeForStatement(st); @@ -3603,7 +3603,7 @@ checker::Type *ETSAnalyzer::GetFunctionReturnType(ir::ReturnStatement *st, ir::S checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-ReturnStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-ReturnStatement"); ETSChecker *checker = GetETSChecker(); ir::AstNode *ancestor = util::Helpers::FindAncestorGivenByType(st, ir::AstNodeType::SCRIPT_FUNCTION); @@ -3638,7 +3638,7 @@ checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-SwitchStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-SwitchStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(checker->Relation(), @@ -3686,7 +3686,7 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-ThrowStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-ThrowStatement"); ETSChecker *checker = GetETSChecker(); const auto *arg = st->argument_; checker::Type *argType = st->argument_->Check(checker); @@ -3709,7 +3709,7 @@ checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-TryStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-TryStatement"); ETSChecker *checker = GetETSChecker(); std::vector exceptions {}; @@ -3753,7 +3753,7 @@ checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const { - ES2PANDA_PERF_SCOPE("@Check-VariableDeclarator"); + ES2PANDA_PERF_SCOPELESS("@Check-VariableDeclarator"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -3800,7 +3800,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-VariableDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-VariableDeclaration"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(st->Annotations()); @@ -3814,7 +3814,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const { - ES2PANDA_PERF_SCOPE("@Check-WhileStatement"); + ES2PANDA_PERF_SCOPELESS("@Check-WhileStatement"); ETSChecker *checker = GetETSChecker(); checker::ScopeContext scopeCtx(checker, st->Scope()); @@ -3841,7 +3841,7 @@ checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const { - ES2PANDA_PERF_SCOPE("@Check-TSArrayType"); + ES2PANDA_PERF_SCOPELESS("@Check-TSArrayType"); ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); node->elementType_->Check(checker); @@ -3854,7 +3854,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-TSAsExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-TSAsExpression"); ETSChecker *checker = GetETSChecker(); if (expr->TsType() != nullptr) { @@ -3900,7 +3900,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-TSEnumDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-TSEnumDeclaration"); // Some invalid TSEnumDeclaration will not be transformed to class. return ReturnTypeForStatement(st); @@ -3908,7 +3908,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-TSInterfaceDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-TSInterfaceDeclaration"); if (st->TsType() != nullptr) { return st->TsType(); } @@ -3939,7 +3939,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const { - ES2PANDA_PERF_SCOPE("@Check-TSNonNullExpression"); + ES2PANDA_PERF_SCOPELESS("@Check-TSNonNullExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -4020,7 +4020,7 @@ static varbinder::Variable *FindNameForImportNamespace(ETSChecker *checker, util checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const { - ES2PANDA_PERF_SCOPE("@Check-TSQualifiedName"); + ES2PANDA_PERF_SCOPELESS("@Check-TSQualifiedName"); ETSChecker *checker = GetETSChecker(); checker::Type *baseType = expr->Left()->Check(checker)->MaybeBaseTypeOfGradualType(); if (baseType->IsETSObjectType()) { @@ -4054,7 +4054,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const { - ES2PANDA_PERF_SCOPE("@Check-TSTypeAliasDeclaration"); + ES2PANDA_PERF_SCOPELESS("@Check-TSTypeAliasDeclaration"); ETSChecker *checker = GetETSChecker(); auto checkerContext = SavedCheckerContext(checker, CheckerStatus::NO_OPTS, checker->Context().ContainingClass()); diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index b17a377527..049b1bc0e0 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -392,7 +392,7 @@ void ETSChecker::CheckProgram(parser::Program *program, bool runAnalysis) ES2PANDA_ASSERT(Program()->Ast()->IsProgram()); { - ES2PANDA_PERF_SCOPE("@Check-AST"); + ES2PANDA_PERF_SCOPELESS("@Check-AST"); Program()->Ast()->Check(this); } diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 45bd4f631f..b6043c1c18 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -283,7 +283,6 @@ void Recheck(PhaseManager *phaseManager, varbinder::ETSBinder *varBinder, checke return; } - ES2PANDA_PERF_SCOPE("@Recheck-Prog-None"); auto *scope = Rebind(phaseManager, varBinder, node); // NOTE(gogabr: should determine checker status more finely. diff --git a/ets2panda/util/perfMetrics.h b/ets2panda/util/perfMetrics.h index 37ef2a373e..16935a1ca8 100644 --- a/ets2panda/util/perfMetrics.h +++ b/ets2panda/util/perfMetrics.h @@ -29,6 +29,12 @@ namespace ark::es2panda::util { // unique record, which accumulates metrics on each subsequent invokation. // CC-OFFNXT(G.PRE.02-CPP) macro definition #define ES2PANDA_PERF_SCOPE(name) \ + thread_local auto ES2PANDA_PERF_CONCAT2(e2pPerfRecord, __LINE__) = \ + ark::es2panda::util::RegisterPerfMetricRecord(name); \ + ark::es2panda::util::PerfMetricScope ES2PANDA_PERF_CONCAT2(e2pPerfScope, __LINE__)( \ + ES2PANDA_PERF_CONCAT2(e2pPerfRecord, __LINE__)) + +#define ES2PANDA_PERF_SCOPELESS(name) \ thread_local auto ES2PANDA_PERF_CONCAT2(e2pPerfRecord, __LINE__) = \ ark::es2panda::util::RegisterPerfMetricRecord(name); \ ark::es2panda::util::PrecisePerfMetricScope ES2PANDA_PERF_CONCAT2(e2pPerfScope, __LINE__)( \ @@ -42,7 +48,7 @@ namespace ark::es2panda::util { // a new performance record. Do not use it if scope is created frequently. // CC-OFFNXT(G.PRE.02-CPP) macro definition #define ES2PANDA_PERF_EVENT_SCOPE(name) \ - ark::es2panda::util::PrecisePerfMetricScope e2pPerfScope(ark::es2panda::util::RegisterPerfMetricRecord(name)) + ark::es2panda::util::PerfMetricScope e2pPerfScope(ark::es2panda::util::RegisterPerfMetricRecord(name)) // NOLINTEND(cppcoreguidelines-macro-usage) // Dump all the collected performance records. Should not be called if there are active threads using the profile. -- Gitee From c0caede09d92f97f4f6910b4f819459b033d9833 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Wed, 6 Aug 2025 17:02:37 +0800 Subject: [PATCH 4/8] arena status --- ets2panda/util/perfMetrics.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ets2panda/util/perfMetrics.cpp b/ets2panda/util/perfMetrics.cpp index 911a31ce5e..76a1487beb 100644 --- a/ets2panda/util/perfMetrics.cpp +++ b/ets2panda/util/perfMetrics.cpp @@ -19,6 +19,7 @@ #include "libpandabase/utils/logger.h" #include "libpandabase/utils/type_converter.h" #include "libpandabase/mem/mem.h" +#include "libpandabase/mem/arena_allocator_stl_adapter.h" #include #include #include @@ -114,7 +115,7 @@ private: class PerfMetricRecord { public: - explicit PerfMetricRecord(std::string_view name) : name_(name) {} + explicit PerfMetricRecord(std::string_view name) : name_(name), aRecord(GetName()), cRecord(GetName()) {} PerfMetricValue const &GetStats() const { @@ -146,6 +147,8 @@ public: if (++nesting_ > maxNesting_) { maxNesting_ = nesting_; } + aRecord.begin(); + cRecord.begin(); } void EndTrace() @@ -153,6 +156,8 @@ public: if (--nesting_ == 0) { acc_ = PerfMetricValue::Accumulate(acc_, begin_, PerfMetricValue::Now()); } + aRecord.end(); + cRecord.end(); } void BeginTrace(PerfMetricRecord *rec) @@ -236,6 +241,9 @@ private: PerfMetricValue min_ = PerfMetricValue::Zero(); PerfMetricValue max_ = PerfMetricValue::Zero(); std::stack callStack; + ark::ArenaMemRecord aRecord; + ark::ContMemRecord cRecord; + }; PerfMetricScope::PerfMetricScope(PerfMetricRecord *record) : record_(record) @@ -428,6 +436,8 @@ static void DumpPerfMetricsImpl(std::optional prefix) } std::cout << ss.str(); + ark::ArenaMemRecord::Print(); + ark::ContMemRecord::Print(); } void DumpPerfMetrics() -- Gitee From cce4ad92ebb6fa7be5dada683f71fdc795807d84 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Mon, 4 Aug 2025 21:12:36 +0800 Subject: [PATCH 5/8] Fix Err on Switch 2 std containner 1, mem reuse err during binding phase 2, fix ite err of vector --- ets2panda/checker/ets/utilityTypeHandlers.cpp | 3 +-- ets2panda/checker/types/ets/etsObjectType.cpp | 7 ++----- ets2panda/checker/types/ets/etsObjectType.h | 8 ++++++++ ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp | 7 ++++--- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 26c11a60a3..519bb79f67 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -1127,8 +1127,7 @@ void ETSChecker::MakePropertyNonNullish(ETSObjectType *const classType, varbinde auto *const propCopy = prop->Copy(ProgramAllocator(), prop->Declaration()); ES2PANDA_ASSERT(propCopy != nullptr); propCopy->SetTsType(nonNullishPropType); - classType->RemoveProperty(prop); - classType->AddProperty(propCopy); + classType->UpdateProperty(prop, propCopy); } static bool StringEqualsPropertyName(const util::StringView pname1, const ir::Expression *const prop2Key) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 4bf8a2f7c1..ec72e7fe48 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -1258,14 +1258,11 @@ void ETSObjectType::UpdateTypeProperty(varbinder::LocalVariable *const prop, Pro PropertyProcesser const &func) { auto const propType = prop->Declaration()->Node()->Check(GetETSChecker()); - auto *const propCopy = func(prop, propType); if (fieldType == PropertyType::INSTANCE_FIELD) { - RemoveProperty(prop); - AddProperty(propCopy); + UpdateProperty(prop, propCopy); } else { - RemoveProperty(prop); - AddProperty(propCopy); + UpdateProperty(prop, propCopy); } } diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index a86f126b97..3398bf6167 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -329,6 +329,7 @@ public: propertiesInstantiated_ = true; } + // Do not erase in loop of properties_' iteration template void RemoveProperty(varbinder::LocalVariable *prop) { @@ -336,6 +337,13 @@ public: propertiesInstantiated_ = true; } + template + void UpdateProperty(varbinder::LocalVariable *oldProp, varbinder::LocalVariable *newProp) + { + properties_[static_cast(TYPE)][oldProp->Name()] = newProp; + propertiesInstantiated_ = true; + } + [[nodiscard]] bool IsGeneric() const noexcept { return !typeArguments_.empty(); diff --git a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp index 7283b469f5..8539c96d3d 100644 --- a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp +++ b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp @@ -205,9 +205,10 @@ void UpdateClassDefintion(checker::ETSChecker *checker, ir::ClassDefinition *cla { checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), classDef->TsType()->AsETSObjectType()); - for (auto *it : classDef->Body()) { - if (it->IsMethodDefinition()) { - HandleMethod(checker, it->AsMethodDefinition()); + for (size_t i = 0; i < classDef->Body().size(); ++i) { + auto *node = classDef->Body()[i]; + if (node->IsMethodDefinition()) { + HandleMethod(checker, node->AsMethodDefinition()); } } } -- Gitee From 33343f80b7a82c84b3933150b1250e4a4df4d174 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Sat, 9 Aug 2025 14:43:12 +0800 Subject: [PATCH 6/8] lazy init containner 4 etsobjtype --- ets2panda/checker/types/ets/etsObjectType.cpp | 73 ++++++++-------- ets2panda/checker/types/ets/etsObjectType.h | 86 ++++++++++++++----- 2 files changed, 102 insertions(+), 57 deletions(-) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index ec72e7fe48..32544a82fc 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -33,8 +33,8 @@ void ETSObjectType::Iterate(const PropertyTraverser &cb) const void ETSObjectType::AddInterface(ETSObjectType *interfaceType) { - if (std::find(interfaces_.begin(), interfaces_.end(), interfaceType) == interfaces_.end()) { - interfaces_.push_back(interfaceType); + if (std::find(GetInterfaces().begin(), GetInterfaces().end(), interfaceType) == GetInterfaces().end()) { + GetInterfaces().push_back(interfaceType); CacheSupertypeTransitive(interfaceType); } } @@ -51,10 +51,10 @@ void ETSObjectType::SetSuperType(ETSObjectType *super) void ETSObjectType::CacheSupertypeTransitive(ETSObjectType *type) { auto const insertType = [this](ETSObjectType *t) { - return transitiveSupertypes_.insert(t->GetOriginalBaseType()).second; + return GetTransitiveSupertypes().insert(t->GetOriginalBaseType()).second; }; if (insertType(type)) { - for (auto &t : type->transitiveSupertypes_) { + for (auto &t : type->GetTransitiveSupertypes()) { insertType(t); } } @@ -116,7 +116,7 @@ varbinder::LocalVariable *ETSObjectType::GetProperty(util::StringView name, Prop if (((flags & PropertySearchFlags::SEARCH_INSTANCE) != 0 || (flags & PropertySearchFlags::SEARCH_STATIC) == 0) && (flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) { - for (auto *interface : interfaces_) { + for (auto *interface : GetInterfaces()) { if (auto res = interface->GetProperty(name, flags); res != nullptr) { return res; } @@ -378,7 +378,7 @@ void ETSObjectType::AddSignatureFromConstructor(std::vector &signat // Need to modify RestTupleConstructionPhase. std::vector matches; std::copy_if( - constructSignatures_.begin(), constructSignatures_.end(), std::back_inserter(matches), + GetConstructSignatures().begin(), GetConstructSignatures().end(), std::back_inserter(matches), [orderConstructorName](Signature *sig) { return sig->Function()->Id()->Name() == orderConstructorName; }); if (!matches.empty()) { @@ -448,7 +448,7 @@ void ETSObjectType::ForEachAllNonOwnProperties(const PropertyTraverser &cb) cons superType_->Iterate(cb); } - for (const auto *interface : interfaces_) { + for (const auto *interface : GetInterfaces()) { interface->Iterate(cb); } } @@ -599,12 +599,12 @@ void ETSObjectType::ToString(std::stringstream &ss, bool precise) const ss << (precise ? internalName_ : name_); - if (!typeArguments_.empty()) { + if (!GetTypeArguments().empty()) { ss << compiler::Signatures::GENERIC_BEGIN; - for (auto arg = typeArguments_.cbegin(); arg != typeArguments_.cend(); ++arg) { + for (auto arg = GetTypeArguments().cbegin(); arg != GetTypeArguments().cend(); ++arg) { (*arg)->ToString(ss, precise); - if (next(arg) != typeArguments_.cend()) { + if (std::next(arg) != GetTypeArguments().cend()) { ss << lexer::TokenToString(lexer::TokenType::PUNCTUATOR_COMMA); } } @@ -674,7 +674,7 @@ void ETSObjectType::IdenticalUptoTypeArguments(TypeRelation *relation, Type *oth } auto const sourceTypeArguments = other->AsETSObjectType()->TypeArguments(); - if (typeArguments_.empty() != sourceTypeArguments.empty()) { + if (GetTypeArguments().empty() != sourceTypeArguments.empty()) { return; } @@ -696,17 +696,19 @@ void ETSObjectType::Identical(TypeRelation *relation, Type *other) auto const otherTypeArguments = other->AsETSObjectType()->TypeArguments(); - auto const argsNumber = typeArguments_.size(); + auto const argsNumber = GetTypeArguments().size(); if (argsNumber != otherTypeArguments.size()) { relation->Result(false); return; } for (size_t idx = 0U; idx < argsNumber; ++idx) { - if (typeArguments_[idx]->IsWildcardType() || otherTypeArguments[idx]->IsWildcardType()) { + auto *typeArg = GetTypeArguments()[idx]; + if (typeArg->IsWildcardType() || otherTypeArguments[idx]->IsWildcardType()) { continue; } - if (!relation->IsIdenticalTo(typeArguments_[idx], otherTypeArguments[idx])) { + + if (!relation->IsIdenticalTo(typeArg, otherTypeArguments[idx])) { return; } } @@ -985,7 +987,7 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) void ETSObjectType::IsSubtypeOf(TypeRelation *relation, Type *target) { if (target->IsETSObjectType()) { - auto &transitives = transitiveSupertypes_; + auto &transitives = GetTransitiveSupertypes(); if (transitives.find(target->AsETSObjectType()->GetOriginalBaseType()) == transitives.end()) { relation->Result(false); return; @@ -1009,7 +1011,7 @@ void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, ETSObjectType * ES2PANDA_ASSERT(HasTypeFlag(TypeFlag::GENERIC)); auto const &sourceTypeArguments = source->TypeArguments(); - auto const typeArgumentsNumber = typeArguments_.size(); + auto const typeArgumentsNumber = GetTypeArguments().size(); if (typeArgumentsNumber > sourceTypeArguments.size()) { relation->Result(false); return; @@ -1018,7 +1020,7 @@ void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, ETSObjectType * ES2PANDA_ASSERT(declNode_ == source->GetDeclNode()); auto *typeParamsDecl = GetTypeParams(); - ES2PANDA_ASSERT(typeParamsDecl != nullptr || typeArguments_.empty()); + ES2PANDA_ASSERT(typeParamsDecl != nullptr || GetTypeArguments().empty()); if (typeParamsDecl == nullptr) { return; @@ -1028,7 +1030,7 @@ void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, ETSObjectType * ES2PANDA_ASSERT(typeParams.size() == typeArgumentsNumber); for (size_t idx = 0U; idx < typeArgumentsNumber; ++idx) { - auto *typeArg = typeArguments_[idx]; + auto *typeArg = GetTypeArguments()[idx]; auto *sourceTypeArg = sourceTypeArguments[idx]; auto *typeParam = typeParams[idx]; @@ -1141,7 +1143,7 @@ Type *ETSObjectType::Instantiate(ArenaAllocator *const allocator, TypeRelation * copiedType->SetVariable(variable_); copiedType->SetSuperType(superType_); - for (auto *const it : interfaces_) { + for (auto *const it : GetInterfaces()) { copiedType->AddInterface(it); } @@ -1200,14 +1202,13 @@ ETSObjectType const *ETSObjectType::GetConstOriginalBaseType() const noexcept } return this; } - bool ETSObjectType::SubstituteTypeArgs(TypeRelation *const relation, ArenaVector &newTypeArgs, const Substitution *const substitution) { bool anyChange = false; - newTypeArgs.reserve(typeArguments_.size()); + newTypeArgs.reserve(GetTypeArguments().size()); - for (auto *const arg : typeArguments_) { + for (auto *const arg : GetTypeArguments()) { auto *const newArg = arg->Substitute(relation, substitution); newTypeArgs.push_back(newArg); anyChange = anyChange || (newArg != arg); @@ -1391,7 +1392,7 @@ ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitut if (superType_ != nullptr) { copiedType->SetSuperType(superType_->Substitute(relation, substitution)->AsETSObjectType()); } - for (auto *itf : interfaces_) { + for (auto *itf : GetInterfaces()) { auto *newItf = itf->Substitute(relation, substitution)->AsETSObjectType(); copiedType->AddInterface(newItf); } @@ -1416,10 +1417,10 @@ ETSObjectType *ETSObjectType::SubstituteArguments(TypeRelation *relation, ArenaV auto substitution = Substitution {}; ES2PANDA_ASSERT(baseType_ == nullptr); - ES2PANDA_ASSERT(typeArguments_.size() == arguments.size()); + ES2PANDA_ASSERT(GetTypeArguments().size() == arguments.size()); - for (size_t ix = 0; ix < typeArguments_.size(); ix++) { - substitution.emplace(typeArguments_[ix]->AsETSTypeParameter(), + for (size_t ix = 0; ix < GetTypeArguments().size(); ix++) { + substitution.emplace(GetTypeArguments()[ix]->AsETSTypeParameter(), checker->MaybeBoxType(arguments[ix]->MaybeBaseTypeOfGradualType())); } @@ -1469,7 +1470,7 @@ void ETSObjectType::InstantiateProperties() const for (auto *const it : baseType_->ConstructSignatures()) { auto *newSig = it->Substitute(relation_, &subst); - constructSignatures_.push_back(newSig); + GetConstructSignatures().push_back(newSig); } for (auto const &[_, prop] : baseType_->InstanceFields()) { @@ -1556,22 +1557,23 @@ std::uint32_t ETSObjectType::GetPrecedence(checker::ETSChecker *checker, ETSObje } return 0U; } + void ETSObjectType::AddReExports(ETSObjectType *reExport) { - if (std::find(reExports_.begin(), reExports_.end(), reExport) == reExports_.end()) { - reExports_.push_back(reExport); + if (std::find(reExports_->begin(), reExports_->end(), reExport) == reExports_->end()) { + GetReExports().push_back(reExport); } } void ETSObjectType::AddReExportAlias(util::StringView const &value, util::StringView const &key) { - reExportAlias_.insert({key, value}); + GetReExportAlias().emplace(key, value); } util::StringView ETSObjectType::GetReExportAliasValue(util::StringView const &key) const { - auto ret = reExportAlias_.find(key); - if (reExportAlias_.end() == ret) { + auto ret = GetReExportAlias().find(key); + if (ret == GetReExportAlias().end()) { return key; } return ret->second; @@ -1579,13 +1581,12 @@ util::StringView ETSObjectType::GetReExportAliasValue(util::StringView const &ke bool ETSObjectType::IsReExportHaveAliasValue(util::StringView const &key) const { - return std::any_of(reExportAlias_.begin(), reExportAlias_.end(), - [&](const auto &val) { return val.second == key; }); + return std::any_of(reExportAlias_->begin(), reExportAlias_->end(), [&](const auto &val) { return val.second == key; }); } const ArenaVector &ETSObjectType::ReExports() const { - return reExports_; + return GetReExports(); } void ETSObjectType::ToAssemblerType([[maybe_unused]] std::stringstream &ss) const @@ -1620,6 +1621,7 @@ ir::TSTypeParameterDeclaration *ETSObjectType::GetTypeParams() const return declNode_->AsTSInterfaceDeclaration()->TypeParams(); } + bool ETSObjectType::IsSameBasedGeneric(TypeRelation *relation, Type const *other) const { const_cast(this)->IdenticalUptoTypeArguments(relation, const_cast(other)); @@ -1672,7 +1674,6 @@ void ETSObjectType::CheckVarianceRecursively(TypeRelation *relation, VarianceFla : VarianceFlag::INVARIANT)); } } - ETSObjectType *ETSObjectType::GetInstantiatedType(util::StringView hash) { auto &instantiationMap = diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 3398bf6167..bc90235c23 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -57,13 +57,13 @@ public: void AddConstructSignature(Signature *signature) { - constructSignatures_.push_back(signature); + GetConstructSignatures().push_back(signature); propertiesInstantiated_ = true; } void AddConstructSignature(const ArenaVector &signatures) const { - constructSignatures_.insert(constructSignatures_.end(), signatures.begin(), signatures.end()); + GetConstructSignatures().insert(GetConstructSignatures().end(), signatures.begin(), signatures.end()); propertiesInstantiated_ = true; } @@ -79,7 +79,7 @@ public: ES2PANDA_ASSERT(t->IsETSReferenceType()); } #endif - typeArguments_ = std::move(typeArgs); + GetTypeArguments() = std::move(typeArgs); } void SetEnclosingType(ETSObjectType *enclosingType) @@ -136,29 +136,29 @@ public: const ArenaVector &TypeArguments() const { - return typeArguments_; + return GetTypeArguments(); } const ArenaVector &ConstructSignatures() const { EnsurePropertiesInstantiated(); - return constructSignatures_; + return GetConstructSignatures(); } ArenaVector &ConstructSignatures() { EnsurePropertiesInstantiated(); - return constructSignatures_; + return GetConstructSignatures(); } const ArenaVector &Interfaces() const { - return interfaces_; + return GetInterfaces(); } const ArenaVector &Interfaces() { - return interfaces_; + return GetInterfaces(); } ir::AstNode *GetDeclNode() const @@ -346,7 +346,7 @@ public: [[nodiscard]] bool IsGeneric() const noexcept { - return !typeArguments_.empty(); + return !GetTypeArguments().empty(); } [[nodiscard]] bool IsPartial() const noexcept @@ -433,15 +433,10 @@ private: name_(name), internalName_(assemblerName), declNode_(std::get(info)), - interfaces_(allocator->Adapter()), - reExports_(allocator->Adapter()), - reExportAlias_(allocator->Adapter()), flags_(std::get(info)), - typeArguments_(allocator->Adapter()), - transitiveSupertypes_(allocator->Adapter()), relation_(std::get(info)), - constructSignatures_(allocator->Adapter()), properties_ {(void(IS), PropertyMap {allocator->Adapter()})...} + { } @@ -481,24 +476,73 @@ private: util::StringView const name_; util::StringView const internalName_; ir::AstNode *const declNode_; - ArenaVector interfaces_; - ArenaVector reExports_; - ArenaMap reExportAlias_; + mutable ArenaVector *interfaces_ {nullptr}; + mutable ArenaVector *reExports_ {nullptr}; + mutable ArenaMap *reExportAlias_ {nullptr}; ETSObjectFlags flags_; - ArenaVector typeArguments_; + mutable ArenaVector *typeArguments_ {nullptr}; ETSObjectType *superType_ {}; ETSObjectType *enclosingType_ {}; ETSObjectType *baseType_ {}; // optimized subtyping - ArenaSet transitiveSupertypes_; + mutable ArenaSet *transitiveSupertypes_ {nullptr}; // for lazy properties instantiation TypeRelation *relation_ = nullptr; const ArenaSubstitution *effectiveSubstitution_ = nullptr; mutable bool propertiesInstantiated_ = false; - mutable ArenaVector constructSignatures_; + mutable ArenaVector *constructSignatures_ {nullptr}; mutable PropertyHolder properties_; + + // Getter methods for lazy initialization + ArenaVector &GetInterfaces() const + { + if (interfaces_ == nullptr) { + interfaces_ = allocator_->New>(allocator_->Adapter()); + } + return *interfaces_; + } + + ArenaVector &GetReExports() const + { + if (reExports_ == nullptr) { + reExports_ = allocator_->New>(allocator_->Adapter()); + } + return *reExports_; + } + + ArenaMap &GetReExportAlias() const + { + if (reExportAlias_ == nullptr) { + reExportAlias_ = allocator_->New>(allocator_->Adapter()); + } + return *reExportAlias_; + } + + ArenaVector &GetTypeArguments() const + { + if (typeArguments_ == nullptr) { + typeArguments_ = allocator_->New>(allocator_->Adapter()); + } + return *typeArguments_; + } + + ArenaSet &GetTransitiveSupertypes() const + { + if (transitiveSupertypes_ == nullptr) { + transitiveSupertypes_ = allocator_->New>(allocator_->Adapter()); + } + return *transitiveSupertypes_; + } + + ArenaVector &GetConstructSignatures() const + { + if (constructSignatures_ == nullptr) { + constructSignatures_ = allocator_->New>(allocator_->Adapter()); + } + return *constructSignatures_; + } }; } // namespace ark::es2panda::checker -- Gitee From 755d42ab9dfdf349b58cac391f0b3cbdc272d142 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Sun, 10 Aug 2025 18:12:05 +0800 Subject: [PATCH 7/8] lazy init property --- ets2panda/checker/types/ets/etsObjectType.cpp | 14 +-- ets2panda/checker/types/ets/etsObjectType.h | 96 ++++++++++--------- 2 files changed, 59 insertions(+), 51 deletions(-) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 32544a82fc..59147ea90c 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -434,7 +434,7 @@ void ETSObjectType::ForEachAllOwnProperties(const PropertyTraverser &cb) const { EnsurePropertiesInstantiated(); for (size_t i = 0; i < static_cast(PropertyType::COUNT); ++i) { - PropertyMap &map = properties_[i]; + PropertyMap &map = GetPropertyMap(i); for (const auto &[_, prop] : map) { (void)_; cb(prop); @@ -1476,37 +1476,37 @@ void ETSObjectType::InstantiateProperties() const for (auto const &[_, prop] : baseType_->InstanceFields()) { (void)_; auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); - properties_[static_cast(PropertyType::INSTANCE_FIELD)].emplace(prop->Name(), copiedProp); + GetPropertyMap(static_cast(PropertyType::INSTANCE_FIELD)).emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->StaticFields()) { (void)_; auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); - properties_[static_cast(PropertyType::STATIC_FIELD)].emplace(prop->Name(), copiedProp); + GetPropertyMap(static_cast(PropertyType::STATIC_FIELD)).emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->InstanceMethods()) { (void)_; auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); - properties_[static_cast(PropertyType::INSTANCE_METHOD)].emplace(prop->Name(), copiedProp); + GetPropertyMap(static_cast(PropertyType::INSTANCE_METHOD)).emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->StaticMethods()) { (void)_; auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); - properties_[static_cast(PropertyType::STATIC_METHOD)].emplace(prop->Name(), copiedProp); + GetPropertyMap(static_cast(PropertyType::STATIC_METHOD)).emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->InstanceDecls()) { (void)_; auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); - properties_[static_cast(PropertyType::INSTANCE_DECL)].emplace(prop->Name(), copiedProp); + GetPropertyMap(static_cast(PropertyType::INSTANCE_DECL)).emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->StaticDecls()) { (void)_; auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); - properties_[static_cast(PropertyType::STATIC_DECL)].emplace(prop->Name(), copiedProp); + GetPropertyMap(static_cast(PropertyType::STATIC_DECL)).emplace(prop->Name(), copiedProp); } } diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index bc90235c23..d9be59bc32 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -39,7 +39,7 @@ public: using PropertyMap = ArenaUnorderedMap; using InstantiationMap = ArenaUnorderedMap; using PropertyTraverser = std::function; - using PropertyHolder = std::array(PropertyType::COUNT)>; + using PropertyHolder = std::array(PropertyType::COUNT)>; explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, ETSObjectFlags flags) @@ -98,42 +98,6 @@ public: return relation_; } - PropertyMap &InstanceMethods() const - { - EnsurePropertiesInstantiated(); - return properties_[static_cast(PropertyType::INSTANCE_METHOD)]; - } - - PropertyMap &InstanceFields() const - { - EnsurePropertiesInstantiated(); - return properties_[static_cast(PropertyType::INSTANCE_FIELD)]; - } - - PropertyMap &InstanceDecls() const - { - EnsurePropertiesInstantiated(); - return properties_[static_cast(PropertyType::INSTANCE_DECL)]; - } - - PropertyMap &StaticMethods() const - { - EnsurePropertiesInstantiated(); - return properties_[static_cast(PropertyType::STATIC_METHOD)]; - } - - PropertyMap &StaticFields() const - { - EnsurePropertiesInstantiated(); - return properties_[static_cast(PropertyType::STATIC_FIELD)]; - } - - PropertyMap &StaticDecls() const - { - EnsurePropertiesInstantiated(); - return properties_[static_cast(PropertyType::STATIC_DECL)]; - } - const ArenaVector &TypeArguments() const { return GetTypeArguments(); @@ -302,8 +266,8 @@ public: varbinder::LocalVariable *GetOwnProperty(const util::StringView name) const { EnsurePropertiesInstantiated(); - auto found = properties_[static_cast(TYPE)].find(name); - if (found != properties_[static_cast(TYPE)].end()) { + auto found = GetPropertyMap(static_cast(TYPE)).find(name); + if (found != GetPropertyMap(static_cast(TYPE)).end()) { return found->second; } return nullptr; @@ -312,7 +276,7 @@ public: template void AddProperty(varbinder::LocalVariable *prop) const { - properties_[static_cast(TYPE)].emplace(prop->Name(), prop); + GetPropertyMap(static_cast(TYPE)).emplace(prop->Name(), prop); propertiesInstantiated_ = true; } @@ -325,7 +289,7 @@ public: nameToAccess = localName; } - properties_[static_cast(TYPE)].emplace(nameToAccess, prop); + GetPropertyMap(static_cast(TYPE)).emplace(nameToAccess, prop); propertiesInstantiated_ = true; } @@ -333,14 +297,14 @@ public: template void RemoveProperty(varbinder::LocalVariable *prop) { - properties_[static_cast(TYPE)].erase(prop->Name()); + GetPropertyMap(static_cast(TYPE)).erase(prop->Name()); propertiesInstantiated_ = true; } template void UpdateProperty(varbinder::LocalVariable *oldProp, varbinder::LocalVariable *newProp) { - properties_[static_cast(TYPE)][oldProp->Name()] = newProp; + GetPropertyMap(static_cast(TYPE))[oldProp->Name()] = newProp; propertiesInstantiated_ = true; } @@ -435,7 +399,7 @@ private: declNode_(std::get(info)), flags_(std::get(info)), relation_(std::get(info)), - properties_ {(void(IS), PropertyMap {allocator->Adapter()})...} + properties_ {(void(IS), nullptr)...} { } @@ -543,6 +507,50 @@ private: } return *constructSignatures_; } + + PropertyMap &GetPropertyMap(size_t index) const + { + if (properties_[index] == nullptr) { + properties_[index] = allocator_->New(allocator_->Adapter()); + } + return *properties_[index]; + } +public: + PropertyMap &InstanceMethods() const + { + EnsurePropertiesInstantiated(); + return GetPropertyMap(static_cast(PropertyType::INSTANCE_METHOD)); + } + + PropertyMap &InstanceFields() const + { + EnsurePropertiesInstantiated(); + return GetPropertyMap(static_cast(PropertyType::INSTANCE_FIELD)); + } + + PropertyMap &InstanceDecls() const + { + EnsurePropertiesInstantiated(); + return GetPropertyMap(static_cast(PropertyType::INSTANCE_DECL)); + } + + PropertyMap &StaticMethods() const + { + EnsurePropertiesInstantiated(); + return GetPropertyMap(static_cast(PropertyType::STATIC_METHOD)); + } + + PropertyMap &StaticFields() const + { + EnsurePropertiesInstantiated(); + return GetPropertyMap(static_cast(PropertyType::STATIC_FIELD)); + } + + PropertyMap &StaticDecls() const + { + EnsurePropertiesInstantiated(); + return GetPropertyMap(static_cast(PropertyType::STATIC_DECL)); + } }; } // namespace ark::es2panda::checker -- Gitee From 4563716c6a779e0a62a8dbf43bf505649e1b56ee Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Mon, 11 Aug 2025 09:56:34 +0800 Subject: [PATCH 8/8] interface add --- ets2panda/checker/types/ets/etsObjectType.cpp | 36 +++++++++++++------ ets2panda/checker/types/ets/etsObjectType.h | 10 ++++++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 59147ea90c..0cbb0b6b96 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -33,10 +33,16 @@ void ETSObjectType::Iterate(const PropertyTraverser &cb) const void ETSObjectType::AddInterface(ETSObjectType *interfaceType) { - if (std::find(GetInterfaces().begin(), GetInterfaces().end(), interfaceType) == GetInterfaces().end()) { - GetInterfaces().push_back(interfaceType); - CacheSupertypeTransitive(interfaceType); + // 先检查接口是否已存在,避免不必要的实例创建 + if (interfaces_ != nullptr) { + if (std::find(interfaces_->begin(), interfaces_->end(), interfaceType) != interfaces_->end()) { + return; + } } + + // 只有在需要添加时才确保容器被创建 + GetInterfaces().push_back(interfaceType); + CacheSupertypeTransitive(interfaceType); } void ETSObjectType::SetSuperType(ETSObjectType *super) @@ -422,8 +428,11 @@ varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std:: } if ((flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) { - for (auto *interface : Interfaces()) { - interface->CollectSignaturesForSyntheticType(signatures, name, flags); + // 使用查询方式访问接口,避免不必要的实例创建 + if (interfaces_ != nullptr) { + for (auto *interface : *interfaces_) { + interface->CollectSignaturesForSyntheticType(signatures, name, flags); + } } } @@ -448,8 +457,11 @@ void ETSObjectType::ForEachAllNonOwnProperties(const PropertyTraverser &cb) cons superType_->Iterate(cb); } - for (const auto *interface : GetInterfaces()) { - interface->Iterate(cb); + // 使用查询方式访问接口,避免不必要的实例创建 + if (interfaces_ != nullptr) { + for (const auto *interface : *interfaces_) { + interface->Iterate(cb); + } } } @@ -999,9 +1011,13 @@ void ETSObjectType::IsSubtypeOf(TypeRelation *relation, Type *target) return; } } - for (auto super : Interfaces()) { - if (relation->IsSupertypeOf(target, super)) { - return; + + // 使用查询方式访问接口,避免不必要的实例创建 + if (interfaces_ != nullptr) { + for (auto super : *interfaces_) { + if (relation->IsSupertypeOf(target, super)) { + return; + } } } } diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index d9be59bc32..e0d610a978 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -119,6 +119,11 @@ public: { return GetInterfaces(); } + + const ArenaVector *InterfacesOrNull() const + { + return GetInterfacesOrNull(); + } const ArenaVector &Interfaces() { @@ -468,6 +473,11 @@ private: return *interfaces_; } + const ArenaVector *GetInterfacesOrNull() const + { + return interfaces_; + } + ArenaVector &GetReExports() const { if (reExports_ == nullptr) { -- Gitee