Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
a5c9fb79
Commit
a5c9fb79
authored
Jul 10, 2020
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libgo: update to Go 1.14.4 release
Reviewed-on:
https://go-review.googlesource.com/c/gofrontend/+/241999
parent
53116900
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
409 additions
and
82 deletions
+409
-82
gcc/go/gofrontend/MERGE
+1
-1
libgo/MERGE
+1
-1
libgo/VERSION
+1
-1
libgo/go/cmd/cgo/gcc.go
+10
-2
libgo/go/encoding/json/decode.go
+5
-0
libgo/go/encoding/json/decode_test.go
+31
-2
libgo/go/encoding/json/encode.go
+6
-5
libgo/go/encoding/json/encode_test.go
+58
-29
libgo/go/encoding/json/stream_test.go
+5
-3
libgo/go/go/doc/example.go
+3
-3
libgo/go/go/doc/example_test.go
+58
-18
libgo/go/go/parser/interface.go
+1
-7
libgo/go/math/big/nat.go
+13
-2
libgo/go/math/big/nat_test.go
+18
-0
libgo/go/os/os_test.go
+35
-0
libgo/go/runtime/crash_test.go
+12
-2
libgo/go/runtime/mgcscavenge.go
+22
-0
libgo/go/runtime/mpagecache.go
+9
-4
libgo/go/runtime/mpagecache_test.go
+31
-2
libgo/go/runtime/proc.go
+6
-0
libgo/go/runtime/proc_test.go
+24
-0
libgo/go/runtime/testdata/testprog/lockosthread.go
+49
-0
libgo/misc/cgo/test/testx.go
+10
-0
No files found.
gcc/go/gofrontend/MERGE
View file @
a5c9fb79
761d68dacefc578e45ff299761f20989aef67823
2ad0970e9da95024110cd3244e9e21313af70a5f
The first line of this file holds the git revision number of the last
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
merge done from the gofrontend repository.
libgo/MERGE
View file @
a5c9fb79
96745b980cfde139e8611772e2bc0c59a8e6cdf7
83b181c68bf332ac7948f145f33d128377a09c42
The first line of this file holds the git revision number of the
The first line of this file holds the git revision number of the
last merge done from the master library sources.
last merge done from the master library sources.
libgo/VERSION
View file @
a5c9fb79
go1.14.
2
go1.14.
4
libgo/go/cmd/cgo/gcc.go
View file @
a5c9fb79
...
@@ -2082,6 +2082,10 @@ var goIdent = make(map[string]*ast.Ident)
...
@@ -2082,6 +2082,10 @@ var goIdent = make(map[string]*ast.Ident)
// that may contain a pointer. This is used for cgo pointer checking.
// that may contain a pointer. This is used for cgo pointer checking.
var
unionWithPointer
=
make
(
map
[
ast
.
Expr
]
bool
)
var
unionWithPointer
=
make
(
map
[
ast
.
Expr
]
bool
)
// anonymousStructTag provides a consistent tag for an anonymous struct.
// The same dwarf.StructType pointer will always get the same tag.
var
anonymousStructTag
=
make
(
map
[
*
dwarf
.
StructType
]
string
)
func
(
c
*
typeConv
)
Init
(
ptrSize
,
intSize
int64
)
{
func
(
c
*
typeConv
)
Init
(
ptrSize
,
intSize
int64
)
{
c
.
ptrSize
=
ptrSize
c
.
ptrSize
=
ptrSize
c
.
intSize
=
intSize
c
.
intSize
=
intSize
...
@@ -2430,8 +2434,12 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
...
@@ -2430,8 +2434,12 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
break
break
}
}
if
tag
==
""
{
if
tag
==
""
{
tag
=
"__"
+
strconv
.
Itoa
(
tagGen
)
tag
=
anonymousStructTag
[
dt
]
tagGen
++
if
tag
==
""
{
tag
=
"__"
+
strconv
.
Itoa
(
tagGen
)
tagGen
++
anonymousStructTag
[
dt
]
=
tag
}
}
else
if
t
.
C
.
Empty
()
{
}
else
if
t
.
C
.
Empty
()
{
t
.
C
.
Set
(
dt
.
Kind
+
" "
+
tag
)
t
.
C
.
Set
(
dt
.
Kind
+
" "
+
tag
)
}
}
...
...
libgo/go/encoding/json/decode.go
View file @
a5c9fb79
...
@@ -1217,6 +1217,11 @@ func (d *decodeState) unquoteBytes(s []byte) (t []byte, ok bool) {
...
@@ -1217,6 +1217,11 @@ func (d *decodeState) unquoteBytes(s []byte) (t []byte, ok bool) {
if
r
==
-
1
{
if
r
==
-
1
{
return
s
,
true
return
s
,
true
}
}
// Only perform up to one safe unquote for each re-scanned string
// literal. In some edge cases, the decoder unquotes a literal a second
// time, even after another literal has been re-scanned. Thus, only the
// first unquote can safely use safeUnquote.
d
.
safeUnquote
=
0
b
:=
make
([]
byte
,
len
(
s
)
+
2
*
utf8
.
UTFMax
)
b
:=
make
([]
byte
,
len
(
s
)
+
2
*
utf8
.
UTFMax
)
w
:=
copy
(
b
,
s
[
0
:
r
])
w
:=
copy
(
b
,
s
[
0
:
r
])
...
...
libgo/go/encoding/json/decode_test.go
View file @
a5c9fb79
...
@@ -2419,7 +2419,7 @@ func (m *textUnmarshalerString) UnmarshalText(text []byte) error {
...
@@ -2419,7 +2419,7 @@ func (m *textUnmarshalerString) UnmarshalText(text []byte) error {
return
nil
return
nil
}
}
// Test unmarshal to a map, w
ith
map key is a user defined type.
// Test unmarshal to a map, w
here the
map key is a user defined type.
// See golang.org/issues/34437.
// See golang.org/issues/34437.
func
TestUnmarshalMapWithTextUnmarshalerStringKey
(
t
*
testing
.
T
)
{
func
TestUnmarshalMapWithTextUnmarshalerStringKey
(
t
*
testing
.
T
)
{
var
p
map
[
textUnmarshalerString
]
string
var
p
map
[
textUnmarshalerString
]
string
...
@@ -2428,6 +2428,35 @@ func TestUnmarshalMapWithTextUnmarshalerStringKey(t *testing.T) {
...
@@ -2428,6 +2428,35 @@ func TestUnmarshalMapWithTextUnmarshalerStringKey(t *testing.T) {
}
}
if
_
,
ok
:=
p
[
"foo"
];
!
ok
{
if
_
,
ok
:=
p
[
"foo"
];
!
ok
{
t
.
Errorf
(
`Key "foo" is not existed in map: %v`
,
p
)
t
.
Errorf
(
`Key "foo" does not exist in map: %v`
,
p
)
}
}
func
TestUnmarshalRescanLiteralMangledUnquote
(
t
*
testing
.
T
)
{
// See golang.org/issues/38105.
var
p
map
[
textUnmarshalerString
]
string
if
err
:=
Unmarshal
([]
byte
(
`{"开源":"12345开源"}`
),
&
p
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal unexpected error: %v"
,
err
)
}
if
_
,
ok
:=
p
[
"开源"
];
!
ok
{
t
.
Errorf
(
`Key "开源" does not exist in map: %v`
,
p
)
}
// See golang.org/issues/38126.
type
T
struct
{
F1
string
`json:"F1,string"`
}
t1
:=
T
{
"aaa
\t
bbb"
}
b
,
err
:=
Marshal
(
t1
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal unexpected error: %v"
,
err
)
}
var
t2
T
if
err
:=
Unmarshal
(
b
,
&
t2
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal unexpected error: %v"
,
err
)
}
if
t1
!=
t2
{
t
.
Errorf
(
"Marshal and Unmarshal roundtrip mismatch: want %q got %q"
,
t1
,
t2
)
}
}
}
}
libgo/go/encoding/json/encode.go
View file @
a5c9fb79
...
@@ -635,11 +635,12 @@ func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
...
@@ -635,11 +635,12 @@ func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
return
return
}
}
if
opts
.
quoted
{
if
opts
.
quoted
{
b
:=
make
([]
byte
,
0
,
v
.
Len
()
+
2
)
e2
:=
newEncodeState
()
b
=
append
(
b
,
'"'
)
// Since we encode the string twice, we only need to escape HTML
b
=
append
(
b
,
[]
byte
(
v
.
String
())
...
)
// the first time.
b
=
append
(
b
,
'"'
)
e2
.
string
(
v
.
String
(),
opts
.
escapeHTML
)
e
.
stringBytes
(
b
,
opts
.
escapeHTML
)
e
.
stringBytes
(
e2
.
Bytes
(),
false
)
encodeStatePool
.
Put
(
e2
)
}
else
{
}
else
{
e
.
string
(
v
.
String
(),
opts
.
escapeHTML
)
e
.
string
(
v
.
String
(),
opts
.
escapeHTML
)
}
}
...
...
libgo/go/encoding/json/encode_test.go
View file @
a5c9fb79
...
@@ -79,37 +79,66 @@ type StringTag struct {
...
@@ -79,37 +79,66 @@ type StringTag struct {
NumberStr
Number
`json:",string"`
NumberStr
Number
`json:",string"`
}
}
var
stringTagExpected
=
`{
func
TestRoundtripStringTag
(
t
*
testing
.
T
)
{
"BoolStr": "true",
tests
:=
[]
struct
{
"IntStr": "42",
name
string
"UintptrStr": "44",
in
StringTag
"StrStr": "\"xzbit\"",
want
string
// empty to just test that we roundtrip
"NumberStr": "46"
}{
}`
{
name
:
"AllTypes"
,
func
TestStringTag
(
t
*
testing
.
T
)
{
in
:
StringTag
{
var
s
StringTag
BoolStr
:
true
,
s
.
BoolStr
=
true
IntStr
:
42
,
s
.
IntStr
=
42
UintptrStr
:
44
,
s
.
UintptrStr
=
44
StrStr
:
"xzbit"
,
s
.
StrStr
=
"xzbit"
NumberStr
:
"46"
,
s
.
NumberStr
=
"46"
},
got
,
err
:=
MarshalIndent
(
&
s
,
""
,
" "
)
want
:
`{
if
err
!=
nil
{
"BoolStr": "true",
t
.
Fatal
(
err
)
"IntStr": "42",
}
"UintptrStr": "44",
if
got
:=
string
(
got
);
got
!=
stringTagExpected
{
"StrStr": "\"xzbit\"",
t
.
Fatalf
(
" got: %s
\n
want: %s
\n
"
,
got
,
stringTagExpected
)
"NumberStr": "46"
}`
,
},
{
// See golang.org/issues/38173.
name
:
"StringDoubleEscapes"
,
in
:
StringTag
{
StrStr
:
"
\b\f\n\r\t\"\\
"
,
NumberStr
:
"0"
,
// just to satisfy the roundtrip
},
want
:
`{
"BoolStr": "false",
"IntStr": "0",
"UintptrStr": "0",
"StrStr": "\"\\u0008\\u000c\\n\\r\\t\\\"\\\\\"",
"NumberStr": "0"
}`
,
},
}
}
for
_
,
test
:=
range
tests
{
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
// Indent with a tab prefix to make the multi-line string
// literals in the table nicer to read.
got
,
err
:=
MarshalIndent
(
&
test
.
in
,
"
\t\t\t
"
,
"
\t
"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
:=
string
(
got
);
got
!=
test
.
want
{
t
.
Fatalf
(
" got: %s
\n
want: %s
\n
"
,
got
,
test
.
want
)
}
// Verify that it round-trips.
// Verify that it round-trips.
var
s2
StringTag
var
s2
StringTag
err
=
NewDecoder
(
bytes
.
NewReader
(
got
))
.
Decode
(
&
s2
)
if
err
:=
Unmarshal
(
got
,
&
s2
);
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Decode: %v"
,
err
)
t
.
Fatalf
(
"Decode: %v"
,
err
)
}
}
if
!
reflect
.
DeepEqual
(
test
.
in
,
s2
)
{
if
!
reflect
.
DeepEqual
(
s
,
s2
)
{
t
.
Fatalf
(
"decode didn't match.
\n
source: %#v
\n
Encoded as:
\n
%s
\n
decode: %#v"
,
test
.
in
,
string
(
got
),
s2
)
t
.
Fatalf
(
"decode didn't match.
\n
source: %#v
\n
Encoded as:
\n
%s
\n
decode: %#v"
,
s
,
string
(
got
),
s2
)
}
})
}
}
}
}
...
...
libgo/go/encoding/json/stream_test.go
View file @
a5c9fb79
...
@@ -144,14 +144,15 @@ func TestEncoderSetEscapeHTML(t *testing.T) {
...
@@ -144,14 +144,15 @@ func TestEncoderSetEscapeHTML(t *testing.T) {
},
},
{
{
"stringOption"
,
stringOption
,
"stringOption"
,
stringOption
,
`{"bar":"\"\
u003chtml\u003efoobar\u003c/html
\u003e\""}`
,
`{"bar":"\"\
\u003chtml\\u003efoobar\\u003c/html\
\u003e\""}`
,
`{"bar":"\"<html>foobar</html>\""}`
,
`{"bar":"\"<html>foobar</html>\""}`
,
},
},
}
{
}
{
var
buf
bytes
.
Buffer
var
buf
bytes
.
Buffer
enc
:=
NewEncoder
(
&
buf
)
enc
:=
NewEncoder
(
&
buf
)
if
err
:=
enc
.
Encode
(
tt
.
v
);
err
!=
nil
{
if
err
:=
enc
.
Encode
(
tt
.
v
);
err
!=
nil
{
t
.
Fatalf
(
"Encode(%s): %s"
,
tt
.
name
,
err
)
t
.
Errorf
(
"Encode(%s): %s"
,
tt
.
name
,
err
)
continue
}
}
if
got
:=
strings
.
TrimSpace
(
buf
.
String
());
got
!=
tt
.
wantEscape
{
if
got
:=
strings
.
TrimSpace
(
buf
.
String
());
got
!=
tt
.
wantEscape
{
t
.
Errorf
(
"Encode(%s) = %#q, want %#q"
,
tt
.
name
,
got
,
tt
.
wantEscape
)
t
.
Errorf
(
"Encode(%s) = %#q, want %#q"
,
tt
.
name
,
got
,
tt
.
wantEscape
)
...
@@ -159,7 +160,8 @@ func TestEncoderSetEscapeHTML(t *testing.T) {
...
@@ -159,7 +160,8 @@ func TestEncoderSetEscapeHTML(t *testing.T) {
buf
.
Reset
()
buf
.
Reset
()
enc
.
SetEscapeHTML
(
false
)
enc
.
SetEscapeHTML
(
false
)
if
err
:=
enc
.
Encode
(
tt
.
v
);
err
!=
nil
{
if
err
:=
enc
.
Encode
(
tt
.
v
);
err
!=
nil
{
t
.
Fatalf
(
"SetEscapeHTML(false) Encode(%s): %s"
,
tt
.
name
,
err
)
t
.
Errorf
(
"SetEscapeHTML(false) Encode(%s): %s"
,
tt
.
name
,
err
)
continue
}
}
if
got
:=
strings
.
TrimSpace
(
buf
.
String
());
got
!=
tt
.
want
{
if
got
:=
strings
.
TrimSpace
(
buf
.
String
());
got
!=
tt
.
want
{
t
.
Errorf
(
"SetEscapeHTML(false) Encode(%s) = %#q, want %#q"
,
t
.
Errorf
(
"SetEscapeHTML(false) Encode(%s) = %#q, want %#q"
,
...
...
libgo/go/go/doc/example.go
View file @
a5c9fb79
...
@@ -62,9 +62,6 @@ func Examples(testFiles ...*ast.File) []*Example {
...
@@ -62,9 +62,6 @@ func Examples(testFiles ...*ast.File) []*Example {
if
!
ok
||
f
.
Recv
!=
nil
{
if
!
ok
||
f
.
Recv
!=
nil
{
continue
continue
}
}
if
params
:=
f
.
Type
.
Params
;
len
(
params
.
List
)
!=
0
{
continue
// function has params; not a valid example
}
numDecl
++
numDecl
++
name
:=
f
.
Name
.
Name
name
:=
f
.
Name
.
Name
if
isTest
(
name
,
"Test"
)
||
isTest
(
name
,
"Benchmark"
)
{
if
isTest
(
name
,
"Test"
)
||
isTest
(
name
,
"Benchmark"
)
{
...
@@ -74,6 +71,9 @@ func Examples(testFiles ...*ast.File) []*Example {
...
@@ -74,6 +71,9 @@ func Examples(testFiles ...*ast.File) []*Example {
if
!
isTest
(
name
,
"Example"
)
{
if
!
isTest
(
name
,
"Example"
)
{
continue
continue
}
}
if
params
:=
f
.
Type
.
Params
;
len
(
params
.
List
)
!=
0
{
continue
// function has params; not a valid example
}
if
f
.
Body
==
nil
{
// ast.File.Body nil dereference (see issue 28044)
if
f
.
Body
==
nil
{
// ast.File.Body nil dereference (see issue 28044)
continue
continue
}
}
...
...
libgo/go/go/doc/example_test.go
View file @
a5c9fb79
...
@@ -331,25 +331,65 @@ func main() {
...
@@ -331,25 +331,65 @@ func main() {
}
}
`
`
const
exampleWholeFileFunction
=
`package foo_test
func Foo(x int) {
}
func Example() {
fmt.Println("Hello, world!")
// Output: Hello, world!
}
`
const
exampleWholeFileFunctionOutput
=
`package main
func Foo(x int) {
}
func main() {
fmt.Println("Hello, world!")
}
`
var
exampleWholeFileTestCases
=
[]
struct
{
Title
,
Source
,
Play
,
Output
string
}{
{
"Methods"
,
exampleWholeFile
,
exampleWholeFileOutput
,
"Hello, world!
\n
"
,
},
{
"Function"
,
exampleWholeFileFunction
,
exampleWholeFileFunctionOutput
,
"Hello, world!
\n
"
,
},
}
func
TestExamplesWholeFile
(
t
*
testing
.
T
)
{
func
TestExamplesWholeFile
(
t
*
testing
.
T
)
{
fset
:=
token
.
NewFileSet
()
for
_
,
c
:=
range
exampleWholeFileTestCases
{
file
,
err
:=
parser
.
ParseFile
(
fset
,
"test.go"
,
strings
.
NewReader
(
exampleWholeFile
),
parser
.
ParseComments
)
fset
:=
token
.
NewFileSet
()
if
err
!=
nil
{
file
,
err
:=
parser
.
ParseFile
(
fset
,
"test.go"
,
strings
.
NewReader
(
c
.
Source
),
parser
.
ParseComments
)
t
.
Fatal
(
err
)
if
err
!=
nil
{
}
t
.
Fatal
(
err
)
es
:=
doc
.
Examples
(
file
)
}
if
len
(
es
)
!=
1
{
es
:=
doc
.
Examples
(
file
)
t
.
Fatalf
(
"wrong number of examples; got %d want 1"
,
len
(
es
))
if
len
(
es
)
!=
1
{
}
t
.
Fatalf
(
"%s: wrong number of examples; got %d want 1"
,
c
.
Title
,
len
(
es
))
e
:=
es
[
0
]
}
if
e
.
Name
!=
""
{
e
:=
es
[
0
]
t
.
Errorf
(
"got Name == %q, want %q"
,
e
.
Name
,
""
)
if
e
.
Name
!=
""
{
}
t
.
Errorf
(
"%s: got Name == %q, want %q"
,
c
.
Title
,
e
.
Name
,
""
)
if
g
,
w
:=
formatFile
(
t
,
fset
,
e
.
Play
),
exampleWholeFileOutput
;
g
!=
w
{
}
t
.
Errorf
(
"got Play == %q, want %q"
,
g
,
w
)
if
g
,
w
:=
formatFile
(
t
,
fset
,
e
.
Play
),
c
.
Play
;
g
!=
w
{
}
t
.
Errorf
(
"%s: got Play == %q, want %q"
,
c
.
Title
,
g
,
w
)
if
g
,
w
:=
e
.
Output
,
"Hello, world!
\n
"
;
g
!=
w
{
}
t
.
Errorf
(
"got Output == %q, want %q"
,
g
,
w
)
if
g
,
w
:=
e
.
Output
,
c
.
Output
;
g
!=
w
{
t
.
Errorf
(
"%s: got Output == %q, want %q"
,
c
.
Title
,
g
,
w
)
}
}
}
}
}
...
...
libgo/go/go/parser/interface.go
View file @
a5c9fb79
...
@@ -133,13 +133,7 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode)
...
@@ -133,13 +133,7 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode)
// first error encountered are returned.
// first error encountered are returned.
//
//
func
ParseDir
(
fset
*
token
.
FileSet
,
path
string
,
filter
func
(
os
.
FileInfo
)
bool
,
mode
Mode
)
(
pkgs
map
[
string
]
*
ast
.
Package
,
first
error
)
{
func
ParseDir
(
fset
*
token
.
FileSet
,
path
string
,
filter
func
(
os
.
FileInfo
)
bool
,
mode
Mode
)
(
pkgs
map
[
string
]
*
ast
.
Package
,
first
error
)
{
fd
,
err
:=
os
.
Open
(
path
)
list
,
err
:=
ioutil
.
ReadDir
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
defer
fd
.
Close
()
list
,
err
:=
fd
.
Readdir
(
-
1
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
libgo/go/math/big/nat.go
View file @
a5c9fb79
...
@@ -740,7 +740,8 @@ func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) {
...
@@ -740,7 +740,8 @@ func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) {
// The remainder overwrites input u.
// The remainder overwrites input u.
//
//
// Precondition:
// Precondition:
// - len(q) >= len(u)-len(v)
// - q is large enough to hold the quotient u / v
// which has a maximum length of len(u)-len(v)+1.
func
(
q
nat
)
divBasic
(
u
,
v
nat
)
{
func
(
q
nat
)
divBasic
(
u
,
v
nat
)
{
n
:=
len
(
v
)
n
:=
len
(
v
)
m
:=
len
(
u
)
-
n
m
:=
len
(
u
)
-
n
...
@@ -779,6 +780,8 @@ func (q nat) divBasic(u, v nat) {
...
@@ -779,6 +780,8 @@ func (q nat) divBasic(u, v nat) {
}
}
// D4.
// D4.
// Compute the remainder u - (q̂*v) << (_W*j).
// The subtraction may overflow if q̂ estimate was off by one.
qhatv
[
n
]
=
mulAddVWW
(
qhatv
[
0
:
n
],
v
,
qhat
,
0
)
qhatv
[
n
]
=
mulAddVWW
(
qhatv
[
0
:
n
],
v
,
qhat
,
0
)
qhl
:=
len
(
qhatv
)
qhl
:=
len
(
qhatv
)
if
j
+
qhl
>
len
(
u
)
&&
qhatv
[
n
]
==
0
{
if
j
+
qhl
>
len
(
u
)
&&
qhatv
[
n
]
==
0
{
...
@@ -787,7 +790,11 @@ func (q nat) divBasic(u, v nat) {
...
@@ -787,7 +790,11 @@ func (q nat) divBasic(u, v nat) {
c
:=
subVV
(
u
[
j
:
j
+
qhl
],
u
[
j
:
],
qhatv
)
c
:=
subVV
(
u
[
j
:
j
+
qhl
],
u
[
j
:
],
qhatv
)
if
c
!=
0
{
if
c
!=
0
{
c
:=
addVV
(
u
[
j
:
j
+
n
],
u
[
j
:
],
v
)
c
:=
addVV
(
u
[
j
:
j
+
n
],
u
[
j
:
],
v
)
u
[
j
+
n
]
+=
c
// If n == qhl, the carry from subVV and the carry from addVV
// cancel out and don't affect u[j+n].
if
n
<
qhl
{
u
[
j
+
n
]
+=
c
}
qhat
--
qhat
--
}
}
...
@@ -827,6 +834,10 @@ func (z nat) divRecursive(u, v nat) {
...
@@ -827,6 +834,10 @@ func (z nat) divRecursive(u, v nat) {
putNat
(
tmp
)
putNat
(
tmp
)
}
}
// divRecursiveStep computes the division of u by v.
// - z must be large enough to hold the quotient
// - the quotient will overwrite z
// - the remainder will overwrite u
func
(
z
nat
)
divRecursiveStep
(
u
,
v
nat
,
depth
int
,
tmp
*
nat
,
temps
[]
*
nat
)
{
func
(
z
nat
)
divRecursiveStep
(
u
,
v
nat
,
depth
int
,
tmp
*
nat
,
temps
[]
*
nat
)
{
u
=
u
.
norm
()
u
=
u
.
norm
()
v
=
v
.
norm
()
v
=
v
.
norm
()
...
...
libgo/go/math/big/nat_test.go
View file @
a5c9fb79
...
@@ -786,3 +786,21 @@ func TestNatDiv(t *testing.T) {
...
@@ -786,3 +786,21 @@ func TestNatDiv(t *testing.T) {
}
}
}
}
}
}
// TestIssue37499 triggers the edge case of divBasic where
// the inaccurate estimate of the first word's quotient
// happens at the very beginning of the loop.
func
TestIssue37499
(
t
*
testing
.
T
)
{
// Choose u and v such that v is slightly larger than u >> N.
// This tricks divBasic into choosing 1 as the first word
// of the quotient. This works in both 32-bit and 64-bit settings.
u
:=
natFromString
(
"0x2b6c385a05be027f5c22005b63c42a1165b79ff510e1706b39f8489c1d28e57bb5ba4ef9fd9387a3e344402c0a453381"
)
v
:=
natFromString
(
"0x2b6c385a05be027f5c22005b63c42a1165b79ff510e1706c"
)
q
:=
nat
(
nil
)
.
make
(
8
)
q
.
divBasic
(
u
,
v
)
q
=
q
.
norm
()
if
s
:=
string
(
q
.
utoa
(
16
));
s
!=
"fffffffffffffffffffffffffffffffffffffffffffffffb"
{
t
.
Fatalf
(
"incorrect quotient: %s"
,
s
)
}
}
libgo/go/os/os_test.go
View file @
a5c9fb79
...
@@ -2450,3 +2450,38 @@ func TestDirSeek(t *testing.T) {
...
@@ -2450,3 +2450,38 @@ func TestDirSeek(t *testing.T) {
}
}
}
}
}
}
// Test that opening a file does not change its permissions. Issue 38225.
func
TestOpenFileKeepsPermissions
(
t
*
testing
.
T
)
{
t
.
Parallel
()
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"TestOpenFileKeepsPermissions"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
RemoveAll
(
dir
)
name
:=
filepath
.
Join
(
dir
,
"x"
)
f
,
err
:=
Create
(
name
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
err
:=
f
.
Close
();
err
!=
nil
{
t
.
Error
(
err
)
}
f
,
err
=
OpenFile
(
name
,
O_WRONLY
|
O_CREATE
|
O_TRUNC
,
0
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
fi
,
err
:=
f
.
Stat
();
err
!=
nil
{
t
.
Error
(
err
)
}
else
if
fi
.
Mode
()
&
0222
==
0
{
t
.
Errorf
(
"f.Stat.Mode after OpenFile is %v, should be writable"
,
fi
.
Mode
())
}
if
err
:=
f
.
Close
();
err
!=
nil
{
t
.
Error
(
err
)
}
if
fi
,
err
:=
Stat
(
name
);
err
!=
nil
{
t
.
Error
(
err
)
}
else
if
fi
.
Mode
()
&
0222
==
0
{
t
.
Errorf
(
"Stat after OpenFile is %v, should be writable"
,
fi
.
Mode
())
}
}
libgo/go/runtime/crash_test.go
View file @
a5c9fb79
...
@@ -55,6 +55,16 @@ func runTestProg(t *testing.T, binary, name string, env ...string) string {
...
@@ -55,6 +55,16 @@ func runTestProg(t *testing.T, binary, name string, env ...string) string {
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
return
runBuiltTestProg
(
t
,
exe
,
name
,
env
...
)
}
func
runBuiltTestProg
(
t
*
testing
.
T
,
exe
,
name
string
,
env
...
string
)
string
{
if
*
flagQuick
{
t
.
Skip
(
"-quick"
)
}
testenv
.
MustHaveGoBuild
(
t
)
cmd
:=
testenv
.
CleanCmdEnv
(
exec
.
Command
(
exe
,
name
))
cmd
:=
testenv
.
CleanCmdEnv
(
exec
.
Command
(
exe
,
name
))
cmd
.
Env
=
append
(
cmd
.
Env
,
env
...
)
cmd
.
Env
=
append
(
cmd
.
Env
,
env
...
)
if
testing
.
Short
()
{
if
testing
.
Short
()
{
...
@@ -64,7 +74,7 @@ func runTestProg(t *testing.T, binary, name string, env ...string) string {
...
@@ -64,7 +74,7 @@ func runTestProg(t *testing.T, binary, name string, env ...string) string {
cmd
.
Stdout
=
&
b
cmd
.
Stdout
=
&
b
cmd
.
Stderr
=
&
b
cmd
.
Stderr
=
&
b
if
err
:=
cmd
.
Start
();
err
!=
nil
{
if
err
:=
cmd
.
Start
();
err
!=
nil
{
t
.
Fatalf
(
"starting %s %s: %v"
,
binary
,
name
,
err
)
t
.
Fatalf
(
"starting %s %s: %v"
,
exe
,
name
,
err
)
}
}
// If the process doesn't complete within 1 minute,
// If the process doesn't complete within 1 minute,
...
@@ -92,7 +102,7 @@ func runTestProg(t *testing.T, binary, name string, env ...string) string {
...
@@ -92,7 +102,7 @@ func runTestProg(t *testing.T, binary, name string, env ...string) string {
}()
}()
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
t
.
Logf
(
"%s %s exit status: %v"
,
binary
,
name
,
err
)
t
.
Logf
(
"%s %s exit status: %v"
,
exe
,
name
,
err
)
}
}
close
(
done
)
close
(
done
)
...
...
libgo/go/runtime/mgcscavenge.go
View file @
a5c9fb79
...
@@ -288,6 +288,28 @@ func bgscavenge(c chan int) {
...
@@ -288,6 +288,28 @@ func bgscavenge(c chan int) {
continue
continue
}
}
if
released
<
physPageSize
{
// If this happens, it means that we may have attempted to release part
// of a physical page, but the likely effect of that is that it released
// the whole physical page, some of which may have still been in-use.
// This could lead to memory corruption. Throw.
throw
(
"released less than one physical page of memory"
)
}
// On some platforms we may see crit as zero if the time it takes to scavenge
// memory is less than the minimum granularity of its clock (e.g. Windows).
// In this case, just assume scavenging takes 10 µs per regular physical page
// (determined empirically), and conservatively ignore the impact of huge pages
// on timing.
//
// We shouldn't ever see a crit value less than zero unless there's a bug of
// some kind, either on our side or in the platform we're running on, but be
// defensive in that case as well.
const
approxCritNSPerPhysicalPage
=
10e3
if
crit
<=
0
{
crit
=
approxCritNSPerPhysicalPage
*
float64
(
released
/
physPageSize
)
}
// Multiply the critical time by 1 + the ratio of the costs of using
// Multiply the critical time by 1 + the ratio of the costs of using
// scavenged memory vs. scavenging memory. This forces us to pay down
// scavenged memory vs. scavenging memory. This forces us to pay down
// the cost of reusing this memory eagerly by sleeping for a longer period
// the cost of reusing this memory eagerly by sleeping for a longer period
...
...
libgo/go/runtime/mpagecache.go
View file @
a5c9fb79
...
@@ -148,9 +148,14 @@ func (s *pageAlloc) allocToCache() pageCache {
...
@@ -148,9 +148,14 @@ func (s *pageAlloc) allocToCache() pageCache {
// Update as an allocation, but note that it's not contiguous.
// Update as an allocation, but note that it's not contiguous.
s
.
update
(
c
.
base
,
pageCachePages
,
false
,
true
)
s
.
update
(
c
.
base
,
pageCachePages
,
false
,
true
)
// We're always searching for the first free page, and we always know the
// Set the search address to the last page represented by the cache.
// up to pageCache size bits will be allocated, so we can always move the
// Since all of the pages in this block are going to the cache, and we
// searchAddr past the cache.
// searched for the first free page, we can confidently start at the
s
.
searchAddr
=
c
.
base
+
pageSize
*
pageCachePages
// next page.
//
// However, s.searchAddr is not allowed to point into unmapped heap memory
// unless it is maxSearchAddr, so make it the last page as opposed to
// the page after.
s
.
searchAddr
=
c
.
base
+
pageSize
*
(
pageCachePages
-
1
)
return
c
return
c
}
}
libgo/go/runtime/mpagecache_test.go
View file @
a5c9fb79
...
@@ -260,12 +260,13 @@ func TestPageAllocAllocToCache(t *testing.T) {
...
@@ -260,12 +260,13 @@ func TestPageAllocAllocToCache(t *testing.T) {
if
GOOS
==
"openbsd"
&&
testing
.
Short
()
{
if
GOOS
==
"openbsd"
&&
testing
.
Short
()
{
t
.
Skip
(
"skipping because virtual memory is limited; see #36210"
)
t
.
Skip
(
"skipping because virtual memory is limited; see #36210"
)
}
}
t
ests
:=
map
[
string
]
struct
{
t
ype
test
struct
{
before
map
[
ChunkIdx
][]
BitRange
before
map
[
ChunkIdx
][]
BitRange
scav
map
[
ChunkIdx
][]
BitRange
scav
map
[
ChunkIdx
][]
BitRange
hits
[]
PageCache
// expected base addresses and patterns
hits
[]
PageCache
// expected base addresses and patterns
after
map
[
ChunkIdx
][]
BitRange
after
map
[
ChunkIdx
][]
BitRange
}{
}
tests
:=
map
[
string
]
test
{
"AllFree"
:
{
"AllFree"
:
{
before
:
map
[
ChunkIdx
][]
BitRange
{
before
:
map
[
ChunkIdx
][]
BitRange
{
BaseChunkIdx
:
{},
BaseChunkIdx
:
{},
...
@@ -349,6 +350,34 @@ func TestPageAllocAllocToCache(t *testing.T) {
...
@@ -349,6 +350,34 @@ func TestPageAllocAllocToCache(t *testing.T) {
},
},
},
},
}
}
if
PageAlloc64Bit
!=
0
{
const
chunkIdxBigJump
=
0x100000
// chunk index offset which translates to O(TiB)
// This test is similar to the one with the same name for
// pageAlloc.alloc and serves the same purpose.
// See mpagealloc_test.go for details.
sumsPerPhysPage
:=
ChunkIdx
(
PhysPageSize
/
PallocSumBytes
)
baseChunkIdx
:=
BaseChunkIdx
&^
(
sumsPerPhysPage
-
1
)
tests
[
"DiscontiguousMappedSumBoundary"
]
=
test
{
before
:
map
[
ChunkIdx
][]
BitRange
{
baseChunkIdx
+
sumsPerPhysPage
-
1
:
{{
0
,
PallocChunkPages
-
1
}},
baseChunkIdx
+
chunkIdxBigJump
:
{{
1
,
PallocChunkPages
-
1
}},
},
scav
:
map
[
ChunkIdx
][]
BitRange
{
baseChunkIdx
+
sumsPerPhysPage
-
1
:
{},
baseChunkIdx
+
chunkIdxBigJump
:
{},
},
hits
:
[]
PageCache
{
NewPageCache
(
PageBase
(
baseChunkIdx
+
sumsPerPhysPage
-
1
,
PallocChunkPages
-
64
),
1
<<
63
,
0
),
NewPageCache
(
PageBase
(
baseChunkIdx
+
chunkIdxBigJump
,
0
),
1
,
0
),
NewPageCache
(
0
,
0
,
0
),
},
after
:
map
[
ChunkIdx
][]
BitRange
{
baseChunkIdx
+
sumsPerPhysPage
-
1
:
{{
0
,
PallocChunkPages
}},
baseChunkIdx
+
chunkIdxBigJump
:
{{
0
,
PallocChunkPages
}},
},
}
}
for
name
,
v
:=
range
tests
{
for
name
,
v
:=
range
tests
{
v
:=
v
v
:=
v
t
.
Run
(
name
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
name
,
func
(
t
*
testing
.
T
)
{
...
...
libgo/go/runtime/proc.go
View file @
a5c9fb79
...
@@ -1704,10 +1704,16 @@ func startTemplateThread() {
...
@@ -1704,10 +1704,16 @@ func startTemplateThread() {
if
GOARCH
==
"wasm"
{
// no threads on wasm yet
if
GOARCH
==
"wasm"
{
// no threads on wasm yet
return
return
}
}
// Disable preemption to guarantee that the template thread will be
// created before a park once haveTemplateThread is set.
mp
:=
acquirem
()
if
!
atomic
.
Cas
(
&
newmHandoff
.
haveTemplateThread
,
0
,
1
)
{
if
!
atomic
.
Cas
(
&
newmHandoff
.
haveTemplateThread
,
0
,
1
)
{
releasem
(
mp
)
return
return
}
}
newm
(
templateThread
,
nil
)
newm
(
templateThread
,
nil
)
releasem
(
mp
)
}
}
// templateThread is a thread in a known-good state that exists solely
// templateThread is a thread in a known-good state that exists solely
...
...
libgo/go/runtime/proc_test.go
View file @
a5c9fb79
...
@@ -6,6 +6,7 @@ package runtime_test
...
@@ -6,6 +6,7 @@ package runtime_test
import
(
import
(
"fmt"
"fmt"
"internal/testenv"
"math"
"math"
"net"
"net"
"runtime"
"runtime"
...
@@ -930,6 +931,29 @@ func TestLockOSThreadAvoidsStatePropagation(t *testing.T) {
...
@@ -930,6 +931,29 @@ func TestLockOSThreadAvoidsStatePropagation(t *testing.T) {
}
}
}
}
func
TestLockOSThreadTemplateThreadRace
(
t
*
testing
.
T
)
{
testenv
.
MustHaveGoRun
(
t
)
exe
,
err
:=
buildTestProg
(
t
,
"testprog"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
iterations
:=
100
if
testing
.
Short
()
{
// Reduce run time to ~100ms, with much lower probability of
// catching issues.
iterations
=
5
}
for
i
:=
0
;
i
<
iterations
;
i
++
{
want
:=
"OK
\n
"
output
:=
runBuiltTestProg
(
t
,
exe
,
"LockOSThreadTemplateThreadRace"
)
if
output
!=
want
{
t
.
Fatalf
(
"run %d: want %q, got %q"
,
i
,
want
,
output
)
}
}
}
// fakeSyscall emulates a system call.
// fakeSyscall emulates a system call.
//go:nosplit
//go:nosplit
func
fakeSyscall
(
duration
time
.
Duration
)
{
func
fakeSyscall
(
duration
time
.
Duration
)
{
...
...
libgo/go/runtime/testdata/testprog/lockosthread.go
View file @
a5c9fb79
...
@@ -7,6 +7,7 @@ package main
...
@@ -7,6 +7,7 @@ package main
import
(
import
(
"os"
"os"
"runtime"
"runtime"
"sync"
"time"
"time"
)
)
...
@@ -30,6 +31,7 @@ func init() {
...
@@ -30,6 +31,7 @@ func init() {
runtime
.
LockOSThread
()
runtime
.
LockOSThread
()
})
})
register
(
"LockOSThreadAvoidsStatePropagation"
,
LockOSThreadAvoidsStatePropagation
)
register
(
"LockOSThreadAvoidsStatePropagation"
,
LockOSThreadAvoidsStatePropagation
)
register
(
"LockOSThreadTemplateThreadRace"
,
LockOSThreadTemplateThreadRace
)
}
}
func
LockOSThreadMain
()
{
func
LockOSThreadMain
()
{
...
@@ -195,3 +197,50 @@ func LockOSThreadAvoidsStatePropagation() {
...
@@ -195,3 +197,50 @@ func LockOSThreadAvoidsStatePropagation() {
runtime
.
UnlockOSThread
()
runtime
.
UnlockOSThread
()
println
(
"OK"
)
println
(
"OK"
)
}
}
func
LockOSThreadTemplateThreadRace
()
{
// This test attempts to reproduce the race described in
// golang.org/issue/38931. To do so, we must have a stop-the-world
// (achieved via ReadMemStats) racing with two LockOSThread calls.
//
// While this test attempts to line up the timing, it is only expected
// to fail (and thus hang) around 2% of the time if the race is
// present.
// Ensure enough Ps to actually run everything in parallel. Though on
// <4 core machines, we are still at the whim of the kernel scheduler.
runtime
.
GOMAXPROCS
(
4
)
go
func
()
{
// Stop the world; race with LockOSThread below.
var
m
runtime
.
MemStats
for
{
runtime
.
ReadMemStats
(
&
m
)
}
}()
// Try to synchronize both LockOSThreads.
start
:=
time
.
Now
()
.
Add
(
10
*
time
.
Millisecond
)
var
wg
sync
.
WaitGroup
wg
.
Add
(
2
)
for
i
:=
0
;
i
<
2
;
i
++
{
go
func
()
{
for
time
.
Now
()
.
Before
(
start
)
{
}
// Add work to the local runq to trigger early startm
// in handoffp.
go
func
(){}()
runtime
.
LockOSThread
()
runtime
.
Gosched
()
// add a preemption point.
wg
.
Done
()
}()
}
wg
.
Wait
()
// If both LockOSThreads completed then we did not hit the race.
println
(
"OK"
)
}
libgo/misc/cgo/test/testx.go
View file @
a5c9fb79
...
@@ -124,6 +124,11 @@ typedef struct {
...
@@ -124,6 +124,11 @@ typedef struct {
} Issue31891B;
} Issue31891B;
void callIssue31891(void);
void callIssue31891(void);
typedef struct {
int i;
} Issue38408, *PIssue38408;
*/
*/
import
"C"
import
"C"
...
@@ -552,3 +557,8 @@ func useIssue31891B(c *C.Issue31891B) {}
...
@@ -552,3 +557,8 @@ func useIssue31891B(c *C.Issue31891B) {}
func
test31891
(
t
*
testing
.
T
)
{
func
test31891
(
t
*
testing
.
T
)
{
C
.
callIssue31891
()
C
.
callIssue31891
()
}
}
// issue 38408
// A typedef pointer can be used as the element type.
// No runtime test; just make sure it compiles.
var
_
C
.
PIssue38408
=
&
C
.
Issue38408
{
i
:
1
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment