已合并
runtime: add StepOpt experiment to optimize step function #57
spy20051623创建于 5月11日
runtime: add StepOpt experiment to optimize step function #57
已合并
spy20051623创建于 5月11日
共 4 个文件变更+66-0
@@ -0,0 +1,8 @@
1+// Code generated by mkconsts.go. DO NOT EDIT.
2+ 
3+//go:build !goexperiment.stepopt
4+ 
5+package goexperiment
6+ 
7+const StepOpt = false
8+const StepOptInt = 0
@@ -0,0 +1,8 @@
1+// Code generated by mkconsts.go. DO NOT EDIT.
2+ 
3+//go:build goexperiment.stepopt
4+ 
5+package goexperiment
6+ 
7+const StepOpt = true
8+const StepOptInt = 1
@@ -131,4 +131,7 @@ type Flags struct {
131 131 
132 // WideTrie uses larger children group in sync.hashtriemap132 // WideTrie uses larger children group in sync.hashtriemap
133 WideTrie bool133 WideTrie bool
134+ 
135+ // StepOpt enables optimization for func step in package runtime
136+ StepOpt bool
134}137}
@@ -7,6 +7,7 @@ package runtime
7import (7import (
8 "internal/abi"8 "internal/abi"
9 "internal/goarch"9 "internal/goarch"
10+ "internal/goexperiment"
10 "internal/runtime/atomic"11 "internal/runtime/atomic"
11 "internal/runtime/sys"12 "internal/runtime/sys"
12 "unsafe"13 "unsafe"
@@ -1246,6 +1247,9 @@ func funcdata(f funcInfo, i uint8) unsafe.Pointer {
1246 1247 
1247// step advances to the next pc, value pair in the encoded table.1248// step advances to the next pc, value pair in the encoded table.
1248func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {1249func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
1250+ if goexperiment.StepOpt {
1251+ return step_exp(p, pc, val, first)
1252+ }
1249 // For both uvdelta and pcdelta, the common case (~70%)1253 // For both uvdelta and pcdelta, the common case (~70%)
1250 // is that they are a single byte. If so, avoid calling readvarint.1254 // is that they are a single byte. If so, avoid calling readvarint.
1251 uvdelta := uint32(p[0])1255 uvdelta := uint32(p[0])
@@ -1269,6 +1273,49 @@ func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool)
1269 return p, true1273 return p, true
1270}1274}
1271 1275 
1276+func step_exp(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
1277+ // For both uvdelta and pcdelta, the common case (~70%)
1278+ // is that they are a single byte. If so, avoid calling readvarint.
1279+ var n uint32
1280+ uvdelta := uint32(p[0])
1281+ if uvdelta == 0 && !first {
1282+ return nil, false
1283+ }
1284+ if uvdelta&0x80 == 0 {
1285+ n = 1
1286+ *val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
1287+ p = p[n:]
1288+ } else {
1289+ a := uint32(p[1])
1290+ if a&0x80 == 0 {
1291+ uvdelta = (uvdelta & 0x7f) | (a << 7)
1292+ n = 2
1293+ } else {
1294+ n, uvdelta = readvarint(p)
1295+ }
1296+ *val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
1297+ p = p[n:]
1298+ }
1299+ 
1300+ pcdelta := uint32(p[0]) // load 2-byte once
1301+ if pcdelta&0x80 == 0 {
1302+ n = 1
1303+ *pc += uintptr((pcdelta & 0xff) * sys.PCQuantum)
1304+ p = p[n:]
1305+ } else {
1306+ a := uint32(p[1])
1307+ if a&0x80 == 0 {
1308+ pcdelta = (pcdelta & 0x7f) | (a << 7)
1309+ n = 2
1310+ } else {
1311+ n, pcdelta = readvarint(p)
1312+ }
1313+ p = p[n:]
1314+ *pc += uintptr(pcdelta * sys.PCQuantum)
1315+ }
1316+ return p, true
1317+}
1318+ 
1272// readvarint reads a varint from p.1319// readvarint reads a varint from p.
1273func readvarint(p []byte) (read uint32, val uint32) {1320func readvarint(p []byte) (read uint32, val uint32) {
1274 var v, shift, n uint321321 var v, shift, n uint32