• David Chase's avatar
    cmd/compile: better modeling of escape across loop levels · e779bfa5
    David Chase authored
    Brief background on "why heap allocate".  Things can be
    forced to the heap for the following reasons:
    
    1) address published, hence lifetime unknown.
    2) size unknown/too large, cannot be stack allocated
    3) multiplicity unknown/too large, cannot be stack allocated
    4) reachable from heap (not necessarily published)
    
    The bug here is a case of failing to enforce 4) when an
    object Y was reachable from a heap allocation X forced
    because of 3).  It was found in the case of a closure
    allocated within a loop (X) and assigned to a variable
    outside the loop (multiplicity unknown) where the closure
    also captured a map (Y) declared outside the loop (reachable
    from heap). Note the variable declared outside the loop (Y)
    is not published, has known size, and known multiplicity
    (one). The only reason for heap allocation is that it was
    reached from a heap allocated item (X), but because that was
    not forced by publication, it has to be tracked by loop
    level, but escape-loop level was not tracked and thus a bug
    results.
    
    The fix is that when a heap allocation is newly discovered,
    use its looplevel as the minimum loop level for downstream
    escape flooding.
    
    Every attempt to generalize this bug to X-in-loop-
    references-Y-outside loop succeeded, so the fix was aimed
    to be general.  Anywhere that loop level forces heap
    allocation, the loop level is tracked.  This is not yet
    tested for all possible X and Y, but it is correctness-
    conservative and because it caused only one trivial
    regression in the escape tests, it is probably also
    performance-conservative.
    
    The new test checks the following:
    1) in the map case, that if fn escapes, so does the map.
    2) in the map case, if fn does not escape, neither does the map.
    3) in the &x case, that if fn escapes, so does &x.
    4) in the &x case, if fn does not escape, neither does &x.
    
    Fixes #13799.
    
    Change-Id: Ie280bef2bb86ec869c7c206789d0b68f080c3fdb
    Reviewed-on: https://go-review.googlesource.com/18234
    Run-TryBot: David Chase <drchase@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
    e779bfa5
Name
Last commit
Last update
..
archive Loading commit data...
bufio Loading commit data...
builtin Loading commit data...
bytes Loading commit data...
cmd Loading commit data...
compress Loading commit data...
container Loading commit data...
crypto Loading commit data...
database/sql Loading commit data...
debug Loading commit data...
encoding Loading commit data...
errors Loading commit data...
expvar Loading commit data...
flag Loading commit data...
fmt Loading commit data...
go Loading commit data...
hash Loading commit data...
html Loading commit data...
image Loading commit data...
index/suffixarray Loading commit data...
internal Loading commit data...
io Loading commit data...
log Loading commit data...
math Loading commit data...
mime Loading commit data...
net Loading commit data...
os Loading commit data...
path Loading commit data...
reflect Loading commit data...
regexp Loading commit data...
runtime Loading commit data...
sort Loading commit data...
strconv Loading commit data...
strings Loading commit data...
sync Loading commit data...
syscall Loading commit data...
testing Loading commit data...
text Loading commit data...
time Loading commit data...
unicode Loading commit data...
unsafe Loading commit data...
vendor/golang.org/x/net/http2/hpack Loading commit data...
Make.dist Loading commit data...
all.bash Loading commit data...
all.bat Loading commit data...
all.rc Loading commit data...
androidtest.bash Loading commit data...
bootstrap.bash Loading commit data...
buildall.bash Loading commit data...
clean.bash Loading commit data...
clean.bat Loading commit data...
clean.rc Loading commit data...
iostest.bash Loading commit data...
make.bash Loading commit data...
make.bat Loading commit data...
make.rc Loading commit data...
nacltest.bash Loading commit data...
race.bash Loading commit data...
race.bat Loading commit data...
run.bash Loading commit data...
run.bat Loading commit data...
run.rc Loading commit data...