]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't allocate convX2X or assertX2X func names before syslook
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 4 Mar 2016 22:02:27 +0000 (22:02 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 4 Mar 2016 23:24:13 +0000 (23:24 +0000)
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>

src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/walk.go

index 0d2de3f2721a277e89139cbdb5823c6c7d01c13b..0dbea98ac2742fb52278e29d093c6ed421e8e58c 100644 (file)
@@ -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'
 }
index 9b5449bb6fae9b3be57440a72054ebb137d4ba49..ca77fc9fbfc193e1e482834afed52d333d5223c4 100644 (file)
@@ -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 {