Do not create a copy of the assembly.

This commit is contained in:
chriseth 2019-01-16 11:44:11 +01:00
parent a9fa2658d8
commit 29f6aa7d56
6 changed files with 22 additions and 14 deletions

View File

@ -47,6 +47,12 @@ void Compiler::compileContract(
m_context.optimise(m_optimize, m_optimizeRuns); m_context.optimise(m_optimize, m_optimizeRuns);
} }
std::shared_ptr<eth::Assembly> Compiler::runtimeAssemblyPtr() const
{
solAssert(m_context.runtimeContext(), "");
return m_context.runtimeContext()->assemblyPtr();
}
eth::AssemblyItem Compiler::functionEntryLabel(FunctionDefinition const& _function) const eth::AssemblyItem Compiler::functionEntryLabel(FunctionDefinition const& _function) const
{ {
return m_runtimeContext.functionEntryLabelIfExists(_function); return m_runtimeContext.functionEntryLabelIfExists(_function);

View File

@ -50,8 +50,10 @@ public:
); );
/// @returns Entire assembly. /// @returns Entire assembly.
eth::Assembly const& assembly() const { return m_context.assembly(); } eth::Assembly const& assembly() const { return m_context.assembly(); }
/// @returns Entire assembly as a shared pointer to non-const.
std::shared_ptr<eth::Assembly> assemblyPtr() const { return m_context.assemblyPtr(); }
/// @returns Runtime assembly. /// @returns Runtime assembly.
eth::Assembly const& runtimeAssembly() const { return m_context.assembly().sub(m_runtimeSub); } std::shared_ptr<eth::Assembly> runtimeAssemblyPtr() const;
/// @returns The entire assembled object (with constructor). /// @returns The entire assembled object (with constructor).
eth::LinkerObject assembledObject() const { return m_context.assembledObject(); } eth::LinkerObject assembledObject() const { return m_context.assembledObject(); }
/// @returns Only the runtime object (without constructor). /// @returns Only the runtime object (without constructor).

View File

@ -167,18 +167,18 @@ unsigned CompilerContext::numberOfLocalVariables() const
return m_localVariables.size(); return m_localVariables.size();
} }
eth::Assembly const& CompilerContext::compiledContract(ContractDefinition const& _contract) const shared_ptr<eth::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const
{ {
auto ret = m_otherCompilers.find(&_contract); auto ret = m_otherCompilers.find(&_contract);
solAssert(ret != m_otherCompilers.end(), "Compiled contract not found."); solAssert(ret != m_otherCompilers.end(), "Compiled contract not found.");
return ret->second->assembly(); return ret->second->assemblyPtr();
} }
eth::Assembly const& CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const shared_ptr<eth::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const
{ {
auto ret = m_otherCompilers.find(&_contract); auto ret = m_otherCompilers.find(&_contract);
solAssert(ret != m_otherCompilers.end(), "Compiled contract not found."); solAssert(ret != m_otherCompilers.end(), "Compiled contract not found.");
return ret->second->runtimeAssembly(); return ret->second->runtimeAssemblyPtr();
} }
bool CompilerContext::isLocalVariable(Declaration const* _declaration) const bool CompilerContext::isLocalVariable(Declaration const* _declaration) const

View File

@ -76,8 +76,8 @@ public:
unsigned numberOfLocalVariables() const; unsigned numberOfLocalVariables() const;
void setOtherCompilers(std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers) { m_otherCompilers = _otherCompilers; } void setOtherCompilers(std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers) { m_otherCompilers = _otherCompilers; }
eth::Assembly const& compiledContract(ContractDefinition const& _contract) const; std::shared_ptr<eth::Assembly> compiledContract(ContractDefinition const& _contract) const;
eth::Assembly const& compiledContractRuntime(ContractDefinition const& _contract) const; std::shared_ptr<eth::Assembly> compiledContractRuntime(ContractDefinition const& _contract) const;
void setStackOffset(int _offset) { m_asm->setDeposit(_offset); } void setStackOffset(int _offset) { m_asm->setDeposit(_offset); }
void adjustStackOffset(int _adjustment) { m_asm->adjustDeposit(_adjustment); } void adjustStackOffset(int _adjustment) { m_asm->adjustDeposit(_adjustment); }
@ -224,15 +224,15 @@ public:
void optimise(bool _fullOptimsation, unsigned _runs = 200) { m_asm->optimise(_fullOptimsation, m_evmVersion, true, _runs); } void optimise(bool _fullOptimsation, unsigned _runs = 200) { m_asm->optimise(_fullOptimsation, m_evmVersion, true, _runs); }
/// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise. /// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise.
CompilerContext* runtimeContext() { return m_runtimeContext; } CompilerContext* runtimeContext() const { return m_runtimeContext; }
/// @returns the identifier of the runtime subroutine. /// @returns the identifier of the runtime subroutine.
size_t runtimeSub() const { return m_runtimeSub; } size_t runtimeSub() const { return m_runtimeSub; }
/// @returns a const reference to the underlying assembly. /// @returns a const reference to the underlying assembly.
eth::Assembly const& assembly() const { return *m_asm; } eth::Assembly const& assembly() const { return *m_asm; }
/// @returns non-const reference to the underlying assembly. Should be avoided in favour of /// @returns a shared pointer to the assembly.
/// wrappers in this class. /// Should be avoided except when adding sub-assemblies.
eth::Assembly& nonConstAssembly() { return *m_asm; } std::shared_ptr<eth::Assembly> assemblyPtr() const { return m_asm; }
/// @arg _sourceCodes is the map of input files to source code strings /// @arg _sourceCodes is the map of input files to source code strings
std::string assemblyString(StringMap const& _sourceCodes = StringMap()) const std::string assemblyString(StringMap const& _sourceCodes = StringMap()) const

View File

@ -1209,12 +1209,12 @@ void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract,
[&contract, _creation](CompilerContext& _context) [&contract, _creation](CompilerContext& _context)
{ {
// copy the contract's code into memory // copy the contract's code into memory
eth::Assembly const& assembly = shared_ptr<eth::Assembly> assembly =
_creation ? _creation ?
_context.compiledContract(contract) : _context.compiledContract(contract) :
_context.compiledContractRuntime(contract); _context.compiledContractRuntime(contract);
// pushes size // pushes size
auto subroutine = _context.addSubroutine(make_shared<eth::Assembly>(assembly)); auto subroutine = _context.addSubroutine(assembly);
_context << Instruction::DUP1 << subroutine; _context << Instruction::DUP1 << subroutine;
_context << Instruction::DUP4 << Instruction::CODECOPY; _context << Instruction::DUP4 << Instruction::CODECOPY;
_context << Instruction::ADD; _context << Instruction::ADD;

View File

@ -716,7 +716,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
CodeGenerator::assemble( CodeGenerator::assemble(
_inlineAssembly.operations(), _inlineAssembly.operations(),
*_inlineAssembly.annotation().analysisInfo, *_inlineAssembly.annotation().analysisInfo,
m_context.nonConstAssembly(), *m_context.assemblyPtr(),
identifierAccess identifierAccess
); );
m_context.setStackOffset(startStackHeight); m_context.setStackOffset(startStackHeight);