From 456df7c282f984133a4e687e5cff1bcda0f180e4 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Mon, 27 Oct 2014 14:23:24 -0700 Subject: [PATCH 01/33] doc/go1.4.html: first pieces of release notes Move the release notes into an HTML file. Start writing the text. LGTM=rsc R=golang-codereviews, bradfitz, kamil.kisiel, tracey.brendan, rsc CC=golang-codereviews https://golang.org/cl/161350043 --- doc/go1.4.html | 256 +++++++++++++++++++++++++++++++++++++++++++++++++ doc/go1.4.txt | 53 ---------- 2 files changed, 256 insertions(+), 53 deletions(-) create mode 100644 doc/go1.4.html delete mode 100644 doc/go1.4.txt diff --git a/doc/go1.4.html b/doc/go1.4.html new file mode 100644 index 0000000000..a48e675f6a --- /dev/null +++ b/doc/go1.4.html @@ -0,0 +1,256 @@ + + +

Introduction to Go 1.4

+ +

+The latest Go release, version 1.4, arrives as scheduled six months after 1.3 +and contains only one tiny language change, +a backwards-compatible simple form of for-range loop. +The release focuses primarily on implementation work, improving the garbage collector +and preparing the ground for a fully concurrent collector to be rolled out in the +next few releases. +Stacks are now contiguous, reallocated when necessary rather than linking on new +"segments"; +this release therefore eliminates the notorious "hot stack split" problem. +There are some new tools available including support in the go command +for build-time source code generation +and TODO. +The release also adds support for TODO architecture and TODO operating systems. +As always, Go 1.4 keeps the promise +of compatibility, +and almost everything +will continue to compile and run without change when moved to 1.4. +

+ +

Changes to the language

+ +

For-range loops

+

+Up until Go 1.3, for-range loop had two forms +

+ +
+for k, v := range x {
+	...
+}
+
+ +

+and +

+ +
+for k := range x {
+	...
+}
+
+ +

+If one was not interested in the loop values, only the iteration itself, it was still +necessary to mention a variable (probably the blank identifier, as in +for _ = range x), because +the form +

+ +
+for range x {
+	...
+}
+
+ +

+was not syntactically permitted. +

+ +

+This situation seemed awkward, so as of Go 1.4 the variable-free form is now legal. +The situation arises only rarely but the code can be cleaner when it does. +

+ +

+Updating: The change is strictly backwards compatible to existing Go +programs, but tools that analyze Go parse trees may need to be modified to accept +this new form as the +Key field of RangeStmt +may now be nil. +

+ +

Changes to the supported operating systems and architectures

+ +

FooBarBlatz

+ +

+TODO news about foobarblatz +

+ +

Changes to the compatibility guidelines

+ +

+The unsafe package allows one +to defeat Go's type system by exploiting internal details of the implementation +or machine representation of data. +It was never explicitly specified what use of unsafe meant +with respect to compatibility as specified in the +Go compatibilty guidelines. +The answer, of course, is that we can make no promise of compatibility +for code that does unsafe things. +

+ +

+We have clarified this situation in the documentation included in the release. +The Go compatibilty guidelines and the +docs for the unsafe package +are now explicit that unsafe code is not guaranteed to remain compatible. +

+ +

+Updating: Nothing technical has changed; this is just a clarification +of the documentation. +

+ + +

Changes to the implementations and tools

+ +

Changes to the garbage collector

+ +

+TODO news about garbage collection +

+ +

Stack

+ +

+TODO news about stacks +

+ +

Status of gccgo

+ +

+TODO gccgo news +

+ +

Changes to the go command

+ +

+TODO go command news +

+ +

Changes to cgo

+ +

+TODO cgo news +

+ + +

Changes to godoc

+

+TODO godoc news +

+ +

Changes to package source layout

+ +

+In the main Go source repository, the source code for the packages was kept in +the directory src/pkg, which made sense but differed from +other repositories, including the Go sub-repositories such as go.tools. +In Go 1.4, the pkg level of the source tree is now gone, so for example +the fmt package's source, once kept in +directory src/pkg/fmt, now lives one level higher in src/fmt. +

+ +

+Updating: Tools like godoc that discover source code +need to know about the new location. All tools and services maintained by the Go team +have been updated. +

+ +

Miscellany

+ +

+TODO misc news +

+ +

Performance

+ +

+TODO performance news +

+ +

Changes to the standard library

+ +

New packages

+ +

+TODO new packages +

+ +

Major changes to the library

+ +

+TODO major changes +

+ +

Minor changes to the library

+ +

+The following list summarizes a number of minor changes to the library, mostly additions. +See the relevant package documentation for more information about each change. +

+ + + +
+
+the directory src/pkg has been deleted, for instance src/pkg/fmt is now just src/fmt (CL 134570043)
+
+cmd/6l, liblink: use pc-relative addressing for all memory references, so that linking Go binaries at high addresses works (CL 125140043). This cuts the maximum size of a Go binary's text+data+bss from 4GB to 2GB.
+cmd/go: import comments (CL 124940043)
+cmd/go: implement "internal" (CL 120600043)
+cmd/go: implement "generate" (CL 125580044)
+cmd/go: disallow C sources except when using cgo (CL 149720043)
+cmd/go: add test -o flag (CL 149070043)
+cmd/go: redefine build -a to skip standard library in releases (CL 151730045)
+cmd/go: compile and link all _test.go files during 'go test', even in packages where there are no Test functions (CL 150980043)
+cmd/go: (via go/build): a GOOS prefix acts as a tag only if preceded by an underscore. this is a breaking change. (CL 147690043)
+
+asm: make textflag.h available outside of cmd/ld (CL 128050043)
+bufio: handling of empty tokens at EOF changed, may require scanner change (CL 145390043)
+compress/flate, compress/gzip, compress/zlib: Reset support (https://codereview.appspot.com/97140043)
+crypto/tls: add support for ALPN (RFC 7301) (CL 108710046)
+crypto/tls: support programmatic selection of server certificates (CL 107400043)
+encoding/asn1: optional elements with a default value will now only be omitted if they have that value (CL 86960045)
+flag: it is now an error to set a flag multiple times (CL 156390043)
+fmt: print type *map[T]T as &map[k:v] (CL 154870043)
+encoding/csv: do not quote empty strings, quote \. (CL 164760043)
+encoding/gob: remove unsafe (CL 102680045)
+misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043)
+net/http: add Request.BasicAuth method (CL 76540043)
+net/http: add Transport.DialTLS hook (CL 137940043)
+net/http/httputil: add ReverseProxy.ErrorLog (CL 132750043)
+os: implement symlink support for windows (CL 86160044)
+reflect: add type.Comparable (CL 144020043)
+runtime: implement monotonic clocks on windows (CL 108700045)
+runtime: memory consumption is reduced by 10-30% (CL 106260045 removes type info from heap, CL 145790043 reduces stack size to 2K (4K on plan 9 and windows))
+runtime: MemStats.Mallocs now counts very small allocations missed in Go 1.3. This may break tests using runtime.ReadMemStats or testing.AllocsPerRun by giving a more accurate answer than Go 1.3 did (CL 143150043).
+runtime/race: freebsd is supported (CL 107270043)
+swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released)
+sync/atomic: add Value (CL 136710045)
+syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043)
+syscall: now frozen (CL 129820043)
+testing: add Coverage (CL 98150043)
+testing: add TestMain support (CL 148770043)
+text/scanner: add IsIdentRune field of Scanner. (CL 108030044)
+text/template: allow comparison of signed and unsigned integers (CL 149780043)
+time: use the micro symbol (µ (U+00B5)) to print microsecond duration (CL 105030046)
+unsafe: document the existing situation that unsafe programs are not go1-guaranteed (CL 162060043)
+
+go.sys subrepo created: http://golang.org/s/go1.4-syscall
+
diff --git a/doc/go1.4.txt b/doc/go1.4.txt deleted file mode 100644 index b9d8ade245..0000000000 --- a/doc/go1.4.txt +++ /dev/null @@ -1,53 +0,0 @@ -This file collects notes about what has changed since Go 1.3 -and should be mentioned in the Go 1.4 release notes. - -Please keep the descriptions to a single line, starting with the -package or cmd/xxx directory name, and ending in a CL number. -Please keep the list sorted (as in sort.Strings of the lines). - -spec: permit for range x (CL 104680043) - -the directory src/pkg has been deleted, for instance src/pkg/fmt is now just src/fmt (CL 134570043) - -cmd/6l, liblink: use pc-relative addressing for all memory references, so that linking Go binaries at high addresses works (CL 125140043). This cuts the maximum size of a Go binary's text+data+bss from 4GB to 2GB. -cmd/go: import comments (CL 124940043) -cmd/go: implement "internal" (CL 120600043) -cmd/go: implement "generate" (CL 125580044) -cmd/go: disallow C sources except when using cgo (CL 149720043) -cmd/go: add test -o flag (CL 149070043) -cmd/go: redefine build -a to skip standard library in releases (CL 151730045) -cmd/go: compile and link all _test.go files during 'go test', even in packages where there are no Test functions (CL 150980043) -cmd/go: (via go/build): a GOOS prefix acts as a tag only if preceded by an underscore. this is a breaking change. (CL 147690043) - -asm: make textflag.h available outside of cmd/ld (CL 128050043) -bufio: handling of empty tokens at EOF changed, may require scanner change (CL 145390043) -compress/flate, compress/gzip, compress/zlib: Reset support (https://codereview.appspot.com/97140043) -crypto/tls: add support for ALPN (RFC 7301) (CL 108710046) -crypto/tls: support programmatic selection of server certificates (CL 107400043) -encoding/asn1: optional elements with a default value will now only be omitted if they have that value (CL 86960045) -flag: it is now an error to set a flag multiple times (CL 156390043) -fmt: print type *map[T]T as &map[k:v] (CL 154870043) -encoding/csv: do not quote empty strings, quote \. (CL 164760043) -encoding/gob: remove unsafe (CL 102680045) -misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043) -net/http: add Request.BasicAuth method (CL 76540043) -net/http: add Transport.DialTLS hook (CL 137940043) -net/http/httputil: add ReverseProxy.ErrorLog (CL 132750043) -os: implement symlink support for windows (CL 86160044) -reflect: add type.Comparable (CL 144020043) -runtime: implement monotonic clocks on windows (CL 108700045) -runtime: memory consumption is reduced by 10-30% (CL 106260045 removes type info from heap, CL 145790043 reduces stack size to 2K (4K on plan 9 and windows)) -runtime: MemStats.Mallocs now counts very small allocations missed in Go 1.3. This may break tests using runtime.ReadMemStats or testing.AllocsPerRun by giving a more accurate answer than Go 1.3 did (CL 143150043). -runtime/race: freebsd is supported (CL 107270043) -swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released) -sync/atomic: add Value (CL 136710045) -syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043) -syscall: now frozen (CL 129820043) -testing: add Coverage (CL 98150043) -testing: add TestMain support (CL 148770043) -text/scanner: add IsIdentRune field of Scanner. (CL 108030044) -text/template: allow comparison of signed and unsigned integers (CL 149780043) -time: use the micro symbol (µ (U+00B5)) to print microsecond duration (CL 105030046) -unsafe: document the existing situation that unsafe programs are not go1-guaranteed (CL 162060043) - -go.sys subrepo created: http://golang.org/s/go1.4-syscall From aec37e7cb1d34896f65948e88465376ceca68e0c Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 27 Oct 2014 18:58:25 -0400 Subject: [PATCH 02/33] encoding/json: encode \t as \t instead of \u0009 Shorter and easier to read form for a common character. LGTM=bradfitz R=adg, bradfitz CC=golang-codereviews, zimmski https://golang.org/cl/162340043 --- src/encoding/json/encode.go | 8 ++++- src/encoding/json/encode_test.go | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 9b7b9d5fd1..fca2a0980b 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -805,6 +805,9 @@ func (e *encodeState) string(s string) (int, error) { case '\r': e.WriteByte('\\') e.WriteByte('r') + case '\t': + e.WriteByte('\\') + e.WriteByte('t') default: // This encodes bytes < 0x20 except for \n and \r, // as well as <, > and &. The latter are escaped because they @@ -878,9 +881,12 @@ func (e *encodeState) stringBytes(s []byte) (int, error) { case '\r': e.WriteByte('\\') e.WriteByte('r') + case '\t': + e.WriteByte('\\') + e.WriteByte('t') default: // This encodes bytes < 0x20 except for \n and \r, - // as well as < and >. The latter are escaped because they + // as well as <, >, and &. The latter are escaped because they // can lead to security holes when user-controlled strings // are rendered into JSON and served to some browsers. e.WriteString(`\u00`) diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index eb84cbae14..7abfa85db7 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -478,3 +478,55 @@ func TestEncodePointerString(t *testing.T) { t.Fatalf("*N = %d; want 42", *back.N) } } + +var encodeStringTests = []struct { + in string + out string +}{ + {"\x00", `"\u0000"`}, + {"\x01", `"\u0001"`}, + {"\x02", `"\u0002"`}, + {"\x03", `"\u0003"`}, + {"\x04", `"\u0004"`}, + {"\x05", `"\u0005"`}, + {"\x06", `"\u0006"`}, + {"\x07", `"\u0007"`}, + {"\x08", `"\u0008"`}, + {"\x09", `"\t"`}, + {"\x0a", `"\n"`}, + {"\x0b", `"\u000b"`}, + {"\x0c", `"\u000c"`}, + {"\x0d", `"\r"`}, + {"\x0e", `"\u000e"`}, + {"\x0f", `"\u000f"`}, + {"\x10", `"\u0010"`}, + {"\x11", `"\u0011"`}, + {"\x12", `"\u0012"`}, + {"\x13", `"\u0013"`}, + {"\x14", `"\u0014"`}, + {"\x15", `"\u0015"`}, + {"\x16", `"\u0016"`}, + {"\x17", `"\u0017"`}, + {"\x18", `"\u0018"`}, + {"\x19", `"\u0019"`}, + {"\x1a", `"\u001a"`}, + {"\x1b", `"\u001b"`}, + {"\x1c", `"\u001c"`}, + {"\x1d", `"\u001d"`}, + {"\x1e", `"\u001e"`}, + {"\x1f", `"\u001f"`}, +} + +func TestEncodeString(t *testing.T) { + for _, tt := range encodeStringTests { + b, err := Marshal(tt.in) + if err != nil { + t.Errorf("Marshal(%q): %v", tt.in, err) + continue + } + out := string(b) + if out != tt.out { + t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out) + } + } +} From 0f698be54742be2d66c044b61267782272777ff8 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 27 Oct 2014 18:59:02 -0400 Subject: [PATCH 03/33] test: make maplinear more robust The test just doubled a certain number of times and then gave up. On a mostly fast but occasionally slow machine this may never make the test run long enough to see the linear growth. Change test to keep doubling until the first round takes at least a full second, to reduce the effect of occasional scheduling or other jitter. The failure we saw had a time for the first round of around 100ms. Note that this test still passes once it sees a linear effect, even with a very small total time. The timeout here only applies to how long the execution must be to support a reported failure. LGTM=khr R=khr CC=golang-codereviews, rlh https://golang.org/cl/164070043 --- test/maplinear.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/maplinear.go b/test/maplinear.go index 06da968ef0..34d0914914 100644 --- a/test/maplinear.go +++ b/test/maplinear.go @@ -44,14 +44,21 @@ func checkLinear(typ string, tries int, f func(n int)) { } return } - fails++ - if fails == 6 { + // If n ops run in under a second and the ratio + // doesn't work out, make n bigger, trying to reduce + // the effect that a constant amount of overhead has + // on the computed ratio. + if t1 < 1*time.Second { + n *= 2 + continue + } + // Once the test runs long enough for n ops, + // try to get the right ratio at least once. + // If five in a row all fail, give up. + if fails++; fails >= 5 { panic(fmt.Sprintf("%s: too slow: %d inserts: %v; %d inserts: %v\n", typ, n, t1, 2*n, t2)) } - if fails < 4 { - n *= 2 - } } } From e71c9cbe260941bfb322c69e4a4f10b4323a228e Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Tue, 28 Oct 2014 10:18:44 +1100 Subject: [PATCH 04/33] html/template: fix build after encoding/js escaping change TBR=rsc R=golang-codereviews CC=golang-codereviews https://golang.org/cl/159590043 --- src/html/template/js_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go index 311e1d2c4e..7af7997de9 100644 --- a/src/html/template/js_test.go +++ b/src/html/template/js_test.go @@ -138,7 +138,7 @@ func TestJSValEscaper(t *testing.T) { // Newlines. {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`}, // "\v" == "v" on IE 6 so use "\x0b" instead. - {"\t\x0b", `"\u0009\u000b"`}, + {"\t\x0b", `"\t\u000b"`}, {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`}, {[]interface{}{}, "[]"}, {[]interface{}{42, "foo", nil}, `[42,"foo",null]`}, From ccc713c7caa8900facc99bffaad4ee4a22013b01 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 27 Oct 2014 16:31:15 -0700 Subject: [PATCH 05/33] spec: permit parentheses around builtin function names Not a language change. This is simply documenting the status quo which permits builtin function names to be parenthesized in calls; e.g., both len(s) and (((len)))(s) are accepted by all compilers and go/types. Changed the grammar by merging the details of BuiltinCall with ordinary Calls. Also renamed the Call production to Arguments which more clearly identifies that part of the grammar and also matches better with its counterpart on the declaration side (Parameters). The fact that the first argument can be a type (for builtins) or cannot be a type (for regular function calls) is expressed in the prose, no need to make the grammar more complicated. Fixes #9001. LGTM=iant, r, rsc R=r, rsc, iant, ken, dave CC=golang-codereviews https://golang.org/cl/160570043 --- doc/go_spec.html | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index ad645c1ffc..050c06465d 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -2449,12 +2449,11 @@ Primary expressions are the operands for unary and binary expressions. PrimaryExpr = Operand | Conversion | - BuiltinCall | PrimaryExpr Selector | PrimaryExpr Index | PrimaryExpr Slice | PrimaryExpr TypeAssertion | - PrimaryExpr Call . + PrimaryExpr Arguments . Selector = "." identifier . Index = "[" Expression "]" . @@ -2462,8 +2461,7 @@ Slice = "[" ( [ Expression ] ":" [ Expression ] ) | ( [ Expression ] ":" Expression ":" Expression ) "]" . TypeAssertion = "." "(" Type ")" . -Call = "(" [ ArgumentList [ "," ] ] ")" . -ArgumentList = ExpressionList [ "..." ] . +Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" . @@ -3166,7 +3164,7 @@ the method.
 math.Atan2(x, y)  // function call
 var pt *Point
