From c4b5b91aa6fe405bc80a0b5635428fc6ba7d8ec7 Mon Sep 17 00:00:00 2001 From: Luca Burgazzoli Date: Wed, 26 Apr 2023 13:28:07 +0200 Subject: [PATCH] examples(allocation): free memory after unmarshalling a result from the guest (cgo, tinymem, bench) Signed-off-by: Luca Burgazzoli --- Makefile | 2 +- examples/allocation/tinygo-malloc/README.md | 22 ++++ examples/allocation/tinygo-malloc/greet.go | 117 +++++++++++++++++ .../allocation/tinygo-malloc/greet_test.go | 23 ++++ .../tinygo-malloc/testdata/greet.go | 123 ++++++++++++++++++ .../tinygo-malloc/testdata/greet.wasm | Bin 0 -> 54544 bytes examples/cli/testdata/cli.wasm | Bin 118720 -> 117707 bytes .../example/testdata/tinygo/cat.wasm | Bin 49325 -> 48954 bytes .../integration_test/vs/bench_allocation.go | 10 +- .../vs/bench_allocation_cgo.go | 89 +++++++++++++ .../vs/bench_allocation_tinymem.go | 89 +++++++++++++ .../vs/compiler/compiler_test.go | 16 +++ .../vs/interpreter/interpreter_test.go | 24 ++++ 13 files changed, 506 insertions(+), 9 deletions(-) create mode 100644 examples/allocation/tinygo-malloc/README.md create mode 100644 examples/allocation/tinygo-malloc/greet.go create mode 100644 examples/allocation/tinygo-malloc/greet_test.go create mode 100644 examples/allocation/tinygo-malloc/testdata/greet.go create mode 100755 examples/allocation/tinygo-malloc/testdata/greet.wasm create mode 100644 internal/integration_test/vs/bench_allocation_cgo.go create mode 100644 internal/integration_test/vs/bench_allocation_tinymem.go diff --git a/Makefile b/Makefile index 8e36cf8c516..150ff3f0097 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ build.examples.as: build.examples.zig: examples/allocation/zig/testdata/greet.wasm imports/wasi_snapshot_preview1/example/testdata/zig/cat.wasm imports/wasi_snapshot_preview1/testdata/zig/wasi.wasm @cd internal/testing/dwarftestdata/testdata/zig; zig build; mv zig-out/*/main.wasm ./ # Need DWARF custom sections. -tinygo_sources := examples/basic/testdata/add.go examples/allocation/tinygo/testdata/greet.go examples/cli/testdata/cli.go imports/wasi_snapshot_preview1/example/testdata/tinygo/cat.go +tinygo_sources := examples/basic/testdata/add.go examples/allocation/tinygo/testdata/greet.go examples/allocation/tinygo-malloc/testdata/greet.go examples/cli/testdata/cli.go imports/wasi_snapshot_preview1/example/testdata/tinygo/cat.go .PHONY: build.examples.tinygo build.examples.tinygo: $(tinygo_sources) @for f in $^; do \ diff --git a/examples/allocation/tinygo-malloc/README.md b/examples/allocation/tinygo-malloc/README.md new file mode 100644 index 00000000000..1e26da6547d --- /dev/null +++ b/examples/allocation/tinygo-malloc/README.md @@ -0,0 +1,22 @@ +## TinyGo allocation example + +This example shows how to pass strings in and out of a Wasm function defined +in TinyGo, built with `tinygo build -o greet.wasm -scheduler=none -target=wasi greet.go` + +```bash +$ go run greet.go cgo wazero +cgo: wazero! +``` + +```bash +$ go run greet.go tinymem wazero +tinymem: wazero! +``` + +Under the covers, [greet.go](testdata/greet.go) does a few things of interest: +* Uses `unsafe.Pointer` to change a Go pointer to a numeric type. +* Uses `unsafe.Slice` to build back a string from a pointer, len pair. +* Uses CGO to allocate and free memory if `cgo` is passed as first argument. +* Uses [TinyMem](https://github.com/tetratelabs/tinymem) alike to allocate and free memory if `tinymem` is passed as first argument. + +See https://wazero.io/languages/tinygo/ for more tips. diff --git a/examples/allocation/tinygo-malloc/greet.go b/examples/allocation/tinygo-malloc/greet.go new file mode 100644 index 00000000000..481c9af4ea9 --- /dev/null +++ b/examples/allocation/tinygo-malloc/greet.go @@ -0,0 +1,117 @@ +package main + +import ( + "context" + _ "embed" + "fmt" + "log" + "os" + + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/api" + "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" +) + +// greetWasm was compiled using `tinygo build -o greet.wasm -scheduler=none --no-debug -target=wasi greet.go` +// +//go:embed testdata/greet.wasm +var greetWasm []byte + +// main shows how to interact with a WebAssembly function that was compiled +// from TinyGo. +// +// See README.md for a full description. +func main() { + // Choose the context to use for function calls. + ctx := context.Background() + + // Create a new WebAssembly Runtime. + r := wazero.NewRuntime(ctx) + defer r.Close(ctx) // This closes everything this Runtime created. + + // Note: testdata/greet.go doesn't use WASI, but TinyGo needs it to + // implement functions such as panic. + wasi_snapshot_preview1.MustInstantiate(ctx, r) + + // Instantiate a WebAssembly module that imports the "log" function defined + // in "env" and exports "memory" and functions we'll use in this example. + mod, err := r.InstantiateWithConfig(ctx, greetWasm, wazero.NewModuleConfig().WithStdout(os.Stdout)) + if err != nil { + log.Panicln(err) + } + + var free api.Function + var malloc api.Function + var greeting api.Function + + switch os.Args[1] { + case "cgo": + // These are undocumented, but exported. See tinygo-org/tinygo#2788 + malloc = mod.ExportedFunction("malloc") + free = mod.ExportedFunction("free") + greeting = mod.ExportedFunction("greeting_cgo") + case "tinymem": + malloc = mod.ExportedFunction("malloc_tinymem") + free = mod.ExportedFunction("free_tinymem") + greeting = mod.ExportedFunction("greeting_tinymem") + default: + log.Panicf("unsupported allocation mode %s", os.Args[1]) + } + + // Let's use the argument to this main function in Wasm. + name := os.Args[2] + nameSize := uint64(len(name)) + + // Instead of an arbitrary memory offset, use TinyGo's allocator. Notice + // there is nothing string-specific in this allocation function. The same + // function could be used to pass binary serialized data to Wasm. + results, err := malloc.Call(ctx, nameSize) + if err != nil { + log.Panicln(err) + } + namePtr := results[0] + + // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. + // So, we have to free it when finished + defer func() { + _, err := free.Call(ctx, namePtr) + if err != nil { + log.Panicln(err) + } + }() + + // The pointer is a linear memory offset, which is where we write the name. + if !mod.Memory().Write(uint32(namePtr), []byte(name)) { + log.Panicf("Memory.Write(%d, %d) out of range of memory size %d", + namePtr, nameSize, mod.Memory().Size()) + } + + // Finally, we get the greeting message "greet" printed. This shows how to + // read-back something allocated by TinyGo. + ptrSize, err := greeting.Call(ctx, namePtr, nameSize) + if err != nil { + log.Panicln(err) + } + + greetingPtr := uint32(ptrSize[0] >> 32) + greetingSize := uint32(ptrSize[0]) + + // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. + // So, we have to free it when finished + if greetingPtr != 0 { + defer func() { + _, err := free.Call(ctx, uint64(greetingPtr)) + if err != nil { + log.Panicln(err) + } + }() + } + + // The pointer is a linear memory offset, which is where we write the name. + if bytes, ok := mod.Memory().Read(greetingPtr, greetingSize); !ok { + log.Panicf("Memory.Read(%d, %d) out of range of memory size %d", + greetingPtr, greetingSize, mod.Memory().Size()) + } else { + fmt.Println(string(bytes)) + } +} diff --git a/examples/allocation/tinygo-malloc/greet_test.go b/examples/allocation/tinygo-malloc/greet_test.go new file mode 100644 index 00000000000..e775d594c64 --- /dev/null +++ b/examples/allocation/tinygo-malloc/greet_test.go @@ -0,0 +1,23 @@ +package main + +import ( + "strings" + "testing" + + "github.com/tetratelabs/wazero/internal/testing/maintester" + "github.com/tetratelabs/wazero/internal/testing/require" +) + +// Test_main ensures the following will work: +// +// go run greet.go cgo|tinymem wazero +func Test_main(t *testing.T) { + t.Run("cgo", func(t *testing.T) { + stdout, _ := maintester.TestMain(t, main, "greet", "cgo", "wazero") + require.Equal(t, `cgo: wazero!`, strings.Replace(stdout, "\n", "", -1)) + }) + t.Run("tinymem", func(t *testing.T) { + stdout, _ := maintester.TestMain(t, main, "greet", "tinymem", "wazero") + require.Equal(t, `tinymem: wazero!`, strings.Replace(stdout, "\n", "", -1)) + }) +} diff --git a/examples/allocation/tinygo-malloc/testdata/greet.go b/examples/allocation/tinygo-malloc/testdata/greet.go new file mode 100644 index 00000000000..3987b612124 --- /dev/null +++ b/examples/allocation/tinygo-malloc/testdata/greet.go @@ -0,0 +1,123 @@ +package main + +import ( + "fmt" + "unsafe" +) + +// #include +import "C" + +// main is required for TinyGo to compile to Wasm. +func main() {} + +// greeting gets a greeting for the name. +func greeting(name string) string { + return fmt.Sprint(name, "!") +} + +// ptrToString returns a string from WebAssembly compatible numeric types +// representing its pointer and length. +func ptrToString(ptr uint32, size uint32) string { + // Get a slice view of the underlying bytes in the stream. + s := unsafe.Slice((*byte)(unsafe.Pointer(uintptr(ptr))), size) + return *(*string)(unsafe.Pointer(&s)) +} + +// +// CGO memory management +// + +// stringToPtr_cgo returns a pointer and size pair for the given string in a way +// compatible with WebAssembly numeric types. The pointer is not automatically +// managed by tinygo but must be freed by the host. +func stringToPtr_cgo(s string) (uint32, uint32) { + if len(s) == 0 { + return 0, 0 + } + + size := C.ulong(len(s)) + ptr := unsafe.Pointer(C.malloc(size)) + + copy(unsafe.Slice((*byte)(ptr), size), []byte(s)) + + return uint32(uintptr(ptr)), uint32(len(s)) +} + +// _greeting_cgo is a WebAssembly export that accepts a string pointer (linear memory +// offset) and returns a pointer/size pair packed into a uint64. +// +// Note: +// - This uses an uint64 instead of two result values for compatibility with +// WebAssembly 1.0. +// - The pointer returned by the function must be freed by the host using builtin free +// as it has been allocated using CGO malloc +// +//export greeting_cgo +func _greeting_cgo(ptr, size uint32) (ptrSize uint64) { + name := ptrToString(ptr, size) + g := greeting("cgo: " + name) + ptr, size = stringToPtr_cgo(g) + return (uint64(ptr) << uint64(32)) | uint64(size) +} + +// +// TinyMem alike memory management (https://github.com/tetratelabs/tinymem) +// + +var alivePointers = map[uintptr]interface{}{} + +// stringToPtr_tinymem returns a pointer and size pair for the given string in a way +// compatible with WebAssembly numeric types. The pointer is not automatically +// managed by tinygo but must be freed by the host. +func stringToPtr_tinymem(s string) (uint32, uint32) { + + ptr := _malloc_tinymem(uint32(len(s))) + unsafePtr := unsafe.Pointer(ptr) + size := len(s) + + copy(unsafe.Slice((*byte)(unsafePtr), size), []byte(s)) + + return uint32(ptr), uint32(len(s)) +} + +// _greeting_tinymem is a WebAssembly export that accepts a string pointer (linear memory +// offset) and returns a pointer/size pair packed into a uint64. +// +// Note: +// - This uses an uint64 instead of two result values for compatibility with +// WebAssembly 1.0. +// - The pointer returned by the function must be freed by the host by using free_tinymem +// as it has been kept alive in a local map +// +//export greeting_tinymem +func _greeting_tinymem(ptr, size uint32) (ptrSize uint64) { + name := ptrToString(ptr, size) + g := greeting("tinymem: " + name) + ptr, size = stringToPtr_tinymem(g) + return (uint64(ptr) << uint64(32)) | uint64(size) +} + +// malloc_tinymem is a WebAssembly export that allocates a pointer (linear memory offset) +// that can be used for the given size in bytes. +// +// Note: This is an ownership transfer, which means the caller must call free +// when finished. +// +//export malloc_tinymem +func _malloc_tinymem(size uint32) uintptr { + buf := make([]byte, size) + ptr := &buf[0] + unsafePtr := uintptr(unsafe.Pointer(ptr)) + alivePointers[unsafePtr] = buf + + return unsafePtr +} + +// free_tinymem frees a uintptr returned by keepaliveBuf or allocate, allowing it +// to be garbage collected. +// +//export free_tinymem +func _free_tinymem(ptr uint32) { + delete(alivePointers, uintptr(ptr)) +} diff --git a/examples/allocation/tinygo-malloc/testdata/greet.wasm b/examples/allocation/tinygo-malloc/testdata/greet.wasm new file mode 100755 index 0000000000000000000000000000000000000000..324fa09139f38d56abd384ac0a29a06f19e5336a GIT binary patch literal 54544 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 OlVC!BE|#SDQU4FWI_n4k literal 0 HcmV?d00001 diff --git a/examples/cli/testdata/cli.wasm b/examples/cli/testdata/cli.wasm index f38dbb3c76c373970c2f8a8e7b5756e67e385734..17fc332e0618affe5e779a2f77c8320af776b18d 100755 GIT binary patch delta 40164 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 ZA5bT!t2iEt>1|)r_UFkPFTueD{{iCJAk_c> delta 41143 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 delta 10285 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 diff --git a/internal/integration_test/vs/bench_allocation.go b/internal/integration_test/vs/bench_allocation.go index 290febb08a2..f0897f50357 100644 --- a/internal/integration_test/vs/bench_allocation.go +++ b/internal/integration_test/vs/bench_allocation.go @@ -24,7 +24,7 @@ func init() { allocationConfig = &RuntimeConfig{ ModuleName: "greet", ModuleWasm: allocationWasm, - FuncNames: []string{"malloc", "free", "greeting", "deallocate"}, + FuncNames: []string{"malloc", "free", "greet", "deallocate"}, NeedsWASI: true, // Needed for TinyGo LogFn: func(buf []byte) error { if !bytes.Equal(allocationResult, buf) { @@ -51,7 +51,7 @@ func allocationCall(m Module, _ int) error { } // Now, we can call "greeting", which reads the string we wrote to memory! - ptrSize, fnErr := m.CallI32I32_I64(testCtx, "greeting", namePtr, nameSize) + fnErr := m.CallI32I32_V(testCtx, "greet", namePtr, nameSize) if fnErr != nil { return fnErr } @@ -62,12 +62,6 @@ func allocationCall(m Module, _ int) error { return err } - // deallocate removes a uintptr from a map which stores a reference to the - // buffer ptrSize points to, allowing it to be garbage collected. - if err := m.CallI32_V(testCtx, "deallocate", uint32(ptrSize>>32)); err != nil { - return err - } - return nil } diff --git a/internal/integration_test/vs/bench_allocation_cgo.go b/internal/integration_test/vs/bench_allocation_cgo.go new file mode 100644 index 00000000000..54f0da33359 --- /dev/null +++ b/internal/integration_test/vs/bench_allocation_cgo.go @@ -0,0 +1,89 @@ +package vs + +import ( + "bytes" + _ "embed" + "fmt" + "testing" + + "github.com/tetratelabs/wazero/internal/testing/require" +) + +var ( + // allocationWasm is compiled from ../../../examples/allocation/tinygo-malloc/testdata/src/greet.go + // We can't use go:embed as it is outside this directory. Copying it isn't ideal due to size and drift. + allocationCGOWasmPath = "../../../examples/allocation/tinygo-malloc/testdata/greet.wasm" + allocationCGOWasm []byte + allocationCGOParam = "wazero" + allocationCGOResult = []byte("cgo: wazero!") + allocationCGOConfig *RuntimeConfig +) + +func init() { + allocationCGOWasm = readRelativeFile(allocationCGOWasmPath) + allocationCGOConfig = &RuntimeConfig{ + ModuleName: "greeting", + ModuleWasm: allocationCGOWasm, + FuncNames: []string{"malloc", "free", "greeting_cgo"}, + NeedsWASI: true, // Needed for TinyGo + LogFn: func(buf []byte) error { + if !bytes.Equal(allocationCGOResult, buf) { + return fmt.Errorf("expected %q, but was %q", allocationCGOResult, buf) + } + return nil + }, + } +} + +func AllocationCGOCall(m Module, _ int) error { + nameSize := uint32(len(allocationCGOParam)) + // Instead of an arbitrary memory offset, use TinyGo's allocator. Notice + // there is nothing string-specific in this allocation function. The same + // function could be used to pass binary serialized data to Wasm. + namePtr, err := m.CallI32_I32(testCtx, "malloc", nameSize) + if err != nil { + return err + } + + // The pointer is a linear memory offset, which is where we write the name. + if err = m.WriteMemory(namePtr, []byte(allocationCGOParam)); err != nil { + return err + } + + // Now, we can call "greeting", which reads the string we wrote to memory! + ptrSize, fnErr := m.CallI32I32_I64(testCtx, "greeting_cgo", namePtr, nameSize) + if fnErr != nil { + return fnErr + } + + // This pointer was allocated by TinyGo, but owned by Go, So, we have to + // deallocate it when finished + if err := m.CallI32_V(testCtx, "free", namePtr); err != nil { + return err + } + + // This pointer was allocated by TinyGo, but owned by Go, So, we have to + // deallocate it when finished + if err := m.CallI32_V(testCtx, "free", uint32(ptrSize>>32)); err != nil { + return err + } + + return nil +} + +func RunTestAllocationCGO(t *testing.T, runtime func() Runtime) { + testCall(t, runtime, allocationCGOConfig, testAllocationCGOCall) +} + +func testAllocationCGOCall(t *testing.T, m Module, instantiation, iteration int) { + err := AllocationCGOCall(m, iteration) + require.NoError(t, err, "instantiation[%d] iteration[%d] failed: %v", instantiation, iteration, err) +} + +func RunTestBenchmarkAllocationCGO_Call_CompilerFastest(t *testing.T, vsRuntime Runtime) { + runTestBenchmark_Call_CompilerFastest(t, allocationCGOConfig, "Allocation", AllocationCGOCall, vsRuntime) +} + +func RunBenchmarkAllocationCGO(b *testing.B, runtime func() Runtime) { + benchmark(b, runtime, allocationCGOConfig, AllocationCGOCall) +} diff --git a/internal/integration_test/vs/bench_allocation_tinymem.go b/internal/integration_test/vs/bench_allocation_tinymem.go new file mode 100644 index 00000000000..9df946b1c14 --- /dev/null +++ b/internal/integration_test/vs/bench_allocation_tinymem.go @@ -0,0 +1,89 @@ +package vs + +import ( + "bytes" + _ "embed" + "fmt" + "testing" + + "github.com/tetratelabs/wazero/internal/testing/require" +) + +var ( + // allocationWasm is compiled from ../../../examples/allocation/tinygo-malloc/testdata/src/greet.go + // We can't use go:embed as it is outside this directory. Copying it isn't ideal due to size and drift. + allocationTinyMemWasmPath = "../../../examples/allocation/tinygo-malloc/testdata/greet.wasm" + allocationTinyMemWasm []byte + allocationTinyMemParam = "wazero" + allocationTinyMemResult = []byte("tinymem: wazero!") + allocationTinyMemConfig *RuntimeConfig +) + +func init() { + allocationTinyMemWasm = readRelativeFile(allocationTinyMemWasmPath) + allocationTinyMemConfig = &RuntimeConfig{ + ModuleName: "greeting", + ModuleWasm: allocationTinyMemWasm, + FuncNames: []string{"malloc_tinymem", "free_tinymem", "greeting_tinymem"}, + NeedsWASI: true, // Needed for TinyGo + LogFn: func(buf []byte) error { + if !bytes.Equal(allocationTinyMemResult, buf) { + return fmt.Errorf("expected %q, but was %q", allocationTinyMemResult, buf) + } + return nil + }, + } +} + +func AllocationTinyMemCall(m Module, _ int) error { + nameSize := uint32(len(allocationTinyMemParam)) + // Instead of an arbitrary memory offset, use TinyGo's allocator. Notice + // there is nothing string-specific in this allocation function. The same + // function could be used to pass binary serialized data to Wasm. + namePtr, err := m.CallI32_I32(testCtx, "malloc_tinymem", nameSize) + if err != nil { + return err + } + + // The pointer is a linear memory offset, which is where we write the name. + if err = m.WriteMemory(namePtr, []byte(allocationTinyMemParam)); err != nil { + return err + } + + // Now, we can call "greeting", which reads the string we wrote to memory! + ptrSize, fnErr := m.CallI32I32_I64(testCtx, "greeting_tinymem", namePtr, nameSize) + if fnErr != nil { + return fnErr + } + + // This pointer was allocated by TinyGo, but owned by Go, So, we have to + // deallocate it when finished + if err := m.CallI32_V(testCtx, "free_tinymem", namePtr); err != nil { + return err + } + + // This pointer was allocated by TinyGo, but owned by Go, So, we have to + // deallocate it when finished + if err := m.CallI32_V(testCtx, "free_tinymem", uint32(ptrSize>>32)); err != nil { + return err + } + + return nil +} + +func RunTestAllocationTinyMem(t *testing.T, runtime func() Runtime) { + testCall(t, runtime, allocationTinyMemConfig, testAllocationTinyMemCall) +} + +func testAllocationTinyMemCall(t *testing.T, m Module, instantiation, iteration int) { + err := AllocationTinyMemCall(m, iteration) + require.NoError(t, err, "instantiation[%d] iteration[%d] failed: %v", instantiation, iteration, err) +} + +func RunTestBenchmarkAllocationTinyMem_Call_CompilerFastest(t *testing.T, vsRuntime Runtime) { + runTestBenchmark_Call_CompilerFastest(t, allocationTinyMemConfig, "Allocation", AllocationTinyMemCall, vsRuntime) +} + +func RunBenchmarkAllocationTinyMem(b *testing.B, runtime func() Runtime) { + benchmark(b, runtime, allocationTinyMemConfig, AllocationTinyMemCall) +} diff --git a/internal/integration_test/vs/compiler/compiler_test.go b/internal/integration_test/vs/compiler/compiler_test.go index 2c711f9e4d2..4ae38e9d16a 100644 --- a/internal/integration_test/vs/compiler/compiler_test.go +++ b/internal/integration_test/vs/compiler/compiler_test.go @@ -16,6 +16,22 @@ func BenchmarkAllocation(b *testing.B) { vs.RunBenchmarkAllocation(b, runtime) } +func TestAllocationCGO(t *testing.T) { + vs.RunTestAllocationCGO(t, runtime) +} + +func BenchmarkAllocationCGO(b *testing.B) { + vs.RunBenchmarkAllocationCGO(b, runtime) +} + +func TestAllocationTinyMem(t *testing.T) { + vs.RunTestAllocationTinyMem(t, runtime) +} + +func BenchmarkAllocationTinyMem(b *testing.B) { + vs.RunBenchmarkAllocationTinyMem(b, runtime) +} + func TestFactorial(t *testing.T) { vs.RunTestFactorial(t, runtime) } diff --git a/internal/integration_test/vs/interpreter/interpreter_test.go b/internal/integration_test/vs/interpreter/interpreter_test.go index 84090af8bff..3a574b54494 100644 --- a/internal/integration_test/vs/interpreter/interpreter_test.go +++ b/internal/integration_test/vs/interpreter/interpreter_test.go @@ -20,6 +20,30 @@ func TestBenchmarkAllocation_Call_CompilerFastest(t *testing.T) { vs.RunTestBenchmarkAllocation_Call_CompilerFastest(t, runtime()) } +func TestAllocationGCO(t *testing.T) { + vs.RunTestAllocationCGO(t, runtime) +} + +func BenchmarkAllocationCGO(b *testing.B) { + vs.RunBenchmarkAllocationCGO(b, runtime) +} + +func TestBenchmarkAllocationCGO_Call_CompilerFastest(t *testing.T) { + vs.RunTestBenchmarkAllocationCGO_Call_CompilerFastest(t, runtime()) +} + +func TestAllocationTinyMem(t *testing.T) { + vs.RunTestAllocationTinyMem(t, runtime) +} + +func BenchmarkAllocationTinyMem(b *testing.B) { + vs.RunBenchmarkAllocationTinyMem(b, runtime) +} + +func TestBenchmarkAllocationTinyMem_Call_CompilerFastest(t *testing.T) { + vs.RunTestBenchmarkAllocationTinyMem_Call_CompilerFastest(t, runtime()) +} + func TestFactorial(t *testing.T) { vs.RunTestFactorial(t, runtime) }