Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

wasmtime: kill the stubs #8959

@pepyakin

Description

@pepyakin

Currently, we use runtime_interface machinery to declare the functions available to be called by the wasm substrate runtimes. Specifically from a declaration like the following a set of sp_wasm_interface::Function will be generated.

#[runtime_interface]
pub trait Foo {
    fn bar(&self, baz: &[u8]) -> Option<Vec<u8>> {
        // implementation is omitted 
    }
}

When we create a wasm runtime instance those will be passed to the instantiated module as imports.

Looking at the Function closely it has two parts:

  • functions to query name and signature
  • execute. This function must be invoked when the wasm instance calls the corresponding host function.

Note that execute takes a vector of wasm values. These parameters have the type sp_wasm_interface::Value. That is, a Substrate representation of wasm values. The concrete implementation must adapt these values from the engine specific to the Substrate ones.

Most importantly though, wasmtime jitted machine code doesn't operate on vectors of such Values. Instead, the machine code generated by wasmtime passes values as a normal machine code generated by a normal native compiler would. That means, wasmtime internally has to generate a thunk that adapts values passed via the ABI to the vector of [Val].

To give an idea how severe is the overhead, I ran a quick benchmark that would import 15k kusama blocks. Out of 47 seconds of runtime, at least 4s are spent within machinery related to conversions.

There is a way shave some of that time. wasmtime provides a Func::wrap. In nutshell, It takes a closure with reified types and under the hood generates an extern "C" function shim. That shim upon call will call the closure. The rustc/LLVM optimizer should be able to slim this down to be almost like a hand-rolled one. All without losing safety guarantees.

However, the problem is, at the place where we generate Funcs for the wasmtime (source) we only have Function and it's execute. It seems to me the part of the solution would involve changing runtime_interface so that it somehow knows how to generate the implementations for wasmtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    I7-refactorCode needs refactoring.I9-optimisationAn enhancement to provide better overall performance in terms of time-to-completion for a task.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions