From 211ee9f07cb454058fab5914117c19f33a7f64de Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 14 Jan 2020 16:37:42 -0800 Subject: [PATCH] cmd/compile: use a bytes.Buffer to format symbols MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit No significant compiler speed changes, but some minor memory savings. Passes toolstash-check. name old alloc/op new alloc/op delta Template 36.3MB ± 0% 36.2MB ± 0% -0.25% (p=0.008 n=5+5) Unicode 28.3MB ± 0% 28.2MB ± 0% -0.16% (p=0.008 n=5+5) GoTypes 122MB ± 0% 121MB ± 0% -0.39% (p=0.008 n=5+5) Compiler 568MB ± 0% 566MB ± 0% -0.21% (p=0.008 n=5+5) SSA 1.95GB ± 0% 1.95GB ± 0% -0.08% (p=0.008 n=5+5) Flate 22.8MB ± 0% 22.8MB ± 0% -0.21% (p=0.008 n=5+5) GoParser 28.0MB ± 0% 27.9MB ± 0% -0.38% (p=0.008 n=5+5) Reflect 78.6MB ± 0% 78.3MB ± 0% -0.33% (p=0.008 n=5+5) Tar 34.1MB ± 0% 34.1MB ± 0% -0.19% (p=0.008 n=5+5) XML 44.3MB ± 0% 44.2MB ± 0% -0.19% (p=0.008 n=5+5) [Geo mean] 79.9MB 79.7MB -0.24% name old allocs/op new allocs/op delta Template 363k ± 0% 359k ± 0% -1.21% (p=0.008 n=5+5) Unicode 329k ± 0% 326k ± 0% -0.90% (p=0.008 n=5+5) GoTypes 1.28M ± 0% 1.25M ± 0% -2.62% (p=0.008 n=5+5) Compiler 5.39M ± 0% 5.31M ± 0% -1.45% (p=0.008 n=5+5) SSA 18.1M ± 0% 17.9M ± 0% -0.78% (p=0.008 n=5+5) Flate 228k ± 0% 226k ± 0% -0.97% (p=0.008 n=5+5) GoParser 295k ± 0% 288k ± 0% -2.26% (p=0.008 n=5+5) Reflect 949k ± 0% 932k ± 0% -1.74% (p=0.008 n=5+5) Tar 336k ± 0% 332k ± 0% -1.12% (p=0.008 n=5+5) XML 417k ± 0% 413k ± 0% -1.10% (p=0.008 n=5+5) [Geo mean] 818k 806k -1.42% Change-Id: Ibdb94650a761edec17d8eba0abdfb70a8a495da9 Reviewed-on: https://go-review.googlesource.com/c/go/+/222920 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/gc/fmt.go | 84 ++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go index d7fc5416e2..80726d0557 100644 --- a/src/cmd/compile/internal/gc/fmt.go +++ b/src/cmd/compile/internal/gc/fmt.go @@ -585,28 +585,44 @@ s%^ ........*\]%&~%g s%~ %%g */ -func symfmt(s *types.Sym, flag FmtFlag, mode fmtMode) string { +func symfmt(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) { if s.Pkg != nil && flag&FmtShort == 0 { switch mode { case FErr: // This is for the user if s.Pkg == builtinpkg || s.Pkg == localpkg { - return s.Name + b.WriteString(s.Name) + return } // If the name was used by multiple packages, display the full path, if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 { - return fmt.Sprintf("%q.%s", s.Pkg.Path, s.Name) + fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name) + return } - return s.Pkg.Name + "." + s.Name + b.WriteString(s.Pkg.Name) + b.WriteByte('.') + b.WriteString(s.Name) + return case FDbg: - return s.Pkg.Name + "." + s.Name + b.WriteString(s.Pkg.Name) + b.WriteByte('.') + b.WriteString(s.Name) + return case FTypeIdName: - return s.Pkg.Name + "." + s.Name // dcommontype, typehash + // dcommontype, typehash + b.WriteString(s.Pkg.Name) + b.WriteByte('.') + b.WriteString(s.Name) + return case FTypeId: - return s.Pkg.Prefix + "." + s.Name // (methodsym), typesym, weaksym + // (methodsym), typesym, weaksym + b.WriteString(s.Pkg.Prefix) + b.WriteByte('.') + b.WriteString(s.Name) + return } } @@ -619,13 +635,15 @@ func symfmt(s *types.Sym, flag FmtFlag, mode fmtMode) string { } if mode == FDbg { - return fmt.Sprintf("@%q.%s", s.Pkg.Path, name) + fmt.Fprintf(b, "@%q.%s", s.Pkg.Path, name) + return } - return name + b.WriteString(name) + return } - return s.Name + b.WriteString(s.Name) } var basicnames = []string{ @@ -652,16 +670,16 @@ var basicnames = []string{ TBLANK: "blank", } -var tconvBufferPool = sync.Pool{ +var fmtBufferPool = sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, } func tconv(t *types.Type, flag FmtFlag, mode fmtMode) string { - buf := tconvBufferPool.Get().(*bytes.Buffer) + buf := fmtBufferPool.Get().(*bytes.Buffer) buf.Reset() - defer tconvBufferPool.Put(buf) + defer fmtBufferPool.Put(buf) tconv2(buf, t, flag, mode, nil) return types.InternString(buf.Bytes()) @@ -703,7 +721,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited case FTypeIdName, FTypeId: t = types.Types[t.Etype] default: - b.WriteString(sconv(t.Sym, FmtShort, mode)) + sconv2(b, t.Sym, FmtShort, mode) return } } @@ -718,15 +736,16 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited case FTypeId, FTypeIdName: if flag&FmtShort != 0 { if t.Vargen != 0 { - fmt.Fprintf(b, "%s·%d", sconv(t.Sym, FmtShort, mode), t.Vargen) + sconv2(b, t.Sym, FmtShort, mode) + fmt.Fprintf(b, "·%d", t.Vargen) return } - b.WriteString(sconv(t.Sym, FmtShort, mode)) + sconv2(b, t.Sym, FmtShort, mode) return } if mode == FTypeIdName { - b.WriteString(sconv(t.Sym, FmtUnsigned, mode)) + sconv2(b, t.Sym, FmtUnsigned, mode) return } @@ -736,7 +755,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited } } - b.WriteString(smodeString(t.Sym, mode)) + sconv2(b, t.Sym, 0, mode) return } @@ -845,13 +864,13 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited // Wrong interface definitions may have types lacking a symbol. break case types.IsExported(f.Sym.Name): - b.WriteString(sconv(f.Sym, FmtShort, mode)) + sconv2(b, f.Sym, FmtShort, mode) default: flag1 := FmtLeft if flag&FmtUnsigned != 0 { flag1 = FmtUnsigned } - b.WriteString(sconv(f.Sym, flag1, mode)) + sconv2(b, f.Sym, flag1, mode) } tconv2(b, f.Type, FmtShort, mode, visited) } @@ -941,7 +960,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited b.WriteString("undefined") if t.Sym != nil { b.WriteByte(' ') - b.WriteString(smodeString(t.Sym, mode)) + sconv2(b, t.Sym, 0, mode) } case TUNSAFEPTR: @@ -1731,9 +1750,30 @@ func sconv(s *types.Sym, flag FmtFlag, mode fmtMode) string { if s.Name == "_" { return "_" } + buf := fmtBufferPool.Get().(*bytes.Buffer) + buf.Reset() + defer fmtBufferPool.Put(buf) + + flag, mode = flag.update(mode) + symfmt(buf, s, flag, mode) + return types.InternString(buf.Bytes()) +} + +func sconv2(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) { + if flag&FmtLong != 0 { + panic("linksymfmt") + } + if s == nil { + b.WriteString("") + return + } + if s.Name == "_" { + b.WriteString("_") + return + } flag, mode = flag.update(mode) - return symfmt(s, flag, mode) + symfmt(b, s, flag, mode) } func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode fmtMode, visited map[*types.Type]int, funarg types.Funarg) { -- 2.50.0