Repository: tetratelabs/wazero
Pull request #1351 (2023-04-10 12:12:44)

binary: makes NameMap and IndirectNameMap slices over values, not ptrs
```
goos: darwin
goarch: arm64
pkg: github.com/tetratelabs/wazero/internal/integration_test/bench
                                   │   old.txt   │              new.txt              │
                                   │   sec/op    │   sec/op     vs base              │
Compilation_sqlite3/compiler-10      215.3m ± 0%   215.6m ± 1%       ~ (p=0.318 n=7)
Compilation_sqlite3/interpreter-10   62.57m ± 1%   62.46m ± 1%       ~ (p=0.383 n=7)
geomean                              116.1m        116.0m       -0.00%

                                   │   old.txt    │              new.txt               │
                                   │     B/op     │     B/op      vs base              │
Compilation_sqlite3/compiler-10      51.97Mi ± 0%   51.97Mi ± 0%  -0.01% (p=0.017 n=7)
Compilation_sqlite3/interpreter-10   51.84Mi ± 0%   51.83Mi ± 0%  -0.02% (p=0.001 n=7)
geomean                              51.91Mi        51.90Mi       -0.01%

                                   │   old.txt   │              new.txt              │
                                   │  allocs/op  │  allocs/op   vs base              │
Compilation_sqlite3/compiler-10      39.07k ± 0%   37.54k ± 0%  -3.91% (p=0.001 n=7)
Compilation_sqlite3/interpreter-10   22.29k ± 0%   20.75k ± 0%  -6.88% (p=0.001 n=7)
geomean                              29.51k        27.91k       -5.41%

```


Patch:
diff --git a/internal/wasm/binary/names.go b/internal/wasm/binary/names.go
index e2249194..56fb96dc 100644
--- a/internal/wasm/binary/names.go
+++ b/internal/wasm/binary/names.go
@@ -93,7 +93,7 @@ func decodeFunctionNames(r *bytes.Reader) (wasm.NameMap, error) {
 		if err != nil {
 			return nil, err
 		}
-		result[i] = &wasm.NameAssoc{Index: functionIndex, Name: name}
+		result[i] = wasm.NameAssoc{Index: functionIndex, Name: name}
 	}
 	return result, nil
 }
@@ -127,9 +127,9 @@ func decodeLocalNames(r *bytes.Reader) (wasm.IndirectNameMap, error) {
 			if err != nil {
 				return nil, err
 			}
-			locals[j] = &wasm.NameAssoc{Index: localIndex, Name: name}
+			locals[j] = wasm.NameAssoc{Index: localIndex, Name: name}
 		}
-		result[i] = &wasm.NameMapAssoc{Index: functionIndex, NameMap: locals}
+		result[i] = wasm.NameMapAssoc{Index: functionIndex, NameMap: locals}
 	}
 	return result, nil
 }
