diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go index cec02220ae..e78b1ace74 100644 --- a/src/cmd/compile/internal/gc/builtin.go +++ b/src/cmd/compile/internal/gc/builtin.go @@ -28,82 +28,81 @@ const runtimeimport = "" + "\x00\x00:\tfr·3\x00\x00\x16\vwid·4\x00\x1bunsafe-uintptr\x01\x02\x00\t\x1d" + "slicestringcopy\x00\x04:X\x00\x00:Z\x00\x00\x01\x02\x00\t\rconvI2E\x00\x02:" + "\relem·2\x00\x00\x02:\vret·1\x00\x00\t\rconvI2I\x00\x04\x17\"\x06\x00\x00:\re" + - "lem·3\x00\x00\x02:f\x00\x00\t\rconvT2E\x00\x06\x17\"\x06\x00\x00\x17:j\x00\x00\x17:\vbuf" + - "·4\x00\x00\x02:f\x00\x00\t\rconvT2I\x00\x06\x17\"\vtab·2\x00\x00\x17:j\x00\x00\x17:n" + - "\x00\x00\x02:f\x00\x00\t\x11assertE2E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·" + - "2\x00\x00\x17:\vret·3\x00\x00\x00\t\x13assertE2E2\x00\x06\x17\"\x06\x00\x00:\x0fifac" + - "e·3\x00\x00\x17:\vret·4\x00\x00\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"v\x00\x00:x" + - "\x00\x00\x17:z\x00\x00\x00\t\x13assertE2I2\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00" + - "\t\x11assertE2T\x00\x06\x17\"v\x00\x00:x\x00\x00\x17:z\x00\x00\x00\t\x13assertE2T2" + - "\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"v\x00\x00:x" + - "\x00\x00\x17:z\x00\x00\x00\t\x13assertI2E2\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00" + - "\t\x11assertI2I\x00\x06\x17\"v\x00\x00:x\x00\x00\x17:z\x00\x00\x00\t\x13assertI2I2" + - "\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"v\x00\x00:x" + - "\x00\x00\x17:z\x00\x00\x00\t\x13assertI2T2\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00" + - "\t\x17panicdottype\x00\x06\x17\"\rhave·1\x00\x00\x17\"\rwant·2\x00\x00" + - "\x17\"~\x00\x00\x00\t\rifaceeq\x00\x04:\ti1·2\x00\x00:\ti2·3\x00\x00\x02\x00f\x00\x00" + - "\t\refaceeq\x00\x04:\x9e\x01\x00\x00:\xa0\x01\x00\x00\x02\x00f\x00\x00\t\rmakemap\x00\b\x17\"\x13" + - "mapType·2\x00\x00\n\rhint·3\x00\x00\x17:\x11mapbuf·4\x00\x00\x17:\x17" + - "bucketbuf·5\x00\x00\x02\x1d::\rhmap·1\x00\x00\t\x13mapaccess1" + - "\x00\x06\x17\"\xa6\x01\x00\x00\x1d::\rhmap·3\x00\x00\x17:\vkey·4\x00\x00\x02\x17:\vval\xc2" + - "\xb71\x00\x00\t!mapaccess1_fast32\x00\x06\x17\"\xa6\x01\x00\x00\x1d::\xb2\x01\x00\x00:\xb4" + - "\x01\x00\x00\x02\x17:\xb6\x01\x00\x00\t!mapaccess1_fast64\x00\x06\x17\"\xa6\x01\x00\x00\x1d::" + - "\xb2\x01\x00\x00:\xb4\x01\x00\x00\x02\x17:\xb6\x01\x00\x00\t#mapaccess1_faststr\x00\x06\x17\"" + - "\xa6\x01\x00\x00\x1d::\xb2\x01\x00\x00:\xb4\x01\x00\x00\x02\x17:\xb6\x01\x00\x00\t\x1bmapaccess1_fat\x00" + - "\b\x17\"\xa6\x01\x00\x00\x1d::\xb2\x01\x00\x00\x17:\xb4\x01\x00\x00\x17\"\rzero·5\x00\x00\x02\x17:\xb6\x01\x00\x00\t" + - "\x13mapaccess2\x00\x06\x17\"\x13mapType·3\x00\x00\x1d::\rhmap·4\x00" + - "\x00\x17:\vkey·5\x00\x00\x04\x17:\xb6\x01\x00\x00\x00\rpres·2\x00\x00\t!mapacces" + - "s2_fast32\x00\x06\x17\"\xc4\x01\x00\x00\x1d::\xc6\x01\x00\x00:\xc8\x01\x00\x00\x04\x17:\xb6\x01\x00\x00\x00\xca\x01\x00" + - "\x00\t!mapaccess2_fast64\x00\x06\x17\"\xc4\x01\x00\x00\x1d::\xc6\x01\x00\x00:\xc8\x01\x00\x00" + - "\x04\x17:\xb6\x01\x00\x00\x00\xca\x01\x00\x00\t#mapaccess2_faststr\x00\x06\x17\"\xc4\x01\x00\x00" + - "\x1d::\xc6\x01\x00\x00:\xc8\x01\x00\x00\x04\x17:\xb6\x01\x00\x00\x00\xca\x01\x00\x00\t\x1bmapaccess2_fat" + - "\x00\b\x17\"\xc4\x01\x00\x00\x1d::\xc6\x01\x00\x00\x17:\xc8\x01\x00\x00\x17\"\rzero·6\x00\x00\x04\x17:\xb6\x01\x00\x00" + - "\x00\xca\x01\x00\x00\t\x13mapassign1\x00\b\x17\"\x13mapType·1\x00\x00\x1d::\rhm" + - "ap·2\x00\x00\x17:\vkey·3\x00\x00\x17:\vval·4\x00\x00\x00\t\x15mapiteri" + - "nit\x00\x06\x17\"\xd8\x01\x00\x00\x1d::\xda\x01\x00\x00\x17:\x0fhiter·3\x00\x00\x00\t\x11mapdel" + - "ete\x00\x06\x17\"\xd8\x01\x00\x00\x1d::\xda\x01\x00\x00\x17:\xdc\x01\x00\x00\x00\t\x15mapiternext\x00\x02" + - "\x17:\x0fhiter·1\x00\x00\x00\t\x0fmakechan\x00\x04\x17\"\x15chanType·2" + - "\x00\x00\n\xa8\x01\x00\x00\x02\x1f\x06:\x0fhchan·1\x00\x00\t\x11chanrecv1\x00\x06\x17\"\x15ch" + - "anType·1\x00\x00\x1f\x02:\x0fhchan·2\x00\x00\x17:j\x00\x00\x00\t\x11chanrec" + - "v2\x00\x06\x17\"\xec\x01\x00\x00\x1f\x02:\x0fhchan·3\x00\x00\x17:\relem·4\x00\x00\x01\x00\x00\t" + - "\x11chansend1\x00\x06\x17\"\xf2\x01\x00\x00\x1f\x04:\xf4\x01\x00\x00\x17:j\x00\x00\x00\t\x11closech" + - "an\x00\x02:\xee\x01\x00\x00\x00\a\x17writeBarrier\x00\x15\x06\renabled\x00\x00\x00\vn" + - "eeded\x00\x00\x00\x05cgo\x00\x00\x00\t\x1dwritebarrierptr\x00\x04\x17:\vdst" + - "·1\x00\x00:\vsrc·2\x00\x00\x00\t\x17typedmemmove\x00\x06\x17\"v\x00\x00\x17:\v" + - "dst·2\x00\x00\x17:\vsrc·3\x00\x00\x00\t\x1btypedslicecopy\x00\x06\x17\"" + - "\x06\x00\x00:\vdst·3\x00\x00:\vsrc·4\x00\x00\x01\x02\x00\t\x17selectnbsend" + - "\x00\x06\x17\"\xec\x01\x00\x00\x1f\x04:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x01\x00\x00\t\x17selectnbrecv\x00\x06" + - "\x17\"\xec\x01\x00\x00\x17:j\x00\x00\x1f\x02:\x0fhchan·4\x00\x00\x01\x00\x00\t\x19selectnbre" + - "cv2\x00\b\x17\"\xec\x01\x00\x00\x17:j\x00\x00\x17\x00\x15received·4\x00\x00\x1f\x02:\x0fhcha" + - "n·5\x00\x00\x01\x00\x00\t\x11newselect\x00\x06\x17\"\vsel·1\x00\x00\n\x13selsi" + - "ze·2\x00\x00\b\rsize·3\x00\x00\x00\t\x13selectsend\x00\x06\x17\"\vsel\xc2" + - "\xb72\x00\x00\x1f\x04:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x02\x00\x15selected·1\x00\x00\t\x13selec" + - "trecv\x00\x06\x17\"\xb0\x02\x00\x00\x1f\x02:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x02\x00\xb2\x02\x00\x00\t\x15select" + - "recv2\x00\b\x17\"\xb0\x02\x00\x00\x1f\x02:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x17\x00\x15received·5" + - "\x00\x00\x02\x00\xb2\x02\x00\x00\t\x19selectdefault\x00\x02\x17\"\xb0\x02\x00\x00\x02\x00\xb2\x02\x00\x00\t\x0fs" + - "electgo\x00\x02\x17\"\xa8\x02\x00\x00\x00\t\tblock\x00\x00\x00\t\x11makeslice\x00\x06\x17" + - "\"\x06\x00\x00\x02\vlen·3\x00\x00\x02\vcap·4\x00\x00\x02\x11:\vary·1\x00\x00\t\x15ma" + - "keslice64\x00\x06\x17\"\x06\x00\x00\n\xc2\x02\x00\x00\n\xc4\x02\x00\x00\x02\x11:\xc6\x02\x00\x00\t\x11grows" + - "lice\x00\x06\x17\"\x06\x00\x00\x11:\vold·3\x00\x00\x02\xc4\x02\x00\x00\x02\x11:\xc6\x02\x00\x00\t\rmemm" + - "ove\x00\x06\x17:\tto·1\x00\x00\x17:\vfrm·2\x00\x00\x16\x11length·3\x00^\x00" + - "\t\vmemclr\x00\x04\x17\"\vptr·1\x00\x00\x16\x11length·2\x00^\x00\t\x0fmem" + - "equal\x00\x06\x17:\ax·2\x00\x00\x17:\ay·3\x00\x00\x16\rsize·4\x00^\x01\x00\x00\t" + - "\x11memequal8\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x13memequal16\x00" + - "\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x13memequal32\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02" + - "\x00\x00\x01\x00\x00\t\x13memequal64\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x15meme" + - "qual128\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x0fint64div\x00\x03\n\x00\n\x00" + - "\x01\n\x00\t\x11uint64div\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint64mod\x00\x03\n\x00\n\x00\x01" + - "\n\x00\t\x11uint64mod\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat64toint64\x00\x01" + - "\x1a\x00\x01\n\x00\t\x1dfloat64touint64\x00\x01\x1a\x00\x01\x14\x00\t\x1dfloat64to" + - "uint32\x00\x01\x1a\x00\x01\x12\x00\t\x1bint64tofloat64\x00\x01\n\x00\x01\x1a\x00\t\x1dui" + - "nt64tofloat64\x00\x01\x14\x00\x01\x1a\x00\t\x1duint32tofloat64\x00\x01\x12" + - "\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e\vnum·2\x00\x00\x1e\vden·3\x00" + - "\x00\x02\x1e\vquo·1\x00\x00\t\x19racefuncenter\x00\x01\x16^\x00\t\x17racefu" + - "ncexit\x00\x00\x00\t\x0fraceread\x00\x01\x16^\x00\t\x11racewrite\x00\x01\x16^\x00" + - "\t\x19racereadrange\x00\x04\x16\raddr·1\x00^\x16\rsize·2\x00^\x00" + - "\t\x1bracewriterange\x00\x04\x16\x94\x03\x00^\x16\x96\x03\x00^\x00\t\x0fmsanread\x00" + - "\x04\x16\x94\x03\x00^\x16\x96\x03\x00^\x00\t\x11msanwrite\x00\x04\x16\x94\x03\x00^\x16\x96\x03\x00^\x00\v\xf6\x01\v" + - "\x00\x01\x00\n$$\n" + "lem·3\x00\x00\x02:f\x00\x00\t\rconvT2E\x00\x04\x17\"\x06\x00\x00\x17:j\x00\x00\x02:f\x00\x00\t" + + "\rconvT2I\x00\x04\x17\"\vtab·2\x00\x00\x17:j\x00\x00\x02:f\x00\x00\t\x11assertE" + + "2E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·2\x00\x00\x17:\vret·3\x00\x00\x00\t" + + "\x13assertE2E2\x00\x06\x17\"\x06\x00\x00:\x0fiface·3\x00\x00\x17:\vret·4\x00" + + "\x00\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assert" + + "E2I2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x11assertE2T\x00\x06\x17\"t" + + "\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertE2T2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00" + + "\x00\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assert" + + "I2E2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x11assertI2I\x00\x06\x17\"t" + + "\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertI2I2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00" + + "\x00\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assert" + + "I2T2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x17panicdottype\x00\x06" + + "\x17\"\rhave·1\x00\x00\x17\"\rwant·2\x00\x00\x17\"||\x00\x00\x00\t\rifaceeq" + + "\x00\x04:\ti1·2\x00\x00:\ti2·3\x00\x00\x02\x00f\x00\x00\t\refaceeq\x00\x04:\x9c\x01\x00" + + "\x00:\x9e\x01\x00\x00\x02\x00f\x00\x00\t\rmakemap\x00\b\x17\"\x13mapType·2\x00\x00\n\rh" + + "int·3\x00\x00\x17:\x11mapbuf·4\x00\x00\x17:\x17bucketbuf·5\x00\x00\x02" + + "\x1d::\rhmap·1\x00\x00\t\x13mapaccess1\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\rhma" + + "p·3\x00\x00\x17:\vkey·4\x00\x00\x02\x17:\vval·1\x00\x00\t!mapaccess" + + "1_fast32\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00\x00\t!map" + + "access1_fast64\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00" + + "\x00\t#mapaccess1_faststr\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00" + + "\x00\x02\x17:\xb4\x01\x00\x00\t\x1bmapaccess1_fat\x00\b\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00\x17" + + ":\xb2\x01\x00\x00\x17\"\rzero·5\x00\x00\x02\x17:\xb4\x01\x00\x00\t\x13mapaccess2\x00\x06\x17\"" + + "\x13mapType·3\x00\x00\x1d::\rhmap·4\x00\x00\x17:\vkey·5\x00\x00\x04\x17:" + + "\xb4\x01\x00\x00\x00\rpres·2\x00\x00\t!mapaccess2_fast32\x00\x06\x17\"\xc2\x01" + + "\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t!mapaccess2_f" + + "ast64\x00\x06\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t#m" + + "apaccess2_faststr\x00\x06\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:" + + "\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t\x1bmapaccess2_fat\x00\b\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00" + + "\x17:\xc6\x01\x00\x00\x17\"\rzero·6\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t\x13mapassig" + + "n1\x00\b\x17\"\x13mapType·1\x00\x00\x1d::\rhmap·2\x00\x00\x17:\vkey·" + + "3\x00\x00\x17:\vval·4\x00\x00\x00\t\x15mapiterinit\x00\x06\x17\"\xd6\x01\x00\x00\x1d::\xd8" + + "\x01\x00\x00\x17:\x0fhiter·3\x00\x00\x00\t\x11mapdelete\x00\x06\x17\"\xd6\x01\x00\x00\x1d::\xd8" + + "\x01\x00\x00\x17:\xda\x01\x00\x00\x00\t\x15mapiternext\x00\x02\x17:\x0fhiter·1\x00\x00\x00\t" + + "\x0fmakechan\x00\x04\x17\"\x15chanType·2\x00\x00\n\xa6\x01\x00\x00\x02\x1f\x06:\x0fhch" + + "an·1\x00\x00\t\x11chanrecv1\x00\x06\x17\"\x15chanType·1\x00\x00\x1f\x02:\x0f" + + "hchan·2\x00\x00\x17:j\x00\x00\x00\t\x11chanrecv2\x00\x06\x17\"\xea\x01\x00\x00\x1f\x02:\x0fh" + + "chan·3\x00\x00\x17:\relem·4\x00\x00\x01\x00\x00\t\x11chansend1\x00\x06\x17\"\xf0" + + "\x01\x00\x00\x1f\x04:\xf2\x01\x00\x00\x17:j\x00\x00\x00\t\x11closechan\x00\x02:\xec\x01\x00\x00\x00\a\x17wri" + + "teBarrier\x00\x15\x06\renabled\x00\x00\x00\vneeded\x00\x00\x00\x05cgo\x00\x00\x00" + + "\t\x1dwritebarrierptr\x00\x04\x17:\vdst·1\x00\x00:\vsrc·2\x00\x00" + + "\x00\t\x17typedmemmove\x00\x06\x17\"t\x00\x00\x17:\vdst·2\x00\x00\x17:\vsrc\xc2" + + "\xb73\x00\x00\x00\t\x1btypedslicecopy\x00\x06\x17\"\x06\x00\x00:\vdst·3\x00\x00:\v" + + "src·4\x00\x00\x01\x02\x00\t\x17selectnbsend\x00\x06\x17\"\xea\x01\x00\x00\x1f\x04:\xf6\x01\x00\x00" + + "\x17:\xf8\x01\x00\x00\x01\x00\x00\t\x17selectnbrecv\x00\x06\x17\"\xea\x01\x00\x00\x17:j\x00\x00\x1f\x02:\x0f" + + "hchan·4\x00\x00\x01\x00\x00\t\x19selectnbrecv2\x00\b\x17\"\xea\x01\x00\x00\x17:j\x00" + + "\x00\x17\x00\x15received·4\x00\x00\x1f\x02:\x0fhchan·5\x00\x00\x01\x00\x00\t\x11news" + + "elect\x00\x06\x17\"\vsel·1\x00\x00\n\x13selsize·2\x00\x00\b\rsize·" + + "3\x00\x00\x00\t\x13selectsend\x00\x06\x17\"\vsel·2\x00\x00\x1f\x04:\xf6\x01\x00\x00\x17:\xf8\x01" + + "\x00\x00\x02\x00\x15selected·1\x00\x00\t\x13selectrecv\x00\x06\x17\"\xae\x02\x00\x00\x1f\x02" + + ":\xf6\x01\x00\x00\x17:\xf8\x01\x00\x00\x02\x00\xb0\x02\x00\x00\t\x15selectrecv2\x00\b\x17\"\xae\x02\x00\x00\x1f\x02" + + ":\xf6\x01\x00\x00\x17:\xf8\x01\x00\x00\x17\x00\x15received·5\x00\x00\x02\x00\xb0\x02\x00\x00\t\x19selec" + + "tdefault\x00\x02\x17\"\xae\x02\x00\x00\x02\x00\xb0\x02\x00\x00\t\x0fselectgo\x00\x02\x17\"\xa6\x02\x00\x00" + + "\x00\t\tblock\x00\x00\x00\t\x11makeslice\x00\x06\x17\"\x06\x00\x00\x02\vlen·3\x00\x00\x02" + + "\vcap·4\x00\x00\x02\x11:\vary·1\x00\x00\t\x15makeslice64\x00\x06\x17\"\x06\x00" + + "\x00\n\xc0\x02\x00\x00\n\xc2\x02\x00\x00\x02\x11:\xc4\x02\x00\x00\t\x11growslice\x00\x06\x17\"\x06\x00\x00\x11:\vo" + + "ld·3\x00\x00\x02\xc2\x02\x00\x00\x02\x11:\xc4\x02\x00\x00\t\rmemmove\x00\x06\x17:\tto·1\x00\x00" + + "\x17:\vfrm·2\x00\x00\x16\x11length·3\x00^\x00\t\vmemclr\x00\x04\x17\"\vpt" + + "r·1\x00\x00\x16\x11length·2\x00^\x00\t\x0fmemequal\x00\x06\x17:\ax·2\x00" + + "\x00\x17:\ay·3\x00\x00\x16\rsize·4\x00^\x01\x00\x00\t\x11memequal8\x00\x04\x17:\xdc" + + "\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00\x00\t\x13memequal16\x00\x04\x17:\xdc\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00" + + "\x00\t\x13memequal32\x00\x04\x17:\xdc\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00\x00\t\x13memequal" + + "64\x00\x04\x17:\xdc\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00\x00\t\x15memequal128\x00\x04\x17:\xdc\x02\x00\x00" + + "\x17:\xde\x02\x00\x00\x01\x00\x00\t\x0fint64div\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64div\x00" + + "\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint64mod\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64mod\x00\x03" + + "\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat64toint64\x00\x01\x1a\x00\x01\n\x00\t\x1dfloat64t" + + "ouint64\x00\x01\x1a\x00\x01\x14\x00\t\x1dfloat64touint32\x00\x01\x1a\x00\x01\x12\x00\t\x1b" + + "int64tofloat64\x00\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00\x01" + + "\x14\x00\x01\x1a\x00\t\x1duint32tofloat64\x00\x01\x12\x00\x01\x1a\x00\t\x19complex12" + + "8div\x00\x04\x1e\vnum·2\x00\x00\x1e\vden·3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19r" + + "acefuncenter\x00\x01\x16^\x00\t\x17racefuncexit\x00\x00\x00\t\x0frace" + + "read\x00\x01\x16^\x00\t\x11racewrite\x00\x01\x16^\x00\t\x19racereadrange" + + "\x00\x04\x16\raddr·1\x00^\x16\rsize·2\x00^\x00\t\x1bracewriterang" + + "e\x00\x04\x16\x92\x03\x00^\x16\x94\x03\x00^\x00\t\x0fmsanread\x00\x04\x16\x92\x03\x00^\x16\x94\x03\x00^\x00\t\x11m" + + "sanwrite\x00\x04\x16\x92\x03\x00^\x16\x94\x03\x00^\x00\v\xf6\x01\v\x00\x01\x00\n$$\n" const unsafeimport = "" + "version 2\n\n\x00\x00\x01\vunsafe\x00\t\x0fOffsetof\x00\x01:\x00\x01\x16\x00\t" + diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go index 762abbaf1c..4d71e4eec3 100644 --- a/src/cmd/compile/internal/gc/builtin/runtime.go +++ b/src/cmd/compile/internal/gc/builtin/runtime.go @@ -60,8 +60,8 @@ func slicestringcopy(to any, fr any) int // interface conversions func convI2E(elem any) (ret any) func convI2I(typ *byte, elem any) (ret any) -func convT2E(typ *byte, elem, buf *any) (ret any) -func convT2I(tab *byte, elem, buf *any) (ret any) +func convT2E(typ *byte, elem *any) (ret any) +func convT2I(tab *byte, elem *any) (ret any) // interface type assertions x.(T) func assertE2E(typ *byte, iface any, ret *any) diff --git a/src/cmd/compile/internal/gc/fixedbugs_test.go b/src/cmd/compile/internal/gc/fixedbugs_test.go index 19b1d9adf6..095b816a53 100644 --- a/src/cmd/compile/internal/gc/fixedbugs_test.go +++ b/src/cmd/compile/internal/gc/fixedbugs_test.go @@ -18,7 +18,7 @@ func makeT() T { var g T -var sink []byte +var sink interface{} func TestIssue15854(t *testing.T) { for i := 0; i < 10000; i++ { diff --git a/src/cmd/compile/internal/gc/iface_test.go b/src/cmd/compile/internal/gc/iface_test.go new file mode 100644 index 0000000000..21c6587217 --- /dev/null +++ b/src/cmd/compile/internal/gc/iface_test.go @@ -0,0 +1,128 @@ +// Copyright 2016 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 gc + +// Test to make sure we make copies of the values we +// put in interfaces. + +import ( + "testing" +) + +var x int + +func TestEfaceConv1(t *testing.T) { + a := 5 + i := interface{}(a) + a += 2 + if got := i.(int); got != 5 { + t.Errorf("wanted 5, got %d\n", got) + } +} + +func TestEfaceConv2(t *testing.T) { + a := 5 + sink = &a + i := interface{}(a) + a += 2 + if got := i.(int); got != 5 { + t.Errorf("wanted 5, got %d\n", got) + } +} + +func TestEfaceConv3(t *testing.T) { + x = 5 + if got := e2int3(x); got != 5 { + t.Errorf("wanted 5, got %d\n", got) + } +} + +//go:noinline +func e2int3(i interface{}) int { + x = 7 + return i.(int) +} + +func TestEfaceConv4(t *testing.T) { + a := 5 + if got := e2int4(a, &a); got != 5 { + t.Errorf("wanted 5, got %d\n", got) + } +} + +//go:noinline +func e2int4(i interface{}, p *int) int { + *p = 7 + return i.(int) +} + +type Int int + +var y Int + +type I interface { + foo() +} + +func (i Int) foo() { +} + +func TestIfaceConv1(t *testing.T) { + a := Int(5) + i := interface{}(a) + a += 2 + if got := i.(Int); got != 5 { + t.Errorf("wanted 5, got %d\n", int(got)) + } +} + +func TestIfaceConv2(t *testing.T) { + a := Int(5) + sink = &a + i := interface{}(a) + a += 2 + if got := i.(Int); got != 5 { + t.Errorf("wanted 5, got %d\n", int(got)) + } +} + +func TestIfaceConv3(t *testing.T) { + y = 5 + if got := i2Int3(y); got != 5 { + t.Errorf("wanted 5, got %d\n", int(got)) + } +} + +//go:noinline +func i2Int3(i I) Int { + y = 7 + return i.(Int) +} + +func TestIfaceConv4(t *testing.T) { + a := Int(5) + if got := i2Int4(a, &a); got != 5 { + t.Errorf("wanted 5, got %d\n", int(got)) + } +} + +//go:noinline +func i2Int4(i I, p *Int) Int { + *p = 7 + return i.(Int) +} + +func BenchmarkEfaceInteger(b *testing.B) { + sum := 0 + for i := 0; i < b.N; i++ { + sum += i2int(i) + } + sink = sum +} + +//go:noinline +func i2int(i interface{}) int { + return i.(int) +} diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 5d5022fea7..6373b5d08e 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -1058,6 +1058,25 @@ opswitch: n = l break } + // Optimize convT2{E,I} when T is not pointer-shaped. + // We make the interface by initializing a stack temporary to + // the value we want to put in the interface, then using the address of + // that stack temporary for the interface data word. + if !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024 { + tmp := temp(n.Left.Type) + init.Append(typecheck(nod(OAS, tmp, n.Left), Etop)) + var t *Node + if n.Type.IsEmptyInterface() { + t = typename(n.Left.Type) + } else { + t = itabname(n.Left.Type, n.Type) + } + l := nod(OEFACE, t, typecheck(nod(OADDR, tmp, nil), Erv)) + l.Type = n.Type + l.Typecheck = n.Typecheck + n = l + break + } var ll []*Node if n.Type.IsEmptyInterface() { @@ -1087,25 +1106,10 @@ opswitch: ll = append(ll, nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil)) } dowidth(n.Left.Type) - r := nodnil() - if n.Esc == EscNone && n.Left.Type.Width <= 1024 { - // Allocate stack buffer for value stored in interface. - r = temp(n.Left.Type) - r = nod(OAS, r, nil) // zero temp - r = typecheck(r, Etop) - init.Append(r) - r = nod(OADDR, r.Left, nil) - r = typecheck(r, Erv) - } - ll = append(ll, r) } fn := syslook(convFuncName(n.Left.Type, n.Type)) - if !n.Left.Type.IsInterface() { - fn = substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type) - } else { - fn = substArgTypes(fn, n.Left.Type, n.Type) - } + fn = substArgTypes(fn, n.Left.Type, n.Type) dowidth(fn.Type) n = nod(OCALL, fn, nil) n.List.Set(ll) diff --git a/src/runtime/iface.go b/src/runtime/iface.go index 7f24a6e69c..476ec7e8b2 100644 --- a/src/runtime/iface.go +++ b/src/runtime/iface.go @@ -152,7 +152,7 @@ func itabsinit() { unlock(&ifaceLock) } -func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e eface) { +func convT2E(t *_type, elem unsafe.Pointer) (e eface) { if raceenabled { raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E)) } @@ -162,18 +162,16 @@ func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e eface) { if isDirectIface(t) { throw("direct convT2E") } - if x == nil { - x = newobject(t) - // TODO: We allocate a zeroed object only to overwrite it with - // actual data. Figure out how to avoid zeroing. Also below in convT2I. - } + x := newobject(t) + // TODO: We allocate a zeroed object only to overwrite it with + // actual data. Figure out how to avoid zeroing. Also below in convT2I. typedmemmove(t, x, elem) e._type = t e.data = x return } -func convT2I(tab *itab, elem unsafe.Pointer, x unsafe.Pointer) (i iface) { +func convT2I(tab *itab, elem unsafe.Pointer) (i iface) { t := tab._type if raceenabled { raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2I)) @@ -184,9 +182,7 @@ func convT2I(tab *itab, elem unsafe.Pointer, x unsafe.Pointer) (i iface) { if isDirectIface(t) { throw("direct convT2I") } - if x == nil { - x = newobject(t) - } + x := newobject(t) typedmemmove(t, x, elem) i.tab = tab i.data = x diff --git a/test/live.go b/test/live.go index dabf82e8f2..2ae8b8f7b6 100644 --- a/test/live.go +++ b/test/live.go @@ -139,7 +139,9 @@ var i9 interface{} func f9() bool { g8() x := i9 - return x != interface{}(99.0i) // ERROR "live at call to convT2E: x.data x.type$" + y := interface{}(99.0i) // ERROR "live at call to convT2E: x.data x.type$" + i9 = y // make y escape so the line above has to call convT2E + return x != y } // liveness formerly confused by UNDEF followed by RET,