mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
eaa97fbf20
commit
790fa1c546
6 changed files with 248 additions and 304 deletions
|
|
@ -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[:]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue