diff options
-rw-r--r-- | Assembly.cpp | 1 | ||||
-rw-r--r-- | ConstantOptimiser.cpp | 20 | ||||
-rw-r--r-- | ConstantOptimiser.h | 8 | ||||
-rw-r--r-- | GasMeter.cpp | 42 | ||||
-rw-r--r-- | GasMeter.h | 8 |
5 files changed, 45 insertions, 34 deletions
diff --git a/Assembly.cpp b/Assembly.cpp index 5d4efac1..7277865e 100644 --- a/Assembly.cpp +++ b/Assembly.cpp @@ -22,7 +22,6 @@ #include "Assembly.h" #include <fstream> #include <libdevcore/Log.h> -#include <libevmcore/Params.h> #include <libevmasm/CommonSubexpressionEliminator.h> #include <libevmasm/ControlFlowGraph.h> #include <libevmasm/BlockDeduplicator.h> diff --git a/ConstantOptimiser.cpp b/ConstantOptimiser.cpp index 88874d81..0ebe2eab 100644 --- a/ConstantOptimiser.cpp +++ b/ConstantOptimiser.cpp @@ -22,7 +22,6 @@ #include "libevmasm/ConstantOptimiser.h" #include <libevmasm/Assembly.h> #include <libevmasm/GasMeter.h> -#include <libevmcore/Params.h> using namespace std; using namespace dev; using namespace dev::eth; @@ -70,12 +69,13 @@ unsigned ConstantOptimisationMethod::optimiseConstants( bigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items) { + EVMSchedule schedule; // TODO: make relevant to context. bigint gas = 0; for (AssemblyItem const& item: _items) if (item.type() == Push) - gas += GasMeter::runGas(Instruction::PUSH1); + gas += GasMeter::runGas(Instruction::PUSH1, schedule); else if (item.type() == Operation) - gas += GasMeter::runGas(item.instruction()); + gas += GasMeter::runGas(item.instruction(), schedule); return gas; } @@ -85,11 +85,11 @@ bigint ConstantOptimisationMethod::dataGas(bytes const& _data) const { bigint gas; for (auto b: _data) - gas += b ? c_txDataNonZeroGas : c_txDataZeroGas; + gas += b ? m_schedule.txDataNonZeroGas : m_schedule.txDataZeroGas; return gas; } else - return c_createDataGas * dataSize(); + return m_schedule.createDataGas * dataSize(); } size_t ConstantOptimisationMethod::bytesRequired(AssemblyItems const& _items) @@ -121,7 +121,7 @@ bigint LiteralMethod::gasNeeded() return combineGas( simpleRunGas({Instruction::PUSH1}), // PUSHX plus data - (m_params.isCreation ? c_txDataNonZeroGas : c_createDataGas) + dataGas(), + (m_params.isCreation ? m_schedule.txDataNonZeroGas : m_schedule.createDataGas) + dataGas(), 0 ); } @@ -148,9 +148,9 @@ bigint CodeCopyMethod::gasNeeded() { return combineGas( // Run gas: we ignore memory increase costs - simpleRunGas(m_copyRoutine) + c_copyGas, + simpleRunGas(m_copyRoutine) + m_schedule.copyGas, // Data gas for copy routines: Some bytes are zero, but we ignore them. - bytesRequired(m_copyRoutine) * (m_params.isCreation ? c_txDataNonZeroGas : c_createDataGas), + bytesRequired(m_copyRoutine) * (m_params.isCreation ? m_schedule.txDataNonZeroGas : m_schedule.createDataGas), // Data gas for data itself dataGas(toBigEndian(m_value)) ); @@ -217,9 +217,9 @@ bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine) { size_t numExps = count(_routine.begin(), _routine.end(), Instruction::EXP); return combineGas( - simpleRunGas(_routine) + numExps * (c_expGas + c_expByteGas), + simpleRunGas(_routine) + numExps * (m_schedule.expGas + m_schedule.expByteGas), // Data gas for routine: Some bytes are zero, but we ignore them. - bytesRequired(_routine) * (m_params.isCreation ? c_txDataNonZeroGas : c_createDataGas), + bytesRequired(_routine) * (m_params.isCreation ? m_schedule.txDataNonZeroGas : m_schedule.createDataGas), 0 ); } diff --git a/ConstantOptimiser.h b/ConstantOptimiser.h index e75eff38..64cb66bb 100644 --- a/ConstantOptimiser.h +++ b/ConstantOptimiser.h @@ -24,6 +24,7 @@ #include <vector> #include <libdevcore/CommonData.h> #include <libdevcore/CommonIO.h> +#include <libethcore/ChainOperationParams.h> namespace dev { @@ -34,6 +35,8 @@ class AssemblyItem; using AssemblyItems = std::vector<AssemblyItem>; class Assembly; +// TODO: FIXME: HOMESTEAD: XXX: @chfast populate m_schedule from an ExtVMFace instance via ExtVMFace::evmSchedule. + /** * Abstract base class for one way to change how constants are represented in the code. */ @@ -88,6 +91,7 @@ protected: Params m_params; u256 const& m_value; + EVMSchedule m_schedule; }; /** @@ -101,6 +105,8 @@ public: ConstantOptimisationMethod(_params, _value) {} virtual bigint gasNeeded() override; virtual void execute(Assembly&, AssemblyItems&) override {} + + EVMSchedule m_schedule; }; /** @@ -115,6 +121,7 @@ public: protected: AssemblyItems m_copyRoutine; + EVMSchedule m_schedule; }; /** @@ -141,6 +148,7 @@ protected: bigint gasNeeded(AssemblyItems const& _routine); AssemblyItems m_routine; + EVMSchedule m_schedule; }; } diff --git a/GasMeter.cpp b/GasMeter.cpp index 00b93214..b792f04d 100644 --- a/GasMeter.cpp +++ b/GasMeter.cpp @@ -21,8 +21,6 @@ #include "GasMeter.h" #include <libevmasm/KnownState.h> -#include <libevmcore/Params.h> - using namespace std; using namespace dev; using namespace dev::eth; @@ -73,13 +71,13 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item) m_state->storageContent().count(slot) && classes.knownNonZero(m_state->storageContent().at(slot)) )) - gas += c_sstoreResetGas; //@todo take refunds into account + gas += m_schedule.sstoreResetGas; //@todo take refunds into account else - gas += c_sstoreSetGas; + gas += m_schedule.sstoreSetGas; break; } case Instruction::SLOAD: - gas += c_sloadGas; + gas += m_schedule.sloadGas; break; case Instruction::RETURN: gas += memoryGas(0, -1); @@ -98,18 +96,18 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item) })); break; case Instruction::SHA3: - gas = c_sha3Gas; - gas += wordGas(c_sha3WordGas, m_state->relativeStackElement(-1)); + gas = m_schedule.sha3Gas; + gas += wordGas(m_schedule.sha3WordGas, m_state->relativeStackElement(-1)); gas += memoryGas(0, -1); break; case Instruction::CALLDATACOPY: case Instruction::CODECOPY: gas += memoryGas(0, -2); - gas += wordGas(c_copyGas, m_state->relativeStackElement(-2)); + gas += wordGas(m_schedule.copyGas, m_state->relativeStackElement(-2)); break; case Instruction::EXTCODECOPY: gas += memoryGas(-1, -3); - gas += wordGas(c_copyGas, m_state->relativeStackElement(-3)); + gas += wordGas(m_schedule.copyGas, m_state->relativeStackElement(-3)); break; case Instruction::LOG0: case Instruction::LOG1: @@ -118,38 +116,38 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item) case Instruction::LOG4: { unsigned n = unsigned(_item.instruction()) - unsigned(Instruction::LOG0); - gas = c_logGas + c_logTopicGas * n; + gas = m_schedule.logGas + m_schedule.logTopicGas * n; gas += memoryGas(0, -1); if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1))) - gas += c_logDataGas * (*value); + gas += m_schedule.logDataGas * (*value); else gas = GasConsumption::infinite(); break; } case Instruction::CALL: case Instruction::CALLCODE: - gas = c_callGas; + gas = m_schedule.callGas; if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0))) gas += (*value); else gas = GasConsumption::infinite(); if (_item.instruction() != Instruction::CALLCODE) - gas += c_callNewAccountGas; // We very rarely know whether the address exists. + gas += m_schedule.callNewAccountGas; // We very rarely know whether the address exists. if (!classes.knownZero(m_state->relativeStackElement(-2))) - gas += c_callValueTransferGas; + gas += m_schedule.callValueTransferGas; gas += memoryGas(-3, -4); gas += memoryGas(-5, -6); break; case Instruction::CREATE: - gas = c_createGas; + gas = m_schedule.createGas; gas += memoryGas(-1, -2); break; case Instruction::EXP: - gas = c_expGas; + gas = m_schedule.expGas; if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1))) - gas += c_expByteGas * (32 - (h256(*value).firstBitSet() / 8)); + gas += m_schedule.expByteGas * (32 - (h256(*value).firstBitSet() / 8)); else - gas += c_expByteGas * 32; + gas += m_schedule.expByteGas * 32; break; default: break; @@ -182,10 +180,10 @@ GasMeter::GasConsumption GasMeter::memoryGas(ExpressionClasses::Id _position) return GasConsumption(u256(0)); u256 previous = m_largestMemoryAccess; m_largestMemoryAccess = *value; - auto memGas = [](u256 const& pos) -> u256 + auto memGas = [=](u256 const& pos) -> u256 { u256 size = (pos + 31) / 32; - return c_memoryGas * size + size * size / c_quadCoeffDiv; + return m_schedule.memoryGas * size + size * size / m_schedule.quadCoeffDiv; }; return memGas(*value) - memGas(previous); } @@ -202,14 +200,14 @@ GasMeter::GasConsumption GasMeter::memoryGas(int _stackPosOffset, int _stackPosS })); } -u256 GasMeter::runGas(Instruction _instruction) +u256 GasMeter::runGas(Instruction _instruction, EVMSchedule const& _es) { if (_instruction == Instruction::JUMPDEST) return 1; int tier = instructionInfo(_instruction).gasPriceTier; assertThrow(tier != InvalidTier, OptimizerException, "Invalid gas tier."); - return c_tierStepGas[tier]; + return _es.tierStepGas[tier]; } @@ -25,6 +25,7 @@ #include <tuple> #include <libevmasm/ExpressionClasses.h> #include <libevmasm/AssemblyItem.h> +#include <libethcore/ChainOperationParams.h> namespace dev { @@ -33,6 +34,8 @@ namespace eth class KnownState; +// TODO: FIXME: HOMESTEAD: XXX: @chfast populate m_schedule from an ExtVMFace instance via ExtVMFace::evmSchedule. + /** * Class that helps computing the maximum gas consumption for instructions. * Has to be initialized with a certain known state that will be automatically updated for @@ -66,7 +69,8 @@ public: u256 const& largestMemoryAccess() const { return m_largestMemoryAccess; } - static u256 runGas(Instruction _instruction); + u256 runGas(Instruction _instruction) const { return runGas(_instruction, m_schedule); } + static u256 runGas(Instruction _instruction, EVMSchedule const& _es); private: /// @returns _multiplier * (_value + 31) / 32, if _value is a known constant and infinite otherwise. @@ -81,6 +85,8 @@ private: std::shared_ptr<KnownState> m_state; /// Largest point where memory was accessed since the creation of this object. u256 m_largestMemoryAccess; + + EVMSchedule m_schedule; }; inline std::ostream& operator<<(std::ostream& _str, GasMeter::GasConsumption const& _consumption) |