Skip to content

Instantly share code, notes, and snippets.

@retronym
Created December 7, 2016 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save retronym/415c9109a37cd10a1657451281a9e129 to your computer and use it in GitHub Desktop.
Save retronym/415c9109a37cd10a1657451281a9e129 to your computer and use it in GitHub Desktop.
⚡ cat sandbox/test.scala; for i in "" -optimise; do (~/scala/2.11.8/bin/scalac $i sandbox/test.scala && javap -private -c -cp . Test && cfr-decompiler Test.class) 2>&1 | tee /tmp/log$i.txt; done; diff -U1000 /tmp/{log,log-optimise}.txt
class Test {
def test = {
lazy val foo = 42
def bar = foo
(foo, bar)
}
}
Compiled from "test.scala"
public class Test {
public scala.Tuple2<java.lang.Object, java.lang.Object> test();
Code:
0: invokestatic #16 // Method scala/runtime/IntRef.zero:()Lscala/runtime/IntRef;
3: astore_1
4: iconst_0
5: invokestatic #22 // Method scala/runtime/VolatileByteRef.create:(B)Lscala/runtime/VolatileByteRef;
8: astore_2
9: new #24 // class scala/Tuple2$mcII$sp
12: dup
13: aload_0
14: aload_1
15: aload_2
16: invokespecial #28 // Method foo$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
19: aload_0
20: aload_1
21: aload_2
22: invokespecial #31 // Method bar$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
25: invokespecial #35 // Method scala/Tuple2$mcII$sp."<init>":(II)V
28: areturn
private final int foo$lzycompute$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_0
1: dup
2: astore_3
3: monitorenter
4: aload_2
5: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
8: iconst_1
9: iand
10: i2b
11: iconst_0
12: if_icmpne 32
15: aload_1
16: bipush 42
18: putfield #49 // Field scala/runtime/IntRef.elem:I
21: aload_2
22: aload_2
23: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
26: iconst_1
27: ior
28: i2b
29: putfield #46 // Field scala/runtime/VolatileByteRef.elem:B
32: getstatic #55 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
35: pop
36: aload_3
37: monitorexit
38: aload_1
39: getfield #49 // Field scala/runtime/IntRef.elem:I
42: ireturn
43: aload_3
44: monitorexit
45: athrow
Exception table:
from to target type
4 38 43 any
private final int foo$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_2
1: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
4: iconst_1
5: iand
6: i2b
7: iconst_0
8: if_icmpne 20
11: aload_0
12: aload_1
13: aload_2
14: invokespecial #61 // Method foo$lzycompute$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
17: goto 24
20: aload_1
21: getfield #49 // Field scala/runtime/IntRef.elem:I
24: ireturn
private final int bar$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_0
1: aload_1
2: aload_2
3: invokespecial #28 // Method foo$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
6: ireturn
public Test();
Code:
0: aload_0
1: invokespecial #64 // Method java/lang/Object."<init>":()V
4: return
}
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* scala.Tuple2
* scala.Tuple2$mcII
* scala.Tuple2$mcII$sp
* scala.reflect.ScalaSignature
* scala.runtime.IntRef
* scala.runtime.VolatileByteRef
*/
import scala.Tuple2;
import scala.reflect.ScalaSignature;
import scala.runtime.IntRef;
import scala.runtime.VolatileByteRef;
@ScalaSignature(bytes="\u0006\u0001i1A!\u0001\u0002\u0001\u000b\t!A+Z:u\u0015\u0005\u0019\u0011a\u0002\u001ff[B$\u0018PP\u0002\u0001'\t\u0001a\u0001\u0005\u0002\b\u00155\t\u0001BC\u0001\n\u0003\u0015\u00198-\u00197b\u0013\tY\u0001B\u0001\u0004B]f\u0014VM\u001a\u0005\u0006\u001b\u0001!\tAD\u0001\u0007y%t\u0017\u000e\u001e \u0015\u0003=\u0001\"\u0001\u0005\u0001\u000e\u0003\tAQA\u0005\u0001\u0005\u0002M\tA\u0001^3tiV\tA\u0003\u0005\u0003\b+]9\u0012B\u0001\f\t\u0005\u0019!V\u000f\u001d7feA\u0011q\u0001G\u0005\u00033!\u00111!\u00138u\u0001")
public class Test {
public Tuple2<Object, Object> test() {
IntRef foo$lzy = IntRef.zero();
VolatileByteRef bitmap$0 = VolatileByteRef.create((byte)0);
return new Tuple2.mcII.sp(this.foo$1(foo$lzy, bitmap$0), this.bar$1(foo$lzy, bitmap$0));
}
private final int foo$lzycompute$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
Test test = this;
synchronized (test) {
if ((byte)(bitmap$0$1.elem & 1) == 0) {
foo$lzy$1.elem = 42;
bitmap$0$1.elem = (byte)(bitmap$0$1.elem | 1);
}
return foo$lzy$1.elem;
}
}
private final int foo$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
return (byte)(bitmap$0$1.elem & 1) == 0 ? this.foo$lzycompute$1(foo$lzy$1, bitmap$0$1) : foo$lzy$1.elem;
}
private final int bar$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
return this.foo$1(foo$lzy$1, bitmap$0$1);
}
}
Compiled from "test.scala"
public class Test {
public scala.Tuple2<java.lang.Object, java.lang.Object> test();
Code:
0: invokestatic #16 // Method scala/runtime/IntRef.zero:()Lscala/runtime/IntRef;
3: astore_1
4: iconst_0
5: invokestatic #22 // Method scala/runtime/VolatileByteRef.create:(B)Lscala/runtime/VolatileByteRef;
8: astore_2
9: new #24 // class scala/Tuple2$mcII$sp
12: dup
13: aload_0
14: aload_1
15: aload_2
16: invokespecial #28 // Method foo$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
19: aload_0
20: aload_1
21: aload_2
22: invokespecial #31 // Method bar$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
25: invokespecial #35 // Method scala/Tuple2$mcII$sp."<init>":(II)V
28: areturn
private final int foo$lzycompute$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_0
1: dup
2: astore_3
3: monitorenter
4: aload_2
5: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
8: iconst_1
9: iand
10: i2b
11: iconst_0
12: if_icmpne 32
15: aload_1
16: bipush 42
18: putfield #49 // Field scala/runtime/IntRef.elem:I
21: aload_2
22: aload_2
23: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
26: iconst_1
27: ior
28: i2b
29: putfield #46 // Field scala/runtime/VolatileByteRef.elem:B
32: getstatic #55 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
35: pop
36: aload_0
37: monitorexit
38: aload_1
39: getfield #49 // Field scala/runtime/IntRef.elem:I
42: ireturn
43: aload_3
44: monitorexit
45: athrow
Exception table:
from to target type
4 38 43 any
private final int foo$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_2
1: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
4: iconst_1
5: iand
6: i2b
7: iconst_0
8: if_icmpne 20
11: aload_0
12: aload_1
13: aload_2
14: invokespecial #61 // Method foo$lzycompute$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
17: goto 24
20: aload_1
21: getfield #49 // Field scala/runtime/IntRef.elem:I
24: ireturn
private final int bar$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_0
1: aload_1
2: aload_2
3: invokespecial #28 // Method foo$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
6: ireturn
public Test();
Code:
0: aload_0
1: invokespecial #64 // Method java/lang/Object."<init>":()V
4: return
}
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* scala.Tuple2
* scala.Tuple2$mcII
* scala.Tuple2$mcII$sp
* scala.reflect.ScalaSignature
* scala.runtime.IntRef
* scala.runtime.VolatileByteRef
*/
import scala.Tuple2;
import scala.reflect.ScalaSignature;
import scala.runtime.IntRef;
import scala.runtime.VolatileByteRef;
@ScalaSignature(bytes="\u0006\u0001i1A!\u0001\u0002\u0001\u000b\t!A+Z:u\u0015\u0005\u0019\u0011a\u0002\u001ff[B$\u0018PP\u0002\u0001'\t\u0001a\u0001\u0005\u0002\b\u00155\t\u0001BC\u0001\n\u0003\u0015\u00198-\u00197b\u0013\tY\u0001B\u0001\u0004B]f\u0014VM\u001a\u0005\u0006\u001b\u0001!\tAD\u0001\u0007y%t\u0017\u000e\u001e \u0015\u0003=\u0001\"\u0001\u0005\u0001\u000e\u0003\tAQA\u0005\u0001\u0005\u0002M\tA\u0001^3tiV\tA\u0003\u0005\u0003\b+]9\u0012B\u0001\f\t\u0005\u0019!V\u000f\u001d7feA\u0011q\u0001G\u0005\u00033!\u00111!\u00138u\u0001")
public class Test {
public Tuple2<Object, Object> test() {
IntRef foo$lzy = IntRef.zero();
VolatileByteRef bitmap$0 = VolatileByteRef.create((byte)0);
return new Tuple2.mcII.sp(this.foo$1(foo$lzy, bitmap$0), this.bar$1(foo$lzy, bitmap$0));
}
private final int foo$lzycompute$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
Test test = this;
synchronized (test) {
if ((byte)(bitmap$0$1.elem & 1) == 0) {
foo$lzy$1.elem = 42;
bitmap$0$1.elem = (byte)(bitmap$0$1.elem | 1);
}
// ** MonitorExit[this] (shouldn't be in output)
return foo$lzy$1.elem;
}
}
private final int foo$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
return (byte)(bitmap$0$1.elem & 1) == 0 ? this.foo$lzycompute$1(foo$lzy$1, bitmap$0$1) : foo$lzy$1.elem;
}
private final int bar$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
return this.foo$1(foo$lzy$1, bitmap$0$1);
}
}
--- /tmp/log.txt 2016-12-07 21:38:52.000000000 +1000
+++ /tmp/log-optimise.txt 2016-12-07 21:38:54.000000000 +1000
@@ -1,134 +1,135 @@
Compiled from "test.scala"
public class Test {
public scala.Tuple2<java.lang.Object, java.lang.Object> test();
Code:
0: invokestatic #16 // Method scala/runtime/IntRef.zero:()Lscala/runtime/IntRef;
3: astore_1
4: iconst_0
5: invokestatic #22 // Method scala/runtime/VolatileByteRef.create:(B)Lscala/runtime/VolatileByteRef;
8: astore_2
9: new #24 // class scala/Tuple2$mcII$sp
12: dup
13: aload_0
14: aload_1
15: aload_2
16: invokespecial #28 // Method foo$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
19: aload_0
20: aload_1
21: aload_2
22: invokespecial #31 // Method bar$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
25: invokespecial #35 // Method scala/Tuple2$mcII$sp."<init>":(II)V
28: areturn
private final int foo$lzycompute$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_0
1: dup
2: astore_3
3: monitorenter
4: aload_2
5: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
8: iconst_1
9: iand
10: i2b
11: iconst_0
12: if_icmpne 32
15: aload_1
16: bipush 42
18: putfield #49 // Field scala/runtime/IntRef.elem:I
21: aload_2
22: aload_2
23: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
26: iconst_1
27: ior
28: i2b
29: putfield #46 // Field scala/runtime/VolatileByteRef.elem:B
32: getstatic #55 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
35: pop
- 36: aload_3
+ 36: aload_0
37: monitorexit
38: aload_1
39: getfield #49 // Field scala/runtime/IntRef.elem:I
42: ireturn
43: aload_3
44: monitorexit
45: athrow
Exception table:
from to target type
4 38 43 any
private final int foo$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_2
1: getfield #46 // Field scala/runtime/VolatileByteRef.elem:B
4: iconst_1
5: iand
6: i2b
7: iconst_0
8: if_icmpne 20
11: aload_0
12: aload_1
13: aload_2
14: invokespecial #61 // Method foo$lzycompute$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
17: goto 24
20: aload_1
21: getfield #49 // Field scala/runtime/IntRef.elem:I
24: ireturn
private final int bar$1(scala.runtime.IntRef, scala.runtime.VolatileByteRef);
Code:
0: aload_0
1: aload_1
2: aload_2
3: invokespecial #28 // Method foo$1:(Lscala/runtime/IntRef;Lscala/runtime/VolatileByteRef;)I
6: ireturn
public Test();
Code:
0: aload_0
1: invokespecial #64 // Method java/lang/Object."<init>":()V
4: return
}
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* scala.Tuple2
* scala.Tuple2$mcII
* scala.Tuple2$mcII$sp
* scala.reflect.ScalaSignature
* scala.runtime.IntRef
* scala.runtime.VolatileByteRef
*/
import scala.Tuple2;
import scala.reflect.ScalaSignature;
import scala.runtime.IntRef;
import scala.runtime.VolatileByteRef;
@ScalaSignature(bytes="\u0006\u0001i1A!\u0001\u0002\u0001\u000b\t!A+Z:u\u0015\u0005\u0019\u0011a\u0002\u001ff[B$\u0018PP\u0002\u0001'\t\u0001a\u0001\u0005\u0002\b\u00155\t\u0001BC\u0001\n\u0003\u0015\u00198-\u00197b\u0013\tY\u0001B\u0001\u0004B]f\u0014VM\u001a\u0005\u0006\u001b\u0001!\tAD\u0001\u0007y%t\u0017\u000e\u001e \u0015\u0003=\u0001\"\u0001\u0005\u0001\u000e\u0003\tAQA\u0005\u0001\u0005\u0002M\tA\u0001^3tiV\tA\u0003\u0005\u0003\b+]9\u0012B\u0001\f\t\u0005\u0019!V\u000f\u001d7feA\u0011q\u0001G\u0005\u00033!\u00111!\u00138u\u0001")
public class Test {
public Tuple2<Object, Object> test() {
IntRef foo$lzy = IntRef.zero();
VolatileByteRef bitmap$0 = VolatileByteRef.create((byte)0);
return new Tuple2.mcII.sp(this.foo$1(foo$lzy, bitmap$0), this.bar$1(foo$lzy, bitmap$0));
}
private final int foo$lzycompute$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
Test test = this;
synchronized (test) {
if ((byte)(bitmap$0$1.elem & 1) == 0) {
foo$lzy$1.elem = 42;
bitmap$0$1.elem = (byte)(bitmap$0$1.elem | 1);
}
+ // ** MonitorExit[this] (shouldn't be in output)
return foo$lzy$1.elem;
}
}
private final int foo$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
return (byte)(bitmap$0$1.elem & 1) == 0 ? this.foo$lzycompute$1(foo$lzy$1, bitmap$0$1) : foo$lzy$1.elem;
}
private final int bar$1(IntRef foo$lzy$1, VolatileByteRef bitmap$0$1) {
return this.foo$1(foo$lzy$1, bitmap$0$1);
}
}
/code/scala on ticket/9264*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment