ipn: remove use of reflect.MethodByName (#10652)

Using reflect.MethodByName disables some linked deadcode optimizations
and makes our binaries much bigger.
Difference before/after this commit:
```
-rwxr-xr-x  1 awly awly  30M Dec 19 15:28 tailscaled.after*
-rwxr-xr-x  1 awly awly  43M Dec 19 15:27 tailscaled.before*
```

Fixes #10627

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
Andrew Lytvynov 2023-12-20 09:12:26 -06:00 committed by GitHub
parent 09136e5995
commit 7a2eb22e94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 13 additions and 5 deletions

View File

@ -414,12 +414,20 @@ func (m *MaskedPrefs) Pretty() string {
continue
}
mpf := mpv.Field(i - 1)
prettyFn := mf.MethodByName("Pretty")
if !prettyFn.IsValid() {
panic(fmt.Sprintf("MaskedPrefs field %q is missing the Pretty method", name))
// This would be much simpler with reflect.MethodByName("Pretty"),
// but using MethodByName disables some linker optimizations and
// makes our binaries much larger. See
// https://github.com/tailscale/tailscale/issues/10627#issuecomment-1861211945
//
// Instead, have this explicit switch by field name to do type
// assertions.
switch name {
case "AutoUpdateSet":
p := mf.Interface().(AutoUpdatePrefsMask).Pretty(mpf.Interface().(AutoUpdatePrefs))
fmt.Fprintf(&sb, "%s={%s}", strings.TrimSuffix(name, "Set"), p)
default:
panic(fmt.Sprintf("unexpected MaskedPrefs field %q", name))
}
res := prettyFn.Call([]reflect.Value{mpf})
fmt.Fprintf(&sb, "%s={%s}", strings.TrimSuffix(name, "Set"), res[0].String())
}
}
sb.WriteString("}")