diff --git a/internal/wasm/function_definition.go b/internal/wasm/function_definition.go
index 582f6a25..ba804c3f 100644
--- a/internal/wasm/function_definition.go
+++ b/internal/wasm/function_definition.go
@@ -80,7 +80,7 @@ func (m *Module) BuildFunctionDefinitions() {
 		funcIdx := d.index
 		var funcName string
 		for ; n < nLen; n++ {
-			next := functionNames[n]
+			next := &functionNames[n]
 			if next.Index > funcIdx {
 				break // we have function names, but starting at a later index.
 			} else if next.Index == funcIdx {
diff --git a/internal/wasm/host.go b/internal/wasm/host.go
index 9284a403..e0a1c190 100644
--- a/internal/wasm/host.go
+++ b/internal/wasm/host.go
@@ -145,7 +145,7 @@ func addFuncs(
 	}
 
 	funcCount := uint32(len(nameToFunc))
-	m.NameSection.FunctionNames = make([]*NameAssoc, 0, funcCount)
+	m.NameSection.FunctionNames = make([]NameAssoc, 0, funcCount)
 	m.FunctionSection = make([]Index, 0, funcCount)
 	m.CodeSection = make([]Code, 0, funcCount)
 
@@ -163,19 +163,19 @@ func addFuncs(
 			m.ExportSection = append(m.ExportSection, Export{Type: ExternTypeFunc, Name: export, Index: idx})
 			m.Exports[export] = &m.ExportSection[len(m.ExportSection)-1]
 		}
-		m.NameSection.FunctionNames = append(m.NameSection.FunctionNames, &NameAssoc{Index: idx, Name: hf.Name})
+		m.NameSection.FunctionNames = append(m.NameSection.FunctionNames, NameAssoc{Index: idx, Name: hf.Name})
 
 		if len(hf.ParamNames) > 0 {
-			localNames := &NameMapAssoc{Index: idx}
+			localNames := NameMapAssoc{Index: idx}
 			for i, n := range hf.ParamNames {
-				localNames.NameMap = append(localNames.NameMap, &NameAssoc{Index: Index(i), Name: n})
+				localNames.NameMap = append(localNames.NameMap, NameAssoc{Index: Index(i), Name: n})
 			}
 			m.NameSection.LocalNames = append(m.NameSection.LocalNames, localNames)
 		}
 		if len(hf.ResultNames) > 0 {
-			resultNames := &NameMapAssoc{Index: idx}
+			resultNames := NameMapAssoc{Index: idx}
 			for i, n := range hf.ResultNames {
-				resultNames.NameMap = append(resultNames.NameMap, &NameAssoc{Index: Index(i), Name: n})
+				resultNames.NameMap = append(resultNames.NameMap, NameAssoc{Index: Index(i), Name: n})
 			}
 			m.NameSection.ResultNames = append(m.NameSection.ResultNames, resultNames)
 		}
diff --git a/internal/wasm/module.go b/internal/wasm/module.go
index 0f731010..16a39630 100644
--- a/internal/wasm/module.go
+++ b/internal/wasm/module.go
@@ -589,14 +589,16 @@ func (m *ModuleInstance) buildGlobals(module *Module, funcRefResolver func(funcI
 }
 
 func paramNames(localNames IndirectNameMap, funcIdx uint32, paramLen int) []string {
-	for _, nm := range localNames {
+	for i := range localNames {
+		nm := &localNames[i]
 		// Only build parameter names if we have one for each.
 		if nm.Index != funcIdx || len(nm.NameMap) < paramLen {
 			continue
 		}
 
 		ret := make([]string, paramLen)
-		for _, p := range nm.NameMap {
+		for j := range nm.NameMap {
+			p := &nm.NameMap[j]
 			if int(p.Index) < paramLen {
 				ret[p.Index] = p.Name
 			}
@@ -867,7 +869,7 @@ type CustomSection struct {
 // Note: NameMap is unique by NameAssoc.Index, but NameAssoc.Name needn't be unique.
 // Note: When encoding in the Binary format, this must be ordered by NameAssoc.Index
 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-namemap
-type NameMap []*NameAssoc
+type NameMap []NameAssoc
 
 type NameAssoc struct {
 	Index Index
@@ -879,7 +881,7 @@ type NameAssoc struct {
 // Note: IndirectNameMap is unique by NameMapAssoc.Index, but NameMapAssoc.NameMap needn't be unique.
 // Note: When encoding in the Binary format, this must be ordered by NameMapAssoc.Index
 // https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-indirectnamemap
-type IndirectNameMap []*NameMapAssoc
+type IndirectNameMap []NameMapAssoc
 
 type NameMapAssoc struct {
 	Index   Index


Test patch:
diff --git a/builder_test.go b/builder_test.go
index bd073c99..7deee604 100644
--- a/builder_test.go
+++ b/builder_test.go
@@ -92,7 +92,7 @@ func TestNewHostModuleBuilder_Compile(t *testing.T) {
 				},
 				NameSection: &wasm.NameSection{
 					FunctionNames: wasm.NameMap{{Index: 0, Name: "get"}},
-					LocalNames:    []*wasm.NameMapAssoc{{Index: 0, NameMap: wasm.NameMap{{Index: 0, Name: "x"}}}},
+					LocalNames:    []wasm.NameMapAssoc{{Index: 0, NameMap: wasm.NameMap{{Index: 0, Name: "x"}}}},
 					ModuleName:    "host",
 				},
 			},
@@ -119,7 +119,7 @@ func TestNewHostModuleBuilder_Compile(t *testing.T) {
 				},
 				NameSection: &wasm.NameSection{
 					FunctionNames: wasm.NameMap{{Index: 0, Name: "get"}},
-					ResultNames:   []*wasm.NameMapAssoc{{Index: 0, NameMap: wasm.NameMap{{Index: 0, Name: "x"}}}},
+					ResultNames:   []wasm.NameMapAssoc{{Index: 0, NameMap: wasm.NameMap{{Index: 0, Name: "x"}}}},
 					ModuleName:    "host",
 				},
 			},
@@ -230,7 +230,7 @@ func TestNewHostModuleBuilder_Compile(t *testing.T) {
 				},
 				NameSection: &wasm.NameSection{
 					FunctionNames: wasm.NameMap{{Index: 0, Name: "get"}},
-					LocalNames:    []*wasm.NameMapAssoc{{Index: 0, NameMap: wasm.NameMap{{Index: 0, Name: "x"}}}},
+					LocalNames:    []wasm.NameMapAssoc{{Index: 0, NameMap: wasm.NameMap{{Index: 0, Name: "x"}}}},
 					ModuleName:    "host",
 				},
 			},
diff --git a/experimental/logging/log_listener_test.go b/experimental/logging/log_listener_test.go
index 5a5fd3de..2fb6f671 100644
--- a/experimental/logging/log_listener_test.go
+++ b/experimental/logging/log_listener_test.go
@@ -314,7 +314,7 @@ func toNameMap(names []string) wasm.NameMap {
 	}
 	var ret wasm.NameMap
 	for i, n := range names {
-		ret = append(ret, &wasm.NameAssoc{Index: wasm.Index(i), Name: n})
+		ret = append(ret, wasm.NameAssoc{Index: wasm.Index(i), Name: n})
 	}
 	return ret
 }
diff --git a/internal/testing/binaryencoding/names.go b/internal/testing/binaryencoding/names.go
index efa0bf0d..7a337020 100644
--- a/internal/testing/binaryencoding/names.go
+++ b/internal/testing/binaryencoding/names.go
@@ -82,7 +82,7 @@ func encodeNameSubsection(subsectionID uint8, content []byte) []byte {
 
 // encodeNameAssoc encodes the index and data prefixed by their size.
 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-namemap
-func encodeNameAssoc(na *wasm.NameAssoc) []byte {
+func encodeNameAssoc(na wasm.NameAssoc) []byte {
 	return append(leb128.EncodeUint32(na.Index), encodeSizePrefixed([]byte(na.Name))...)
 }
 
diff --git a/internal/testing/binaryencoding/names_test.go b/internal/testing/binaryencoding/names_test.go
index 54f92ff6..20c39c3b 100644
--- a/internal/testing/binaryencoding/names_test.go
+++ b/internal/testing/binaryencoding/names_test.go
@@ -131,12 +131,12 @@ func TestEncodeNameSubsection(t *testing.T) {
 }
 
 func TestEncodeNameAssoc(t *testing.T) {
-	na := &wasm.NameAssoc{Index: 1, Name: "hello"}
+	na := wasm.NameAssoc{Index: 1, Name: "hello"}
 	require.Equal(t, []byte{byte(na.Index), 5, 'h', 'e', 'l', 'l', 'o'}, encodeNameAssoc(na))
 }
 
 func TestEncodeNameMap(t *testing.T) {
-	na := &wasm.NameAssoc{Index: 1, Name: "hello"}
+	na := wasm.NameAssoc{Index: 1, Name: "hello"}
 	m := wasm.NameMap{na}
 	require.Equal(t, []byte{byte(1), byte(na.Index), 5, 'h', 'e', 'l', 'l', 'o'}, encodeNameMap(m))
 }
diff --git a/internal/testing/proxy/proxy.go b/internal/testing/proxy/proxy.go
index fda57e89..793f7b95 100644
--- a/internal/testing/proxy/proxy.go
+++ b/internal/testing/proxy/proxy.go
@@ -77,15 +77,15 @@ func NewModuleBinary(moduleName string, proxyTarget wazero.CompiledModule) []byt
 
 		proxyFuncIndex := cnt + funcNum
 		// Assigns the same params name as the imported one.
-		paramNames := &wasm.NameMapAssoc{Index: proxyFuncIndex}
+		paramNames := wasm.NameMapAssoc{Index: proxyFuncIndex}
 		for i, n := range def.ParamNames() {
-			paramNames.NameMap = append(paramNames.NameMap, &wasm.NameAssoc{Index: wasm.Index(i), Name: n})
+			paramNames.NameMap = append(paramNames.NameMap, wasm.NameAssoc{Index: wasm.Index(i), Name: n})
 		}
 		proxyModule.NameSection.LocalNames = append(proxyModule.NameSection.LocalNames, paramNames)
 
 		// Plus, assigns the same function name.
 		proxyModule.NameSection.FunctionNames = append(proxyModule.NameSection.FunctionNames,
-			&wasm.NameAssoc{Index: proxyFuncIndex, Name: name})
+			wasm.NameAssoc{Index: proxyFuncIndex, Name: name})
 
 		// Finally, exports the proxy function with the same name as the imported one.
 		proxyModule.ExportSection = append(proxyModule.ExportSection, wasm.Export{