From c705b129b1d20c41a208d9818570698c4c3d2c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Wed, 17 May 2023 18:36:16 +0100 Subject: [PATCH 1/6] Wasmer: Delete module instance after use --- src/lib_scoru_wasm/fast/exec.ml | 2 ++ src/lib_wasmer/api_funcs_desc.ml | 3 +++ src/lib_wasmer/exports.ml | 27 ++++++++++++++++----------- src/lib_wasmer/tezos_wasmer.mli | 5 +++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/lib_scoru_wasm/fast/exec.ml b/src/lib_scoru_wasm/fast/exec.ml index 1d72df6e4e93..ddae356a21d2 100644 --- a/src/lib_scoru_wasm/fast/exec.ml +++ b/src/lib_scoru_wasm/fast/exec.ml @@ -95,6 +95,8 @@ let compute ~version ~reveal_builtins ~write_debug durable buffers = Lwt.finalize kernel_run (fun () -> (* Make sure that the instance is deleted regardless of whether [kernel_run] succeeds or not. *) + main_mem := None ; + Wasmer.Exports.delete exports ; Wasmer.Instance.delete instance ; Lwt.return_unit) in diff --git a/src/lib_wasmer/api_funcs_desc.ml b/src/lib_wasmer/api_funcs_desc.ml index e811a04d910d..2889fe1f543d 100644 --- a/src/lib_wasmer/api_funcs_desc.ml +++ b/src/lib_wasmer/api_funcs_desc.ml @@ -256,6 +256,9 @@ module Functions (S : FOREIGN) = struct foreign "wasm_extern_as_memory" (ptr Types.Extern.t @-> returning (ptr Types.Memory.t)) + + let delete = + foreign "wasm_extern_delete" (ptr Types.Extern.t @-> returning void) end (** Functions with the [wasm_extern_vec_] prefix *) diff --git a/src/lib_wasmer/exports.ml b/src/lib_wasmer/exports.ml index 56a15b3fc320..90bd0d145949 100644 --- a/src/lib_wasmer/exports.ml +++ b/src/lib_wasmer/exports.ml @@ -47,17 +47,22 @@ let from_instance inst = let exports = Module.exports inst.Instance.module_ |> Export_type_vector.to_list in - let externs = Extern_vector.empty () in - Functions.Instance.exports inst.instance (Ctypes.addr externs) ; - let externs = Extern_vector.to_list externs in - List.fold_right2 - (fun export extern tail -> - let name = Export_type.name export in - let kind = Export_type.type_ export |> Functions.Externtype.kind in - Resolver.add (name, kind) extern tail) - exports - externs - Resolver.empty + let externs_vec = Extern_vector.empty () in + Functions.Instance.exports inst.instance (Ctypes.addr externs_vec) ; + let externs = Extern_vector.to_list externs_vec in + let resolved = + List.fold_right2 + (fun export extern tail -> + let name = Export_type.name export in + let kind = Export_type.type_ export |> Functions.Externtype.kind in + Resolver.add (name, kind) extern tail) + exports + externs + Resolver.empty + in + resolved + +let delete = Resolver.iter (fun _ extern -> Functions.Extern.delete extern) exception Export_not_found of {name : string; kind : Unsigned.uint8} diff --git a/src/lib_wasmer/tezos_wasmer.mli b/src/lib_wasmer/tezos_wasmer.mli index ca241475d7ec..53bef3e462ad 100644 --- a/src/lib_wasmer/tezos_wasmer.mli +++ b/src/lib_wasmer/tezos_wasmer.mli @@ -187,6 +187,11 @@ module Exports : sig (** [from_intance instance] extracts the exports from the given instance. *) val from_instance : Instance.t -> t + (** [delete exports] cleans up the exports collection to free its associated + objects. You must not use previously extracted export objects after + calling call. *) + val delete : t -> unit + (** [fn exports name typ] looks for a function called [name] and type checks it against [typ]. *) val fn : t -> string -> 'a fn -> 'a -- GitLab From ad04240239d8c424e9c92d86043393636e8301b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Wed, 17 May 2023 19:52:57 +0100 Subject: [PATCH 2/6] Wasmer: Delete export types after use --- src/lib_wasmer/api_funcs_desc.ml | 5 +++++ src/lib_wasmer/exports.ml | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib_wasmer/api_funcs_desc.ml b/src/lib_wasmer/api_funcs_desc.ml index 2889fe1f543d..8d81674b6d44 100644 --- a/src/lib_wasmer/api_funcs_desc.ml +++ b/src/lib_wasmer/api_funcs_desc.ml @@ -419,6 +419,11 @@ module Functions (S : FOREIGN) = struct foreign "wasm_exporttype_type" (ptr Types.Exporttype.t @-> returning (ptr Types.Externtype.t)) + + let delete = + foreign + "wasm_exporttype_delete" + (ptr Types.Exporttype.t @-> returning void) end (** Functions with the [wasm_exporttype_vec_] prefix *) diff --git a/src/lib_wasmer/exports.ml b/src/lib_wasmer/exports.ml index 90bd0d145949..fa8f86adcfd3 100644 --- a/src/lib_wasmer/exports.ml +++ b/src/lib_wasmer/exports.ml @@ -44,9 +44,8 @@ type t = Types.Extern.t Ctypes.ptr Resolver.t let from_instance inst = - let exports = - Module.exports inst.Instance.module_ |> Export_type_vector.to_list - in + let exports_vec = Module.exports inst.Instance.module_ in + let exports = Export_type_vector.to_list exports_vec in let externs_vec = Extern_vector.empty () in Functions.Instance.exports inst.instance (Ctypes.addr externs_vec) ; let externs = Extern_vector.to_list externs_vec in @@ -60,6 +59,9 @@ let from_instance inst = externs Resolver.empty in + (* The exports vector is consumed in read-only or copying fashion, therefore + there are no references to it at this point. We can clean it up. *) + Functions.Exporttype_vec.delete (Ctypes.addr exports_vec) ; resolved let delete = Resolver.iter (fun _ extern -> Functions.Extern.delete extern) -- GitLab From 1d6b5a764808e5e92068c095f8783c49b61a681a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Wed, 17 May 2023 20:17:26 +0100 Subject: [PATCH 3/6] Wasmer: Delete function types after use --- src/lib_wasmer/api_funcs_desc.ml | 3 +++ src/lib_wasmer/function.ml | 11 +++++++++-- src/lib_wasmer/function_type.ml | 12 ++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/lib_wasmer/api_funcs_desc.ml b/src/lib_wasmer/api_funcs_desc.ml index 8d81674b6d44..8742e2536374 100644 --- a/src/lib_wasmer/api_funcs_desc.ml +++ b/src/lib_wasmer/api_funcs_desc.ml @@ -281,6 +281,9 @@ module Functions (S : FOREIGN) = struct foreign "wasm_functype_results" (ptr Types.Functype.t @-> returning (ptr Types.Valtype.Vec.t)) + + let delete = + foreign "wasm_functype_delete" (ptr Types.Functype.t @-> returning void) end (** Functions with the [wasm_func_] prefix *) diff --git a/src/lib_wasmer/function.ml b/src/lib_wasmer/function.ml index 693aeb14320c..a9b07ca51262 100644 --- a/src/lib_wasmer/function.ml +++ b/src/lib_wasmer/function.ml @@ -96,7 +96,11 @@ let create : type f. Store.t -> f Function_type.t -> f -> owned * (unit -> unit) let try_run = Ctypes.coerce Func_callback_maker.t Types.Func_callback.t try_run in - (Functions.Func.new_ store func_type try_run, free) + let owned = Functions.Func.new_ store func_type try_run in + (* [wasm_func_new] doesn't consume [func_type], therefore we must manually + garbage collect it. *) + Functions.Functype.delete func_type ; + (owned, free) let call_raw func inputs = let open Lwt.Syntax in @@ -160,6 +164,9 @@ let unpack_outputs results outputs = go results 0 Fun.id let call func typ = - Function_type.check_types typ (Functions.Func.type_ func) ; + let func_type = Functions.Func.type_ func in + Function_type.check_types typ func_type ; + (* Once the types have been checked, [func_type] can be deleted. *) + Functions.Functype.delete func_type ; let (Function_type.Function (params, results)) = typ in pack_inputs params func (unpack_outputs results) diff --git a/src/lib_wasmer/function_type.ml b/src/lib_wasmer/function_type.ml index bd19742b9224..88f3c828dcb5 100644 --- a/src/lib_wasmer/function_type.ml +++ b/src/lib_wasmer/function_type.ml @@ -97,10 +97,14 @@ type 'f t = Function : ('f, 'r Lwt.t) params * 'r results -> 'f t let to_owned (Function (params, results)) = let inputs = param_types params in let outputs = result_types results in - (* Note, this consumes the elements in [inputs] and [outputs] but not the - structures themselves. Ctypes will free the structures once they go out - of scope. *) - Functions.Functype.new_ (Ctypes.addr inputs) (Ctypes.addr outputs) + let type_ = + Functions.Functype.new_ (Ctypes.addr inputs) (Ctypes.addr outputs) + in + (* Since creating a new function type does not consume the input and output + type vectors, we can safely delete them here. *) + Functions.Valtype_vec.delete (Ctypes.addr inputs) ; + Functions.Valtype_vec.delete (Ctypes.addr outputs) ; + type_ exception Wrong_number_of_params of {expected : Unsigned.size_t; got : Unsigned.size_t} -- GitLab From c371811982c71bea526674108eb3c3c7277def12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Wed, 17 May 2023 20:30:33 +0100 Subject: [PATCH 4/6] Wasmer: Delete memory type after use --- src/lib_wasmer/exports.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib_wasmer/exports.ml b/src/lib_wasmer/exports.ml index fa8f86adcfd3..e3945fbeaf9e 100644 --- a/src/lib_wasmer/exports.ml +++ b/src/lib_wasmer/exports.ml @@ -111,6 +111,8 @@ let mem_of_extern extern = (Functions.Memory.data mem) (Functions.Memory.data_size mem |> Unsigned.Size_t.to_int) in + (* The memory type is no longer used after this, so we must delete it. *) + Functions.Memory_type.delete mem_type ; Memory.{raw; min; max} let mem exports name = -- GitLab From 7d2982303be2bdea8cba3f25172f63556b29ccd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Wed, 17 May 2023 21:05:00 +0100 Subject: [PATCH 5/6] Wasmer: Delete value types after use -- GitLab From 7650ffa947ab283277eae03d6db386e4d1f30d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Mon, 22 May 2023 14:57:48 +0100 Subject: [PATCH 6/6] Wasmer: Delete import types after use --- src/lib_wasmer/instance.ml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib_wasmer/instance.ml b/src/lib_wasmer/instance.ml index 9e22812b2f7d..1abbec20a242 100644 --- a/src/lib_wasmer/instance.ml +++ b/src/lib_wasmer/instance.ml @@ -67,9 +67,8 @@ let resolve_imports store modul resolver = | None -> raise (Unsatisfied_import {module_; name; kind}) | Some m -> Extern.to_extern store m in - let imports = - Module.imports modul |> Import_type_vector.to_array |> Array.map lookup - in + let imports_vec = Module.imports modul in + let imports = Import_type_vector.to_array imports_vec |> Array.map lookup in let externs = Extern_vector.from_array (Array.map fst imports) in let clean = Array.fold_left @@ -81,6 +80,9 @@ let resolve_imports store modul resolver = Fun.id imports in + (* There are no references to the imports vector after this, so we can + delete it. *) + Functions.Importtype_vec.delete (Ctypes.addr imports_vec) ; (externs, clean) let create store module_ externs = -- GitLab