1
0
mirror of https://github.com/golang/go synced 2024-11-26 05:07:59 -07:00

cmd/compile: make map functions ABI insensitive

Following CL 309029, this CL does the same thing for map
functions (mapaccess, mapassign, mapdelete).

For simplicity, always wrap "defer delete(m, k)". With
regabidefers enabled, this call is wrapped in a closure and the
rewriting happens automatically. Without regabidefers, it may not
be wrapped for certain key types, and then we'd need special
handling of the delete (because earlier the order pass does not
handle it). And we will turn on defer wrapping by default anyway.

Change-Id: I30663b1aa8e1d6f98e1fb81bf8c0c0ce607ab80b
Reviewed-on: https://go-review.googlesource.com/c/go/+/309510
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-04-12 16:12:20 -04:00
parent c19759aa48
commit 9913f821e2
8 changed files with 248 additions and 197 deletions

View File

@ -95,109 +95,109 @@ var runtimeDecls = [...]struct {
{"makemap_small", funcTag, 77},
{"mapaccess1", funcTag, 78},
{"mapaccess1_fast32", funcTag, 79},
{"mapaccess1_fast64", funcTag, 79},
{"mapaccess1_faststr", funcTag, 79},
{"mapaccess1_fat", funcTag, 80},
{"mapaccess2", funcTag, 81},
{"mapaccess2_fast32", funcTag, 82},
{"mapaccess2_fast64", funcTag, 82},
{"mapaccess2_faststr", funcTag, 82},
{"mapaccess2_fat", funcTag, 83},
{"mapaccess1_fast64", funcTag, 80},
{"mapaccess1_faststr", funcTag, 81},
{"mapaccess1_fat", funcTag, 82},
{"mapaccess2", funcTag, 83},
{"mapaccess2_fast32", funcTag, 84},
{"mapaccess2_fast64", funcTag, 85},
{"mapaccess2_faststr", funcTag, 86},
{"mapaccess2_fat", funcTag, 87},
{"mapassign", funcTag, 78},
{"mapassign_fast32", funcTag, 79},
{"mapassign_fast32ptr", funcTag, 79},
{"mapassign_fast64", funcTag, 79},
{"mapassign_fast64ptr", funcTag, 79},
{"mapassign_faststr", funcTag, 79},
{"mapiterinit", funcTag, 84},
{"mapdelete", funcTag, 84},
{"mapdelete_fast32", funcTag, 85},
{"mapdelete_fast64", funcTag, 85},
{"mapdelete_faststr", funcTag, 85},
{"mapiternext", funcTag, 86},
{"mapclear", funcTag, 87},
{"makechan64", funcTag, 89},
{"makechan", funcTag, 90},
{"chanrecv1", funcTag, 92},
{"chanrecv2", funcTag, 93},
{"chansend1", funcTag, 95},
{"mapassign_fast32ptr", funcTag, 88},
{"mapassign_fast64", funcTag, 80},
{"mapassign_fast64ptr", funcTag, 88},
{"mapassign_faststr", funcTag, 81},
{"mapiterinit", funcTag, 89},
{"mapdelete", funcTag, 89},
{"mapdelete_fast32", funcTag, 90},
{"mapdelete_fast64", funcTag, 91},
{"mapdelete_faststr", funcTag, 92},
{"mapiternext", funcTag, 93},
{"mapclear", funcTag, 94},
{"makechan64", funcTag, 96},
{"makechan", funcTag, 97},
{"chanrecv1", funcTag, 99},
{"chanrecv2", funcTag, 100},
{"chansend1", funcTag, 102},
{"closechan", funcTag, 30},
{"writeBarrier", varTag, 97},
{"typedmemmove", funcTag, 98},
{"typedmemclr", funcTag, 99},
{"typedslicecopy", funcTag, 100},
{"selectnbsend", funcTag, 101},
{"selectnbrecv", funcTag, 102},
{"selectsetpc", funcTag, 103},
{"selectgo", funcTag, 104},
{"writeBarrier", varTag, 104},
{"typedmemmove", funcTag, 105},
{"typedmemclr", funcTag, 106},
{"typedslicecopy", funcTag, 107},
{"selectnbsend", funcTag, 108},
{"selectnbrecv", funcTag, 109},
{"selectsetpc", funcTag, 110},
{"selectgo", funcTag, 111},
{"block", funcTag, 9},
{"makeslice", funcTag, 105},
{"makeslice64", funcTag, 106},
{"makeslicecopy", funcTag, 107},
{"growslice", funcTag, 109},
{"memmove", funcTag, 110},
{"memclrNoHeapPointers", funcTag, 111},
{"memclrHasPointers", funcTag, 111},
{"memequal", funcTag, 112},
{"memequal0", funcTag, 113},
{"memequal8", funcTag, 113},
{"memequal16", funcTag, 113},
{"memequal32", funcTag, 113},
{"memequal64", funcTag, 113},
{"memequal128", funcTag, 113},
{"f32equal", funcTag, 114},
{"f64equal", funcTag, 114},
{"c64equal", funcTag, 114},
{"c128equal", funcTag, 114},
{"strequal", funcTag, 114},
{"interequal", funcTag, 114},
{"nilinterequal", funcTag, 114},
{"memhash", funcTag, 115},
{"memhash0", funcTag, 116},
{"memhash8", funcTag, 116},
{"memhash16", funcTag, 116},
{"memhash32", funcTag, 116},
{"memhash64", funcTag, 116},
{"memhash128", funcTag, 116},
{"f32hash", funcTag, 116},
{"f64hash", funcTag, 116},
{"c64hash", funcTag, 116},
{"c128hash", funcTag, 116},
{"strhash", funcTag, 116},
{"interhash", funcTag, 116},
{"nilinterhash", funcTag, 116},
{"int64div", funcTag, 117},
{"uint64div", funcTag, 118},
{"int64mod", funcTag, 117},
{"uint64mod", funcTag, 118},
{"float64toint64", funcTag, 119},
{"float64touint64", funcTag, 120},
{"float64touint32", funcTag, 121},
{"int64tofloat64", funcTag, 122},
{"uint64tofloat64", funcTag, 123},
{"uint32tofloat64", funcTag, 124},
{"complex128div", funcTag, 125},
{"getcallerpc", funcTag, 126},
{"getcallersp", funcTag, 126},
{"makeslice", funcTag, 112},
{"makeslice64", funcTag, 113},
{"makeslicecopy", funcTag, 114},
{"growslice", funcTag, 116},
{"memmove", funcTag, 117},
{"memclrNoHeapPointers", funcTag, 118},
{"memclrHasPointers", funcTag, 118},
{"memequal", funcTag, 119},
{"memequal0", funcTag, 120},
{"memequal8", funcTag, 120},
{"memequal16", funcTag, 120},
{"memequal32", funcTag, 120},
{"memequal64", funcTag, 120},
{"memequal128", funcTag, 120},
{"f32equal", funcTag, 121},
{"f64equal", funcTag, 121},
{"c64equal", funcTag, 121},
{"c128equal", funcTag, 121},
{"strequal", funcTag, 121},
{"interequal", funcTag, 121},
{"nilinterequal", funcTag, 121},
{"memhash", funcTag, 122},
{"memhash0", funcTag, 123},
{"memhash8", funcTag, 123},
{"memhash16", funcTag, 123},
{"memhash32", funcTag, 123},
{"memhash64", funcTag, 123},
{"memhash128", funcTag, 123},
{"f32hash", funcTag, 123},
{"f64hash", funcTag, 123},
{"c64hash", funcTag, 123},
{"c128hash", funcTag, 123},
{"strhash", funcTag, 123},
{"interhash", funcTag, 123},
{"nilinterhash", funcTag, 123},
{"int64div", funcTag, 124},
{"uint64div", funcTag, 125},
{"int64mod", funcTag, 124},
{"uint64mod", funcTag, 125},
{"float64toint64", funcTag, 126},
{"float64touint64", funcTag, 127},
{"float64touint32", funcTag, 128},
{"int64tofloat64", funcTag, 129},
{"uint64tofloat64", funcTag, 130},
{"uint32tofloat64", funcTag, 131},
{"complex128div", funcTag, 132},
{"getcallerpc", funcTag, 133},
{"getcallersp", funcTag, 133},
{"racefuncenter", funcTag, 31},
{"racefuncexit", funcTag, 9},
{"raceread", funcTag, 31},
{"racewrite", funcTag, 31},
{"racereadrange", funcTag, 127},
{"racewriterange", funcTag, 127},
{"msanread", funcTag, 127},
{"msanwrite", funcTag, 127},
{"msanmove", funcTag, 128},
{"checkptrAlignment", funcTag, 129},
{"checkptrArithmetic", funcTag, 131},
{"libfuzzerTraceCmp1", funcTag, 132},
{"libfuzzerTraceCmp2", funcTag, 133},
{"libfuzzerTraceCmp4", funcTag, 134},
{"libfuzzerTraceCmp8", funcTag, 135},
{"libfuzzerTraceConstCmp1", funcTag, 132},
{"libfuzzerTraceConstCmp2", funcTag, 133},
{"libfuzzerTraceConstCmp4", funcTag, 134},
{"libfuzzerTraceConstCmp8", funcTag, 135},
{"racereadrange", funcTag, 134},
{"racewriterange", funcTag, 134},
{"msanread", funcTag, 134},
{"msanwrite", funcTag, 134},
{"msanmove", funcTag, 135},
{"checkptrAlignment", funcTag, 136},
{"checkptrArithmetic", funcTag, 138},
{"libfuzzerTraceCmp1", funcTag, 139},
{"libfuzzerTraceCmp2", funcTag, 140},
{"libfuzzerTraceCmp4", funcTag, 141},
{"libfuzzerTraceCmp8", funcTag, 142},
{"libfuzzerTraceConstCmp1", funcTag, 139},
{"libfuzzerTraceConstCmp2", funcTag, 140},
{"libfuzzerTraceConstCmp4", funcTag, 141},
{"libfuzzerTraceConstCmp8", funcTag, 142},
{"x86HasPOPCNT", varTag, 6},
{"x86HasSSE41", varTag, 6},
{"x86HasFMA", varTag, 6},
@ -220,7 +220,7 @@ func params(tlist ...*types.Type) []*types.Field {
}
func runtimeTypes() []*types.Type {
var typs [136]*types.Type
var typs [143]*types.Type
typs[0] = types.ByteType
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[types.TANY]
@ -300,62 +300,69 @@ func runtimeTypes() []*types.Type {
typs[76] = newSig(params(typs[1], typs[15], typs[3]), params(typs[74]))
typs[77] = newSig(nil, params(typs[74]))
typs[78] = newSig(params(typs[1], typs[74], typs[3]), params(typs[3]))
typs[79] = newSig(params(typs[1], typs[74], typs[2]), params(typs[3]))
typs[80] = newSig(params(typs[1], typs[74], typs[3], typs[1]), params(typs[3]))
typs[81] = newSig(params(typs[1], typs[74], typs[3]), params(typs[3], typs[6]))
typs[82] = newSig(params(typs[1], typs[74], typs[2]), params(typs[3], typs[6]))
typs[83] = newSig(params(typs[1], typs[74], typs[3], typs[1]), params(typs[3], typs[6]))
typs[84] = newSig(params(typs[1], typs[74], typs[3]), nil)
typs[85] = newSig(params(typs[1], typs[74], typs[2]), nil)
typs[86] = newSig(params(typs[3]), nil)
typs[87] = newSig(params(typs[1], typs[74]), nil)
typs[88] = types.NewChan(typs[2], types.Cboth)
typs[89] = newSig(params(typs[1], typs[22]), params(typs[88]))
typs[90] = newSig(params(typs[1], typs[15]), params(typs[88]))
typs[91] = types.NewChan(typs[2], types.Crecv)
typs[92] = newSig(params(typs[91], typs[3]), nil)
typs[93] = newSig(params(typs[91], typs[3]), params(typs[6]))
typs[94] = types.NewChan(typs[2], types.Csend)
typs[95] = newSig(params(typs[94], typs[3]), nil)
typs[96] = types.NewArray(typs[0], 3)
typs[97] = types.NewStruct(types.NoPkg, []*types.Field{types.NewField(src.NoXPos, Lookup("enabled"), typs[6]), types.NewField(src.NoXPos, Lookup("pad"), typs[96]), types.NewField(src.NoXPos, Lookup("needed"), typs[6]), types.NewField(src.NoXPos, Lookup("cgo"), typs[6]), types.NewField(src.NoXPos, Lookup("alignme"), typs[24])})
typs[98] = newSig(params(typs[1], typs[3], typs[3]), nil)
typs[99] = newSig(params(typs[1], typs[3]), nil)
typs[100] = newSig(params(typs[1], typs[3], typs[15], typs[3], typs[15]), params(typs[15]))
typs[101] = newSig(params(typs[94], typs[3]), params(typs[6]))
typs[102] = newSig(params(typs[3], typs[91]), params(typs[6], typs[6]))
typs[103] = newSig(params(typs[71]), nil)
typs[104] = newSig(params(typs[1], typs[1], typs[71], typs[15], typs[15], typs[6]), params(typs[15], typs[6]))
typs[105] = newSig(params(typs[1], typs[15], typs[15]), params(typs[7]))
typs[106] = newSig(params(typs[1], typs[22], typs[22]), params(typs[7]))
typs[107] = newSig(params(typs[1], typs[15], typs[15], typs[7]), params(typs[7]))
typs[108] = types.NewSlice(typs[2])
typs[109] = newSig(params(typs[1], typs[108], typs[15]), params(typs[108]))
typs[110] = newSig(params(typs[3], typs[3], typs[5]), nil)
typs[111] = newSig(params(typs[7], typs[5]), nil)
typs[112] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
typs[113] = newSig(params(typs[3], typs[3]), params(typs[6]))
typs[114] = newSig(params(typs[7], typs[7]), params(typs[6]))
typs[115] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
typs[116] = newSig(params(typs[7], typs[5]), params(typs[5]))
typs[117] = newSig(params(typs[22], typs[22]), params(typs[22]))
typs[118] = newSig(params(typs[24], typs[24]), params(typs[24]))
typs[119] = newSig(params(typs[20]), params(typs[22]))
typs[120] = newSig(params(typs[20]), params(typs[24]))
typs[121] = newSig(params(typs[20]), params(typs[60]))
typs[122] = newSig(params(typs[22]), params(typs[20]))
typs[123] = newSig(params(typs[24]), params(typs[20]))
typs[124] = newSig(params(typs[60]), params(typs[20]))
typs[125] = newSig(params(typs[26], typs[26]), params(typs[26]))
typs[126] = newSig(nil, params(typs[5]))
typs[127] = newSig(params(typs[5], typs[5]), nil)
typs[128] = newSig(params(typs[5], typs[5], typs[5]), nil)
typs[129] = newSig(params(typs[7], typs[1], typs[5]), nil)
typs[130] = types.NewSlice(typs[7])
typs[131] = newSig(params(typs[7], typs[130]), nil)
typs[132] = newSig(params(typs[64], typs[64]), nil)
typs[133] = newSig(params(typs[58], typs[58]), nil)
typs[134] = newSig(params(typs[60], typs[60]), nil)
typs[135] = newSig(params(typs[24], typs[24]), nil)
typs[79] = newSig(params(typs[1], typs[74], typs[60]), params(typs[3]))
typs[80] = newSig(params(typs[1], typs[74], typs[24]), params(typs[3]))
typs[81] = newSig(params(typs[1], typs[74], typs[28]), params(typs[3]))
typs[82] = newSig(params(typs[1], typs[74], typs[3], typs[1]), params(typs[3]))
typs[83] = newSig(params(typs[1], typs[74], typs[3]), params(typs[3], typs[6]))
typs[84] = newSig(params(typs[1], typs[74], typs[60]), params(typs[3], typs[6]))
typs[85] = newSig(params(typs[1], typs[74], typs[24]), params(typs[3], typs[6]))
typs[86] = newSig(params(typs[1], typs[74], typs[28]), params(typs[3], typs[6]))
typs[87] = newSig(params(typs[1], typs[74], typs[3], typs[1]), params(typs[3], typs[6]))
typs[88] = newSig(params(typs[1], typs[74], typs[7]), params(typs[3]))
typs[89] = newSig(params(typs[1], typs[74], typs[3]), nil)
typs[90] = newSig(params(typs[1], typs[74], typs[60]), nil)
typs[91] = newSig(params(typs[1], typs[74], typs[24]), nil)
typs[92] = newSig(params(typs[1], typs[74], typs[28]), nil)
typs[93] = newSig(params(typs[3]), nil)
typs[94] = newSig(params(typs[1], typs[74]), nil)
typs[95] = types.NewChan(typs[2], types.Cboth)
typs[96] = newSig(params(typs[1], typs[22]), params(typs[95]))
typs[97] = newSig(params(typs[1], typs[15]), params(typs[95]))
typs[98] = types.NewChan(typs[2], types.Crecv)
typs[99] = newSig(params(typs[98], typs[3]), nil)
typs[100] = newSig(params(typs[98], typs[3]), params(typs[6]))
typs[101] = types.NewChan(typs[2], types.Csend)
typs[102] = newSig(params(typs[101], typs[3]), nil)
typs[103] = types.NewArray(typs[0], 3)
typs[104] = types.NewStruct(types.NoPkg, []*types.Field{types.NewField(src.NoXPos, Lookup("enabled"), typs[6]), types.NewField(src.NoXPos, Lookup("pad"), typs[103]), types.NewField(src.NoXPos, Lookup("needed"), typs[6]), types.NewField(src.NoXPos, Lookup("cgo"), typs[6]), types.NewField(src.NoXPos, Lookup("alignme"), typs[24])})
typs[105] = newSig(params(typs[1], typs[3], typs[3]), nil)
typs[106] = newSig(params(typs[1], typs[3]), nil)
typs[107] = newSig(params(typs[1], typs[3], typs[15], typs[3], typs[15]), params(typs[15]))
typs[108] = newSig(params(typs[101], typs[3]), params(typs[6]))
typs[109] = newSig(params(typs[3], typs[98]), params(typs[6], typs[6]))
typs[110] = newSig(params(typs[71]), nil)
typs[111] = newSig(params(typs[1], typs[1], typs[71], typs[15], typs[15], typs[6]), params(typs[15], typs[6]))
typs[112] = newSig(params(typs[1], typs[15], typs[15]), params(typs[7]))
typs[113] = newSig(params(typs[1], typs[22], typs[22]), params(typs[7]))
typs[114] = newSig(params(typs[1], typs[15], typs[15], typs[7]), params(typs[7]))
typs[115] = types.NewSlice(typs[2])
typs[116] = newSig(params(typs[1], typs[115], typs[15]), params(typs[115]))
typs[117] = newSig(params(typs[3], typs[3], typs[5]), nil)
typs[118] = newSig(params(typs[7], typs[5]), nil)
typs[119] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
typs[120] = newSig(params(typs[3], typs[3]), params(typs[6]))
typs[121] = newSig(params(typs[7], typs[7]), params(typs[6]))
typs[122] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
typs[123] = newSig(params(typs[7], typs[5]), params(typs[5]))
typs[124] = newSig(params(typs[22], typs[22]), params(typs[22]))
typs[125] = newSig(params(typs[24], typs[24]), params(typs[24]))
typs[126] = newSig(params(typs[20]), params(typs[22]))
typs[127] = newSig(params(typs[20]), params(typs[24]))
typs[128] = newSig(params(typs[20]), params(typs[60]))
typs[129] = newSig(params(typs[22]), params(typs[20]))
typs[130] = newSig(params(typs[24]), params(typs[20]))
typs[131] = newSig(params(typs[60]), params(typs[20]))
typs[132] = newSig(params(typs[26], typs[26]), params(typs[26]))
typs[133] = newSig(nil, params(typs[5]))
typs[134] = newSig(params(typs[5], typs[5]), nil)
typs[135] = newSig(params(typs[5], typs[5], typs[5]), nil)
typs[136] = newSig(params(typs[7], typs[1], typs[5]), nil)
typs[137] = types.NewSlice(typs[7])
typs[138] = newSig(params(typs[7], typs[137]), nil)
typs[139] = newSig(params(typs[64], typs[64]), nil)
typs[140] = newSig(params(typs[58], typs[58]), nil)
typs[141] = newSig(params(typs[60], typs[60]), nil)
typs[142] = newSig(params(typs[24], typs[24]), nil)
return typs[:]
}

View File

@ -127,26 +127,26 @@ func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
func makemap_small() (hmap map[any]any)
func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
func mapaccess1_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
func mapaccess1_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
func mapaccess1_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any)
func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
func mapaccess2_fast32(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapaccess2_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any, pres bool)
func mapaccess2_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any, pres bool)
func mapaccess2_faststr(mapType *byte, hmap map[any]any, key string) (val *any, pres bool)
func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
func mapassign_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
func mapassign_fast32ptr(mapType *byte, hmap map[any]any, key any) (val *any)
func mapassign_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
func mapassign_fast64ptr(mapType *byte, hmap map[any]any, key any) (val *any)
func mapassign_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
func mapassign_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
func mapassign_fast32ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
func mapassign_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
func mapassign_fast64ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
func mapassign_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
func mapdelete(mapType *byte, hmap map[any]any, key *any)
func mapdelete_fast32(mapType *byte, hmap map[any]any, key any)
func mapdelete_fast64(mapType *byte, hmap map[any]any, key any)
func mapdelete_faststr(mapType *byte, hmap map[any]any, key any)
func mapdelete_fast32(mapType *byte, hmap map[any]any, key uint32)
func mapdelete_fast64(mapType *byte, hmap map[any]any, key uint64)
func mapdelete_faststr(mapType *byte, hmap map[any]any, key string)
func mapiternext(hiter *any)
func mapclear(mapType *byte, hmap map[any]any)