-pt.Scale(3.5)  // method call with receiver pt
+pt.Scale(3.5)     // method call with receiver pt
 

@@ -5371,11 +5369,6 @@ so they can only appear in call expressions; they cannot be used as function values.

-
-BuiltinCall = identifier "(" [ BuiltinArgs [ "," ] ] ")" .
-BuiltinArgs = Type [ "," ArgumentList ] | ArgumentList .
-
-

Close

From 2eb1b658305bfd32774fd1e6a32cd6463564cf89 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Mon, 27 Oct 2014 17:08:50 -0700 Subject: [PATCH 06/33] doc/go_mem.html: don't be clever Add a short introductory section saying what most Go programmers really need to know, which is that you shouldn't have to read this document to understand the behavior of your program. LGTM=bradfitz, adg, tracey.brendan, iant, rsc, dsymonds R=golang-codereviews, bradfitz, tracey.brendan, adg, iant, rsc, dsymonds CC=golang-codereviews https://golang.org/cl/158500043 --- doc/go_mem.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/go_mem.html b/doc/go_mem.html index 2ea1ded7a3..5dd48ff7fb 100644 --- a/doc/go_mem.html +++ b/doc/go_mem.html @@ -21,6 +21,29 @@ reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine.

+ +

Advice

+ +

+Programs that modify data being simultaneously accessed by multiple goroutines +must serialize such access. +

+ +

+To serialize access, protect the data with channel operations or other synchronization primitives +such as those in the sync +and sync/atomic packages. +

+ +

+If you must read the rest of this document to understand the behavior of your program, +you are being too clever. +

+ +

+Don't be clever. +

+

Happens Before

From 2fe9482343a4321d54dac5eca5eb04e06aea29d6 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Mon, 27 Oct 2014 20:35:15 -0400 Subject: [PATCH 07/33] runtime: add fake time support back. Revived from CL 15690048. Fixes #5356. LGTM=rsc R=adg, dvyukov, rsc CC=golang-codereviews https://golang.org/cl/101400043 --- src/runtime/proc.c | 20 ++++++++++++++++++++ src/runtime/rt0_nacl_amd64p32.s | 4 ++-- src/runtime/sys_nacl_amd64p32.s | 6 +++--- src/runtime/time.go | 29 ++++++++++++++++++++++++++--- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/runtime/proc.c b/src/runtime/proc.c index 1426790f40..52f7ef3a5b 100644 --- a/src/runtime/proc.c +++ b/src/runtime/proc.c @@ -2758,6 +2758,8 @@ static void checkdead(void) { G *gp; + P *p; + M *mp; int32 run, grunning, s; uintptr i; @@ -2799,6 +2801,24 @@ checkdead(void) runtime·unlock(&runtime·allglock); if(grunning == 0) // possible if main goroutine calls runtime·Goexit() runtime·throw("no goroutines (main called runtime.Goexit) - deadlock!"); + + // Maybe jump time forward for playground. + if((gp = runtime·timejump()) != nil) { + runtime·casgstatus(gp, Gwaiting, Grunnable); + globrunqput(gp); + p = pidleget(); + if(p == nil) + runtime·throw("checkdead: no p for timer"); + mp = mget(); + if(mp == nil) + newm(nil, p); + else { + mp->nextp = p; + runtime·notewakeup(&mp->park); + } + return; + } + g->m->throwing = -1; // do not dump full stacks runtime·throw("all goroutines are asleep - deadlock!"); } diff --git a/src/runtime/rt0_nacl_amd64p32.s b/src/runtime/rt0_nacl_amd64p32.s index d8703dc0f0..6ad8bea6c7 100644 --- a/src/runtime/rt0_nacl_amd64p32.s +++ b/src/runtime/rt0_nacl_amd64p32.s @@ -25,6 +25,6 @@ TEXT _rt0_amd64p32_nacl(SB),NOSPLIT,$16 TEXT main(SB),NOSPLIT,$0 // Uncomment for fake time like on Go Playground. - //MOVQ $1257894000000000000, AX - //MOVQ AX, runtime·timens(SB) + MOVQ $1257894000000000000, AX + MOVQ AX, runtime·faketime(SB) JMP runtime·rt0_go(SB) diff --git a/src/runtime/sys_nacl_amd64p32.s b/src/runtime/sys_nacl_amd64p32.s index c30c2a8933..4eb4aacdd5 100644 --- a/src/runtime/sys_nacl_amd64p32.s +++ b/src/runtime/sys_nacl_amd64p32.s @@ -60,7 +60,7 @@ TEXT syscall·naclWrite(SB), NOSPLIT, $24-20 TEXT runtime·write(SB),NOSPLIT,$16-20 // If using fake time and writing to stdout or stderr, // emit playback header before actual data. - MOVQ runtime·timens(SB), AX + MOVQ runtime·faketime(SB), AX CMPQ AX, $0 JEQ write MOVL fd+0(FP), DI @@ -242,7 +242,7 @@ TEXT runtime·mmap(SB),NOSPLIT,$8 RET TEXT time·now(SB),NOSPLIT,$16 - MOVQ runtime·timens(SB), AX + MOVQ runtime·faketime(SB), AX CMPQ AX, $0 JEQ realtime MOVQ $0, DX @@ -277,7 +277,7 @@ TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0 RET TEXT runtime·nanotime(SB),NOSPLIT,$16 - MOVQ runtime·timens(SB), AX + MOVQ runtime·faketime(SB), AX CMPQ AX, $0 JEQ 3(PC) MOVQ AX, ret+0(FP) diff --git a/src/runtime/time.go b/src/runtime/time.go index 8cf9eecf83..11862c7e23 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -35,8 +35,8 @@ var timers struct { t []*timer } -// nacl fake time support. -var timens int64 +// nacl fake time support - time in nanoseconds since 1970 +var faketime int64 // Package time APIs. // Godoc uses the comments in package time, not these. @@ -194,7 +194,7 @@ func timerproc() { f(arg, seq) lock(&timers.lock) } - if delta < 0 { + if delta < 0 || faketime > 0 { // No timers left - put goroutine to sleep. timers.rescheduling = true goparkunlock(&timers.lock, "timer goroutine (idle)") @@ -208,6 +208,29 @@ func timerproc() { } } +func timejump() *g { + if faketime == 0 { + return nil + } + + lock(&timers.lock) + if !timers.created || len(timers.t) == 0 { + unlock(&timers.lock) + return nil + } + + var gp *g + if faketime < timers.t[0].when { + faketime = timers.t[0].when + if timers.rescheduling { + timers.rescheduling = false + gp = timers.gp + } + } + unlock(&timers.lock) + return gp +} + // Heap maintenance algorithms. func siftupTimer(i int) { From 1c534714e1d353d45670a3ed76f4f4a7c7bfa7c6 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 27 Oct 2014 20:45:16 -0400 Subject: [PATCH 08/33] syscall: accept pre-existing directories in nacl zip file NaCl creates /tmp. This lets the zip file populate it. LGTM=adg R=adg CC=golang-codereviews https://golang.org/cl/159600043 --- src/syscall/fs_nacl.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/syscall/fs_nacl.go b/src/syscall/fs_nacl.go index 4abc9b81c9..6e6ce2ab7b 100644 --- a/src/syscall/fs_nacl.go +++ b/src/syscall/fs_nacl.go @@ -818,6 +818,12 @@ func create(name string, mode uint32, sec int64, data []byte) error { fs.mu.Unlock() f, err := fs.open(name, O_CREATE|O_EXCL, mode) if err != nil { + if mode&S_IFMT == S_IFDIR { + ip, _, err := fs.namei(name, false) + if err == nil && (ip.Mode&S_IFMT) == S_IFDIR { + return nil // directory already exists + } + } return err } ip := f.(*fsysFile).inode From 138b5ccd12739f47be1f21f6437d6795b389b9f7 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 27 Oct 2014 20:47:15 -0400 Subject: [PATCH 09/33] runtime: disable fake time on nacl This leaked into the CL I submitted for Minux, because I was testing it. TBR=adg CC=golang-codereviews https://golang.org/cl/159600044 --- src/runtime/rt0_nacl_amd64p32.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/rt0_nacl_amd64p32.s b/src/runtime/rt0_nacl_amd64p32.s index 6ad8bea6c7..54e4b1de89 100644 --- a/src/runtime/rt0_nacl_amd64p32.s +++ b/src/runtime/rt0_nacl_amd64p32.s @@ -25,6 +25,6 @@ TEXT _rt0_amd64p32_nacl(SB),NOSPLIT,$16 TEXT main(SB),NOSPLIT,$0 // Uncomment for fake time like on Go Playground. - MOVQ $1257894000000000000, AX - MOVQ AX, runtime·faketime(SB) + //MOVQ $1257894000000000000, AX + //MOVQ AX, runtime·faketime(SB) JMP runtime·rt0_go(SB) From d39907e6491fe1bed48f89ef9717ccb2ad249102 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Mon, 27 Oct 2014 20:35:34 -0700 Subject: [PATCH 10/33] doc/go1.4.html: runtime and performance LGTM=adg, rsc R=golang-codereviews, adg, bradfitz, dave, rsc CC=golang-codereviews https://golang.org/cl/164090044 --- doc/go1.4.html | 81 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/doc/go1.4.html b/doc/go1.4.html index a48e675f6a..7f5a12d0bf 100644 --- a/doc/go1.4.html +++ b/doc/go1.4.html @@ -87,6 +87,59 @@ may now be nil. TODO news about foobarblatz

+

Changes to the runtime

+ +

+Up to Go 1.4, the runtime (garbage collector, concurrency support, interface management, +maps, slices, strings, ...) was mostly written in C, with some assembler support. +In 1.4, much of the code has been translated to Go so that the garbage collector can scan +the stacks of programs in the runtime and get accurate information about what variables +are active. +This change was large but should have no semantic effect on programs. +

+ +

+This rewrite allows the garbage collector in 1.4 to be fully precise, +meaning that it is aware of the location of all active pointers in the program. +This means the heap will be smaller as there will be no false positives keeping non-pointers alive. +Other related changes also reduce the heap size, which is smaller by 10%-30% overall +relative to the previous release. +

+ +

