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 <mdempsky@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 9b5449b..ca77fc9 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -397,6 +397,63 @@
}
}
+// 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 @@
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 @@
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 @@
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 @@
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 @@
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 {