View File

@ -176,10 +176,10 @@ func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
var call *ir.CallExpr
if w := t.Elem().Width; w <= zeroValSize {
fn := mapfn(mapaccess2[fast], t)
fn := mapfn(mapaccess2[fast], t, false)
call = mkcall1(fn, fn.Type().Results(), init, reflectdata.TypePtr(t), r.X, key)
} else {
fn := mapfn("mapaccess2_fat", t)
fn := mapfn("mapaccess2_fat", t, true)
z := reflectdata.ZeroAddr(w)
call = mkcall1(fn, fn.Type().Results(), init, reflectdata.TypePtr(t), r.X, key, z)
}

View File

@ -475,7 +475,10 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
zero := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0))
cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(tk.NumElem()))
incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1)))
body := ir.NewAssignStmt(base.Pos, lhs, rhs)
var body ir.Node = ir.NewAssignStmt(base.Pos, lhs, rhs)
body = typecheck.Stmt(body) // typechecker rewrites OINDEX to OINDEXMAP
body = orderStmtInPlace(body, map[string][]*ir.Name{})
loop := ir.NewForStmt(base.Pos, nil, cond, incr, nil)
loop.Body = []ir.Node{body}
@ -503,7 +506,10 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpelem, elem))
ir.SetPos(tmpelem)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, tmpkey), tmpelem))
var a ir.Node = ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, tmpkey), tmpelem)
a = typecheck.Stmt(a) // typechecker rewrites OINDEX to OINDEXMAP
a = orderStmtInPlace(a, map[string][]*ir.Name{})
appendWalkStmt(init, a)
}
appendWalkStmt(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, tmpkey))

