diff --git a/Changelog.md b/Changelog.md index 45ec293a15fe..b0b4ea404082 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: * Code Generator: Transient storage value type state variables are now supported by the legacy pipeline. + * CompilerStack: Generate Yul ASTs only on demand to reduce memory usage. Bugfixes: diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index deb748fbe7d8..bac358a939f4 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -956,21 +956,24 @@ std::string const& CompilerStack::yulIR(std::string const& _contractName) const return contract(_contractName).yulIR; } -Json const& CompilerStack::yulIRAst(std::string const& _contractName) const +Json CompilerStack::yulIRAst(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulIRAst; + + // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to + // keep it around when compiling a large project containing many contracts. + return loadGeneratedIR(contract(_contractName).yulIR).astJson(); } -Json const& CompilerStack::yulCFGJson(std::string const& _contractName) const +Json CompilerStack::yulCFGJson(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulCFGJson; + // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to + // keep it around when compiling a large project containing many contracts. + return loadGeneratedIR(contract(_contractName).yulIR).cfgJson(); } std::string const& CompilerStack::yulIROptimized(std::string const& _contractName) const @@ -979,11 +982,14 @@ std::string const& CompilerStack::yulIROptimized(std::string const& _contractNam return contract(_contractName).yulIROptimized; } -Json const& CompilerStack::yulIROptimizedAst(std::string const& _contractName) const +Json CompilerStack::yulIROptimizedAst(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulIROptimizedAst; + + // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to + // keep it around when compiling a large project containing many contracts. + return loadGeneratedIR(contract(_contractName).yulIROptimized).astJson(); } evmasm::LinkerObject const& CompilerStack::object(std::string const& _contractName) const @@ -1539,13 +1545,10 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti } YulStack stack = loadGeneratedIR(compiledContract.yulIR); - compiledContract.yulIRAst = stack.astJson(); - compiledContract.yulCFGJson = stack.cfgJson(); if (!_unoptimizedOnly) { stack.optimize(); compiledContract.yulIROptimized = stack.print(); - compiledContract.yulIROptimizedAst = stack.astJson(); } } diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 885438475345..c0166af96d5b 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -295,15 +295,15 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::string const& yulIR(std::string const& _contractName) const; /// @returns the IR representation of a contract AST in format. - Json const& yulIRAst(std::string const& _contractName) const; + Json yulIRAst(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract. std::string const& yulIROptimized(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract AST in JSON format. - Json const& yulIROptimizedAst(std::string const& _contractName) const; + Json yulIROptimizedAst(std::string const& _contractName) const; - Json const& yulCFGJson(std::string const& _contractName) const; + Json yulCFGJson(std::string const& _contractName) const; /// @returns the assembled object for a contract. virtual evmasm::LinkerObject const& object(std::string const& _contractName) const override; @@ -416,9 +416,6 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac evmasm::LinkerObject runtimeObject; ///< Runtime object. std::string yulIR; ///< Yul IR code straight from the code generator. std::string yulIROptimized; ///< Reparsed and possibly optimized Yul IR code. - Json yulIRAst; ///< JSON AST of Yul IR code. - Json yulIROptimizedAst; ///< JSON AST of optimized Yul IR code. - Json yulCFGJson; ///< JSON CFG of Yul IR code. util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. util::LazyInit abi; util::LazyInit storageLayout;