已合并
runtime: add StepOpt experiment to optimize step function #57
spy20051623创建于 5月11日
runtime: add StepOpt experiment to optimize step function #57
已合并
共 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.hashtriemap | 132 | // WideTrie uses larger children group in sync.hashtriemap |
| 133 | WideTrie bool | 133 | WideTrie bool |
| 134 | + | ||
| 135 | + // StepOpt enables optimization for func step in package runtime | ||
| 136 | + StepOpt bool | ||
| 134 | } | 137 | } |
| @@ -7,6 +7,7 @@ package runtime | |||
| 7 | import ( | 7 | import ( |
| 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. |
| 1248 | func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) { | 1249 | func 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, true | 1273 | 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. |
| 1273 | func readvarint(p []byte) (read uint32, val uint32) { | 1320 | func readvarint(p []byte) (read uint32, val uint32) { |
| 1274 | var v, shift, n uint32 | 1321 | var v, shift, n uint32 |