Skip to content

Commit e9cacb9

Browse files
Merge branch 'golang:master' into master
2 parents ca16999 + 6a08e80 commit e9cacb9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1365
-416
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
On Windows, the [OpenFile] `flag` parameter can now contain any combination of
2+
Windows-specific file flags, such as `FILE_FLAG_OVERLAPPED` and
3+
`FILE_FLAG_SEQUENTIAL_SCAN`, for control of file or device caching behavior,
4+
access modes, and other special-purpose flags.

src/bytes/bytes.go

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,41 +1117,34 @@ func trimRightUnicode(s []byte, cutset string) []byte {
11171117
// TrimSpace returns a subslice of s by slicing off all leading and
11181118
// trailing white space, as defined by Unicode.
11191119
func TrimSpace(s []byte) []byte {
1120-
// Fast path for ASCII: look for the first ASCII non-space byte
1121-
start := 0
1122-
for ; start < len(s); start++ {
1123-
c := s[start]
1120+
// Fast path for ASCII: look for the first ASCII non-space byte.
1121+
for lo, c := range s {
11241122
if c >= utf8.RuneSelf {
11251123
// If we run into a non-ASCII byte, fall back to the
1126-
// slower unicode-aware method on the remaining bytes
1127-
return TrimFunc(s[start:], unicode.IsSpace)
1128-
}
1129-
if asciiSpace[c] == 0 {
1130-
break
1124+
// slower unicode-aware method on the remaining bytes.
1125+
return TrimFunc(s[lo:], unicode.IsSpace)
11311126
}
1132-
}
1133-
1134-
// Now look for the first ASCII non-space byte from the end
1135-
stop := len(s)
1136-
for ; stop > start; stop-- {
1137-
c := s[stop-1]
1138-
if c >= utf8.RuneSelf {
1139-
return TrimFunc(s[start:stop], unicode.IsSpace)
1127+
if asciiSpace[c] != 0 {
1128+
continue
11401129
}
1141-
if asciiSpace[c] == 0 {
1142-
break
1130+
s = s[lo:]
1131+
// Now look for the first ASCII non-space byte from the end.
1132+
for hi := len(s) - 1; hi >= 0; hi-- {
1133+
c := s[hi]
1134+
if c >= utf8.RuneSelf {
1135+
return TrimFunc(s[:hi+1], unicode.IsSpace)
1136+
}
1137+
if asciiSpace[c] == 0 {
1138+
// At this point, s[:hi+1] starts and ends with ASCII
1139+
// non-space bytes, so we're done. Non-ASCII cases have
1140+
// already been handled above.
1141+
return s[:hi+1]
1142+
}
11431143
}
11441144
}
1145-
1146-
// At this point s[start:stop] starts and ends with an ASCII
1147-
// non-space bytes, so we're done. Non-ASCII cases have already
1148-
// been handled above.
1149-
if start == stop {
1150-
// Special case to preserve previous TrimLeftFunc behavior,
1151-
// returning nil instead of empty slice if all spaces.
1152-
return nil
1153-
}
1154-
return s[start:stop]
1145+
// Special case to preserve previous TrimLeftFunc behavior,
1146+
// returning nil instead of empty slice if all spaces.
1147+
return nil
11551148
}
11561149

11571150
// Runes interprets s as a sequence of UTF-8-encoded code points.

src/cmd/cgo/gcc.go

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"slices"
2828
"strconv"
2929
"strings"
30+
"sync/atomic"
3031
"unicode"
3132
"unicode/utf8"
3233

@@ -194,13 +195,12 @@ func (p *Package) Translate(f *File) {
194195
var conv typeConv
195196
conv.Init(p.PtrSize, p.IntSize)
196197

197-
p.typedefs = map[string]bool{}
198-
p.typedefList = nil
198+
ft := fileTypedefs{typedefs: make(map[string]bool)}
199199
numTypedefs := -1
200-
for len(p.typedefs) > numTypedefs {
201-
numTypedefs = len(p.typedefs)
200+
for len(ft.typedefs) > numTypedefs {
201+
numTypedefs = len(ft.typedefs)
202202
// Also ask about any typedefs we've seen so far.
203-
for _, info := range p.typedefList {
203+
for _, info := range ft.typedefList {
204204
if f.Name[info.typedef] != nil {
205205
continue
206206
}
@@ -213,7 +213,8 @@ func (p *Package) Translate(f *File) {
213213
}
214214
needType := p.guessKinds(f)
215215
if len(needType) > 0 {
216-
p.loadDWARF(f, &conv, needType)
216+
d := p.loadDWARF(f, &ft, needType)
217+
p.recordTypes(f, d, &conv)
217218
}
218219

219220
// In godefs mode we're OK with the typedefs, which
@@ -522,7 +523,7 @@ func (p *Package) guessKinds(f *File) []*Name {
522523
// loadDWARF parses the DWARF debug information generated
523524
// by gcc to learn the details of the constants, variables, and types
524525
// being referred to as C.xxx.
525-
func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
526+
func (p *Package) loadDWARF(f *File, ft *fileTypedefs, names []*Name) *debug {
526527
// Extract the types from the DWARF section of an object
527528
// from a well-formed C program. Gcc only generates DWARF info
528529
// for symbols in the object file, so it is not enough to print the
@@ -636,13 +637,28 @@ func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
636637
fatalf("malformed __cgo__ name: %s", name)
637638
}
638639
types[i] = t.Type
639-
p.recordTypedefs(t.Type, f.NamePos[names[i]])
640+
ft.recordTypedefs(t.Type, f.NamePos[names[i]])
640641
}
641642
if e.Tag != dwarf.TagCompileUnit {
642643
r.SkipChildren()
643644
}
644645
}
645646

647+
return &debug{names, types, ints, floats, strs}
648+
}
649+
650+
// debug is the data extracted by running an iteration of loadDWARF on a file.
651+
type debug struct {
652+
names []*Name
653+
types []dwarf.Type
654+
ints []int64
655+
floats []float64
656+
strs []string
657+
}
658+
659+
func (p *Package) recordTypes(f *File, data *debug, conv *typeConv) {
660+
names, types, ints, floats, strs := data.names, data.types, data.ints, data.floats, data.strs
661+
646662
// Record types and typedef information.
647663
for i, n := range names {
648664
if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
@@ -701,12 +717,17 @@ func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
701717
}
702718
}
703719

704-
// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
705-
func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
706-
p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
720+
type fileTypedefs struct {
721+
typedefs map[string]bool // type names that appear in the types of the objects we're interested in
722+
typedefList []typedefInfo
723+
}
724+
725+
// recordTypedefs remembers in ft.typedefs all the typedefs used in dtypes and its children.
726+
func (ft *fileTypedefs) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
727+
ft.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
707728
}
708729

709-
func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
730+
func (ft *fileTypedefs) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
710731
if dtype == nil {
711732
return
712733
}
@@ -720,25 +741,25 @@ func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[d
720741
// Don't look inside builtin types. There be dragons.
721742
return
722743
}
723-
if !p.typedefs[dt.Name] {
724-
p.typedefs[dt.Name] = true
725-
p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
726-
p.recordTypedefs1(dt.Type, pos, visited)
744+
if !ft.typedefs[dt.Name] {
745+
ft.typedefs[dt.Name] = true
746+
ft.typedefList = append(ft.typedefList, typedefInfo{dt.Name, pos})
747+
ft.recordTypedefs1(dt.Type, pos, visited)
727748
}
728749
case *dwarf.PtrType:
729-
p.recordTypedefs1(dt.Type, pos, visited)
750+
ft.recordTypedefs1(dt.Type, pos, visited)
730751
case *dwarf.ArrayType:
731-
p.recordTypedefs1(dt.Type, pos, visited)
752+
ft.recordTypedefs1(dt.Type, pos, visited)
732753
case *dwarf.QualType:
733-
p.recordTypedefs1(dt.Type, pos, visited)
754+
ft.recordTypedefs1(dt.Type, pos, visited)
734755
case *dwarf.FuncType:
735-
p.recordTypedefs1(dt.ReturnType, pos, visited)
756+
ft.recordTypedefs1(dt.ReturnType, pos, visited)
736757
for _, a := range dt.ParamType {
737-
p.recordTypedefs1(a, pos, visited)
758+
ft.recordTypedefs1(a, pos, visited)
738759
}
739760
case *dwarf.StructType:
740-
for _, f := range dt.Field {
741-
p.recordTypedefs1(f.Type, pos, visited)
761+
for _, l := range dt.Field {
762+
ft.recordTypedefs1(l.Type, pos, visited)
742763
}
743764
}
744765
}
@@ -1756,20 +1777,23 @@ func gccMachine() []string {
17561777
return nil
17571778
}
17581779

1780+
var n atomic.Int64
1781+
17591782
func gccTmp() string {
1760-
return *objDir + "_cgo_.o"
1783+
c := strconv.Itoa(int(n.Add(1)))
1784+
return *objDir + "_cgo_" + c + ".o"
17611785
}
17621786

17631787
// gccCmd returns the gcc command line to use for compiling
17641788
// the input.
1765-
func (p *Package) gccCmd() []string {
1789+
func (p *Package) gccCmd(ofile string) []string {
17661790
c := append(gccBaseCmd,
1767-
"-w", // no warnings
1768-
"-Wno-error", // warnings are not errors
1769-
"-o"+gccTmp(), // write object to tmp
1770-
"-gdwarf-2", // generate DWARF v2 debugging symbols
1771-
"-c", // do not link
1772-
"-xc", // input language is C
1791+
"-w", // no warnings
1792+
"-Wno-error", // warnings are not errors
1793+
"-o"+ofile, // write object to tmp
1794+
"-gdwarf-2", // generate DWARF v2 debugging symbols
1795+
"-c", // do not link
1796+
"-xc", // input language is C
17731797
)
17741798
if p.GccIsClang {
17751799
c = append(c,
@@ -1806,7 +1830,8 @@ func (p *Package) gccCmd() []string {
18061830
// gccDebug runs gcc -gdwarf-2 over the C program stdin and
18071831
// returns the corresponding DWARF data and, if present, debug data block.
18081832
func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
1809-
runGcc(stdin, p.gccCmd())
1833+
ofile := gccTmp()
1834+
runGcc(stdin, p.gccCmd(ofile))
18101835

18111836
isDebugInts := func(s string) bool {
18121837
// Some systems use leading _ to denote non-assembly symbols.
@@ -1856,11 +1881,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
18561881
}
18571882
}
18581883

1859-
if f, err := macho.Open(gccTmp()); err == nil {
1884+
if f, err := macho.Open(ofile); err == nil {
18601885
defer f.Close()
18611886
d, err := f.DWARF()
18621887
if err != nil {
1863-
fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1888+
fatalf("cannot load DWARF output from %s: %v", ofile, err)
18641889
}
18651890
bo := f.ByteOrder
18661891
if f.Symtab != nil {
@@ -1934,11 +1959,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
19341959
return d, ints, floats, strs
19351960
}
19361961

1937-
if f, err := elf.Open(gccTmp()); err == nil {
1962+
if f, err := elf.Open(ofile); err == nil {
19381963
defer f.Close()
19391964
d, err := f.DWARF()
19401965
if err != nil {
1941-
fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1966+
fatalf("cannot load DWARF output from %s: %v", ofile, err)
19421967
}
19431968
bo := f.ByteOrder
19441969
symtab, err := f.Symbols()
@@ -2034,11 +2059,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
20342059
return d, ints, floats, strs
20352060
}
20362061

2037-
if f, err := pe.Open(gccTmp()); err == nil {
2062+
if f, err := pe.Open(ofile); err == nil {
20382063
defer f.Close()
20392064
d, err := f.DWARF()
20402065
if err != nil {
2041-
fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
2066+
fatalf("cannot load DWARF output from %s: %v", ofile, err)
20422067
}
20432068
bo := binary.LittleEndian
20442069
for _, s := range f.Symbols {
@@ -2106,11 +2131,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
21062131
return d, ints, floats, strs
21072132
}
21082133

2109-
if f, err := xcoff.Open(gccTmp()); err == nil {
2134+
if f, err := xcoff.Open(ofile); err == nil {
21102135
defer f.Close()
21112136
d, err := f.DWARF()
21122137
if err != nil {
2113-
fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
2138+
fatalf("cannot load DWARF output from %s: %v", ofile, err)
21142139
}
21152140
bo := binary.BigEndian
21162141
for _, s := range f.Symbols {
@@ -2176,7 +2201,7 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
21762201
buildStrings()
21772202
return d, ints, floats, strs
21782203
}
2179-
fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
2204+
fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", ofile)
21802205
panic("not reached")
21812206
}
21822207

@@ -2196,7 +2221,7 @@ func gccDefines(stdin []byte, gccOptions []string) string {
21962221
// gcc to fail.
21972222
func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string {
21982223
// TODO(rsc): require failure
2199-
args := p.gccCmd()
2224+
args := p.gccCmd(gccTmp())
22002225

22012226
// Optimization options can confuse the error messages; remove them.
22022227
nargs := make([]string, 0, len(args)+len(extraArgs))

src/cmd/cgo/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ type Package struct {
4949
GoFiles []string // list of Go files
5050
GccFiles []string // list of gcc output files
5151
Preamble string // collected preamble for _cgo_export.h
52-
typedefs map[string]bool // type names that appear in the types of the objects we're interested in
53-
typedefList []typedefInfo
5452
noCallbacks map[string]bool // C function names with #cgo nocallback directive
5553
noEscapes map[string]bool // C function names with #cgo noescape directive
5654
}

src/cmd/compile/internal/ssa/_gen/RISCV64.rules

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
(Mul64 ...) => (MUL ...)
1313
(Mul64uhilo ...) => (LoweredMuluhilo ...)
1414
(Mul64uover ...) => (LoweredMuluover ...)
15-
(Mul32 ...) => (MULW ...)
16-
(Mul16 x y) => (MULW (SignExt16to32 x) (SignExt16to32 y))
17-
(Mul8 x y) => (MULW (SignExt8to32 x) (SignExt8to32 y))
15+
(Mul(32|16|8) ...) => (MULW ...)
1816
(Mul(64|32)F ...) => (FMUL(D|S) ...)
1917

2018
(Div(64|32)F ...) => (FDIV(D|S) ...)

src/cmd/compile/internal/ssa/_gen/generic.rules

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,22 +1896,10 @@
18961896
(Neq(8|16|32|64) s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Neq(8|16|32|64) x y)
18971897

18981898
// Optimize bitsets
1899-
(Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
1900-
=> (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
1901-
(Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
1902-
=> (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
1903-
(Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
1904-
=> (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
1905-
(Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
1906-
=> (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
1907-
(Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
1908-
=> (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
1909-
(Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
1910-
=> (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
1911-
(Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
1912-
=> (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
1913-
(Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
1914-
=> (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
1899+
(Eq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [y])) && oneBit(y)
1900+
=> (Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [0]))
1901+
(Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [y])) && oneBit(y)
1902+
=> (Eq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [0]))
19151903

19161904
// Reassociate expressions involving
19171905
// constants such that constants come first,

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -470,11 +470,10 @@ func ntz32(x int32) int { return bits.TrailingZeros32(uint32(x)) }
470470
func ntz16(x int16) int { return bits.TrailingZeros16(uint16(x)) }
471471
func ntz8(x int8) int { return bits.TrailingZeros8(uint8(x)) }
472472

473-
func oneBit(x int64) bool { return x&(x-1) == 0 && x != 0 }
474-
func oneBit8(x int8) bool { return x&(x-1) == 0 && x != 0 }
475-
func oneBit16(x int16) bool { return x&(x-1) == 0 && x != 0 }
476-
func oneBit32(x int32) bool { return x&(x-1) == 0 && x != 0 }
477-
func oneBit64(x int64) bool { return x&(x-1) == 0 && x != 0 }
473+
// oneBit reports whether x contains exactly one set bit.
474+
func oneBit[T int8 | int16 | int32 | int64](x T) bool {
475+
return x&(x-1) == 0 && x != 0
476+
}
478477

479478
// nto returns the number of trailing ones.
480479
func nto(x int64) int64 {

0 commit comments

Comments
 (0)