summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend
Commit message (Collapse)AuthorAgeFilesLines
...
* | Merge pull request #5157 from retronym/topic/lambda-staticsJason Zaugg2016-06-064-8/+14
|\ \ | | | | | | Lambda impl methods static and more stably named
| * | Treat self parameter as non-null in the optimizerLukas Rytz2016-06-013-7/+13
| | |
| * | Lambda impl methods static and more stably namedJason Zaugg2016-06-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The body of lambdas is compiled into a synthetic method in the enclosing class. Previously, this method was a public virtual method named `fully$qualified$Class$$anonfun$n`. For lambdas that didn't capture a `this` reference, a static method was used. This commit changes two aspects. Firstly, all lambda impl methods are now emitted static. An extra parameter is added to those that require a this reference. This is an improvement as it: - allows, shorter, more readable names for the lambda impl method - avoids pollution of the vtable of the class. Note that javac uses private instance methods, rather than public static methods. If we followed its lead, we would be unable to support important use cases in our inliner Secondly, the name of the enclosing method has been included in the name of the lambda impl method to improve debuggability and to improve serialization compatibility. The serialization improvement comes from the way that fresh names for the impl methods are allocated: adding or removing lambdas in methods not named "foo" won't change the numbering of the `anonfun$foo$n` impl methods from methods named "foo". This is in line with user expectations about anonymous class and lambda serialization stability. Brian Goetz has described this tricky area well in: http://cr.openjdk.java.net/~briangoetz/eg-attachments/lambda-serialization.html This commit doesn't go as far a Javac, we don't use the hash of the lambda type info, param names, etc to map to a lambda impl method name. As such, we are more prone to the type-1 and -2 failures described there. However, our Scala 2.11.8 has similar characteristics, so we aren't going backwards. Special case in the naming: Use "new" rather than "<init>" for constructor enclosed lambdas, as javac does. I have also changed the way that "delambdafy target" methods are identifed. Rather than relying on the naming convention, I have switched to using a symbol attachment. The assumption is that we only need to identify them from within the same compilation unit. This means we can distinguish impl metbods for expanded functions (ones called from an `apply` method of an ahead-of-time expanded anonfun class), from those that truly end up as targets for lambda metafactory. Only the latter are translated to static methods in this patch.
* | | Fix comparisons involving NaNLukas Rytz2016-06-023-17/+14
|/ / | | | | | | | | Floating point comparisons involving NaN should always return false, except for !=. Fixes a regression introduced by #4963.
* | Merge pull request #5186 from lrytz/inlinerM5Jason Zaugg2016-05-273-11/+78
|\ \ | | | | | | Debug flag to print a summary of the inliner's work
| * | Debug flag to print a summary of the inliner's workLukas Rytz2016-05-243-11/+78
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Example output below. Note that inlining List.map fails because the trait forwarder uses `INVOKESPECIAL` for now, will change with pr 5177. $ cat Test.scala class C { def foo = Map(1 -> 'a', 2 -> 'b') def bar(l: List[Int]) = l.map(_ + 1) } $ qsc -Yopt-log-inline _ -Yopt:l:classpath Test.scala Inlining into C.foo (initially 36 instructions, ultimately 72): - Inlined scala/Predef$ArrowAssoc$.$minus$greater$extension (8 instructions) 2 times: the callee is annotated `@inline` Inlining into C.bar (initially 12 instructions, ultimately 12): - Failed to inline scala/collection/immutable/List.map (the callee is a higher-order method, the argument for parameter (bf: Function1) is a function literal): The callee scala/collection/immutable/List::map(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object; contains the instruction INVOKESPECIAL scala/collection/TraversableLike.map (Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object; that would cause an IllegalAccessError when inlined into class C.
* | | Rename -Yopt to -opt, -Yopt-warnings to -opt-warningsLukas Rytz2016-05-2510-42/+42
|/ / | | | | | | Keep -Yopt-inline-heuristics and -Yopt-trace unchanged
* / SI-9121 test case (fixed in new optimizer), SI-9179 test caseLukas Rytz2016-05-231-1/+1
|/ | | | | Also adds a mising phase travel in the backend. A comment already points out why it's necessary, but it was actually forgotten.
* Generate static forwarders for object members in companion interface (#5131)Jason Zaugg2016-05-191-2/+1
| | | | | | | | | | We used to disable generation of static forwarders when a object had a trait as a companion, as one could not add methods with bodies to an interface in JVM 6. The JVM lifted this restriction to support default methods in interfaces, so we can lift the restriction on static forwarders, too. Fixes https://github.com/scala/scala-dev/issues/59
* Merge pull request #5112 from lrytz/dropRecursiveClasspathJason Zaugg2016-05-053-39/+14
|\ | | | | Remove legacy recursive classpath implementation
| * Remove abstraction layer in classpath implementationLukas Rytz2016-05-023-20/+16
| |
| * remove recursive classpath implementationLukas Rytz2016-04-233-27/+6
| |
* | Merge pull request #5140 from lrytz/inlineDefaultMethodsJason Zaugg2016-05-055-53/+161
|\ \ | | | | | | SD-140 inline the correct default method
| * | SD-140 inline the correct default methodLukas Rytz2016-04-285-53/+161
| | | | | | | | | | | | | | | When inheriting multiple default methods, select the correct one to inline. Implements method resolution according to the JVM spec.
* | | SD-142 Avoid noisy log output in backend (#5134)Jason Zaugg2016-05-021-1/+1
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `withCurrentUnit` is designed to be called once per compilation unit as it side effects by logging and updating progress counters. `GenBCode` was calling it more frequently (once per `ClassDef`.) This is due to the somewhat convoluted internal architecture of that phase, which is designed to support paralellism in the future. This commit factors out the internal part of `withCompilationUnit` that modifies `currentUnit`, and calls that instead in the loop over classes. After this change: ``` % qscala -Ydebug ... [running phase jvm on <console>] // only once ```
* | Merge pull request #5109 from lrytz/pr5064Lukas Rytz2016-04-2314-17/+14
|\ \ | | | | | | SI-9684 Deprecate JavaConversions
| * | SI-9684 Deprecate JavaConversionsSom Snytt2016-04-2214-17/+14
| |/ | | | | | | | | | | | | | | | | Implicit conversions are now in package convert as ImplicitConversions, ImplicitConversionsToScala and ImplicitConversionsToJava. Deprecated WrapAsJava, WrapAsScala and the values in package object. Improve documentation.
* / SI-9516 Fix the behavior of Int shift Long operations. (#5117)Sébastien Doeraene2016-04-231-4/+5
|/ | | | | | | | | | | In any shift operation where the lhs is an Int (or smaller) and the rhs is a Long, the result kind must be Int, and not Long. This is important because the lhs must *not* be promoted to a Long, as that causes an opcode for long shift to be emitted. This uses an rhs modulo 64, instead of int shifts which use an rhs module 32. Instead, the rhs must be downgraded to an Int. The new behavior is consistent with the same operations in the Java programming language.
* Merge pull request #5110 from sjrd/remove-duplicate-implem-of-hashcodesLukas Rytz2016-04-222-2/+1
|\ | | | | Remove the duplicate implem of hash codes for numbers.
| * Remove the duplicate implem of hash codes for numbers.Sébastien Doeraene2016-04-212-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, there were two separate implementations of hash code for boxed number classes: * One in Statics, used by the codegen of case class methods. * One in ScalaRunTime + BoxesRunTime, used by everything else. This commit removes the variant implemented in ScalaRunTime + BoxesRunTime, and always uses Statics instead. We use Statics because the one from ScalaRunTime causes an unnecessary module load. The entry point ScalaRunTime.hash() is kept, as deprecated, for bootstrapping reasons.
* | Merge pull request #5096 from lrytz/traitParentsLukas Rytz2016-04-205-231/+233
|\ \ | | | | | | Ensure ClassBTypes constructed from symbol and classfile are identical
| * | Ensure ClassBTypes constructed from symbol and classfile are identicalLukas Rytz2016-04-204-21/+58
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A super call (invokespecial) to a default method T.m is only allowed if the interface T is a direct parent of the class. Super calls are introduced for example in Mixin when generating forwarder methods: trait T { override def clone(): Object = "hi" } trait U extends T class C extends U The class C gets a forwarder that invokes T.clone(). During code generation the interface T is added as direct parent to class C. Note that T is not a (direct) parent in the frontend type of class C. This commit stores interfaces that are added to a class during code generation in the InlineInfo classfile attribute. This allows filtering the interface list when constructing a ClassBType from a classfile.
| * | Clean up code gen for method invocationsLukas Rytz2016-04-203-211/+176
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The code was patched many times in the history and became a bit scattered. When emitting a virtual call, the receiver in the bytecode cannot just be the method's owner (the class in which it is declared), because that class may not be accessible at the callsite. Instead we use the type of the receiver. This was basically done to fix - aladdin bug 455 (9954eaf) - SI-1430 (0bea2ab) - basically the same bug, slightly different - SI-4283 (8707c9e) - the same for field reads In this patch we extend the fix to field writes, and clean up the code. This patch basically reverts 6eb55d4b, the fix for SI-4560, which was rather a workaround than a fix. The underlying problem was that in some cases, in a method invocation `foo.bar()`, the method `bar` was not actually a member of `foo.tpe`, causing a NoSuchMethodErrors. The issue was related to trait implementation classes. The idea of the fix was to check, at code-gen time, `foo.tpe.member("bar")`, and if that returns `NoSymbol`, use `barSym.owner`. With the new trait encoding the underlying problem seems to be fixed - all tests still pass (run/t4560.scala and run/t4560b.scala).
* / SI-6710 / PR 5072 follow-up: fix Unit.box / Unit.unboxLukas Rytz2016-04-201-4/+4
|/ | | | | | | The backend replaces .box / .unbox methods by corresponding invocations to BoxesRunTime, but not for Unit. This commit restores the body of `Unit.box` and `Unit.unbox`.
* Merge pull request #5082 from lrytz/inlineImplClassCleanupLukas Rytz2016-04-0710-269/+70
|\ | | | | Cleanups related to the removal of trait impl classes
| * Fix InlineInfo attribute for nested module accessorsLukas Rytz2016-04-071-5/+7
| |
| * Remove references to trait impl classes, mostly in doc commentsLukas Rytz2016-04-074-70/+22
| |
| * Remove unused optimizer warnings related to trait impl classesLukas Rytz2016-04-041-6/+0
| |
| * Remove dead code in the optimizer related to trait impl classesLukas Rytz2016-04-047-188/+41
| |
* | General cleanups and less warnings during a Scala buildsoc2016-04-0411-26/+20
|/
* Merge pull request #5059 from lrytz/t9702Adriaan Moors2016-03-313-52/+52
|\ | | | | SI-9702 Fix backend crash with classOf[T] annotation argument
| * SI-9702 Fix backend crash with classOf[T] annotation argumentLukas Rytz2016-03-303-52/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit fixes various issues with classOf literals and Java annotations. - Ensure that a Type within a ConstantType (i.e., a classOf literal) is erased, so `classOf[List[Int]]` becomes `classOf[List]`. - Ensure that no non-erased types are passed to `typeToBType` in the backend. This happens for Java annotations: the annotation type and `classOf` annotation arguments are not erased, the annotationInfos of a symbol are not touched in the compiler pipeline. - If T is an alias to a value class, ensure that `classOf[T]` erases to the value class by calling `dealiasWiden` in erasure.
* | Merge pull request #4971 from adriaanm/genbcode-delambdafyAdriaan Moors2016-03-315-16/+15
|\ \ | | | | | | Unify treatment of built-in functions and SAMs
| * | Target FunctionN, not scala/runtime/java8/JFunction.Adriaan Moors2016-03-283-12/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We compile FunctionN to Java 8's idea of a function now, so no need to target the artisanal JFunction and friends, except when the function is specialized, as I don't yet see how we can use LMF with the way specialization handles FunctionN: First, the working status quo -- the hand-crafted specialized versions of JFunction0. Notice how `apply$mcB$sp` is looking pretty SAMmy: ``` @FunctionalInterface public interface JFunction0$mcB$sp extends JFunction0 { @Override public byte apply$mcB$sp(); @Override default public Object apply() { return BoxesRunTime.boxToByte(this.apply$mcB$sp()); } } ``` Contrast this with our specialized standard FunctionN: ``` public interface Function0<R> { public R apply(); default public byte apply$mcB$sp() { return BoxesRunTime.unboxToByte(this.apply()); } } public interface Function0$mcB$sp extends Function0<Object> { } ``` The single abstract method in `Function0$mcB$sp` is `apply`, and the method that would let us avoid boxing, if it were abstract, is `apply$mcB$sp`... TODO (after M4): - do same for specialized functions (issues with boxing?) - remove scala/runtime/java8/JFunction* (need new STARR?)
| * | Track Function's SAM symbol & target type using an attachmentAdriaan Moors2016-03-261-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We cannot use the expected type to track whether a Function node targets a SAM type, as the expected type may be erased (see test for an example). Thus, the type checker attaches a SAMFunction attachment to a Function node when SAM conversion is performed in adapt. Ideally, we'd move to Dotty's Closure AST, but that will need a deprecation cycle. Thanks to Jason for catching my mistake, suggesting the fix and providing the test. Both the sam method symbol and sam target type must be tracked, as their relationship can be complicated (due to inheritance). For example, the sam method could be defined in a superclass (T) of the Function's target type (U). ``` trait T { def foo(a: Any): Any } trait U extends T { def apply = ??? } (((x: Any) => x) : U).foo("") ``` This removes some of the duplication in deriving the sam method from the expected type, but some grossness (see TODO) remains.
| * | SI-9415 Turn on SAM by defaultJason Zaugg2016-03-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Initial work to change settings and test by Svyatoslav Ilinskiy Thanks! To avoid cycles during overload resolution (which showed up during bootstrapping), and to improve performance, I've guarded the detection of SAM types in `isCompatible` to cases when the LHS is potentially compatible.
| * | Remove dead code now that `genBCodeActive` is always true.Adriaan Moors2016-03-261-0/+2
| |/
* | Merge pull request #5058 from lrytz/newTraitsInlinerLukas Rytz2016-03-302-3/+9
|\ \ | | | | | | Inline super calls, as they are statically resolved
| * | Inline super calls, as they are statically resolvedLukas Rytz2016-03-232-3/+9
| |/ | | | | | | | | | | | | Ensures that mixin methods of `@inline` annotated concrete trait methods inline the trait method. Fixes https://github.com/scala/scala-dev/issues/86
* / Fix a bug in multi-dimensional array creationDmitry Petrashko2016-03-231-2/+2
|/ | | | | `']' * 5` is not `]]]]]` but `245`. I guess this code is never executed, because it would never work.
* Support :require when using the flat classpath representation.Lukas Rytz2016-03-222-8/+21
| | | | | | :require was re-incarnated in https://github.com/scala/scala/pull/4051, it seems to be used by the spark repl. This commit makes it work when using the flat classpath representation.
* Merge pull request #5043 from dongjoon-hyun/fix_typos_in_spec_and_commentsJason Zaugg2016-03-217-12/+12
|\ | | | | Fix some typos in `spec` documents and comments.
| * Fix some typos in `spec` documents and comments.Dongjoon Hyun2016-03-157-12/+12
| |
* | New trait encoding: use default methods, jettison impl classesJason Zaugg2016-03-186-71/+59
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, concrete methods in traits were encoded with "trait implementation classes". - Such a trait would compile to two class files - the trait interface, a Java interface, and - the implementation class, containing "trait implementation methods" - trait implementation methods are static methods has an explicit self parameter. - some methods don't require addition of an interface method, such as private methods. Calls to these directly call the implementation method - classes that mixin a trait install "trait forwarders", which implement the abstract method in the interface by forwarding to the trait implementation method. The new encoding: - no longer emits trait implementation classes or trait implementation methods. - instead, concrete methods are simply retained in the interface, as JVM 8 default interface methods (the JVM spec changes in [JSR-335](http://download.oracle.com/otndocs/jcp/lambda-0_9_3-fr-eval-spec/index.html) pave the way) - use `invokespecial` to call private or particular super implementations of a method (rather `invokestatic`) - in cases when we `invokespecial` to a method in an indirect ancestor, we add that ancestor redundantly as a direct parent. We are investigating alternatives approaches here. - we still emit trait fowrarders, although we are [investigating](https://github.com/scala/scala-dev/issues/98) ways to only do this when the JVM would be unable to resolve the correct method using its rules for default method resolution. Here's an example: ``` trait T { println("T") def m1 = m2 private def m2 = "m2" } trait U extends T { println("T") override def m1 = super[T].m1 } class C extends U { println("C") def test = m1 } ``` The old and new encodings are displayed and diffed here: https://gist.github.com/retronym/f174d23f859f0e053580 Some notes in the implementation: - No need to filter members from class decls at all in AddInterfaces (although we do have to trigger side effecting info transformers) - We can now emit an EnclosingMethod attribute for classes nested in private trait methods - Created a factory method for an AST shape that is used in a number of places to symbolically bind to a particular super method without needed to specify the qualifier of the `Super` tree (which is too limiting, as it only allows you to refer to direct parents.) - I also found a similar tree shape created in Delambdafy, that is better expressed with an existing tree creation factory method, mkSuperInit.
* Remove -Y settings that are no longer used in 2.12Lukas Rytz2016-02-161-4/+1
| | | | | | Added a deprecation warning for `-optimize`. Later we'll also graduate `-Yopt` to `-opt`, probably for 2.12.0-M5.
* SD-79 don't issue spurious inliner warnings under l:projectLukas Rytz2016-02-154-15/+20
| | | | | | | | | | | When enabling `-Yopt:inline-project` (or `-Yopt:l:project`), the inliner would spuriously warn about callsites to methods marked `@inline` that are read from the classpath (not being compiled currently). This patch introduces yet another field to the `Callsite` class, which is growing a bit too large. But the call graph representation will get an overhaul when implementing the new inliner heuristics (2.12.0-M5), so this is just a temporary fix that would be nice to have in M4.
* Avoid generating ACONST_NULL; POP; ACONST_NULL when loading nullLukas Rytz2016-02-142-11/+21
| | | | | | | When loading a value of type scala.runtime.Null$ we need to add POP; ACONST_NULL, see comment in BCodeBodyBuilder.adapt. This is however not necessary if the null value is a simple ACONST_NULL. This patch eliminates that redundancy.
* Generate leaner code for branchesLukas Rytz2016-02-132-87/+94
| | | | | | | | | | | | | | | | | | | | | | | | | GenBCode used to generate more bytecode for branching instructions than GenASM. A simple method def f(x: Int, b: Boolean) = if (b) 1 else 2 would generate ILOAD 2 IFNE L1 GOTO L2 L1 ICONST_1 GOTO L3 L2 ICONST_2 L3 IRETURN If the conditional branch is negated (IFEQ) the GOTO is unnecessary. While -Yopt:l:method would clean this up, it's also not too hard to generate the leaner bytecode in the first place.
* Merge pull request #4944 from lrytz/stringBuilderNoBoxLukas Rytz2016-02-122-9/+20
|\ | | | | SI-9571 Avoid boxing primitives in string concatenation
| * SI-9571 Avoid boxing primitives in string concatenationMarko Elezovic2016-02-062-9/+20
| |