View File

@ -681,12 +681,16 @@ func walkIndexMap(n *ir.IndexExpr, init *ir.Nodes) ir.Node {
if n.Assigned {
// This m[k] expression is on the left-hand side of an assignment.
fast := mapfast(t)
if fast == mapslow {
switch fast {
case mapslow:
// standard version takes key by reference.
// order.expr made sure key is addressable.
key = typecheck.NodAddr(key)
case mapfast32ptr, mapfast64ptr:
// pointer version takes pointer key.
key = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, types.Types[types.TUNSAFEPTR], key)
}
call = mkcall1(mapfn(mapassign[fast], t), nil, init, reflectdata.TypePtr(t), map_, key)
call = mkcall1(mapfn(mapassign[fast], t, false), nil, init, reflectdata.TypePtr(t), map_, key)
} else {
// m[k] is not the target of an assignment.
fast := mapfast(t)
@ -697,10 +701,10 @@ func walkIndexMap(n *ir.IndexExpr, init *ir.Nodes) ir.Node {
}
if w := t.Elem().Width; w <= zeroValSize {
call = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key)
call = mkcall1(mapfn(mapaccess1[fast], t, false), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key)
} else {
z := reflectdata.ZeroAddr(w)
call = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key, z)
call = mkcall1(mapfn("mapaccess1_fat", t, true), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key, z)
}
}
call.SetType(types.NewPtr(t.Elem()))

