aboutsummaryrefslogtreecommitdiffstats
path: root/libevmasm
diff options
context:
space:
mode:
Diffstat (limited to 'libevmasm')
-rw-r--r--libevmasm/Assembly.cpp3
-rw-r--r--libevmasm/AssemblyItem.cpp4
-rw-r--r--libevmasm/EVMSchedule.h62
-rw-r--r--libevmasm/Instruction.h18
-rw-r--r--libevmasm/PeepholeOptimiser.cpp11
-rw-r--r--libevmasm/SemanticInformation.cpp6
6 files changed, 34 insertions, 70 deletions
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index df691e7d..5fab24e1 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -408,7 +408,10 @@ map<u256, u256> Assembly::optimiseInternal(
{
PeepholeOptimiser peepOpt(m_items);
while (peepOpt.optimise())
+ {
count++;
+ assertThrow(count < 64000, OptimizerException, "Peephole optimizer seems to be stuck.");
+ }
}
// This only modifies PushTags, we have to run again to actually remove code.
diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp
index cfe91be0..64963021 100644
--- a/libevmasm/AssemblyItem.cpp
+++ b/libevmasm/AssemblyItem.cpp
@@ -17,8 +17,6 @@
#include <libevmasm/AssemblyItem.h>
-#include <libevmasm/SemanticInformation.h>
-
#include <libdevcore/CommonData.h>
#include <libdevcore/FixedHash.h>
@@ -112,7 +110,7 @@ bool AssemblyItem::canBeFunctional() const
switch (m_type)
{
case Operation:
- return !SemanticInformation::isDupInstruction(*this) && !SemanticInformation::isSwapInstruction(*this);
+ return !isDupInstruction(instruction()) && !isSwapInstruction(instruction());
case Push:
case PushString:
case PushTag:
diff --git a/libevmasm/EVMSchedule.h b/libevmasm/EVMSchedule.h
deleted file mode 100644
index 1695a59c..00000000
--- a/libevmasm/EVMSchedule.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- This file is part of solidity.
-
- solidity is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- solidity is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with solidity. If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file EVMSchedule.h
- * @author Gav <i@gavwood.com>
- * @author Christian <c@ethdev.com>
- * @date 2015
- */
-
-#pragma once
-
-namespace dev
-{
-namespace solidity
-{
-
-struct EVMSchedule
-{
- unsigned stackLimit = 1024;
- unsigned expGas = 10;
- unsigned expByteGas = 10;
- unsigned keccak256Gas = 30;
- unsigned keccak256WordGas = 6;
- unsigned sloadGas = 200;
- unsigned sstoreSetGas = 20000;
- unsigned sstoreResetGas = 5000;
- unsigned sstoreRefundGas = 15000;
- unsigned jumpdestGas = 1;
- unsigned logGas = 375;
- unsigned logDataGas = 8;
- unsigned logTopicGas = 375;
- unsigned createGas = 32000;
- unsigned callGas = 40;
- unsigned callStipend = 2300;
- unsigned callValueTransferGas = 9000;
- unsigned callNewAccountGas = 25000;
- unsigned selfdestructRefundGas = 24000;
- unsigned memoryGas = 3;
- unsigned quadCoeffDiv = 512;
- unsigned createDataGas = 200;
- unsigned txGas = 21000;
- unsigned txCreateGas = 53000;
- unsigned txDataZeroGas = 4;
- unsigned txDataNonZeroGas = 68;
- unsigned copyGas = 3;
-};
-
-}
-}
diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h
index afbef71d..d9c53900 100644
--- a/libevmasm/Instruction.h
+++ b/libevmasm/Instruction.h
@@ -197,6 +197,24 @@ enum class Instruction: uint8_t
SELFDESTRUCT = 0xff ///< halt execution and register account for later deletion
};
+/// @returns true if the instruction is a PUSH
+inline bool isPushInstruction(Instruction _inst)
+{
+ return Instruction::PUSH1 <= _inst && _inst <= Instruction::PUSH32;
+}
+
+/// @returns true if the instruction is a DUP
+inline bool isDupInstruction(Instruction _inst)
+{
+ return Instruction::DUP1 <= _inst && _inst <= Instruction::DUP16;
+}
+
+/// @returns true if the instruction is a SWAP
+inline bool isSwapInstruction(Instruction _inst)
+{
+ return Instruction::SWAP1 <= _inst && _inst <= Instruction::SWAP16;
+}
+
/// @returns the number of PUSH Instruction _inst
inline unsigned getPushNumber(Instruction _inst)
{
diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp
index 31fdd317..168d1109 100644
--- a/libevmasm/PeepholeOptimiser.cpp
+++ b/libevmasm/PeepholeOptimiser.cpp
@@ -249,6 +249,11 @@ void applyMethods(OptimiserState& _state, Method, OtherMethods... _other)
applyMethods(_state, _other...);
}
+size_t numberOfPops(AssemblyItems const& _items)
+{
+ return std::count(_items.begin(), _items.end(), Instruction::POP);
+}
+
}
bool PeepholeOptimiser::optimise()
@@ -257,8 +262,10 @@ bool PeepholeOptimiser::optimise()
while (state.i < m_items.size())
applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity());
if (m_optimisedItems.size() < m_items.size() || (
- m_optimisedItems.size() == m_items.size() &&
- eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3)
+ m_optimisedItems.size() == m_items.size() && (
+ eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) ||
+ numberOfPops(m_optimisedItems) > numberOfPops(m_items)
+ )
))
{
m_items = std::move(m_optimisedItems);
diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp
index ceb3fbdd..61a6ccda 100644
--- a/libevmasm/SemanticInformation.cpp
+++ b/libevmasm/SemanticInformation.cpp
@@ -90,14 +90,14 @@ bool SemanticInformation::isDupInstruction(AssemblyItem const& _item)
{
if (_item.type() != Operation)
return false;
- return Instruction::DUP1 <= _item.instruction() && _item.instruction() <= Instruction::DUP16;
+ return solidity::isDupInstruction(_item.instruction());
}
bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item)
{
if (_item.type() != Operation)
return false;
- return Instruction::SWAP1 <= _item.instruction() && _item.instruction() <= Instruction::SWAP16;
+ return solidity::isSwapInstruction(_item.instruction());
}
bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item)
@@ -198,6 +198,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction)
case Instruction::ORIGIN:
case Instruction::CALLER:
case Instruction::CALLVALUE:
+ case Instruction::GAS:
case Instruction::GASPRICE:
case Instruction::EXTCODESIZE:
case Instruction::EXTCODECOPY:
@@ -223,7 +224,6 @@ bool SemanticInformation::invalidInViewFunctions(Instruction _instruction)
case Instruction::SSTORE:
case Instruction::JUMP:
case Instruction::JUMPI:
- case Instruction::GAS:
case Instruction::LOG0:
case Instruction::LOG1:
case Instruction::LOG2: