| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|\
| |
| | |
More conservative optimization for unnecessary outer ref checks
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The old algorithm omitted necessary outer ref checks in some places.
This new one is more conservative. It only omits outer ref checks when
the expected type and the scrutinee type match up, or when the expected
type is defined in a static location. For this specific purpose the top
level of a method or other code block (which is not a trait or class
definition) is also considered static because it does not have a prefix.
This change comes with a spec update to clarify the prefix rule for type
patterns. The new wording makes it clear that the presence of a prefix
is to be interpreted in a *semantic* way, i.e. the existence of a prefix
determines the necessity for an outer ref check, no matter if the prefix
is actually spelled out *syntactically*. Note that the old outer ref
check implementation did not use the alternative interpretation of
requiring prefixes to be given syntactically. It never created an outer
ref check for a local class `C`, no matter if the pattern was `_: C`
or `_: this.C`, thus violating both interpretations of the spec.
There is now explicit support for unchecked matches (like
`case _: (T @unchecked) =>`) to suppress warnings for unchecked outer
refs. `@unchecked` worked before and was used for this purpose in
`neg/t7721` but never actually existed as a feature. It was a result of
a bug that prevented an outer ref check from being generated in the
first place if *any* annotation was used on an expected type in a type
pattern. This new version will still generate the outer ref check if an
outer ref is available but suppress the warning otherwise. Other
annotations on type patterns are ignored.
New tests are in `neg/outer-ref-checks`. The expected results of tests
`neg/t7171` and `neg/t7171b` have changed because the compiler now
tries to generate additional outer ref checks that were not present
before (which was a bug).
|
|/
|
|
|
| |
WeakHashSet is internal so an exception was made against binary
compatibility to allow the var to be made private.
|
|\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
merge/2.11.x-to-2.12.x-20160225
Conflicts:
scripts/jobs/integrate/bootstrap
src/build/maven/scala-actors-pom.xml
test/files/pos/t3420.flags
Conflicts were trivial to resolve.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The old approach of recursively calling `fullNameAsName`
creates a lot of garbage for intermediate results, in
addition to needless interning of those results into
the name table.
This commit instead creates a string buffer of the
correct capacity and writes the component names
directly into this.
I compared old and new approaches and this shows a 2x
speedup.
```
scala> val th = ichi.bench.Thyme.warmed(verbose = print)
th: ichi.bench.Thyme = ichi.bench.Thyme@1643e817
scala> val w_old = th.Warm(sym.fullNameAsNameOld('.'))
w_old: th.Warm[$r.intp.global.Name] = ichi.bench.Thyme$Warm@7a8d001b
scala> val w_new = th.Warm(sym.fullNameAsName('.'))
w_new: th.Warm[$r.intp.global.Name] = ichi.bench.Thyme$Warm@1ec14586
scala> th.pbenchOffWarm("", x => println(x))(w_old, 10, "old")(w_new, 10, "new")
Benchmark comparison (in 4.084 s)
old vs new
Significantly different (p ~= 0)
Time ratio: 0.53572 95% CI 0.51618 - 0.55525 (n=20)
old 64.54 ns 95% CI 62.41 ns - 66.67 ns
new 34.57 ns 95% CI 34.04 ns - 35.11 ns
res3: $r.intp.global.Name = scala.collection.parallel.mutable.ParSeq
```
It is still expensive enough that we should still consider
caching. The call to full name in `classBTypeFromSymbol`
in the new backed is a prime candidate for optimization.
|
|\ \
| | |
| | | |
Simplify TypeRef hierarchy. baseType returns NoType, as needed for isSubtype. Also improves performance.
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Redeem myself for e1c732db44 -- hopefully.
I inlined `thisInfo` (== `sym.info`), and made sure to use `relativeInfo`
wherever prefix and args influence the result of the query that we're
delegating to the underlying type. For type aliases, use `normalize`
for `baseClasses` and `decls`, since `relativeInfo` breaks the gnarly SI-8177.
I think normalize is okay for aliases, as the prefix should not matter
when computing base classes, and infos for the members in `decls`
are given the `asSeenFrom` treatment individually downstream.
(It's a tight rope between rewriting too many symbols and maintaining correctness.
Documented the trade-off in the code.)
Renamed the unimaginative `transform` to `relativize`, which, although everything
is relative, hopefully says a bit more about its usage than `transform`.
Removed a lot of over-factoring in the TypeRef hierarchy. Ultimately, we need
to reduce the number of TypeRef subclasses further, I think. It's really hard
to follow what's going on.
Removed the `thisInfo` cache, since `sym.info` and `relativeInfo` are both cached.
Made the cache invalidation hooks a bit more OO-y.
Compare `Symbol`s with `eq` -- they don't define an `equals` method.
Also, don't recurse in isSubtype when a `baseType` results in `NoType`.
This happens a lot and is cheap to check, so I posit (without proof),
that it's better for performance (and clarity) to check before recursing.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
By reducing excessive factoring, we can save an extraneous call
to `asSeenFrom`, and hopefully in a following commit figure out
a bigger problem with `baseType` that is causing wrong subtyping results.
This commit is a pure refactoring, save for the dropped ASF call,
which is explained below.
To motivate the following change to `relativeInfo`:
```
private[Types] def relativeInfo = /*trace(s"relativeInfo(${safeToString}})")*/{
if (relativeInfoPeriod != currentPeriod) {
- val memberInfo = pre.memberInfo(sym)
- relativeInfoCache = transformInfo(memberInfo)
+ relativeInfoCache = memberInfoInstantiated
```
Let's consolidate the two removed line in this new method:
```
def memberInfoInstantiated = transformInfo(pre.memberInfo(sym))
```
To understand what `transformInfo` does, take these helpers spread over
various `*TypeRef` traits, and consolidate them:
```
- def asSeenFromOwner(tp: Type) = tp.asSeenFrom(pre, sym.owner)
// regular type refs:
- def transformInfo(tp: Type): Type = appliedType(asSeenFromOwner(tp), args)
// for no-args type refs:
- override def transformInfo(tp: Type): Type = appliedType(asSeenFromOwner(tp), dummyArgs)
```
By removing the dynamic dispatch, we get the following method
(given `require(args0 ne Nil, this)` in `ArgsTypeRef`,
and `args eq Nil` by construction in `NoArgsTypeRef` ):
```
def transformInfo(tp: Type) =
appliedType(tp.asSeenFrom(pre, sym.owner), if (args.isEmpty) dummyArgs else args)
```
Inlining `memberInfo`, which is defined as:
```
def memberInfo(sym: Symbol): Type = {
require(sym ne NoSymbol, this)
sym.info.asSeenFrom(this, sym.owner)
}
```
gives us:
```
def memberInfoInstantiated = transformInfo(sym.info.asSeenFrom(pre, sym.owner))
```
Inlining `transformInfo` as reworked above:
```
def memberInfoInstantiated =
appliedType(sym.info.asSeenFrom(pre, sym.owner).asSeenFrom(pre, sym.owner),
if (args.isEmpty) dummyArgs else args)
```
Whoops! One `asSeenFrom` should do...
```
+ final protected def memberInfoInstantiated: Type =
+ appliedType(sym.info.asSeenFrom(pre, sym.owner), if (args.isEmpty) dummyArgs else args)
```
|
|\ \ \
| |/ /
|/| | |
Use invokedynamic for structural calls, symbol literals, lambda ser.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The previous encodings created static fields in the enclosing class
to host caches. However, this isn't an option once emit code in default
methods of interfaces, as Java interfaces don't allow private static
fields.
We could continue to emit fields, and make them public when added to
traits.
Or, as chosen in this commit, we can emulate a call-site specific
static field by using invokedynamic: when the call site is linked,
our bootstrap methid can perform one-time computation, and we can
capture the result in the CallSite.
To implement this, I've allowed encoding of arbitrary invokedynamic
calls in ApplyDynamic.
The encoding is:
ApplyDynamic(
NoSymbol.newTermSymbol(TermName("methodName")).setInfo(invokedType)
Literal(Constant(bootstrapMethodSymbol)) :: (
Literal(Constant(staticArg0)) :: Literal(Constant(staticArgN)) :: Nil
) :::
(dynArg0 :: dynArgN :: Nil)
)
So far, static args may be `MethodType`, numeric or string literals, or
method symbols, all of which can be converted to constant pool entries.
`MethodTypes` are transformed to the erased JVM type and are converted
to descriptors as String constants.
I've taken advantage of this for symbol literal caching and
for the structural call site cache.
I've also included a test case that shows how a macro could target this
(albeit using private APIs) to cache compiled regexes.
I haven't managed to use this for LambdaMetafactory yet, not sure
if the facility is general enough.
|
|\ \ \
| | | |
| | | | |
SI-9542 Fix regression in value classes (served two ways)
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The new unit test shows failures in transitivity of subtyping
and type equivalence, which boil down the the inconsistent
handling of the semantically equivalent:
ThisType(pre, ModuleClass)
ModuleTypeRef(pre, ModuleClass)
SingleType(pre, Module)
This commit:
- adds a case to `normalizePlus` to unwrap a `ThisType` to
a `ModuleTypeRef`
- Use `normalizePlus` more widely during subtype comparison
- refactor `fourthTry` (part of `isSubType`) to remove code
that becomes obviated by the use of `normalizePlus`.
This fixes the regression in the extension methods phase which
was triggered by https://github.com/scala/scala/pull/4749.
We can also fix that regression by tweaking the extension methods
phase itself to emit the `ThisType` representation of the owner
of the value class, as before.
I plan to demonstrate the two approaches to fixing the regression
on separate branches, and the propose that the merged result of these
two is useds.
|
|\ \ \
| | | |
| | | |
| | | | |
merge/2.11.x-to-2.12.x-20160203
|
| |/ /
| | |
| | |
| | |
| | |
| | | |
... instead of scala.collection.mutable.StringBuilder to benefit from
JVM optimizations. Unfortunately primitives are already boxed in erasure
when they end up in this part of the backend.
|
|\ \ \
| |/ /
|/| /
| |/
| |
| |
| |
| |
| | |
Conflicts:
src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
src/compiler/scala/tools/nsc/transform/Constructors.scala
src/compiler/scala/tools/nsc/typechecker/Contexts.scala
src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js
|
| |
| |
| |
| | |
The the word 'the' is often used twice. Fix that.
|
|\ \
| | |
| | | |
SI-9437 Emit and support parameter names in class files
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
JEP 118 added a MethodParameters attribute to the class file spec which
holds the parameter names of methods when compiling Java code with
`javac -parameters`.
We emit parameter names by default now.
|
|\| | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Before this commit, multiple invocations of universe.showRaw used a
shared weak map that caches footnotes. If the two printed objects
have equal components printed as footnotes, e.g., an equal TypeRef,
the result of the second invocation depends on whether the object
has been collected (and removed from the weak map) or not.
See https://github.com/scala/scala-dev/issues/70#issuecomment-171701671
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
- Language imports are preceding other imports
- Deleted empty file: InlineErasure
- Removed some unused private[parallel] methods in
scala/collection/parallel/package.scala
This removes hundreds of warnings when compiling with
"-Xlint -Ywarn-dead-code -Ywarn-unused -Ywarn-unused-import".
|
| |\ \
| | | |
| | | | |
Desugar module var and accessor in refchecks/lazyvals
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Rather than leaving it until mixin.
The broader motivation is to simplify the mixin phase of the
compiler before we get rid of implementatation classes in
favour of using JDK8 default interface methods.
The current code in mixin is used for both lazy val and modules,
and puts the "slow path" code that uses the monitor into a
dedicated method (`moduleName$lzyCompute`). I tracked this
back to a3d4d17b77. I can't tell from that commit whether the
performance sensititivity was related to modules or lazy vals,
from the commit message I'd say the latter.
As the initialization code for a module is just a constructor call,
rather than an arbitraryly large chunk of code for a lazy initializer,
this commit opts to inline the `lzycompute` method.
During refchecks, mixin module accessors are added to classes, so
that mixed in and defined modules are translated uniformly. Trait
owned modules get an accessor method with an empty body (that shares
the module symbol), but no module var.
Defer synthesis of the double checked locking idiom to the lazyvals
phase, which gets us a step closer to a unified translation of
modules and lazy vals.
I had to change the `atOwner` methods to to avoid using the
non-existent module class of a module accessor method as the
current owner. This fixes a latent bug. Without this change,
retypechecking of the module accessor method during erasure crashes
with an accessibility error selecting the module var.
In the process, I've tweaked a tree generation utility method
to wvoid synthesizing redundant blocks in module desugaring.
|
| |\ \ \
| | | | |
| | | | | |
SI-9110 Pattern `O.C` must check `$outer eq O` for a top level O
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The outer check was not being generated when the prefix was a
top level module. The enclosed test shows that we in fact must
synthesize the outer check in that case.
Perhaps the bug was introduced by neglecting to consider that
a module can inherit member classes.
|
| |\ \ \ \
| | |/ / /
| |/| | /
| | | |/
| | |/| |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Fix a batch of code inspection recommendations generated by IntelliJ 14.1.5.
Categories of fix,
Unnecessary public modifier in interface
Replace filter+size with count
Replace filter+nonEmpty with exists
Replace filter+headOption with find
Replace `if (x != null) Some(x) else None` with Option(x)
Replace getOrElse null with orNull
Drop redundant semicolons
Replace anon fun with PF
Replace anon fun with method
|
| |\| | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
- Don't normalize existentials during the `contain`-s type map;
`ExistentialType#normalize' calls contains internally and
an exponential blowup ensues.
- Ensure that the type map used in variance validation never
returns modified types in order to avoid needless cloning of
symbols.
The enclosed test case still gets stuck in Uncurry, thanks to
the way that `TypeMap#mapOver(List[Symbol])` recurses through the
type first to check whether the type map would be an no-op or not.
If not, it repeats the type map with cloned symbols. Doing the work
twice at each level of recursion blows up the complexity.
Removing that "fast path" allows the enclosed test to compile
completely. As at this commit, it gets stuck in uncurry, which
dealiases `s.List` to `s.c.i.List` within the type.
Some more background on the troublesome part of `TypeMap`:
http://lrytz.github.io/scala-aladdin-bugtracker/displayItem.do%3Fid=1210.html
https://github.com/scala/scala/commit/f8b2b21050e7a2ca0f537ef70e3e0c8eead43abc
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Comment about my poor naming choice in Types.
NullaryMethodType sounds like the method has one empty argument list,
whereas it really has no argument lists at all.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
sbt's [API extraction phase](https://github.com/sbt/sbt/blob/0.13/compile/interface/src/main/scala/xsbt/API.scala#L25)
extends `scala.reflect.internal.Phase`, which implements a bunch of methods,
such as `erasedTypes` as `false`, which are then overridden by scalac
in `GlobalPhase` (nested in scala.tools.nsc.Global).
(`erasedTypes` in particular is again overridden in the back-end -- for performance?)
However, since sbt's compiler phases extend `reflect.internal.Phase`,
the logic for detecting the current phase does not work,
as the default implementation is called (simply returning `false`),
when chasing the `prev` pointers hits an sbt-injected phase,
as its implementation is `reflect.internal`'s constant `false`.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
This logic was scattered all over the hierarchy,
even though it's only needed in one spot, and is unlikely to evolve.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
Keep owner for module (symbol of the tree) and module class (holds the members)
in synch while moving trees between owners (e.g., while duplicating them in specialization)
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
All class internal names that are referenced from a class being
compiled should be referenced through their ClassBType. This makes
sure that the ClassBType is cached in `classBTypeFromInternalName`,
which is required during classfile writing: when ASM computes stack
map frames, we need to answer subtyping queries, for which we need
to look up the ClassBTypes.
|
|/ / /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The previous methods to identify method invocations that can be
optimized, such as `isPredefAutoBox`, were String-based. Now we
obtain class and method signatures from symbols through the
BTypes infrastructure.
We also piggy-back on specialization's type transformer to create
all specialized subclasses of Tuple1/Tuple2. We'll do the same in
the future for FunctionN, but the current JFunctionN are written
in Java and specialized artisanally.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
For @throws[E] where E is not a class type, GenASM incorrectly writes
the non-class type to the classfile. GenBCode used to crash before
this commit. Now GenBCode correctly emits the erased type (like
javac) and adds a generic signature.
|
| |/
|/|
| |
| |
| |
| |
| | |
Allow annotating individual callsites @inline / @noinline using an
annotation ascription
c.foo(): @inline
|
|\| |
|
| |\
| | |
| | | |
get test suite passing on Windows
|
| | | |
|
| |\ \
| | |/
| |/| |
fix indentation
|
| | |
| | |
| | |
| | | |
this sneaked into 2d025fe2d0c9cd0e01e390055b0531166988f901
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
A trio of problems were hampering autocompletion of annotations.
First, given that that annotation is written before the annotated
member, it is very common to end parse incomplete code that has a
floating annotation without an anotatee.
The parser was discarding the annotations (ie, the modifiers) and
emitting an `EmptyTree`.
Second, the presetation compiler was only looking for annotations
in the Modifiers of a member def, but after typechecking annotations
are moved into the symbol.
Third, if an annotation failed to typecheck, it was being discarded
in place of `ErroneousAnnotation`.
This commit:
- modifies the parser to uses a dummy class- or type-def tree,
instead of EmptyTree, which can carry the annotations.
- updates the locator to look in the symbol annotations of the
modifiers contains no annotations.
- uses a separate instance of `ErroneousAnnotation` for each
erroneous annotation, and stores the original tree in its
`original` tree.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
I found another spot where I had previously needed to manually
invalidate a TypeRef cache, and modified that to route through
the newly added `invalidatedCaches`.
`invalidatedCaches` now invalidates all the other caches I could
find in our types of types. I opted for a non-OO approach here,
as we've got a fairly intricate lattice of traits in place that
define caches, and I didn't have the stomach for adding a polymorphic
`Type::invalidatedCaches` with the the right sprinkling over overrides
and super calls.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Typechecking a pattern that defines a pattern type variable
initially assigns abstract type symbol with open type bounds.
Later on, pattern type inference kicks in to sharpen the type
of the variable based on constraints imposed by the expected
type (ie, the type of scrutinee of the pattern.)
However, before inference does this, a `TypeRef` to the abstract
type symbol can be queried for its base type with respect to some
class, which leads to it populating an internal cache. This cache
becomes stale when the underlying symbol has its type mutated.
The repercussions of this meant that a subsequent call to `baseType`
gave the wrong result (`NoType`), which lead to an `asSeenFrom`
operation to miss out of substitution of a type variable. Note the
appearance of `A` in the old type errors in the enclosed test case.
This commit takes an approach similar to 286dafbd to invalidate
caches after the mutation. I've routed both bandaids through the
same first aid kit: I'm sure over time we'll add additional calls
to this method, and additional cache invalidations within it.
|
|\| |
|
| |\
| | |
| | | |
Topic/completely 2.11
|
| | |\ |
|