View File

@ -6,6 +6,7 @@ package walk
import (
"fmt"
"go/constant"
"cmd/compile/internal/base"
"cmd/compile/internal/escape"
@ -269,10 +270,51 @@ func (o *orderState) addrTemp(n ir.Node) ir.Node {
func (o *orderState) mapKeyTemp(t *types.Type, n ir.Node) ir.Node {
// Most map calls need to take the address of the key.
// Exception: map*_fast* calls. See golang.org/issue/19015.
if mapfast(t) == mapslow {
alg := mapfast(t)
if alg == mapslow {
return o.addrTemp(n)
}
return n
var kt *types.Type
switch alg {
case mapfast32, mapfast32ptr:
kt = types.Types[types.TUINT32]
case mapfast64, mapfast64ptr:
kt = types.Types[types.TUINT64]
case mapfaststr:
kt = types.Types[types.TSTRING]
}
nt := n.Type()
switch {
case nt == kt:
return n
case nt.Kind() == kt.Kind():
// can directly convert (e.g. named type to underlying type)
return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, kt, n))
case nt.IsInteger() && kt.IsInteger():
// can directly convert (e.g. int32 to uint32)
if n.Op() == ir.OLITERAL && nt.IsSigned() {
// avoid constant overflow error
n = ir.NewConstExpr(constant.MakeUint64(uint64(ir.Int64Val(n))), n)
n.SetType(kt)
return n
}
return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONV, kt, n))
default:
// Unsafe cast through memory.
// We'll need to do a load with type kt. Create a temporary of type kt to
// ensure sufficient alignment. nt may be under-aligned.
if kt.Align < nt.Align {
base.Fatalf("mapKeyTemp: key type is not sufficiently aligned, kt=%v nt=%v", kt, nt)
}
clear := base.Flag.Cfg.Instrumenting // clear tmp if instrumenting, as it may be live at an inserted race call
tmp := o.newTemp(kt, clear)
// *(*nt)(&tmp) = n
var e ir.Node = typecheck.NodAddr(tmp)
e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, nt.PtrTo(), e)
e = ir.NewStarExpr(n.Pos(), e)
o.append(ir.NewAssignStmt(base.Pos, e, n))
return tmp
}
}
// mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP

