cmd/compile: unify reflect, string and slice copy runtime functions

Use a common runtime slicecopy function to copy strings or slices
into slices. This deduplicates similar code previously used in
reflect.slicecopy and runtime.stringslicecopy.

Change-Id: I09572ff0647a9e12bb5c6989689ce1c43f16b7f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/254658
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Martin Möhrmann <moehrmann@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Martin Möhrmann 2020-09-14 16:30:43 +02:00
parent eaa97fbf20
commit 790fa1c546
6 changed files with 248 additions and 304 deletions

View file

@ -64,136 +64,135 @@ var runtimeDecls = [...]struct {
{"stringtoslicebyte", funcTag, 49}, {"stringtoslicebyte", funcTag, 49},
{"stringtoslicerune", funcTag, 52}, {"stringtoslicerune", funcTag, 52},
{"slicecopy", funcTag, 53}, {"slicecopy", funcTag, 53},
{"slicestringcopy", funcTag, 54}, {"decoderune", funcTag, 54},
{"decoderune", funcTag, 55}, {"countrunes", funcTag, 55},
{"countrunes", funcTag, 56}, {"convI2I", funcTag, 56},
{"convI2I", funcTag, 57}, {"convT16", funcTag, 57},
{"convT16", funcTag, 58}, {"convT32", funcTag, 57},
{"convT32", funcTag, 58}, {"convT64", funcTag, 57},
{"convT64", funcTag, 58}, {"convTstring", funcTag, 57},
{"convTstring", funcTag, 58}, {"convTslice", funcTag, 57},
{"convTslice", funcTag, 58}, {"convT2E", funcTag, 58},
{"convT2E", funcTag, 59}, {"convT2Enoptr", funcTag, 58},
{"convT2Enoptr", funcTag, 59}, {"convT2I", funcTag, 58},
{"convT2I", funcTag, 59}, {"convT2Inoptr", funcTag, 58},
{"convT2Inoptr", funcTag, 59}, {"assertE2I", funcTag, 56},
{"assertE2I", funcTag, 57}, {"assertE2I2", funcTag, 59},
{"assertE2I2", funcTag, 60}, {"assertI2I", funcTag, 56},
{"assertI2I", funcTag, 57}, {"assertI2I2", funcTag, 59},
{"assertI2I2", funcTag, 60}, {"panicdottypeE", funcTag, 60},
{"panicdottypeE", funcTag, 61}, {"panicdottypeI", funcTag, 60},
{"panicdottypeI", funcTag, 61}, {"panicnildottype", funcTag, 61},
{"panicnildottype", funcTag, 62}, {"ifaceeq", funcTag, 63},
{"ifaceeq", funcTag, 64}, {"efaceeq", funcTag, 63},
{"efaceeq", funcTag, 64}, {"fastrand", funcTag, 65},
{"fastrand", funcTag, 66}, {"makemap64", funcTag, 67},
{"makemap64", funcTag, 68}, {"makemap", funcTag, 68},
{"makemap", funcTag, 69}, {"makemap_small", funcTag, 69},
{"makemap_small", funcTag, 70}, {"mapaccess1", funcTag, 70},
{"mapaccess1", funcTag, 71}, {"mapaccess1_fast32", funcTag, 71},
{"mapaccess1_fast32", funcTag, 72}, {"mapaccess1_fast64", funcTag, 71},
{"mapaccess1_fast64", funcTag, 72}, {"mapaccess1_faststr", funcTag, 71},
{"mapaccess1_faststr", funcTag, 72}, {"mapaccess1_fat", funcTag, 72},
{"mapaccess1_fat", funcTag, 73}, {"mapaccess2", funcTag, 73},
{"mapaccess2", funcTag, 74}, {"mapaccess2_fast32", funcTag, 74},
{"mapaccess2_fast32", funcTag, 75}, {"mapaccess2_fast64", funcTag, 74},
{"mapaccess2_fast64", funcTag, 75}, {"mapaccess2_faststr", funcTag, 74},
{"mapaccess2_faststr", funcTag, 75}, {"mapaccess2_fat", funcTag, 75},
{"mapaccess2_fat", funcTag, 76}, {"mapassign", funcTag, 70},
{"mapassign", funcTag, 71}, {"mapassign_fast32", funcTag, 71},
{"mapassign_fast32", funcTag, 72}, {"mapassign_fast32ptr", funcTag, 71},
{"mapassign_fast32ptr", funcTag, 72}, {"mapassign_fast64", funcTag, 71},
{"mapassign_fast64", funcTag, 72}, {"mapassign_fast64ptr", funcTag, 71},
{"mapassign_fast64ptr", funcTag, 72}, {"mapassign_faststr", funcTag, 71},
{"mapassign_faststr", funcTag, 72}, {"mapiterinit", funcTag, 76},
{"mapiterinit", funcTag, 77}, {"mapdelete", funcTag, 76},
{"mapdelete", funcTag, 77}, {"mapdelete_fast32", funcTag, 77},
{"mapdelete_fast32", funcTag, 78}, {"mapdelete_fast64", funcTag, 77},
{"mapdelete_fast64", funcTag, 78}, {"mapdelete_faststr", funcTag, 77},
{"mapdelete_faststr", funcTag, 78}, {"mapiternext", funcTag, 78},
{"mapiternext", funcTag, 79}, {"mapclear", funcTag, 79},
{"mapclear", funcTag, 80}, {"makechan64", funcTag, 81},
{"makechan64", funcTag, 82}, {"makechan", funcTag, 82},
{"makechan", funcTag, 83}, {"chanrecv1", funcTag, 84},
{"chanrecv1", funcTag, 85}, {"chanrecv2", funcTag, 85},
{"chanrecv2", funcTag, 86}, {"chansend1", funcTag, 87},
{"chansend1", funcTag, 88},
{"closechan", funcTag, 30}, {"closechan", funcTag, 30},
{"writeBarrier", varTag, 90}, {"writeBarrier", varTag, 89},
{"typedmemmove", funcTag, 91}, {"typedmemmove", funcTag, 90},
{"typedmemclr", funcTag, 92}, {"typedmemclr", funcTag, 91},
{"typedslicecopy", funcTag, 93}, {"typedslicecopy", funcTag, 92},
{"selectnbsend", funcTag, 94}, {"selectnbsend", funcTag, 93},
{"selectnbrecv", funcTag, 95}, {"selectnbrecv", funcTag, 94},
{"selectnbrecv2", funcTag, 97}, {"selectnbrecv2", funcTag, 96},
{"selectsetpc", funcTag, 98}, {"selectsetpc", funcTag, 97},
{"selectgo", funcTag, 99}, {"selectgo", funcTag, 98},
{"block", funcTag, 9}, {"block", funcTag, 9},
{"makeslice", funcTag, 100}, {"makeslice", funcTag, 99},
{"makeslice64", funcTag, 101}, {"makeslice64", funcTag, 100},
{"makeslicecopy", funcTag, 102}, {"makeslicecopy", funcTag, 101},
{"growslice", funcTag, 104}, {"growslice", funcTag, 103},
{"memmove", funcTag, 105}, {"memmove", funcTag, 104},
{"memclrNoHeapPointers", funcTag, 106}, {"memclrNoHeapPointers", funcTag, 105},
{"memclrHasPointers", funcTag, 106}, {"memclrHasPointers", funcTag, 105},
{"memequal", funcTag, 107}, {"memequal", funcTag, 106},
{"memequal0", funcTag, 108}, {"memequal0", funcTag, 107},
{"memequal8", funcTag, 108}, {"memequal8", funcTag, 107},
{"memequal16", funcTag, 108}, {"memequal16", funcTag, 107},
{"memequal32", funcTag, 108}, {"memequal32", funcTag, 107},
{"memequal64", funcTag, 108}, {"memequal64", funcTag, 107},
{"memequal128", funcTag, 108}, {"memequal128", funcTag, 107},
{"f32equal", funcTag, 109}, {"f32equal", funcTag, 108},
{"f64equal", funcTag, 109}, {"f64equal", funcTag, 108},
{"c64equal", funcTag, 109}, {"c64equal", funcTag, 108},
{"c128equal", funcTag, 109}, {"c128equal", funcTag, 108},
{"strequal", funcTag, 109}, {"strequal", funcTag, 108},
{"interequal", funcTag, 109}, {"interequal", funcTag, 108},
{"nilinterequal", funcTag, 109}, {"nilinterequal", funcTag, 108},
{"memhash", funcTag, 110}, {"memhash", funcTag, 109},
{"memhash0", funcTag, 111}, {"memhash0", funcTag, 110},
{"memhash8", funcTag, 111}, {"memhash8", funcTag, 110},
{"memhash16", funcTag, 111}, {"memhash16", funcTag, 110},
{"memhash32", funcTag, 111}, {"memhash32", funcTag, 110},
{"memhash64", funcTag, 111}, {"memhash64", funcTag, 110},
{"memhash128", funcTag, 111}, {"memhash128", funcTag, 110},
{"f32hash", funcTag, 111}, {"f32hash", funcTag, 110},
{"f64hash", funcTag, 111}, {"f64hash", funcTag, 110},
{"c64hash", funcTag, 111}, {"c64hash", funcTag, 110},
{"c128hash", funcTag, 111}, {"c128hash", funcTag, 110},
{"strhash", funcTag, 111}, {"strhash", funcTag, 110},
{"interhash", funcTag, 111}, {"interhash", funcTag, 110},
{"nilinterhash", funcTag, 111}, {"nilinterhash", funcTag, 110},
{"int64div", funcTag, 112}, {"int64div", funcTag, 111},
{"uint64div", funcTag, 113}, {"uint64div", funcTag, 112},
{"int64mod", funcTag, 112}, {"int64mod", funcTag, 111},
{"uint64mod", funcTag, 113}, {"uint64mod", funcTag, 112},
{"float64toint64", funcTag, 114}, {"float64toint64", funcTag, 113},
{"float64touint64", funcTag, 115}, {"float64touint64", funcTag, 114},
{"float64touint32", funcTag, 116}, {"float64touint32", funcTag, 115},
{"int64tofloat64", funcTag, 117}, {"int64tofloat64", funcTag, 116},
{"uint64tofloat64", funcTag, 118}, {"uint64tofloat64", funcTag, 117},
{"uint32tofloat64", funcTag, 119}, {"uint32tofloat64", funcTag, 118},
{"complex128div", funcTag, 120}, {"complex128div", funcTag, 119},
{"racefuncenter", funcTag, 121}, {"racefuncenter", funcTag, 120},
{"racefuncenterfp", funcTag, 9}, {"racefuncenterfp", funcTag, 9},
{"racefuncexit", funcTag, 9}, {"racefuncexit", funcTag, 9},
{"raceread", funcTag, 121}, {"raceread", funcTag, 120},
{"racewrite", funcTag, 121}, {"racewrite", funcTag, 120},
{"racereadrange", funcTag, 122}, {"racereadrange", funcTag, 121},
{"racewriterange", funcTag, 122}, {"racewriterange", funcTag, 121},
{"msanread", funcTag, 122}, {"msanread", funcTag, 121},
{"msanwrite", funcTag, 122}, {"msanwrite", funcTag, 121},
{"checkptrAlignment", funcTag, 123}, {"checkptrAlignment", funcTag, 122},
{"checkptrArithmetic", funcTag, 125}, {"checkptrArithmetic", funcTag, 124},
{"libfuzzerTraceCmp1", funcTag, 127}, {"libfuzzerTraceCmp1", funcTag, 126},
{"libfuzzerTraceCmp2", funcTag, 129}, {"libfuzzerTraceCmp2", funcTag, 128},
{"libfuzzerTraceCmp4", funcTag, 130}, {"libfuzzerTraceCmp4", funcTag, 129},
{"libfuzzerTraceCmp8", funcTag, 131}, {"libfuzzerTraceCmp8", funcTag, 130},
{"libfuzzerTraceConstCmp1", funcTag, 127}, {"libfuzzerTraceConstCmp1", funcTag, 126},
{"libfuzzerTraceConstCmp2", funcTag, 129}, {"libfuzzerTraceConstCmp2", funcTag, 128},
{"libfuzzerTraceConstCmp4", funcTag, 130}, {"libfuzzerTraceConstCmp4", funcTag, 129},
{"libfuzzerTraceConstCmp8", funcTag, 131}, {"libfuzzerTraceConstCmp8", funcTag, 130},
{"x86HasPOPCNT", varTag, 6}, {"x86HasPOPCNT", varTag, 6},
{"x86HasSSE41", varTag, 6}, {"x86HasSSE41", varTag, 6},
{"x86HasFMA", varTag, 6}, {"x86HasFMA", varTag, 6},
@ -202,7 +201,7 @@ var runtimeDecls = [...]struct {
} }
func runtimeTypes() []*types.Type { func runtimeTypes() []*types.Type {
var typs [132]*types.Type var typs [131]*types.Type
typs[0] = types.Bytetype typs[0] = types.Bytetype
typs[1] = types.NewPtr(typs[0]) typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[TANY] typs[2] = types.Types[TANY]
@ -257,83 +256,82 @@ func runtimeTypes() []*types.Type {
typs[51] = types.NewPtr(typs[50]) typs[51] = types.NewPtr(typs[50])
typs[52] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[28])}, []*Node{anonfield(typs[46])}) typs[52] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[28])}, []*Node{anonfield(typs[46])})
typs[53] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])}) typs[53] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])})
typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[28])}, []*Node{anonfield(typs[15])}) typs[54] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[45]), anonfield(typs[15])})
typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[45]), anonfield(typs[15])}) typs[55] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])})
typs[56] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])}) typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])}) typs[57] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])})
typs[58] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])}) typs[58] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])}) typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[6])})
typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[6])}) typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil) typs[61] = functype(nil, []*Node{anonfield(typs[1])}, nil)
typs[62] = functype(nil, []*Node{anonfield(typs[1])}, nil) typs[62] = types.NewPtr(typs[5])
typs[63] = types.NewPtr(typs[5]) typs[63] = functype(nil, []*Node{anonfield(typs[62]), anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
typs[64] = functype(nil, []*Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])}) typs[64] = types.Types[TUINT32]
typs[65] = types.Types[TUINT32] typs[65] = functype(nil, nil, []*Node{anonfield(typs[64])})
typs[66] = functype(nil, nil, []*Node{anonfield(typs[65])}) typs[66] = types.NewMap(typs[2], typs[2])
typs[67] = types.NewMap(typs[2], typs[2]) typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*Node{anonfield(typs[67])}) typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[67])}) typs[69] = functype(nil, nil, []*Node{anonfield(typs[66])})
typs[70] = functype(nil, nil, []*Node{anonfield(typs[67])}) typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*Node{anonfield(typs[3])}) typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3])}) typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])}) typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[6])}) typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[6])}) typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[6])}) typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, nil)
typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil) typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, nil)
typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil) typs[78] = functype(nil, []*Node{anonfield(typs[3])}, nil)
typs[79] = functype(nil, []*Node{anonfield(typs[3])}, nil) typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66])}, nil)
typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67])}, nil) typs[80] = types.NewChan(typs[2], types.Cboth)
typs[81] = types.NewChan(typs[2], types.Cboth) typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22])}, []*Node{anonfield(typs[80])})
typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22])}, []*Node{anonfield(typs[81])}) typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[80])})
typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[81])}) typs[83] = types.NewChan(typs[2], types.Crecv)
typs[84] = types.NewChan(typs[2], types.Crecv) typs[84] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, nil)
typs[85] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, nil) typs[85] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
typs[86] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, []*Node{anonfield(typs[6])}) typs[86] = types.NewChan(typs[2], types.Csend)
typs[87] = types.NewChan(typs[2], types.Csend) typs[87] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, nil)
typs[88] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, nil) typs[88] = types.NewArray(typs[0], 3)
typs[89] = types.NewArray(typs[0], 3) typs[89] = tostruct([]*Node{namedfield("enabled", typs[6]), namedfield("pad", typs[88]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
typs[90] = tostruct([]*Node{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])}) typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil) typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil) typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*Node{anonfield(typs[15])}) typs[93] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
typs[94] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, []*Node{anonfield(typs[6])}) typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[83])}, []*Node{anonfield(typs[6])})
typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[84])}, []*Node{anonfield(typs[6])}) typs[95] = types.NewPtr(typs[6])
typs[96] = types.NewPtr(typs[6]) typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[95]), anonfield(typs[83])}, []*Node{anonfield(typs[6])})
typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*Node{anonfield(typs[6])}) typs[97] = functype(nil, []*Node{anonfield(typs[62])}, nil)
typs[98] = functype(nil, []*Node{anonfield(typs[63])}, nil) typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[62]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*Node{anonfield(typs[15]), anonfield(typs[6])})
typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*Node{anonfield(typs[15]), anonfield(typs[6])}) typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])})
typs[100] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])}) typs[100] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[7])})
typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[7])}) typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*Node{anonfield(typs[7])})
typs[102] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*Node{anonfield(typs[7])}) typs[102] = types.NewSlice(typs[2])
typs[103] = types.NewSlice(typs[2]) typs[103] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[102]), anonfield(typs[15])}, []*Node{anonfield(typs[102])})
typs[104] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*Node{anonfield(typs[103])}) typs[104] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil) typs[105] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
typs[106] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil) typs[106] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*Node{anonfield(typs[6])})
typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*Node{anonfield(typs[6])}) typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
typs[108] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])}) typs[108] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
typs[109] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])}) typs[109] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*Node{anonfield(typs[5])}) typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
typs[111] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])}) typs[111] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])})
typs[112] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])}) typs[112] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])})
typs[113] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])}) typs[113] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])})
typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])}) typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])})
typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])}) typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[64])})
typs[116] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[65])}) typs[116] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])})
typs[117] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])}) typs[117] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
typs[118] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])}) typs[118] = functype(nil, []*Node{anonfield(typs[64])}, []*Node{anonfield(typs[20])})
typs[119] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])}) typs[119] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
typs[120] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])}) typs[120] = functype(nil, []*Node{anonfield(typs[5])}, nil)
typs[121] = functype(nil, []*Node{anonfield(typs[5])}, nil) typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
typs[122] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil) typs[122] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
typs[123] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil) typs[123] = types.NewSlice(typs[7])
typs[124] = types.NewSlice(typs[7]) typs[124] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
typs[125] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[124])}, nil) typs[125] = types.Types[TUINT8]
typs[126] = types.Types[TUINT8] typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
typs[127] = functype(nil, []*Node{anonfield(typs[126]), anonfield(typs[126])}, nil) typs[127] = types.Types[TUINT16]
typs[128] = types.Types[TUINT16] typs[128] = functype(nil, []*Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
typs[129] = functype(nil, []*Node{anonfield(typs[128]), anonfield(typs[128])}, nil) typs[129] = functype(nil, []*Node{anonfield(typs[64]), anonfield(typs[64])}, nil)
typs[130] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil) typs[130] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
typs[131] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
return typs[:] return typs[:]
} }

