mirror of
https://github.com/golang/go
synced 2024-11-23 19:40:08 -07:00
runtime: split PCs out of scase
Per-case PCs are only needed for race detector builds, so this allows skipping allocating stack space for them for non-race builds. It's possible to arrange the PCs and order arrays consecutively in memory so that we could just reuse the order0 pointer to identify both. However, there's more risk of that silently going wrong, so this commit passes them as separate arguments for now. We can revisit this in the future. Updates #40410. Change-Id: I8468bc25749e559891cb0cb007d1cc4a40fdd0f8 Reviewed-on: https://go-review.googlesource.com/c/go/+/245124 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
8a984e8e3f
commit
d36bc7d78a
@ -126,74 +126,74 @@ var runtimeDecls = [...]struct {
|
||||
{"selectnbsend", funcTag, 94},
|
||||
{"selectnbrecv", funcTag, 95},
|
||||
{"selectnbrecv2", funcTag, 97},
|
||||
{"selectsetpc", funcTag, 62},
|
||||
{"selectgo", funcTag, 98},
|
||||
{"selectsetpc", funcTag, 98},
|
||||
{"selectgo", funcTag, 99},
|
||||
{"block", funcTag, 9},
|
||||
{"makeslice", funcTag, 99},
|
||||
{"makeslice64", funcTag, 100},
|
||||
{"makeslicecopy", funcTag, 101},
|
||||
{"growslice", funcTag, 103},
|
||||
{"memmove", funcTag, 104},
|
||||
{"memclrNoHeapPointers", funcTag, 105},
|
||||
{"memclrHasPointers", funcTag, 105},
|
||||
{"memequal", funcTag, 106},
|
||||
{"memequal0", funcTag, 107},
|
||||
{"memequal8", funcTag, 107},
|
||||
{"memequal16", funcTag, 107},
|
||||
{"memequal32", funcTag, 107},
|
||||
{"memequal64", funcTag, 107},
|
||||
{"memequal128", funcTag, 107},
|
||||
{"f32equal", funcTag, 108},
|
||||
{"f64equal", funcTag, 108},
|
||||
{"c64equal", funcTag, 108},
|
||||
{"c128equal", funcTag, 108},
|
||||
{"strequal", funcTag, 108},
|
||||
{"interequal", funcTag, 108},
|
||||
{"nilinterequal", funcTag, 108},
|
||||
{"memhash", funcTag, 109},
|
||||
{"memhash0", funcTag, 110},
|
||||
{"memhash8", funcTag, 110},
|
||||
{"memhash16", funcTag, 110},
|
||||
{"memhash32", funcTag, 110},
|
||||
{"memhash64", funcTag, 110},
|
||||
{"memhash128", funcTag, 110},
|
||||
{"f32hash", funcTag, 110},
|
||||
{"f64hash", funcTag, 110},
|
||||
{"c64hash", funcTag, 110},
|
||||
{"c128hash", funcTag, 110},
|
||||
{"strhash", funcTag, 110},
|
||||
{"interhash", funcTag, 110},
|
||||
{"nilinterhash", funcTag, 110},
|
||||
{"int64div", funcTag, 111},
|
||||
{"uint64div", funcTag, 112},
|
||||
{"int64mod", funcTag, 111},
|
||||
{"uint64mod", funcTag, 112},
|
||||
{"float64toint64", funcTag, 113},
|
||||
{"float64touint64", funcTag, 114},
|
||||
{"float64touint32", funcTag, 115},
|
||||
{"int64tofloat64", funcTag, 116},
|
||||
{"uint64tofloat64", funcTag, 117},
|
||||
{"uint32tofloat64", funcTag, 118},
|
||||
{"complex128div", funcTag, 119},
|
||||
{"racefuncenter", funcTag, 120},
|
||||
{"makeslice", funcTag, 100},
|
||||
{"makeslice64", funcTag, 101},
|
||||
{"makeslicecopy", funcTag, 102},
|
||||
{"growslice", funcTag, 104},
|
||||
{"memmove", funcTag, 105},
|
||||
{"memclrNoHeapPointers", funcTag, 106},
|
||||
{"memclrHasPointers", funcTag, 106},
|
||||
{"memequal", funcTag, 107},
|
||||
{"memequal0", funcTag, 108},
|
||||
{"memequal8", funcTag, 108},
|
||||
{"memequal16", funcTag, 108},
|
||||
{"memequal32", funcTag, 108},
|
||||
{"memequal64", funcTag, 108},
|
||||
{"memequal128", funcTag, 108},
|
||||
{"f32equal", funcTag, 109},
|
||||
{"f64equal", funcTag, 109},
|
||||
{"c64equal", funcTag, 109},
|
||||
{"c128equal", funcTag, 109},
|
||||
{"strequal", funcTag, 109},
|
||||
{"interequal", funcTag, 109},
|
||||
{"nilinterequal", funcTag, 109},
|
||||
{"memhash", funcTag, 110},
|
||||
{"memhash0", funcTag, 111},
|
||||
{"memhash8", funcTag, 111},
|
||||
{"memhash16", funcTag, 111},
|
||||
{"memhash32", funcTag, 111},
|
||||
{"memhash64", funcTag, 111},
|
||||
{"memhash128", funcTag, 111},
|
||||
{"f32hash", funcTag, 111},
|
||||
{"f64hash", funcTag, 111},
|
||||
{"c64hash", funcTag, 111},
|
||||
{"c128hash", funcTag, 111},
|
||||
{"strhash", funcTag, 111},
|
||||
{"interhash", funcTag, 111},
|
||||
{"nilinterhash", funcTag, 111},
|
||||
{"int64div", funcTag, 112},
|
||||
{"uint64div", funcTag, 113},
|
||||
{"int64mod", funcTag, 112},
|
||||
{"uint64mod", funcTag, 113},
|
||||
{"float64toint64", funcTag, 114},
|
||||
{"float64touint64", funcTag, 115},
|
||||
{"float64touint32", funcTag, 116},
|
||||
{"int64tofloat64", funcTag, 117},
|
||||
{"uint64tofloat64", funcTag, 118},
|
||||
{"uint32tofloat64", funcTag, 119},
|
||||
{"complex128div", funcTag, 120},
|
||||
{"racefuncenter", funcTag, 121},
|
||||
{"racefuncenterfp", funcTag, 9},
|
||||
{"racefuncexit", funcTag, 9},
|
||||
{"raceread", funcTag, 120},
|
||||
{"racewrite", funcTag, 120},
|
||||
{"racereadrange", funcTag, 121},
|
||||
{"racewriterange", funcTag, 121},
|
||||
{"msanread", funcTag, 121},
|
||||
{"msanwrite", funcTag, 121},
|
||||
{"checkptrAlignment", funcTag, 122},
|
||||
{"checkptrArithmetic", funcTag, 124},
|
||||
{"libfuzzerTraceCmp1", funcTag, 126},
|
||||
{"libfuzzerTraceCmp2", funcTag, 128},
|
||||
{"libfuzzerTraceCmp4", funcTag, 129},
|
||||
{"libfuzzerTraceCmp8", funcTag, 130},
|
||||
{"libfuzzerTraceConstCmp1", funcTag, 126},
|
||||
{"libfuzzerTraceConstCmp2", funcTag, 128},
|
||||
{"libfuzzerTraceConstCmp4", funcTag, 129},
|
||||
{"libfuzzerTraceConstCmp8", funcTag, 130},
|
||||
{"raceread", funcTag, 121},
|
||||
{"racewrite", funcTag, 121},
|
||||
{"racereadrange", funcTag, 122},
|
||||
{"racewriterange", funcTag, 122},
|
||||
{"msanread", funcTag, 122},
|
||||
{"msanwrite", funcTag, 122},
|
||||
{"checkptrAlignment", funcTag, 123},
|
||||
{"checkptrArithmetic", funcTag, 125},
|
||||
{"libfuzzerTraceCmp1", funcTag, 127},
|
||||
{"libfuzzerTraceCmp2", funcTag, 129},
|
||||
{"libfuzzerTraceCmp4", funcTag, 130},
|
||||
{"libfuzzerTraceCmp8", funcTag, 131},
|
||||
{"libfuzzerTraceConstCmp1", funcTag, 127},
|
||||
{"libfuzzerTraceConstCmp2", funcTag, 129},
|
||||
{"libfuzzerTraceConstCmp4", funcTag, 130},
|
||||
{"libfuzzerTraceConstCmp8", funcTag, 131},
|
||||
{"x86HasPOPCNT", varTag, 6},
|
||||
{"x86HasSSE41", varTag, 6},
|
||||
{"x86HasFMA", varTag, 6},
|
||||
@ -202,7 +202,7 @@ var runtimeDecls = [...]struct {
|
||||
}
|
||||
|
||||
func runtimeTypes() []*types.Type {
|
||||
var typs [131]*types.Type
|
||||
var typs [132]*types.Type
|
||||
typs[0] = types.Bytetype
|
||||
typs[1] = types.NewPtr(typs[0])
|
||||
typs[2] = types.Types[TANY]
|
||||
@ -301,38 +301,39 @@ func runtimeTypes() []*types.Type {
|
||||
typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
|
||||
typs[96] = types.NewPtr(typs[6])
|
||||
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[1]), anonfield(typs[15])}, []*Node{anonfield(typs[15]), anonfield(typs[6])})
|
||||
typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])})
|
||||
typs[100] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[7])})
|
||||
typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*Node{anonfield(typs[7])})
|
||||
typs[102] = types.NewSlice(typs[2])
|
||||
typs[103] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[102]), anonfield(typs[15])}, []*Node{anonfield(typs[102])})
|
||||
typs[104] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
|
||||
typs[105] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
|
||||
typs[106] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*Node{anonfield(typs[6])})
|
||||
typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
|
||||
typs[108] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
|
||||
typs[109] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
|
||||
typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
|
||||
typs[111] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])})
|
||||
typs[112] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])})
|
||||
typs[113] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])})
|
||||
typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])})
|
||||
typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[65])})
|
||||
typs[116] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])})
|
||||
typs[117] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
|
||||
typs[118] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])})
|
||||
typs[119] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
|
||||
typs[120] = functype(nil, []*Node{anonfield(typs[5])}, nil)
|
||||
typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
|
||||
typs[122] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
|
||||
typs[123] = types.NewSlice(typs[7])
|
||||
typs[124] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
|
||||
typs[125] = types.Types[TUINT8]
|
||||
typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
|
||||
typs[127] = types.Types[TUINT16]
|
||||
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)
|
||||
typs[98] = functype(nil, []*Node{anonfield(typs[63])}, nil)
|
||||
typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15])}, []*Node{anonfield(typs[15]), anonfield(typs[6])})
|
||||
typs[100] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])})
|
||||
typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[7])})
|
||||
typs[102] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*Node{anonfield(typs[7])})
|
||||
typs[103] = types.NewSlice(typs[2])
|
||||
typs[104] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*Node{anonfield(typs[103])})
|
||||
typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
|
||||
typs[106] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
|
||||
typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*Node{anonfield(typs[6])})
|
||||
typs[108] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
|
||||
typs[109] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
|
||||
typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
|
||||
typs[111] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
|
||||
typs[112] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])})
|
||||
typs[113] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])})
|
||||
typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])})
|
||||
typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])})
|
||||
typs[116] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[65])})
|
||||
typs[117] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])})
|
||||
typs[118] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
|
||||
typs[119] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])})
|
||||
typs[120] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
|
||||
typs[121] = functype(nil, []*Node{anonfield(typs[5])}, nil)
|
||||
typs[122] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
|
||||
typs[123] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
|
||||
typs[124] = types.NewSlice(typs[7])
|
||||
typs[125] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[124])}, nil)
|
||||
typs[126] = types.Types[TUINT8]
|
||||
typs[127] = functype(nil, []*Node{anonfield(typs[126]), anonfield(typs[126])}, nil)
|
||||
typs[128] = types.Types[TUINT16]
|
||||
typs[129] = functype(nil, []*Node{anonfield(typs[128]), anonfield(typs[128])}, nil)
|
||||
typs[130] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
|
||||
typs[131] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
|
||||
return typs[:]
|
||||
}
|
||||
|
@ -169,8 +169,8 @@ func selectnbsend(hchan chan<- any, elem *any) bool
|
||||
func selectnbrecv(elem *any, hchan <-chan any) bool
|
||||
func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool
|
||||
|
||||
func selectsetpc(cas *byte)
|
||||
func selectgo(cas0 *byte, order0 *byte, ncases int) (int, bool)
|
||||
func selectsetpc(pc *uintptr)
|
||||
func selectgo(cas0 *byte, order0 *byte, pc0 *uintptr, ncases int) (int, bool)
|
||||
func block()
|
||||
|
||||
func makeslice(typ *byte, len int, cap int) unsafe.Pointer
|
||||
|
@ -271,6 +271,14 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||
r = typecheck(r, ctxStmt)
|
||||
init = append(init, r)
|
||||
|
||||
var pc0, pcs *Node
|
||||
if flag_race {
|
||||
pcs = temp(types.NewArray(types.Types[TUINTPTR], int64(n)))
|
||||
pc0 = typecheck(nod(OADDR, nod(OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
|
||||
} else {
|
||||
pc0 = nodnil()
|
||||
}
|
||||
|
||||
// register cases
|
||||
for i, cas := range cases.Slice() {
|
||||
setlineno(cas)
|
||||
@ -324,8 +332,8 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||
|
||||
// TODO(mdempsky): There should be a cleaner way to
|
||||
// handle this.
|
||||
if instrumenting {
|
||||
r = mkcall("selectsetpc", nil, nil, bytePtrToIndex(selv, int64(i)))
|
||||
if flag_race {
|
||||
r = mkcall("selectsetpc", nil, nil, nod(OADDR, nod(OINDEX, pcs, nodintconst(int64(i))), nil))
|
||||
init = append(init, r)
|
||||
}
|
||||
}
|
||||
@ -337,13 +345,16 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||
r = nod(OAS2, nil, nil)
|
||||
r.List.Set2(chosen, recvOK)
|
||||
fn := syslook("selectgo")
|
||||
r.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), nodintconst(int64(n))))
|
||||
r.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(n))))
|
||||
r = typecheck(r, ctxStmt)
|
||||
init = append(init, r)
|
||||
|
||||
// selv and order are no longer alive after selectgo.
|
||||
init = append(init, nod(OVARKILL, selv, nil))
|
||||
init = append(init, nod(OVARKILL, order, nil))
|
||||
if flag_race {
|
||||
init = append(init, nod(OVARKILL, pcs, nil))
|
||||
}
|
||||
|
||||
// dispatch cases
|
||||
for i, cas := range cases.Slice() {
|
||||
@ -385,7 +396,6 @@ func scasetype() *types.Type {
|
||||
namedfield("c", types.Types[TUNSAFEPTR]),
|
||||
namedfield("elem", types.Types[TUNSAFEPTR]),
|
||||
namedfield("kind", types.Types[TUINT16]),
|
||||
namedfield("pc", types.Types[TUINTPTR]),
|
||||
})
|
||||
scase.SetNoalg(true)
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ type scase struct {
|
||||
c *hchan // chan
|
||||
elem unsafe.Pointer // data element
|
||||
kind uint16
|
||||
pc uintptr // race pc (for race detector / msan)
|
||||
}
|
||||
|
||||
var (
|
||||
@ -37,8 +36,8 @@ var (
|
||||
chanrecvpc = funcPC(chanrecv)
|
||||
)
|
||||
|
||||
func selectsetpc(cas *scase) {
|
||||
cas.pc = getcallerpc()
|
||||
func selectsetpc(pc *uintptr) {
|
||||
*pc = getcallerpc()
|
||||
}
|
||||
|
||||
func sellock(scases []scase, lockorder []uint16) {
|
||||
@ -108,11 +107,15 @@ func block() {
|
||||
// Both reside on the goroutine's stack (regardless of any escaping in
|
||||
// selectgo).
|
||||
//
|
||||
// For race detector builds, pc0 points to an array of type
|
||||
// [ncases]uintptr (also on the stack); for other builds, it's set to
|
||||
// nil.
|
||||
//
|
||||
// selectgo returns the index of the chosen scase, which matches the
|
||||
// ordinal position of its respective select{recv,send,default} call.
|
||||
// Also, if the chosen scase was a receive operation, it reports whether
|
||||
// a value was received.
|
||||
func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) {
|
||||
func selectgo(cas0 *scase, order0 *uint16, pc0 *uintptr, ncases int) (int, bool) {
|
||||
if debugSelect {
|
||||
print("select: cas0=", cas0, "\n")
|
||||
}
|
||||
@ -126,6 +129,21 @@ func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) {
|
||||
pollorder := order1[:ncases:ncases]
|
||||
lockorder := order1[ncases:][:ncases:ncases]
|
||||
|
||||
// Even when raceenabled is true, there might be select
|
||||
// statements in packages compiled without -race (e.g.,
|
||||
// ensureSigM in runtime/signal_unix.go).
|
||||
var pcs []uintptr
|
||||
if raceenabled && pc0 != nil {
|
||||
pc1 := (*[1 << 16]uintptr)(unsafe.Pointer(pc0))
|
||||
pcs = pc1[:ncases:ncases]
|
||||
}
|
||||
casePC := func(casi int) uintptr {
|
||||
if pcs == nil {
|
||||
return 0
|
||||
}
|
||||
return pcs[casi]
|
||||
}
|
||||
|
||||
var t0 int64
|
||||
if blockprofilerate > 0 {
|
||||
t0 = cputicks()
|
||||
@ -247,7 +265,7 @@ func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) {
|
||||
|
||||
case caseSend:
|
||||
if raceenabled {
|
||||
racereadpc(c.raceaddr(), cas.pc, chansendpc)
|
||||
racereadpc(c.raceaddr(), casePC(casi), chansendpc)
|
||||
}
|
||||
if c.closed != 0 {
|
||||
goto sclose
|
||||
@ -371,9 +389,9 @@ func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) {
|
||||
|
||||
if raceenabled {
|
||||
if cas.kind == caseRecv && cas.elem != nil {
|
||||
raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
|
||||
raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
|
||||
} else if cas.kind == caseSend {
|
||||
raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
|
||||
raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
|
||||
}
|
||||
}
|
||||
if msanenabled {
|
||||
@ -391,7 +409,7 @@ bufrecv:
|
||||
// can receive from buffer
|
||||
if raceenabled {
|
||||
if cas.elem != nil {
|
||||
raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
|
||||
raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
|
||||
}
|
||||
raceacquire(chanbuf(c, c.recvx))
|
||||
racerelease(chanbuf(c, c.recvx))
|
||||
@ -418,7 +436,7 @@ bufsend:
|
||||
if raceenabled {
|
||||
raceacquire(chanbuf(c, c.sendx))
|
||||
racerelease(chanbuf(c, c.sendx))
|
||||
raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
|
||||
raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
|
||||
}
|
||||
if msanenabled {
|
||||
msanread(cas.elem, c.elemtype.size)
|
||||
@ -456,7 +474,7 @@ rclose:
|
||||
send:
|
||||
// can send to a sleeping receiver (sg)
|
||||
if raceenabled {
|
||||
raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
|
||||
raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
|
||||
}
|
||||
if msanenabled {
|
||||
msanread(cas.elem, c.elemtype.size)
|
||||
@ -519,12 +537,18 @@ func reflect_rselect(cases []runtimeSelect) (int, bool) {
|
||||
case selectRecv:
|
||||
sel[i] = scase{kind: caseRecv, c: rc.ch, elem: rc.val}
|
||||
}
|
||||
if raceenabled || msanenabled {
|
||||
selectsetpc(&sel[i])
|
||||
}
|
||||
}
|
||||
|
||||
return selectgo(&sel[0], &order[0], len(cases))
|
||||
var pc0 *uintptr
|
||||
if raceenabled {
|
||||
pcs := make([]uintptr, len(cases))
|
||||
for i := range pcs {
|
||||
selectsetpc(&pcs[i])
|
||||
}
|
||||
pc0 = &pcs[0]
|
||||
}
|
||||
|
||||
return selectgo(&sel[0], &order[0], pc0, len(cases))
|
||||
}
|
||||
|
||||
func (q *waitq) dequeueSudoG(sgp *sudog) {
|
||||
|
Loading…
Reference in New Issue
Block a user