Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Scala Under the Hood / ScalaSwarm

Slides of my talk "Scala Under the Hood" at ScalaSwarm 2017
https://www.scala-swarm.org

  • Identifiez-vous pour voir les commentaires

Scala Under the Hood / ScalaSwarm

  1. 1. SCALA UNDER THE HOOD TZOFIA SHIFTAN / OVEROPS
  2. 2. AGENDA 1. JVM 101 2. THE COOL STUFF
  3. 3. JVM 101
  4. 4. bytecode Noun Java bytecode is the instruction set of the Java virtual machine Wikipedia
  5. 5. JVM Example.classExample.scala scalac scala javap class file
  6. 6. javap
  7. 7. $ javap Example.class Compiled from "Example.scala" public class Example { public int b(); public int bar(int); public Example(); } javap
  8. 8. $ javap -p Example.class Compiled from "Example.scala" public class Example { private int a; private final int b; private int a(); private void a_$eq(int); public int b(); private void foo(); public int bar(int); public Example(); } javap
  9. 9. $ javap -c Example.class Compiled from "Example.scala" public class Example { public int b(); Code: 0: aload_0 1: getfield #21 // Field b:I 4: ireturn public int bar(int); Code: 0: iconst_3 1: iload_1 2: imul 3: ireturn ... javap
  10. 10. JVM THREADTHREAD THREAD STACK STACK STACK FRAME FRAME FRAME FRAME FRAME FRAME FRAME FRAME FRAME
  11. 11. FRAME OPERAND STACKLOCAL VARIABLES this 0 1 2
  12. 12. def add(a : Int, b : Int) = a+b iload_0 iload_1 iadd ireturn add(2,5) FRAME LOCAL VARIABLES OPERAND STACK a b 2 5
  13. 13. def add(a : Int, b : Int) = a+b iload_0 iload_1 iadd ireturn add(2,5) FRAME LOCAL VARIABLES OPERAND STACK a b 2 5 2
  14. 14. def add(a : Int, b : Int) = a+b iload_0 iload_1 iadd ireturn add(2,5) FRAME LOCAL VARIABLES OPERAND STACK a b 2 5 2 5
  15. 15. def add(a : Int, b : Int) = a+b iload_0 iload_1 iadd ireturn add(2,5) FRAME LOCAL VARIABLES OPERAND STACK a b 2 5 7 2 5 7 + = 2 5
  16. 16. FRAME LOCAL VARIABLES OPERAND STACK a b 2 5 7 def add(a : Int, b : Int) = a+b iload_0 iload_1 iadd ireturn add(2,5)
  17. 17. THE COOL STUFF
  18. 18. val vs var vs def
  19. 19. val var def class Var { var a = 1 } class Val { val a = 1 } class Def { def a = 1 }
  20. 20. javap -p Var javap -p Val javap -p Def val var def
  21. 21. private final int a; public int a(); public Val(); private int a; public int a(); public void a_$eq(int); public Var(); public int a(); public Def(); val var def
  22. 22. private final int a; public int a(); public Val(); private int a; public int a(); public void a_$eq(int); public Var(); public int a(); public Def(); val var def
  23. 23. private final int a; public int a(); public Val(); private int a; public int a(); public void a_$eq(int); public Var(); public int a(); public Def(); val var def
  24. 24. private final int a; public int a(); public Val(); private int a; public int a(); public void a_$eq(int); public Var(); public int a(); public Def(); val var def
  25. 25. public int a(); aload_0 getfield #13 // Field a:I ireturn public int a(); iconst_1 ireturn return this.a return 1 val var def
  26. 26. private final int a; public int a(); public Val(); private int a; public int a(); public void a_$eq(int); public Var(); public int a(); public Def(); val var def
  27. 27. public void a_$eq(int); aload_0 iload_1 putfield #13 // Field a:I return this.a = a val var def
  28. 28. private final int a; public int a(); public Val(); private int a; public int a(); public void a_$eq(int); public Var(); public int a(); public Def(); val var def
  29. 29. public Va[r|l](); aload_0 invokespecial #19 // Method java/lang/Object."<init>":()V aload_0 iconst_1 putfield #13 // Field a:I return public Def(); aload_0 invokespecial #16 // Method java/lang/Object."<init>":()V return val var def this.a = 1 return
  30. 30. getter setter evaluation val 1 var 1 def multiple
  31. 31. lazy val
  32. 32. val lazy val class Val { val a = 1 } class LazyVal { lazy val a = 1 }
  33. 33. javap -p Val javap -p LazyVal val lazy val
  34. 34. private final int a; public Val(); public int a(); private int a; public LazyVal(); private volatile boolean bitmap$0; private int a$lzycompute(); public int a(); val lazy val
  35. 35. private final int a; public Val(); public int a(); private int a; public LazyVal(); private volatile boolean bitmap$0; private int a$lzycompute(); public int a(); val lazy val
  36. 36. private final int a; public Val(); public int a(); private int a; public LazyVal(); private volatile boolean bitmap$0; private int a$lzycompute(); public int a(); val lazy val
  37. 37. public Val(); aload_0 invokespecial #19 // Method java/lang/Object."<init>":()V aload_0 iconst_1 putfield #13 // Field a:I return public LazyVal(); aload_0 Invokespecial #28 // Method java/lang/Object."<init>":()V return super() val lazy val
  38. 38. private final int a; public Val(); public int a(); private int a; public LazyVal(); private volatile boolean bitmap$0; private int a$lzycompute(); public int a(); val lazy val
  39. 39. private int a$lzycompute(); 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: getfield #16 // Field bitmap$0:Z 8: ifne 21 11: aload_0 12: iconst_1 13: putfield #18 // Field a:I 16: aload_0 17: iconst_1 18: putfield #16 // Field bitmap$0:Z 21: aload_1 22: monitorexit 23: goto 29 26: aload_1 27: monitorexit 28: athrow 29: aload_0 30: getfield #18 // Field a:I 33: ireturn
  40. 40. private int a$lzycompute(); 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: getfield #16 // Field bitmap$0:Z 8: ifne 21 11: aload_0 12: iconst_1 13: putfield #18 // Field a:I 16: aload_0 17: iconst_1 18: putfield #16 // Field bitmap$0:Z 21: aload_1 22: monitorexit 23: goto 29 26: aload_1 27: monitorexit 28: athrow 29: aload_0 30: getfield #18 // Field a:I 33: ireturn synchronize start
  41. 41. private int a$lzycompute(); 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: getfield #16 // Field bitmap$0:Z 8: ifne 21 11: aload_0 12: iconst_1 13: putfield #18 // Field a:I 16: aload_0 17: iconst_1 18: putfield #16 // Field bitmap$0:Z 21: aload_1 22: monitorexit 23: goto 29 26: aload_1 27: monitorexit 28: athrow 29: aload_0 30: getfield #18 // Field a:I 33: ireturn bitmap$0 ? 0
  42. 42. private int a$lzycompute(); 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: getfield #16 // Field bitmap$0:Z 8: ifne 21 11: aload_0 12: iconst_1 13: putfield #18 // Field a:I 16: aload_0 17: iconst_1 18: putfield #16 // Field bitmap$0:Z 21: aload_1 22: monitorexit 23: goto 29 26: aload_1 27: monitorexit 28: athrow 29: aload_0 30: getfield #18 // Field a:I 33: ireturn this.a = 1 this.bitmap$0 = 1 synchronize end return this.a bitmap$0 == 0
  43. 43. private int a$lzycompute(); 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: getfield #16 // Field bitmap$0:Z 8: ifne 21 11: aload_0 12: iconst_1 13: putfield #18 // Field a:I 16: aload_0 17: iconst_1 18: putfield #16 // Field bitmap$0:Z 21: aload_1 22: monitorexit 23: goto 29 26: aload_1 27: monitorexit 28: athrow 29: aload_0 30: getfield #18 // Field a:I 33: ireturn synchronize end return this.a bitmap$0 == 1
  44. 44. private int a$lzycompute() { LazyVal lazyVal = this; synchronized (lazyVal) { if (!this.bitmap$0) { this.a = 1; this.bitmap$0 = true; } } return this.a; }
  45. 45. private int a$lzycompute() { LazyVal lazyVal = this; synchronized (lazyVal) { if (!this.bitmap$0) { this.a = 1; this.bitmap$0 = true; } } return this.a; }
  46. 46. private int a$lzycompute() { LazyVal lazyVal = this; synchronized (lazyVal) { if (!this.bitmap$0) { this.a = 1; this.bitmap$0 = true; } } return this.a; }
  47. 47. private final int a; public Val(); public int a(); private int a; public LazyVal(); private volatile boolean bitmap$0; private int a$lzycompute(); public int a(); val lazy val
  48. 48. public int a(); 0: aload_0 1: getfield #16 // Field bitmap$0:Z 4: ifne 14 7: aload_0 8: invokespecial #24 // Method a$lzycompute:()I 11: goto 18 14: aload_0 15: getfield #18 // Field a:I 18: ireturn
  49. 49. public int a(); 0: aload_0 1: getfield #16 // Field bitmap$0:Z 4: ifne 14 7: aload_0 8: invokespecial #24 // Method a$lzycompute:()I 11: goto 18 14: aload_0 15: getfield #18 // Field a:I 18: ireturn bitmap$0 ? 0
  50. 50. public int a(); 0: aload_0 1: getfield #16 // Field bitmap$0:Z 4: ifne 14 7: aload_0 8: invokespecial #24 // Method a$lzycompute:()I 11: goto 18 14: aload_0 15: getfield #18 // Field a:I 18: ireturn this.a$lzycompute() return ^ bitmap$0 == 0
  51. 51. public int a(); 0: aload_0 1: getfield #16 // Field bitmap$0:Z 4: ifne 14 7: aload_0 8: invokespecial #24 // Method a$lzycompute:()I 11: goto 18 14: aload_0 15: getfield #18 // Field a:I 18: ireturn bitmap$0 == 1 return this.a
  52. 52. evaluation val c’tor lazy val lzycompute
  53. 53. object
  54. 54. object Hello { def main(args: Array[String]) { println("Hello, Scala Swarm!") } }
  55. 55. Hello.scala Hello.class Hello$.class scalac
  56. 56. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  57. 57. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  58. 58. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  59. 59. public static void main(java.lang.String[]); getstatic #16 // Field Hello$.MODULE$:LHello$; aload_0 invokevirtual #18 // Method Hello$.main:([Ljava/lang/String;)V return Hello$.MODULE$.main(args)
  60. 60. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  61. 61. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  62. 62. public static {}; new #2 // class Hello$ invokespecial #12 // Method "<init>":()V return new Hello$()
  63. 63. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  64. 64. private Hello$(); aload_0 invokespecial #29 // Method java/lang/Object."<init>":()V aload_0 putstatic #31 // Field MODULE$:LHello$; return MODULE$ = this
  65. 65. Compiled from "Hello.scala" public final class Hello { public static void main(java.lang.String[]); } Compiled from "Hello.scala" public final class Hello$ { public static Hello$ MODULE$; public static {}; private Hello$(); public void main(java.lang.String[]); }
  66. 66. public void main(java.lang.String[]); getstatic #20 // Field scala/Predef$.MODULE$:Lscala/Predef$; ldc #22 // String Hello, Scala Swarm! invokevirtual #26 // Method scala/Predef$.println:(Ljava/lang/Object;)V return println(“Hello, Scala Swarm!”)
  67. 67. public final class Hello$ { public static Hello$ MODULE$; public static { new Hello$(); } private Hello$() { MODULE$ = this; } public void main(String[] args) { println("Hello, Scala Swarm!"); } } public final class Hello { public static void main(final String[] args) { Hello$.MODULE$.main(args); } }
  68. 68. public final class Hello$ { public static Hello$ MODULE$; public static { new Hello$(); } private Hello$() { MODULE$ = this; } public void main(String[] args) { println("Hello, Scala Swarm!"); } } public final class Hello { public static void main(final String[] args) { Hello$.MODULE$.main(args); } }
  69. 69. public final class Hello$ { public static Hello$ MODULE$; public static { new Hello$(); } private Hello$() { MODULE$ = this; } public void main(String[] args) { println("Hello, Scala Swarm!"); } } public final class Hello { public static void main(final String[] args) { Hello$.MODULE$.main(args); } }
  70. 70. public final class Hello$ { public static Hello$ MODULE$; public static { new Hello$(); } private Hello$() { MODULE$ = this; } public void main(String[] args) { println("Hello, Scala Swarm!"); } } public final class Hello { public static void main(final String[] args) { Hello$.MODULE$.main(args); } }
  71. 71. public final class Hello$ { public static Hello$ MODULE$; public static { new Hello$(); } private Hello$() { MODULE$ = this; } public void main(String[] args) { println(“Hello, Scala Swarm!"); } } public final class Hello { public static void main(final String[] args) { Hello$.MODULE$.main(args); } }
  72. 72. public final class Hello$ { public static Hello$ MODULE$; public static { new Hello$(); } private Hello$() { MODULE$ = this; } public void main(String[] args) { println("Hello, Scala Swarm!"); } } public final class Hello { public static void main(final String[] args) { Hello$.MODULE$.main(args); } }
  73. 73. Hello, Scala Swarm!
  74. 74. SUMMARY Given a problem, consider the following steps: 1. javap 2. repeat
  75. 75. tzofia@overopshq.com @tzofias

×