View file

@ -75,8 +75,7 @@ func slicebytetostringtmp(ptr *byte, n int) string
func slicerunetostring(*[32]byte, []rune) string func slicerunetostring(*[32]byte, []rune) string
func stringtoslicebyte(*[32]byte, string) []byte func stringtoslicebyte(*[32]byte, string) []byte
func stringtoslicerune(*[32]rune, string) []rune func stringtoslicerune(*[32]rune, string) []rune
func slicecopy(toPtr *any, toLen int, frPtr *any, frLen int, wid uintptr) int func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int
func slicestringcopy(toPtr *byte, toLen int, fr string) int
func decoderune(string, int) (retv rune, retk int) func decoderune(string, int) (retv rune, retk int)
func countrunes(string) int func countrunes(string) int

View file

@ -928,16 +928,20 @@ func (o Op) IsSlice3() bool {
return false return false
} }
// slicePtrLen extracts the pointer and length from a slice. // backingArrayPtrLen extracts the pointer and length from a slice or string.
// This constructs two nodes referring to n, so n must be a cheapexpr. // This constructs two nodes referring to n, so n must be a cheapexpr.
func (n *Node) slicePtrLen() (ptr, len *Node) { func (n *Node) backingArrayPtrLen() (ptr, len *Node) {
var init Nodes var init Nodes
c := cheapexpr(n, &init) c := cheapexpr(n, &init)
if c != n || init.Len() != 0 { if c != n || init.Len() != 0 {
Fatalf("slicePtrLen not cheap: %v", n) Fatalf("backingArrayPtrLen not cheap: %v", n)
} }
ptr = nod(OSPTR, n, nil) ptr = nod(OSPTR, n, nil)
if n.Type.IsString() {
ptr.Type = types.Types[TUINT8].PtrTo()
} else {
ptr.Type = n.Type.Elem().PtrTo() ptr.Type = n.Type.Elem().PtrTo()
}
len = nod(OLEN, n, nil) len = nod(OLEN, n, nil)
len.Type = types.Types[TINT] len.Type = types.Types[TINT]
return ptr, len return ptr, len

View file

@ -1484,7 +1484,7 @@ opswitch:
} else { } else {
// slicebytetostring(*[32]byte, ptr *byte, n int) string // slicebytetostring(*[32]byte, ptr *byte, n int) string
n.Left = cheapexpr(n.Left, init) n.Left = cheapexpr(n.Left, init)
ptr, len := n.Left.slicePtrLen() ptr, len := n.Left.backingArrayPtrLen()
n = mkcall("slicebytetostring", n.Type, init, a, ptr, len) n = mkcall("slicebytetostring", n.Type, init, a, ptr, len)
} }
@ -1497,7 +1497,7 @@ opswitch:
} }
// slicebytetostringtmp(ptr *byte, n int) string // slicebytetostringtmp(ptr *byte, n int) string
n.Left = cheapexpr(n.Left, init) n.Left = cheapexpr(n.Left, init)
ptr, len := n.Left.slicePtrLen() ptr, len := n.Left.backingArrayPtrLen()
n = mkcall("slicebytetostringtmp", n.Type, init, ptr, len) n = mkcall("slicebytetostringtmp", n.Type, init, ptr, len)
case OSTR2BYTES: case OSTR2BYTES:
@ -2764,36 +2764,25 @@ func appendslice(n *Node, init *Nodes) *Node {
// instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int // instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
fn := syslook("typedslicecopy") fn := syslook("typedslicecopy")
fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem()) fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem())
ptr1, len1 := nptr1.slicePtrLen() ptr1, len1 := nptr1.backingArrayPtrLen()
ptr2, len2 := nptr2.slicePtrLen() ptr2, len2 := nptr2.backingArrayPtrLen()
ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2) ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2)
} else if instrumenting && !compiling_runtime { } else if instrumenting && !compiling_runtime {
// rely on runtime to instrument copy. // rely on runtime to instrument:
// copy(s[len(l1):], l2) // copy(s[len(l1):], l2)
// l2 can be a slice or string.
nptr1 := nod(OSLICE, s, nil) nptr1 := nod(OSLICE, s, nil)
nptr1.Type = s.Type nptr1.Type = s.Type
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil) nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
nptr1 = cheapexpr(nptr1, &nodes) nptr1 = cheapexpr(nptr1, &nodes)
nptr2 := l2 nptr2 := l2
if l2.Type.IsString() { ptr1, len1 := nptr1.backingArrayPtrLen()
// instantiate func slicestringcopy(toPtr *byte, toLen int, fr string) int ptr2, len2 := nptr2.backingArrayPtrLen()
fn := syslook("slicestringcopy")
ptr, len := nptr1.slicePtrLen()
str := nod(OCONVNOP, nptr2, nil)
str.Type = types.Types[TSTRING]
ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr, len, str)
} else {
// instantiate func slicecopy(to any, fr any, wid uintptr) int
fn := syslook("slicecopy")
fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem())
ptr1, len1 := nptr1.slicePtrLen()
ptr2, len2 := nptr2.slicePtrLen()
ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width))
}
fn := syslook("slicecopy")
fn = substArgTypes(fn, ptr1.Type.Elem(), ptr2.Type.Elem())
ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width))
} else { } else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil)) nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
@ -3092,28 +3081,25 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
Curfn.Func.setWBPos(n.Pos) Curfn.Func.setWBPos(n.Pos)
fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem()) fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem())
n.Left = cheapexpr(n.Left, init) n.Left = cheapexpr(n.Left, init)
ptrL, lenL := n.Left.slicePtrLen() ptrL, lenL := n.Left.backingArrayPtrLen()
n.Right = cheapexpr(n.Right, init) n.Right = cheapexpr(n.Right, init)
ptrR, lenR := n.Right.slicePtrLen() ptrR, lenR := n.Right.backingArrayPtrLen()
return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), ptrL, lenL, ptrR, lenR) return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), ptrL, lenL, ptrR, lenR)
} }
if runtimecall { if runtimecall {
if n.Right.Type.IsString() { // rely on runtime to instrument:
fn := syslook("slicestringcopy") // copy(n.Left, n.Right)
// n.Right can be a slice or string.
n.Left = cheapexpr(n.Left, init) n.Left = cheapexpr(n.Left, init)
ptr, len := n.Left.slicePtrLen() ptrL, lenL := n.Left.backingArrayPtrLen()
str := nod(OCONVNOP, n.Right, nil) n.Right = cheapexpr(n.Right, init)
str.Type = types.Types[TSTRING] ptrR, lenR := n.Right.backingArrayPtrLen()
return mkcall1(fn, n.Type, init, ptr, len, str)
}
fn := syslook("slicecopy") fn := syslook("slicecopy")
fn = substArgTypes(fn, n.Left.Type.Elem(), n.Right.Type.Elem()) fn = substArgTypes(fn, ptrL.Type.Elem(), ptrR.Type.Elem())
n.Left = cheapexpr(n.Left, init)
ptrL, lenL := n.Left.slicePtrLen()
n.Right = cheapexpr(n.Right, init)
ptrR, lenR := n.Right.slicePtrLen()
return mkcall1(fn, n.Type, init, ptrL, lenL, ptrR, lenR, nodintconst(n.Left.Type.Elem().Width)) return mkcall1(fn, n.Type, init, ptrL, lenL, ptrR, lenR, nodintconst(n.Left.Type.Elem().Width))
} }

