forked from scala/scala
-
Notifications
You must be signed in to change notification settings - Fork 1
ci scripts backport to 2.11.4 #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Owner
Author
|
ping |
Owner
Author
|
a |
8 similar comments
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
5 similar comments
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
Owner
Author
|
a |
cunei
pushed a commit
to cunei/scala
that referenced
this pull request
May 19, 2015
In Scala 2.8.2, an optimization was added to create a static
cache for Symbol literals (ie, the results of `Symbol.apply("foo"))`.
This saves the map lookup on the second pass through code.
This actually was broken somewhere during the Scala 2.10 series,
after the addition of an overloaded `apply` method to `Symbol`.
The cache synthesis code was made aware of the overload and brought
back to working condition recently, in scala#3149.
However, this has uncovered a latent bug when the Symbol literals are
defined with traits.
One of the enclosed tests failed with:
jvm > t8933b-run.log
java.lang.IllegalAccessError: tried to access field MotherClass.symbol$1 from class MixinWithSymbol$class
at MixinWithSymbol$class.symbolFromTrait(A.scala:3)
at MotherClass.symbolFromTrait(Test.scala:1)
This commit simply disables the optimization if we are in a trait.
Alternative fixes might be: a) make the static Symbol cache field
public / b) "mixin" the static symbol cache. Neither of these
seem worth the effort and risk for an already fairly situational
optimization.
Here's how the optimization looks in a class:
% cat sandbox/test.scala; qscalac sandbox/test.scala && echo ":javap C" | qscala;
class C {
'a; 'b
}
Welcome to Scala version 2.11.5-20141106-145558-aa558dce6d (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_20).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :javap C
Size 722 bytes
MD5 checksum 6bb00189166917254e8d40499ee7c887
Compiled from "test.scala"
public class C
{
public static {};
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=0, args_size=0
0: getstatic adriaanm#16 // Field scala/Symbol$.MODULE$:Lscala/Symbol$;
3: ldc adriaanm#18 // String a
5: invokevirtual adriaanm#22 // Method scala/Symbol$.apply:(Ljava/lang/String;)Lscala/Symbol;
8: putstatic adriaanm#26 // Field symbol$1:Lscala/Symbol;
11: getstatic adriaanm#16 // Field scala/Symbol$.MODULE$:Lscala/Symbol$;
14: ldc scala#28 // String b
16: invokevirtual adriaanm#22 // Method scala/Symbol$.apply:(Ljava/lang/String;)Lscala/Symbol;
19: putstatic scala#31 // Field symbol$2:Lscala/Symbol;
22: return
public C();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial scala#34 // Method java/lang/Object."<init>":()V
4: getstatic adriaanm#26 // Field symbol$1:Lscala/Symbol;
7: pop
8: getstatic scala#31 // Field symbol$2:Lscala/Symbol;
11: pop
12: return
}
fixup
adriaanm
pushed a commit
that referenced
this pull request
Aug 3, 2015
And do the same for the specialized variants.
Tested by a Java source file that uses lambda syntax to create
instances of generic and specialized `Function{0,1}`.
Here's how the interfaces look now:
```
% javap -c -classpath /tmp/function 'scala.Function1'
Compiled from "Function1.scala"
public interface scala.Function1<T1, R> {
public abstract R apply(T1);
public <A> scala.Function1<A, R> compose(scala.Function1<A, T1>);
Code:
0: aload_0
1: aload_1
2: invokestatic #18 // Method scala/Function1$class.compose:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
5: areturn
public <A> scala.Function1<T1, A> andThen(scala.Function1<R, A>);
Code:
0: aload_0
1: aload_1
2: invokestatic #24 // Method scala/Function1$class.andThen:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
5: areturn
public abstract java.lang.String toString();
public int apply$mcII$sp(int);
Code:
0: aload_0
1: iload_1
2: invokestatic scala#110 // Method scala/Function1$class.apply$mcII$sp:(Lscala/Function1;I)I
5: ireturn
public long apply$mcJI$sp(int);
Code:
0: aload_0
1: iload_1
2: invokestatic scala#115 // Method scala/Function1$class.apply$mcJI$sp:(Lscala/Function1;I)J
5: lreturn
...
}
% javap -c -classpath /tmp/function 'scala.Function1$mcII$sp'
Compiled from "Function1.scala"
public interface scala.Function1$mcII$sp extends scala.Function1<java.lang.Object, java.lang.Object> {
public java.lang.Object apply(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokestatic #16 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
5: invokeinterface #19, 2 // InterfaceMethod apply:(I)I
10: invokestatic #23 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: areturn
public abstract int apply$mcII$sp(int);
public int apply(int);
Code:
0: aload_0
1: iload_1
2: invokeinterface scala#30, 2 // InterfaceMethod apply$mcII$sp:(I)I
7: ireturn
}
```
adriaanm
pushed a commit
that referenced
this pull request
Aug 8, 2015
And do the same for the specialized variants.
Tested by a Java source file that uses lambda syntax to create
instances of generic and specialized `Function{0,1}`.
Here's how the interfaces look now:
```
% javap -c -classpath /tmp/function 'scala.Function1'
Compiled from "Function1.scala"
public interface scala.Function1<T1, R> {
public abstract R apply(T1);
public <A> scala.Function1<A, R> compose(scala.Function1<A, T1>);
Code:
0: aload_0
1: aload_1
2: invokestatic #18 // Method scala/Function1$class.compose:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
5: areturn
public <A> scala.Function1<T1, A> andThen(scala.Function1<R, A>);
Code:
0: aload_0
1: aload_1
2: invokestatic #24 // Method scala/Function1$class.andThen:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
5: areturn
public abstract java.lang.String toString();
public int apply$mcII$sp(int);
Code:
0: aload_0
1: iload_1
2: invokestatic scala#110 // Method scala/Function1$class.apply$mcII$sp:(Lscala/Function1;I)I
5: ireturn
public long apply$mcJI$sp(int);
Code:
0: aload_0
1: iload_1
2: invokestatic scala#115 // Method scala/Function1$class.apply$mcJI$sp:(Lscala/Function1;I)J
5: lreturn
...
}
% javap -c -classpath /tmp/function 'scala.Function1$mcII$sp'
Compiled from "Function1.scala"
public interface scala.Function1$mcII$sp extends scala.Function1<java.lang.Object, java.lang.Object> {
public java.lang.Object apply(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokestatic #16 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
5: invokeinterface #19, 2 // InterfaceMethod apply:(I)I
10: invokestatic #23 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: areturn
public abstract int apply$mcII$sp(int);
public int apply(int);
Code:
0: aload_0
1: iload_1
2: invokeinterface scala#30, 2 // InterfaceMethod apply$mcII$sp:(I)I
7: ireturn
}
```
adriaanm
pushed a commit
that referenced
this pull request
Sep 2, 2015
And do the same for the specialized variants.
Tested by a Java source file that uses lambda syntax to create
instances of generic and specialized `Function{0,1}`.
Here's how the interfaces look now:
```
% javap -c -classpath /tmp/function 'scala.Function1'
Compiled from "Function1.scala"
public interface scala.Function1<T1, R> {
public abstract R apply(T1);
public <A> scala.Function1<A, R> compose(scala.Function1<A, T1>);
Code:
0: aload_0
1: aload_1
2: invokestatic #18 // Method scala/Function1$class.compose:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
5: areturn
public <A> scala.Function1<T1, A> andThen(scala.Function1<R, A>);
Code:
0: aload_0
1: aload_1
2: invokestatic #24 // Method scala/Function1$class.andThen:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
5: areturn
public abstract java.lang.String toString();
public int apply$mcII$sp(int);
Code:
0: aload_0
1: iload_1
2: invokestatic scala#110 // Method scala/Function1$class.apply$mcII$sp:(Lscala/Function1;I)I
5: ireturn
public long apply$mcJI$sp(int);
Code:
0: aload_0
1: iload_1
2: invokestatic scala#115 // Method scala/Function1$class.apply$mcJI$sp:(Lscala/Function1;I)J
5: lreturn
...
}
% javap -c -classpath /tmp/function 'scala.Function1$mcII$sp'
Compiled from "Function1.scala"
public interface scala.Function1$mcII$sp extends scala.Function1<java.lang.Object, java.lang.Object> {
public java.lang.Object apply(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokestatic #16 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
5: invokeinterface #19, 2 // InterfaceMethod apply:(I)I
10: invokestatic #23 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: areturn
public abstract int apply$mcII$sp(int);
public int apply(int);
Code:
0: aload_0
1: iload_1
2: invokeinterface scala#30, 2 // InterfaceMethod apply$mcII$sp:(I)I
7: ireturn
}
```
adriaanm
pushed a commit
that referenced
this pull request
Mar 30, 2016
Rather than in implementation of the abstract method in the
expanded anonymous class.
This leads to more more efficient use of the constant pool,
code shapes more amenable to SAM inlining, and is compatible
with the old behaviour of `-Xexperimental` in Scala 2.11,
which ScalaJS now relies upon.
Manual test:
```
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package p1; trait T { val x = 0; def apply(): Any }; class DelambdafyInline { def t: T = (() => "") }
// Exiting paste mode, now interpreting.
scala> :javap -c p1.DelambdafyInline
Compiled from "<pastie>"
public class p1.DelambdafyInline {
public p1.T t();
Code:
0: new #10 // class p1/DelambdafyInline$$anonfun$t$1
3: dup
4: aload_0
5: invokespecial #16 // Method p1/DelambdafyInline$$anonfun$t$1."<init>":(Lp1/DelambdafyInline;)V
8: areturn
public final java.lang.Object p1$DelambdafyInline$$$anonfun$1();
Code:
0: ldc #22 // String
2: areturn
public p1.DelambdafyInline();
Code:
0: aload_0
1: invokespecial #25 // Method java/lang/Object."<init>":()V
4: return
}
scala> :javap -c p1.DelambdafyInline$$anonfun$t$1
Compiled from "<pastie>"
public final class p1.DelambdafyInline$$anonfun$t$1 implements p1.T,scala.Serializable {
public static final long serialVersionUID;
public int x();
Code:
0: aload_0
1: getfield #25 // Field x:I
4: ireturn
public void p1$T$_setter_$x_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #25 // Field x:I
5: return
public final java.lang.Object apply();
Code:
0: aload_0
1: getfield scala#34 // Field $outer:Lp1/DelambdafyInline;
4: invokevirtual scala#37 // Method p1/DelambdafyInline.p1$DelambdafyInline$$$anonfun$1:()Ljava/lang/Object;
7: areturn
public p1.DelambdafyInline$$anonfun$t$1(p1.DelambdafyInline);
Code:
0: aload_1
1: ifnonnull 6
4: aconst_null
5: athrow
6: aload_0
7: aload_1
8: putfield scala#34 // Field $outer:Lp1/DelambdafyInline;
11: aload_0
12: invokespecial scala#42 // Method java/lang/Object."<init>":()V
15: aload_0
16: invokespecial scala#45 // Method p1/T.$init$:()V
19: return
}
scala> :quit
```
adriaanm
pushed a commit
that referenced
this pull request
Mar 30, 2016
Rather than in implementation of the abstract method in the
expanded anonymous class.
This leads to more more efficient use of the constant pool,
code shapes more amenable to SAM inlining, and is compatible
with the old behaviour of `-Xexperimental` in Scala 2.11,
which ScalaJS now relies upon.
Manual test:
```
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package p1; trait T { val x = 0; def apply(): Any }; class DelambdafyInline { def t: T = (() => "") }
// Exiting paste mode, now interpreting.
scala> :javap -c p1.DelambdafyInline
Compiled from "<pastie>"
public class p1.DelambdafyInline {
public p1.T t();
Code:
0: new #10 // class p1/DelambdafyInline$$anonfun$t$1
3: dup
4: aload_0
5: invokespecial #16 // Method p1/DelambdafyInline$$anonfun$t$1."<init>":(Lp1/DelambdafyInline;)V
8: areturn
public final java.lang.Object p1$DelambdafyInline$$$anonfun$1();
Code:
0: ldc #22 // String
2: areturn
public p1.DelambdafyInline();
Code:
0: aload_0
1: invokespecial #25 // Method java/lang/Object."<init>":()V
4: return
}
scala> :javap -c p1.DelambdafyInline$$anonfun$t$1
Compiled from "<pastie>"
public final class p1.DelambdafyInline$$anonfun$t$1 implements p1.T,scala.Serializable {
public static final long serialVersionUID;
public int x();
Code:
0: aload_0
1: getfield #25 // Field x:I
4: ireturn
public void p1$T$_setter_$x_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #25 // Field x:I
5: return
public final java.lang.Object apply();
Code:
0: aload_0
1: getfield scala#34 // Field $outer:Lp1/DelambdafyInline;
4: invokevirtual scala#37 // Method p1/DelambdafyInline.p1$DelambdafyInline$$$anonfun$1:()Ljava/lang/Object;
7: areturn
public p1.DelambdafyInline$$anonfun$t$1(p1.DelambdafyInline);
Code:
0: aload_1
1: ifnonnull 6
4: aconst_null
5: athrow
6: aload_0
7: aload_1
8: putfield scala#34 // Field $outer:Lp1/DelambdafyInline;
11: aload_0
12: invokespecial scala#42 // Method java/lang/Object."<init>":()V
15: aload_0
16: invokespecial scala#45 // Method p1/T.$init$:()V
19: return
}
scala> :quit
```
Adriaan is to `git blame` for `reflection-mem-typecheck.scala`.
adriaanm
pushed a commit
that referenced
this pull request
Aug 19, 2016
- Avoid boxing the {Object, Int, ...}Ref itself by storing it in
a val, not a var
- Avoid box/unbox of primitive lazy expressions due which are added
to "adapt" it to the erased type of the fictional syncronized
method, by using a `return`. We have to add a dummy throw after
the synchronized block, but this is elimnated by the always-on
DCE in the code generator.
```
⚡ qscalac -Xprint:mixin $(f "class C { def foo = { lazy val x = 42; x }}"); javap -private -c -cp . C
[[syntax trees at end of mixin]] // a.scala
package <empty> {
class C extends Object {
def foo(): Int = {
lazy <artifact> val x$lzy: scala.runtime.LazyInt = new scala.runtime.LazyInt();
C.this.x$1(x$lzy)
};
final private[this] def x$1(x$lzy$1: scala.runtime.LazyInt): Int = {
x$lzy$1.synchronized({
if (x$lzy$1.initialized().unary_!())
{
x$lzy$1.initialized_=(true);
x$lzy$1.value_=(42)
};
return x$lzy$1.value()
});
throw null
};
def <init>(): C = {
C.super.<init>();
()
}
}
}
Compiled from "a.scala"
public class C {
public int foo();
Code:
0: new #12 // class scala/runtime/LazyInt
3: dup
4: invokespecial #16 // Method scala/runtime/LazyInt."<init>":()V
7: astore_1
8: aload_1
9: invokestatic #20 // Method x$1:(Lscala/runtime/LazyInt;)I
12: ireturn
private static final int x$1(scala.runtime.LazyInt);
Code:
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: invokevirtual scala#31 // Method scala/runtime/LazyInt.initialized:()Z
8: ifne 22
11: aload_0
12: iconst_1
13: invokevirtual scala#35 // Method scala/runtime/LazyInt.initialized_$eq:(Z)V
16: aload_0
17: bipush 42
19: invokevirtual scala#39 // Method scala/runtime/LazyInt.value_$eq:(I)V
22: aload_0
23: invokevirtual scala#42 // Method scala/runtime/LazyInt.value:()I
26: istore_2
27: goto 33
30: aload_1
31: monitorexit
32: athrow
33: aload_1
34: monitorexit
35: iload_2
36: ireturn
Exception table:
from to target type
4 30 30 Class java/lang/Throwable
public C();
Code:
0: aload_0
1: invokespecial scala#43 // Method java/lang/Object."<init>":()V
4: return
}
```
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.