From 4711879cd1b3e2f62178defb1c4928987f468246 Mon Sep 17 00:00:00 2001 From: huyunhui Date: Fri, 11 Jul 2025 11:45:27 +0800 Subject: [PATCH 1/7] 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 be08906774..fb03897939 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -111,6 +111,7 @@ export abstract class BaseMode { public byteCodeHar: boolean; public es2pandaMode: number; public skipDeclCheck: boolean; + public dumpPerf: boolean = true; constructor(buildConfig: BuildConfig) { this.buildConfig = buildConfig; @@ -321,6 +322,9 @@ export abstract class BaseMode { if (this.isDebug) { ets2pandaCmd.push('--debug-info'); } + 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 04039bb900..0514c372f1 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" @@ -284,6 +285,9 @@ extern "C" void DestroyConfig(es2panda_Config *config) return; } + if (cfg->options->IsDumpPerfMetrics()) { + util::DumpPerfMetrics(); + } delete cfg->options; cfg->diagnosticEngine->FlushDiagnostic(); delete cfg->diagnosticEngine; @@ -552,6 +556,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); @@ -620,6 +625,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(); @@ -660,6 +666,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; @@ -690,6 +697,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(); @@ -1090,6 +1098,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 febb8e8a2a26349f41b3fa66723f323432f2f725 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Fri, 11 Jul 2025 19:06:22 +0800 Subject: [PATCH 2/7] 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 + ets2panda/util/perfMetrics.cpp | 215 +++++++++++++++++++++++---- ets2panda/util/perfMetrics.h | 16 +- 5 files changed, 283 insertions(+), 33 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index f4fc39afe2..bf3959cc0b 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -29,6 +29,7 @@ #include "types/type.h" #include "types/typeFlag.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(); } @@ -139,6 +143,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)) { @@ -207,6 +212,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(); @@ -329,6 +335,7 @@ static void CheckDuplicationInOverloadDeclaration(ETSChecker *const checker, ir: checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const { + ES2PANDA_PERF_SCOPE("@Check-OverloadDeclaration"); ETSChecker *checker = GetETSChecker(); ES2PANDA_ASSERT(node != nullptr); ES2PANDA_ASSERT(node->Key()); @@ -366,12 +373,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(); } @@ -401,6 +410,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(); @@ -408,6 +418,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(); @@ -434,6 +445,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(); } @@ -507,6 +519,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(); } @@ -572,6 +585,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(); } @@ -600,6 +614,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(); } @@ -632,11 +647,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(); @@ -657,12 +674,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); @@ -670,6 +689,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); @@ -677,12 +697,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(); } @@ -692,6 +714,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()); @@ -699,6 +722,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()); @@ -706,12 +730,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); @@ -719,6 +745,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); } @@ -938,6 +965,7 @@ static Type *GetAppropriatePreferredType(Type *originalType, std::functionTsType() != nullptr) { return expr->TsType(); @@ -1003,6 +1031,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) { @@ -1162,6 +1191,7 @@ static bool IsInvalidMethodAssignment(const ir::AssignmentExpression *const expr checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const { + ES2PANDA_PERF_SCOPE("@Check-AssignmentExpression"); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1293,6 +1323,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(); @@ -1354,6 +1385,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(); } @@ -1395,6 +1427,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(); } @@ -1626,6 +1659,7 @@ checker::Type *ETSAnalyzer::GetCallExpressionReturnType(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(); @@ -1720,6 +1754,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(); } @@ -1819,6 +1854,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(); } @@ -2661,6 +2697,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(); @@ -2673,6 +2710,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) { @@ -2723,6 +2761,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(); @@ -2771,6 +2810,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(); @@ -2778,6 +2818,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()); @@ -2789,6 +2830,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()); @@ -2800,6 +2842,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()); @@ -2845,6 +2888,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(); } @@ -2879,6 +2923,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())); @@ -2888,6 +2933,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); @@ -2907,6 +2953,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()) { @@ -2920,6 +2967,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); @@ -2950,11 +2998,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()); @@ -3006,6 +3056,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()) { @@ -3023,6 +3074,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); @@ -3030,6 +3082,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); } @@ -3076,6 +3129,7 @@ static void ProcessRequiredFields(ArenaUnorderedMapExpr()->TsType() != nullptr) { return ReturnTypeForStatement(st); } @@ -3117,6 +3171,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()) { @@ -3134,6 +3189,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()); @@ -3149,11 +3205,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); } @@ -3193,6 +3251,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()); @@ -3229,6 +3288,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()); @@ -3255,6 +3315,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(); @@ -3308,6 +3369,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); @@ -3426,6 +3488,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); @@ -3460,6 +3523,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(), @@ -3507,6 +3571,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); @@ -3529,6 +3594,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 {}; @@ -3572,6 +3638,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(); } @@ -3618,6 +3685,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()); @@ -3631,6 +3699,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()); @@ -3657,6 +3726,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); @@ -3669,6 +3739,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) { @@ -3719,12 +3790,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(); } @@ -3757,6 +3831,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(); } @@ -3837,6 +3912,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()) { @@ -3870,6 +3946,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 d5290ab601..5d9347398b 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 865e9d1827..a31d7c8c02 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -20,6 +20,7 @@ #include "checker/checker.h" #include "checker/ETSAnalyzer.h" #include "checker/types/gradualType.h" +#include "util/perfMetrics.h" namespace ark::es2panda::compiler { @@ -271,12 +272,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/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 63798cabecd36bf0dbbb7637d5aa95947d0a825a Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Mon, 21 Jul 2025 15:57:46 +0800 Subject: [PATCH 3/7] add perf point 4 GenerateBin Signed-off-by: wanmingxiang --- ets2panda/compiler/core/ETSemitter.cpp | 1 + ets2panda/compiler/core/emitter.cpp | 7 +++++++ ets2panda/public/es2panda_lib.cpp | 7 +++++++ ets2panda/util/generateBin.cpp | 1 + 4 files changed, 16 insertions(+) diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index 71855bef27..e3abc31d74 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -161,6 +161,7 @@ static pandasm::Function GenScriptFunction(const ir::ScriptFunction *scriptFunc, pandasm::Function *ETSFunctionEmitter::GenFunctionSignature() { + ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionSignature"); auto *scriptFunc = Cg()->RootNode()->AsScriptFunction(); auto *emitter = static_cast(Cg()->Context()->emitter); auto func = GenScriptFunction(scriptFunc, emitter); diff --git a/ets2panda/compiler/core/emitter.cpp b/ets2panda/compiler/core/emitter.cpp index 6586372749..1919c4a651 100644 --- a/ets2panda/compiler/core/emitter.cpp +++ b/ets2panda/compiler/core/emitter.cpp @@ -124,11 +124,17 @@ static LiteralPair TransformLiteral(const compiler::Literal *literal) void FunctionEmitter::Generate() { + ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionSignature"); auto *func = GenFunctionSignature(); + ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionInstructions"); GenFunctionInstructions(func); + ES2PANDA_PERF_SCOPE("@GenAsmGenVariablesDebugInfo"); GenVariablesDebugInfo(func); + ES2PANDA_PERF_SCOPE("@GenAsmGenScopeVariableInfo"); GenSourceFileDebugInfo(func); + ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionCatchTables"); GenFunctionCatchTables(func); + ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionAnnotations"); GenFunctionAnnotations(func); } @@ -535,6 +541,7 @@ void Emitter::AddLiteralBuffer(const LiteralBuffer &literals, uint32_t index) pandasm::Program *Emitter::Finalize(bool dumpDebugInfo, std::string_view globalClass) { if (dumpDebugInfo) { + ES2PANDA_PERF_SCOPE("@GenAsmDumpDebugInfo"); debuginfo::DebugInfoDumper dumper(prog_); dumper.Dump(); } diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 0514c372f1..f92ee62f9f 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -702,6 +702,7 @@ __attribute__((unused)) static Context *GenerateAsm(Context *ctx) emitter->GenAnnotation(); // Handle context literals. + ES2PANDA_PERF_SCOPE("@GenAsm-Literals"); uint32_t index = 0; for (const auto &buff : ctx->contextLiterals) { emitter->AddLiteralBuffer(buff, index++); @@ -710,10 +711,16 @@ __attribute__((unused)) static Context *GenerateAsm(Context *ctx) emitter->LiteralBufferIndex() += ctx->contextLiterals.size(); /* Main thread can also be used instead of idling */ + + ES2PANDA_PERF_SCOPE("@GenAsm-Schedule"); ctx->queue->Schedule(ctx); + ES2PANDA_PERF_SCOPE("@GenAsm-Consume"); ctx->queue->Consume(); + + ES2PANDA_PERF_SCOPE("@GenAsm-Wait"); ctx->queue->Wait([emitter](compiler::CompileJob *job) { emitter->AddProgramElement(job->GetProgramElement()); }); ES2PANDA_ASSERT(ctx->program == nullptr); + ES2PANDA_PERF_SCOPE("@GenAsm-EmitFinalize"); ctx->program = emitter->Finalize(ctx->config->options->IsDumpDebugInfo(), compiler::Signatures::ETS_GLOBAL); ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_ASM_GENERATED : ES2PANDA_STATE_ERROR; return ctx; diff --git a/ets2panda/util/generateBin.cpp b/ets2panda/util/generateBin.cpp index 134b2c9511..168a33783e 100644 --- a/ets2panda/util/generateBin.cpp +++ b/ets2panda/util/generateBin.cpp @@ -65,6 +65,7 @@ static int GenerateProgramImpl(ark::pandasm::Program *prog, const util::Options ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp) { if (options.IsDumpAssembly()) { + ES2PANDA_PERF_SCOPE("@GenBinDumpAsm"); es2panda::Compiler::DumpAsm(prog); } -- Gitee From 05a93f00f4904961dc0ea68a98a1e786e649818d Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Tue, 22 Jul 2025 19:14:19 +0800 Subject: [PATCH 4/7] add scope less perf point --- ets2panda/checker/ETSAnalyzer.cpp | 150 ++++++++++++------------- ets2panda/checker/ETSchecker.cpp | 2 +- ets2panda/compiler/core/ETSemitter.cpp | 1 - ets2panda/compiler/core/emitter.cpp | 14 +-- ets2panda/public/es2panda_lib.cpp | 10 +- ets2panda/util/perfMetrics.h | 8 +- 6 files changed, 95 insertions(+), 90 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index bf3959cc0b..457c713387 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(); } @@ -143,7 +143,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)) { @@ -212,7 +212,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(); @@ -335,7 +335,7 @@ static void CheckDuplicationInOverloadDeclaration(ETSChecker *const checker, ir: 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()); @@ -373,14 +373,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(); } @@ -410,7 +410,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(); @@ -418,7 +418,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(); @@ -445,7 +445,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(); } @@ -519,7 +519,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(); } @@ -585,7 +585,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(); } @@ -614,7 +614,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(); } @@ -647,13 +647,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(); @@ -674,14 +674,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); @@ -689,7 +689,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); @@ -697,14 +697,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(); } @@ -714,7 +714,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()); @@ -722,7 +722,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()); @@ -730,14 +730,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); @@ -745,7 +745,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); } @@ -965,7 +965,7 @@ static Type *GetAppropriatePreferredType(Type *originalType, std::functionTsType() != nullptr) { return expr->TsType(); @@ -1031,7 +1031,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) { @@ -1191,7 +1191,7 @@ static bool IsInvalidMethodAssignment(const ir::AssignmentExpression *const expr 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(); } @@ -1323,7 +1323,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(); @@ -1385,7 +1385,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(); } @@ -1427,7 +1427,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(); } @@ -1659,7 +1659,7 @@ checker::Type *ETSAnalyzer::GetCallExpressionReturnType(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(); @@ -1754,7 +1754,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(); } @@ -1854,7 +1854,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(); } @@ -2697,7 +2697,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(); @@ -2710,7 +2710,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) { @@ -2761,7 +2761,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(); @@ -2810,7 +2810,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(); @@ -2818,7 +2818,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()); @@ -2830,7 +2830,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()); @@ -2842,7 +2842,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()); @@ -2888,7 +2888,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(); } @@ -2923,7 +2923,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())); @@ -2933,7 +2933,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); @@ -2953,7 +2953,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()) { @@ -2967,7 +2967,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); @@ -2998,13 +2998,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()); @@ -3056,7 +3056,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()) { @@ -3074,7 +3074,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); @@ -3082,7 +3082,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); } @@ -3129,7 +3129,7 @@ static void ProcessRequiredFields(ArenaUnorderedMapExpr()->TsType() != nullptr) { return ReturnTypeForStatement(st); } @@ -3171,7 +3171,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()) { @@ -3189,7 +3189,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()); @@ -3205,13 +3205,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); } @@ -3251,7 +3251,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()); @@ -3288,7 +3288,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()); @@ -3315,7 +3315,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(); @@ -3369,7 +3369,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); @@ -3488,7 +3488,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); @@ -3523,7 +3523,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(), @@ -3571,7 +3571,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); @@ -3594,7 +3594,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 {}; @@ -3638,7 +3638,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(); } @@ -3685,7 +3685,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()); @@ -3699,7 +3699,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()); @@ -3726,7 +3726,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); @@ -3739,7 +3739,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) { @@ -3790,7 +3790,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); @@ -3798,7 +3798,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(); } @@ -3831,7 +3831,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(); } @@ -3912,7 +3912,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()) { @@ -3946,7 +3946,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 5d9347398b..175d4d937d 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/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index e3abc31d74..71855bef27 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -161,7 +161,6 @@ static pandasm::Function GenScriptFunction(const ir::ScriptFunction *scriptFunc, pandasm::Function *ETSFunctionEmitter::GenFunctionSignature() { - ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionSignature"); auto *scriptFunc = Cg()->RootNode()->AsScriptFunction(); auto *emitter = static_cast(Cg()->Context()->emitter); auto func = GenScriptFunction(scriptFunc, emitter); diff --git a/ets2panda/compiler/core/emitter.cpp b/ets2panda/compiler/core/emitter.cpp index 1919c4a651..246eedccb3 100644 --- a/ets2panda/compiler/core/emitter.cpp +++ b/ets2panda/compiler/core/emitter.cpp @@ -124,17 +124,17 @@ static LiteralPair TransformLiteral(const compiler::Literal *literal) void FunctionEmitter::Generate() { - ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionSignature"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-GenFunctionSignature"); auto *func = GenFunctionSignature(); - ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionInstructions"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-GenFunctionInstructions"); GenFunctionInstructions(func); - ES2PANDA_PERF_SCOPE("@GenAsmGenVariablesDebugInfo"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-GenVariablesDebugInfo"); GenVariablesDebugInfo(func); - ES2PANDA_PERF_SCOPE("@GenAsmGenScopeVariableInfo"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-GenScopeVariableInfo"); GenSourceFileDebugInfo(func); - ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionCatchTables"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-GenFunctionCatchTables"); GenFunctionCatchTables(func); - ES2PANDA_PERF_SCOPE("@GenAsmGenFunctionAnnotations"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-GenFunctionAnnotations"); GenFunctionAnnotations(func); } @@ -541,7 +541,7 @@ void Emitter::AddLiteralBuffer(const LiteralBuffer &literals, uint32_t index) pandasm::Program *Emitter::Finalize(bool dumpDebugInfo, std::string_view globalClass) { if (dumpDebugInfo) { - ES2PANDA_PERF_SCOPE("@GenAsmDumpDebugInfo"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-DumpDebugInfo"); debuginfo::DebugInfoDumper dumper(prog_); dumper.Dump(); } diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index f92ee62f9f..925cf224f6 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -702,7 +702,7 @@ __attribute__((unused)) static Context *GenerateAsm(Context *ctx) emitter->GenAnnotation(); // Handle context literals. - ES2PANDA_PERF_SCOPE("@GenAsm-Literals"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-Literals"); uint32_t index = 0; for (const auto &buff : ctx->contextLiterals) { emitter->AddLiteralBuffer(buff, index++); @@ -712,15 +712,15 @@ __attribute__((unused)) static Context *GenerateAsm(Context *ctx) /* Main thread can also be used instead of idling */ - ES2PANDA_PERF_SCOPE("@GenAsm-Schedule"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-Schedule"); ctx->queue->Schedule(ctx); - ES2PANDA_PERF_SCOPE("@GenAsm-Consume"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-Consume"); ctx->queue->Consume(); - ES2PANDA_PERF_SCOPE("@GenAsm-Wait"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-Wait"); ctx->queue->Wait([emitter](compiler::CompileJob *job) { emitter->AddProgramElement(job->GetProgramElement()); }); ES2PANDA_ASSERT(ctx->program == nullptr); - ES2PANDA_PERF_SCOPE("@GenAsm-EmitFinalize"); + ES2PANDA_PERF_SCOPELESS("@GenAsm-EmitFinalize"); ctx->program = emitter->Finalize(ctx->config->options->IsDumpDebugInfo(), compiler::Signatures::ETS_GLOBAL); ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_ASM_GENERATED : ES2PANDA_STATE_ERROR; return ctx; 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 a498940ea7e5cf6a05e71f4b804129876d2a0808 Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Tue, 22 Jul 2025 20:25:47 +0800 Subject: [PATCH 5/7] fix contension issues 4 GenAsm --- ets2panda/checker/ETSchecker.cpp | 7 +++++-- ets2panda/checker/ETSchecker.h | 5 ++++- ets2panda/checker/ets/object.cpp | 9 +++++++-- ets2panda/compiler/core/codeGen.cpp | 10 ++++++---- ets2panda/compiler/core/codeGen.h | 4 +++- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 175d4d937d..d1a484a09f 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -76,8 +76,11 @@ void ETSChecker::ReputCheckerData() auto &globalArraySigs = eChecker->globalArraySignatures_; globalArraySignatures_.insert(globalArraySigs.cbegin(), globalArraySigs.cend()); - auto &apparentTypes = eChecker->apparentTypes_; - apparentTypes_.insert(apparentTypes.cbegin(), apparentTypes.cend()); + { + ark::os::memory::WriteLockHolder lock(apparentTypesLock_); + auto &apparentTypes = eChecker->apparentTypes_; + apparentTypes_.insert(apparentTypes.cbegin(), apparentTypes.cend()); + } auto &objectInstantiationMap = eChecker->objectInstantiationMap_; for (auto &[key, value] : objectInstantiationMap) { diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index b79f790e69..f781112ddd 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -28,6 +28,7 @@ #include "ir/visitor/AstVisitor.h" #include "types/type.h" #include "util/helpers.h" +#include "os/mutex.h" namespace ark::es2panda::varbinder { class VarBinder; @@ -940,6 +941,7 @@ public: void ClearApparentTypes() noexcept { + ark::os::memory::WriteLockHolder lock(apparentTypesLock_); apparentTypes_.clear(); } @@ -961,7 +963,7 @@ public: } dynamicLambdaSignatureCache_.clear(); functionalInterfaceCache_.clear(); - apparentTypes_.clear(); + ClearApparentTypes(); for (auto &dynamicCallNamesMap : dynamicCallNames_) { dynamicCallNamesMap.clear(); } @@ -1117,6 +1119,7 @@ private: DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_; FunctionalInterfaceMap functionalInterfaceCache_; TypeMapping apparentTypes_; + mutable ark::os::memory::RWLock apparentTypesLock_; std::array dynamicCallNames_; std::recursive_mutex mtx_; evaluate::ScopedDebugInfoPlugin *debugInfoPlugin_ {nullptr}; diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index f53671473d..70e76186c6 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -2610,11 +2610,16 @@ Type *ETSChecker::GetApparentType(Type *type) { auto currChecker = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker(); auto &apparentTypes = currChecker->apparentTypes_; - + { + ark::os::memory::ReadLockHolder lock(apparentTypesLock_); + if (auto it = apparentTypes.find(type); LIKELY(it != apparentTypes.end())) { + return it->second; + } + } + ark::os::memory::WriteLockHolder lock(apparentTypesLock_); if (auto it = apparentTypes.find(type); LIKELY(it != apparentTypes.end())) { return it->second; } - auto cached = [&apparentTypes, type](Type *res) { if (type != res) { apparentTypes.insert({type, res}); diff --git a/ets2panda/compiler/core/codeGen.cpp b/ets2panda/compiler/core/codeGen.cpp index fd01a1c9f2..2f17c0af28 100644 --- a/ets2panda/compiler/core/codeGen.cpp +++ b/ets2panda/compiler/core/codeGen.cpp @@ -98,11 +98,13 @@ VReg CodeGen::AllocRegWithType(const checker::Type *const type) void CodeGen::SetVRegType(const VReg vreg, const checker::Type *const type) { + ark::os::memory::WriteLockHolder lock(typeMapMutex_); typeMap_.insert_or_assign(vreg, type); } const checker::Type *CodeGen::GetVRegType(const VReg vreg) const { + ark::os::memory::ReadLockHolder lock(typeMapMutex_); const auto it = typeMap_.find(vreg); return it != typeMap_.end() ? it->second : nullptr; } @@ -340,10 +342,10 @@ ProgramElement *CodeGen::ProgElement() const noexcept return programElement_; } -CodeGen::TypeMap &CodeGen::GetTypeMap() noexcept -{ - return typeMap_; -} +// CodeGen::TypeMap &CodeGen::GetTypeMap() noexcept +// { +// return typeMap_; +// } const CodeGen::TypeMap &CodeGen::GetTypeMap() const noexcept { diff --git a/ets2panda/compiler/core/codeGen.h b/ets2panda/compiler/core/codeGen.h index 8fbeeb0106..404c9c955e 100644 --- a/ets2panda/compiler/core/codeGen.h +++ b/ets2panda/compiler/core/codeGen.h @@ -20,6 +20,7 @@ #include "compiler/core/ASTCompiler.h" #include "compiler/core/regAllocator.h" #include "compiler/core/regScope.h" +#include "os/mutex.h" namespace ark::es2panda::compiler { class CatchTable; class DynamicContext; @@ -162,7 +163,7 @@ protected: [[nodiscard]] RangeRegAllocator &Rra() noexcept; [[nodiscard]] const RangeRegAllocator &Rra() const noexcept; [[nodiscard]] ProgramElement *ProgElement() const noexcept; - [[nodiscard]] TypeMap &GetTypeMap() noexcept; +// [[nodiscard]] TypeMap &GetTypeMap() noexcept; [[nodiscard]] const TypeMap &GetTypeMap() const noexcept; private: @@ -176,6 +177,7 @@ private: ArenaVector insns_; ArenaVector catchList_; TypeMap typeMap_; + mutable ark::os::memory::RWLock typeMapMutex_; ProgramElement *programElement_ {}; DynamicContext *dynamicContext_ {}; -- Gitee From 025adabda1e2e60088875f301e78575b859673df Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Tue, 22 Jul 2025 21:57:37 +0800 Subject: [PATCH 6/7] fix dl in recursive call stack --- ets2panda/checker/ETSchecker.cpp | 2 +- ets2panda/checker/ETSchecker.h | 4 ++-- ets2panda/checker/ets/object.cpp | 8 +------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index d1a484a09f..80dd6133bf 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -77,7 +77,7 @@ void ETSChecker::ReputCheckerData() globalArraySignatures_.insert(globalArraySigs.cbegin(), globalArraySigs.cend()); { - ark::os::memory::WriteLockHolder lock(apparentTypesLock_); + std::unique_lock lock(apparentTypesLock_); auto &apparentTypes = eChecker->apparentTypes_; apparentTypes_.insert(apparentTypes.cbegin(), apparentTypes.cend()); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index f781112ddd..96970df683 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -941,7 +941,7 @@ public: void ClearApparentTypes() noexcept { - ark::os::memory::WriteLockHolder lock(apparentTypesLock_); + std::unique_lock lock(apparentTypesLock_); apparentTypes_.clear(); } @@ -1119,7 +1119,7 @@ private: DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_; FunctionalInterfaceMap functionalInterfaceCache_; TypeMapping apparentTypes_; - mutable ark::os::memory::RWLock apparentTypesLock_; + std::recursive_mutex apparentTypesLock_; std::array dynamicCallNames_; std::recursive_mutex mtx_; evaluate::ScopedDebugInfoPlugin *debugInfoPlugin_ {nullptr}; diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 70e76186c6..494ea38f0c 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -2610,13 +2610,7 @@ Type *ETSChecker::GetApparentType(Type *type) { auto currChecker = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker(); auto &apparentTypes = currChecker->apparentTypes_; - { - ark::os::memory::ReadLockHolder lock(apparentTypesLock_); - if (auto it = apparentTypes.find(type); LIKELY(it != apparentTypes.end())) { - return it->second; - } - } - ark::os::memory::WriteLockHolder lock(apparentTypesLock_); + std::unique_lock lock(currChecker->apparentTypesLock_); if (auto it = apparentTypes.find(type); LIKELY(it != apparentTypes.end())) { return it->second; } -- Gitee From 8363aa714ae520d606ebba991861d0f89e75b00a Mon Sep 17 00:00:00 2001 From: wanmingxiang Date: Sat, 26 Jul 2025 10:40:41 +0800 Subject: [PATCH 7/7] make gen ext record in pall --- ets2panda/BUILD.gn | 2 + ets2panda/CMakeLists.txt | 2 + ets2panda/compiler/core/ETSemitter.cpp | 15 +-- ets2panda/compiler/core/ETSemitter.h | 2 + ets2panda/compiler/core/GenExtRecordQueue.cpp | 42 +++++++ ets2panda/compiler/core/GenExtRecordQueue.h | 51 ++++++++ ets2panda/public/es2panda_lib.cpp | 2 +- ets2panda/util/workerQueue.cpp | 118 ++++++++++++++++++ ets2panda/util/workerQueue.h | 71 +++++++++++ 9 files changed, 297 insertions(+), 8 deletions(-) create mode 100644 ets2panda/compiler/core/GenExtRecordQueue.cpp create mode 100644 ets2panda/compiler/core/GenExtRecordQueue.h create mode 100644 ets2panda/util/workerQueue.cpp create mode 100644 ets2panda/util/workerQueue.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 60c32ea888..b515e33cbb 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -192,6 +192,7 @@ libes2panda_sources = [ "compiler/core/JSCompilerUnreachable.cpp", "compiler/core/JSemitter.cpp", "compiler/core/codeGen.cpp", + "compiler/core/GenExtRecordQueue.cpp", "compiler/core/compileJob.cpp", "compiler/core/compileQueue.cpp", "compiler/core/compilerImpl.cpp", @@ -514,6 +515,7 @@ libes2panda_sources = [ "util/perfMetrics.cpp", "util/plugin.cpp", "util/ustring.cpp", + "util/workerQueue.cpp", "varbinder/ASBinder.cpp", "varbinder/ETSBinder.cpp", "varbinder/JSBinder.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 73d465ae36..5af457e76c 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -232,6 +232,7 @@ set(ES2PANDA_LIB_SRC compiler/base/optionalChain.cpp compiler/core/CFG.cpp compiler/core/codeGen.cpp + compiler/core/GenExtRecordQueue.cpp compiler/core/compileJob.cpp compiler/core/compileQueue.cpp compiler/core/compilerImpl.cpp @@ -652,6 +653,7 @@ set(ES2PANDA_LIB_SRC util/plugin.cpp util/perfMetrics.cpp util/ustring.cpp + util/workerQueue.cpp evaluate/debugInfoDeserialization/debugInfoDeserializer.cpp evaluate/debugInfoDeserialization/inheritanceResolution.cpp evaluate/debugInfoDeserialization/methodBuilder.cpp diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index 71855bef27..32ec8552bd 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -16,6 +16,7 @@ #include "ETSemitter.h" #include "annotation.h" +#include "GenExtRecordQueue.h" #include "compiler/core/ETSGen.h" #include "varbinder/varbinder.h" #include "varbinder/ETSBinder.h" @@ -284,15 +285,15 @@ void ETSEmitter::GenAnnotation() Program()->AddToFunctionTable(std::move(func)); } - for (auto [extProg, recordTable] : varbinder->GetExternalRecordTable()) { - if (recordTable == varbinder->GetRecordTable()) { - continue; - } - GenExternalRecord(recordTable, extProg); - } + ES2PANDA_PERF_SCOPELESS("@GenAnnotation-GenExternalRecord"); + constexpr size_t MAX_THREADS = 8; // TODO + GenExtRecordQueue queue(MAX_THREADS, Context()); + queue.Schedule(); + queue.Consume(); + queue.Wait(); const auto *checker = static_cast(Context()->GetChecker()); - + ES2PANDA_PERF_SCOPELESS("@GenAnnotation-GenGlobalArrayRecord"); for (auto [arrType, signature] : checker->GlobalArrayTypes()) { GenGlobalArrayRecord(arrType, signature); } diff --git a/ets2panda/compiler/core/ETSemitter.h b/ets2panda/compiler/core/ETSemitter.h index 084964321b..3bef85fe3b 100644 --- a/ets2panda/compiler/core/ETSemitter.h +++ b/ets2panda/compiler/core/ETSemitter.h @@ -85,6 +85,8 @@ public: private: using DynamicCallNamesMap = ArenaMap, uint32_t>; + static void GenExtWorker(ETSEmitter *self, varbinder::RecordTable *recordTable, const parser::Program *extProg); +public: void GenExternalRecord(varbinder::RecordTable *recordTable, const parser::Program *extProg); void GenGlobalArrayRecord(const checker::ETSArrayType *arrayType, checker::Signature *signature); std::vector GenAnnotations(const ir::ClassDefinition *classDef); diff --git a/ets2panda/compiler/core/GenExtRecordQueue.cpp b/ets2panda/compiler/core/GenExtRecordQueue.cpp new file mode 100644 index 0000000000..9c2b714403 --- /dev/null +++ b/ets2panda/compiler/core/GenExtRecordQueue.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 - 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "GenExtRecordQueue.h" +#include "util/diagnostic.h" +#include "varbinder/ETSBinder.h" +#include "public/public.h" + +namespace ark::es2panda::compiler { + +void GenExtRecordJob::Run() +{ + emitter_->GenExternalRecord(recordTable_, extProg_); +} + +void GenExtRecordQueue::Schedule() +{ + auto *varbinder = static_cast(context_->parserProgram->VarBinder()); + for (auto [extProg, recordTable] : varbinder->GetExternalRecordTable()) { + if (recordTable == varbinder->GetRecordTable()) { + continue; + + ETSEmitter *emitter = static_cast (context_->emitter); + GenExtRecordJob *pJob = new GenExtRecordJob(emitter, recordTable, extProg); + jobs_.push_back(pJob); + jobsCount_++; + } + } +} +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/core/GenExtRecordQueue.h b/ets2panda/compiler/core/GenExtRecordQueue.h new file mode 100644 index 0000000000..1790af1360 --- /dev/null +++ b/ets2panda/compiler/core/GenExtRecordQueue.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_GENEXTRECORDQUEUE_H +#define ES2PANDA_COMPILER_CORE_GENEXTRECORDQUEUE_H + +#include "util/workerQueue.h" +#include "ETSemitter.h" + +namespace ark::es2panda::compiler { +class GenExtRecordJob : public ark::es2panda::util::WorkerJob { +public: + explicit GenExtRecordJob(ETSEmitter *emitter, varbinder::RecordTable *recordTable, const parser::Program *extProg) + : emitter_(emitter), recordTable_(recordTable), extProg_(extProg) + { + } + NO_COPY_SEMANTIC(GenExtRecordJob); + NO_MOVE_SEMANTIC(GenExtRecordJob); + + void Run() override; + + ETSEmitter *emitter_; + varbinder::RecordTable *recordTable_; + const parser::Program *extProg_; +}; + +class GenExtRecordQueue : public ark::es2panda::util::WorkerQueue { +public: + explicit GenExtRecordQueue(size_t threadCount, const public_lib::Context *context) + : util::WorkerQueue(threadCount), context_(context) + { + } + void Schedule() override; + +private: + const public_lib::Context *context_; +}; +} // namespace ark::es2panda::compiler +#endif diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 925cf224f6..1dabbe6c37 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -321,7 +321,7 @@ static void CompileJob(public_lib::Context *context, varbinder::FunctionScope *s compiler::ProgramElement *programElement) { compiler::StaticRegSpiller regSpiller; - ArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER, nullptr, true}; + StackArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER}; compiler::ETSCompiler astCompiler {}; compiler::ETSGen cg {&allocator, ®Spiller, context, std::make_tuple(scope, programElement, &astCompiler)}; compiler::ETSFunctionEmitter funcEmitter {&cg, programElement}; diff --git a/ets2panda/util/workerQueue.cpp b/ets2panda/util/workerQueue.cpp new file mode 100644 index 0000000000..52bf3f4e7a --- /dev/null +++ b/ets2panda/util/workerQueue.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "workerQueue.h" + +namespace ark::es2panda::util { + +void WorkerJob::DependsOn(WorkerJob *job) +{ + job->dependants_.push_back(this); + dependencies_++; +} + +void WorkerJob::Signal() +{ + { + std::lock_guard lock(m_); + dependencies_--; + } + + cond_.notify_one(); +} + +WorkerQueue::WorkerQueue(size_t threadCount) +{ + threads_.reserve(threadCount); + + for (size_t i = 0; i < threadCount; i++) { + threads_.push_back(os::thread::ThreadStart(Worker, this)); + } +} + +WorkerQueue::~WorkerQueue() +{ + void *retval = nullptr; + + std::unique_lock lock(m_); + terminate_ = true; + lock.unlock(); + jobsAvailable_.notify_all(); + + for (const auto handle_id : threads_) { + os::thread::ThreadJoin(handle_id, &retval); + } +} + +void WorkerQueue::Worker(WorkerQueue *queue) +{ + while (true) { + std::unique_lock lock(queue->m_); + queue->jobsAvailable_.wait(lock, [queue]() { return queue->terminate_ || queue->jobsCount_ != 0; }); + + if (queue->terminate_) { + return; + } + + lock.unlock(); + + queue->Consume(); + queue->jobsFinished_.notify_one(); + } +} + +void WorkerQueue::Consume() +{ + std::unique_lock lock(m_); + activeWorkers_++; + + while (jobsCount_ > 0) { + --jobsCount_; + auto &job = *(jobs_[jobsCount_]); + + lock.unlock(); + + try { + job.Run(); + } catch (const util::ThrowableDiagnostic &e) { + lock.lock(); +// errors_.push_back(e); + lock.unlock(); + } + + lock.lock(); + } + + activeWorkers_--; +} + +void WorkerQueue::Wait() +{ + std::unique_lock lock(m_); + jobsFinished_.wait(lock, [this]() { return activeWorkers_ == 0 && jobsCount_ == 0; }); + for (auto it = jobs_.begin(); it != jobs_.end(); it++) { + if (*it != nullptr) { + delete *it; + *it = nullptr; + } + } + jobs_.clear(); + +// if (!errors_.empty()) { +// // NOLINTNEXTLINE +// throw errors_.front(); +// } +} +} // namespace ark::es2panda::util diff --git a/ets2panda/util/workerQueue.h b/ets2panda/util/workerQueue.h new file mode 100644 index 0000000000..4d6cf8aa30 --- /dev/null +++ b/ets2panda/util/workerQueue.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_UTIL_WORKERQUEUE_H +#define ES2PANDA_UTIL_WORKERQUEUE_H + +#include +#include +#include + +#include +#include + +namespace ark::es2panda::util { + +class WorkerJob { +public: + explicit WorkerJob() {}; + NO_COPY_SEMANTIC(WorkerJob); + NO_MOVE_SEMANTIC(WorkerJob); + virtual ~WorkerJob() = default; + + virtual void Run() = 0; + void DependsOn(WorkerJob *job); + void Signal(); + +protected: + std::mutex m_; + std::condition_variable cond_; + std::vector dependants_ {}; + size_t dependencies_ {0}; +}; + +class WorkerQueue { +public: + explicit WorkerQueue(size_t threadCount); + NO_COPY_SEMANTIC(WorkerQueue); + NO_MOVE_SEMANTIC(WorkerQueue); + virtual ~WorkerQueue(); + + virtual void Schedule() = 0; + void Consume(); + void Wait(); + +protected: + static void Worker(WorkerQueue *queue); + + std::vector threads_; + std::mutex m_; + std::condition_variable jobsAvailable_; + std::condition_variable jobsFinished_; + std::vector jobs_ {}; + size_t jobsCount_ {0}; + size_t activeWorkers_ {0}; + bool terminate_ {false}; +}; +} // namespace panda::es2panda::util + +#endif -- Gitee