Skip to content

Commit

Permalink
Merge pull request #168 from ethereum/op_metrics_table
Browse files Browse the repository at this point in the history
New metrics table
  • Loading branch information
chfast authored Sep 12, 2019
2 parents ae53cbb + 867a4ec commit a3e55ec
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 190 deletions.
2 changes: 1 addition & 1 deletion lib/evmone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ add_library(evmone
limits.hpp
opcodes_helpers.h
)
target_link_libraries(evmone PUBLIC evmc::evmc PRIVATE intx::intx evmc::instructions ethash::keccak)
target_link_libraries(evmone PUBLIC evmc::evmc PRIVATE intx::intx ethash::keccak)
target_include_directories(evmone PUBLIC
$<BUILD_INTERFACE:${include_dir}>$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
Expand Down
22 changes: 8 additions & 14 deletions lib/evmone/analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ inline constexpr uint64_t load64be(const unsigned char* data) noexcept

code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) noexcept
{
const auto& fns = get_op_table(rev);
const auto opx_beginblock_fn = fns[OPX_BEGINBLOCK];
const auto& op_tbl = get_op_table(rev);
const auto opx_beginblock_fn = op_tbl[OPX_BEGINBLOCK].fn;

code_analysis analysis;

Expand All @@ -44,8 +44,6 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size)
const auto max_args_storage_size = code_size + 1;
analysis.push_values.reserve(max_args_storage_size);

const auto* instr_table = evmc_get_instruction_metrics_table(rev);

// Create first block.
analysis.instrs.emplace_back(opx_beginblock_fn);
auto block = block_analysis{0};
Expand All @@ -56,17 +54,13 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size)
while (code_pos != code_end)
{
const auto opcode = *code_pos++;
const auto& opcode_info = op_tbl[opcode];

const auto metrics = instr_table[opcode];
const auto instr_stack_req = metrics.num_stack_arguments;
const auto instr_stack_change = metrics.num_stack_returned_items - instr_stack_req;

block.stack_req = std::max(block.stack_req, instr_stack_req - block.stack_change);
block.stack_change += instr_stack_change;
block.stack_req = std::max(block.stack_req, opcode_info.stack_req - block.stack_change);
block.stack_change += opcode_info.stack_change;
block.stack_max_growth = std::max(block.stack_max_growth, block.stack_change);

if (metrics.gas_cost > 0) // can be -1 for undefined instruction
block.gas_cost += metrics.gas_cost;
block.gas_cost += opcode_info.gas_cost;

if (opcode == OP_JUMPDEST)
{
Expand All @@ -77,7 +71,7 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size)
static_cast<int16_t>(analysis.instrs.size() - 1));
}
else
analysis.instrs.emplace_back(fns[opcode]);
analysis.instrs.emplace_back(opcode_info.fn);

auto& instr = analysis.instrs.back();

Expand Down Expand Up @@ -177,7 +171,7 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size)

// Make sure the last block is terminated.
// TODO: This is not needed if the last instruction is a terminating one.
analysis.instrs.emplace_back(fns[OP_STOP]);
analysis.instrs.emplace_back(op_tbl[OP_STOP].fn);

// FIXME: assert(analysis.instrs.size() <= max_instrs_size);

Expand Down
12 changes: 10 additions & 2 deletions lib/evmone/analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,15 @@ enum intrinsic_opcodes
OPX_BEGINBLOCK = OP_JUMPDEST
};

using exec_fn_table = std::array<exec_fn, 256>;
struct op_table_entry
{
exec_fn fn;
int16_t gas_cost;
int8_t stack_req;
int8_t stack_change;
};

using op_table = std::array<op_table_entry, 256>;

struct instr_info
{
Expand Down Expand Up @@ -213,6 +221,6 @@ inline int find_jumpdest(const code_analysis& analysis, int offset) noexcept
EVMC_EXPORT code_analysis analyze(
evmc_revision rev, const uint8_t* code, size_t code_size) noexcept;

EVMC_EXPORT const exec_fn_table& get_op_table(evmc_revision rev) noexcept;
EVMC_EXPORT const op_table& get_op_table(evmc_revision rev) noexcept;

} // namespace evmone
Loading

0 comments on commit a3e55ec

Please sign in to comment.