From dd907febac3e4371eaa7610064db47ecb9922368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 19 May 2021 11:20:19 +0200 Subject: [PATCH] squash! Support all depths in Histogram --- lib/evmone/tracing.cpp | 61 +++++++++++++++++++-------------- test/integration/CMakeLists.txt | 2 +- test/unittests/tracing_test.cpp | 14 ++++++-- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/lib/evmone/tracing.cpp b/lib/evmone/tracing.cpp index 497b060f0a..63cbd3d740 100644 --- a/lib/evmone/tracing.cpp +++ b/lib/evmone/tracing.cpp @@ -4,52 +4,61 @@ #include "tracing.hpp" #include +#include namespace evmone { namespace { +std::string get_name(const char* const* names, uint8_t opcode) +{ + const auto name = names[opcode]; + return (name != nullptr) ? name : "0x" + evmc::hex(opcode); +} + /// @see create_histogram_tracer() class HistogramTracer : public Tracer { - const uint8_t* m_code = nullptr; - int32_t m_depth = -1; - const char* const* m_opcode_names = nullptr; - uint32_t m_counts[256]{}; + struct Context + { + const int32_t depth; + const uint8_t* const code; + const char* const* const opcode_names; + uint32_t counts[256]{}; + + Context(int32_t _depth, const uint8_t* _code, const char* const* _opcode_names) noexcept + : depth{_depth}, code{_code}, opcode_names{_opcode_names} + {} + }; + + std::stack m_contexts; std::ostream& m_out; void on_execution_start( evmc_revision rev, const evmc_message& msg, bytes_view code) noexcept override { - m_code = code.data(); - m_depth = msg.depth; - if (m_depth == 0) - m_opcode_names = evmc_get_instruction_names_table(rev); + m_contexts.emplace(msg.depth, code.data(), evmc_get_instruction_names_table(rev)); } - void on_instruction_start(uint32_t pc) noexcept override { ++m_counts[m_code[pc]]; } + void on_instruction_start(uint32_t pc) noexcept override + { + auto& ctx = m_contexts.top(); + ++ctx.counts[ctx.code[pc]]; + } void on_execution_end(const evmc_result& /*result*/) noexcept override { - if (m_depth == 0) - { - m_out << "--- # HISTOGRAM\nopcode,count\n"; - for (size_t i = 0; i < std::size(m_counts); ++i) - { - if (m_counts[i] != 0) - { - if (const auto name = m_opcode_names[i]; name != nullptr) - m_out << name; - else - m_out << "0x" << evmc::hex(static_cast(i)); - m_out << ',' << m_counts[i] << '\n'; - } - } + const auto& ctx = m_contexts.top(); + const auto names = ctx.opcode_names; - m_opcode_names = nullptr; - m_depth = -1; - m_code = nullptr; + m_out << "--- # HISTOGRAM depth=" << ctx.depth << "\nopcode,count\n"; + for (size_t i = 0; i < std::size(ctx.counts); ++i) + { + if (ctx.counts[i] != 0) + m_out << get_name(names, static_cast(i)) << ',' << ctx.counts[i] << '\n'; } + + m_contexts.pop(); } public: diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index a6ac815911..6d26d4a664 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -10,7 +10,7 @@ if(EVMONE_LIB_TYPE STREQUAL SHARED_LIBRARY) add_test(NAME ${PREFIX}/histogram COMMAND $ --vm $,O=0,histogram run 6000808080800101010200) set_tests_properties( ${PREFIX}/histogram PROPERTIES PASS_REGULAR_EXPRESSION - "--- # HISTOGRAM + "--- # HISTOGRAM depth=0 opcode,count STOP,1 ADD,3 diff --git a/test/unittests/tracing_test.cpp b/test/unittests/tracing_test.cpp index 8f292f9cb5..018d54b015 100644 --- a/test/unittests/tracing_test.cpp +++ b/test/unittests/tracing_test.cpp @@ -103,7 +103,7 @@ TEST_F(tracing, histogram) trace_stream << '\n'; EXPECT_EQ(trace(add(0, 0)), R"( ---- # HISTOGRAM +--- # HISTOGRAM depth=0 opcode,count ADD,1 PUSH1,2 @@ -116,7 +116,7 @@ TEST_F(tracing, histogram_undefined_instruction) trace_stream << '\n'; EXPECT_EQ(trace(bytecode{"EF"}), R"( ---- # HISTOGRAM +--- # HISTOGRAM depth=0 opcode,count 0xef,1 )"); @@ -125,5 +125,13 @@ opcode,count TEST_F(tracing, histogram_internal_call) { vm.add_tracer(evmone::create_histogram_tracer(trace_stream)); - EXPECT_EQ(trace(add(0, 0), 1), ""); // No output on depth=1. + trace_stream << '\n'; + EXPECT_EQ(trace(push(0) + OP_DUP1 + OP_SWAP1 + OP_POP + OP_POP, 1), R"( +--- # HISTOGRAM depth=1 +opcode,count +POP,2 +PUSH1,1 +DUP1,1 +SWAP1,1 +)"); }