Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The companion Leap PR for using a single execution context per wasm interface #1484

Merged
merged 7 commits into from
Aug 17, 2023
Merged
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
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/webassembly/eos-vm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct profile_config {

template<typename Backend>
class eos_vm_runtime : public eosio::chain::wasm_runtime_interface {
using context_t = typename Backend::template context<eos_vm_host_functions_t>;
public:
eos_vm_runtime();
std::unique_ptr<wasm_instantiated_module_interface> instantiate_module(const char* code_bytes, size_t code_size,
Expand All @@ -49,6 +50,7 @@ class eos_vm_runtime : public eosio::chain::wasm_runtime_interface {
private:
// todo: managing this will get more complicated with sync calls;
eos_vm_backend_t<Backend>* _bkend = nullptr; // non owning pointer to allow for immediate exit
context_t _exec_ctx;

template<typename Impl>
friend class eos_vm_instantiated_module;
Expand Down
12 changes: 9 additions & 3 deletions libraries/chain/webassembly/runtimes/eos-vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ class eos_vm_instantiated_module : public wasm_instantiated_module_interface {
_instantiated_module(std::move(mod)) {}

void apply(apply_context& context) override {
// Reset execution context (reused per thread)
_runtime->_exec_ctx.set_module(&(_instantiated_module->get_module()));
_instantiated_module->set_context(&_runtime->_exec_ctx);
_instantiated_module->reset_max_call_depth();
_instantiated_module->reset_max_pages();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was originally worried about the case where the apply options change between apply() calls right here.

For example reset_max_call_depth() sets the context's max call depth to initial_max_call_depth which was computed based on the options passed when the backend is created,
https://github.com/AntelopeIO/eos-vm/blob/8e1d571db99ff1eecd119c299b42886f72ef40b4/include/eosio/vm/backend.hpp#L177-L180
But the max call depth that should be configured at this point in time is what the current options protocol limits are.

But a few lines down from here,

if(context.control.is_builtin_activated(builtin_protocol_feature_t::configurable_wasm_limits)) {
const wasm_config& config = context.control.get_global_properties().wasm_configuration;
opts = {config.max_pages, config.max_call_depth};
}
auto fn = [&]() {
eosio::chain::webassembly::interface iface(context);
_runtime->_bkend->initialize(&iface, opts);

The important part is the initialize() call that,
https://github.com/AntelopeIO/eos-vm/blob/8e1d571db99ff1eecd119c299b42886f72ef40b4/include/eosio/vm/backend.hpp#L198-L203
seems to set up the context correctly for each apply once WASM_LIMITS2 is activated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your careful analysis.


_instantiated_module->set_wasm_allocator(&context.control.get_wasm_allocator());
_runtime->_bkend = _instantiated_module.get();
apply_options opts;
Expand Down Expand Up @@ -242,10 +248,10 @@ std::unique_ptr<wasm_instantiated_module_interface> eos_vm_runtime<Impl>::instan
std::unique_ptr<backend_t> bkend = nullptr;
#ifdef EOSIO_EOS_VM_JIT_RUNTIME_ENABLED
if constexpr (std::is_same_v<Impl, eosio::vm::jit>)
bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, true); // true -- JIT uses single parsing
bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, true, false); // true, false <--> single parsing, backend does not own execution context (execution context is reused per thread)
else
#endif
bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, false); // false -- Interpreter uses 2-passes parsing
bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, false, false); // false, false <--> 2-passes parsing, backend does not own execution context (execution context is reused per thread)
eos_vm_host_functions_t::resolve(bkend->get_module());
return std::make_unique<eos_vm_instantiated_module<Impl>>(this, std::move(bkend));
} catch(eosio::vm::exception& e) {
Expand All @@ -267,7 +273,7 @@ std::unique_ptr<wasm_instantiated_module_interface> eos_vm_profile_runtime::inst
wasm_code_ptr code((uint8_t*)code_bytes, code_size);
apply_options options = { .max_pages = 65536,
.max_call_depth = 0 };
std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, true); // true -- JIT uses single parsing
std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, true, false); // true, false <--> single parsing, backend does not own execution context (execution context is reused per thread)
eos_vm_host_functions_t::resolve(bkend->get_module());
return std::make_unique<eos_vm_profiling_module>(std::move(bkend), code_bytes, code_size);
} catch(eosio::vm::exception& e) {
Expand Down
2 changes: 1 addition & 1 deletion libraries/eos-vm