From 0f014554556cf4ae39e1b5b1829f7b8c48ce1e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 19 Aug 2022 19:15:48 +0200 Subject: [PATCH] Add option to disable "computed goto" dispatch Add EVMC option cgoto=no to disable the "computed goto" dispatch in Baseline. --- lib/evmone/baseline.cpp | 7 ++++--- lib/evmone/vm.cpp | 13 +++++++++++++ lib/evmone/vm.hpp | 4 ++++ test/bench/bench.cpp | 12 ++++++++++++ test/unittests/evm_fixture.cpp | 6 +++++- 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index d67bdc8344..984697497a 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -325,10 +325,11 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana else { #if EVMONE_CGOTO_SUPPORTED - dispatch_cgoto(cost_table, state); -#else - dispatch(cost_table, state, tracer); + if (vm.cgoto) + dispatch_cgoto(cost_table, state); + else #endif + dispatch(cost_table, state, tracer); } const auto gas_left = diff --git a/lib/evmone/vm.cpp b/lib/evmone/vm.cpp index f18782f5b0..3903d0e57d 100644 --- a/lib/evmone/vm.cpp +++ b/lib/evmone/vm.cpp @@ -47,6 +47,19 @@ evmc_set_option_result set_option(evmc_vm* c_vm, char const* c_name, char const* } return EVMC_SET_OPTION_INVALID_VALUE; } + else if (name == "cgoto") + { +#if EVMONE_CGOTO_SUPPORTED + if (value == "no") + { + vm.cgoto = false; + return EVMC_SET_OPTION_SUCCESS; + } + return EVMC_SET_OPTION_INVALID_VALUE; +#else + return EVMC_SET_OPTION_INVALID_NAME; +#endif + } else if (name == "trace") { vm.add_tracer(create_instruction_tracer(std::cerr)); diff --git a/lib/evmone/vm.hpp b/lib/evmone/vm.hpp index 9b221d27eb..98c8d39105 100644 --- a/lib/evmone/vm.hpp +++ b/lib/evmone/vm.hpp @@ -17,6 +17,10 @@ namespace evmone /// The evmone EVMC instance. class VM : public evmc_vm { +public: + bool cgoto = EVMONE_CGOTO_SUPPORTED; + +private: std::unique_ptr m_first_tracer; public: diff --git a/test/bench/bench.cpp b/test/bench/bench.cpp index 9125034d79..b92954b10e 100644 --- a/test/bench/bench.cpp +++ b/test/bench/bench.cpp @@ -150,10 +150,13 @@ void register_benchmarks(const std::vector& benchmark_cases) { evmc::VM* advanced_vm = nullptr; evmc::VM* baseline_vm = nullptr; + evmc::VM* basel_cg_vm = nullptr; if (const auto it = registered_vms.find("advanced"); it != registered_vms.end()) advanced_vm = &it->second; if (const auto it = registered_vms.find("baseline"); it != registered_vms.end()) baseline_vm = &it->second; + if (const auto it = registered_vms.find("bnocgoto"); it != registered_vms.end()) + basel_cg_vm = &it->second; for (const auto& b : benchmark_cases) { @@ -193,6 +196,14 @@ void register_benchmarks(const std::vector& benchmark_cases) })->Unit(kMicrosecond); } + if (basel_cg_vm != nullptr) + { + const auto name = "bnocgoto/execute/" + case_name; + RegisterBenchmark(name.c_str(), [&vm = *basel_cg_vm, &b, &input](State& state) { + bench_baseline_execute(state, vm, b.code, input.input, input.expected_output); + })->Unit(kMicrosecond); + } + for (auto& [vm_name, vm] : registered_vms) { const auto name = std::string{vm_name} + "/total/" + case_name; @@ -308,6 +319,7 @@ int main(int argc, char** argv) registered_vms["advanced"] = evmc::VM{evmc_create_evmone(), {{"O", "2"}}}; registered_vms["baseline"] = evmc::VM{evmc_create_evmone(), {{"O", "0"}}}; + registered_vms["bnocgoto"] = evmc::VM{evmc_create_evmone(), {{"O", "0"}, {"cgoto", "no"}}}; register_benchmarks(benchmark_cases); register_synthetic_benchmarks(); RunSpecifiedBenchmarks(); diff --git a/test/unittests/evm_fixture.cpp b/test/unittests/evm_fixture.cpp index c166583460..f439491f77 100644 --- a/test/unittests/evm_fixture.cpp +++ b/test/unittests/evm_fixture.cpp @@ -11,6 +11,7 @@ namespace { evmc::VM advanced_vm{evmc_create_evmone(), {{"O", "2"}}}; evmc::VM baseline_vm{evmc_create_evmone(), {{"O", "0"}}}; +evmc::VM bnocgoto_vm{evmc_create_evmone(), {{"O", "0"}, {"cgoto", "no"}}}; const char* print_vm_name(const testing::TestParamInfo& info) noexcept { @@ -18,9 +19,12 @@ const char* print_vm_name(const testing::TestParamInfo& info) noexcep return "advanced"; if (info.param == &baseline_vm) return "baseline"; + if (info.param == &bnocgoto_vm) + return "bnocgoto"; return "unknown"; } } // namespace -INSTANTIATE_TEST_SUITE_P(evmone, evm, testing::Values(&advanced_vm, &baseline_vm), print_vm_name); +INSTANTIATE_TEST_SUITE_P( + evmone, evm, testing::Values(&advanced_vm, &baseline_vm, &bnocgoto_vm), print_vm_name); } // namespace evmone::test