Skip to content

Commit

Permalink
Merge pull request #305 from ethereum/baseline_export_build_jumpdest_map
Browse files Browse the repository at this point in the history
Export and benchmark build_jumpdest_map()
  • Loading branch information
chfast authored Apr 22, 2021
2 parents 1119215 + 79679f5 commit 43e8ed5
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 10 deletions.
2 changes: 1 addition & 1 deletion lib/evmone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
$<BUILD_INTERFACE:${include_dir}>$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
Expand Down
14 changes: 6 additions & 8 deletions lib/evmone/baseline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@

namespace evmone
{
namespace
{
using JumpdestMap = std::vector<bool>;

JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size)
{
JumpdestMap m(code_size);
Expand All @@ -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<size_t>(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();
Expand Down Expand Up @@ -96,19 +94,19 @@ 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<ExecutionState>(*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();
const auto code_size = state.code.size();

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;
Expand Down
9 changes: 8 additions & 1 deletion lib/evmone/baseline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@

#include "execution_state.hpp"
#include <evmc/evmc.h>
#include <evmc/utils.h>
#include <vector>

namespace evmone
{
using JumpdestMap = std::vector<bool>;

/// 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
8 changes: 8 additions & 0 deletions test/bench/bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@


#if HAVE_STD_FILESYSTEM
#include <evmone/baseline.hpp>
#include <filesystem>
namespace fs = std::filesystem;
#else
Expand Down Expand Up @@ -167,6 +168,13 @@ void register_benchmarks(const std::vector<BenchmarkCase>& 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 =
Expand Down
16 changes: 16 additions & 0 deletions test/bench/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <benchmark/benchmark.h>
#include <evmc/evmc.hpp>
#include <evmone/analysis.hpp>
#include <evmone/baseline.hpp>

namespace evmone::test
{
Expand All @@ -30,6 +31,21 @@ inline void analyse(benchmark::State& state, evmc_revision rev, bytes_view code)
state.counters["rate"] = Counter(static_cast<double>(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<double>(code.size()));
state.counters["rate"] = Counter(static_cast<double>(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
{
Expand Down

0 comments on commit 43e8ed5

Please sign in to comment.