View File

@ -197,11 +197,7 @@ func walkGoDefer(n *ir.GoDeferStmt) ir.Node {
case ir.ODELETE:
call := call.(*ir.CallExpr)
if mapfast(call.Args[0].Type()) == mapslow {
n.Call = wrapCall(call, &init)
} else {
n.Call = walkExpr(call, &init)
}
n.Call = wrapCall(call, &init)
case ir.OCOPY:
call := call.(*ir.BinaryExpr)

View File

@ -14,7 +14,6 @@ import (
"cmd/compile/internal/ssagen"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/objabi"
"cmd/internal/src"
)
@ -158,12 +157,16 @@ func chanfn(name string, n int, t *types.Type) ir.Node {
return fn
}
func mapfn(name string, t *types.Type) ir.Node {
func mapfn(name string, t *types.Type, isfat bool) ir.Node {
if !t.IsMap() {
base.Fatalf("mapfn %v", t)
}
fn := typecheck.LookupRuntime(name)
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
if mapfast(t) == mapslow || isfat {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
} else {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Elem())
}
return fn
}
@ -172,7 +175,11 @@ func mapfndel(name string, t *types.Type) ir.Node {
base.Fatalf("mapfn %v", t)
}
fn := typecheck.LookupRuntime(name)
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key())
if mapfast(t) == mapslow {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key())
} else {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
}
return fn
}
@ -204,13 +211,6 @@ func mapfast(t *types.Type) int {
}
switch reflectdata.AlgType(t.Key()) {
case types.AMEM32:
if objabi.Experiment.RegabiArgs && t.Key().NumComponents(types.CountBlankFields) != 1 {
// If key has multiple components, under register ABI it will
// be passed differently than uint32.
// TODO: maybe unsafe-case to uint32. But needs to make the type
// checker happy.
return mapslow
}
if !t.Key().HasPointers() {
return mapfast32
}
@ -219,10 +219,6 @@ func mapfast(t *types.Type) int {
}
base.Fatalf("small pointer %v", t.Key())
case types.AMEM64:
if objabi.Experiment.RegabiArgs && t.Key().NumComponents(types.CountBlankFields) != 1 {
// See above.
return mapslow
}
if !t.Key().HasPointers() {
return mapfast64
}