diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index 5ff49420c5..bde1679e84 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -12,21 +12,22 @@ namespace evmone::baseline { -CodeAnalysis analyze(const uint8_t* code, size_t code_size) +CodeAnalysis analyze(const uint8_t* code, size_t code_size, const EOF1Header& header) { // To find if op is any PUSH opcode (OP_PUSH1 <= op <= OP_PUSH32) // it can be noticed that OP_PUSH32 is INT8_MAX (0x7f) therefore // static_cast(op) <= OP_PUSH32 is always true and can be skipped. static_assert(OP_PUSH32 == std::numeric_limits::max()); + // TODO optimize to store only bits for code section CodeAnalysis::JumpdestMap map(code_size); // Allocate and init bitmap with zeros. - for (size_t i = 0; i < code_size; ++i) + for (auto i = header.code_begin(code); i < header.code_end(code, code_size); ++i) { - const auto op = code[i]; + const auto op = *i; if (static_cast(op) >= OP_PUSH1) // If any PUSH opcode (see explanation above). i += op - size_t{OP_PUSH1 - 1}; // Skip PUSH data. else if (INTX_UNLIKELY(op == OP_JUMPDEST)) - map[i] = true; + map[static_cast(i - code)] = true; } return CodeAnalysis{std::move(map)}; } @@ -788,7 +789,7 @@ evmc_result execute(evmc_vm* c_vm, const evmc_host_interface* host, evmc_host_co EOF1Header eof1_header; if (is_eof_code(code, code_size)) eof1_header = read_valid_eof1_header(code); - const auto jumpdest_map = analyze(code, code_size); + const auto jumpdest_map = analyze(code, code_size, eof1_header); auto state = std::make_unique(*msg, rev, *host, ctx, code, code_size); return execute(*vm, *state, eof1_header, jumpdest_map); } diff --git a/lib/evmone/baseline.hpp b/lib/evmone/baseline.hpp index e3022f1dcd..a75428b23e 100644 --- a/lib/evmone/baseline.hpp +++ b/lib/evmone/baseline.hpp @@ -23,7 +23,7 @@ struct CodeAnalysis }; /// Analyze the code to build the bitmap of valid JUMPDEST locations. -EVMC_EXPORT CodeAnalysis analyze(const uint8_t* code, size_t code_size); +EVMC_EXPORT CodeAnalysis analyze(const uint8_t* code, size_t code_size, const EOF1Header& header); /// Executes in Baseline interpreter using EVMC-compatible parameters. evmc_result execute(evmc_vm* vm, const evmc_host_interface* host, evmc_host_context* ctx, diff --git a/test/bench/helpers.hpp b/test/bench/helpers.hpp index cc5676b586..804260a74f 100644 --- a/test/bench/helpers.hpp +++ b/test/bench/helpers.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace evmone::test { @@ -37,7 +38,7 @@ inline void baseline_analyze(benchmark::State& state, bytes_view code) noexcept auto bytes_analysed = uint64_t{0}; for (auto _ : state) { - auto r = evmone::baseline::analyze(code.data(), code.size()); + auto r = evmone::baseline::analyze(code.data(), code.size(), {}); benchmark::DoNotOptimize(r); bytes_analysed += code.size(); }