summaryrefslogtreecommitdiff
path: root/libgo/go/fmt/print.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/fmt/print.go')
-rw-r--r--libgo/go/fmt/print.go31
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('}')