From: Brad Fitzpatrick Date: Fri, 4 Mar 2016 22:02:27 +0000 (+0000) Subject: cmd/compile: don't allocate convX2X or assertX2X func names before syslook X-Git-Tag: go1.7beta1~1543 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e3a9dca7cc61d956656d443753545d5ff03a575f;p=gostls13.git cmd/compile: don't allocate convX2X or assertX2X func names before syslook Change-Id: Ib632ee7ac893750bec4cfe223745bca5f31900ab Reviewed-on: https://go-review.googlesource.com/20234 Reviewed-by: Matthew Dempsky Run-TryBot: Brad Fitzpatrick Reviewed-by: David Crawshaw TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 0d2de3f272..0dbea98ac2 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -2804,15 +2804,15 @@ func isdirectiface(t *Type) bool { return false } -// type2IET returns "T" if t is a concrete type, -// "I" if t is an interface type, and "E" if t is an empty interface type. +// iet returns 'T' if t is a concrete type, +// 'I' if t is an interface type, and 'E' if t is an empty interface type. // It is used to build calls to the conv* and assert* runtime routines. -func type2IET(t *Type) string { +func (t *Type) iet() byte { if isnilinter(t) { - return "E" + return 'E' } if Isinter(t) { - return "I" + return 'I' } - return "T" + return 'T' } diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 9b5449bb6f..ca77fc9fbf 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -397,6 +397,63 @@ func walkexprlistcheap(l nodesOrNodeList, init nodesOrNodeListPtr) { } } +// Build name of function: convI2E etc. +// Not all names are possible +// (e.g., we'll never generate convE2E or convE2I). +func convFuncName(from, to *Type) string { + tkind := to.iet() + switch from.iet() { + case 'I': + switch tkind { + case 'E': + return "convI2E" + case 'I': + return "convI2I" + } + case 'T': + switch tkind { + case 'E': + return "convT2E" + case 'I': + return "convT2I" + } + } + Fatalf("unknown conv func %c2%c", from.iet(), to.iet()) + panic("unreachable") +} + +// Build name of function: assertI2E etc. +// If with2suffix is true, the form ending in "2" is returned". +func assertFuncName(from, to *Type, with2suffix bool) string { + l := len("assertX2X2") + if !with2suffix { + l-- + } + tkind := to.iet() + switch from.iet() { + case 'E': + switch tkind { + case 'I': + return "assertE2I2"[:l] + case 'E': + return "assertE2E2"[:l] + case 'T': + return "assertE2T2"[:l] + } + case 'I': + switch tkind { + case 'I': + return "assertI2I2"[:l] + case 'E': + return "assertI2E2"[:l] + case 'T': + return "assertI2T2"[:l] + } + } + Fatalf("unknown assert func %c2%c", from.iet(), to.iet()) + panic("unreachable") +} + func walkexpr(np **Node, init nodesOrNodeListPtr) { n := *np @@ -689,8 +746,7 @@ opswitch: Warn("type assertion not inlined") } - buf := "assert" + type2IET(r.Left.Type) + "2" + type2IET(r.Type) - fn := syslook(buf, 1) + fn := syslook(assertFuncName(r.Left.Type, r.Type, false), 1) substArgTypes(fn, r.Left.Type, r.Type) n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1) @@ -892,8 +948,8 @@ opswitch: oktype = ok.Type } - fromKind := type2IET(from.Type) - toKind := type2IET(t) + fromKind := from.Type.iet() + toKind := t.iet() // Avoid runtime calls in a few cases of the form _, ok := i.(T). // This is faster and shorter and allows the corresponding assertX2X2 @@ -901,13 +957,13 @@ opswitch: if isblank(nodeSeqFirst(n.List)) { var fast *Node switch { - case fromKind == "E" && toKind == "T": + case fromKind == 'E' && toKind == 'T': tab := Nod(OITAB, from, nil) // type:eface::tab:iface typ := Nod(OCONVNOP, typename(t), nil) typ.Type = Ptrto(Types[TUINTPTR]) fast = Nod(OEQ, tab, typ) - case fromKind == "I" && toKind == "E", - fromKind == "E" && toKind == "E": + case fromKind == 'I' && toKind == 'E', + fromKind == 'E' && toKind == 'E': tab := Nod(OITAB, from, nil) fast = Nod(ONE, nodnil(), tab) } @@ -932,8 +988,7 @@ opswitch: if Debug_typeassert > 0 { Warn("type assertion not inlined") } - buf := "assert" + fromKind + "2" + toKind + "2" - fn := syslook(buf, 1) + fn := syslook(assertFuncName(from.Type, t, true), 1) substArgTypes(fn, from.Type, t) call := mkcall1(fn, oktype, init, typename(t), from, resptr) n = Nod(OAS, ok, call) @@ -1046,11 +1101,7 @@ opswitch: ll = list(ll, r) } - // Build name of function: convI2E etc. - // Not all names are possible - // (e.g., we'll never generate convE2E or convE2I). - buf := "conv" + type2IET(n.Left.Type) + "2" + type2IET(n.Type) - fn := syslook(buf, 1) + fn := syslook(convFuncName(n.Left.Type, n.Type), 1) if !Isinter(n.Left.Type) { substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type) } else {