View file

@ -281,28 +281,7 @@ func typedslicecopy(typ *_type, dstPtr unsafe.Pointer, dstLen int, srcPtr unsafe
//go:linkname reflect_typedslicecopy reflect.typedslicecopy //go:linkname reflect_typedslicecopy reflect.typedslicecopy
func reflect_typedslicecopy(elemType *_type, dst, src slice) int { func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
if elemType.ptrdata == 0 { if elemType.ptrdata == 0 {
n := dst.len return slicecopy(dst.array, dst.len, src.array, src.len, elemType.size)
if n > src.len {
n = src.len
}
if n == 0 {
return 0
}
size := uintptr(n) * elemType.size
if raceenabled {
callerpc := getcallerpc()
pc := funcPC(reflect_typedslicecopy)
racewriterangepc(dst.array, size, callerpc, pc)
racereadrangepc(src.array, size, callerpc, pc)
}
if msanenabled {
msanwrite(dst.array, size)
msanread(src.array, size)
}
memmove(dst.array, src.array, size)
return n
} }
return typedslicecopy(elemType, dst.array, dst.len, src.array, src.len) return typedslicecopy(elemType, dst.array, dst.len, src.array, src.len)
} }

View file

@ -243,12 +243,13 @@ func isPowerOfTwo(x uintptr) bool {
return x&(x-1) == 0 return x&(x-1) == 0
} }
func slicecopy(toPtr unsafe.Pointer, toLen int, fmPtr unsafe.Pointer, fmLen int, width uintptr) int { // slicecopy is used to copy from a string or slice of pointerless elements into a slice.
if fmLen == 0 || toLen == 0 { func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int {
if fromLen == 0 || toLen == 0 {
return 0 return 0
} }
n := fmLen n := fromLen
if toLen < n { if toLen < n {
n = toLen n = toLen
} }
@ -257,46 +258,23 @@ func slicecopy(toPtr unsafe.Pointer, toLen int, fmPtr unsafe.Pointer, fmLen int,
return n return n
} }
size := uintptr(n) * width
if raceenabled { if raceenabled {
callerpc := getcallerpc() callerpc := getcallerpc()
pc := funcPC(slicecopy) pc := funcPC(slicecopy)
racereadrangepc(fmPtr, uintptr(n*int(width)), callerpc, pc) racereadrangepc(fromPtr, size, callerpc, pc)
racewriterangepc(toPtr, uintptr(n*int(width)), callerpc, pc) racewriterangepc(toPtr, size, callerpc, pc)
} }
if msanenabled { if msanenabled {
msanread(fmPtr, uintptr(n*int(width))) msanread(fromPtr, size)
msanwrite(toPtr, uintptr(n*int(width))) msanwrite(toPtr, size)
} }
size := uintptr(n) * width
if size == 1 { // common case worth about 2x to do here if size == 1 { // common case worth about 2x to do here
// TODO: is this still worth it with new memmove impl? // TODO: is this still worth it with new memmove impl?
*(*byte)(toPtr) = *(*byte)(fmPtr) // known to be a byte pointer *(*byte)(toPtr) = *(*byte)(fromPtr) // known to be a byte pointer
} else { } else {
memmove(toPtr, fmPtr, size) memmove(toPtr, fromPtr, size)
} }
return n return n
} }
func slicestringcopy(toPtr *byte, toLen int, fm string) int {
if len(fm) == 0 || toLen == 0 {
return 0
}
n := len(fm)
if toLen < n {
n = toLen
}
if raceenabled {
callerpc := getcallerpc()
pc := funcPC(slicestringcopy)
racewriterangepc(unsafe.Pointer(toPtr), uintptr(n), callerpc, pc)
}
if msanenabled {
msanwrite(unsafe.Pointer(toPtr), uintptr(n))
}
memmove(unsafe.Pointer(toPtr), stringStructOf(&fm).str, uintptr(n))
return n
}