diff --git a/common/bootcommand/boot_command.go b/common/bootcommand/boot_command.go index 1447a4337..b16864e42 100644 --- a/common/bootcommand/boot_command.go +++ b/common/bootcommand/boot_command.go @@ -13,6 +13,7 @@ import ( "sort" "strconv" "strings" + "sync" "time" "unicode" "unicode/utf8" @@ -981,7 +982,7 @@ type position struct { } func (p position) String() string { - return fmt.Sprintf("%d:%d [%d]", p.line, p.col, p.offset) + return strconv.Itoa(p.line) + ":" + strconv.Itoa(p.col) + " [" + strconv.Itoa(p.offset) + "]" } // savepoint stores all state required to go back to this point in the @@ -1445,13 +1446,24 @@ type Cloner interface { Clone() interface{} } +var statePool = &sync.Pool{ + New: func() interface{} { return make(storeDict) }, +} + +func (sd storeDict) Discard() { + for k := range sd { + delete(sd, k) + } + statePool.Put(sd) +} + // clone and return parser current state. func (p *parser) cloneState() storeDict { if p.debug { defer p.out(p.in("cloneState")) } - state := make(storeDict, len(p.cur.state)) + state := statePool.Get().(storeDict) for k, v := range p.cur.state { if c, ok := v.(Cloner); ok { state[k] = c.Clone() @@ -1468,6 +1480,7 @@ func (p *parser) restoreState(state storeDict) { if p.debug { defer p.out(p.in("restoreState")) } + p.cur.state.Discard() p.cur.state = state } @@ -1580,7 +1593,7 @@ func listJoin(list []string, sep string, lastSep string) string { case 1: return list[0] default: - return fmt.Sprintf("%s %s %s", strings.Join(list[:len(list)-1], sep), lastSep, list[len(list)-1]) + return strings.Join(list[:len(list)-1], sep) + " " + lastSep + " " + list[len(list)-1] } } @@ -1880,7 +1893,7 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { if lit.ignoreCase { ignoreCase = "i" } - val := fmt.Sprintf("%q%s", lit.val, ignoreCase) + val := string(strconv.AppendQuote([]byte{}, lit.val)) + ignoreCase // wrap 'lit.val' with double quotes start := p.pt for _, want := range lit.val { cur := p.pt.rn