summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* Merge pull request #4534 from Ichoran/sorting-reimplAdriaan Moors2015-06-163-477/+357
|\ | | | | Clean implementation of sorts for scala.util.Sorting.
| * Clean implementation of sorts for scala.util.Sorting.Rex Kerr2015-06-013-477/+357
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Removed code based on Sun JDK sorts and implemented new (basic) sorts from scratch. Deferred to Java Arrays.sort whenever practical. Behavior of `scala.util.Sorting` should be unchanged, but changed documentation to specify when the Java methods are being used (as they're typically very fast). A JUnit test is provided. Performance is important for sorts. Everything is better with this patch, though it could be better yet, as described below. Below are sort times (in microseconds, SEM < 5%) for various 1024-element arrays of small case classes that compare on an int field (quickSort), or int arrays that use custom ordering (stableSort). Note: "degenerate" means there are only 16 values possible, so there are lots of ties. Times are all with fresh data (no re-using cache from run to run). Results: ``` random sorted reverse degenerate big:64k tiny:16 Old Sorting.quickSort 234 181 178 103 25,700 1.4 New Sorting.quickSort 170 27 115 74 18,600 0.8 Old Sorting.stableSort 321 234 236 282 32,600 2.1 New Sorting.stableSort 239 16 194 194 25,100 1.2 java.util.Arrays.sort 124 4 8 105 13,500 0.8 java.util.Arrays.sort|Box 126 15 13 112 13,200 0.9 ``` The new versions are uniformly faster, but uniformly slower than Java sorting. scala.util.Sorting has use cases that don't map easily in to Java unless everything is pre-boxed, but the overhead of pre-boxing is minimal compared to the sort. A snapshot of some of my benchmarking code is below. (Yes, lots of repeating myself--it's dangerous not to when trying to get somewhat accurate benchmarks.) ``` import java.util.Arrays import java.util.Comparator import math.Ordering import util.Sorting import reflect.ClassTag val th = ichi.bench.Thyme.warmed() case class N(i: Int, j: Int) {} val a = Array.fill(1024)( Array.tabulate(1024)(i => N(util.Random.nextInt, i)) ) var ai = 0 val b = Array.fill(1024)( Array.tabulate(1024)(i => N(i, i)) ) var bi = 0 val c = Array.fill(1024)( Array.tabulate(1024)(i => N(1024-i, i)) ) var ci = 0 val d = Array.fill(1024)( Array.tabulate(1024)(i => N(util.Random.nextInt(16), i)) ) var di = 0 val e = Array.fill(16)( Array.tabulate(65536)(i => N(util.Random.nextInt, i)) ) var ei = 0 val f = Array.fill(65535)( Array.tabulate(16)(i => N(util.Random.nextInt, i)) ) var fi = 0 val o = new Ordering[N]{ def compare(a: N, b: N) = if (a.i < b.i) -1 else if (a.i > b.i) 1 else 0 } for (s <- Seq("one", "two", "three")) { println(s) th.pbench{ val x = a(ai).clone; ai = (ai+1)%a.length; Sorting.quickSort(x)(o); x(x.length/3) } th.pbench{ val x = b(bi).clone; bi = (bi+1)%b.length; Sorting.quickSort(x)(o); x(x.length/3) } th.pbench{ val x = c(ci).clone; ci = (ci+1)%c.length; Sorting.quickSort(x)(o); x(x.length/3) } th.pbench{ val x = d(di).clone; di = (di+1)%d.length; Sorting.quickSort(x)(o); x(x.length/3) } th.pbench{ val x = e(ei).clone; ei = (ei+1)%e.length; Sorting.quickSort(x)(o); x(x.length/3) } th.pbench{ val x = f(fi).clone; fi = (fi+1)%f.length; Sorting.quickSort(x)(o); x(x.length/3) } } def ix(ns: Array[N]) = { val is = new Array[Int](ns.length) var i = 0 while (i < ns.length) { is(i) = ns(i).i i += 1 } is } val p = new Ordering[Int]{ def compare(a: Int, b: Int) = if (a > b) 1 else if (a < b) -1 else 0 } for (s <- Seq("one", "two", "three")) { println(s) val tag: ClassTag[Int] = implicitly[ClassTag[Int]] th.pbench{ val x = ix(a(ai)); ai = (ai+1)%a.length; Sorting.stableSort(x)(tag, p); x(x.length/3) } th.pbench{ val x = ix(b(bi)); bi = (bi+1)%b.length; Sorting.stableSort(x)(tag, p); x(x.length/3) } th.pbench{ val x = ix(c(ci)); ci = (ci+1)%c.length; Sorting.stableSort(x)(tag, p); x(x.length/3) } th.pbench{ val x = ix(d(di)); di = (di+1)%d.length; Sorting.stableSort(x)(tag, p); x(x.length/3) } th.pbench{ val x = ix(e(ei)); ei = (ei+1)%e.length; Sorting.stableSort(x)(tag, p); x(x.length/3) } th.pbench{ val x = ix(f(fi)); fi = (fi+1)%f.length; Sorting.stableSort(x)(tag, p); x(x.length/3) } } for (s <- Seq("one", "two", "three")) { println(s) th.pbench{ val x = a(ai).clone; ai = (ai+1)%a.length; Arrays.sort(x, o); x(x.length/3) } th.pbench{ val x = b(bi).clone; bi = (bi+1)%b.length; Arrays.sort(x, o); x(x.length/3) } th.pbench{ val x = c(ci).clone; ci = (ci+1)%c.length; Arrays.sort(x, o); x(x.length/3) } th.pbench{ val x = d(di).clone; di = (di+1)%d.length; Arrays.sort(x, o); x(x.length/3) } th.pbench{ val x = e(ei).clone; ei = (ei+1)%e.length; Arrays.sort(x, o); x(x.length/3) } th.pbench{ val x = f(fi).clone; fi = (fi+1)%f.length; Arrays.sort(x, o); x(x.length/3) } } def bx(is: Array[Int]): Array[java.lang.Integer] = { val Is = new Array[java.lang.Integer](is.length) var i = 0 while (i < is.length) { Is(i) = java.lang.Integer.valueOf(is(i)) i += 1 } Is } def xb(Is: Array[java.lang.Integer]): Array[Int] = { val is = new Array[Int](Is.length) var i = 0 while (i < is.length) { is(i) = Is(i).intValue i += 1 } is } val q = new Comparator[java.lang.Integer]{ def compare(a: java.lang.Integer, b: java.lang.Integer) = o.compare(a.intValue, b.intValue) } for (s <- Seq("one", "two", "three")) { println(s) val tag: ClassTag[Int] = implicitly[ClassTag[Int]] th.pbench{ val x = bx(ix(a(ai))); ai = (ai+1)%a.length; Arrays.sort(x, q); xb(x)(x.length/3) } th.pbench{ val x = bx(ix(b(bi))); bi = (bi+1)%b.length; Arrays.sort(x, q); xb(x)(x.length/3) } th.pbench{ val x = bx(ix(c(ci))); ci = (ci+1)%c.length; Arrays.sort(x, q); xb(x)(x.length/3) } th.pbench{ val x = bx(ix(d(di))); di = (di+1)%d.length; Arrays.sort(x, q); xb(x)(x.length/3) } th.pbench{ val x = bx(ix(e(ei))); ei = (ei+1)%e.length; Arrays.sort(x, q); xb(x)(x.length/3) } th.pbench{ val x = bx(ix(f(fi))); fi = (fi+1)%f.length; Arrays.sort(x, q); xb(x)(x.length/3) } } ```
* | Merge pull request #4548 from ScrapCodes/git_4522Jason Zaugg2015-06-146-25/+187
|\ \ | | | | | | SI-7747 Make REPL wrappers serialization friendly.
| * | SI-7747 More tests and logic according to our conclusions on #4522.Prashant Sharma2015-06-105-6/+29
| | |
| * | SI-7747 Limit previous change to imports of REPL valsJason Zaugg2015-05-262-14/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We only need to introduce the temporary val in the imports wrapper when we are importing a val or module defined in the REPL. The test case from the previous commit still passes, but we are generating slightly simpler code. Compared to 2.11.6, these two commits result in the following diff: https://gist.github.com/retronym/aa4bd3aeef1ab1b85fe9
| * | SI-7747 Make REPL wrappers serialization friendlyPrashant Sharma2015-05-266-25/+162
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Spark has been shipping a forked version of our REPL for sometime. We have been trying to fold the patches back into the mainline so they can defork. This is the last outstanding issue. Consider this REPL session: ``` scala> val x = StdIn.readInt scala> class A(a: Int) scala> serializedAndExecuteRemotely { () => new A(x) } ``` As shown by the enclosed test, the REPL, even with the Spark friendly option `-Yrepl-class-based`, will re-initialize `x` on the remote system. This test simulates this by running a REPL session, and then deserializing the resulting closure into a fresh classloader based on the class files generated by that session. Before this patch, it printed "evaluating x" twice. This is based on the Spark change described: https://github.com/mesos/spark/pull/535#discussion_r3541925 A followup commit will avoid the `val lineN$read = ` part if we import classes or type aliases only. [Original commit from Prashant Sharma, test case from Jason Zaugg]
* | | Merge pull request #4536 from danieldietrich/2.11.xJason Zaugg2015-06-071-4/+5
|\ \ \ | | | | | | | | Applying inverse index instead of reversing a List
| * | | Better names for length valuesDaniel Dietrich2015-06-051-5/+5
| | | |
| * | | Applying inverse index instead of reversing a ListDaniel Dietrich2015-06-021-1/+2
| | |/ | |/|
* | | Merge pull request #4519 from lrytz/opt/nullness-2.11Jason Zaugg2015-06-0713-26/+1364
|\ \ \ | | | | | | | | Nullness Analysis for GenBCode
| * | | Fix aliasing / nullness of CHECKCASTLukas Rytz2015-06-043-3/+30
| | | |
| * | | Compiler option for disabling nullness analysisLukas Rytz2015-06-044-9/+23
| | | |
| * | | Address review feedbackLukas Rytz2015-05-254-69/+109
| | | | | | | | | | | | | | | | | | | | | | | | Address feedback in #4516 / 57b8da4cd8. Save allocations of NullnessValue - there's only 4 possible instances. Also save tuple allocations in InstructionStackEffect.
| * | | Fix wrong result in InstructionStackEffect for ATHROW, RETURNLukas Rytz2015-05-251-3/+3
| | | |
| * | | Fix wrong indexing in FrameExtensions.peekStackLukas Rytz2015-05-251-1/+1
| | | |
| * | | Enable nullness analysis in the inlinerLukas Rytz2015-05-255-15/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When inlining an instance call, the inliner has to ensure that a NPE is still thrown if the receiver object is null. By using the nullness analysis, we can avoid emitting this code in case the receiver object is known to be not-null.
| * | | Nullness AnalysisLukas Rytz2015-05-228-8/+1237
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Tracks nullness of values using an ASM analyzer. Tracking nullness requires alias tracking for local variables and stack values. For example, after an instance call, local variables that point to the same object as the receiver are treated not-null.
* | | | Merge pull request #4537 from som-snytt/issue/xml-unapplyJason Zaugg2015-06-043-21/+17
|\ \ \ \ | |_|/ / |/| | | SI-9343 Xlint less strict on pattern sequences
| * | | SI-9343 Xlint less strict on pattern sequencesSom Snytt2015-06-033-21/+17
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -Xlint:stars-align warns only if elementarity > 0, that is, if an extracted sequence is not matched entirely by a pattern sequence, that is, in SLS 8.1.9 on pattern sequences, n = 1 and that pattern is a pattern sequence. This is still only triggered if productarity > 0, that is, a non-pattern-sequence pattern is required for the match. This is a sensitive area because it borders on exhaustiveness checking: it would be preferable to verify just that the match is exhaustive, and to emit this warning only if it is not.
* | | Merge pull request #4511 from sriggin/SI-9322Lukas Rytz2015-05-282-3/+3
|\ \ \ | | | | | | | | SI-9322 Elapsed times in compiler calculated with System.currentTimeMillis and System.nanoTime
| * | | SI-9322 Elapsed times in compiler calculated withSean Riggin2015-05-262-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | System.currentTimeMillis and System.nanoTime Reverted elapsedTime calculation in compiler to use System.currentTimeMillis, consistent with the start time.
* | | | Merge pull request #4528 from xuwei-k/patch-2Lukas Rytz2015-05-281-1/+1
|\ \ \ \ | | | | | | | | | | fix typo
| * | | | fix typokenji yoshida2015-05-281-1/+1
| | | | |
* | | | | Merge pull request #4530 from som-snytt/issue/9332Lukas Rytz2015-05-282-20/+22
|\ \ \ \ \ | | | | | | | | | | | | SI-9332 Iterator.span exhausts leading iterator
| * | | | | SI-9332 Iterator.span simplifiedSom Snytt2015-05-271-15/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The queue is only used when the prefix is drained by finish. Since a finished flag has been introduced, distinguish between the drained state and using the underlying (buffered) iterator.
| * | | | | SI-9332 Iterator.span exhausts leading iteratorSom Snytt2015-05-272-17/+22
| |/ / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since the leading and trailing iterators returned by span share the underlying iterator, the leading iterator must flag when it is exhausted (when the span predicate fails) since the trailing iterator will advance the underlying iterator. It would also be possible to leave the failing element in the leading lookahead buffer, where it would forever fail the predicate, but that entails evaluating the predicate twice, on both enqueue and dequeue.
* | | | | Merge pull request #4531 from kzys/8210-inherited-doc-211Lukas Rytz2015-05-283-3/+28
|\ \ \ \ \ | | | | | | | | | | | | SI-8210 Scaladoc: Fix the false negative @inheritdoc warning on accessors
| * | | | | SI-8210 Scaladoc: Fix the false negative @inheritdoc warning on accessorsKato Kazuyoshi2015-05-273-3/+28
| |/ / / / | | | | | | | | | | | | | | | | | | | | This fix is just for the false negative warning. Probably we can skip setters entirely, but I'm not 100% sure.
* | | | | Merge pull request #4532 from kzys/9144-posix-211Lukas Rytz2015-05-281-0/+1
|\ \ \ \ \ | |/ / / / |/| | | | SI-9144 Scaladoc: Make generated HTML files POSIX-compatible text files
| * | | | SI-9144 Scaladoc: Make generated HTML files POSIX-compatible text filesKato Kazuyoshi2015-05-271-0/+1
|/ / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | According POSIX, every text file contains characters organized into zero or more lines [1], and every line must be terminated by "\n" [2]. This change makes Scaladoc's HTML files POSIX-compatible text files. [1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_397 [2] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206
* | | | Merge pull request #4524 from lrytz/BCodeDelambdafyFixesLukas Rytz2015-05-2716-75/+83
|\ \ \ \ | | | | | | | | | | Fix several tests under GenBCode
| * | | | Make two tests work under -Ydelambdafy:methodJason Zaugg2015-05-264-61/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Recently, in 029cce7, I changed uncurry to selectively fallback to the old method of emitting lambdas when we detect that `-Ydelambdafy:method`. The change in classfile names breaks the expectations of the test `innerClassAttribute`. This commit changes that test to avoid using specialized functions, so that under -Ydelambdafy:method all functions are uniform. This changes a few fresh suffixes for anonymous class names under both `-Ydelambdafy:{inline,method}`, so the expectations have been duly updated. Similarly, I have changed `javaReflection` in the same manner. Its checkfiles remained unchanged.
| * | | | Fix several tests under GenBCodeLukas Rytz2015-05-2612-14/+17
| | |/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - private-inline, t8601-closure-elim, inline-in-constructors - test closure inlining / elimination, which is not yet implemented in GenBCode. noted in https://github.com/scala-opt/scala/issues/14. - constant-optimization, t7006 - no constant folding in GenBCode yet. noted in https://github.com/scala-opt/scala/issues/29. - patmat_opt_ignore_underscore, patmat_opt_no_nullcheck, patmat_opt_primitive_typetest - not all optimizations in GenBCode yet. noted in https://github.com/scala-opt/scala/issues/30. - t3234 - tests a warning of trait inlining - trait inlining works in GenBCode - synchronized - ignore inliner warnings (they changed a bit) - t6102 - account for the changed outputo of -Ydebug has under GenBCode
* | | | Update README.mdAdriaan Moors2015-05-261-4/+10
| | | |
* | | | Merge pull request #4515 from sschaef/fix-grammar-errorJason Zaugg2015-05-261-1/+1
|\ \ \ \ | | | | | | | | | | Fix small grammar error in `Warnings`
| * | | | Fix small grammar error in `Warnings`Simon Schäfer2015-05-221-1/+1
| |/ / /
* | | | Merge pull request #4520 from xuwei-k/patch-1Jason Zaugg2015-05-261-1/+1
|\ \ \ \ | | | | | | | | | | fix typo
| * | | | fix typokenji yoshida2015-05-251-1/+1
| |/ / /
* | | | Merge pull request #4512 from retronym/ticket/9321Jason Zaugg2015-05-262-4/+13
|\ \ \ \ | |/ / / |/| | | SI-9321 Clarify spec for inheritance of qualified private
| * | | SI-9321 Clarify spec for inheritance of qualified privateJason Zaugg2015-05-222-4/+13
| |/ / | | | | | | | | | | | | | | | | | | | | | | | | I checked the intent with Martin, who said: > [...] qualified private members are inherited like other members, > it’s just that their access is restricted. I've locked this in with a test as well.
* | | Merge pull request #4513 from retronym/topic/indylambda-bump-compatLukas Rytz2015-05-221-1/+1
|\ \ \ | | | | | | | | Update to scala-java8-compat 0.5.0
| * | | Update to scala-java8-compat 0.5.0Jason Zaugg2015-05-221-1/+1
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This contains LambdaDeserializer, which we refer to in our synthetic `$deserializeLambda$` method under -target:jvm-1.8. Note: this library is only reference in the Ant build under a non-standard build flag that includes that library into scala-library.jar. This is only for our internal use in running partest for indylambda. The SBT build doesn't have the same option at the moment.
* | | Merge pull request #4477 from retronym/ticket/9286Adriaan Moors2015-05-217-2/+54
|\ \ \ | | | | | | | | SI-9286 Check subclass privates for "same type after erasure"
| * | | SI-9286 Check subclass privates for "same type after erasure"Jason Zaugg2015-05-187-2/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The overriding pairs cursor used to detect erased signature clashes was turning a blind eye to any pair that contained a private method. However, this could lead to a `VerifyError` or `IllegalAccessError`. Checking against javac's behaviour in both directions: ``` % cat sandbox/Test.java public abstract class Test { class C { int foo() { return 0; } } class D extends C { private <A> int foo() { return 1; } } } % javac sandbox/Test.java sandbox/Test.java:3: error: name clash: <A>foo() in Test.D and foo() in Test.C have the same erasure, yet neither overrides the other class D extends C { private <A> int foo() { return 1; } } ^ where A is a type-variable: A extends Object declared in method <A>foo() 1 error ``` ``` % cat sandbox/Test.java public abstract class Test { class C { private int foo() { return 0; } } class D extends C { <A> int foo() { return 1; } } } % javac sandbox/Test.java % ``` This commit only the exludes private symbols from the superclass from the checks by moving the test from `excludes` to `matches`.
* | | | Merge pull request #4501 from retronym/topic/indylambda-serializationAdriaan Moors2015-05-2111-22/+179
|\ \ \ \ | |_|/ / |/| | | [indylambda] Support lambda {de}serialization
| * | | [indylambda] Enable caching for lambda deserializationJason Zaugg2015-05-186-8/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We add a static field to each class that defines lambdas that will hold a `ju.Map[String, MethodHandle]` to cache references to the constructors of the classes originally created by `LambdaMetafactory`. The cache is initially null, and created on the first deserialization. In case of a race between two threads deserializing the first lambda hosted by a class, the last one to finish will clobber the one-element cache of the first. This lack of strong guarantees mirrors the current policy in `LambdaDeserializer`. We should consider whether to strengthen the combinaed guarantee here. A useful benchmark would be those of the invokedynamic instruction, which allows multiple threads to call the boostrap method in parallel, but guarantees that if that happens, the results of all but one will be discarded: > If several threads simultaneously execute the bootstrap method for > the same dynamic call site, the Java Virtual Machine must choose > one returned call site object and install it visibly to all threads. We could meet this guarantee easily, albeit excessively, by synchronizing `$deserializeLambda$`. But a more fine grained approach is possible and desirable. A test is included that shows we are able to garbage collect classloaders of classes that have hosted lambda deserialization.
| * | | [indylambda] Support lambda {de}serializationJason Zaugg2015-05-179-22/+105
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To support serialization, we use the alternative lambda metafactory that lets us specify that our anonymous functions should extend the marker interface `scala.Serializable`. They will also have a `writeObject` method added that implements the serialization proxy pattern using `j.l.invoke.SerializedLamba`. To support deserialization, we synthesize a `$deserializeLamba$` method in each class with lambdas. This will be called reflectively by `SerializedLambda#readResolve`. This method in turn delegates to `LambdaDeserializer`, currently defined [1] in `scala-java8-compat`, that uses `LambdaMetafactory` to spin up the anonymous class and instantiate it with the deserialized environment. Note: `LambdaDeserializer` can reuses the anonymous class on subsequent deserializations of a given lambda, in the same spirit as an invokedynamic call site only spins up the class on the first time it is run. But first we'll need to host a cache in a static field of each lambda hosting class. This is noted as a TODO and a failing test, and will be updated in the next commit. `LambdaDeserializer` will be moved into our standard library in the 2.12.x branch, where we can introduce dependencies on the Java 8 standard library. The enclosed test cases must be manually run with indylambda enabled. Once we enable indylambda by default on 2.12.x, the test will actually test the new feature. ``` % echo $INDYLAMBDA -Ydelambdafy:method -Ybackend:GenBCode -target:jvm-1.8 -classpath .:scala-java8-compat_2.11-0.5.0-SNAPSHOT.jar % qscala $INDYLAMBDA -e "println((() => 42).getClass)" class Main$$anon$1$$Lambda$1/1183231938 % qscala $INDYLAMBDA -e "assert(classOf[scala.Serializable].isInstance(() => 42))" % qscalac $INDYLAMBDA test/files/run/lambda-serialization.scala && qscala $INDYLAMBDA Test ``` This commit contains a few minor refactorings to the code that generates the invokedynamic instruction to use more meaningful names and to reuse Java signature generation code in ASM rather than the DIY approach. [1] https://github.com/scala/scala-java8-compat/pull/37
* | | | Merge pull request #4508 from retronym/topic/uncurry-specializedLukas Rytz2015-05-201-1/+1
|\ \ \ \ | | | | | | | | | | Avoid inefficient specialied lambdas w. delambdafy jvm-1.8, GenASM
| * | | | Avoid inefficient specialied lambdas w. delambdafy jvm-1.8, GenASMJason Zaugg2015-05-201-1/+1
| | |/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A previous change disabled -Ydelambdafy:method for specialized lambdas, as `DelambdafyTransformer` made no attempt to emit the requisite machinery to avoid boxing. This was loosened to allow them under `-target:jvm-1.8`, in the knowledge that `indylambda` would do the right thing. However, this wasn't quite right: indylambda is only supported in `GenBCode`, so we should consider that setting as well.
* | | | Merge pull request #4509 from retronym/topic/manLukas Rytz2015-05-201-2/+3
|\ \ \ \ | | | | | | | | | | Document -target:jvm-1.8 in the man page