From c38ae167c87cf48626ca131ef5f4b9091ff1223e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 22 Apr 2021 08:20:08 +0200 Subject: [PATCH 1/2] Export and benchmark build_jumpdest_map() --- lib/evmone/baseline.cpp | 14 ++++++-------- lib/evmone/baseline.hpp | 9 ++++++++- test/bench/bench.cpp | 8 ++++++++ test/bench/helpers.hpp | 16 ++++++++++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index db8a72cdbb..6ea06ab1b7 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -10,10 +10,6 @@ namespace evmone { -namespace -{ -using JumpdestMap = std::vector; - JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size) { JumpdestMap m(code_size); @@ -23,11 +19,13 @@ JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size) if (op == OP_JUMPDEST) m[i] = true; else if (op >= OP_PUSH1 && op <= OP_PUSH32) - i += static_cast(op - OP_PUSH1 + 1); + i += op - size_t{OP_PUSH1 - 1}; } return m; } +namespace +{ const uint8_t* op_jump(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept { const auto dst = state.stack.pop(); @@ -96,11 +94,12 @@ evmc_result baseline_execute(evmc_vm* /*vm*/, const evmc_host_interface* host, evmc_host_context* ctx, evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept { + const auto jumpdest_map = build_jumpdest_map(code, code_size); auto state = std::make_unique(*msg, rev, *host, ctx, code, code_size); - return baseline_execute(*state); + return baseline_execute(*state, jumpdest_map); } -evmc_result baseline_execute(ExecutionState& state) noexcept +evmc_result baseline_execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept { const auto rev = state.rev; const auto code = state.code.data(); @@ -108,7 +107,6 @@ evmc_result baseline_execute(ExecutionState& state) noexcept const auto instruction_names = evmc_get_instruction_names_table(rev); const auto instruction_metrics = evmc_get_instruction_metrics_table(rev); - const auto jumpdest_map = build_jumpdest_map(code, code_size); const auto code_end = code + code_size; auto* pc = code; diff --git a/lib/evmone/baseline.hpp b/lib/evmone/baseline.hpp index b445ac1cdc..0e1bb152b9 100644 --- a/lib/evmone/baseline.hpp +++ b/lib/evmone/baseline.hpp @@ -5,13 +5,20 @@ #include "execution_state.hpp" #include +#include +#include namespace evmone { +using JumpdestMap = std::vector; + +/// Builds the bitmap of valid JUMPDEST locations in the code. +EVMC_EXPORT JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size); + /// Executes in Baseline interpreter using EVMC-compatible parameters. evmc_result baseline_execute(evmc_vm* vm, const evmc_host_interface* host, evmc_host_context* ctx, evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept; /// Executes in Baseline interpreter on the given external and initialized state. -evmc_result baseline_execute(ExecutionState& state) noexcept; +evmc_result baseline_execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept; } // namespace evmone diff --git a/test/bench/bench.cpp b/test/bench/bench.cpp index 4a2098a6b3..0c5c06425e 100644 --- a/test/bench/bench.cpp +++ b/test/bench/bench.cpp @@ -13,6 +13,7 @@ #if HAVE_STD_FILESYSTEM +#include #include namespace fs = std::filesystem; #else @@ -167,6 +168,13 @@ void register_benchmarks(const std::vector& benchmark_cases) })->Unit(kMicrosecond); } + if (registered_vms.count("baseline")) + { + RegisterBenchmark(("baseline/analyse/" + b.name).c_str(), [&b](State& state) { + build_jumpdest_map(state, b.code); + })->Unit(kMicrosecond); + } + for (const auto& input : b.inputs) { const auto case_name = diff --git a/test/bench/helpers.hpp b/test/bench/helpers.hpp index 625542a2bf..3dc27fdb18 100644 --- a/test/bench/helpers.hpp +++ b/test/bench/helpers.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace evmone::test { @@ -30,6 +31,21 @@ inline void analyse(benchmark::State& state, evmc_revision rev, bytes_view code) state.counters["rate"] = Counter(static_cast(bytes_analysed), Counter::kIsRate); } +inline void build_jumpdest_map(benchmark::State& state, bytes_view code) noexcept +{ + auto bytes_analysed = uint64_t{0}; + for (auto _ : state) + { + auto r = evmone::build_jumpdest_map(code.data(), code.size()); + benchmark::DoNotOptimize(r); + bytes_analysed += code.size(); + } + + using benchmark::Counter; + state.counters["size"] = Counter(static_cast(code.size())); + state.counters["rate"] = Counter(static_cast(bytes_analysed), Counter::kIsRate); +} + inline evmc::result execute( evmc::VM& vm, evmc_revision rev, int64_t gas_limit, bytes_view code, bytes_view input) noexcept { From 79679f552ab0db8cc09f7e524f15d9ca0b6c302e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 22 Apr 2021 13:40:00 +0200 Subject: [PATCH 2/2] cmake: Make intx public dependency of evmone --- lib/evmone/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/evmone/CMakeLists.txt b/lib/evmone/CMakeLists.txt index 3126e2d8ae..8e86589f73 100644 --- a/lib/evmone/CMakeLists.txt +++ b/lib/evmone/CMakeLists.txt @@ -23,7 +23,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 intx::intx PRIVATE evmc::instructions ethash::keccak) target_include_directories(evmone PUBLIC $$ )