diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-10-08 23:50:59 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-10-09 00:28:12 +1000 |
commit | 24a0777219d647ec310a0b6da305f619f69950cd (patch) | |
tree | 1a1e02b629a6f15dceeaf8186ea837831270d032 /src/reflect | |
parent | 8d25e84c9123fe9784ec9844b5184aa1b697b429 (diff) | |
download | scala-24a0777219d647ec310a0b6da305f619f69950cd.tar.gz scala-24a0777219d647ec310a0b6da305f619f69950cd.tar.bz2 scala-24a0777219d647ec310a0b6da305f619f69950cd.zip |
SI-8871 Fix specialization under REPL / FSC
The transformation of applications to specialized methods
relies on the owner of said method having had the specialization
info transform run which stashes a bunch of related data into
per-run caches such as `SpecializeTypes#{typeEnv}`.
Recently, we found that per-run caches didn't quite live up
to there name, and in fact weren't being cleaned up before
a new run. This was remedied in 00e11ff.
However, no good deed goes unpunished, and this led to a
regression in specialization in the REPL and FSC.
This commit makes two changes:
- change the specialization info tranformer to no longer
directly enter specialized methods into the `info` of whatever
the current phase happens to be. This stops them showing up
`enteringTyper` of the following run.
- change `adaptInfos` to simply discard all but the oldest
entry in the type history when bringing a symbol from one
run into the next. This generalizes the approach taken to
fix SI-7801. The specialization info transformer will now
execute in each run, and repopulate `typeEnv` and friends.
I see that we have a seemingly related bandaid for this sort
of problem since 08505bd4ec. In a followup, I'll try to revert
that.
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index b0c23ef45d..3296b2322f 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -173,7 +173,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => with HasFlags with Annotatable[Symbol] with Attachable { - // makes sure that all symbols that runtime reflection deals with are synchronized private def isSynchronized = this.isInstanceOf[scala.reflect.runtime.SynchronizedSymbols#SynchronizedSymbol] private def isAprioriThreadsafe = isThreadsafe(AllOps) @@ -1592,13 +1591,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => assert(isCompilerUniverse) if (infos == null || runId(infos.validFrom) == currentRunId) { infos - } else if (isPackageClass) { - // SI-7801 early phase package scopes are mutated in new runs (Namers#enterPackage), so we have to - // discard transformed infos, rather than just marking them as from this run. - val oldest = infos.oldest - oldest.validFrom = validTo - this.infos = oldest - oldest + } else if (infos ne infos.oldest) { + // SI-8871 Discard all but the first element of type history. Specialization only works in the resident + // compiler / REPL if re-run its info transformer in this run to correctly populate its + // per-run caches, e.g. typeEnv + adaptInfos(infos.oldest) } else { val prev1 = adaptInfos(infos.prev) if (prev1 ne infos.prev) prev1 |