mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: optimize make+copy pattern to avoid memclr
match: m = make([]T, x); copy(m, s) for pointer free T and x==len(s) rewrite to: m = mallocgc(x*elemsize(T), nil, false); memmove(&m, &s, x*elemsize(T)) otherwise rewrite to: m = makeslicecopy([]T, x, s) This avoids memclear and shading of pointers in the newly created slice before the copy. With this CL "s" is only be allowed to bev a variable and not a more complex expression. This restriction could be lifted in future versions of this optimization when it can be proven that "s" is not referencing "m". Triggers 450 times during make.bash.. Reduces go binary size by ~8 kbyte. name old time/op new time/op delta MakeSliceCopy/mallocmove/Byte 71.1ns ± 1% 65.8ns ± 0% -7.49% (p=0.000 n=10+9) MakeSliceCopy/mallocmove/Int 71.2ns ± 1% 66.0ns ± 0% -7.27% (p=0.000 n=10+8) MakeSliceCopy/mallocmove/Ptr 104ns ± 4% 99ns ± 1% -5.13% (p=0.000 n=10+10) MakeSliceCopy/makecopy/Byte 70.3ns ± 0% 68.0ns ± 0% -3.22% (p=0.000 n=10+9) MakeSliceCopy/makecopy/Int 70.3ns ± 0% 68.5ns ± 1% -2.59% (p=0.000 n=9+10) MakeSliceCopy/makecopy/Ptr 102ns ± 0% 99ns ± 1% -2.97% (p=0.000 n=9+9) MakeSliceCopy/nilappend/Byte 75.4ns ± 0% 74.9ns ± 2% -0.63% (p=0.015 n=9+9) MakeSliceCopy/nilappend/Int 75.6ns ± 0% 76.4ns ± 3% ~ (p=0.245 n=9+10) MakeSliceCopy/nilappend/Ptr 107ns ± 0% 108ns ± 1% +0.93% (p=0.005 n=9+10) Fixes #26252 Change-Id: Iec553dd1fef6ded16197216a472351c8799a8e71 Reviewed-on: https://go-review.googlesource.com/c/go/+/146719 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
97240d546c
commit
6ed4661807
@ -10,325 +10,329 @@ var runtimeDecls = [...]struct {
|
|||||||
typ int
|
typ int
|
||||||
}{
|
}{
|
||||||
{"newobject", funcTag, 4},
|
{"newobject", funcTag, 4},
|
||||||
{"panicdivide", funcTag, 5},
|
{"mallocgc", funcTag, 8},
|
||||||
{"panicshift", funcTag, 5},
|
{"panicdivide", funcTag, 9},
|
||||||
{"panicmakeslicelen", funcTag, 5},
|
{"panicshift", funcTag, 9},
|
||||||
{"panicmakeslicecap", funcTag, 5},
|
{"panicmakeslicelen", funcTag, 9},
|
||||||
{"throwinit", funcTag, 5},
|
{"panicmakeslicecap", funcTag, 9},
|
||||||
{"panicwrap", funcTag, 5},
|
{"throwinit", funcTag, 9},
|
||||||
{"gopanic", funcTag, 7},
|
{"panicwrap", funcTag, 9},
|
||||||
{"gorecover", funcTag, 10},
|
{"gopanic", funcTag, 11},
|
||||||
{"goschedguarded", funcTag, 5},
|
{"gorecover", funcTag, 14},
|
||||||
{"goPanicIndex", funcTag, 12},
|
{"goschedguarded", funcTag, 9},
|
||||||
{"goPanicIndexU", funcTag, 14},
|
{"goPanicIndex", funcTag, 16},
|
||||||
{"goPanicSliceAlen", funcTag, 12},
|
{"goPanicIndexU", funcTag, 18},
|
||||||
{"goPanicSliceAlenU", funcTag, 14},
|
{"goPanicSliceAlen", funcTag, 16},
|
||||||
{"goPanicSliceAcap", funcTag, 12},
|
{"goPanicSliceAlenU", funcTag, 18},
|
||||||
{"goPanicSliceAcapU", funcTag, 14},
|
{"goPanicSliceAcap", funcTag, 16},
|
||||||
{"goPanicSliceB", funcTag, 12},
|
{"goPanicSliceAcapU", funcTag, 18},
|
||||||
{"goPanicSliceBU", funcTag, 14},
|
{"goPanicSliceB", funcTag, 16},
|
||||||
{"goPanicSlice3Alen", funcTag, 12},
|
{"goPanicSliceBU", funcTag, 18},
|
||||||
{"goPanicSlice3AlenU", funcTag, 14},
|
{"goPanicSlice3Alen", funcTag, 16},
|
||||||
{"goPanicSlice3Acap", funcTag, 12},
|
{"goPanicSlice3AlenU", funcTag, 18},
|
||||||
{"goPanicSlice3AcapU", funcTag, 14},
|
{"goPanicSlice3Acap", funcTag, 16},
|
||||||
{"goPanicSlice3B", funcTag, 12},
|
{"goPanicSlice3AcapU", funcTag, 18},
|
||||||
{"goPanicSlice3BU", funcTag, 14},
|
{"goPanicSlice3B", funcTag, 16},
|
||||||
{"goPanicSlice3C", funcTag, 12},
|
{"goPanicSlice3BU", funcTag, 18},
|
||||||
{"goPanicSlice3CU", funcTag, 14},
|
{"goPanicSlice3C", funcTag, 16},
|
||||||
{"printbool", funcTag, 16},
|
{"goPanicSlice3CU", funcTag, 18},
|
||||||
{"printfloat", funcTag, 18},
|
{"printbool", funcTag, 19},
|
||||||
{"printint", funcTag, 20},
|
{"printfloat", funcTag, 21},
|
||||||
{"printhex", funcTag, 22},
|
{"printint", funcTag, 23},
|
||||||
{"printuint", funcTag, 22},
|
{"printhex", funcTag, 25},
|
||||||
{"printcomplex", funcTag, 24},
|
{"printuint", funcTag, 25},
|
||||||
{"printstring", funcTag, 26},
|
{"printcomplex", funcTag, 27},
|
||||||
{"printpointer", funcTag, 27},
|
{"printstring", funcTag, 29},
|
||||||
{"printiface", funcTag, 27},
|
{"printpointer", funcTag, 30},
|
||||||
{"printeface", funcTag, 27},
|
{"printiface", funcTag, 30},
|
||||||
{"printslice", funcTag, 27},
|
{"printeface", funcTag, 30},
|
||||||
{"printnl", funcTag, 5},
|
{"printslice", funcTag, 30},
|
||||||
{"printsp", funcTag, 5},
|
{"printnl", funcTag, 9},
|
||||||
{"printlock", funcTag, 5},
|
{"printsp", funcTag, 9},
|
||||||
{"printunlock", funcTag, 5},
|
{"printlock", funcTag, 9},
|
||||||
{"concatstring2", funcTag, 30},
|
{"printunlock", funcTag, 9},
|
||||||
{"concatstring3", funcTag, 31},
|
{"concatstring2", funcTag, 33},
|
||||||
{"concatstring4", funcTag, 32},
|
{"concatstring3", funcTag, 34},
|
||||||
{"concatstring5", funcTag, 33},
|
{"concatstring4", funcTag, 35},
|
||||||
{"concatstrings", funcTag, 35},
|
{"concatstring5", funcTag, 36},
|
||||||
{"cmpstring", funcTag, 36},
|
{"concatstrings", funcTag, 38},
|
||||||
{"intstring", funcTag, 39},
|
{"cmpstring", funcTag, 39},
|
||||||
{"slicebytetostring", funcTag, 40},
|
{"intstring", funcTag, 42},
|
||||||
{"slicebytetostringtmp", funcTag, 41},
|
{"slicebytetostring", funcTag, 43},
|
||||||
{"slicerunetostring", funcTag, 44},
|
{"slicebytetostringtmp", funcTag, 44},
|
||||||
{"stringtoslicebyte", funcTag, 46},
|
{"slicerunetostring", funcTag, 47},
|
||||||
{"stringtoslicerune", funcTag, 49},
|
{"stringtoslicebyte", funcTag, 49},
|
||||||
{"slicecopy", funcTag, 51},
|
{"stringtoslicerune", funcTag, 52},
|
||||||
{"slicestringcopy", funcTag, 52},
|
{"slicecopy", funcTag, 53},
|
||||||
{"decoderune", funcTag, 53},
|
{"slicestringcopy", funcTag, 54},
|
||||||
{"countrunes", funcTag, 54},
|
{"decoderune", funcTag, 55},
|
||||||
{"convI2I", funcTag, 55},
|
{"countrunes", funcTag, 56},
|
||||||
{"convT16", funcTag, 57},
|
{"convI2I", funcTag, 57},
|
||||||
{"convT32", funcTag, 57},
|
{"convT16", funcTag, 58},
|
||||||
{"convT64", funcTag, 57},
|
{"convT32", funcTag, 58},
|
||||||
{"convTstring", funcTag, 57},
|
{"convT64", funcTag, 58},
|
||||||
{"convTslice", funcTag, 57},
|
{"convTstring", funcTag, 58},
|
||||||
{"convT2E", funcTag, 58},
|
{"convTslice", funcTag, 58},
|
||||||
{"convT2Enoptr", funcTag, 58},
|
{"convT2E", funcTag, 59},
|
||||||
{"convT2I", funcTag, 58},
|
{"convT2Enoptr", funcTag, 59},
|
||||||
{"convT2Inoptr", funcTag, 58},
|
{"convT2I", funcTag, 59},
|
||||||
{"assertE2I", funcTag, 55},
|
{"convT2Inoptr", funcTag, 59},
|
||||||
{"assertE2I2", funcTag, 59},
|
{"assertE2I", funcTag, 57},
|
||||||
{"assertI2I", funcTag, 55},
|
{"assertE2I2", funcTag, 60},
|
||||||
{"assertI2I2", funcTag, 59},
|
{"assertI2I", funcTag, 57},
|
||||||
{"panicdottypeE", funcTag, 60},
|
{"assertI2I2", funcTag, 60},
|
||||||
{"panicdottypeI", funcTag, 60},
|
{"panicdottypeE", funcTag, 61},
|
||||||
{"panicnildottype", funcTag, 61},
|
{"panicdottypeI", funcTag, 61},
|
||||||
{"ifaceeq", funcTag, 63},
|
{"panicnildottype", funcTag, 62},
|
||||||
{"efaceeq", funcTag, 63},
|
{"ifaceeq", funcTag, 64},
|
||||||
{"fastrand", funcTag, 65},
|
{"efaceeq", funcTag, 64},
|
||||||
{"makemap64", funcTag, 67},
|
{"fastrand", funcTag, 66},
|
||||||
{"makemap", funcTag, 68},
|
{"makemap64", funcTag, 68},
|
||||||
{"makemap_small", funcTag, 69},
|
{"makemap", funcTag, 69},
|
||||||
{"mapaccess1", funcTag, 70},
|
{"makemap_small", funcTag, 70},
|
||||||
{"mapaccess1_fast32", funcTag, 71},
|
{"mapaccess1", funcTag, 71},
|
||||||
{"mapaccess1_fast64", funcTag, 71},
|
{"mapaccess1_fast32", funcTag, 72},
|
||||||
{"mapaccess1_faststr", funcTag, 71},
|
{"mapaccess1_fast64", funcTag, 72},
|
||||||
{"mapaccess1_fat", funcTag, 72},
|
{"mapaccess1_faststr", funcTag, 72},
|
||||||
{"mapaccess2", funcTag, 73},
|
{"mapaccess1_fat", funcTag, 73},
|
||||||
{"mapaccess2_fast32", funcTag, 74},
|
{"mapaccess2", funcTag, 74},
|
||||||
{"mapaccess2_fast64", funcTag, 74},
|
{"mapaccess2_fast32", funcTag, 75},
|
||||||
{"mapaccess2_faststr", funcTag, 74},
|
{"mapaccess2_fast64", funcTag, 75},
|
||||||
{"mapaccess2_fat", funcTag, 75},
|
{"mapaccess2_faststr", funcTag, 75},
|
||||||
{"mapassign", funcTag, 70},
|
{"mapaccess2_fat", funcTag, 76},
|
||||||
{"mapassign_fast32", funcTag, 71},
|
{"mapassign", funcTag, 71},
|
||||||
{"mapassign_fast32ptr", funcTag, 71},
|
{"mapassign_fast32", funcTag, 72},
|
||||||
{"mapassign_fast64", funcTag, 71},
|
{"mapassign_fast32ptr", funcTag, 72},
|
||||||
{"mapassign_fast64ptr", funcTag, 71},
|
{"mapassign_fast64", funcTag, 72},
|
||||||
{"mapassign_faststr", funcTag, 71},
|
{"mapassign_fast64ptr", funcTag, 72},
|
||||||
{"mapiterinit", funcTag, 76},
|
{"mapassign_faststr", funcTag, 72},
|
||||||
{"mapdelete", funcTag, 76},
|
{"mapiterinit", funcTag, 77},
|
||||||
{"mapdelete_fast32", funcTag, 77},
|
{"mapdelete", funcTag, 77},
|
||||||
{"mapdelete_fast64", funcTag, 77},
|
{"mapdelete_fast32", funcTag, 78},
|
||||||
{"mapdelete_faststr", funcTag, 77},
|
{"mapdelete_fast64", funcTag, 78},
|
||||||
{"mapiternext", funcTag, 78},
|
{"mapdelete_faststr", funcTag, 78},
|
||||||
{"mapclear", funcTag, 79},
|
{"mapiternext", funcTag, 79},
|
||||||
{"makechan64", funcTag, 81},
|
{"mapclear", funcTag, 80},
|
||||||
{"makechan", funcTag, 82},
|
{"makechan64", funcTag, 82},
|
||||||
{"chanrecv1", funcTag, 84},
|
{"makechan", funcTag, 83},
|
||||||
{"chanrecv2", funcTag, 85},
|
{"chanrecv1", funcTag, 85},
|
||||||
{"chansend1", funcTag, 87},
|
{"chanrecv2", funcTag, 86},
|
||||||
{"closechan", funcTag, 27},
|
{"chansend1", funcTag, 88},
|
||||||
{"writeBarrier", varTag, 89},
|
{"closechan", funcTag, 30},
|
||||||
{"typedmemmove", funcTag, 90},
|
{"writeBarrier", varTag, 90},
|
||||||
{"typedmemclr", funcTag, 91},
|
{"typedmemmove", funcTag, 91},
|
||||||
{"typedslicecopy", funcTag, 92},
|
{"typedmemclr", funcTag, 92},
|
||||||
{"selectnbsend", funcTag, 93},
|
{"typedslicecopy", funcTag, 93},
|
||||||
{"selectnbrecv", funcTag, 94},
|
{"selectnbsend", funcTag, 94},
|
||||||
{"selectnbrecv2", funcTag, 96},
|
{"selectnbrecv", funcTag, 95},
|
||||||
{"selectsetpc", funcTag, 61},
|
{"selectnbrecv2", funcTag, 97},
|
||||||
{"selectgo", funcTag, 97},
|
{"selectsetpc", funcTag, 62},
|
||||||
{"block", funcTag, 5},
|
{"selectgo", funcTag, 98},
|
||||||
{"makeslice", funcTag, 98},
|
{"block", funcTag, 9},
|
||||||
{"makeslice64", funcTag, 99},
|
{"makeslice", funcTag, 99},
|
||||||
{"growslice", funcTag, 101},
|
{"makeslice64", funcTag, 100},
|
||||||
{"memmove", funcTag, 102},
|
{"makeslicecopy", funcTag, 101},
|
||||||
{"memclrNoHeapPointers", funcTag, 103},
|
{"growslice", funcTag, 103},
|
||||||
{"memclrHasPointers", funcTag, 103},
|
{"memmove", funcTag, 104},
|
||||||
{"memequal", funcTag, 104},
|
{"memclrNoHeapPointers", funcTag, 105},
|
||||||
{"memequal0", funcTag, 105},
|
{"memclrHasPointers", funcTag, 105},
|
||||||
{"memequal8", funcTag, 105},
|
{"memequal", funcTag, 106},
|
||||||
{"memequal16", funcTag, 105},
|
{"memequal0", funcTag, 107},
|
||||||
{"memequal32", funcTag, 105},
|
{"memequal8", funcTag, 107},
|
||||||
{"memequal64", funcTag, 105},
|
{"memequal16", funcTag, 107},
|
||||||
{"memequal128", funcTag, 105},
|
{"memequal32", funcTag, 107},
|
||||||
{"f32equal", funcTag, 106},
|
{"memequal64", funcTag, 107},
|
||||||
{"f64equal", funcTag, 106},
|
{"memequal128", funcTag, 107},
|
||||||
{"c64equal", funcTag, 106},
|
{"f32equal", funcTag, 108},
|
||||||
{"c128equal", funcTag, 106},
|
{"f64equal", funcTag, 108},
|
||||||
{"strequal", funcTag, 106},
|
{"c64equal", funcTag, 108},
|
||||||
{"interequal", funcTag, 106},
|
{"c128equal", funcTag, 108},
|
||||||
{"nilinterequal", funcTag, 106},
|
{"strequal", funcTag, 108},
|
||||||
{"memhash", funcTag, 107},
|
{"interequal", funcTag, 108},
|
||||||
{"memhash0", funcTag, 108},
|
{"nilinterequal", funcTag, 108},
|
||||||
{"memhash8", funcTag, 108},
|
{"memhash", funcTag, 109},
|
||||||
{"memhash16", funcTag, 108},
|
{"memhash0", funcTag, 110},
|
||||||
{"memhash32", funcTag, 108},
|
{"memhash8", funcTag, 110},
|
||||||
{"memhash64", funcTag, 108},
|
{"memhash16", funcTag, 110},
|
||||||
{"memhash128", funcTag, 108},
|
{"memhash32", funcTag, 110},
|
||||||
{"f32hash", funcTag, 108},
|
{"memhash64", funcTag, 110},
|
||||||
{"f64hash", funcTag, 108},
|
{"memhash128", funcTag, 110},
|
||||||
{"c64hash", funcTag, 108},
|
{"f32hash", funcTag, 110},
|
||||||
{"c128hash", funcTag, 108},
|
{"f64hash", funcTag, 110},
|
||||||
{"strhash", funcTag, 108},
|
{"c64hash", funcTag, 110},
|
||||||
{"interhash", funcTag, 108},
|
{"c128hash", funcTag, 110},
|
||||||
{"nilinterhash", funcTag, 108},
|
{"strhash", funcTag, 110},
|
||||||
{"int64div", funcTag, 109},
|
{"interhash", funcTag, 110},
|
||||||
{"uint64div", funcTag, 110},
|
{"nilinterhash", funcTag, 110},
|
||||||
{"int64mod", funcTag, 109},
|
{"int64div", funcTag, 111},
|
||||||
{"uint64mod", funcTag, 110},
|
{"uint64div", funcTag, 112},
|
||||||
{"float64toint64", funcTag, 111},
|
{"int64mod", funcTag, 111},
|
||||||
{"float64touint64", funcTag, 112},
|
{"uint64mod", funcTag, 112},
|
||||||
{"float64touint32", funcTag, 113},
|
{"float64toint64", funcTag, 113},
|
||||||
{"int64tofloat64", funcTag, 114},
|
{"float64touint64", funcTag, 114},
|
||||||
{"uint64tofloat64", funcTag, 115},
|
{"float64touint32", funcTag, 115},
|
||||||
{"uint32tofloat64", funcTag, 116},
|
{"int64tofloat64", funcTag, 116},
|
||||||
{"complex128div", funcTag, 117},
|
{"uint64tofloat64", funcTag, 117},
|
||||||
{"racefuncenter", funcTag, 118},
|
{"uint32tofloat64", funcTag, 118},
|
||||||
{"racefuncenterfp", funcTag, 5},
|
{"complex128div", funcTag, 119},
|
||||||
{"racefuncexit", funcTag, 5},
|
{"racefuncenter", funcTag, 120},
|
||||||
{"raceread", funcTag, 118},
|
{"racefuncenterfp", funcTag, 9},
|
||||||
{"racewrite", funcTag, 118},
|
{"racefuncexit", funcTag, 9},
|
||||||
{"racereadrange", funcTag, 119},
|
{"raceread", funcTag, 120},
|
||||||
{"racewriterange", funcTag, 119},
|
{"racewrite", funcTag, 120},
|
||||||
{"msanread", funcTag, 119},
|
{"racereadrange", funcTag, 121},
|
||||||
{"msanwrite", funcTag, 119},
|
{"racewriterange", funcTag, 121},
|
||||||
{"checkptrAlignment", funcTag, 120},
|
{"msanread", funcTag, 121},
|
||||||
{"checkptrArithmetic", funcTag, 122},
|
{"msanwrite", funcTag, 121},
|
||||||
{"libfuzzerTraceCmp1", funcTag, 124},
|
{"checkptrAlignment", funcTag, 122},
|
||||||
{"libfuzzerTraceCmp2", funcTag, 126},
|
{"checkptrArithmetic", funcTag, 124},
|
||||||
{"libfuzzerTraceCmp4", funcTag, 127},
|
{"libfuzzerTraceCmp1", funcTag, 126},
|
||||||
{"libfuzzerTraceCmp8", funcTag, 128},
|
{"libfuzzerTraceCmp2", funcTag, 128},
|
||||||
{"libfuzzerTraceConstCmp1", funcTag, 124},
|
{"libfuzzerTraceCmp4", funcTag, 129},
|
||||||
{"libfuzzerTraceConstCmp2", funcTag, 126},
|
{"libfuzzerTraceCmp8", funcTag, 130},
|
||||||
{"libfuzzerTraceConstCmp4", funcTag, 127},
|
{"libfuzzerTraceConstCmp1", funcTag, 126},
|
||||||
{"libfuzzerTraceConstCmp8", funcTag, 128},
|
{"libfuzzerTraceConstCmp2", funcTag, 128},
|
||||||
{"x86HasPOPCNT", varTag, 15},
|
{"libfuzzerTraceConstCmp4", funcTag, 129},
|
||||||
{"x86HasSSE41", varTag, 15},
|
{"libfuzzerTraceConstCmp8", funcTag, 130},
|
||||||
{"x86HasFMA", varTag, 15},
|
{"x86HasPOPCNT", varTag, 6},
|
||||||
{"armHasVFPv4", varTag, 15},
|
{"x86HasSSE41", varTag, 6},
|
||||||
{"arm64HasATOMICS", varTag, 15},
|
{"x86HasFMA", varTag, 6},
|
||||||
|
{"armHasVFPv4", varTag, 6},
|
||||||
|
{"arm64HasATOMICS", varTag, 6},
|
||||||
}
|
}
|
||||||
|
|
||||||
func runtimeTypes() []*types.Type {
|
func runtimeTypes() []*types.Type {
|
||||||
var typs [129]*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]
|
||||||
typs[3] = types.NewPtr(typs[2])
|
typs[3] = types.NewPtr(typs[2])
|
||||||
typs[4] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[3])})
|
typs[4] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[3])})
|
||||||
typs[5] = functype(nil, nil, nil)
|
typs[5] = types.Types[TUINTPTR]
|
||||||
typs[6] = types.Types[TINTER]
|
typs[6] = types.Types[TBOOL]
|
||||||
typs[7] = functype(nil, []*Node{anonfield(typs[6])}, nil)
|
typs[7] = types.Types[TUNSAFEPTR]
|
||||||
typs[8] = types.Types[TINT32]
|
typs[8] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*Node{anonfield(typs[7])})
|
||||||
typs[9] = types.NewPtr(typs[8])
|
typs[9] = functype(nil, nil, nil)
|
||||||
typs[10] = functype(nil, []*Node{anonfield(typs[9])}, []*Node{anonfield(typs[6])})
|
typs[10] = types.Types[TINTER]
|
||||||
typs[11] = types.Types[TINT]
|
typs[11] = functype(nil, []*Node{anonfield(typs[10])}, nil)
|
||||||
typs[12] = functype(nil, []*Node{anonfield(typs[11]), anonfield(typs[11])}, nil)
|
typs[12] = types.Types[TINT32]
|
||||||
typs[13] = types.Types[TUINT]
|
typs[13] = types.NewPtr(typs[12])
|
||||||
typs[14] = functype(nil, []*Node{anonfield(typs[13]), anonfield(typs[11])}, nil)
|
typs[14] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[10])})
|
||||||
typs[15] = types.Types[TBOOL]
|
typs[15] = types.Types[TINT]
|
||||||
typs[16] = functype(nil, []*Node{anonfield(typs[15])}, nil)
|
typs[16] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, nil)
|
||||||
typs[17] = types.Types[TFLOAT64]
|
typs[17] = types.Types[TUINT]
|
||||||
typs[18] = functype(nil, []*Node{anonfield(typs[17])}, nil)
|
typs[18] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
|
||||||
typs[19] = types.Types[TINT64]
|
typs[19] = functype(nil, []*Node{anonfield(typs[6])}, nil)
|
||||||
typs[20] = functype(nil, []*Node{anonfield(typs[19])}, nil)
|
typs[20] = types.Types[TFLOAT64]
|
||||||
typs[21] = types.Types[TUINT64]
|
typs[21] = functype(nil, []*Node{anonfield(typs[20])}, nil)
|
||||||
typs[22] = functype(nil, []*Node{anonfield(typs[21])}, nil)
|
typs[22] = types.Types[TINT64]
|
||||||
typs[23] = types.Types[TCOMPLEX128]
|
typs[23] = functype(nil, []*Node{anonfield(typs[22])}, nil)
|
||||||
typs[24] = functype(nil, []*Node{anonfield(typs[23])}, nil)
|
typs[24] = types.Types[TUINT64]
|
||||||
typs[25] = types.Types[TSTRING]
|
typs[25] = functype(nil, []*Node{anonfield(typs[24])}, nil)
|
||||||
typs[26] = functype(nil, []*Node{anonfield(typs[25])}, nil)
|
typs[26] = types.Types[TCOMPLEX128]
|
||||||
typs[27] = functype(nil, []*Node{anonfield(typs[2])}, nil)
|
typs[27] = functype(nil, []*Node{anonfield(typs[26])}, nil)
|
||||||
typs[28] = types.NewArray(typs[0], 32)
|
typs[28] = types.Types[TSTRING]
|
||||||
typs[29] = types.NewPtr(typs[28])
|
typs[29] = functype(nil, []*Node{anonfield(typs[28])}, nil)
|
||||||
typs[30] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
|
typs[30] = functype(nil, []*Node{anonfield(typs[2])}, nil)
|
||||||
typs[31] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
|
typs[31] = types.NewArray(typs[0], 32)
|
||||||
typs[32] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
|
typs[32] = types.NewPtr(typs[31])
|
||||||
typs[33] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
|
typs[33] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
|
||||||
typs[34] = types.NewSlice(typs[25])
|
typs[34] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
|
||||||
typs[35] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[34])}, []*Node{anonfield(typs[25])})
|
typs[35] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
|
||||||
typs[36] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[11])})
|
typs[36] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
|
||||||
typs[37] = types.NewArray(typs[0], 4)
|
typs[37] = types.NewSlice(typs[28])
|
||||||
typs[38] = types.NewPtr(typs[37])
|
typs[38] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[37])}, []*Node{anonfield(typs[28])})
|
||||||
typs[39] = functype(nil, []*Node{anonfield(typs[38]), anonfield(typs[19])}, []*Node{anonfield(typs[25])})
|
typs[39] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
|
||||||
typs[40] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[25])})
|
typs[40] = types.NewArray(typs[0], 4)
|
||||||
typs[41] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[25])})
|
typs[41] = types.NewPtr(typs[40])
|
||||||
typs[42] = types.Runetype
|
typs[42] = functype(nil, []*Node{anonfield(typs[41]), anonfield(typs[22])}, []*Node{anonfield(typs[28])})
|
||||||
typs[43] = types.NewSlice(typs[42])
|
typs[43] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
|
||||||
typs[44] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[43])}, []*Node{anonfield(typs[25])})
|
typs[44] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
|
||||||
typs[45] = types.NewSlice(typs[0])
|
typs[45] = types.Runetype
|
||||||
typs[46] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25])}, []*Node{anonfield(typs[45])})
|
typs[46] = types.NewSlice(typs[45])
|
||||||
typs[47] = types.NewArray(typs[42], 32)
|
typs[47] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[46])}, []*Node{anonfield(typs[28])})
|
||||||
typs[48] = types.NewPtr(typs[47])
|
typs[48] = types.NewSlice(typs[0])
|
||||||
typs[49] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[25])}, []*Node{anonfield(typs[43])})
|
typs[49] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28])}, []*Node{anonfield(typs[48])})
|
||||||
typs[50] = types.Types[TUINTPTR]
|
typs[50] = types.NewArray(typs[45], 32)
|
||||||
typs[51] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[11]), anonfield(typs[3]), anonfield(typs[11]), anonfield(typs[50])}, []*Node{anonfield(typs[11])})
|
typs[51] = types.NewPtr(typs[50])
|
||||||
typs[52] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), anonfield(typs[25])}, []*Node{anonfield(typs[11])})
|
typs[52] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[28])}, []*Node{anonfield(typs[46])})
|
||||||
typs[53] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[11])}, []*Node{anonfield(typs[42]), anonfield(typs[11])})
|
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[25])}, []*Node{anonfield(typs[11])})
|
typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
|
||||||
typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
|
typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[45]), anonfield(typs[15])})
|
||||||
typs[56] = types.Types[TUNSAFEPTR]
|
typs[56] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])})
|
||||||
typs[57] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[56])})
|
typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
|
||||||
typs[58] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
|
typs[58] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])})
|
||||||
typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[15])})
|
typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
|
||||||
typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
|
typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[6])})
|
||||||
typs[61] = functype(nil, []*Node{anonfield(typs[1])}, nil)
|
typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
|
||||||
typs[62] = types.NewPtr(typs[50])
|
typs[62] = functype(nil, []*Node{anonfield(typs[1])}, nil)
|
||||||
typs[63] = functype(nil, []*Node{anonfield(typs[62]), anonfield(typs[56]), anonfield(typs[56])}, []*Node{anonfield(typs[15])})
|
typs[63] = types.NewPtr(typs[5])
|
||||||
typs[64] = types.Types[TUINT32]
|
typs[64] = functype(nil, []*Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
|
||||||
typs[65] = functype(nil, nil, []*Node{anonfield(typs[64])})
|
typs[65] = types.Types[TUINT32]
|
||||||
typs[66] = types.NewMap(typs[2], typs[2])
|
typs[66] = functype(nil, nil, []*Node{anonfield(typs[65])})
|
||||||
typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
|
typs[67] = types.NewMap(typs[2], typs[2])
|
||||||
typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), 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[69] = functype(nil, nil, []*Node{anonfield(typs[66])})
|
typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[67])})
|
||||||
typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
|
typs[70] = functype(nil, nil, []*Node{anonfield(typs[67])})
|
||||||
typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
|
typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*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[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
|
||||||
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
|
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
|
||||||
typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
|
typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*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[15])})
|
typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
|
||||||
typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, nil)
|
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[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, nil)
|
typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
|
||||||
typs[78] = functype(nil, []*Node{anonfield(typs[3])}, nil)
|
typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
|
||||||
typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66])}, nil)
|
typs[79] = functype(nil, []*Node{anonfield(typs[3])}, nil)
|
||||||
typs[80] = types.NewChan(typs[2], types.Cboth)
|
typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
|
||||||
typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19])}, []*Node{anonfield(typs[80])})
|
typs[81] = types.NewChan(typs[2], types.Cboth)
|
||||||
typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[80])})
|
typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22])}, []*Node{anonfield(typs[81])})
|
||||||
typs[83] = types.NewChan(typs[2], types.Crecv)
|
typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[81])})
|
||||||
typs[84] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, nil)
|
typs[84] = types.NewChan(typs[2], types.Crecv)
|
||||||
typs[85] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
|
typs[85] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
|
||||||
typs[86] = types.NewChan(typs[2], types.Csend)
|
typs[86] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
|
||||||
typs[87] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, nil)
|
typs[87] = types.NewChan(typs[2], types.Csend)
|
||||||
typs[88] = types.NewArray(typs[0], 3)
|
typs[88] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, nil)
|
||||||
typs[89] = tostruct([]*Node{namedfield("enabled", typs[15]), namedfield("pad", typs[88]), namedfield("needed", typs[15]), namedfield("cgo", typs[15]), namedfield("alignme", typs[21])})
|
typs[89] = types.NewArray(typs[0], 3)
|
||||||
typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
|
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[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
|
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
|
||||||
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[11]), anonfield(typs[3]), anonfield(typs[11])}, []*Node{anonfield(typs[11])})
|
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
|
||||||
typs[93] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, []*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[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[83])}, []*Node{anonfield(typs[15])})
|
typs[94] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
|
||||||
typs[95] = types.NewPtr(typs[15])
|
typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
|
||||||
typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[95]), anonfield(typs[83])}, []*Node{anonfield(typs[15])})
|
typs[96] = types.NewPtr(typs[6])
|
||||||
typs[97] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[11]), anonfield(typs[15])})
|
typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
|
||||||
typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), anonfield(typs[11])}, []*Node{anonfield(typs[56])})
|
typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[15]), anonfield(typs[6])})
|
||||||
typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[56])})
|
typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])})
|
||||||
typs[100] = types.NewSlice(typs[2])
|
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[100]), anonfield(typs[11])}, []*Node{anonfield(typs[100])})
|
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[3]), anonfield(typs[3]), anonfield(typs[50])}, nil)
|
typs[102] = types.NewSlice(typs[2])
|
||||||
typs[103] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, nil)
|
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[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[15])})
|
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])}, []*Node{anonfield(typs[15])})
|
typs[105] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
|
||||||
typs[106] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[56])}, []*Node{anonfield(typs[15])})
|
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[56]), anonfield(typs[50]), anonfield(typs[50])}, []*Node{anonfield(typs[50])})
|
typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
|
||||||
typs[108] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, []*Node{anonfield(typs[50])})
|
typs[108] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
|
||||||
typs[109] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
|
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[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
|
typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
|
||||||
typs[111] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[19])})
|
typs[111] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])})
|
||||||
typs[112] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[21])})
|
typs[112] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])})
|
||||||
typs[113] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[64])})
|
typs[113] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])})
|
||||||
typs[114] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[17])})
|
typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])})
|
||||||
typs[115] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[17])})
|
typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[65])})
|
||||||
typs[116] = functype(nil, []*Node{anonfield(typs[64])}, []*Node{anonfield(typs[17])})
|
typs[116] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])})
|
||||||
typs[117] = functype(nil, []*Node{anonfield(typs[23]), anonfield(typs[23])}, []*Node{anonfield(typs[23])})
|
typs[117] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
|
||||||
typs[118] = functype(nil, []*Node{anonfield(typs[50])}, nil)
|
typs[118] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])})
|
||||||
typs[119] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
|
typs[119] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
|
||||||
typs[120] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[1]), anonfield(typs[50])}, nil)
|
typs[120] = functype(nil, []*Node{anonfield(typs[5])}, nil)
|
||||||
typs[121] = types.NewSlice(typs[56])
|
typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
|
||||||
typs[122] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[121])}, nil)
|
typs[122] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
|
||||||
typs[123] = types.Types[TUINT8]
|
typs[123] = types.NewSlice(typs[7])
|
||||||
typs[124] = functype(nil, []*Node{anonfield(typs[123]), anonfield(typs[123])}, nil)
|
typs[124] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
|
||||||
typs[125] = types.Types[TUINT16]
|
typs[125] = types.Types[TUINT8]
|
||||||
typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
|
typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
|
||||||
typs[127] = functype(nil, []*Node{anonfield(typs[64]), anonfield(typs[64])}, nil)
|
typs[127] = types.Types[TUINT16]
|
||||||
typs[128] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, nil)
|
typs[128] = functype(nil, []*Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
|
||||||
|
typs[129] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
|
||||||
|
typs[130] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
|
||||||
return typs[:]
|
return typs[:]
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ package runtime
|
|||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
func newobject(typ *byte) *any
|
func newobject(typ *byte) *any
|
||||||
|
func mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
|
||||||
func panicdivide()
|
func panicdivide()
|
||||||
func panicshift()
|
func panicshift()
|
||||||
func panicmakeslicelen()
|
func panicmakeslicelen()
|
||||||
@ -174,6 +175,7 @@ func block()
|
|||||||
|
|
||||||
func makeslice(typ *byte, len int, cap int) unsafe.Pointer
|
func makeslice(typ *byte, len int, cap int) unsafe.Pointer
|
||||||
func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
|
func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
|
||||||
|
func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
|
||||||
func growslice(typ *byte, old []any, cap int) (ary []any)
|
func growslice(typ *byte, old []any, cap int) (ary []any)
|
||||||
func memmove(to *any, frm *any, length uintptr)
|
func memmove(to *any, frm *any, length uintptr)
|
||||||
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||||
|
@ -1165,92 +1165,93 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var opprec = []int{
|
var opprec = []int{
|
||||||
OALIGNOF: 8,
|
OALIGNOF: 8,
|
||||||
OAPPEND: 8,
|
OAPPEND: 8,
|
||||||
OBYTES2STR: 8,
|
OBYTES2STR: 8,
|
||||||
OARRAYLIT: 8,
|
OARRAYLIT: 8,
|
||||||
OSLICELIT: 8,
|
OSLICELIT: 8,
|
||||||
ORUNES2STR: 8,
|
ORUNES2STR: 8,
|
||||||
OCALLFUNC: 8,
|
OCALLFUNC: 8,
|
||||||
OCALLINTER: 8,
|
OCALLINTER: 8,
|
||||||
OCALLMETH: 8,
|
OCALLMETH: 8,
|
||||||
OCALL: 8,
|
OCALL: 8,
|
||||||
OCAP: 8,
|
OCAP: 8,
|
||||||
OCLOSE: 8,
|
OCLOSE: 8,
|
||||||
OCONVIFACE: 8,
|
OCONVIFACE: 8,
|
||||||
OCONVNOP: 8,
|
OCONVNOP: 8,
|
||||||
OCONV: 8,
|
OCONV: 8,
|
||||||
OCOPY: 8,
|
OCOPY: 8,
|
||||||
ODELETE: 8,
|
ODELETE: 8,
|
||||||
OGETG: 8,
|
OGETG: 8,
|
||||||
OLEN: 8,
|
OLEN: 8,
|
||||||
OLITERAL: 8,
|
OLITERAL: 8,
|
||||||
OMAKESLICE: 8,
|
OMAKESLICE: 8,
|
||||||
OMAKE: 8,
|
OMAKESLICECOPY: 8,
|
||||||
OMAPLIT: 8,
|
OMAKE: 8,
|
||||||
ONAME: 8,
|
OMAPLIT: 8,
|
||||||
ONEW: 8,
|
ONAME: 8,
|
||||||
ONONAME: 8,
|
ONEW: 8,
|
||||||
OOFFSETOF: 8,
|
ONONAME: 8,
|
||||||
OPACK: 8,
|
OOFFSETOF: 8,
|
||||||
OPANIC: 8,
|
OPACK: 8,
|
||||||
OPAREN: 8,
|
OPANIC: 8,
|
||||||
OPRINTN: 8,
|
OPAREN: 8,
|
||||||
OPRINT: 8,
|
OPRINTN: 8,
|
||||||
ORUNESTR: 8,
|
OPRINT: 8,
|
||||||
OSIZEOF: 8,
|
ORUNESTR: 8,
|
||||||
OSTR2BYTES: 8,
|
OSIZEOF: 8,
|
||||||
OSTR2RUNES: 8,
|
OSTR2BYTES: 8,
|
||||||
OSTRUCTLIT: 8,
|
OSTR2RUNES: 8,
|
||||||
OTARRAY: 8,
|
OSTRUCTLIT: 8,
|
||||||
OTCHAN: 8,
|
OTARRAY: 8,
|
||||||
OTFUNC: 8,
|
OTCHAN: 8,
|
||||||
OTINTER: 8,
|
OTFUNC: 8,
|
||||||
OTMAP: 8,
|
OTINTER: 8,
|
||||||
OTSTRUCT: 8,
|
OTMAP: 8,
|
||||||
OINDEXMAP: 8,
|
OTSTRUCT: 8,
|
||||||
OINDEX: 8,
|
OINDEXMAP: 8,
|
||||||
OSLICE: 8,
|
OINDEX: 8,
|
||||||
OSLICESTR: 8,
|
OSLICE: 8,
|
||||||
OSLICEARR: 8,
|
OSLICESTR: 8,
|
||||||
OSLICE3: 8,
|
OSLICEARR: 8,
|
||||||
OSLICE3ARR: 8,
|
OSLICE3: 8,
|
||||||
OSLICEHEADER: 8,
|
OSLICE3ARR: 8,
|
||||||
ODOTINTER: 8,
|
OSLICEHEADER: 8,
|
||||||
ODOTMETH: 8,
|
ODOTINTER: 8,
|
||||||
ODOTPTR: 8,
|
ODOTMETH: 8,
|
||||||
ODOTTYPE2: 8,
|
ODOTPTR: 8,
|
||||||
ODOTTYPE: 8,
|
ODOTTYPE2: 8,
|
||||||
ODOT: 8,
|
ODOTTYPE: 8,
|
||||||
OXDOT: 8,
|
ODOT: 8,
|
||||||
OCALLPART: 8,
|
OXDOT: 8,
|
||||||
OPLUS: 7,
|
OCALLPART: 8,
|
||||||
ONOT: 7,
|
OPLUS: 7,
|
||||||
OBITNOT: 7,
|
ONOT: 7,
|
||||||
ONEG: 7,
|
OBITNOT: 7,
|
||||||
OADDR: 7,
|
ONEG: 7,
|
||||||
ODEREF: 7,
|
OADDR: 7,
|
||||||
ORECV: 7,
|
ODEREF: 7,
|
||||||
OMUL: 6,
|
ORECV: 7,
|
||||||
ODIV: 6,
|
OMUL: 6,
|
||||||
OMOD: 6,
|
ODIV: 6,
|
||||||
OLSH: 6,
|
OMOD: 6,
|
||||||
ORSH: 6,
|
OLSH: 6,
|
||||||
OAND: 6,
|
ORSH: 6,
|
||||||
OANDNOT: 6,
|
OAND: 6,
|
||||||
OADD: 5,
|
OANDNOT: 6,
|
||||||
OSUB: 5,
|
OADD: 5,
|
||||||
OOR: 5,
|
OSUB: 5,
|
||||||
OXOR: 5,
|
OOR: 5,
|
||||||
OEQ: 4,
|
OXOR: 5,
|
||||||
OLT: 4,
|
OEQ: 4,
|
||||||
OLE: 4,
|
OLT: 4,
|
||||||
OGE: 4,
|
OLE: 4,
|
||||||
OGT: 4,
|
OGE: 4,
|
||||||
ONE: 4,
|
OGT: 4,
|
||||||
OSEND: 3,
|
ONE: 4,
|
||||||
OANDAND: 2,
|
OSEND: 3,
|
||||||
OOROR: 1,
|
OANDAND: 2,
|
||||||
|
OOROR: 1,
|
||||||
|
|
||||||
// Statements handled by stmtfmt
|
// Statements handled by stmtfmt
|
||||||
OAS: -1,
|
OAS: -1,
|
||||||
@ -1572,6 +1573,9 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
|
|||||||
}
|
}
|
||||||
mode.Fprintf(s, "make(%v)", n.Type)
|
mode.Fprintf(s, "make(%v)", n.Type)
|
||||||
|
|
||||||
|
case OMAKESLICECOPY:
|
||||||
|
mode.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type, n.Left, n.Right)
|
||||||
|
|
||||||
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
||||||
// Unary
|
// Unary
|
||||||
mode.Fprintf(s, "%#v", n.Op)
|
mode.Fprintf(s, "%#v", n.Op)
|
||||||
|
@ -82,89 +82,90 @@ func _() {
|
|||||||
_ = x[OMAKECHAN-71]
|
_ = x[OMAKECHAN-71]
|
||||||
_ = x[OMAKEMAP-72]
|
_ = x[OMAKEMAP-72]
|
||||||
_ = x[OMAKESLICE-73]
|
_ = x[OMAKESLICE-73]
|
||||||
_ = x[OMUL-74]
|
_ = x[OMAKESLICECOPY-74]
|
||||||
_ = x[ODIV-75]
|
_ = x[OMUL-75]
|
||||||
_ = x[OMOD-76]
|
_ = x[ODIV-76]
|
||||||
_ = x[OLSH-77]
|
_ = x[OMOD-77]
|
||||||
_ = x[ORSH-78]
|
_ = x[OLSH-78]
|
||||||
_ = x[OAND-79]
|
_ = x[ORSH-79]
|
||||||
_ = x[OANDNOT-80]
|
_ = x[OAND-80]
|
||||||
_ = x[ONEW-81]
|
_ = x[OANDNOT-81]
|
||||||
_ = x[ONEWOBJ-82]
|
_ = x[ONEW-82]
|
||||||
_ = x[ONOT-83]
|
_ = x[ONEWOBJ-83]
|
||||||
_ = x[OBITNOT-84]
|
_ = x[ONOT-84]
|
||||||
_ = x[OPLUS-85]
|
_ = x[OBITNOT-85]
|
||||||
_ = x[ONEG-86]
|
_ = x[OPLUS-86]
|
||||||
_ = x[OOROR-87]
|
_ = x[ONEG-87]
|
||||||
_ = x[OPANIC-88]
|
_ = x[OOROR-88]
|
||||||
_ = x[OPRINT-89]
|
_ = x[OPANIC-89]
|
||||||
_ = x[OPRINTN-90]
|
_ = x[OPRINT-90]
|
||||||
_ = x[OPAREN-91]
|
_ = x[OPRINTN-91]
|
||||||
_ = x[OSEND-92]
|
_ = x[OPAREN-92]
|
||||||
_ = x[OSLICE-93]
|
_ = x[OSEND-93]
|
||||||
_ = x[OSLICEARR-94]
|
_ = x[OSLICE-94]
|
||||||
_ = x[OSLICESTR-95]
|
_ = x[OSLICEARR-95]
|
||||||
_ = x[OSLICE3-96]
|
_ = x[OSLICESTR-96]
|
||||||
_ = x[OSLICE3ARR-97]
|
_ = x[OSLICE3-97]
|
||||||
_ = x[OSLICEHEADER-98]
|
_ = x[OSLICE3ARR-98]
|
||||||
_ = x[ORECOVER-99]
|
_ = x[OSLICEHEADER-99]
|
||||||
_ = x[ORECV-100]
|
_ = x[ORECOVER-100]
|
||||||
_ = x[ORUNESTR-101]
|
_ = x[ORECV-101]
|
||||||
_ = x[OSELRECV-102]
|
_ = x[ORUNESTR-102]
|
||||||
_ = x[OSELRECV2-103]
|
_ = x[OSELRECV-103]
|
||||||
_ = x[OIOTA-104]
|
_ = x[OSELRECV2-104]
|
||||||
_ = x[OREAL-105]
|
_ = x[OIOTA-105]
|
||||||
_ = x[OIMAG-106]
|
_ = x[OREAL-106]
|
||||||
_ = x[OCOMPLEX-107]
|
_ = x[OIMAG-107]
|
||||||
_ = x[OALIGNOF-108]
|
_ = x[OCOMPLEX-108]
|
||||||
_ = x[OOFFSETOF-109]
|
_ = x[OALIGNOF-109]
|
||||||
_ = x[OSIZEOF-110]
|
_ = x[OOFFSETOF-110]
|
||||||
_ = x[OBLOCK-111]
|
_ = x[OSIZEOF-111]
|
||||||
_ = x[OBREAK-112]
|
_ = x[OBLOCK-112]
|
||||||
_ = x[OCASE-113]
|
_ = x[OBREAK-113]
|
||||||
_ = x[OCONTINUE-114]
|
_ = x[OCASE-114]
|
||||||
_ = x[ODEFER-115]
|
_ = x[OCONTINUE-115]
|
||||||
_ = x[OEMPTY-116]
|
_ = x[ODEFER-116]
|
||||||
_ = x[OFALL-117]
|
_ = x[OEMPTY-117]
|
||||||
_ = x[OFOR-118]
|
_ = x[OFALL-118]
|
||||||
_ = x[OFORUNTIL-119]
|
_ = x[OFOR-119]
|
||||||
_ = x[OGOTO-120]
|
_ = x[OFORUNTIL-120]
|
||||||
_ = x[OIF-121]
|
_ = x[OGOTO-121]
|
||||||
_ = x[OLABEL-122]
|
_ = x[OIF-122]
|
||||||
_ = x[OGO-123]
|
_ = x[OLABEL-123]
|
||||||
_ = x[ORANGE-124]
|
_ = x[OGO-124]
|
||||||
_ = x[ORETURN-125]
|
_ = x[ORANGE-125]
|
||||||
_ = x[OSELECT-126]
|
_ = x[ORETURN-126]
|
||||||
_ = x[OSWITCH-127]
|
_ = x[OSELECT-127]
|
||||||
_ = x[OTYPESW-128]
|
_ = x[OSWITCH-128]
|
||||||
_ = x[OTCHAN-129]
|
_ = x[OTYPESW-129]
|
||||||
_ = x[OTMAP-130]
|
_ = x[OTCHAN-130]
|
||||||
_ = x[OTSTRUCT-131]
|
_ = x[OTMAP-131]
|
||||||
_ = x[OTINTER-132]
|
_ = x[OTSTRUCT-132]
|
||||||
_ = x[OTFUNC-133]
|
_ = x[OTINTER-133]
|
||||||
_ = x[OTARRAY-134]
|
_ = x[OTFUNC-134]
|
||||||
_ = x[ODDD-135]
|
_ = x[OTARRAY-135]
|
||||||
_ = x[OINLCALL-136]
|
_ = x[ODDD-136]
|
||||||
_ = x[OEFACE-137]
|
_ = x[OINLCALL-137]
|
||||||
_ = x[OITAB-138]
|
_ = x[OEFACE-138]
|
||||||
_ = x[OIDATA-139]
|
_ = x[OITAB-139]
|
||||||
_ = x[OSPTR-140]
|
_ = x[OIDATA-140]
|
||||||
_ = x[OCLOSUREVAR-141]
|
_ = x[OSPTR-141]
|
||||||
_ = x[OCFUNC-142]
|
_ = x[OCLOSUREVAR-142]
|
||||||
_ = x[OCHECKNIL-143]
|
_ = x[OCFUNC-143]
|
||||||
_ = x[OVARDEF-144]
|
_ = x[OCHECKNIL-144]
|
||||||
_ = x[OVARKILL-145]
|
_ = x[OVARDEF-145]
|
||||||
_ = x[OVARLIVE-146]
|
_ = x[OVARKILL-146]
|
||||||
_ = x[ORESULT-147]
|
_ = x[OVARLIVE-147]
|
||||||
_ = x[OINLMARK-148]
|
_ = x[ORESULT-148]
|
||||||
_ = x[ORETJMP-149]
|
_ = x[OINLMARK-149]
|
||||||
_ = x[OGETG-150]
|
_ = x[ORETJMP-150]
|
||||||
_ = x[OEND-151]
|
_ = x[OGETG-151]
|
||||||
|
_ = x[OEND-152]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMULDIVMODLSHRSHANDANDNOTNEWNEWOBJNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKRETJMPGETGEND"
|
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNEWOBJNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKRETJMPGETGEND"
|
||||||
|
|
||||||
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 70, 82, 91, 100, 112, 121, 123, 126, 136, 143, 150, 157, 161, 165, 173, 181, 190, 198, 201, 206, 213, 220, 226, 235, 243, 251, 257, 261, 270, 277, 281, 284, 291, 299, 307, 314, 320, 323, 329, 336, 344, 348, 355, 363, 365, 367, 369, 371, 373, 375, 380, 385, 393, 396, 405, 408, 412, 420, 427, 436, 439, 442, 445, 448, 451, 454, 460, 463, 469, 472, 478, 482, 485, 489, 494, 499, 505, 510, 514, 519, 527, 535, 541, 550, 561, 568, 572, 579, 586, 594, 598, 602, 606, 613, 620, 628, 634, 639, 644, 648, 656, 661, 666, 670, 673, 681, 685, 687, 692, 694, 699, 705, 711, 717, 723, 728, 732, 739, 745, 750, 756, 759, 766, 771, 775, 780, 784, 794, 799, 807, 813, 820, 827, 833, 840, 846, 850, 853}
|
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 70, 82, 91, 100, 112, 121, 123, 126, 136, 143, 150, 157, 161, 165, 173, 181, 190, 198, 201, 206, 213, 220, 226, 235, 243, 251, 257, 261, 270, 277, 281, 284, 291, 299, 307, 314, 320, 323, 329, 336, 344, 348, 355, 363, 365, 367, 369, 371, 373, 375, 380, 385, 393, 396, 405, 408, 412, 420, 427, 436, 449, 452, 455, 458, 461, 464, 467, 473, 476, 482, 485, 491, 495, 498, 502, 507, 512, 518, 523, 527, 532, 540, 548, 554, 563, 574, 581, 585, 592, 599, 607, 611, 615, 619, 626, 633, 641, 647, 652, 657, 661, 669, 674, 679, 683, 686, 694, 698, 700, 705, 707, 712, 718, 724, 730, 736, 741, 745, 752, 758, 763, 769, 772, 779, 784, 788, 793, 797, 807, 812, 820, 826, 833, 840, 846, 853, 859, 863, 866}
|
||||||
|
|
||||||
func (i Op) String() string {
|
func (i Op) String() string {
|
||||||
if i >= Op(len(_Op_index)-1) {
|
if i >= Op(len(_Op_index)-1) {
|
||||||
|
@ -319,11 +319,82 @@ func (o *Order) cleanTemp(top ordermarker) {
|
|||||||
|
|
||||||
// stmtList orders each of the statements in the list.
|
// stmtList orders each of the statements in the list.
|
||||||
func (o *Order) stmtList(l Nodes) {
|
func (o *Order) stmtList(l Nodes) {
|
||||||
for _, n := range l.Slice() {
|
s := l.Slice()
|
||||||
o.stmt(n)
|
for i := range s {
|
||||||
|
orderMakeSliceCopy(s[i:])
|
||||||
|
o.stmt(s[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// orderMakeSliceCopy matches the pattern:
|
||||||
|
// m = OMAKESLICE([]T, x); OCOPY(m, s)
|
||||||
|
// and rewrites it to:
|
||||||
|
// m = OMAKESLICECOPY([]T, x, s); nil
|
||||||
|
func orderMakeSliceCopy(s []*Node) {
|
||||||
|
const go115makeslicecopy = true
|
||||||
|
if !go115makeslicecopy {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if Debug['N'] != 0 || instrumenting {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s) < 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
asn := s[0]
|
||||||
|
copyn := s[1]
|
||||||
|
|
||||||
|
if asn == nil || asn.Op != OAS {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if asn.Left.Op != ONAME {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if asn.Left.isBlank() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
maken := asn.Right
|
||||||
|
if maken == nil || maken.Op != OMAKESLICE {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if maken.Esc == EscNone {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if maken.Left == nil || maken.Right != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if copyn.Op != OCOPY {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if copyn.Left.Op != ONAME {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if asn.Left.Sym != copyn.Left.Sym {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if copyn.Right.Op != ONAME {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if copyn.Left.Sym == copyn.Right.Sym {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
maken.Op = OMAKESLICECOPY
|
||||||
|
maken.Right = copyn.Right
|
||||||
|
// Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
|
||||||
|
maken.SetBounded(maken.Left.Op == OLEN && samesafeexpr(maken.Left.Left, copyn.Right))
|
||||||
|
|
||||||
|
maken = typecheck(maken, ctxExpr)
|
||||||
|
|
||||||
|
s[1] = nil // remove separate copy call
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// edge inserts coverage instrumentation for libfuzzer.
|
// edge inserts coverage instrumentation for libfuzzer.
|
||||||
func (o *Order) edge() {
|
func (o *Order) edge() {
|
||||||
if Debug_libfuzzer == 0 {
|
if Debug_libfuzzer == 0 {
|
||||||
@ -1150,6 +1221,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
|||||||
OMAKECHAN,
|
OMAKECHAN,
|
||||||
OMAKEMAP,
|
OMAKEMAP,
|
||||||
OMAKESLICE,
|
OMAKESLICE,
|
||||||
|
OMAKESLICECOPY,
|
||||||
ONEW,
|
ONEW,
|
||||||
OREAL,
|
OREAL,
|
||||||
ORECOVER,
|
ORECOVER,
|
||||||
|
@ -208,12 +208,16 @@ func (n *Node) MarkNonNil() {
|
|||||||
// SetBounded indicates whether operation n does not need safety checks.
|
// SetBounded indicates whether operation n does not need safety checks.
|
||||||
// When n is an index or slice operation, n does not need bounds checks.
|
// When n is an index or slice operation, n does not need bounds checks.
|
||||||
// When n is a dereferencing operation, n does not need nil checks.
|
// When n is a dereferencing operation, n does not need nil checks.
|
||||||
|
// When n is a makeslice+copy operation, n does not need length and cap checks.
|
||||||
func (n *Node) SetBounded(b bool) {
|
func (n *Node) SetBounded(b bool) {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
|
case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
|
||||||
// No bounds checks needed.
|
// No bounds checks needed.
|
||||||
case ODOTPTR, ODEREF:
|
case ODOTPTR, ODEREF:
|
||||||
// No nil check needed.
|
// No nil check needed.
|
||||||
|
case OMAKESLICECOPY:
|
||||||
|
// No length and cap checks needed
|
||||||
|
// since new slice and copied over slice data have same length.
|
||||||
default:
|
default:
|
||||||
Fatalf("SetBounded(%v)", n)
|
Fatalf("SetBounded(%v)", n)
|
||||||
}
|
}
|
||||||
@ -714,30 +718,38 @@ const (
|
|||||||
ODCLCONST // const pi = 3.14
|
ODCLCONST // const pi = 3.14
|
||||||
ODCLTYPE // type Int int or type Int = int
|
ODCLTYPE // type Int int or type Int = int
|
||||||
|
|
||||||
ODELETE // delete(Left, Right)
|
ODELETE // delete(Left, Right)
|
||||||
ODOT // Left.Sym (Left is of struct type)
|
ODOT // Left.Sym (Left is of struct type)
|
||||||
ODOTPTR // Left.Sym (Left is of pointer to struct type)
|
ODOTPTR // Left.Sym (Left is of pointer to struct type)
|
||||||
ODOTMETH // Left.Sym (Left is non-interface, Right is method name)
|
ODOTMETH // Left.Sym (Left is non-interface, Right is method name)
|
||||||
ODOTINTER // Left.Sym (Left is interface, Right is method name)
|
ODOTINTER // Left.Sym (Left is interface, Right is method name)
|
||||||
OXDOT // Left.Sym (before rewrite to one of the preceding)
|
OXDOT // Left.Sym (before rewrite to one of the preceding)
|
||||||
ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved); after walk, .Right contains address of interface type descriptor and .Right.Right contains address of concrete type descriptor
|
ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved); after walk, .Right contains address of interface type descriptor and .Right.Right contains address of concrete type descriptor
|
||||||
ODOTTYPE2 // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, .Right contains address of interface type descriptor
|
ODOTTYPE2 // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, .Right contains address of interface type descriptor
|
||||||
OEQ // Left == Right
|
OEQ // Left == Right
|
||||||
ONE // Left != Right
|
ONE // Left != Right
|
||||||
OLT // Left < Right
|
OLT // Left < Right
|
||||||
OLE // Left <= Right
|
OLE // Left <= Right
|
||||||
OGE // Left >= Right
|
OGE // Left >= Right
|
||||||
OGT // Left > Right
|
OGT // Left > Right
|
||||||
ODEREF // *Left
|
ODEREF // *Left
|
||||||
OINDEX // Left[Right] (index of array or slice)
|
OINDEX // Left[Right] (index of array or slice)
|
||||||
OINDEXMAP // Left[Right] (index of map)
|
OINDEXMAP // Left[Right] (index of map)
|
||||||
OKEY // Left:Right (key:value in struct/array/map literal)
|
OKEY // Left:Right (key:value in struct/array/map literal)
|
||||||
OSTRUCTKEY // Sym:Left (key:value in struct literal, after type checking)
|
OSTRUCTKEY // Sym:Left (key:value in struct literal, after type checking)
|
||||||
OLEN // len(Left)
|
OLEN // len(Left)
|
||||||
OMAKE // make(List) (before type checking converts to one of the following)
|
OMAKE // make(List) (before type checking converts to one of the following)
|
||||||
OMAKECHAN // make(Type, Left) (type is chan)
|
OMAKECHAN // make(Type, Left) (type is chan)
|
||||||
OMAKEMAP // make(Type, Left) (type is map)
|
OMAKEMAP // make(Type, Left) (type is map)
|
||||||
OMAKESLICE // make(Type, Left, Right) (type is slice)
|
OMAKESLICE // make(Type, Left, Right) (type is slice)
|
||||||
|
OMAKESLICECOPY // makeslicecopy(Type, Left, Right) (type is slice; Left is length and Right is the copied from slice)
|
||||||
|
// OMAKESLICECOPY is created by the order pass and corresponds to:
|
||||||
|
// s = make(Type, Left); copy(s, Right)
|
||||||
|
//
|
||||||
|
// Bounded can be set on the node when Left == len(Right) is known at compile time.
|
||||||
|
//
|
||||||
|
// This node is created so the walk pass can optimize this pattern which would
|
||||||
|
// otherwise be hard to detect after the order pass.
|
||||||
OMUL // Left * Right
|
OMUL // Left * Right
|
||||||
ODIV // Left / Right
|
ODIV // Left / Right
|
||||||
OMOD // Left % Right
|
OMOD // Left % Right
|
||||||
|
@ -1149,6 +1149,49 @@ func typecheck1(n *Node, top int) (res *Node) {
|
|||||||
n.List.SetFirst(l)
|
n.List.SetFirst(l)
|
||||||
n.List.SetSecond(c)
|
n.List.SetSecond(c)
|
||||||
|
|
||||||
|
case OMAKESLICECOPY:
|
||||||
|
// Errors here are Fatalf instead of yyerror because only the compiler
|
||||||
|
// can construct an OMAKESLICECOPY node.
|
||||||
|
// Components used in OMAKESCLICECOPY that are supplied by parsed source code
|
||||||
|
// have already been typechecked in OMAKE and OCOPY earlier.
|
||||||
|
ok |= ctxExpr
|
||||||
|
|
||||||
|
t := n.Type
|
||||||
|
|
||||||
|
if t == nil {
|
||||||
|
Fatalf("no type specified for OMAKESLICECOPY")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !t.IsSlice() {
|
||||||
|
Fatalf("invalid type %v for OMAKESLICECOPY", n.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.Left == nil {
|
||||||
|
Fatalf("missing len argument for OMAKESLICECOPY")
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.Right == nil {
|
||||||
|
Fatalf("missing slice argument to copy for OMAKESLICECOPY")
|
||||||
|
}
|
||||||
|
|
||||||
|
n.Left = typecheck(n.Left, ctxExpr)
|
||||||
|
n.Right = typecheck(n.Right, ctxExpr)
|
||||||
|
|
||||||
|
n.Left = defaultlit(n.Left, types.Types[TINT])
|
||||||
|
|
||||||
|
if !n.Left.Type.IsInteger() && n.Type.Etype != TIDEAL {
|
||||||
|
yyerror("non-integer len argument in OMAKESLICECOPY")
|
||||||
|
}
|
||||||
|
|
||||||
|
if Isconst(n.Left, CTINT) {
|
||||||
|
if n.Left.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
|
||||||
|
Fatalf("len for OMAKESLICECOPY too large")
|
||||||
|
}
|
||||||
|
if n.Left.Int64() < 0 {
|
||||||
|
Fatalf("len for OMAKESLICECOPY must be non-negative")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case OSLICE, OSLICE3:
|
case OSLICE, OSLICE3:
|
||||||
ok |= ctxExpr
|
ok |= ctxExpr
|
||||||
n.Left = typecheck(n.Left, ctxExpr)
|
n.Left = typecheck(n.Left, ctxExpr)
|
||||||
|
@ -1390,6 +1390,63 @@ opswitch:
|
|||||||
n = m
|
n = m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OMAKESLICECOPY:
|
||||||
|
if n.Esc == EscNone {
|
||||||
|
Fatalf("OMAKESLICECOPY with EscNone: %v", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
t := n.Type
|
||||||
|
if t.Elem().NotInHeap() {
|
||||||
|
Fatalf("%v is go:notinheap; heap allocation disallowed", t.Elem())
|
||||||
|
}
|
||||||
|
|
||||||
|
length := conv(n.Left, types.Types[TINT])
|
||||||
|
copylen := nod(OLEN, n.Right, nil)
|
||||||
|
copyptr := nod(OSPTR, n.Right, nil)
|
||||||
|
|
||||||
|
if !types.Haspointers(t.Elem()) && n.Bounded() {
|
||||||
|
// When len(to)==len(from) and elements have no pointers:
|
||||||
|
// replace make+copy with runtime.mallocgc+runtime.memmove.
|
||||||
|
|
||||||
|
// We do not check for overflow of len(to)*elem.Width here
|
||||||
|
// since len(from) is an existing checked slice capacity
|
||||||
|
// with same elem.Width for the from slice.
|
||||||
|
size := nod(OMUL, conv(length, types.Types[TUINTPTR]), conv(nodintconst(t.Elem().Width), types.Types[TUINTPTR]))
|
||||||
|
|
||||||
|
// instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
|
||||||
|
fn := syslook("mallocgc")
|
||||||
|
sh := nod(OSLICEHEADER, nil, nil)
|
||||||
|
sh.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, size, nodnil(), nodbool(false))
|
||||||
|
sh.Left.MarkNonNil()
|
||||||
|
sh.List.Set2(length, length)
|
||||||
|
sh.Type = t
|
||||||
|
|
||||||
|
s := temp(t)
|
||||||
|
r := typecheck(nod(OAS, s, sh), ctxStmt)
|
||||||
|
r = walkexpr(r, init)
|
||||||
|
init.Append(r)
|
||||||
|
|
||||||
|
// instantiate memmove(to *any, frm *any, size uintptr)
|
||||||
|
fn = syslook("memmove")
|
||||||
|
fn = substArgTypes(fn, t.Elem(), t.Elem())
|
||||||
|
ncopy := mkcall1(fn, nil, init, nod(OSPTR, s, nil), copyptr, size)
|
||||||
|
ncopy = typecheck(ncopy, ctxStmt)
|
||||||
|
ncopy = walkexpr(ncopy, init)
|
||||||
|
init.Append(ncopy)
|
||||||
|
|
||||||
|
n = s
|
||||||
|
} else { // Replace make+copy with runtime.makeslicecopy.
|
||||||
|
// instantiate makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
|
||||||
|
fn := syslook("makeslicecopy")
|
||||||
|
s := nod(OSLICEHEADER, nil, nil)
|
||||||
|
s.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, typename(t.Elem()), length, copylen, conv(copyptr, types.Types[TUNSAFEPTR]))
|
||||||
|
s.Left.MarkNonNil()
|
||||||
|
s.List.Set2(length, length)
|
||||||
|
s.Type = t
|
||||||
|
n = typecheck(s, ctxExpr)
|
||||||
|
n = walkexpr(n, init)
|
||||||
|
}
|
||||||
|
|
||||||
case ORUNESTR:
|
case ORUNESTR:
|
||||||
a := nodnil()
|
a := nodnil()
|
||||||
if n.Esc == EscNone {
|
if n.Esc == EscNone {
|
||||||
@ -3772,6 +3829,9 @@ func candiscard(n *Node) bool {
|
|||||||
// Difficult to tell what sizes are okay.
|
// Difficult to tell what sizes are okay.
|
||||||
case OMAKESLICE:
|
case OMAKESLICE:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
case OMAKESLICECOPY:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) {
|
if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) {
|
||||||
|
@ -31,6 +31,55 @@ func panicmakeslicecap() {
|
|||||||
panic(errorString("makeslice: cap out of range"))
|
panic(errorString("makeslice: cap out of range"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// makeslicecopy allocates a slice of "tolen" elements of type "et",
|
||||||
|
// then copies "fromlen" elements of type "et" into that new allocation from "from".
|
||||||
|
func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer {
|
||||||
|
var tomem, copymem uintptr
|
||||||
|
if uintptr(tolen) > uintptr(fromlen) {
|
||||||
|
var overflow bool
|
||||||
|
tomem, overflow = math.MulUintptr(et.size, uintptr(tolen))
|
||||||
|
if overflow || tomem > maxAlloc || tolen < 0 {
|
||||||
|
panicmakeslicelen()
|
||||||
|
}
|
||||||
|
copymem = et.size * uintptr(fromlen)
|
||||||
|
} else {
|
||||||
|
// fromlen is a known good length providing and equal or greater than tolen,
|
||||||
|
// thereby making tolen a good slice length too as from and to slices have the
|
||||||
|
// same element width.
|
||||||
|
tomem = et.size * uintptr(tolen)
|
||||||
|
copymem = tomem
|
||||||
|
}
|
||||||
|
|
||||||
|
var to unsafe.Pointer
|
||||||
|
if et.ptrdata == 0 {
|
||||||
|
to = mallocgc(tomem, nil, false)
|
||||||
|
if copymem < tomem {
|
||||||
|
memclrNoHeapPointers(add(to, copymem), tomem-copymem)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
|
||||||
|
to = mallocgc(tomem, et, true)
|
||||||
|
if writeBarrier.enabled {
|
||||||
|
// Only shade the pointers in old.array since we know the destination slice to
|
||||||
|
// only contains nil pointers because it has been cleared during alloc.
|
||||||
|
bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if raceenabled {
|
||||||
|
callerpc := getcallerpc()
|
||||||
|
pc := funcPC(makeslicecopy)
|
||||||
|
racereadrangepc(from, copymem, callerpc, pc)
|
||||||
|
}
|
||||||
|
if msanenabled {
|
||||||
|
msanread(from, copymem)
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(to, from, copymem)
|
||||||
|
|
||||||
|
return to
|
||||||
|
}
|
||||||
|
|
||||||
func makeslice(et *_type, len, cap int) unsafe.Pointer {
|
func makeslice(et *_type, len, cap int) unsafe.Pointer {
|
||||||
mem, overflow := math.MulUintptr(et.size, uintptr(cap))
|
mem, overflow := math.MulUintptr(et.size, uintptr(cap))
|
||||||
if overflow || mem > maxAlloc || len < 0 || len > cap {
|
if overflow || mem > maxAlloc || len < 0 || len > cap {
|
||||||
|
@ -10,6 +10,84 @@ import (
|
|||||||
|
|
||||||
const N = 20
|
const N = 20
|
||||||
|
|
||||||
|
func BenchmarkMakeSliceCopy(b *testing.B) {
|
||||||
|
const length = 32
|
||||||
|
var bytes = make([]byte, 8*length)
|
||||||
|
var ints = make([]int, length)
|
||||||
|
var ptrs = make([]*byte, length)
|
||||||
|
b.Run("mallocmove", func(b *testing.B) {
|
||||||
|
b.Run("Byte", func(b *testing.B) {
|
||||||
|
var x []byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = make([]byte, len(bytes))
|
||||||
|
copy(x, bytes)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Int", func(b *testing.B) {
|
||||||
|
var x []int
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = make([]int, len(ints))
|
||||||
|
copy(x, ints)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Ptr", func(b *testing.B) {
|
||||||
|
var x []*byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = make([]*byte, len(ptrs))
|
||||||
|
copy(x, ptrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
b.Run("makecopy", func(b *testing.B) {
|
||||||
|
b.Run("Byte", func(b *testing.B) {
|
||||||
|
var x []byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = make([]byte, 8*length)
|
||||||
|
copy(x, bytes)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Int", func(b *testing.B) {
|
||||||
|
var x []int
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = make([]int, length)
|
||||||
|
copy(x, ints)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Ptr", func(b *testing.B) {
|
||||||
|
var x []*byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = make([]*byte, length)
|
||||||
|
copy(x, ptrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
b.Run("nilappend", func(b *testing.B) {
|
||||||
|
b.Run("Byte", func(b *testing.B) {
|
||||||
|
var x []byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = append([]byte(nil), bytes...)
|
||||||
|
_ = x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Int", func(b *testing.B) {
|
||||||
|
var x []int
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = append([]int(nil), ints...)
|
||||||
|
_ = x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("Ptr", func(b *testing.B) {
|
||||||
|
var x []*byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
x = append([]*byte(nil), ptrs...)
|
||||||
|
_ = x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
struct24 struct{ a, b, c int64 }
|
struct24 struct{ a, b, c int64 }
|
||||||
struct32 struct{ a, b, c, d int64 }
|
struct32 struct{ a, b, c, d int64 }
|
||||||
|
@ -104,6 +104,189 @@ func SliceExtensionInt64(s []int, l64 int64) []int {
|
|||||||
return append(s, make([]int, l64)...)
|
return append(s, make([]int, l64)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------ //
|
||||||
|
// Make+Copy //
|
||||||
|
// ------------------ //
|
||||||
|
|
||||||
|
// Issue #26252 - avoid memclr for make+copy
|
||||||
|
|
||||||
|
func SliceMakeCopyLen(s []int) []int {
|
||||||
|
// amd64:`.*runtime\.mallocgc`
|
||||||
|
// amd64:`.*runtime\.memmove`
|
||||||
|
// amd64:-`.*runtime\.makeslice`
|
||||||
|
a := make([]int, len(s))
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyLenPtr(s []*int) []*int {
|
||||||
|
// amd64:`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslice\(`
|
||||||
|
// amd64:-`.*runtime\.typedslicecopy
|
||||||
|
a := make([]*int, len(s))
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyConst(s []int) []int {
|
||||||
|
// amd64:`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslice\(`
|
||||||
|
// amd64:-`.*runtime\.memmove`
|
||||||
|
a := make([]int, 4)
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyConstPtr(s []*int) []*int {
|
||||||
|
// amd64:`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslice\(`
|
||||||
|
// amd64:-`.*runtime\.typedslicecopy
|
||||||
|
a := make([]*int, 4)
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptNoDeref(s []*int) []*int {
|
||||||
|
a := new([]*int)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
*a = make([]*int, 4)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
copy(*a, s)
|
||||||
|
return *a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptNoVar(s []*int) []*int {
|
||||||
|
a := make([][]*int, 1)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a[0] = make([]*int, 4)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
copy(a[0], s)
|
||||||
|
return a[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptBlank(s []*int) []*int {
|
||||||
|
var a []*int
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
_ = make([]*int, 4)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptNoMake(s []*int) []*int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:-`.*runtime\.objectnew`
|
||||||
|
a := *new([]*int)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptNoHeapAlloc(s []*int) int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
a := make([]*int, 4)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
copy(a, s)
|
||||||
|
return cap(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptNoCap(s []*int) []*int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]*int, 0, 4)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptNoCopy(s []*int) []*int {
|
||||||
|
copy := func(x, y []*int) {}
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]*int, 4)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptWrongOrder(s []*int) []*int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]*int, 4)
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
copy(s, a)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptWrongAssign(s []*int) []*int {
|
||||||
|
var a []*int
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
s = make([]*int, 4)
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
copy(a, s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptCopyLength(s []*int) (int, []*int) {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]*int, 4)
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
n := copy(a, s)
|
||||||
|
return n, a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptSelfCopy(s []*int) []*int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]*int, 4)
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
copy(a, a)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptTargetReference(s []*int) []*int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]*int, 4)
|
||||||
|
// amd64:`.*runtime\.typedslicecopy`
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
copy(a, s[:len(a)])
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoOptCap(s []int) []int {
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.makeslice\(`
|
||||||
|
a := make([]int, len(s), 9)
|
||||||
|
// amd64:-`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:`.*runtime\.memmove`
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceMakeCopyNoMemmoveDifferentLen(s []int) []int {
|
||||||
|
// amd64:`.*runtime\.makeslicecopy`
|
||||||
|
// amd64:-`.*runtime\.memmove`
|
||||||
|
a := make([]int, len(s)-1)
|
||||||
|
// amd64:-`.*runtime\.memmove`
|
||||||
|
copy(a, s)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------- //
|
// ---------------------- //
|
||||||
// Nil check of &s[0] //
|
// Nil check of &s[0] //
|
||||||
// ---------------------- //
|
// ---------------------- //
|
||||||
|
149
test/makeslice.go
Normal file
149
test/makeslice.go
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// run
|
||||||
|
|
||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := -1
|
||||||
|
testInts(uint64(n))
|
||||||
|
testBytes(uint64(n))
|
||||||
|
|
||||||
|
var t *byte
|
||||||
|
if unsafe.Sizeof(t) == 8 {
|
||||||
|
// Test mem > maxAlloc
|
||||||
|
testInts(1 << 59)
|
||||||
|
|
||||||
|
// Test elem.size*cap overflow
|
||||||
|
testInts(1<<63 - 1)
|
||||||
|
|
||||||
|
testInts(1<<64 - 1)
|
||||||
|
testBytes(1<<64 - 1)
|
||||||
|
} else {
|
||||||
|
testInts(1<<31 - 1)
|
||||||
|
|
||||||
|
// Test elem.size*cap overflow
|
||||||
|
testInts(1<<32 - 1)
|
||||||
|
testBytes(1<<32 - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldPanic(str string, f func()) {
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err == nil {
|
||||||
|
panic("did not panic")
|
||||||
|
}
|
||||||
|
s := err.(error).Error()
|
||||||
|
if !strings.Contains(s, str) {
|
||||||
|
panic("got panic " + s + ", want " + str)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInts(n uint64) {
|
||||||
|
testMakeInts(n)
|
||||||
|
testMakeCopyInts(n)
|
||||||
|
testMakeInAppendInts(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBytes(n uint64) {
|
||||||
|
testMakeBytes(n)
|
||||||
|
testMakeCopyBytes(n)
|
||||||
|
testMakeInAppendBytes(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test make panics for given length or capacity n.
|
||||||
|
func testMakeInts(n uint64) {
|
||||||
|
type T []int
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, int(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n)) })
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, uint(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, uint(n)) })
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, uint64(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, uint64(n)) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMakeBytes(n uint64) {
|
||||||
|
type T []byte
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, int(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n)) })
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, uint(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, uint(n)) })
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
|
||||||
|
shouldPanic("len out of range", func() { _ = make(T, uint64(n)) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = make(T, 0, uint64(n)) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test make+copy panics since the gc compiler optimizes these
|
||||||
|
// to runtime.makeslicecopy calls.
|
||||||
|
func testMakeCopyInts(n uint64) {
|
||||||
|
type T []int
|
||||||
|
var c = make(T, 8)
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, int(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, int(n)); copy(x, c) })
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, uint(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, uint(n)); copy(x, c) })
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, int64(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, int64(n)); copy(x, c) })
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, uint64(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, uint64(n)); copy(x, c) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMakeCopyBytes(n uint64) {
|
||||||
|
type T []byte
|
||||||
|
var c = make(T, 8)
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, int(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, int(n)); copy(x, c) })
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, uint(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, uint(n)); copy(x, c) })
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, int64(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, int64(n)); copy(x, c) })
|
||||||
|
shouldPanic("len out of range", func() { x := make(T, uint64(n)); copy(x, c) })
|
||||||
|
shouldPanic("cap out of range", func() { x := make(T, 0, uint64(n)); copy(x, c) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test make in append panics for int slices since the gc compiler optimizes makes in appends.
|
||||||
|
func testMakeInAppendInts(n uint64) {
|
||||||
|
type T []int
|
||||||
|
for _, length := range []int{0, 1} {
|
||||||
|
t := make(T, length)
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMakeInAppendBytes(n uint64) {
|
||||||
|
type T []byte
|
||||||
|
for _, length := range []int{0, 1} {
|
||||||
|
t := make(T, length)
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
|
||||||
|
shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
|
||||||
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user