diff options
Diffstat (limited to 'libgo/go/fmt/print.go')
-rw-r--r-- | libgo/go/fmt/print.go | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index f67f8056037..42fcd8b979b 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -6,6 +6,7 @@ package fmt import ( "errors" + "internal/fmtsort" "io" "os" "reflect" @@ -139,6 +140,16 @@ func newPrinter() *pp { // free saves used pp structs in ppFree; avoids an allocation per invocation. func (p *pp) free() { + // Proper usage of a sync.Pool requires each entry to have approximately + // the same memory cost. To obtain this property when the stored type + // contains a variably-sized buffer, we add a hard limit on the maximum buffer + // to place back in the pool. + // + // See https://golang.org/issue/23199 + if cap(p.buf) > 64<<10 { + return + } + p.buf = p.buf[:0] p.arg = nil p.value = reflect.Value{} @@ -477,7 +488,7 @@ func (p *pp) fmtBytes(v []byte, verb rune, typeString string) { p.buf.WriteByte(']') } case 's': - p.fmt.fmtS(string(v)) + p.fmt.fmtBs(v) case 'x': p.fmt.fmtBx(v, ldigits) case 'X': @@ -527,7 +538,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune) { } } -func (p *pp) catchPanic(arg interface{}, verb rune) { +func (p *pp) catchPanic(arg interface{}, verb rune, method string) { if err := recover(); err != nil { // If it's a nil pointer, just say "<nil>". The likeliest causes are a // Stringer that fails to guard against nil or a nil pointer for a @@ -550,6 +561,8 @@ func (p *pp) catchPanic(arg interface{}, verb rune) { p.buf.WriteString(percentBangString) p.buf.WriteRune(verb) p.buf.WriteString(panicString) + p.buf.WriteString(method) + p.buf.WriteString(" method: ") p.panicking = true p.printArg(err, 'v') p.panicking = false @@ -566,7 +579,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) { // Is it a Formatter? if formatter, ok := p.arg.(Formatter); ok { handled = true - defer p.catchPanic(p.arg, verb) + defer p.catchPanic(p.arg, verb, "Format") formatter.Format(p, verb) return } @@ -575,7 +588,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) { if p.fmt.sharpV { if stringer, ok := p.arg.(GoStringer); ok { handled = true - defer p.catchPanic(p.arg, verb) + defer p.catchPanic(p.arg, verb, "GoString") // Print the result of GoString unadorned. p.fmt.fmtS(stringer.GoString()) return @@ -593,13 +606,13 @@ func (p *pp) handleMethods(verb rune) (handled bool) { switch v := p.arg.(type) { case error: handled = true - defer p.catchPanic(p.arg, verb) + defer p.catchPanic(p.arg, verb, "Error") p.fmtString(v.Error(), verb) return case Stringer: handled = true - defer p.catchPanic(p.arg, verb) + defer p.catchPanic(p.arg, verb, "String") p.fmtString(v.String(), verb) return } @@ -743,8 +756,8 @@ func (p *pp) printValue(value reflect.Value, verb rune, depth int) { } else { p.buf.WriteString(mapString) } - keys := f.MapKeys() - for i, key := range keys { + sorted := fmtsort.Sort(f) + for i, key := range sorted.Key { if i > 0 { if p.fmt.sharpV { p.buf.WriteString(commaSpaceString) @@ -754,7 +767,7 @@ func (p *pp) printValue(value reflect.Value, verb rune, depth int) { } p.printValue(key, verb, depth+1) p.buf.WriteByte(':') - p.printValue(f.MapIndex(key), verb, depth+1) + p.printValue(sorted.Value[i], verb, depth+1) } if p.fmt.sharpV { p.buf.WriteByte('}') |