Skip to content

Commit

Permalink
Create more generic baseline::CodeAnalysis type
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed May 4, 2021
1 parent cd69225 commit 77ec2ea
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 15 deletions.
17 changes: 9 additions & 8 deletions lib/evmone/baseline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

namespace evmone::baseline
{
JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size)
CodeAnalysis analyze(const uint8_t* code, size_t code_size)
{
// 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<int8_t>(op) <= OP_PUSH32 is always true and can be skipped.
static_assert(OP_PUSH32 == std::numeric_limits<int8_t>::max());

JumpdestMap map(code_size); // Allocate and init bitmap with zeros.
CodeAnalysis::JumpdestMap map(code_size); // Allocate and init bitmap with zeros.
for (size_t i = 0; i < code_size; ++i)
{
const auto op = code[i];
Expand All @@ -26,12 +26,13 @@ JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size)
else if (INTX_UNLIKELY(op == OP_JUMPDEST))
map[i] = true;
}
return map;
return CodeAnalysis{std::move(map)};
}

namespace
{
const uint8_t* op_jump(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept
const uint8_t* op_jump(
ExecutionState& state, const CodeAnalysis::JumpdestMap& jumpdest_map) noexcept
{
const auto dst = state.stack.pop();
if (dst >= jumpdest_map.size() || !jumpdest_map[static_cast<size_t>(dst)])
Expand Down Expand Up @@ -98,12 +99,12 @@ inline evmc_status_code check_requirements(const char* const* instruction_names,
evmc_result 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);
const auto jumpdest_map = analyze(code, code_size);
auto state = std::make_unique<ExecutionState>(*msg, rev, *host, ctx, code, code_size);
return execute(*state, jumpdest_map);
}

evmc_result execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept
evmc_result execute(ExecutionState& state, const CodeAnalysis& analysis) noexcept
{
const auto rev = state.rev;
const auto code = state.code.data();
Expand Down Expand Up @@ -381,12 +382,12 @@ evmc_result execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noex
}

case OP_JUMP:
pc = op_jump(state, jumpdest_map);
pc = op_jump(state, analysis.jumpdest_map);
continue;
case OP_JUMPI:
if (state.stack[1] != 0)
{
pc = op_jump(state, jumpdest_map);
pc = op_jump(state, analysis.jumpdest_map);
}
else
{
Expand Down
13 changes: 9 additions & 4 deletions lib/evmone/baseline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@

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

JumpdestMap jumpdest_map;
};

/// Builds the bitmap of valid JUMPDEST locations in the code.
EVMC_EXPORT JumpdestMap build_jumpdest_map(const uint8_t* code, size_t code_size);
/// Analyze the code to build the bitmap of valid JUMPDEST locations.
EVMC_EXPORT CodeAnalysis analyze(const uint8_t* code, size_t code_size);

/// Executes in Baseline interpreter using EVMC-compatible parameters.
evmc_result 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 execute(ExecutionState& state, const JumpdestMap& jumpdest_map) noexcept;
evmc_result execute(ExecutionState& state, const CodeAnalysis& analysis) noexcept;
} // namespace evmone::baseline
2 changes: 1 addition & 1 deletion test/bench/bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ void register_benchmarks(const std::vector<BenchmarkCase>& benchmark_cases)
if (registered_vms.count("baseline"))
{
RegisterBenchmark(("baseline/analyse/" + b.name).c_str(), [&b](State& state) {
build_jumpdest_map(state, b.code);
baseline_analyze(state, b.code);
})->Unit(kMicrosecond);
}

Expand Down
4 changes: 2 additions & 2 deletions test/bench/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ 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
inline void baseline_analyze(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());
auto r = evmone::baseline::analyze(code.data(), code.size());
benchmark::DoNotOptimize(r);
bytes_analysed += code.size();
}
Expand Down

0 comments on commit 77ec2ea

Please sign in to comment.