https://github.com/JuliaLang/julia
Revision 90a2162282489ef6e872a329fa8483d4a9a3e1ea authored by Keno Fischer on 19 March 2018, 02:57:36 UTC, committed by Keno Fischer on 19 March 2018, 03:16:55 UTC
This is a bit of a tricky one, so let me start at the beginning. In
PR #25506, I pushed my WIP of a new inlining passes. However, one of
the things it temporarily doesn't do is turn call sites to :invoke,
causing significantly more jl_apply_generic calls to be codegened.
On CI for that PR (as well as locally), we non-deterministically see
errors like:
```
LoadError("sysimg.jl", 213, KeyError(LibGit2 [76f85450-5226-5b5a-8eaa-529ad045b433]))
```
Some investigation revealed that what happened here is that a `PkgId`
got placed in a dictionary, but was later failed to be retrieved
because its hash had supposedly changes. Further investigation reveals
that while the hash function used to place the item in the dictionary
was `hash(x::Union{String,SubString{String}}, h::UInt64)` in hashing2.jl,
the hash function being used to retrieve it is `hash(@nospecialize(x), h::UInt64)`
in hashing.jl. The former is loaded later than the latter and should thus invalidate
all specializations of the latter, making them ineligible for selection by
jl_apply_generic. However, looking at the appropriate age ranges showed that
`typeof(hash).name.mt.cache` had entries for both hash functions with overlapping
age ranges (which is obviously incorrect).

Tracking age range updates, it turns out the world age range for the specialization
of `hash(@nospecialize(x), h::UInt64)` was expanded by invalidate_backedges called
upon the definition of a hash function inside `LibGit2`. This seems wrong. I believe
invalidate_backedges should only ever truncate world age ranges rather than expanding
them. This patch simply does that.

The non-determinism of the original issue appears to have to do with which of the
specializations happen to be in the `jl_lookup_generic_` `call_cache` fast-path.

This issue is fairly hard to reproduce because it requires a very specific confluence
of circumstances. Since the range of the captured specialization only gets extended
to before the min_world age of the new definition, it is never visible in the latest
world (e.g. at the REPL). The included test case demonstrates the issue by capturing
the world age with a task. Commenting out the `f(x::Float64)` definition makes
the test pass, because it is that definition that causes the expansion of the original
specialization of `f`.
1 parent 40f64e5
History
Tip revision: 90a2162282489ef6e872a329fa8483d4a9a3e1ea authored by Keno Fischer on 19 March 2018, 02:57:36 UTC
Fix incorrect world age range expansion
Tip revision: 90a2162
File Mode Size
.circleci
.github
base
contrib
deps
doc
etc
src
stdlib
test
ui
.freebsdci.sh -rwxr-xr-x 1.0 KB
.gitattributes -rw-r--r-- 67 bytes
.gitignore -rw-r--r-- 213 bytes
.mailmap -rw-r--r-- 9.5 KB
.travis.yml -rw-r--r-- 6.5 KB
CONTRIBUTING.md -rw-r--r-- 20.4 KB
DISTRIBUTING.md -rw-r--r-- 23.6 KB
HISTORY.md -rw-r--r-- 144.9 KB
LICENSE.md -rw-r--r-- 5.4 KB
Make.inc -rw-r--r-- 35.1 KB
Makefile -rw-r--r-- 25.5 KB
NEWS.md -rw-r--r-- 73.2 KB
README.arm.md -rw-r--r-- 5.7 KB
README.md -rw-r--r-- 29.7 KB
README.windows.md -rw-r--r-- 13.0 KB
VERSION -rw-r--r-- 10 bytes
Windows.inc -rw-r--r-- 1.5 KB
appveyor.yml -rw-r--r-- 2.2 KB

README.md

back to top