mirror of
https://github.com/golang/go
synced 2024-11-19 13:34:45 -07:00
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>
This commit is contained in:
parent
80e5b52566
commit
e3a9dca7cc
@ -2804,15 +2804,15 @@ func isdirectiface(t *Type) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// type2IET returns "T" if t is a concrete 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.
|
// '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.
|
// 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) {
|
if isnilinter(t) {
|
||||||
return "E"
|
return 'E'
|
||||||
}
|
}
|
||||||
if Isinter(t) {
|
if Isinter(t) {
|
||||||
return "I"
|
return 'I'
|
||||||
}
|
}
|
||||||
return "T"
|
return 'T'
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
func walkexpr(np **Node, init nodesOrNodeListPtr) {
|
||||||
n := *np
|
n := *np
|
||||||
|
|
||||||
@ -689,8 +746,7 @@ opswitch:
|
|||||||
Warn("type assertion not inlined")
|
Warn("type assertion not inlined")
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := "assert" + type2IET(r.Left.Type) + "2" + type2IET(r.Type)
|
fn := syslook(assertFuncName(r.Left.Type, r.Type, false), 1)
|
||||||
fn := syslook(buf, 1)
|
|
||||||
substArgTypes(fn, r.Left.Type, r.Type)
|
substArgTypes(fn, r.Left.Type, r.Type)
|
||||||
|
|
||||||
n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1)
|
n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1)
|
||||||
@ -892,8 +948,8 @@ opswitch:
|
|||||||
oktype = ok.Type
|
oktype = ok.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
fromKind := type2IET(from.Type)
|
fromKind := from.Type.iet()
|
||||||
toKind := type2IET(t)
|
toKind := t.iet()
|
||||||
|
|
||||||
// Avoid runtime calls in a few cases of the form _, ok := i.(T).
|
// Avoid runtime calls in a few cases of the form _, ok := i.(T).
|
||||||
// This is faster and shorter and allows the corresponding assertX2X2
|
// This is faster and shorter and allows the corresponding assertX2X2
|
||||||
@ -901,13 +957,13 @@ opswitch:
|
|||||||
if isblank(nodeSeqFirst(n.List)) {
|
if isblank(nodeSeqFirst(n.List)) {
|
||||||
var fast *Node
|
var fast *Node
|
||||||
switch {
|
switch {
|
||||||
case fromKind == "E" && toKind == "T":
|
case fromKind == 'E' && toKind == 'T':
|
||||||
tab := Nod(OITAB, from, nil) // type:eface::tab:iface
|
tab := Nod(OITAB, from, nil) // type:eface::tab:iface
|
||||||
typ := Nod(OCONVNOP, typename(t), nil)
|
typ := Nod(OCONVNOP, typename(t), nil)
|
||||||
typ.Type = Ptrto(Types[TUINTPTR])
|
typ.Type = Ptrto(Types[TUINTPTR])
|
||||||
fast = Nod(OEQ, tab, typ)
|
fast = Nod(OEQ, tab, typ)
|
||||||
case fromKind == "I" && toKind == "E",
|
case fromKind == 'I' && toKind == 'E',
|
||||||
fromKind == "E" && toKind == "E":
|
fromKind == 'E' && toKind == 'E':
|
||||||
tab := Nod(OITAB, from, nil)
|
tab := Nod(OITAB, from, nil)
|
||||||
fast = Nod(ONE, nodnil(), tab)
|
fast = Nod(ONE, nodnil(), tab)
|
||||||
}
|
}
|
||||||
@ -932,8 +988,7 @@ opswitch:
|
|||||||
if Debug_typeassert > 0 {
|
if Debug_typeassert > 0 {
|
||||||
Warn("type assertion not inlined")
|
Warn("type assertion not inlined")
|
||||||
}
|
}
|
||||||
buf := "assert" + fromKind + "2" + toKind + "2"
|
fn := syslook(assertFuncName(from.Type, t, true), 1)
|
||||||
fn := syslook(buf, 1)
|
|
||||||
substArgTypes(fn, from.Type, t)
|
substArgTypes(fn, from.Type, t)
|
||||||
call := mkcall1(fn, oktype, init, typename(t), from, resptr)
|
call := mkcall1(fn, oktype, init, typename(t), from, resptr)
|
||||||
n = Nod(OAS, ok, call)
|
n = Nod(OAS, ok, call)
|
||||||
@ -1046,11 +1101,7 @@ opswitch:
|
|||||||
ll = list(ll, r)
|
ll = list(ll, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build name of function: convI2E etc.
|
fn := syslook(convFuncName(n.Left.Type, n.Type), 1)
|
||||||
// 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)
|
|
||||||
if !Isinter(n.Left.Type) {
|
if !Isinter(n.Left.Type) {
|
||||||
substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type)
|
substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user