remove zerostack compiler experiment; will do at link time instead
««« original CL description
cmd/gc: add GOEXPERIMENT=zerostack to clear stack on function entry
This is expensive but it might be useful in cases where
people are suffering from false positives during garbage
collection and are willing to trade the CPU time for getting
rid of the false positives.
On the other hand it only eliminates false positives caused
by other function calls, not false positives caused by dead
temporaries stored in the current function call.
The 5g/6g/8g changes were pulled out of the history, from
the last time we needed to do this (to work around a goto bug).
The code in go.h, lex.c, pgen.c is new but tiny.
R=ken2
CC=golang-dev
https://golang.org/cl/6938073
»»»
R=ken2
CC=golang-dev
https://golang.org/cl/7002051
A fatal error used to happen when escassign-ing a multiple
function return to a single node. However, the situation
naturally appears when using "go f(g())" or "defer f(g())",
because g() is escassign-ed to sink.
Fixes#4529.
R=golang-dev, lvd, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/6920060
This is expensive but it might be useful in cases where
people are suffering from false positives during garbage
collection and are willing to trade the CPU time for getting
rid of the false positives.
On the other hand it only eliminates false positives caused
by other function calls, not false positives caused by dead
temporaries stored in the current function call.
The 5g/6g/8g changes were pulled out of the history, from
the last time we needed to do this (to work around a goto bug).
The code in go.h, lex.c, pgen.c is new but tiny.
R=ken2
CC=golang-dev
https://golang.org/cl/6938073
The code:
func main() {
v := make([]int64, 10)
i := 1
_ = v[(i*4)/3]
}
crashes compiler with:
Program received signal SIGSEGV, Segmentation fault.
0x000000000043c274 in walkexpr (np=0x7fffffffc9b8, init=0x0) at src/cmd/gc/walk.c:587
587 *init = concat(*init, n->ninit);
(gdb) bt
#0 0x000000000043c274 in walkexpr (np=0x7fffffffc9b8, init=0x0) at src/cmd/gc/walk.c:587
#1 0x0000000000432d15 in copyexpr (n=0x7ffff7f69a48, t=<optimized out>, init=0x0) at src/cmd/gc/subr.c:2020
#2 0x000000000043f281 in walkdiv (init=0x0, np=0x7fffffffca70) at src/cmd/gc/walk.c:2901
#3 walkexpr (np=0x7ffff7f69760, init=0x0) at src/cmd/gc/walk.c:956
#4 0x000000000043d801 in walkexpr (np=0x7ffff7f69bc0, init=0x0) at src/cmd/gc/walk.c:988
#5 0x000000000043cc9b in walkexpr (np=0x7ffff7f69d38, init=0x0) at src/cmd/gc/walk.c:1068
#6 0x000000000043c50b in walkexpr (np=0x7ffff7f69f50, init=0x0) at src/cmd/gc/walk.c:879
#7 0x000000000043c50b in walkexpr (np=0x7ffff7f6a0c8, init=0x0) at src/cmd/gc/walk.c:879
#8 0x0000000000440a53 in walkexprlist (l=0x7ffff7f6a0c8, init=0x0) at src/cmd/gc/walk.c:357
#9 0x000000000043d0bf in walkexpr (np=0x7fffffffd318, init=0x0) at src/cmd/gc/walk.c:566
#10 0x00000000004402bf in vmkcall (fn=<optimized out>, t=0x0, init=0x0, va=0x7fffffffd368) at src/cmd/gc/walk.c:2275
#11 0x000000000044059a in mkcall (name=<optimized out>, t=0x0, init=0x0) at src/cmd/gc/walk.c:2287
#12 0x000000000042862b in callinstr (np=0x7fffffffd4c8, init=0x7fffffffd568, wr=0, skip=<optimized out>) at src/cmd/gc/racewalk.c:478
#13 0x00000000004288b7 in racewalknode (np=0x7ffff7f68108, init=0x7fffffffd568, wr=0, skip=0) at src/cmd/gc/racewalk.c:287
#14 0x0000000000428781 in racewalknode (np=0x7ffff7f65840, init=0x7fffffffd568, wr=0, skip=0) at src/cmd/gc/racewalk.c:302
#15 0x0000000000428abd in racewalklist (l=0x7ffff7f65840, init=0x0) at src/cmd/gc/racewalk.c:97
#16 0x0000000000428d0b in racewalk (fn=0x7ffff7f5f010) at src/cmd/gc/racewalk.c:63
#17 0x0000000000402b9c in compile (fn=0x7ffff7f5f010) at src/cmd/6g/../gc/pgen.c:67
#18 0x0000000000419f86 in funccompile (n=0x7ffff7f5f010, isclosure=0) at src/cmd/gc/dcl.c:1414
#19 0x0000000000424161 in p9main (argc=<optimized out>, argv=<optimized out>) at src/cmd/gc/lex.c:431
#20 0x0000000000401739 in main (argc=<optimized out>, argv=<optimized out>) at src/lib9/main.c:35
The problem is nil init passed to mkcall().
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6940045
The code inside the casee and casep labels can perfectly be merged since
they essentially do the same. The character to be stored where cp points is
just the character contained by the c variable.
R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/6845112
This check for BADWIDTH might happen while in defercheckwidth, making it raise errors for non-erroneous situations.
Fixes#4495.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6927043
Used to say:
issue4251.go:12: inverted slice range
issue4251.go:12: constant -1 overflows uint64
issue4251.go:16: inverted slice range
issue4251.go:16: constant -1 overflows uint64
issue4251.go:20: inverted slice range
issue4251.go:20: constant -1 overflows uint64
With this patch, only gives the "inverted slice range" errors.
R=golang-dev, daniel.morsing
CC=golang-dev
https://golang.org/cl/6871058
The compiler was confused when inlining a T.Method(f()) call
where f returns multiple values: support for this was marked
as TODO.
Variadic calls are not supported but are not inlined either.
Add a test preventively for that case.
Fixes#4167.
R=golang-dev, rsc, lvd
CC=golang-dev
https://golang.org/cl/6871043
W/o this change stack traces do not show from where sync.Once()
or atomic.XXX was called.
This change add funcenter/exit instrumentation to sync/sync.atomic
packages.
R=golang-dev
CC=golang-dev
https://golang.org/cl/6854112
This allows 5g and 8g to benefit from the rewrite as shifts
or magic multiplies. The 64-bit arithmetic is not handled there,
and left in 6g.
Update #2230.
R=golang-dev, dave, mtj, iant, rsc
CC=golang-dev
https://golang.org/cl/6819123
Bools from comparisons can be assigned to all bool types, but this idealness would propagate through logical operators when the result should have been lowered to a non-ideal form.
Fixes#3924.
R=golang-dev, remyoudompheng, r, rsc, mtj
CC=golang-dev
https://golang.org/cl/6855061
Check the return value from malloc - do not assume that we were
allocated memory just because we asked for it.
Update #4415.
R=minux.ma, daniel.morsing, remyoudompheng, rsc
CC=golang-dev
https://golang.org/cl/6782100
In order to add these, we need to be able to find references
to such types that already exist in the binary. To do that, introduce
a new linker section holding a list of the types corresponding to
arrays, chans, maps, and slices.
To offset the storage cost of this list, and to simplify the code,
remove the interface{} header from the representation of a
runtime type. It was used in early versions of the code but was
made obsolete by the kind field: a switch on kind is more efficient
than a type switch.
In the godoc binary, removing the interface{} header cuts two
words from each of about 10,000 types. Adding back the list of pointers
to array, chan, map, and slice types reintroduces one word for
each of about 500 types. On a 64-bit machine, then, this CL *removes*
a net 156 kB of read-only data from the binary.
This CL does not include the needed support for precise garbage
collection. I have created issue 4375 to track that.
This CL also does not set the 'algorithm' - specifically the equality
and copy functions - for a new array correctly, so I have unexported
ArrayOf for now. That is also part of issue 4375.
Fixes#2339.
R=r, remyoudompheng, mirtchovski, iant
CC=golang-dev
https://golang.org/cl/6572043
When exporting a body containing
x, ok := v.(Type)
the definition for Type was not being included, so when the body
was actually used, it would cause an "unknown type" compiler error.
Fixes#4370.
R=ken2
CC=golang-dev
https://golang.org/cl/6827064
The code assumed that the only choices were EscNone, EscScope, and EscHeap,
so that it makes sense to set EscScope only if the current setting is EscNone.
Now that we have the many variants of EscReturn, this logic is false, and it was
causing important EscScopes to be ignored in favor of EscReturn.
Fixes#4360.
R=ken2
CC=golang-dev, lvd
https://golang.org/cl/6816103
Avoids problems with local declarations shadowing other names.
We write a more explicit form than the incoming program, so there
may be additional type annotations. For example:
int := "hello"
j := 2
would normally turn into
var int string = "hello"
var j int = 2
but the int variable shadows the int type in the second line.
This CL marks all local variables with a per-function sequence number,
so that this would instead be:
var int·1 string = "hello"
var j·2 int = 2
Fixes#4326.
R=ken2
CC=golang-dev
https://golang.org/cl/6816100
Current racewalk transformation looks like:
x := <-makeChan().c
\/\/\/\/\/\/\/\/\/
runtime.raceread(&makeChan().c)
x := <-makeChan().c
and so makeChan() is called twice.
With this CL the transformation looks like:
x := <-makeChan().c
\/\/\/\/\/\/\/\/\/
chan *tmp = &(makeChan().c)
raceread(&*tmp)
x := <-(*tmp)
Fixes#4245.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6822075
It is refactoring towards generic walk
+ it handles mode nodes.
Partially fixes 4228 issue.
R=golang-dev, lvd, rsc
CC=golang-dev
https://golang.org/cl/6775098
When the first result of a type assertion is blank, the compiler would still copy out a potentially large non-interface type.
Fixes#1021.
R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/6812079
The test for this is test/index.go, which is not run by
default. That test does not currently pass even after this is
applied, due to issue 4348.
Fixes#4344.
R=golang-dev, daniel.morsing, rsc
CC=golang-dev
https://golang.org/cl/6815085
It happens that blocks are used for function calls in a
quite low-level way so they cannot be instrumented as
usual.
Blocks are also used for inlined functions.
R=golang-dev, rsc, dvyukov
CC=golang-dev
https://golang.org/cl/6821068
Compiling expressions like:
s[s[s[s[s[s[s[s[s[s[s[s[i]]]]]]]]]]]]
make 5g and 6g run out of registers. Such expressions can arise
if a slice is used to represent a permutation and the user wants
to iterate it.
This is due to the usual problem of allocating registers before
going down the expression tree, instead of allocating them in a
postfix way.
The functions cgenr and agenr (that generate a value to a newly
allocated register instead of an existing location), are either
introduced or modified when they already existed to allocate
the new register as late as possible, and sudoaddable is disabled
for OINDEX nodes so that igen/agenr is used instead.
Update #4207.
R=dave, daniel.morsing, rsc
CC=golang-dev
https://golang.org/cl/6733055
This is an experiment in static analysis of Go programs
to understand which struct fields a program might use.
It is not part of the Go language specification, it must
be enabled explicitly when building the toolchain,
and it may be removed at any time.
After building the toolchain with GOEXPERIMENT=fieldtrack,
a specific field can be marked for tracking by including
`go:"track"` in the field tag:
package pkg
type T struct {
F int `go:"track"`
G int // untracked
}
To simplify usage, only named struct types can have
tracked fields, and only exported fields can be tracked.
The implementation works by making each function begin
with a sequence of no-op USEFIELD instructions declaring
which tracked fields are accessed by a specific function.
After the linker's dead code elimination removes unused
functions, the fields referred to by the remaining
USEFIELD instructions are the ones reported as used by
the binary.
The -k option to the linker specifies the fully qualified
symbol name (such as my/pkg.list) of a string variable that
should be initialized with the field tracking information
for the program. The field tracking string is a sequence
of lines, each terminated by a \n and describing a single
tracked field referred to by the program. Each line is made
up of one or more tab-separated fields. The first field is
the name of the tracked field, fully qualified, as in
"my/pkg.T.F". Subsequent fields give a shortest path of
reverse references from that field to a global variable or
function, corresponding to one way in which the program
might reach that field.
A common source of false positives in field tracking is
types with large method sets, because a reference to the
type descriptor carries with it references to all methods.
To address this problem, the CL also introduces a comment
annotation
//go:nointerface
that marks an upcoming method declaration as unavailable
for use in satisfying interfaces, both statically and
dynamically. Such a method is also invisible to package
reflect.
Again, all of this is disabled by default. It only turns on
if you have GOEXPERIMENT=fieldtrack set during make.bash.
R=iant, ken
CC=golang-dev
https://golang.org/cl/6749064
1. Prepend racefuncenter() to fn->enter -- fn->enter can contain new() calls,
and we want them to be in the scope of the function.
2. Dump fn->enter and fn->exit.
3. Add TODO that OTYPESW expression can contain interesting memory accesses.
4. Ignore only _ names instead of all names starting with _.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6822048
The idea is to (1) process ninit of all nodes,
and (2) put instrumentation of ninit into the nodes themselves (not the top-level statement ninit).
Fixes#4304.
R=golang-dev, rsc
CC=golang-dev, lvd
https://golang.org/cl/6818049
When local declarations needed unexported types, these could
be missing in the export data.
Fixes build with -gcflags -lll, except for exp/gotype.
R=golang-dev, rsc, lvd
CC=golang-dev
https://golang.org/cl/6813067
This should make the compiler emit errors specific to the bounds checking instead of overflow errors on the underlying types.
Updates #4232.
R=rsc
CC=golang-dev
https://golang.org/cl/6783054
Plan 9 and Go's lib9/fmt disagree on whether %#x includes the 0x prefix
when printing 0, because ANSI C gave bad advice long ago.
Avoiding that case makes binaries compiled on different systems compatible.
R=ken2
CC=akumar, golang-dev
https://golang.org/cl/6814066
- make sure dclcontext == PAUTO only in function bodies
- introduce PDISCARD to discard declarations in bodies of repeated imports
- skip printing initializing OAS'es in export mode, assuming they only occur after ODCL's
- remove ODCL and the initializing OAS from inl.c:ishairy
- fix confused use of ->typecheck in typecheckinl: it's about the ->inl, not about the fn.
- debuging aids: print ntype on ONAMEs too and -Emm instead of -Ell.
fixes#2812
R=rsc
CC=golang-dev
https://golang.org/cl/6800043
includes step 0: synthesize outparams, from 6600044
includes step 1,2: give outparams loopdepth 0 and verify unchanged results
generate esc:$mask tags, but still tie to sink if a param has mask != 0
from 6610054
adds final steps:
- have esccall generate n->escretval, a list of nodes the function results flow to
- use these in esccall and ORETURN/OAS2FUNC/and f(g())
- only tie parameters to sink if tag is absent, otherwise according to mask, tie them to escretval
R=rsc, bradfitz
CC=dave, gobot, golang-dev, iant, rsc
https://golang.org/cl/6741044
includes step 0: synthesize outparams, from 6600044
step 1: give outparams loopdepth 0 and verify unchanged results
step 2: generate esc:$mask tags, but still tie to sink if a param has mask != 0
next step: use in esccall (and ORETURN with implicit OAS2FUNC) to avoid tying to sink
R=rsc
CC=golang-dev
https://golang.org/cl/6610054
in typecheck and walk, conversion from OAS2RECV to OAS2
and to OSELRECV2 duplicated the ->rlist->n to ->right
thereby destroying the strict tree-ness of the AST (up to
ONAMES) of course. Several recursions in esc.c and inl.c
and probably elsewhere assume nodes of the tree aren't duplicated.
rather than defensively code around this, i'd rather assert
these cases away and fix their cause.
(this was tripped in 6741044)
R=rsc
CC=golang-dev
https://golang.org/cl/6750043
Someone new to the language may not know the connection between ints and arrays, which was the only thing that the previous error told you anything about.
Fixes#4256.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6739048
Since this patch changes the way complex literals are written
in export data, there are a few other glitches.
Fixes#4159.
R=golang-dev, rsc
CC=golang-dev, remy
https://golang.org/cl/6674047
The compiler is crashing on the following code:
type TypeID int
func (t *TypeID) encodeType(x int) (tt TypeID, err error) {
switch x {
case 0:
return t.encodeType(x * x)
}
return 0, nil
}
The pass marks "return struct" {tt TypeID, err error} as used,
and this causes internal check failure.
I've added the test to:
https://golang.org/cl/6525052/diff/7020/src/pkg/runtime/race/regression_test.go
R=golang-dev, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/6611049
The protection against segfaults does not completely solve
crashes and breaks test/fixedbugs/bug365.go
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6615058
The nil dereference in the next few lines doesn't seem
to cause a segmentation fault on Unix, but does seem
to halt the Go compiler.
The following is a test case:
>>>
package main
func mine(int b) int {
return b + 2
}
func main() {
mine()
c = mine()
}
<<<
Without this change only the following is caught:
typecheck.go:3: undefined: b
typecheck.go:4: undefined: b
with it, we catch all the errors:
typecheck.go:3: undefined: b
typecheck.go:4: undefined: b
typecheck.go:10: undefined: c
typecheck.go:10: cannot assign to c .
R=rsc, minux.ma
CC=golang-dev
https://golang.org/cl/6542060
This is the first part of a bigger change that adds data race detection feature:
https://golang.org/cl/6456044
This change makes gc compiler instrument memory accesses when supplied with -b flag.
R=rsc, nigeltao, lvd
CC=golang-dev
https://golang.org/cl/6497074
Also mention that ignoring second blank identifier of range is required by the spec in the code.
Fixes#4173.
R=daniel.morsing, remyoudompheng, r
CC=golang-dev
https://golang.org/cl/6594043
Low hanging fruit optimization. Will remove an expensive copy if the range variable is an array.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6564052
Was not handling &x.y[0] and &x.y.z correctly where
y is an array or struct-valued field (not a pointer).
R=ken2
CC=golang-dev
https://golang.org/cl/6551059
This CL makes the compiler understand that the type of
the len or cap of a map, slice, or string is 'int', not 'int32'.
It does not change the meaning of int, but it should make
the eventual change of the meaning of int in 6g a bit smoother.
Update #2188.
R=ken, dave, remyoudompheng
CC=golang-dev
https://golang.org/cl/6542059
During interface compare, the operands will be evaluated twice. The operands might include function calls for conversion, so make them cheap before comparing them.
R=rsc
CC=golang-dev
https://golang.org/cl/6498133
In switches without an expression, the compiler would not convert the implicit true to an interface, causing codegen errors.
Fixes#3980.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6497147
This fixes a problem with ELF tools thinking they know the
format of the symbol table, as we do not use any of the
standard formats for that table.
This change will probably annoy the Plan 9 users, but I
believe there are other incompatibilities already that mean
they have to use a Go-specific nm.
Fixes#3473.
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/6500117
Accomplished by synchronizing the formatting of conversion errors between typecheck.c and subr.c
Fixes#3984.
R=golang-dev, remyoudompheng, rsc
CC=golang-dev
https://golang.org/cl/6500064