+A consequence is that stacks are no longer segmented, eliminating the "hot split" problem. +When a stack limit is reached, a new, larger stack is allocated, all active frames for +the goroutine are copied there, and any pointers into the stack are updated. +Performance can be noticeably better in some cases and is always more predictable. +Details are available in the design document. +

+ +

+The use of contiguous stacks means that stacks can start smaller without triggering performance issues, +so the default starting size for a goroutine's stack in 1.4 has been reduced to 2048 bytes from 8192 bytes. +TODO: It may be bumped to 4096 for the release. +

+ +

+As preparation for the concurrent garbage collector scheduled for the 1.5 release, +writes to pointer values in the heap are now done by a function call, +called a write barrier, rather than directly from the function updating the value. +In this next release, this will permit the garbage collector to mediate writes to the heap while it is running. +This change has no semantic effect on programs in 1.4, but was +included in the release to test the compiler and the resulting performance. +

+ +

+The implementation of interface values has been modified. +In earlier releases, the interface contained a word that was either a pointer or a one-word +scalar value, depending on the type of the concrete object stored. +This implementation was problematical for the garbage collector, +so as of 1.4 interface values always hold a pointer. +In running programs, most interface values were pointers anyway, +so the effect is minimal, but programs that store integers (for example) in +interfaces will see more allocations. +

+

Changes to the compatibility guidelines

@@ -177,7 +230,29 @@ TODO misc news

Performance

-TODO performance news +Most programs will run about the same speed or slightly faster in 1.4 than in 1.3; +some will be slightly slower. +There are many changes, making it hard to be precise about what to expect. +

+ +

+As mentioned above, much of the runtime was translated to Go from C, +which led to some reduction in heap sizes. +It also improved performance slightly because the Go compiler is better +at optimization, due to things like inlining, than the C compiler used to build +the runtime. +

+ +

+The garbage collector was sped up, leading to measurable improvements for +garbage-heavy programs. +On the other hand, the new write barriers slow things down again, typically +by about the same amount but, depending on their behavior, some programs +may be somewhat slower or faster. +

+ +

+Library changes that affect performance are documented below.

Changes to the standard library

@@ -209,8 +284,6 @@ See the relevant package documentation for more information about each change.
 
-the directory src/pkg has been deleted, for instance src/pkg/fmt is now just src/fmt (CL 134570043)
-
 cmd/6l, liblink: use pc-relative addressing for all memory references, so that linking Go binaries at high addresses works (CL 125140043). This cuts the maximum size of a Go binary's text+data+bss from 4GB to 2GB.
 cmd/go: import comments (CL 124940043)
 cmd/go: implement "internal" (CL 120600043)
@@ -237,8 +310,8 @@ net/http: add Transport.DialTLS hook (CL 137940043)
 net/http/httputil: add ReverseProxy.ErrorLog (CL 132750043)
 os: implement symlink support for windows (CL 86160044)
 reflect: add type.Comparable (CL 144020043)
+reflect: Value is one word smaller
 runtime: implement monotonic clocks on windows (CL 108700045)
-runtime: memory consumption is reduced by 10-30% (CL 106260045 removes type info from heap, CL 145790043 reduces stack size to 2K (4K on plan 9 and windows))
 runtime: MemStats.Mallocs now counts very small allocations missed in Go 1.3. This may break tests using runtime.ReadMemStats or testing.AllocsPerRun by giving a more accurate answer than Go 1.3 did (CL 143150043).
 runtime/race: freebsd is supported (CL 107270043)
 swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released)

From cd69218bdffc08e3c17023ac604bbb1a995b8602 Mon Sep 17 00:00:00 2001
From: Rob Pike 
Date: Mon, 27 Oct 2014 22:47:50 -0700
Subject: [PATCH 11/33] doc/go1.4.html: much of the go command's changes still
 need to do internal and import comments

LGTM=adg
R=golang-codereviews, adg
CC=golang-codereviews
https://golang.org/cl/160600043
---
 doc/go1.4.html | 178 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 127 insertions(+), 51 deletions(-)

diff --git a/doc/go1.4.html b/doc/go1.4.html
index 7f5a12d0bf..592b8661f1 100644
--- a/doc/go1.4.html
+++ b/doc/go1.4.html
@@ -87,7 +87,35 @@ may now be nil.
 TODO news about foobarblatz
 

-

Changes to the runtime

+

Changes to the compatibility guidelines

+ +

+The unsafe package allows one +to defeat Go's type system by exploiting internal details of the implementation +or machine representation of data. +It was never explicitly specified what use of unsafe meant +with respect to compatibility as specified in the +Go compatibilty guidelines. +The answer, of course, is that we can make no promise of compatibility +for code that does unsafe things. +

+ +

+We have clarified this situation in the documentation included in the release. +The Go compatibilty guidelines and the +docs for the unsafe package +are now explicit that unsafe code is not guaranteed to remain compatible. +

+ +

+Updating: Nothing technical has changed; this is just a clarification +of the documentation. +

+ + +

Changes to the implementations and tools

+ +

Changes to the runtime

