Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ struct controller_impl {
cfg.reversible_cache_size, false, cfg.db_map_mode, cfg.db_hugepage_paths ),
blog( cfg.blog ),
fork_db( cfg.state_dir ),
wasmif( cfg.wasm_runtime, cfg.eosvmoc_tierup, db, cfg.state_dir, cfg.eosvmoc_config ),
wasmif( cfg.wasm_runtime, cfg.eosvmoc_tierup, db, cfg.state_dir, cfg.eosvmoc_config, !cfg.profile_accounts.empty() ),
resource_limits( db, [&s]() { return s.get_deep_mind_logger(); }),
authorization( s, db ),
protocol_features( std::move(pfs), [&s]() { return s.get_deep_mind_logger(); } ),
Expand Down Expand Up @@ -3247,6 +3247,10 @@ bool controller::contracts_console()const {
return my->conf.contracts_console;
}

bool controller::is_profiling(account_name account) const {
return my->conf.profile_accounts.find(account) != my->conf.profile_accounts.end();
}

chain_id_type controller::get_chain_id()const {
return my->chain_id;
}
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ namespace eosio { namespace chain {
flat_set<account_name> resource_greylist;
flat_set<account_name> trusted_producers;
uint32_t greylist_limit = chain::config::maximum_elastic_resource_multiplier;

flat_set<account_name> profile_accounts;
};

enum class block_status {
Expand Down Expand Up @@ -289,6 +291,8 @@ namespace eosio { namespace chain {

bool contracts_console()const;

bool is_profiling(account_name name) const;

chain_id_type get_chain_id()const;

db_read_mode get_read_mode()const;
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/wasm_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace eosio { namespace chain {
}
}

wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config);
wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile);
~wasm_interface();

//call before dtor to skip what can be minutes of dtor overhead with some runtimes; can cause leaks
Expand Down
10 changes: 7 additions & 3 deletions libraries/chain/include/eosio/chain/wasm_interface_private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ namespace eosio { namespace chain {
};
#endif

wasm_interface_impl(wasm_interface::vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config) : db(d), wasm_runtime_time(vm) {
wasm_interface_impl(wasm_interface::vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile) : db(d), wasm_runtime_time(vm) {
#ifdef EOSIO_EOS_VM_RUNTIME_ENABLED
if(vm == wasm_interface::vm_type::eos_vm)
runtime_interface = std::make_unique<webassembly::eos_vm_runtime::eos_vm_runtime<eosio::vm::interpreter>>();
#endif
#ifdef EOSIO_EOS_VM_JIT_RUNTIME_ENABLED
if(vm == wasm_interface::vm_type::eos_vm_jit)
if(vm == wasm_interface::vm_type::eos_vm_jit && profile) {
eosio::vm::set_profile_interval_us(200);
runtime_interface = std::make_unique<webassembly::eos_vm_runtime::eos_vm_profile_runtime>();
}
if(vm == wasm_interface::vm_type::eos_vm_jit && !profile)
runtime_interface = std::make_unique<webassembly::eos_vm_runtime::eos_vm_runtime<eosio::vm::jit>>();
#endif
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
Expand All @@ -86,7 +90,7 @@ namespace eosio { namespace chain {
if(is_shutting_down)
for(wasm_cache_index::iterator it = wasm_instantiation_cache.begin(); it != wasm_instantiation_cache.end(); ++it)
wasm_instantiation_cache.modify(it, [](wasm_cache_entry& e) {
e.module.release();
e.module.release()->fast_shutdown();
});
}

Expand Down
63 changes: 32 additions & 31 deletions libraries/chain/include/eosio/chain/webassembly/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,64 +58,65 @@ namespace eosio { namespace chain {
};

// define the type converter for eosio
struct type_converter : public eosio::vm::type_converter<webassembly::interface, eosio::vm::execution_interface> {
using base_type = eosio::vm::type_converter<webassembly::interface, eosio::vm::execution_interface>;
using base_type::type_converter;
template<typename Interface>
struct basic_type_converter : public eosio::vm::type_converter<webassembly::interface, Interface> {
using base_type = eosio::vm::type_converter<webassembly::interface, Interface>;
using base_type::base_type;
using base_type::from_wasm;
using base_type::to_wasm;
using base_type::as_value;
using base_type::as_result;
using base_type::elem_type;
using base_type::get_host;

EOS_VM_FROM_WASM(memcpy_params, (void* dst, const void* src, vm::wasm_size_t size)) {
validate_pointer<char>(dst, size);
validate_pointer<char>(src, size);
validate_pointer<char>(dst, 1);
return { dst, src, size };

EOS_VM_FROM_WASM(bool, (uint32_t value)) { return value ? 1 : 0; }

EOS_VM_FROM_WASM(memcpy_params, (vm::wasm_ptr_t dst, vm::wasm_ptr_t src, vm::wasm_size_t size)) {
auto d = this->template validate_pointer<char>(dst, size);
auto s = this->template validate_pointer<char>(src, size);
this->template validate_pointer<char>(dst, 1);
return { d, s, size };
}

EOS_VM_FROM_WASM(memcmp_params, (const void* lhs, const void* rhs, vm::wasm_size_t size)) {
validate_pointer<char>(lhs, size);
validate_pointer<char>(rhs, size);
return { lhs, rhs, size };
EOS_VM_FROM_WASM(memcmp_params, (vm::wasm_ptr_t lhs, vm::wasm_ptr_t rhs, vm::wasm_size_t size)) {
auto l = this->template validate_pointer<char>(lhs, size);
auto r = this->template validate_pointer<char>(rhs, size);
return { l, r, size };
}

EOS_VM_FROM_WASM(memset_params, (void* dst, int32_t val, vm::wasm_size_t size)) {
validate_pointer<char>(dst, size);
validate_pointer<char>(dst, 1);
return { dst, val, size };
EOS_VM_FROM_WASM(memset_params, (vm::wasm_ptr_t dst, int32_t val, vm::wasm_size_t size)) {
auto d = this->template validate_pointer<char>(dst, size);
this->template validate_pointer<char>(dst, 1);
return { d, val, size };
}

template <typename T>
auto from_wasm(void* ptr) const
auto from_wasm(vm::wasm_ptr_t ptr) const
-> std::enable_if_t< std::is_pointer_v<T>,
vm::argument_proxy<T> > {
validate_pointer<std::remove_pointer_t<T>>(ptr, 1);
return {ptr};
auto p = this->template validate_pointer<std::remove_pointer_t<T>>(ptr, 1);
return {p};
}

template <typename T>
auto from_wasm(void* ptr, vm::tag<T> = {}) const
auto from_wasm(vm::wasm_ptr_t ptr, vm::tag<T> = {}) const
-> std::enable_if_t< vm::is_argument_proxy_type_v<T> &&
std::is_pointer_v<typename T::proxy_type>, T> {
if constexpr(T::is_legacy()) {
EOS_ASSERT(ptr != this->get_interface().get_memory(), wasm_execution_error, "references cannot be created for null pointers");
EOS_ASSERT(ptr != 0, wasm_execution_error, "references cannot be created for null pointers");
}
this->template validate_pointer<typename T::pointee_type>(ptr, 1);
return {ptr};
auto p = this->template validate_pointer<typename T::pointee_type>(ptr, 1);
return {p};
}

EOS_VM_FROM_WASM(null_terminated_ptr, (const void* ptr)) {
validate_null_terminated_pointer(ptr);
return {static_cast<const char*>(ptr)};
EOS_VM_FROM_WASM(null_terminated_ptr, (vm::wasm_ptr_t ptr)) {
auto p = this->validate_null_terminated_pointer(ptr);
return {static_cast<const char*>(p)};
}
EOS_VM_FROM_WASM(name, (uint64_t e)) { return name{e}; }
uint64_t to_wasm(name&& n) { return n.to_uint64_t(); }
EOS_VM_FROM_WASM(float32_t, (float f)) { return ::to_softfloat32(f); }
EOS_VM_FROM_WASM(float64_t, (double f)) { return ::to_softfloat64(f); }
};

using type_converter = basic_type_converter<eosio::vm::execution_interface>;

using eos_vm_host_functions_t = eosio::vm::registered_host_functions<webassembly::interface,
eosio::vm::execution_interface,
eosio::chain::type_converter>;
Expand Down
75 changes: 10 additions & 65 deletions libraries/chain/include/eosio/chain/webassembly/eos-vm-oc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,82 +185,27 @@ struct wasm_function_type_provider<Ret(Args...)> {

struct eos_vm_oc_execution_interface {
inline const auto& operand_from_back(std::size_t index) const { return *(os - index - 1); }
eosio::vm::native_value* os;
};

struct eos_vm_oc_type_converter : public eosio::vm::type_converter<webassembly::interface, eos_vm_oc_execution_interface> {
using base_type = eosio::vm::type_converter<webassembly::interface, eos_vm_oc_execution_interface>;
using base_type::type_converter;
using base_type::to_wasm;
using base_type::as_result;
using base_type::get_host;

EOS_VM_FROM_WASM(bool, (uint32_t value)) { return value ? 1 : 0; }

EOS_VM_FROM_WASM(memcpy_params, (vm::wasm_ptr_t dst, vm::wasm_ptr_t src, vm::wasm_size_t size)) {
auto d = array_ptr_impl<char>(dst, size);
auto s = array_ptr_impl<char>(src, size);
array_ptr_impl<char>(dst, 1);
return { d, s, size };
}

EOS_VM_FROM_WASM(memcmp_params, (vm::wasm_ptr_t lhs, vm::wasm_ptr_t rhs, vm::wasm_size_t size)) {
auto l = array_ptr_impl<char>(lhs, size);
auto r = array_ptr_impl<char>(rhs, size);
return { l, r, size };
}

EOS_VM_FROM_WASM(memset_params, (vm::wasm_ptr_t dst, int32_t val, vm::wasm_size_t size)) {
auto d = array_ptr_impl<char>(dst, size);
array_ptr_impl<char>(dst, 1);
return { d, val, size };
}

template <typename T>
auto from_wasm(vm::wasm_ptr_t ptr) const
-> std::enable_if_t< std::is_pointer_v<T>,
vm::argument_proxy<T> > {
void* p = array_ptr_impl<std::remove_pointer_t<T>>(ptr, 1);
return {p};
inline void* validate_pointer(vm::wasm_ptr_t ptr, vm::wasm_size_t len) const {
return array_ptr_impl<T>(ptr, len);
}

template <typename T>
auto from_wasm(vm::wasm_ptr_t ptr, vm::wasm_size_t len, vm::tag<T> = {}) const
-> std::enable_if_t<vm::is_span_type_v<T>, T> {
void* p = array_ptr_impl<typename T::value_type>(ptr, len);
return {static_cast<typename T::pointer>(p), len};
inline void* validate_null_terminated_pointer(vm::wasm_ptr_t ptr) const {
return null_terminated_ptr_impl(ptr);
}

template <typename T>
auto from_wasm(vm::wasm_ptr_t ptr, vm::wasm_size_t len, vm::tag<T> = {}) const
-> std::enable_if_t< vm::is_argument_proxy_type_v<T> &&
vm::is_span_type_v<typename T::proxy_type>, T> {
void* p = array_ptr_impl<typename T::pointee_type>(ptr, len);
return {p, len};
}
eosio::vm::native_value* os;
};

template <typename T>
auto from_wasm(vm::wasm_ptr_t ptr, vm::tag<T> = {}) const
-> std::enable_if_t< vm::is_argument_proxy_type_v<T> &&
std::is_pointer_v<typename T::proxy_type>, T> {
if constexpr(T::is_legacy()) {
EOS_ASSERT(ptr != 0, wasm_execution_error, "references cannot be created for null pointers");
}
void* p = array_ptr_impl<typename T::pointee_type>(ptr, 1);
return {p};
}
struct eos_vm_oc_type_converter : public basic_type_converter<eos_vm_oc_execution_interface> {
using base_type = basic_type_converter<eos_vm_oc_execution_interface>;
using base_type::basic_type_converter;
using base_type::to_wasm;

EOS_VM_FROM_WASM(null_terminated_ptr, (vm::wasm_ptr_t ptr)) {
auto p = null_terminated_ptr_impl(ptr);
return {static_cast<const char*>(p)};
}
EOS_VM_FROM_WASM(name, (uint64_t e)) { return name{e}; }
uint64_t to_wasm(name&& n) { return n.to_uint64_t(); }
vm::wasm_ptr_t to_wasm(void*&& ptr) {
return convert_native_to_wasm(static_cast<char*>(ptr));
}
EOS_VM_FROM_WASM(float32_t, (float f)) { return ::to_softfloat32(f); }
EOS_VM_FROM_WASM(float64_t, (double f)) { return ::to_softfloat64(f); }

template<typename T>
inline decltype(auto) as_value(const vm::native_value& val) const {
Expand Down
17 changes: 16 additions & 1 deletion libraries/chain/include/eosio/chain/webassembly/eos-vm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

//eos-vm includes
#include <eosio/vm/backend.hpp>
#include <eosio/vm/profile.hpp>

namespace eosio { namespace chain { namespace webassembly { namespace eos_vm_runtime {

Expand All @@ -18,7 +19,7 @@ struct apply_options;
}}

template <typename Impl>
using eos_vm_backend_t = eosio::vm::backend<eos_vm_host_functions_t, Impl, webassembly::eos_vm_runtime::apply_options>;
using eos_vm_backend_t = eosio::vm::backend<eos_vm_host_functions_t, Impl, webassembly::eos_vm_runtime::apply_options, vm::profile_instr_map>;

template <typename Options>
using eos_vm_null_backend_t = eosio::vm::backend<eos_vm_host_functions_t, eosio::vm::null_backend, Options>;
Expand All @@ -34,6 +35,10 @@ void validate(const bytes& code, const wasm_config& cfg, const whitelisted_intri

struct apply_options;

struct profile_config {
boost::container::flat_set<name> accounts_to_profile;
};

template<typename Backend>
class eos_vm_runtime : public eosio::chain::wasm_runtime_interface {
public:
Expand All @@ -54,4 +59,14 @@ class eos_vm_runtime : public eosio::chain::wasm_runtime_interface {
friend class eos_vm_instantiated_module;
};

class eos_vm_profile_runtime : public eosio::chain::wasm_runtime_interface {
public:
eos_vm_profile_runtime();
bool inject_module(IR::Module&) override;
std::unique_ptr<wasm_instantiated_module_interface> instantiate_module(const char* code_bytes, size_t code_size, std::vector<uint8_t>,
const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) override;

void immediately_exit_currently_running_module() override;
};

}}}}// eosio::chain::webassembly::eos_vm_runtime
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class apply_context;
class wasm_instantiated_module_interface {
public:
virtual void apply(apply_context& context) = 0;
virtual void fast_shutdown() {}

virtual ~wasm_instantiated_module_interface();
};
Expand Down
4 changes: 2 additions & 2 deletions libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

namespace eosio { namespace chain {

wasm_interface::wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config)
: my( new wasm_interface_impl(vm, eosvmoc_tierup, d, data_dir, eosvmoc_config) ) {}
wasm_interface::wasm_interface(vm_type vm, bool eosvmoc_tierup, const chainbase::database& d, const boost::filesystem::path data_dir, const eosvmoc::config& eosvmoc_config, bool profile)
: my( new wasm_interface_impl(vm, eosvmoc_tierup, d, data_dir, eosvmoc_config, profile) ) {}

wasm_interface::~wasm_interface() {}

Expand Down
Loading