From 891b7c83d7cbc551c8b3a74cb67bcd6ea26ad96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 26 Sep 2024 18:38:40 +0200 Subject: [PATCH 1/2] Do not cache instances of Compiler in CompilerStack --- libsolidity/interface/CompilerStack.cpp | 14 +++++++++----- libsolidity/interface/CompilerStack.h | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index bac358a939f4..8dd390f5edd2 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -861,15 +861,18 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run c.generatedSources; return sources.init([&]{ Json sources = Json::array(); - // If there is no compiler, then no bytecode was generated and thus no + + solAssert(c.generatedYulUtilityCode.has_value() == c.runtimeGeneratedYulUtilityCode.has_value()); + + // If there is no generated utility code, then no bytecode was generated and thus no // sources were generated (or we compiled "via IR"). - if (c.compiler) + if (c.runtimeGeneratedYulUtilityCode.has_value()) { solAssert(!m_viaIR, ""); std::string source = _runtime ? - c.compiler->runtimeGeneratedYulUtilityCode() : - c.compiler->generatedYulUtilityCode(); + *c.runtimeGeneratedYulUtilityCode : + *c.generatedYulUtilityCode; if (!source.empty()) { std::string sourceName = CompilerContext::yulUtilityFileName(); @@ -1469,13 +1472,14 @@ void CompilerStack::compileContract( Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); std::shared_ptr compiler = std::make_shared(m_evmVersion, m_revertStrings, m_optimiserSettings); - compiledContract.compiler = compiler; solAssert(!m_viaIR, ""); bytes cborEncodedMetadata = createCBORMetadata(compiledContract, /* _forIR */ false); // Run optimiser and compile the contract. compiler->compileContract(_contract, _otherCompilers, cborEncodedMetadata); + compiledContract.generatedYulUtilityCode = compiler->generatedYulUtilityCode(); + compiledContract.runtimeGeneratedYulUtilityCode = compiler->runtimeGeneratedYulUtilityCode(); _otherCompilers[compiledContract.contract] = compiler; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index c0166af96d5b..f167477faf3b 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -409,9 +409,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac struct Contract { ContractDefinition const* contract = nullptr; - std::shared_ptr compiler; + std::shared_ptr evmAssembly; std::shared_ptr evmRuntimeAssembly; + std::optional generatedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the creation assembly + std::optional runtimeGeneratedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the deployed assembly evmasm::LinkerObject object; ///< Deployment object (includes the runtime sub-object). evmasm::LinkerObject runtimeObject; ///< Runtime object. std::string yulIR; ///< Yul IR code straight from the code generator. From 3c5e46b7d75172114413c7c775c412ffc41d9d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 26 Sep 2024 23:16:19 +0200 Subject: [PATCH 2/2] CompilerStack: Do not cache the JSON representation of generated sources --- libsolidity/interface/CompilerStack.cpp | 60 +++++++++++-------------- libsolidity/interface/CompilerStack.h | 2 - 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 8dd390f5edd2..a9f2708d8023 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -855,43 +855,35 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& c = contract(_contractName); - util::LazyInit const& sources = - _runtime ? - c.runtimeGeneratedSources : - c.generatedSources; - return sources.init([&]{ - Json sources = Json::array(); - + Json sources = Json::array(); + // If there is no compiler, then no bytecode was generated and thus no + // sources were generated (or we compiled "via IR"). + if (c.runtimeGeneratedYulUtilityCode.has_value()) + { solAssert(c.generatedYulUtilityCode.has_value() == c.runtimeGeneratedYulUtilityCode.has_value()); - - // If there is no generated utility code, then no bytecode was generated and thus no - // sources were generated (or we compiled "via IR"). - if (c.runtimeGeneratedYulUtilityCode.has_value()) + solAssert(!m_viaIR); + std::string source = + _runtime ? + *c.runtimeGeneratedYulUtilityCode : + *c.generatedYulUtilityCode; + if (!source.empty()) { - solAssert(!m_viaIR, ""); - std::string source = - _runtime ? - *c.runtimeGeneratedYulUtilityCode : - *c.generatedYulUtilityCode; - if (!source.empty()) - { - std::string sourceName = CompilerContext::yulUtilityFileName(); - unsigned sourceIndex = sourceIndices()[sourceName]; - ErrorList errors; - ErrorReporter errorReporter(errors); - CharStream charStream(source, sourceName); - yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); - std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); - solAssert(parserResult, ""); - sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); - sources[0]["name"] = sourceName; - sources[0]["id"] = sourceIndex; - sources[0]["language"] = "Yul"; - sources[0]["contents"] = std::move(source); - } + std::string sourceName = CompilerContext::yulUtilityFileName(); + unsigned sourceIndex = sourceIndices()[sourceName]; + ErrorList errors; + ErrorReporter errorReporter(errors); + CharStream charStream(source, sourceName); + yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); + solAssert(parserResult); + sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); + sources[0]["name"] = sourceName; + sources[0]["id"] = sourceIndex; + sources[0]["language"] = "Yul"; + sources[0]["contents"] = std::move(source); } - return sources; - }); + } + return sources; } std::string const* CompilerStack::sourceMapping(std::string const& _contractName) const diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index f167477faf3b..2b891293b3e0 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -424,8 +424,6 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac util::LazyInit transientStorageLayout; util::LazyInit userDocumentation; util::LazyInit devDocumentation; - util::LazyInit generatedSources; - util::LazyInit runtimeGeneratedSources; mutable std::optional sourceMapping; mutable std::optional runtimeSourceMapping; };