Up to Go 1.4, the runtime (garbage collector, concurrency support, interface management, @@ -140,58 +168,114 @@ so the effect is minimal, but programs that store integers (for example) in interfaces will see more allocations.

-

Changes to the compatibility guidelines

- -

-The unsafe package allows one -to defeat Go's type system by exploiting internal details of the implementation -or machine representation of data. -It was never explicitly specified what use of unsafe meant -with respect to compatibility as specified in the -Go compatibilty guidelines. -The answer, of course, is that we can make no promise of compatibility -for code that does unsafe things. -

- -

-We have clarified this situation in the documentation included in the release. -The Go compatibilty guidelines and the -docs for the unsafe package -are now explicit that unsafe code is not guaranteed to remain compatible. -

- -

-Updating: Nothing technical has changed; this is just a clarification -of the documentation. -

- - -

Changes to the implementations and tools

- -

Changes to the garbage collector

- -

-TODO news about garbage collection -

- -

Stack

- -

-TODO news about stacks -

-

Status of gccgo

TODO gccgo news

-

Changes to the go command

+

Internal packages

+
+TODO prose for these
+cmd/go: implement "internal" (CL 120600043)
+
+ +

Import comments

+ +
+TODO prose for these
+cmd/go: import comments (CL 124940043)
+
+ +

The go generate subcommand

-TODO go command news +The go command has a new subcommand, +go generate, +to automate the running of tools to generate source code before compilation. +For example, it can be used to run the yacc +compiler-compiler on a .y file to produce the Go source file implementing the grammar, +or to automate the generation of String methods for typed constants using the new +stringer +tool in the go.tools repository.

+

+For more information, see the +design document. +

+ +

Change to file name handling

+ +

+Build constraints, also known as build tags, control compilation by including or excluding files +(see the documentation /go/build). +Compilation can also be controlled by the name of the file itself by "tagging" the file with +a suffix (before the .go or .s extension) with an underscore +and the name of the architecture or operating system. +For instance, the file gopher_arm.go will only be compiled if the target +processor is an ARM. +

+ +

+Before Go 1.4, a file called just arm.go was similarly tagged, but this behavior +can break sources when new architectures are added, causing files to suddenly become tagged. +In 1.4, therefore, a file will be tagged in this manner only if the tag (architecture or operating +system name) is preceded by an underscore. +

+ +

+Updating: Packages that depend on the old behavior will no longer compile correctly. +Files with names like windows.go or arm64.go should either +have explicit build tags added to the source or be renamed to something like +os_windows.go or support_arm64.go. +

+ +

Other changes to the go command

+ +

+There were a number of minor changes to the +cmd/go +command worth noting. +

+ +
    + +
  • +Unless cgo is being used to build the package, +the go command now refuses to compile C source files, +since the relevant C compilers +(6c etc.) +are intended to be removed from the installation in some future release. +(They are used today only to build part of the runtime.) +It is difficult to use them correctly in any case, so any extant uses are likely incorrect, +so we have disabled them. +
  • + +
  • +The go test +subcommand has a new flag, -o, to set the name of the resulting binary, +corresponding to the same flag in other subcommands. +The non-functional -file flag has been removed. +
  • + +
  • +The go test +will compile and link all *_test.go files in the package, +even when there are no Test functions in them. +It previously ignored such files. +
  • + +
  • +The behavior of the +go build's +-a flag has been changed for non-development installations. +For installations running a released distribution, the -a flag will no longer +rebuild the standard library and commands, to avoid overwriting the installation's files. +
  • + +
+

Changes to cgo

@@ -285,14 +369,6 @@ See the relevant package documentation for more information about each change.

 
 cmd/6l, liblink: use pc-relative addressing for all memory references, so that linking Go binaries at high addresses works (CL 125140043). This cuts the maximum size of a Go binary's text+data+bss from 4GB to 2GB.
-cmd/go: import comments (CL 124940043)
-cmd/go: implement "internal" (CL 120600043)
-cmd/go: implement "generate" (CL 125580044)
-cmd/go: disallow C sources except when using cgo (CL 149720043)
-cmd/go: add test -o flag (CL 149070043)
-cmd/go: redefine build -a to skip standard library in releases (CL 151730045)
-cmd/go: compile and link all _test.go files during 'go test', even in packages where there are no Test functions (CL 150980043)
-cmd/go: (via go/build): a GOOS prefix acts as a tag only if preceded by an underscore. this is a breaking change. (CL 147690043)
 
 asm: make textflag.h available outside of cmd/ld (CL 128050043)
 bufio: handling of empty tokens at EOF changed, may require scanner change (CL 145390043)

From 21a9141ab364ecfea016bf36b8222f4747afa1fb Mon Sep 17 00:00:00 2001
From: Mikio Hara 
Date: Tue, 28 Oct 2014 16:20:49 +0900
Subject: [PATCH 12/33] net: add test for lookupIPDeadline

Just to confirm the fix, by typing the follwing:
go test -run=TestLookupIPDeadline -dnsflood or
go test -run=TestLookupIPDeadline -dnsflood -tags netgo

Update #8602

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/166740043
---
 src/net/z_last_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/src/net/z_last_test.go b/src/net/z_last_test.go
index 4f6a54a560..716c103db2 100644
--- a/src/net/z_last_test.go
+++ b/src/net/z_last_test.go
@@ -8,6 +8,7 @@ import (
 	"flag"
 	"fmt"
 	"testing"
+	"time"
 )
 
 var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
@@ -35,3 +36,64 @@ func TestDNSThreadLimit(t *testing.T) {
 
 	// If we're still here, it worked.
 }
+
+func TestLookupIPDeadline(t *testing.T) {
+	if !*testDNSFlood {
+		t.Skip("test disabled; use -dnsflood to enable")
+	}
+
+	const N = 5000
+	const timeout = 3 * time.Second
+	c := make(chan error, 2*N)
+	for i := 0; i < N; i++ {
+		name := fmt.Sprintf("%d.net-test.golang.org", i)
+		go func() {
+			_, err := lookupIPDeadline(name, time.Now().Add(timeout/2))
+			c <- err
+		}()
+		go func() {
+			_, err := lookupIPDeadline(name, time.Now().Add(timeout))
+			c <- err
+		}()
+	}
+	qstats := struct {
+		succeeded, failed         int
+		timeout, temporary, other int
+		unknown                   int
+	}{}
+	deadline := time.After(timeout + time.Second)
+	for i := 0; i < 2*N; i++ {
+		select {
+		case <-deadline:
+			t.Fatal("deadline exceeded")
+		case err := <-c:
+			switch err := err.(type) {
+			case nil:
+				qstats.succeeded++
+			case Error:
+				qstats.failed++
+				if err.Timeout() {
+					qstats.timeout++
+				}
+				if err.Temporary() {
+					qstats.temporary++
+				}
+				if !err.Timeout() && !err.Temporary() {
+					qstats.other++
+				}
+			default:
+				qstats.failed++
+				qstats.unknown++
+			}
+		}
+	}
+
+	// A high volume of DNS queries for sub-domain of golang.org
+	// would be coordinated by authoritative or recursive server,
+	// or stub resolver which implements query-response rate
+	// limitation, so we can expect some query successes and more
+	// failures including timeout, temporary and other here.
+	// As a rule, unknown must not be shown but it might possibly
+	// happen due to issue 4856 for now.
+	t.Logf("%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)", qstats.succeeded, qstats.failed, qstats.timeout, qstats.temporary, qstats.other, qstats.unknown)
+}

From ea295a4cfbb0641f58c41d3722e7e8fb3b3f493f Mon Sep 17 00:00:00 2001
From: Russ Cox 
Date: Tue, 28 Oct 2014 11:14:25 -0400
Subject: [PATCH 13/33] cmd/go: add get -f flag

get -u now checks that remote repo paths match the
ones predicted by the import paths: if you are get -u'ing
rsc.io/pdf, it has to be checked out from the right location.
This is important in case the rsc.io/pdf redirect changes.

In some cases, people have good reasons to use
non-standard remote repos. Add -f flag to allow that.
The f can stand for force or fork, as you see fit.

Fixes #8850.

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/164120043
---
 src/cmd/go/get.go    | 14 ++++++++++++--
 src/cmd/go/test.bash | 10 ++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go
index b8eac5c1ef..86e1697618 100644
--- a/src/cmd/go/get.go
+++ b/src/cmd/go/get.go
@@ -16,7 +16,7 @@ import (
 )
 
 var cmdGet = &Command{
-	UsageLine: "get [-d] [-fix] [-t] [-u] [build flags] [packages]",
+	UsageLine: "get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]",
 	Short:     "download and install packages and dependencies",
 	Long: `
 Get downloads and installs the packages named by the import paths,
@@ -25,6 +25,11 @@ along with their dependencies.
 The -d flag instructs get to stop after downloading the packages; that is,
 it instructs get not to install the packages.
 
+The -f flag, valid only when -u is set, forces get -u not to verify that
+each package has been checked out from the source control repository
+implied by its import path. This can be useful if the source is a local fork
+of the original.
+
 The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
@@ -53,6 +58,7 @@ See also: go build, go install, go clean.
 }
 
 var getD = cmdGet.Flag.Bool("d", false, "")
+var getF = cmdGet.Flag.Bool("f", false, "")
 var getT = cmdGet.Flag.Bool("t", false, "")
 var getU = cmdGet.Flag.Bool("u", false, "")
 var getFix = cmdGet.Flag.Bool("fix", false, "")
@@ -63,6 +69,10 @@ func init() {
 }
 
 func runGet(cmd *Command, args []string) {
+	if *getF && !*getU {
+		fatalf("go get: cannot use -f flag without -u")
+	}
+
 	// Phase 1.  Download/update.
 	var stk importStack
 	for _, arg := range downloadPaths(args) {
@@ -268,7 +278,7 @@ func downloadPackage(p *Package) error {
 		repo = "" // should be unused; make distinctive
 
 		// Double-check where it came from.
-		if *getU && vcs.remoteRepo != nil {
+		if *getU && vcs.remoteRepo != nil && !*getF {
 			dir := filepath.Join(p.build.SrcRoot, rootPath)
 			if remote, err := vcs.remoteRepo(vcs, dir); err == nil {
 				if rr, err := repoRootForImportPath(p.ImportPath); err == nil {
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
index 652ef3b5b6..2b5230b1aa 100755
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -219,6 +219,16 @@ q' | ed $d/src/$config >/dev/null 2>&1
 			cat $d/err
 			ok=false
 		fi
+		
+		if GOPATH=$d ./testgo get -d -f -u $url 2>$d/err; then
+			echo "go get -d -u $url succeeded with wrong remote repo"
+			cat $d/err
+			ok=false
+		elif ! egrep -i 'validating server certificate|not found' $d/err >/dev/null; then
+			echo "go get -d -f -u $url failed for wrong reason"
+			cat $d/err
+			ok=false
+		fi
 	fi
 	rm -rf $d
 }

From 96e9e81b5f353636965fa6ba5e014c2bab13fadc Mon Sep 17 00:00:00 2001
From: Russ Cox 
Date: Tue, 28 Oct 2014 11:35:00 -0400
Subject: [PATCH 14/33] syscall: fix ParseRoutingSockaddr with unexpected
 submessages

No easy way to test (would have to actually trigger some routing
events from kernel) but the code is clearly wrong as written.
If the header says there is a submessage, we need to at least
skip over its bytes, not just continue to the next iteration.

Fixes #8203.

LGTM=r
R=r
CC=golang-codereviews, mikioh.mikioh, p
https://golang.org/cl/164140044
---
 src/syscall/route_bsd.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/syscall/route_bsd.go b/src/syscall/route_bsd.go
index 48af587450..1dabe42531 100644
--- a/src/syscall/route_bsd.go
+++ b/src/syscall/route_bsd.go
@@ -153,7 +153,7 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
 	// RTAX_NETMASK socket address on the FreeBSD kernel.
 	preferredFamily := uint8(AF_UNSPEC)
 	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaIfaMask&(1<
Date: Tue, 28 Oct 2014 12:35:25 -0400
Subject: [PATCH 15/33] runtime: add PauseEnd array to MemStats and GCStats

Fixes #8787.

LGTM=rsc
R=rsc, dvyukov
CC=golang-codereviews
https://golang.org/cl/153670043
---
 src/runtime/debug/garbage.go      | 30 +++++++++++++++++++++---------
 src/runtime/debug/garbage_test.go | 13 +++++++++++++
 src/runtime/malloc.h              |  3 ++-
 src/runtime/mem.go                |  3 ++-
 src/runtime/mgc0.c                | 23 ++++++++++++++---------
 5 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/src/runtime/debug/garbage.go b/src/runtime/debug/garbage.go
index 30994f2196..4a77dcfcd6 100644
--- a/src/runtime/debug/garbage.go
+++ b/src/runtime/debug/garbage.go
@@ -16,6 +16,7 @@ type GCStats struct {
 	NumGC          int64           // number of garbage collections
 	PauseTotal     time.Duration   // total pause for all collections
 	Pause          []time.Duration // pause history, most recent first
+	PauseEnd       []time.Time     // pause end times history, most recent first
 	PauseQuantiles []time.Duration
 }
 
@@ -30,25 +31,36 @@ type GCStats struct {
 func ReadGCStats(stats *GCStats) {
 	// Create a buffer with space for at least two copies of the
 	// pause history tracked by the runtime. One will be returned
-	// to the caller and the other will be used as a temporary buffer
-	// for computing quantiles.
+	// to the caller and the other will be used as transfer buffer
+	// for end times history and as a temporary buffer for
+	// computing quantiles.
 	const maxPause = len(((*runtime.MemStats)(nil)).PauseNs)
-	if cap(stats.Pause) < 2*maxPause {
-		stats.Pause = make([]time.Duration, 2*maxPause)
+	if cap(stats.Pause) < 2*maxPause+3 {
+		stats.Pause = make([]time.Duration, 2*maxPause+3)
 	}
 
-	// readGCStats fills in the pause history (up to maxPause entries)
-	// and then three more: Unix ns time of last GC, number of GC,
-	// and total pause time in nanoseconds. Here we depend on the
-	// fact that time.Duration's native unit is nanoseconds, so the
-	// pauses and the total pause time do not need any conversion.
+	// readGCStats fills in the pause and end times histories (up to
+	// maxPause entries) and then three more: Unix ns time of last GC,
+	// number of GC, and total pause time in nanoseconds. Here we
+	// depend on the fact that time.Duration's native unit is
+	// nanoseconds, so the pauses and the total pause time do not need
+	// any conversion.
 	readGCStats(&stats.Pause)
 	n := len(stats.Pause) - 3
 	stats.LastGC = time.Unix(0, int64(stats.Pause[n]))
 	stats.NumGC = int64(stats.Pause[n+1])
 	stats.PauseTotal = stats.Pause[n+2]
+	n /= 2 // buffer holds pauses and end times
 	stats.Pause = stats.Pause[:n]
 
+	if cap(stats.PauseEnd) < maxPause {
+		stats.PauseEnd = make([]time.Time, 0, maxPause)
+	}
+	stats.PauseEnd = stats.PauseEnd[:0]
+	for _, ns := range stats.Pause[n : n+n] {
+		stats.PauseEnd = append(stats.PauseEnd, time.Unix(0, int64(ns)))
+	}
+
 	if len(stats.PauseQuantiles) > 0 {
 		if n == 0 {
 			for i := range stats.PauseQuantiles {
diff --git a/src/runtime/debug/garbage_test.go b/src/runtime/debug/garbage_test.go
index 149bafc6f3..54c33bd4f3 100644
--- a/src/runtime/debug/garbage_test.go
+++ b/src/runtime/debug/garbage_test.go
@@ -70,6 +70,19 @@ func TestReadGCStats(t *testing.T) {
 			t.Errorf("stats.PauseQuantiles[%d]=%d > stats.PauseQuantiles[%d]=%d", i, q[i], i+1, q[i+1])
 		}
 	}
+
+	// compare memory stats with gc stats:
+	if len(stats.PauseEnd) != n {
+		t.Fatalf("len(stats.PauseEnd) = %d, want %d", len(stats.PauseEnd), n)
+	}
+	off := (int(mstats.NumGC) + len(mstats.PauseEnd) - 1) % len(mstats.PauseEnd)
+	for i := 0; i < n; i++ {
+		dt := stats.PauseEnd[i]
+		if dt.UnixNano() != int64(mstats.PauseEnd[off]) {
+			t.Errorf("stats.PauseEnd[%d] = %d, want %d", i, dt, mstats.PauseEnd[off])
+		}
+		off = (off + len(mstats.PauseEnd) - 1) % len(mstats.PauseEnd)
+	}
 }
 
 var big = make([]byte, 1<<20)
diff --git a/src/runtime/malloc.h b/src/runtime/malloc.h
index d1930756a2..adb8d3d677 100644
--- a/src/runtime/malloc.h
+++ b/src/runtime/malloc.h
@@ -267,7 +267,8 @@ struct MStats
 	uint64	next_gc;	// next GC (in heap_alloc time)
 	uint64  last_gc;	// last GC (in absolute time)
 	uint64	pause_total_ns;
-	uint64	pause_ns[256];
+	uint64	pause_ns[256];  // circular buffer of recent GC pause lengths
+	uint64	pause_end[256]; // circular buffer of recent GC end times (nanoseconds since 1970)
 	uint32	numgc;
 	bool	enablegc;
 	bool	debuggc;
diff --git a/src/runtime/mem.go b/src/runtime/mem.go
index 438f22ec09..e6f1eb0e64 100644
--- a/src/runtime/mem.go
+++ b/src/runtime/mem.go
@@ -44,7 +44,8 @@ type MemStats struct {
 	NextGC       uint64 // next collection will happen when HeapAlloc ≥ this amount
 	LastGC       uint64 // end time of last collection (nanoseconds since 1970)
 	PauseTotalNs uint64
-	PauseNs      [256]uint64 // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
+	PauseNs      [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256]
+	PauseEnd     [256]uint64 // circular buffer of recent GC pause end times
 	NumGC        uint32
 	EnableGC     bool
 	DebugGC      bool
diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c
index 2ff64aaa30..cba2beaa74 100644
--- a/src/runtime/mgc0.c
+++ b/src/runtime/mgc0.c
@@ -1459,6 +1459,7 @@ gc(struct gc_args *args)
 	t4 = runtime·nanotime();
 	runtime·atomicstore64(&mstats.last_gc, runtime·unixnanotime());  // must be Unix time to make sense to user
 	mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
+	mstats.pause_end[mstats.numgc%nelem(mstats.pause_end)] = t4;
 	mstats.pause_total_ns += t4 - t0;
 	mstats.numgc++;
 	if(mstats.debuggc)
@@ -1572,7 +1573,7 @@ readgcstats_m(void)
 {
 	Slice *pauses;	
 	uint64 *p;
-	uint32 i, n;
+	uint32 i, j, n;
 	
 	pauses = g->m->ptrarg[0];
 	g->m->ptrarg[0] = nil;
@@ -1581,25 +1582,29 @@ readgcstats_m(void)
 	if(pauses->cap < nelem(mstats.pause_ns)+3)
 		runtime·throw("runtime: short slice passed to readGCStats");
 
-	// Pass back: pauses, last gc (absolute time), number of gc, total pause ns.
+	// Pass back: pauses, pause ends, last gc (absolute time), number of gc, total pause ns.
 	p = (uint64*)pauses->array;
 	runtime·lock(&runtime·mheap.lock);
+
 	n = mstats.numgc;
 	if(n > nelem(mstats.pause_ns))
 		n = nelem(mstats.pause_ns);
-	
+
 	// The pause buffer is circular. The most recent pause is at
 	// pause_ns[(numgc-1)%nelem(pause_ns)], and then backward
 	// from there to go back farther in time. We deliver the times
 	// most recent first (in p[0]).
-	for(i=0; ilen = n+3;
+	pauses->len = n+n+3;
 }
 
 void

From bd1169dd2144abbe58767bf2dfaa3f20e8cf553b Mon Sep 17 00:00:00 2001
From: Rob Pike 
Date: Tue, 28 Oct 2014 10:51:28 -0700
Subject: [PATCH 16/33] doc/go1.4.html: vanity imports and internal packages

LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews
https://golang.org/cl/165800043
---
 doc/go1.4.html | 107 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 93 insertions(+), 14 deletions(-)

diff --git a/doc/go1.4.html b/doc/go1.4.html
index 592b8661f1..ffabdb82c0 100644
--- a/doc/go1.4.html
+++ b/doc/go1.4.html
@@ -95,7 +95,7 @@ to defeat Go's type system by exploiting internal details of the implementation
 or machine representation of data.
 It was never explicitly specified what use of unsafe meant
 with respect to compatibility as specified in the
-Go compatibilty guidelines.
+Go compatibility guidelines.
 The answer, of course, is that we can make no promise of compatibility
 for code that does unsafe things.
 

@@ -175,25 +175,103 @@ TODO gccgo news

Internal packages

-
-TODO prose for these
-cmd/go: implement "internal" (CL 120600043)
-
-

Import comments

+

+Go's package system makes it easy to structure programs into components with clean boundaries, +but there are only two forms of access: local (unexported) and global (exported). +Sometimes one wishes to have components that are not exported, +for instance to avoid acquiring clients of interfaces to code that is part of a public repository +but not intended for use outside the program to which it belongs. +

+ +

+The Go language does not have the power to enforce this distinction, but as of Go 1.4 the +go command introduces +a mechanism to define "internal" packages that may not be imported by packages outside +the source subtree in which they reside. +

+ +

+To create such a package, place it in a directory named internal or in a subdirectory of a directory +named internal. +When the go command sees an import of a package with internal in its path, +it verifies that the package doing the import +is within the tree rooted at the parent of the internal directory. +For example, a package .../a/b/c/internal/d/e/f +can be imported only by code in the directory tree rooted at .../a/b/c. +It cannot be imported by code in .../a/b/g or in any other repository. +

+ +

+For Go 1.4, the internal package mechanism is enforced for the main Go repository; +from 1.5 and onward it will be enforced for any repository. +

+ +

+Full details of the mechanism are in +the design document. +

+ +

Canonical import paths

+ +

+Code often lives in repositories hosted by public services such as github.com, +meaning that the import paths for packages begin with the name of the hosting service, +github.com/rsc/pdf for example. +One can use +an existing mechanism +to provide a "custom" or "vanity" import path such as +rsc.io/pdf, but +that creates two valid import paths for the package. +That is a problem: one may inadvertently import the package through the two +distinct paths in a single program, which is wasteful; +miss an update to a package because the path being used is not recognized to be +out of date; +or break clients using the old path by moving the package to a different hosting service. +

+ +

+Go 1.4 introduces an annotation for package clauses in Go source that identify a canonical +import path for the package. +If an import is attempted using a path that is not canonical, +the go command +will refuse to compile the importing package. +

+ +

+The syntax is simple: put an identifying comment on the package line. +For our example, the package clause would read: +

-TODO prose for these
-cmd/go: import comments (CL 124940043)
+package pdf // import "rsc.io/pdf"
 
+

+With this in place, +the go command will +refuse to compile a package that imports github.com/rsc/pdf, +ensuring that the code can be moved without breaking users. +

+ +

+The check is at build time, not download time, so if go get +fails because of this check, the mis-imported package has been copied to the local machine +and should be removed manually. +

+ +

+Further information is in +the design document. +

+

The go generate subcommand

The go command has a new subcommand, go generate, to automate the running of tools to generate source code before compilation. -For example, it can be used to run the yacc +For example, it can be used to run the yacc compiler-compiler on a .y file to produce the Go source file implementing the grammar, or to automate the generation of String methods for typed constants using the new stringer @@ -226,9 +304,9 @@ system name) is preceded by an underscore.

Updating: Packages that depend on the old behavior will no longer compile correctly. -Files with names like windows.go or arm64.go should either +Files with names like windows.go or amd64.go should either have explicit build tags added to the source or be renamed to something like -os_windows.go or support_arm64.go. +os_windows.go or support_amd64.go.

Other changes to the go command

@@ -261,14 +339,15 @@ The non-functional -file flag has been removed.
  • The go test -will compile and link all *_test.go files in the package, +subcommand will compile and link all *_test.go files in the package, even when there are no Test functions in them. It previously ignored such files.
  • The behavior of the -go build's +go build +subcommand's -a flag has been changed for non-development installations. For installations running a released distribution, the -a flag will no longer rebuild the standard library and commands, to avoid overwriting the installation's files. @@ -376,7 +455,6 @@ compress/flate, compress/gzip, compress/zlib: Reset support (https://codereview. crypto/tls: add support for ALPN (RFC 7301) (CL 108710046) crypto/tls: support programmatic selection of server certificates (CL 107400043) encoding/asn1: optional elements with a default value will now only be omitted if they have that value (CL 86960045) -flag: it is now an error to set a flag multiple times (CL 156390043) fmt: print type *map[T]T as &map[k:v] (CL 154870043) encoding/csv: do not quote empty strings, quote \. (CL 164760043) encoding/gob: remove unsafe (CL 102680045) @@ -390,6 +468,7 @@ reflect: Value is one word smaller runtime: implement monotonic clocks on windows (CL 108700045) runtime: MemStats.Mallocs now counts very small allocations missed in Go 1.3. This may break tests using runtime.ReadMemStats or testing.AllocsPerRun by giving a more accurate answer than Go 1.3 did (CL 143150043). runtime/race: freebsd is supported (CL 107270043) +runtime: add PauseEnd array to MemStats and GCStats (CL 153670043) swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released) sync/atomic: add Value (CL 136710045) syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043) From a62da2027bf0fb5e6cd242c8806c04af7161a6fa Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 15:00:13 -0400 Subject: [PATCH 17/33] os: do not assume syscall i/o funcs return n=0 on error Fixes #9007. LGTM=iant, r R=r, iant CC=golang-codereviews https://golang.org/cl/160670043 --- src/os/dir_unix.go | 2 +- src/os/file.go | 9 +++++++++ src/os/file_plan9.go | 11 ++++------- src/os/file_posix.go | 2 +- src/os/file_unix.go | 10 +++++----- src/os/file_windows.go | 4 ++-- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go index d353e405e5..589db85274 100644 --- a/src/os/dir_unix.go +++ b/src/os/dir_unix.go @@ -36,7 +36,7 @@ func (f *File) readdirnames(n int) (names []string, err error) { if d.bufp >= d.nbuf { d.bufp = 0 var errno error - d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf) + d.nbuf, errno = fixCount(syscall.ReadDirent(f.fd, d.buf)) if errno != nil { return names, NewSyscallError("readdirent", errno) } diff --git a/src/os/file.go b/src/os/file.go index b4a7458016..e12428cbe1 100644 --- a/src/os/file.go +++ b/src/os/file.go @@ -255,3 +255,12 @@ var lstat = Lstat func Rename(oldpath, newpath string) error { return rename(oldpath, newpath) } + +// Many functions in package syscall return a count of -1 instead of 0. +// Using fixCount(call()) instead of call() corrects the count. +func fixCount(n int, err error) (int, error) { + if n < 0 { + n = 0 + } + return n, err +} diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go index a804b81973..22860e20af 100644 --- a/src/os/file_plan9.go +++ b/src/os/file_plan9.go @@ -244,14 +244,14 @@ func (f *File) Sync() (err error) { // read reads up to len(b) bytes from the File. // It returns the number of bytes read and an error, if any. func (f *File) read(b []byte) (n int, err error) { - return syscall.Read(f.fd, b) + return fixCount(syscall.Read(f.fd, b)) } // pread reads len(b) bytes from the File starting at byte offset off. // It returns the number of bytes read and the error, if any. // EOF is signaled by a zero count with err set to nil. func (f *File) pread(b []byte, off int64) (n int, err error) { - return syscall.Pread(f.fd, b, off) + return fixCount(syscall.Pread(f.fd, b, off)) } // write writes len(b) bytes to the File. @@ -259,10 +259,7 @@ func (f *File) pread(b []byte, off int64) (n int, err error) { // Since Plan 9 preserves message boundaries, never allow // a zero-byte write. func (f *File) write(b []byte) (n int, err error) { - if len(b) == 0 { - return 0, nil - } - return syscall.Write(f.fd, b) + return fixCount(syscall.Write(f.fd, b)) } // pwrite writes len(b) bytes to the File starting at byte offset off. @@ -273,7 +270,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { if len(b) == 0 { return 0, nil } - return syscall.Pwrite(f.fd, b, off) + return fixCount(syscall.Pwrite(f.fd, b, off)) } // seek sets the offset for the next Read or Write on file to offset, interpreted diff --git a/src/os/file_posix.go b/src/os/file_posix.go index 9cff7e5bcc..fbb3b5e4d8 100644 --- a/src/os/file_posix.go +++ b/src/os/file_posix.go @@ -18,7 +18,7 @@ func sigpipe() // implemented in package runtime func Readlink(name string) (string, error) { for len := 128; ; len *= 2 { b := make([]byte, len) - n, e := syscall.Readlink(name, b) + n, e := fixCount(syscall.Readlink(name, b)) if e != nil { return "", &PathError{"readlink", name, e} } diff --git a/src/os/file_unix.go b/src/os/file_unix.go index bba0d9c0f6..4e413fbe84 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -187,7 +187,7 @@ func (f *File) read(b []byte) (n int, err error) { if needsMaxRW && len(b) > maxRW { b = b[:maxRW] } - return syscall.Read(f.fd, b) + return fixCount(syscall.Read(f.fd, b)) } // pread reads len(b) bytes from the File starting at byte offset off. @@ -197,7 +197,7 @@ func (f *File) pread(b []byte, off int64) (n int, err error) { if needsMaxRW && len(b) > maxRW { b = b[:maxRW] } - return syscall.Pread(f.fd, b, off) + return fixCount(syscall.Pread(f.fd, b, off)) } // write writes len(b) bytes to the File. @@ -208,7 +208,7 @@ func (f *File) write(b []byte) (n int, err error) { if needsMaxRW && len(bcap) > maxRW { bcap = bcap[:maxRW] } - m, err := syscall.Write(f.fd, bcap) + m, err := fixCount(syscall.Write(f.fd, bcap)) n += m // If the syscall wrote some data but not all (short write) @@ -234,7 +234,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { if needsMaxRW && len(b) > maxRW { b = b[:maxRW] } - return syscall.Pwrite(f.fd, b, off) + return fixCount(syscall.Pwrite(f.fd, b, off)) } // seek sets the offset for the next Read or Write on file to offset, interpreted @@ -242,7 +242,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { - return syscall.Seek(f.fd, offset, whence) + return fixCount(syscall.Seek(f.fd, offset, whence)) } // Truncate changes the size of the named file. diff --git a/src/os/file_windows.go b/src/os/file_windows.go index e78d4abf64..3b5519390b 100644 --- a/src/os/file_windows.go +++ b/src/os/file_windows.go @@ -295,7 +295,7 @@ func (f *File) read(b []byte) (n int, err error) { if f.isConsole { return f.readConsole(b) } - return syscall.Read(f.fd, b) + return fixCount(syscall.Read(f.fd, b)) } // pread reads len(b) bytes from the File starting at byte offset off. @@ -376,7 +376,7 @@ func (f *File) write(b []byte) (n int, err error) { if f.isConsole { return f.writeConsole(b) } - return syscall.Write(f.fd, b) + return fixCount(syscall.Write(f.fd, b)) } // pwrite writes len(b) bytes to the File starting at byte offset off. From d7660143b6fb99073614b60269f57d9e47f07c2c Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 28 Oct 2014 12:11:34 -0700 Subject: [PATCH 18/33] doc/go1.4.html: new ports LGTM=rsc, aram, minux R=golang-codereviews, aram, minux, rsc CC=golang-codereviews https://golang.org/cl/162370045 --- doc/go1.4.html | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/doc/go1.4.html b/doc/go1.4.html index ffabdb82c0..35a0015a79 100644 --- a/doc/go1.4.html +++ b/doc/go1.4.html @@ -19,7 +19,8 @@ this release therefore eliminates the notorious "hot stack split" problem. There are some new tools available including support in the go command for build-time source code generation and TODO. -The release also adds support for TODO architecture and TODO operating systems. +The release also adds support for ARM processors on Android and Native Client (NaCl) +and AMD64 on Plan 9. As always, Go 1.4 keeps the promise of compatibility, and almost everything @@ -68,7 +69,7 @@ was not syntactically permitted.

    This situation seemed awkward, so as of Go 1.4 the variable-free form is now legal. -The situation arises only rarely but the code can be cleaner when it does. +The pattern arises rarely but the code can be cleaner when it does.

    @@ -81,10 +82,30 @@ may now be nil.

    Changes to the supported operating systems and architectures

    -

    FooBarBlatz

    +

    Android

    -TODO news about foobarblatz +Go 1.4 can build binaries for ARM processors running the Android operating system. +It can also build a .so library that can be loaded by an Android application +using the supporting packages in the go.mobile repository. +A brief description of the plans for this experimental port are available +here. +

    + +

    NaCl on ARM

    + +

    +The previous release introduced Native Client (NaCl) support for the 32-bit x86 +(GOARCH=386) +and 64-bit x86 using 32-bit pointers (GOARCH=amd64p32). +The 1.4 release adds NaCl support for ARM (GOARCH=arm). +

    + +

    Plan9 on AMD64

    + +

    +This release adds support for the Plan 9 operating system on AMD64 processors, +provided the kernel supports the nsec system call and uses 4K pages.

    Changes to the compatibility guidelines

    @@ -388,6 +409,7 @@ have been updated.

    TODO misc news +misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043)

    Performance

    @@ -432,6 +454,11 @@ TODO new packages TODO major changes

    +
    +encoding/gob: remove unsafe (CL 102680045)
    +syscall: now frozen (CL 129820043)
    +
    +

    Minor changes to the library

    @@ -457,8 +484,6 @@ crypto/tls: support programmatic selection of server certificates (CL 107400043) encoding/asn1: optional elements with a default value will now only be omitted if they have that value (CL 86960045) fmt: print type *map[T]T as &map[k:v] (CL 154870043) encoding/csv: do not quote empty strings, quote \. (CL 164760043) -encoding/gob: remove unsafe (CL 102680045) -misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043) net/http: add Request.BasicAuth method (CL 76540043) net/http: add Transport.DialTLS hook (CL 137940043) net/http/httputil: add ReverseProxy.ErrorLog (CL 132750043) @@ -472,13 +497,11 @@ runtime: add PauseEnd array to MemStats and GCStats (CL 153670043) swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released) sync/atomic: add Value (CL 136710045) syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043) -syscall: now frozen (CL 129820043) testing: add Coverage (CL 98150043) testing: add TestMain support (CL 148770043) text/scanner: add IsIdentRune field of Scanner. (CL 108030044) text/template: allow comparison of signed and unsigned integers (CL 149780043) time: use the micro symbol (µ (U+00B5)) to print microsecond duration (CL 105030046) -unsafe: document the existing situation that unsafe programs are not go1-guaranteed (CL 162060043) go.sys subrepo created: http://golang.org/s/go1.4-syscall

  • From 8a9c2c55bd0ccbadcf49126482110bee92fb5826 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 15:34:50 -0400 Subject: [PATCH 19/33] os: fix build TBR=crawshaw CC=golang-codereviews https://golang.org/cl/162390043 --- src/os/file_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/file_unix.go b/src/os/file_unix.go index 4e413fbe84..f59d563e69 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -242,7 +242,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { - return fixCount(syscall.Seek(f.fd, offset, whence)) + return syscall.Seek(f.fd, offset, whence) } // Truncate changes the size of the named file. From 202bf8d94dfedfca3a404f5fe9dd19f19f760372 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 15:51:06 -0400 Subject: [PATCH 20/33] doc/asm: explain coordination with garbage collector Also a few other minor changes. Fixes #8712. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/164150043 --- doc/asm.html | 131 ++++++++++++++++++++++++++++++++++------- src/runtime/funcdata.h | 3 + 2 files changed, 114 insertions(+), 20 deletions(-) diff --git a/doc/asm.html b/doc/asm.html index 943347216e..771c493cc2 100644 --- a/doc/asm.html +++ b/doc/asm.html @@ -117,6 +117,9 @@ All user-defined symbols other than jump labels are written as offsets to these

    The SB pseudo-register can be thought of as the origin of memory, so the symbol foo(SB) is the name foo as an address in memory. +This form is used to name global functions and data. +Adding <> to the name, as in foo<>(SB), makes the name +visible only in the current source file, like a top-level static declaration in a C file.

    @@ -128,8 +131,11 @@ Thus 0(FP) is the first argument to the function, When referring to a function argument this way, it is conventional to place the name at the beginning, as in first_arg+0(FP) and second_arg+8(FP). Some of the assemblers enforce this convention, rejecting plain 0(FP) and 8(FP). -For assembly functions with Go prototypes, go vet will check that the argument names +For assembly functions with Go prototypes, go vet will check that the argument names and offsets match. +On 32-bit systems, the low and high 32 bits of a 64-bit value are distinguished by adding +a _lo or _hi suffix to the name, as in arg_lo+0(FP) or arg_hi+4(FP). +If a Go prototype does not name its result, the expected assembly name is ret.

    @@ -206,6 +212,8 @@ The frame size $24-8 states that the function has a 24-byte frame and is called with 8 bytes of argument, which live on the caller's frame. If NOSPLIT is not specified for the TEXT, the argument size must be provided. +For assembly functions with Go prototypes, go vet will check that the +argument size is correct.

    @@ -216,19 +224,20 @@ simple name profileloop.

    -For DATA directives, the symbol is followed by a slash and the number -of bytes the memory associated with the symbol occupies. -The arguments are optional flags and the data itself. -For instance, -

    +Global data symbols are defined by a sequence of initializing +DATA directives followed by a GLOBL directive. +Each DATA directive initializes a section of the +corresponding memory. +The memory not explicitly initialized is zeroed. +The general form of the DATA directive is
    -DATA  runtime·isplan9(SB)/4, $1
    +DATA	symbol+offset(SB)/width, value
     

    -declares the local symbol runtime·isplan9 of size 4 and value 1. -Again the symbol has the middle dot and is offset from SB. +which initializes the symbol memory at the given offset and width with the given value. +The DATA directives for a given symbol must be written with increasing offsets.

    @@ -237,15 +246,26 @@ The arguments are optional flags and the size of the data being declared as a gl which will have initial value all zeros unless a DATA directive has initialized it. The GLOBL directive must follow any corresponding DATA directives. -This example +

    + +

    +For example,

    -GLOBL runtime·tlsoffset(SB),$4
    +DATA divtab<>+0x00(SB)/4, $0xf4f8fcff
    +DATA divtab<>+0x04(SB)/4, $0xe6eaedf0
    +...
    +DATA divtab<>+0x3c(SB)/4, $0x81828384
    +GLOBL divtab<>(SB), RODATA, $64
    +
    +GLOBL runtime·tlsoffset(SB), NOPTR, $4
     

    -declares runtime·tlsoffset to have size 4. +declares and initializes divtab<>, a read-only 64-byte table of 4-byte integer values, +and declares runtime·tlsoffset, a 4-byte, implicitly zeroed variable that +contains no pointers.

    @@ -299,6 +319,80 @@ This is a wrapper function and should not count as disabling recover +

    Runtime Coordination

    + +

    +For garbage collection to run correctly, the runtime must know the +location of pointers in all global data and in most stack frames. +The Go compiler emits this information when compiling Go source files, +but assembly programs must define it explicitly. +

    + +

    +A data symbol marked with the NOPTR flag (see above) +is treated as containing no pointers to runtime-allocated data. +A data symbol with the RODATA flag +is allocated in read-only memory and is therefore treated +as implicitly marked NOPTR. +A data symbol with a total size smaller than a pointer +is also treated as implicitly marked NOPTR. +It is not possible to define a symbol containing pointers in an assembly source file; +such a symbol must be defined in a Go source file instead. +Assembly source can still refer to the symbol by name +even without DATA and GLOBL directives. +A good general rule of thumb is to define all non-RODATA +symbols in Go instead of in assembly. +

    + +

    +Each function also needs annotations giving the location of +live pointers in its arguments, results, and local stack frame. +For an assembly function with no pointer results and +either no local stack frame or no function calls, +the only requirement is to define a Go prototype for the function +in a Go source file in the same package. +For more complex situations, explicit annotation is needed. +These annotations use pseudo-instructions defined in the standard +#include file funcdata.h. +

    + +

    +If a function has no arguments and no results, +the pointer information can be omitted. +This is indicated by an argument size annotation of $n-0 +on the TEXT instruction. +Otherwise, pointer information must be provided by +a Go prototype for the function in a Go source file, +even for assembly functions not called directly from Go. +(The prototype will also let go vet check the argument references.) +At the start of the function, the arguments are assumed +to be initialized but the results are assumed uninitialized. +If the results will hold live pointers during a call instruction, +the function should start by zeroing the results and then +executing the pseudo-instruction GO_RESULTS_INITIALIZED. +This instruction records that the results are now initialized +and should be scanned during stack movement and garbage collection. +It is typically easier to arrange that assembly functions do not +return pointers or do not contain call instructions; +no assembly functions in the standard library use +GO_RESULTS_INITIALIZED. +

    + +

    +If a function has no local stack frame, +the pointer information can be omitted. +This is indicated by a local frame size annotation of $0-n +on the TEXT instruction. +The pointer information can also be omitted if the +function contains no call instructions. +Otherwise, the local stack frame must not contain pointers, +and the assembly must confirm this fact by executing the +pseudo-instruction NO_LOCAL_POINTERS. +Because stack resizing is implemented by moving the stack, +the stack pointer may change during any function call: +even pointers to stack data must not be kept in local variables. +

    +

    Architecture-specific details

    @@ -434,13 +528,10 @@ Here's how the 386 runtime defines the 64-bit atomic load function. // so actually // void atomicload64(uint64 *res, uint64 volatile *addr); TEXT runtime·atomicload64(SB), NOSPLIT, $0-8 - MOVL 4(SP), BX - MOVL 8(SP), AX - // MOVQ (%EAX), %MM0 - BYTE $0x0f; BYTE $0x6f; BYTE $0x00 - // MOVQ %MM0, 0(%EBX) - BYTE $0x0f; BYTE $0x7f; BYTE $0x03 - // EMMS - BYTE $0x0F; BYTE $0x77 + MOVL ptr+0(FP), AX + LEAL ret_lo+4(FP), BX + BYTE $0x0f; BYTE $0x6f; BYTE $0x00 // MOVQ (%EAX), %MM0 + BYTE $0x0f; BYTE $0x7f; BYTE $0x03 // MOVQ %MM0, 0(%EBX) + BYTE $0x0F; BYTE $0x77 // EMMS RET

    diff --git a/src/runtime/funcdata.h b/src/runtime/funcdata.h index a2667a4c02..d6c14fcb41 100644 --- a/src/runtime/funcdata.h +++ b/src/runtime/funcdata.h @@ -28,6 +28,9 @@ // defines the pointer map for the function's arguments. // GO_ARGS should be the first instruction in a function that uses it. // It can be omitted if there are no arguments at all. +// GO_ARGS is inserted implicitly by the linker for any function +// that also has a Go prototype and therefore is usually not necessary +// to write explicitly. #define GO_ARGS FUNCDATA $FUNCDATA_ArgsPointerMaps, go_args_stackmap(SB) // GO_RESULTS_INITIALIZED indicates that the assembly function From 982dcb249d107c1cab844912583c5eca0a07a00f Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 28 Oct 2014 13:49:41 -0700 Subject: [PATCH 21/33] doc/go1.4.html: breaking compiler change, no plugins in misc LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews https://golang.org/cl/166850043 --- doc/go1.4.html | 56 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/doc/go1.4.html b/doc/go1.4.html index 35a0015a79..c5a918adcd 100644 --- a/doc/go1.4.html +++ b/doc/go1.4.html @@ -9,6 +9,7 @@

    The latest Go release, version 1.4, arrives as scheduled six months after 1.3 and contains only one tiny language change, +a possibly breaking change to the compiler, a backwards-compatible simple form of for-range loop. The release focuses primarily on implementation work, improving the garbage collector and preparing the ground for a fully concurrent collector to be rolled out in the @@ -80,6 +81,39 @@ this new form as the may now be nil.

    +

    Method calls on **T

    + +

    +Given these declarations, +

    + +
    +type T int
    +func (T) M() {}
    +var x **T
    +
    + +

    +both gc and gccgo accepted the method call +

    + +
    +x.M()
    +
    + +

    +which is a double dereference of the pointer-to-pointer x. +The Go specification allows a single dereference to be inserted automatically, +but not two, so this call is erroneous according to the language definition. +It has therefore been disallowed in Go 1.4, which is a breaking change, +although very few programs will be affected. +

    + +

    +Updating: Code that depends on the old, erroneous behavior will no longer +compile but is easy to fix by adding an explicit dereference. +

    +

    Changes to the supported operating systems and architectures

    Android

    @@ -408,8 +442,20 @@ have been updated.

    Miscellany

    -TODO misc news -misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043) +The standard repository's top-level misc directory used to contain +Go support for editors and IDEs: plugins, initialization scripts and so on. +Maintaining these was becoming time-consuming +and needed external help because many of the editors listed were not used by +members of the core team. +It also required us to make decisions about which plugin was best for a given +editor, even for editors we do not use. +

    + +

    +The Go community at large is much better suited to managing this information. +In Go 1.4, therefore, this support has been removed from the repository. +Instead, there is a curated, informative list of what's available on +a wiki page.

    Performance

    @@ -445,7 +491,7 @@ Library changes that affect performance are documented below.

    New packages

    -TODO new packages +There are no new packages in this release.

    Major changes to the library

    @@ -456,7 +502,7 @@ TODO major changes
     encoding/gob: remove unsafe (CL 102680045)
    -syscall: now frozen (CL 129820043)
    +syscall: now frozen (CL 129820043); go.sys subrepo created: http://golang.org/s/go1.4-syscall
     

    Minor changes to the library

    @@ -502,6 +548,4 @@ testing: add TestMain support (CL 148770043) text/scanner: add IsIdentRune field of Scanner. (CL 108030044) text/template: allow comparison of signed and unsigned integers (CL 149780043) time: use the micro symbol (µ (U+00B5)) to print microsecond duration (CL 105030046) - -go.sys subrepo created: http://golang.org/s/go1.4-syscall From 5f54f06a359f2973521ff3f42899c12d3a6a7fed Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 28 Oct 2014 22:44:59 +0100 Subject: [PATCH 22/33] os: fix write on Plan 9 In CL 160670043 the write function was changed so a zero-length write is now allowed. This leads the ExampleWriter_Init test to fail. The reason is that Plan 9 preserves message boundaries, while the os library expects systems that don't preserve them. We have to ignore zero-length writes so they will never turn into EOF. This issue was previously discussed in CL 7406046. LGTM=bradfitz R=rsc, bradfitz CC=golang-codereviews https://golang.org/cl/163510043 --- src/os/file_plan9.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go index 22860e20af..5efc2a4f1d 100644 --- a/src/os/file_plan9.go +++ b/src/os/file_plan9.go @@ -259,6 +259,9 @@ func (f *File) pread(b []byte, off int64) (n int, err error) { // Since Plan 9 preserves message boundaries, never allow // a zero-byte write. func (f *File) write(b []byte) (n int, err error) { + if len(b) == 0 { + return 0, nil + } return fixCount(syscall.Write(f.fd, b)) } From 5e568545991cb358a8a004b21e23ac6fa9801124 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 21:52:53 -0400 Subject: [PATCH 23/33] cmd/gc: avoid use of goprintf goprintf is a printf-like print for Go. It is used in the code generated by 'defer print(...)' and 'go print(...)'. Normally print(1, 2, 3) turns into printint(1) printint(2) printint(3) but defer and go need a single function call to give the runtime; they give the runtime something like goprintf("%d%d%d", 1, 2, 3). Variadic functions like goprintf cannot be described in the new type information world, so we have to replace it. Replace with a custom function, so that defer print(1, 2, 3) turns into defer func(a1, a2, a3 int) { print(a1, a2, a3) }(1, 2, 3) (and then the print becomes three different printints as usual). Fixes #8614. LGTM=austin R=austin CC=golang-codereviews, r https://golang.org/cl/159700043 --- src/cmd/gc/builtin.c | 1 - src/cmd/gc/runtime.go | 1 - src/cmd/gc/walk.c | 228 +++++++++++++++++++++--------------------- src/runtime/print1.go | 27 ++--- 4 files changed, 118 insertions(+), 139 deletions(-) diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c index 5fbb4f0cf3..fbca4ee5f6 100644 --- a/src/cmd/gc/builtin.c +++ b/src/cmd/gc/builtin.c @@ -24,7 +24,6 @@ char *runtimeimport = "func @\"\".printslice (? any)\n" "func @\"\".printnl ()\n" "func @\"\".printsp ()\n" - "func @\"\".goprintf ()\n" "func @\"\".concatstring2 (? string, ? string) (? string)\n" "func @\"\".concatstring3 (? string, ? string, ? string) (? string)\n" "func @\"\".concatstring4 (? string, ? string, ? string, ? string) (? string)\n" diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index 86afe67f17..0fb15c2651 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -36,7 +36,6 @@ func printeface(any) func printslice(any) func printnl() func printsp() -func goprintf() func concatstring2(string, string) string func concatstring3(string, string, string) string diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index b761662d14..e5f2217970 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -7,7 +7,7 @@ #include "go.h" #include "../ld/textflag.h" -static Node* walkprint(Node*, NodeList**, int); +static Node* walkprint(Node*, NodeList**); static Node* writebarrierfn(char*, Type*, Type*); static Node* applywritebarrier(Node*, NodeList**); static Node* mapfn(char*, Type*); @@ -32,6 +32,7 @@ static void walkmul(Node**, NodeList**); static void walkdiv(Node**, NodeList**); static int bounded(Node*, int64); static Mpint mpzero; +static void walkprintfunc(Node**, NodeList**); void walk(Node *fn) @@ -226,8 +227,7 @@ walkstmt(Node **np) switch(n->left->op) { case OPRINT: case OPRINTN: - walkexprlist(n->left->list, &n->ninit); - n->left = walkprint(n->left, &n->ninit, 1); + walkprintfunc(&n->left, &n->ninit); break; case OCOPY: n->left = copyany(n->left, &n->ninit, 1); @@ -260,8 +260,7 @@ walkstmt(Node **np) switch(n->left->op) { case OPRINT: case OPRINTN: - walkexprlist(n->left->list, &n->ninit); - n->left = walkprint(n->left, &n->ninit, 1); + walkprintfunc(&n->left, &n->ninit); break; case OCOPY: n->left = copyany(n->left, &n->ninit, 1); @@ -543,7 +542,7 @@ walkexpr(Node **np, NodeList **init) case OPRINT: case OPRINTN: walkexprlist(n->list, init); - n = walkprint(n, init, 0); + n = walkprint(n, init); goto ret; case OPANIC: @@ -1757,7 +1756,7 @@ ret: // generate code for print static Node* -walkprint(Node *nn, NodeList **init, int defer) +walkprint(Node *nn, NodeList **init) { Node *r; Node *n; @@ -1766,7 +1765,6 @@ walkprint(Node *nn, NodeList **init, int defer) Type *t; int notfirst, et, op; NodeList *calls, *intypes, *args; - Fmt fmt; on = nil; op = nn->op; @@ -1776,20 +1774,9 @@ walkprint(Node *nn, NodeList **init, int defer) intypes = nil; args = nil; - memset(&fmt, 0, sizeof fmt); - if(defer) { - // defer print turns into defer printf with format string - fmtstrinit(&fmt); - intypes = list(intypes, nod(ODCLFIELD, N, typenod(types[TSTRING]))); - args = list1(nod(OXXX, N, N)); - } - for(l=all; l; l=l->next) { if(notfirst) { - if(defer) - fmtprint(&fmt, " "); - else - calls = list(calls, mkcall("printsp", T, init)); + calls = list(calls, mkcall("printsp", T, init)); } notfirst = op == OPRINTN; @@ -1817,122 +1804,63 @@ walkprint(Node *nn, NodeList **init, int defer) t = n->type; et = n->type->etype; if(isinter(n->type)) { - if(defer) { - if(isnilinter(n->type)) - fmtprint(&fmt, "%%e"); - else - fmtprint(&fmt, "%%i"); - } else { - if(isnilinter(n->type)) - on = syslook("printeface", 1); - else - on = syslook("printiface", 1); - argtype(on, n->type); // any-1 - } + if(isnilinter(n->type)) + on = syslook("printeface", 1); + else + on = syslook("printiface", 1); + argtype(on, n->type); // any-1 } else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) { - if(defer) { - fmtprint(&fmt, "%%p"); - } else { - on = syslook("printpointer", 1); - argtype(on, n->type); // any-1 - } + on = syslook("printpointer", 1); + argtype(on, n->type); // any-1 } else if(isslice(n->type)) { - if(defer) { - fmtprint(&fmt, "%%a"); - } else { - on = syslook("printslice", 1); - argtype(on, n->type); // any-1 - } + on = syslook("printslice", 1); + argtype(on, n->type); // any-1 } else if(isint[et]) { - if(defer) { - if(et == TUINT64) - fmtprint(&fmt, "%%U"); - else { - fmtprint(&fmt, "%%D"); - t = types[TINT64]; - } - } else { - if(et == TUINT64) { - if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0) - on = syslook("printhex", 0); - else - on = syslook("printuint", 0); - } else - on = syslook("printint", 0); - } + if(et == TUINT64) { + if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0) + on = syslook("printhex", 0); + else + on = syslook("printuint", 0); + } else + on = syslook("printint", 0); } else if(isfloat[et]) { - if(defer) { - fmtprint(&fmt, "%%f"); - t = types[TFLOAT64]; - } else - on = syslook("printfloat", 0); + on = syslook("printfloat", 0); } else if(iscomplex[et]) { - if(defer) { - fmtprint(&fmt, "%%C"); - t = types[TCOMPLEX128]; - } else - on = syslook("printcomplex", 0); + on = syslook("printcomplex", 0); } else if(et == TBOOL) { - if(defer) - fmtprint(&fmt, "%%t"); - else - on = syslook("printbool", 0); + on = syslook("printbool", 0); } else if(et == TSTRING) { - if(defer) - fmtprint(&fmt, "%%S"); - else - on = syslook("printstring", 0); + on = syslook("printstring", 0); } else { badtype(OPRINT, n->type, T); continue; } - if(!defer) { - t = *getinarg(on->type); - if(t != nil) - t = t->type; - if(t != nil) - t = t->type; - } + t = *getinarg(on->type); + if(t != nil) + t = t->type; + if(t != nil) + t = t->type; if(!eqtype(t, n->type)) { n = nod(OCONV, n, N); n->type = t; } - if(defer) { - intypes = list(intypes, nod(ODCLFIELD, N, typenod(t))); - args = list(args, n); - } else { - r = nod(OCALL, on, N); - r->list = list1(n); - calls = list(calls, r); - } - } - - if(defer) { - if(op == OPRINTN) - fmtprint(&fmt, "\n"); - on = syslook("goprintf", 1); - on->type = functype(nil, intypes, nil); - args->n = nod(OLITERAL, N, N); - args->n->val.ctype = CTSTR; - args->n->val.u.sval = strlit(fmtstrflush(&fmt)); r = nod(OCALL, on, N); - r->list = args; - typecheck(&r, Etop); - walkexpr(&r, init); - } else { - if(op == OPRINTN) - calls = list(calls, mkcall("printnl", T, nil)); - typechecklist(calls, Etop); - walkexprlist(calls, init); - - r = nod(OEMPTY, N, N); - typecheck(&r, Etop); - walkexpr(&r, init); - r->ninit = calls; + r->list = list1(n); + calls = list(calls, r); } + + if(op == OPRINTN) + calls = list(calls, mkcall("printnl", T, nil)); + typechecklist(calls, Etop); + walkexprlist(calls, init); + + r = nod(OEMPTY, N, N); + typecheck(&r, Etop); + walkexpr(&r, init); + r->ninit = calls; return r; } @@ -3934,3 +3862,71 @@ candiscard(Node *n) return 1; } + +// rewrite +// print(x, y, z) +// into +// func(a1, a2, a3) { +// print(a1, a2, a3) +// }(x, y, z) +// and same for println. +static void +walkprintfunc(Node **np, NodeList **init) +{ + Node *n; + Node *a, *fn, *t, *oldfn; + NodeList *l, *printargs; + int num; + char buf[100]; + static int prgen; + + n = *np; + + if(n->ninit != nil) { + walkstmtlist(n->ninit); + *init = concat(*init, n->ninit); + n->ninit = nil; + } + + t = nod(OTFUNC, N, N); + num = 0; + printargs = nil; + for(l=n->list; l != nil; l=l->next) { + snprint(buf, sizeof buf, "a%d", num++); + a = nod(ODCLFIELD, newname(lookup(buf)), typenod(l->n->type)); + t->list = list(t->list, a); + printargs = list(printargs, a->left); + } + + fn = nod(ODCLFUNC, N, N); + snprint(buf, sizeof buf, "print·%d", ++prgen); + fn->nname = newname(lookup(buf)); + fn->nname->defn = fn; + fn->nname->ntype = t; + declare(fn->nname, PFUNC); + + oldfn = curfn; + curfn = nil; + funchdr(fn); + + a = nod(n->op, N, N); + a->list = printargs; + typecheck(&a, Etop); + walkstmt(&a); + + fn->nbody = list1(a); + + funcbody(fn); + + typecheck(&fn, Etop); + typechecklist(fn->nbody, Etop); + xtop = list(xtop, fn); + curfn = oldfn; + + a = nod(OCALL, N, N); + a->left = fn->nname; + a->list = n->list; + typecheck(&a, Etop); + walkexpr(&a, init); + *np = a; +} diff --git a/src/runtime/print1.go b/src/runtime/print1.go index 0fa1fb63c4..8f8268873b 100644 --- a/src/runtime/print1.go +++ b/src/runtime/print1.go @@ -19,32 +19,17 @@ func bytes(s string) (ret []byte) { return } -// goprintf is the function call that is actually deferred when you write -// defer print(...) -// It is otherwise unused. In particular it is not used for ordinary prints. -// Right now a dynamically allocated string that is being passed as an -// argument is invisible to the garbage collector and might be collected -// if that argument list is the only reference. For now we ignore that possibility. -// To fix, we should change to defer a call to vprintf with a pointer to -// an argument list on the stack, stored in an appropriately typed -// struct. golang.org/issue/8614. -//go:nosplit -func goprintf(s string) { - vprintf(s, add(unsafe.Pointer(&s), unsafe.Sizeof(s))) -} - -// printf is only called from C code. It has the same problem as goprintf -// with strings possibly being collected from underneath. -// However, the runtime never prints dynamically allocated -// Go strings using printf. The strings it prints come from the symbol -// and type tables. +// printf is only called from C code. It has no type information for the args, +// but C stacks are ignored by the garbage collector anyway, so having +// type information would not add anything. //go:nosplit func printf(s *byte) { vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s))) } -// sprintf is only called from C code. -// It has the same problem as goprintf. +// sprintf is only called from C code. It has no type information for the args, +// but C stacks are ignored by the garbage collector anyway, so having +// type information would not add anything. //go:nosplit func snprintf(dst *byte, n int32, s *byte) { buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:n:n] From c4efaac15daac5e15092532dcc7ca9c30a0e0fbc Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 21:53:09 -0400 Subject: [PATCH 24/33] runtime: fix unrecovered panic on external thread Fixes #8588. LGTM=austin R=austin CC=golang-codereviews, khr https://golang.org/cl/159700044 --- src/runtime/asm_386.s | 14 ++++++++++ src/runtime/asm_amd64.s | 14 ++++++++++ src/runtime/asm_arm.s | 15 +++++++++++ src/runtime/crash_cgo_test.go | 49 +++++++++++++++++++++++++++++++++++ src/runtime/crash_test.go | 17 ++++++++++-- 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index 20d3c47c94..0d46a9eff7 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -732,6 +732,20 @@ needm: MOVL g(CX), BP MOVL g_m(BP), BP + // Set m->sched.sp = SP, so that if a panic happens + // during the function we are about to execute, it will + // have a valid SP to run on the g0 stack. + // The next few lines (after the havem label) + // will save this SP onto the stack and then write + // the same SP back to m->sched.sp. That seems redundant, + // but if an unrecovered panic happens, unwindm will + // restore the g->sched.sp from the stack location + // and then onM will try to use it. If we don't set it here, + // that restored SP will be uninitialized (typically 0) and + // will not be usable. + MOVL m_g0(BP), SI + MOVL SP, (g_sched+gobuf_sp)(SI) + havem: // Now there's a valid m, and we're running on its m->g0. // Save current m->g0->sched.sp on stack and then set it to SP. diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s index 709834180e..a9b082beb8 100644 --- a/src/runtime/asm_amd64.s +++ b/src/runtime/asm_amd64.s @@ -717,6 +717,20 @@ needm: get_tls(CX) MOVQ g(CX), BP MOVQ g_m(BP), BP + + // Set m->sched.sp = SP, so that if a panic happens + // during the function we are about to execute, it will + // have a valid SP to run on the g0 stack. + // The next few lines (after the havem label) + // will save this SP onto the stack and then write + // the same SP back to m->sched.sp. That seems redundant, + // but if an unrecovered panic happens, unwindm will + // restore the g->sched.sp from the stack location + // and then onM will try to use it. If we don't set it here, + // that restored SP will be uninitialized (typically 0) and + // will not be usable. + MOVQ m_g0(BP), SI + MOVQ SP, (g_sched+gobuf_sp)(SI) havem: // Now there's a valid m, and we're running on its m->g0. diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s index 621d13187a..e94b4c1ff6 100644 --- a/src/runtime/asm_arm.s +++ b/src/runtime/asm_arm.s @@ -556,6 +556,21 @@ TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-12 MOVW $runtime·needm(SB), R0 BL (R0) + // Set m->sched.sp = SP, so that if a panic happens + // during the function we are about to execute, it will + // have a valid SP to run on the g0 stack. + // The next few lines (after the havem label) + // will save this SP onto the stack and then write + // the same SP back to m->sched.sp. That seems redundant, + // but if an unrecovered panic happens, unwindm will + // restore the g->sched.sp from the stack location + // and then onM will try to use it. If we don't set it here, + // that restored SP will be uninitialized (typically 0) and + // will not be usable. + MOVW g_m(g), R8 + MOVW m_g0(R8), R3 + MOVW R13, (g_sched+gobuf_sp)(R3) + havem: MOVW g_m(g), R8 MOVW R8, savedm-4(SP) diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 4ff0084c22..7877965587 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -8,6 +8,7 @@ package runtime_test import ( "runtime" + "strings" "testing" ) @@ -34,6 +35,14 @@ func TestCgoTraceback(t *testing.T) { } } +func TestCgoExternalThreadPanic(t *testing.T) { + got := executeTest(t, cgoExternalThreadPanicSource, nil, "main.c", cgoExternalThreadPanicC) + want := "panic: BOOM" + if !strings.Contains(got, want) { + t.Fatalf("want failure containing %q. output:\n%s\n", want, got) + } +} + const cgoSignalDeadlockSource = ` package main @@ -117,3 +126,43 @@ func main() { fmt.Printf("OK\n") } ` + +const cgoExternalThreadPanicSource = ` +package main + +// void start(void); +import "C" + +func main() { + C.start() + select {} +} + +//export gopanic +func gopanic() { + panic("BOOM") +} +` + +const cgoExternalThreadPanicC = ` +#include +#include +#include + +void gopanic(void); + +static void* +die(void* x) +{ + gopanic(); + return 0; +} + +void +start(void) +{ + pthread_t t; + if(pthread_create(&t, 0, die, 0) != 0) + printf("pthread_create failed\n"); +} +` diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go index 783b4c48f5..211a0476fd 100644 --- a/src/runtime/crash_test.go +++ b/src/runtime/crash_test.go @@ -31,7 +31,7 @@ func testEnv(cmd *exec.Cmd) *exec.Cmd { return cmd } -func executeTest(t *testing.T, templ string, data interface{}) string { +func executeTest(t *testing.T, templ string, data interface{}, extra ...string) string { switch runtime.GOOS { case "android", "nacl": t.Skipf("skipping on %s", runtime.GOOS) @@ -61,7 +61,20 @@ func executeTest(t *testing.T, templ string, data interface{}) string { t.Fatalf("failed to close file: %v", err) } - got, _ := testEnv(exec.Command("go", "run", src)).CombinedOutput() + for i := 0; i < len(extra); i += 2 { + if err := ioutil.WriteFile(filepath.Join(dir, extra[i]), []byte(extra[i+1]), 0666); err != nil { + t.Fatal(err) + } + } + + cmd := exec.Command("go", "build", "-o", "a.exe") + cmd.Dir = dir + out, err := testEnv(cmd).CombinedOutput() + if err != nil { + t.Fatalf("building source: %v\n%s", err, out) + } + + got, _ := testEnv(exec.Command(filepath.Join(dir, "a.exe"))).CombinedOutput() return string(got) } From 8fcdc70c5ebf9c8d160b85e9402e7db5f4bf0793 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 21:53:31 -0400 Subject: [PATCH 25/33] runtime: add GODEBUG invalidptr setting Fixes #8861. Fixes #8911. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/165780043 --- src/runtime/extern.go | 6 ++++++ src/runtime/mgc0.c | 4 ++-- src/runtime/runtime.c | 4 ++++ src/runtime/runtime.h | 2 ++ src/runtime/stack.c | 4 ++-- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/runtime/extern.go b/src/runtime/extern.go index b8db5d0c4b..1b8052bb56 100644 --- a/src/runtime/extern.go +++ b/src/runtime/extern.go @@ -39,6 +39,12 @@ a comma-separated list of name=val pairs. Supported names are: gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots that it thinks are dead. + invalidptr: defaults to invalidptr=1, causing the garbage collector and stack + copier to crash the program if an invalid pointer value (for example, 1) + is found in a pointer-typed location. Setting invalidptr=0 disables this check. + This should only be used as a temporary workaround to diagnose buggy code. + The real fix is to not store integers in pointer-typed locations. + scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit detailed multiline info every X milliseconds, describing state of the scheduler, processors, threads and goroutines. diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c index cba2beaa74..1b41bf9a79 100644 --- a/src/runtime/mgc0.c +++ b/src/runtime/mgc0.c @@ -330,7 +330,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask) if(obj == nil) continue; if(obj < arena_start || obj >= arena_used) { - if((uintptr)obj < PhysPageSize) { + if((uintptr)obj < PhysPageSize && runtime·invalidptr) { s = nil; goto badobj; } @@ -375,7 +375,7 @@ scanblock(byte *b, uintptr n, byte *ptrmask) else runtime·printf(" span=%p-%p-%p state=%d\n", (uintptr)s->start<limit, (uintptr)(s->start+s->npages)<state); if(ptrmask != nil) - runtime·throw("bad pointer"); + runtime·throw("invalid heap pointer"); // Add to badblock list, which will cause the garbage collection // to keep repeating until it has traced the chain of pointers // leading to obj all the way back to a root. diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index b3503fb909..c823691ec5 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -276,9 +276,13 @@ struct DbgVar int32* value; }; +// Do we report invalid pointers found during stack or heap scans? +int32 runtime·invalidptr = 1; + #pragma dataflag NOPTR /* dbgvar has no heap pointers */ static DbgVar dbgvar[] = { {"allocfreetrace", &runtime·debug.allocfreetrace}, + {"invalidptr", &runtime·invalidptr}, {"efence", &runtime·debug.efence}, {"gctrace", &runtime·debug.gctrace}, {"gcdead", &runtime·debug.gcdead}, diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index a84a32525e..2a60740063 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -657,6 +657,8 @@ enum { byte* runtime·startup_random_data; uint32 runtime·startup_random_data_len; +int32 runtime·invalidptr; + enum { // hashinit wants this many random bytes HashRandomBytes = 32 diff --git a/src/runtime/stack.c b/src/runtime/stack.c index e402691f45..ed8f4f8727 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -401,12 +401,12 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f) break; case BitsPointer: p = scanp[i]; - if(f != nil && (byte*)0 < p && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) { + if(f != nil && (byte*)0 < p && (p < (byte*)PageSize && runtime·invalidptr || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) { // Looks like a junk value in a pointer slot. // Live analysis wrong? g->m->traceback = 2; runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p); - runtime·throw("bad pointer!"); + runtime·throw("invalid stack pointer"); } if(minp <= p && p < maxp) { if(StackDebug >= 3) From ce7c8fe0fd171bb09296c3dd4d8ca419e28ac5d0 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 28 Oct 2014 20:12:17 -0700 Subject: [PATCH 26/33] doc/go1.4.html: GODEBUG and assembler changes LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews https://golang.org/cl/160660046 --- doc/go1.4.html | 65 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/doc/go1.4.html b/doc/go1.4.html index c5a918adcd..7e670c47cb 100644 --- a/doc/go1.4.html +++ b/doc/go1.4.html @@ -157,7 +157,7 @@ for code that does unsafe things.

    We have clarified this situation in the documentation included in the release. -The Go compatibilty guidelines and the +The Go compatibility guidelines and the docs for the unsafe package are now explicit that unsafe code is not guaranteed to remain compatible.

    @@ -223,6 +223,61 @@ so the effect is minimal, but programs that store integers (for example) in interfaces will see more allocations.

    +

    +As of Go 1.3, the runtime crashes if it finds a memory word that should contain +a valid pointer but instead contains an obviously invalid pointer (for example, the value 3). +Programs that store integers in pointer values may run afoul of this check and crash. +In Go 1.4, setting the GODEBUG variable +invalidptr=0 disables +the crash as a workaround, but we cannot guarantee that future releases will be +able to avoid the crash; the correct fix is to rewrite code not to alias integers and pointers. +

    + +

    Assembly

    + +

    +The language accepted by the assemblers cmd/5a, cmd/6a +and cmd/8a has had several changes, +mostly to make it easier to deliver type information to the runtime. +

    + +

    +First, the textflag.h file that defines flags for TEXT directives +has been copied from the linker source directory to a standard location so it can be +included with the simple directive +

    + +
    +#include "textflag.h"
    +
    + +

    +The more important changes are in how assembler source can define the necessary +type information. +For most programs it will suffice to move data +definitions (DATA and GLOBL directives) +out of assembly into Go files +and to write a Go declaration for each assembly function. +The assembly document describes what to do. +

    + +

    +Updating: +Assembly files that include textflag.h from its old +location will still work, but should be updated. +For the type information, most assembly routines will need no change, +but all should be examined. +Assembly source files that define data, +functions with non-empty stack frames, or functions that return pointers +need particular attention. +A description of the necessary (but simple) changes +is in the assembly document. +

    + +

    +More information about these changes is in the assembly document. +

    +

    Status of gccgo

    @@ -410,13 +465,6 @@ rebuild the standard library and commands, to avoid overwriting the installation -

    Changes to cgo

    - -

    -TODO cgo news -

    - -

    Changes to godoc

    TODO godoc news @@ -522,7 +570,6 @@ See the relevant package documentation for more information about each change. cmd/6l, liblink: use pc-relative addressing for all memory references, so that linking Go binaries at high addresses works (CL 125140043). This cuts the maximum size of a Go binary's text+data+bss from 4GB to 2GB. -asm: make textflag.h available outside of cmd/ld (CL 128050043) bufio: handling of empty tokens at EOF changed, may require scanner change (CL 145390043) compress/flate, compress/gzip, compress/zlib: Reset support (https://codereview.appspot.com/97140043) crypto/tls: add support for ALPN (RFC 7301) (CL 108710046) From c88ba199e2cf24b6dff3d069b50d3bccda4c1552 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 28 Oct 2014 20:19:03 -0700 Subject: [PATCH 27/33] fmt: fix documentation for %g and %G It now echoes what strconv.FormatFloat says. Fixes #9012. LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews https://golang.org/cl/169730043 --- src/fmt/doc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fmt/doc.go b/src/fmt/doc.go index 304b9e9581..28387f5d4b 100644 --- a/src/fmt/doc.go +++ b/src/fmt/doc.go @@ -38,8 +38,8 @@ %E scientific notation, e.g. -1234.456E+78 %f decimal point but no exponent, e.g. 123.456 %F synonym for %f - %g whichever of %e or %f produces more compact output - %G whichever of %E or %f produces more compact output + %g %e for large exponents, %f otherwise + %G %E for large exponents, %G otherwise String and slice of bytes: %s the uninterpreted bytes of the string or slice %q a double-quoted string safely escaped with Go syntax From 6b54cc93d015e4cab1b12c8c78edf1d4a0a7cd0e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 23:22:46 -0400 Subject: [PATCH 28/33] cmd/gc: fix internal compiler error in struct compare Fixes #9006. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/167800043 --- src/cmd/gc/walk.c | 17 ++++++++++++----- test/fixedbugs/issue9006.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/fixedbugs/issue9006.go diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index e5f2217970..2986f4b542 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -3157,7 +3157,7 @@ countfield(Type *t) static void walkcompare(Node **np, NodeList **init) { - Node *n, *l, *r, *call, *a, *li, *ri, *expr; + Node *n, *l, *r, *call, *a, *li, *ri, *expr, *cmpl, *cmpr; int andor, i; Type *t, *t1; @@ -3177,18 +3177,25 @@ walkcompare(Node **np, NodeList **init) break; } - if(!islvalue(n->left) || !islvalue(n->right)) { - fatal("arguments of comparison must be lvalues"); + cmpl = n->left; + while(cmpl != N && cmpl->op == OCONVNOP) + cmpl = cmpl->left; + cmpr = n->right; + while(cmpr != N && cmpr->op == OCONVNOP) + cmpr = cmpr->left; + + if(!islvalue(cmpl) || !islvalue(cmpr)) { + fatal("arguments of comparison must be lvalues - %N %N", cmpl, cmpr); } l = temp(ptrto(t)); - a = nod(OAS, l, nod(OADDR, n->left, N)); + a = nod(OAS, l, nod(OADDR, cmpl, N)); a->right->etype = 1; // addr does not escape typecheck(&a, Etop); *init = list(*init, a); r = temp(ptrto(t)); - a = nod(OAS, r, nod(OADDR, n->right, N)); + a = nod(OAS, r, nod(OADDR, cmpr, N)); a->right->etype = 1; // addr does not escape typecheck(&a, Etop); *init = list(*init, a); diff --git a/test/fixedbugs/issue9006.go b/test/fixedbugs/issue9006.go new file mode 100644 index 0000000000..c559f58f14 --- /dev/null +++ b/test/fixedbugs/issue9006.go @@ -0,0 +1,37 @@ +// run + +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +type T1 struct { + X int +} + +func NewT1(x int) T1 { return T1{x} } + +type T2 int + +func NewT2(x int) T2 { return T2(x) } + +func main() { + switch (T1{}) { + case NewT1(1): + panic("bad1") + case NewT1(0): + // ok + default: + panic("bad2") + } + + switch T2(0) { + case NewT2(2): + panic("bad3") + case NewT2(0): + // ok + default: + panic("bad4") + } +} From 324b293878613574a1c0ab8d87f238ad15a67387 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 28 Oct 2014 23:25:55 -0400 Subject: [PATCH 29/33] cmd/objdump: disassemble local text symbols Fixes #8803. LGTM=rsc R=rsc CC=golang-codereviews https://golang.org/cl/169720043 --- src/cmd/objdump/main.go | 2 +- src/cmd/objdump/objdump_test.go | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/cmd/objdump/main.go b/src/cmd/objdump/main.go index aafc501110..0f66f20a40 100644 --- a/src/cmd/objdump/main.go +++ b/src/cmd/objdump/main.go @@ -159,7 +159,7 @@ func dump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, goarch string, printed := false for _, sym := range syms { - if sym.Code != 'T' || sym.Size == 0 || sym.Name == "_text" || sym.Name == "text" || sym.Addr < textStart || symRE != nil && !symRE.MatchString(sym.Name) { + if (sym.Code != 'T' && sym.Code != 't') || sym.Size == 0 || sym.Name == "_text" || sym.Name == "text" || sym.Addr < textStart || symRE != nil && !symRE.MatchString(sym.Name) { continue } if sym.Addr >= textStart+uint64(len(textData)) || sym.Addr+uint64(sym.Size) > textStart+uint64(len(textData)) { diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go index 5410856262..a9eeea1e06 100644 --- a/src/cmd/objdump/objdump_test.go +++ b/src/cmd/objdump/objdump_test.go @@ -157,12 +157,15 @@ var armNeed = []string{ // binary for the current system (only) and test that objdump // can handle that one. -func TestDisasm(t *testing.T) { +func testDisasm(t *testing.T, flags ...string) { tmp, exe := buildObjdump(t) defer os.RemoveAll(tmp) hello := filepath.Join(tmp, "hello.exe") - out, err := exec.Command("go", "build", "-o", hello, "testdata/fmthello.go").CombinedOutput() + args := []string{"build", "-o", hello} + args = append(args, flags...) + args = append(args, "testdata/fmthello.go") + out, err := exec.Command("go", args...).CombinedOutput() if err != nil { t.Fatalf("go build fmthello.go: %v\n%s", err, out) } @@ -194,3 +197,15 @@ func TestDisasm(t *testing.T) { t.Logf("full disassembly:\n%s", text) } } + +func TestDisasm(t *testing.T) { + testDisasm(t) +} + +func TestDisasmExtld(t *testing.T) { + switch runtime.GOOS { + case "windows": + t.Skipf("skipping on %s", runtime.GOOS) + } + testDisasm(t, "-ldflags=-linkmode=external") +} From 260028fc0e55e47b66d9c21d7a703bec0066fd52 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 23:45:01 -0400 Subject: [PATCH 30/33] cmd/gc: fix build - remove unused variables in walkprint TBR=austin CC=golang-codereviews https://golang.org/cl/162420043 --- src/cmd/gc/walk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 2986f4b542..ff9b362083 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -1764,15 +1764,13 @@ walkprint(Node *nn, NodeList **init) Node *on; Type *t; int notfirst, et, op; - NodeList *calls, *intypes, *args; + NodeList *calls; on = nil; op = nn->op; all = nn->list; calls = nil; notfirst = 0; - intypes = nil; - args = nil; for(l=all; l; l=l->next) { if(notfirst) { From 3ce6a4fb971491b58ec8157496a1f56348cc62c0 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 29 Oct 2014 00:02:29 -0400 Subject: [PATCH 31/33] runtime: fix windows build TBR=austin CC=golang-codereviews https://golang.org/cl/167820043 --- src/runtime/crash_cgo_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 7877965587..5958ad8914 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -36,6 +36,9 @@ func TestCgoTraceback(t *testing.T) { } func TestCgoExternalThreadPanic(t *testing.T) { + if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { + t.Skipf("no pthreads on %s", runtime.GOOS) + } got := executeTest(t, cgoExternalThreadPanicSource, nil, "main.c", cgoExternalThreadPanicC) want := "panic: BOOM" if !strings.Contains(got, want) { From 08b7805e458b4e205005d18d7e75dc73c27a3442 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 29 Oct 2014 00:03:17 -0400 Subject: [PATCH 32/33] cmd/objdump: skip extld test on plan9 TBR=iant CC=golang-codereviews https://golang.org/cl/164180043 --- src/cmd/objdump/objdump_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go index a9eeea1e06..0a2d2565a7 100644 --- a/src/cmd/objdump/objdump_test.go +++ b/src/cmd/objdump/objdump_test.go @@ -204,7 +204,7 @@ func TestDisasm(t *testing.T) { func TestDisasmExtld(t *testing.T) { switch runtime.GOOS { - case "windows": + case "plan9", "windows": t.Skipf("skipping on %s", runtime.GOOS) } testDisasm(t, "-ldflags=-linkmode=external") From 3bbc8638d5dd2564b3c60a603c094c0e570bd301 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Wed, 29 Oct 2014 06:53:05 -0700 Subject: [PATCH 33/33] fmt: fix one-letter typo in doc.go Stupid mistake in previous CL. TBR=rsc R=rsc CC=golang-codereviews https://golang.org/cl/166880043 --- src/fmt/doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmt/doc.go b/src/fmt/doc.go index 28387f5d4b..ee54463e27 100644 --- a/src/fmt/doc.go +++ b/src/fmt/doc.go @@ -39,7 +39,7 @@ %f decimal point but no exponent, e.g. 123.456 %F synonym for %f %g %e for large exponents, %f otherwise - %G %E for large exponents, %G otherwise + %G %E for large exponents, %F otherwise String and slice of bytes: %s the uninterpreted bytes of the string or slice %q a double-quoted string safely escaped with Go syntax