Skip to content

Commit 43e8ed5

Browse files
authored
Merge pull request #305 from ethereum/baseline_export_build_jumpdest_map
Export and benchmark build_jumpdest_map()
2 parents 1119215 + 79679f5 commit 43e8ed5

File tree

5 files changed

+39
-10
lines changed

5 files changed

+39
-10
lines changed

lib/evmone/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ add_library(evmone
2323
limits.hpp
2424
opcodes_helpers.h
2525
)
26-
target_link_libraries(evmone PUBLIC evmc::evmc PRIVATE intx::intx evmc::instructions ethash::keccak)
26+
target_link_libraries(evmone PUBLIC evmc::evmc intx::intx PRIVATE evmc::instructions ethash::keccak)
2727
target_include_directories(evmone PUBLIC
2828
$<BUILD_INTERFACE:${include_dir}>$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
2929
)

lib/evmone/baseline.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010

1111
namespace evmone
1212
{
13-
namespace
14-
{
15-
using JumpdestMap = std::vector<bool>;
16-
1713
JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size)
1814
{
1915
JumpdestMap m(code_size);
@@ -23,11 +19,13 @@ JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size)
2319
if (op == OP_JUMPDEST)
2420
m[i] = true;
2521
else if (op >= OP_PUSH1 && op <= OP_PUSH32)
26-
i += static_cast<size_t>(op - OP_PUSH1 + 1);
22+
i += op - size_t{OP_PUSH1 - 1};
2723
}
2824
return m;
2925
}
3026

27+
namespace
28+
{
3129
const uint8_t* op_jump(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept
3230
{
3331
const auto dst = state.stack.pop();
@@ -96,19 +94,19 @@ evmc_result baseline_execute(evmc_vm* /*vm*/, const evmc_host_interface* host,
9694
evmc_host_context* ctx, evmc_revision rev, const evmc_message* msg, const uint8_t* code,
9795
size_t code_size) noexcept
9896
{
97+
const auto jumpdest_map = build_jumpdest_map(code, code_size);
9998
auto state = std::make_unique<ExecutionState>(*msg, rev, *host, ctx, code, code_size);
100-
return baseline_execute(*state);
99+
return baseline_execute(*state, jumpdest_map);
101100
}
102101

103-
evmc_result baseline_execute(ExecutionState& state) noexcept
102+
evmc_result baseline_execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept
104103
{
105104
const auto rev = state.rev;
106105
const auto code = state.code.data();
107106
const auto code_size = state.code.size();
108107

109108
const auto instruction_names = evmc_get_instruction_names_table(rev);
110109
const auto instruction_metrics = evmc_get_instruction_metrics_table(rev);
111-
const auto jumpdest_map = build_jumpdest_map(code, code_size);
112110

113111
const auto code_end = code + code_size;
114112
auto* pc = code;

lib/evmone/baseline.hpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,20 @@
55

66
#include "execution_state.hpp"
77
#include <evmc/evmc.h>
8+
#include <evmc/utils.h>
9+
#include <vector>
810

911
namespace evmone
1012
{
13+
using JumpdestMap = std::vector<bool>;
14+
15+
/// Builds the bitmap of valid JUMPDEST locations in the code.
16+
EVMC_EXPORT JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size);
17+
1118
/// Executes in Baseline interpreter using EVMC-compatible parameters.
1219
evmc_result baseline_execute(evmc_vm* vm, const evmc_host_interface* host, evmc_host_context* ctx,
1320
evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept;
1421

1522
/// Executes in Baseline interpreter on the given external and initialized state.
16-
evmc_result baseline_execute(ExecutionState& state) noexcept;
23+
evmc_result baseline_execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept;
1724
} // namespace evmone

test/bench/bench.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414

1515
#if HAVE_STD_FILESYSTEM
16+
#include <evmone/baseline.hpp>
1617
#include <filesystem>
1718
namespace fs = std::filesystem;
1819
#else
@@ -167,6 +168,13 @@ void register_benchmarks(const std::vector<BenchmarkCase>& benchmark_cases)
167168
})->Unit(kMicrosecond);
168169
}
169170

171+
if (registered_vms.count("baseline"))
172+
{
173+
RegisterBenchmark(("baseline/analyse/" + b.name).c_str(), [&b](State& state) {
174+
build_jumpdest_map(state, b.code);
175+
})->Unit(kMicrosecond);
176+
}
177+
170178
for (const auto& input : b.inputs)
171179
{
172180
const auto case_name =

test/bench/helpers.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <benchmark/benchmark.h>
88
#include <evmc/evmc.hpp>
99
#include <evmone/analysis.hpp>
10+
#include <evmone/baseline.hpp>
1011

1112
namespace evmone::test
1213
{
@@ -30,6 +31,21 @@ inline void analyse(benchmark::State& state, evmc_revision rev, bytes_view code)
3031
state.counters["rate"] = Counter(static_cast<double>(bytes_analysed), Counter::kIsRate);
3132
}
3233

34+
inline void build_jumpdest_map(benchmark::State& state, bytes_view code) noexcept
35+
{
36+
auto bytes_analysed = uint64_t{0};
37+
for (auto _ : state)
38+
{
39+
auto r = evmone::build_jumpdest_map(code.data(), code.size());
40+
benchmark::DoNotOptimize(r);
41+
bytes_analysed += code.size();
42+
}
43+
44+
using benchmark::Counter;
45+
state.counters["size"] = Counter(static_cast<double>(code.size()));
46+
state.counters["rate"] = Counter(static_cast<double>(bytes_analysed), Counter::kIsRate);
47+
}
48+
3349
inline evmc::result execute(
3450
evmc::VM& vm, evmc_revision rev, int64_t gas_limit, bytes_view code, bytes_view input) noexcept
3551
{

0 commit comments

Comments
 (0)