From 8850a04d82e7687446bc30ea16fa948cbf7da54e Mon Sep 17 00:00:00 2001 From: Geng Chen Date: Tue, 29 Jul 2025 15:21:20 +0800 Subject: [PATCH] add local allocator in varbinder Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICSLHI Signed-off-by: Geng Chen --- ets2panda/checker/ets/utilityTypeHandlers.cpp | 4 +-- .../lowering/scopesInit/savedBindingsCtx.cpp | 2 +- .../lowering/scopesInit/scopesInitPhase.cpp | 25 ++++++++++--------- ets2panda/compiler/lowering/util.cpp | 6 ++++- ets2panda/parser/program/program.h | 2 +- ets2panda/public/es2panda_lib.cpp | 2 +- .../unit/lowerings/scopes_initialization.cpp | 4 +-- ets2panda/varbinder/ASBinder.h | 4 +-- ets2panda/varbinder/ETSBinder.h | 9 ++++--- ets2panda/varbinder/JSBinder.h | 4 +-- ets2panda/varbinder/TSBinder.h | 4 +-- ets2panda/varbinder/TypedBinder.h | 5 ++-- ets2panda/varbinder/varbinder.h | 14 ++++++----- 13 files changed, 47 insertions(+), 38 deletions(-) diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 0ee26101bb..612e41648e 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -732,8 +732,8 @@ ir::TSInterfaceDeclaration *ETSChecker::CreateInterfaceProto(util::StringView na // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const interfaceId = ProgramAllocNode(name, ProgramAllocator()); - const auto [decl, var] = VarBinder()->NewVarDecl(interfaceId->Start(), ProgramAllocator(), - interfaceId->Name()); + const auto [decl, var] = VarBinder()->NewVarDecl( + interfaceId->Start(), VarBinder()->Allocator(), interfaceId->Name()); ES2PANDA_ASSERT(interfaceId != nullptr); interfaceId->SetVariable(var); diff --git a/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp b/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp index 8d4ee9e016..cb4f38fd85 100644 --- a/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp +++ b/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp @@ -26,7 +26,7 @@ void ImportDeclarationContext::BindImportDecl(ir::ImportDeclaration *importDecl) { varbinder::ModuleScope::ImportDeclList declList(Allocator()->Adapter()); - for (const auto &[name, variable] : VarBinder()->GetScope()->OrderedBindings(Allocator())) { + for (const auto &[name, variable] : VarBinder()->GetScope()->OrderedBindings(VarBinder()->Allocator())) { if (SavedBindings().find(name) != SavedBindings().end()) { continue; } diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index b97fd7aed2..09e9052912 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -446,8 +446,8 @@ void ScopesInitPhase::LogDiagnostic(const diagnostic::DiagnosticKind &kind, cons void ScopesInitPhase::CreateFuncDecl(ir::ScriptFunction *func) { - AddOrGetDecl(VarBinder(), func->Id()->Name(), func, func->Id()->Start(), Allocator(), - func->Id()->Name(), func); + AddOrGetDecl(VarBinder(), func->Id()->Name(), func, func->Id()->Start(), + VarBinder()->Allocator(), func->Id()->Name(), func); } util::StringView ScopesInitPhase::FormInterfaceOrEnumDeclarationIdBinding(ir::Identifier *id) @@ -498,13 +498,13 @@ std::tuple ScopesInitPhase::AddOrGetVa if (auto var = id->Variable(); var != nullptr) { if (!name.Is(ERROR_LITERAL) && (scope->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES) == nullptr)) { - var = scope->AddDecl(Allocator(), var->Declaration(), VarBinder()->Extension()); + var = scope->AddDecl(VarBinder()->Allocator(), var->Declaration(), VarBinder()->Extension()); } return {var->Declaration(), var}; } if (name.Is(ERROR_LITERAL)) { - name = compiler::GenName(Allocator()).View(); + name = compiler::GenName(VarBinder()->Allocator()).View(); } else if (VarBinder()->IsETSBinder()) { if (auto var = scope->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES); var != nullptr) { ES2PANDA_ASSERT(ctx_->diagnosticEngine->IsAnyError()); @@ -633,7 +633,7 @@ void ScopeInitTyped::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *int bool alreadyExists = false; if (res == bindings.end()) { - decl = VarBinder()->AddTsDecl(ident->Start(), Allocator(), name); + decl = VarBinder()->AddTsDecl(ident->Start(), VarBinder()->Allocator(), name); } else if (!AllowInterfaceRedeclaration()) { LogDiagnostic(diagnostic::INTERFACE_REDECLARED, interfDecl->Start()); return; @@ -775,7 +775,8 @@ void InitScopesPhaseTs::CreateFuncDecl(ir::ScriptFunction *func) varbinder::FunctionDecl *decl {}; if (res == bindings.end()) { - decl = VarBinder()->AddDecl(startLoc, Allocator(), identNode->Name(), func); + decl = + VarBinder()->AddDecl(startLoc, VarBinder()->Allocator(), identNode->Name(), func); } else { varbinder::Decl *currentDecl = res->second->Declaration(); @@ -942,8 +943,8 @@ void InitScopesPhaseETS::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock varbinder::Variable *var; if (var = VarBinder()->GetScope()->FindLocal(func->Id()->Name(), varbinder::ResolveBindingOptions::STATIC_METHODS); var == nullptr) { - var = std::get<1>(VarBinder()->NewVarDecl(func->Id()->Start(), Allocator(), - func->Id()->Name(), staticBlock)); + var = std::get<1>(VarBinder()->NewVarDecl( + func->Id()->Start(), VarBinder()->Allocator(), func->Id()->Name(), staticBlock)); var->AddFlag(varbinder::VariableFlags::METHOD); } @@ -1018,8 +1019,8 @@ void InitScopesPhaseETS::MaybeAddOverload(ir::MethodDefinition *method, ir::Iden auto *var = methodName->Variable(); if (var == nullptr) { - var = std::get<1>(VarBinder()->NewVarDecl(methodName->Start(), Allocator(), - methodName->Name(), method)); + var = std::get<1>(VarBinder()->NewVarDecl( + methodName->Start(), VarBinder()->Allocator(), methodName->Name(), method)); var->SetScope(clsScope); if (targetScope->HasFlag(varbinder::ScopeFlags::STATIC)) { var->AddFlag(varbinder::VariableFlags::STATIC); @@ -1127,8 +1128,8 @@ void InitScopesPhaseETS::DeclareClassOverload(ir::OverloadDeclaration *overloadd } auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), targetScope); - auto var = std::get<1>(VarBinder()->NewVarDecl(overloadName->Start(), Allocator(), - overloadName->Name(), overloaddecl)); + auto var = std::get<1>(VarBinder()->NewVarDecl( + overloadName->Start(), VarBinder()->Allocator(), overloadName->Name(), overloaddecl)); var->SetScope(clsScope); if (targetScope->HasFlag(varbinder::ScopeFlags::STATIC)) { var->AddFlag(varbinder::VariableFlags::STATIC); diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 84e9ccb559..96cafb6047 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -250,11 +250,15 @@ void Recheck(PhaseManager *phaseManager, varbinder::ETSBinder *varBinder, checke phaseManager->SetCurrentPhaseId(0); auto program = node->AsETSModule()->Program(); - auto newVarbinder = ctx->allocator->New(ctx->allocator); + auto newVarbinder = ctx->allocator->New(); newVarbinder->SetProgram(program); newVarbinder->SetContext(ctx); program->PushVarBinder(newVarbinder); varBinder->CopyTo(newVarbinder); + + // Reclaim memory from old varbinder's allocator after copying + varBinder->~ETSBinder(); + HandleExternalProgram(newVarbinder, program); ClearHelper(program); diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index 5056378116..2933dea3c4 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -79,7 +79,7 @@ public: static Program NewProgram(ArenaAllocator *allocator, varbinder::VarBinder *varBinder = nullptr) { if (varBinder == nullptr) { - auto *vb = allocator->New(allocator); + auto *vb = allocator->New(); return Program(allocator, vb); } return Program(allocator, varBinder); diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index f9295c138b..4a12cffc45 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -341,7 +341,7 @@ static void InitializeContext(Context *res) res->phaseManager = new compiler::PhaseManager(res, ScriptExtension::ETS, res->allocator); res->queue = new compiler::CompileQueue(res->config->options->GetThread()); - auto *varbinder = res->allocator->New(res->allocator); + auto *varbinder = res->allocator->New(); res->parserProgram = res->allocator->New(res->allocator, varbinder); res->parser = new parser::ETSParser(res->parserProgram, *res->config->options, *res->diagnosticEngine, parser::ParserStatus::NO_OPTS); diff --git a/ets2panda/test/unit/lowerings/scopes_initialization.cpp b/ets2panda/test/unit/lowerings/scopes_initialization.cpp index 1c82aeed87..1f6513ccd5 100644 --- a/ets2panda/test/unit/lowerings/scopes_initialization.cpp +++ b/ets2panda/test/unit/lowerings/scopes_initialization.cpp @@ -58,7 +58,7 @@ TEST_F(ScopesInitPhaseTest, TestForUpdateLoop) /* * for (int x = 0; x < 10; x++ ) { let x; } */ - auto varbinder = varbinder::VarBinder(Allocator()); + auto varbinder = varbinder::VarBinder(); auto forNode = NodeGen().CreateForUpdate(); compiler::InitScopesPhaseETS::RunExternalNode(forNode, &varbinder); @@ -87,7 +87,7 @@ TEST_F(ScopesInitPhaseTest, CreateWhile) /* * while (x < 10) { let x; } */ - auto varbinder = varbinder::VarBinder(Allocator()); + auto varbinder = varbinder::VarBinder(); auto whileNode = NodeGen().CreateWhile(); compiler::InitScopesPhaseETS::RunExternalNode(whileNode, &varbinder); diff --git a/ets2panda/varbinder/ASBinder.h b/ets2panda/varbinder/ASBinder.h index debfef7647..754f54ffe7 100644 --- a/ets2panda/varbinder/ASBinder.h +++ b/ets2panda/varbinder/ASBinder.h @@ -21,9 +21,9 @@ namespace ark::es2panda::varbinder { class ASBinder : public VarBinder { public: - explicit ASBinder(ArenaAllocator *allocator) : VarBinder(allocator) {} + explicit ASBinder() : VarBinder() {} - ASBinder() = delete; + ASBinder(ArenaAllocator *allocator) = delete; NO_COPY_SEMANTIC(ASBinder); NO_MOVE_SEMANTIC(ASBinder); ~ASBinder() override = default; diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 025f4c30d9..9163eab5d7 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -57,9 +57,10 @@ using DynamicImportVariables = ArenaUnorderedMapAdapter()), defaultImports_(Allocator()->Adapter()), @@ -71,7 +72,7 @@ public: InitImplicitThisParam(); } - ETSBinder() = delete; + ETSBinder(ArenaAllocator *allocator) = delete; NO_COPY_SEMANTIC(ETSBinder); NO_MOVE_SEMANTIC(ETSBinder); ~ETSBinder() override = default; diff --git a/ets2panda/varbinder/JSBinder.h b/ets2panda/varbinder/JSBinder.h index 9b2cc876f0..bb37e8666b 100644 --- a/ets2panda/varbinder/JSBinder.h +++ b/ets2panda/varbinder/JSBinder.h @@ -21,9 +21,9 @@ namespace ark::es2panda::varbinder { class JSBinder : public VarBinder { public: - explicit JSBinder(ArenaAllocator *allocator) : VarBinder(allocator) {} + explicit JSBinder() : VarBinder() {} - JSBinder() = delete; + JSBinder(ArenaAllocator *allocator) = delete; NO_COPY_SEMANTIC(JSBinder); NO_MOVE_SEMANTIC(JSBinder); ~JSBinder() override = default; diff --git a/ets2panda/varbinder/TSBinder.h b/ets2panda/varbinder/TSBinder.h index ec89742536..1db4afa951 100644 --- a/ets2panda/varbinder/TSBinder.h +++ b/ets2panda/varbinder/TSBinder.h @@ -21,9 +21,9 @@ namespace ark::es2panda::varbinder { class TSBinder : public TypedBinder { public: - explicit TSBinder(ArenaAllocator *allocator) : TypedBinder(allocator) {} + explicit TSBinder() : TypedBinder() {} - TSBinder() = delete; + TSBinder(ArenaAllocator *allocator) = delete; NO_COPY_SEMANTIC(TSBinder); NO_MOVE_SEMANTIC(TSBinder); ~TSBinder() override = default; diff --git a/ets2panda/varbinder/TypedBinder.h b/ets2panda/varbinder/TypedBinder.h index 533966d64a..0ddc73255b 100644 --- a/ets2panda/varbinder/TypedBinder.h +++ b/ets2panda/varbinder/TypedBinder.h @@ -21,9 +21,10 @@ namespace ark::es2panda::varbinder { class TypedBinder : public VarBinder { public: - explicit TypedBinder(ArenaAllocator *allocator) : VarBinder(allocator) {} + // NOLINTNEXTLINE + explicit TypedBinder() : VarBinder() {}; - TypedBinder() = delete; + TypedBinder(ArenaAllocator *allocator) = delete; NO_COPY_SEMANTIC(TypedBinder); NO_MOVE_SEMANTIC(TypedBinder); ~TypedBinder() override = default; diff --git a/ets2panda/varbinder/varbinder.h b/ets2panda/varbinder/varbinder.h index ff674f639b..942ef2096f 100644 --- a/ets2panda/varbinder/varbinder.h +++ b/ets2panda/varbinder/varbinder.h @@ -53,9 +53,12 @@ class ETSBinder; class VarBinder { public: - explicit VarBinder(ArenaAllocator *allocator) : allocator_(allocator), functionScopes_(allocator_->Adapter()) {} + explicit VarBinder() + : allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true), functionScopes_(allocator_.Adapter()) + { + } - VarBinder() = delete; + VarBinder(ArenaAllocator *allocator) = delete; NO_COPY_SEMANTIC(VarBinder); NO_MOVE_SEMANTIC(VarBinder); virtual ~VarBinder() = default; @@ -177,9 +180,9 @@ public: template friend class LexicalScope; - [[nodiscard]] ArenaAllocator *Allocator() const noexcept + [[nodiscard]] ThreadSafeArenaAllocator *Allocator() const noexcept { - return allocator_; + return const_cast(&allocator_); } [[nodiscard]] const ArenaVector &Functions() const noexcept @@ -288,7 +291,6 @@ protected: virtual void CopyTo(VarBinder *target) { target->program_ = program_; - target->allocator_ = allocator_; target->context_ = context_; target->bindingOptions_ = bindingOptions_; target->genStdLib_ = genStdLib_; @@ -296,7 +298,7 @@ protected: private: parser::Program *program_ {}; - ArenaAllocator *allocator_ {}; + ThreadSafeArenaAllocator allocator_; public_lib::Context *context_ {}; GlobalScope *topScope_ {}; Scope *scope_ {}; -- Gitee