Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dive into JVM JIT Compiler

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Dive into JVM JIT Compiler

Explained what is happening in the JITCompiler of the JVM called HotSpotVM by looking at a compiled assembly.

Avatar for Ikuo Suyama

Ikuo Suyama

August 10, 2022
Tweet

More Decks by Ikuo Suyama

Other Decks in Programming

Transcript

  1. ΠϯλϓϦλͱίϯύΠϥ 'JCKBWB package jit; public class Fib { public static

    void main(String[] args) { int i = Integer.valueOf(args[0]); System.out.println(fib(i)); } private static int fib(int i) { if (i <= 0) { return 0; } else if (i == 1) { return 1; } else { return (fib(i - 1) + fib(i - 2)); } } } ❯ javac Fib.java ❯ javap -v -p -s -constants Fib.class > Fib.jvm private static int fib(int); descriptor: (I)I flags: (0x000a) ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn 'JCKWN fi CϝιουͷΈൈਮ ΈΜͳେ޷͖ϑΟϘφον਺Λ ࠶ؼͰܭࢉ͢ΔΫϥε +7.Ϛγϯޠ͸ΠϯλϓϦλʢஞ࣮࣍ߦʣݴޠ
  2. ΠϯλϓϦλͱίϯύΠϥ 'JCKBWB package jit; public class Fib { public static

    void main(String[] args) { int i = Integer.valueOf(args[0]); System.out.println(fib(i)); } private static int fib(int i) { if (i <= 0) { return 0; } else if (i == 1) { return 1; } else { return (fib(i - 1) + fib(i - 2)); } } } ❯ javac Fib.java ❯ javap -v -p -s -constants Fib.class > Fib.jvm private static int fib(int); descriptor: (I)I flags: (0x000a) ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn 'JCKWN fi CϝιουͷΈൈਮ ͜Μͳײ͡Ͱͨ͠Ͷʁ +7.Ϛγϯޠ͸ΠϯλϓϦλʢஞ࣮࣍ߦʣݴޠ
  3. ΠϯλϓϦλͱίϯύΠϥ private static int fib(int); descriptor: (I)I flags: (0x000a) ACC_PRIVATE,

    ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn +7.Ϛγϯޠ͸ΠϯλϓϦλʢஞ࣮࣍ߦʣݴޠ
  4. ΠϯλϓϦλͱίϯύΠϥ private static int fib(int); descriptor: (I)I flags: (0x000a) ACC_PRIVATE,

    ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn +7.Ϛγϯޠ͸ΠϯλϓϦλʢஞ࣮࣍ߦʣݴޠ iload_0 = 26 (0x1a) iconst_1 = 4 (0x4) isub = 100 (0x64) invokestatic = 184 (0xb8) indexbyte1 indexbyte2 KBWBD͸͜ͷΑ͏ʹɺ ॻ͍ͯ͋Δ͜ͱΛجຊͦͷ··+7.ΠϯετϥΫγϣϯʹ༁͠ɺ +7.͸͜ΕΛ্͔Βஞ࣮࣍ߦ͢Δ
  5. ΠϯλϓϦλͱίϯύΠϥ ύϑΥʔϚϯε͸Ͳ͏͔ʁ 9JOUʜJOUFSQSJUFSϞʔυͷΈͰ࣮ߦ .BDCPPL1SPJODI()DPSFJ ͰTdNJOɻ஗͍ʁ ❯ time java -Xint jit.Fib

    48 512559680 ________________________________________________________ Executed in 847.43 secs fish external usr time 844.04 secs 119.00 micros 844.04 secs sys time 1.79 secs 898.00 micros 1.79 secs
  6. ΠϯλϓϦλͱίϯύΠϥ ݟͤͯ΋Β͏͔ɺ+*5ίϯύΠϥ͕ੜ੒͢ΔΞηϯϒϦͱ΍ΒΛ ❯ sudo wget https://raw.githubusercontent.com/a10y/hsdis-macos/master/hsdis-amd64.dylib \ $JAVA_HOME/lib/server/ ❯ java

    \ -XX:+UnlockDiagnosticVMOptions \ -XX:-PrintAssembly \ -XX:+PrintInterpreter \ jit.Fib 10 > Fib.fib.int.print ˞όΠφϦͷग़ྗʹ͸ITEJT͕ඞཁɻ ITEJTBNEEZMJC GPS*OUFM.BD Λ+"7"@)0.&MJCʹೖΕ͓ͯ͘
  7. ΠϯλϓϦλͱίϯύΠϥ ݟͤͯ΋Β͏͔ɺ+*5ίϯύΠϥ͕ੜ੒͢ΔΞηϯϒϦͱ΍ΒΛ ---------------------------------------------------------------------- iload_0 26 iload_0 [0x0000000124986bc0, 0x0000000124986c20] 96 bytes

    0x0000000124986bc0: push %rax 0x0000000124986bc1: jmpq 0x0000000124986bff 0x0000000124986bc6: sub $0x8,%rsp 0x0000000124986bca: vmovss %xmm0,(%rsp) 0x0000000124986bcf: jmpq 0x0000000124986bff 0x0000000124986bd4: sub $0x10,%rsp 0x0000000124986bd8: vmovsd %xmm0,(%rsp) 0x0000000124986bdd: jmpq 0x0000000124986bff 0x0000000124986be2: sub $0x10,%rsp 0x0000000124986be6: mov %rax,(%rsp) 0x0000000124986bea: movabs $0x0,%r10 0x0000000124986bf4: mov %r10,0x8(%rsp) 0x0000000124986bf9: jmpq 0x0000000124986bff 0x0000000124986bfe: push %rax 0x0000000124986bff: mov (%r14),%eax 0x0000000124986c02: movzbl 0x1(%r13),%ebx 0x0000000124986c07: inc %r13 0x0000000124986c0a: movabs $0x1151d5220,%r10 0x0000000124986c14: jmpq *(%r10,%rbx,8) 0x0000000124986c18: add %al,(%rax) 0x0000000124986c1a: add %al,(%rax) 0x0000000124986c1c: add %al,(%rax) 0x0000000124986c1e: add %al,(%rax) private static int fib(int); descriptor: (I)I flags: (0x000a) ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn ͔ͨ͠ʹɺ֤ΠϯετϥΫγϣϯͷ όΠφϦεχϖοτ͕ੜ੒͞Ε͍ͯΔʂ
  8. +7.+*5$PNQJMFS +*5$PNQJMFSΛ0Oʹͯ͠ɺ࠶౓'JCΛ࣮ߦͯ͠ΈΔ ❯ time java jit.Fib 48 : ________________________________________________________ Executed

    in 19.04 secs fish external usr time 18.93 secs 111.00 micros 18.93 secs sys time 0.11 secs 811.00 micros 0.11 secs ❯ time java -Xint jit.Fib 48 512559680 ________________________________________________________ Executed in 847.43 secs fish external usr time 844.04 secs 119.00 micros 844.04 secs sys time 1.79 secs 898.00 micros 1.79 secs TT໿ഒͷߴ଎Խ
  9. +7.+*5$PNQJMFS ❯ time java -XX:+PrintCompilation jit.Fib 48 38 1 3

    java.lang.StringLatin1::hashCode (42 bytes) 39 2 3 java.util.concurrent.ConcurrentHashMap::tabAt (22 bytes) 39 4 n 0 jdk.internal.misc.Unsafe::getObjectVolatile (native) : 70 89 3 jit.Fib::fib (27 bytes) 71 90 4 jit.Fib::fib (27 bytes) 72 89 3 jit.Fib::fib (27 bytes) made not entrant ίϯύΠϧͷ༷ࢠΛ೷͍ͯΈΔ99 1SJOU$PNQJMBUJPO Format: $1: $2 $3 $4 $5 ($6 bytes) $7 —— $1: JavaϝιουͷίϯύΠϧཁٻൃੜ࣌ؒ(ϩάग़ྗ࣌ͷ࣌ؒ) $2: ௨͠൪߸ $3: ۭന·ͨ͸ϝιουͷίϯύΠϧछผ $4:ۭന·ͨ͸ϝιουͷίϯύΠϧϨϕϧ $5: Javaϝιου໊ $6: JavaϝιουͷόΠτ਺·ͨ͸(native) $7: ۭന·ͨ͸(static)·ͨ͸ made not entrant fi Cϝιου͕ෳ਺ճίϯύΠϧ͞Ε͍ͯΔ
  10. )PU4QPU7. DMJFOUDPNQJMFS $ TFSWFSDPNQJMFS $  +7. ͸΍ͨΒΊͬͨΒͦ͜Β͡Ύ͏ΛίϯύΠϧ͢ΔΘ͚Ͱ͸ͳ͍  ਖ਼֬ʹ͸Ͱ͖ͳ͍ʜ+*5ɺͭ·ΓΦϯϥΠϯͰίϯύΠϧΛ͍ͯ͠Δʂ

     ద੾ͳՕॴΛɺద੾ͳλΠϛϯάΛݟܭΒͬͯίϯύΠϧ͍ͯ͠Δ  ׂͷ࣌ؒ͸ɺׂͷίʔυ͔Β͘Δ  ద੾ͳՕॴʁ  Α࣮͘ߦ͞ΕΔ৔ॴŠ)PU4QPU  ద੾ͳλΠϛϯάʁ  ͭͷίϯύΠϥ ಛఆͷ࣮૷ͷɻ)PU4QPUͰͳ͍+7.΋ଘࡏ͢Δ
  11. )PU4QPU7. DMJFOUDPNQJMFS $ TFSWFSDPNQJMFS $ $MJFOU$PNQJMFS $-FWFM 4FSWFS$PNQJMFS $-FWFM ϝιουΛ͢͹΍͘ίϯύΠϧ͠·͕͢ɺαʔόʔɾίϯύ

    Πϥ΄Ͳ͸࠷దԽ͞Εͳ͍ϚγϯɾίʔυΛੜ੒͠·͢ɻ ͜ͷίϯύΠϥΛ࢖༻͢Δͱɺਝ଎ʹىಈ͠·͢ɻ ·ͨɺ͜ͷίϯύΠϥͰ͸ɺগͳ͍ϝϞϦʔɾϑοτϓϦϯ τ͕ఆৗύϑΥʔϚϯεΑΓॏཁͰ͢ɻ ͜ͷίϯύΠϥ͸ɺಉ͡ϝιουͷίϯύΠϧʹΑΓଟ͘ͷ ͕͔͔࣌ؒΓ·͢ ͓ΑͼΑΓଟ͘ͷϝϞϦʔΛফඅ͠·͢ ɻ ͨͩ͠ɺΫϥΠΞϯτɾίϯύΠϥͰੜ੒ͨ͠ίʔυΑΓ࠷ దԽ͞ΕͨϚγϯɾίʔυΛੜ੒͠·͢ɻ ΞϓϦέʔγϣϯ͕ఆৗʹୡͨ͠ޙ͸ɺ࣮ߦ࣌ύϑΥʔϚϯ ε͕޲্͠·͢ɻ ŠίϯύΠϧ࠷దԽ0SBDMF w ίϯύΠϧ͕ૣ͍ɺ͍ܰʢ$16.&.ʣ w ੑೳ͸ͦͦ͜͜ w ࢖͍ॴ w ϥΠϑλΠϜ͕୹͍ʢ$MJFOU"QQMJDBUJPOʣ w "QQMJDBUJPO#PPUTUSBQ w ίϯύΠϧ͕௕͍ɺॏ͍ w ੑೳ͸όϦόϦ w ࢖͍ॴ w ϥΠϑλΠϜ͕௕͍ʢ4FSWFS"QQMJDBUJPOʣ w "GUFS#PPUTUSBQ
  12. +7.+*5$PNQJMFS τϨʔυΦϑͱ֊૚ίϯύΠϧ ❯ java -XX:+PrintCompilation jit.Fib 48 38 1 3

    java.lang.StringLatin1::hashCode (42 bytes) 39 2 3 java.util.concurrent.ConcurrentHashMap::tabAt (22 bytes) 39 4 n 0 jdk.internal.misc.Unsafe::getObjectVolatile (native) 39 3 3 jdk.internal.misc.Unsafe::getObjectAcquire (7 bytes) 40 5 3 java.lang.Object::<init> (1 bytes) 40 6 3 java.lang.String::isLatin1 (19 bytes) 40 7 3 java.lang.String::hashCode (49 bytes) 41 8 3 java.lang.String::coder (15 bytes) 41 9 3 java.lang.Math::floorMod (10 bytes) 41 10 3 java.lang.Math::floorDiv (22 bytes) 41 11 3 java.util.ImmutableCollections$SetN::probe (56 bytes) 42 12 3 java.lang.String::equals (65 bytes) 42 13 3 java.lang.StringLatin1::equals (36 bytes) 42 14 3 java.util.ImmutableCollections$SetN::hashCode (46 bytes) 43 15 3 java.util.Objects::equals (23 bytes) 43 16 3 java.util.ImmutableCollections::emptySet (4 bytes) 43 17 3 java.util.Set::of (4 bytes) 43 18 3 java.lang.module.ModuleDescriptor$Exports::<init> (20 bytes) 43 20 4 java.lang.StringLatin1::hashCode (42 bytes) : 70 89 3 jit.Fib::fib (27 bytes) 71 90 4 jit.Fib::fib (27 bytes) 72 89 3 jit.Fib::fib (27 bytes) made not entrant Ұ౓ΫϥΠΞϯτίϯύΠϧ ʢ-FWFMʣ͞Εͨޙɺαʔόʔί ϯύΠϧ͞Ε௚ͨ͠ʢ-FWFMʣ ΫϥΠΞϯτίϯύΠϧΛܦͯαʔ όʔίϯύΠϧ͞Ε͕ͨɺԿΒ͔ͷ ཧ༝Ͱ-ʹϑΥʔϧόοΫ͞Εͨ
  13. +7.+*5$PNQJMFS $MJFOU$PNQJMFͷόΠφϦ private static int fib(int); descriptor: (I)I flags: (0x000a)

    ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn 'JCKWN fi CϝιουͷΈൈਮ 'JC fi CDMJFOUQSJOU 0x000000011da82860: mov %eax,-0x14000(%rsp) 0x000000011da82867: push %rbp 0x000000011da82868: sub $0x60,%rsp 0x000000011da8286c: movabs $0x10b2cf5c0,%rdi 0x000000011da82876: mov 0x18(%rdi),%ebx 0x000000011da82879: add $0x8,%ebx 0x000000011da8287c: mov %ebx,0x18(%rdi) 0x000000011da8287f: and $0x3ff8,%ebx 0x000000011da82885: cmp $0x0,%ebx 0x000000011da82888: je 0x000000011da829af ;*iload_0 {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@0 (line 10) 0x000000011da8288e: cmp $0x0,%esi 0x000000011da82891: jle 0x000000011da8299a ;*ifgt {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@1 (line 10) 0x000000011da82897: cmp $0x1,%esi 0x000000011da8289a: je 0x000000011da82985 ;*if_icmpne {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@8 (line 12) 0x000000011da828a0: mov %rsi,%rdi 0x000000011da828a3: dec %edi 0x000000011da828a5: cmp $0x0,%edi 0x000000011da828a8: jg 0x000000011da828b8 ;*ifgt {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@1 (line 10) ; - jit.Fib::fib@16 (line 15) : 0x000000011da829af: movabs $0x10b2cf418,%r10 ; {metadata({method} {0x000000010b2cf418} 'fib' '(I)I' in 'jit/Fib')} 0x000000011da829b9: mov %r10,0x8(%rsp) 0x000000011da829be: movq $0xffffffffffffffff,(%rsp) 0x000000011da829c6: callq 0x000000011cfba400 ; ImmutableOopMap{} ;*synchronization entry ; - jit.Fib::fib@-1 (line 10) ; {runtime_call counter_overflow Runtime1 stub} ❯ java -XX:TieredStopAtLevel=2 \ -XX:+UnlockDiagnosticVMOptions \ '-XX:CompileCommand=print,*Fib.fib' \ jit.Fib 48 > ./jit/Fib.client.PrintAssembly
  14. +7.+*5$PNQJMFS $MJFOU$PNQJMFͷόΠφϦ private static int fib(int); descriptor: (I)I flags: (0x000a)

    ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn 'JCKWN fi CϝιουͷΈൈਮ 0x000000011da82860: mov %eax,-0x14000(%rsp) 0x000000011da82867: push %rbp 0x000000011da82868: sub $0x60,%rsp 0x000000011da8286c: movabs $0x10b2cf5c0,%rdi 0x000000011da82876: mov 0x18(%rdi),%ebx 0x000000011da82879: add $0x8,%ebx 0x000000011da8287c: mov %ebx,0x18(%rdi) 0x000000011da8287f: and $0x3ff8,%ebx 0x000000011da82885: cmp $0x0,%ebx 0x000000011da82888: je 0x000000011da829af ;*iload_0 {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@0 (line 10) 0x000000011da8288e: cmp $0x0,%esi 0x000000011da82891: jle 0x000000011da8299a ;*ifgt {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@1 (line 10) 0x000000011da82897: cmp $0x1,%esi 0x000000011da8289a: je 0x000000011da82985 ;*if_icmpne {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@8 (line 12) 0x000000011da828a0: mov %rsi,%rdi 0x000000011da828a3: dec %edi 0x000000011da828a5: cmp $0x0,%edi 0x000000011da828a8: jg 0x000000011da828b8 ;*ifgt {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@1 (line 10) ; - jit.Fib::fib@16 (line 15) : 0x000000011da829af: movabs $0x10b2cf418,%r10 ; {metadata({method} {0x000000010b2cf418} 'fib' '(I)I' in 'jit/Fib')} 0x000000011da829b9: mov %r10,0x8(%rsp) 0x000000011da829be: movq $0xffffffffffffffff,(%rsp) 0x000000011da829c6: callq 0x000000011cfba400 ; ImmutableOopMap{} ;*synchronization entry ; - jit.Fib::fib@-1 (line 10) ; {runtime_call counter_overflow Runtime1 stub} 'JC fi CDMJFOUQSJOU ͥΜͥΜΘ͔Βͳ͍ʂʂʂʂ ❯ java -XX:TieredStopAtLevel=2 \ -XX:+UnlockDiagnosticVMOptions \ '-XX:CompileCommand=print,*Fib.fib' \ jit.Fib 48 > ./jit/Fib.client.PrintAssembly
  15. +7.+*5$PNQJMFS 4FSWFS$PNQJMFͷόΠφϦ private static int fib(int); descriptor: (I)I flags: (0x000a)

    ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn 'JCKWN fi CϝιουͷΈൈਮ 'JC fi CTFSWFSQSJOU : 0x0000000115519ead: jmp 0x0000000115519e8f ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@16 (line 15) ; - jit.Fib::fib@16 (line 15) 0x0000000115519eaf: mov %rax,%rsi 0x0000000115519eb2: jmp 0x0000000115519ec1 ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@22 (line 15) ; - jit.Fib::fib@16 (line 15) 0x0000000115519eb4: mov %rax,%rsi 0x0000000115519eb7: jmp 0x0000000115519ec1 ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@16 (line 15) ; - jit.Fib::fib@22 (line 15) 0x0000000115519eb9: mov %rax,%rsi 0x0000000115519ebc: jmp 0x0000000115519ec1 ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@22 (line 15) ; - jit.Fib::fib@22 (line 15) 0x0000000115519ebe: mov %rax,%rsi ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@22 (line 15) ; - jit.Fib::fib@16 (line 15) 0x0000000115519ec1: add $0x20,%rsp 0x0000000115519ec5: pop %rbp 0x0000000115519ec6: jmpq 0x0000000115516500 ; {runtime_call _rethrow_Java} ❯ java -XX:-TieredCompilation \ -XX:+UnlockDiagnosticVMOptions \ '-XX:CompileCommand=print,*Fib.fib' \ jit.Fib 48 > ./jit/Fib.client.PrintAssembly
  16. +7.+*5$PNQJMFS 4FSWFS$PNQJMFͷόΠφϦ private static int fib(int); descriptor: (I)I flags: (0x000a)

    ACC_PRIVATE, ACC_STATIC Code: stack=3, locals=1, args_size=1 0: iload_0 1: ifgt 6 4: iconst_0 5: ireturn 6: iload_0 7: iconst_1 8: if_icmpne 13 11: iconst_1 12: ireturn 13: iload_0 14: iconst_1 15: isub 16: invokestatic #5 // Method fib:(I)I 19: iload_0 20: iconst_2 21: isub 22: invokestatic #5 // Method fib:(I)I 25: iadd 26: ireturn 'JCKWN fi CϝιουͷΈൈਮ 'JC fi CTFSWFSQSJOU : 0x0000000115519ead: jmp 0x0000000115519e8f ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@16 (line 15) ; - jit.Fib::fib@16 (line 15) 0x0000000115519eaf: mov %rax,%rsi 0x0000000115519eb2: jmp 0x0000000115519ec1 ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@22 (line 15) ; - jit.Fib::fib@16 (line 15) 0x0000000115519eb4: mov %rax,%rsi 0x0000000115519eb7: jmp 0x0000000115519ec1 ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@16 (line 15) ; - jit.Fib::fib@22 (line 15) 0x0000000115519eb9: mov %rax,%rsi 0x0000000115519ebc: jmp 0x0000000115519ec1 ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@22 (line 15) ; - jit.Fib::fib@22 (line 15) 0x0000000115519ebe: mov %rax,%rsi ;*invokestatic fib {reexecute=0 rethrow=0 return_oop=0} ; - jit.Fib::fib@22 (line 15) ; - jit.Fib::fib@16 (line 15) 0x0000000115519ec1: add $0x20,%rsp 0x0000000115519ec5: pop %rbp 0x0000000115519ec6: jmpq 0x0000000115516500 ; {runtime_call _rethrow_Java} NFUIPEDBMM͕DBMMRͯ͠ͳ͍ɻ *OMJOFԽ͞Ε͍ͯΔʜͷ͔ʁʁ ❯ java -XX:-TieredCompilation \ -XX:+UnlockDiagnosticVMOptions \ '-XX:CompileCommand=print,*Fib.fib' \ jit.Fib 48 > ./jit/Fib.client.PrintAssembly
  17. (PJOH%FFQFSʜ )PXUP6TF+*58BUDI # download and build, launch ❯ git clone

    [email protected]:AdoptOpenJDK/jitwatch.git ❯ cd jitwatch/ ❯ ./gradlew clean build run # log compilation ❯ java \ -XX:+UnlockDiagnosticVMOptions \ -XX:+TraceClassLoading \ -XX:+LogCompilation \ -XX:+PrintAssembly \ -XX:+DebugNonSafepoints \ jit.Fib 48 $PO fi HͰର৅ͷTSDDMBTTΛࢦఆ Ͱग़ྗ͞ΕΔIPUTQPU@QJEYYYYMPHΛ0QFO
  18. +*58BUDI $PNQJMFS5ISFBE"DUJWJUZ  2VFVFʹ௥Ճ͞Ε͔ͯΒɺ&NNJU͞ΕΔ·ͰͷλΠϜϥά  ͔͔ͬͨ࣌ؒ  #ZUFDPEF4J[F ɾίϯύΠϧର৅ʹͳͬͨλΠϛϯάͰ 2VFVFʹ௥Ճ͞Εɺ%FRVFVF͞ΕͯίϯύΠ

    ϧ͕׬ྃͨ࣌͠఺Ͱ&NNJU͞ΕΔ ɾଟ͘ͷ৔߹$͸NTҎԼɺ$͸NTΦʔμʔ ʹ+*5ίϯύΠϧ͸ΞϓϦέʔγϣϯʹӨڹΛ ٴ΅͢ఔ౓ͷ$16࣌ؒΛ࢖͏ ɾͨͩ͠+*5ίϯύΠϥ͸ΞϓϦέʔγϣϯε Ϩουͱ͸ผͷεϨουΛ࢖͏ͨΊɺ࣮ߦ࣌ ؒͦͷ΋ͷ΁ͷӨڹ͸େ͖͘ͳ͍
  19. 5JQT8BSNVQCZ%FFQ1JOH  ݟ͖ͯͨͱ͓Γɺ+*5ίϯύΠϧ͸͕͔͔ͦͦ࣌ؒ͜͜Δ  NTΦʔμʔ  αʔόʔΞϓϦέʔγϣϯ͸ΦϯϥΠϯʹ౤ೖ͢ΔલʹɺΤϯυϙΠϯτΛԿ ౓͔ୟ͍ͯ΍Δ͜ͱͰ౤ೖ࣌ͷੑೳྼԽΛܰݮͰ͖Δ  ଞʹ΋$MBTT-PBE΍*OWPLF%ZOBNJD౳ɺॳճʹ͕͔͔࣌ؒΔέʔε͸ଟ͍

     ͨͩ͠ɺ4FSWFS$PNQJMFͷͨΊͷΩϡʔ౤ೖᮢ஋͸σϑΥϧτͰ ճ  ͦΕͰ΋$MJFOU$PNQJMFSʹΑΔ࠷దԽ͸ظ଴Ͱ͖Δ  99$PNQJMF5ISFTIPMEͰࢦఆՄೳ͕ͩɺখ͗͘͢͞͠Δͱ)PU4QPUͷࢫຯ ͕ͳ͘ͳΔ  ίϯύΠϧࣗମʹ΋ίετ͕͔͔ΔࣄΛ๨Εͣʹ
  20. 5JQT#JOBSZTJ[F +7.+*5DPNQJMFSPWFSWJFX  +*5$PNQJMFSͷ࠷దԽ͸਺ଟ͍͕ɺॏཁͳҰͭʹΠϯϥΠϯ Խ͕͋Δ  *OWPLF999ʹΑΔϝιου࣮ߦ͸جຊతʹίετ͕ߴ͍  Ϋϥε֊૚Λ௥ͬͯϝιουΛಛఆ͠ɺ'SBNFΛ৽ ͨʹ࡞੒ͯ͠0QFSBOE4UBDLͱ-PDBM7BSΛ४උ͢Δ

     ͜ΕΛආ͚ΔͨΊɺݺͼग़͞ΕΔϝιουΛ֘౰Օॴʹ ల։ͯ͠͠·͏ͷ͕ΠϯϥΠϯԽ  99 6OMPDL%JBHOPTUJD7.0QUJPOT99 1SJOU*OMJOJOHͰ *OMJOFԽ͞ΕͨϝιουͷৄࡉΛ֬ೝͰ͖Δ  ΠϯϥΠϯԽ͞ΕΔͨΊͷ৚݅ͱͯ͠ɺόΠφϦαΠζʹ্ ݶ͕ઃ͚ΒΕ͍ͯΔ
  21. 5JQT#JOBSZTJ[F  ΠϯϥΠϯԽͰ͖ΔϝιουॲཧͷόΠφϦαΠζʹ͸੍ݶ͕͋Δ  .BY*OMJOF4J[F͸.JO*OMJOJOH5ISFTIPME %FQSFDBUFE!KBWB Λ௒͑ͳ͍ϝιουͷ੍ݶ  'SFR*OMJOF4J[F͸.JO*OMJOJOH5ISFTIPMEΛ௒͑Δճ਺࣮ߦ͞Εͨ.FUIPEʹదԠ͞ΕΔ 

    ͜ͷαΠζΛ௒͑Δϝιου͸ɺ.JO*OMJOJOH5ISFTIPMEΛ௒͑ͯ΋ΠϯϥΠϯԽ͞Εͳ͍ IPUNFUIPEUPPCJH   )PU4QPU+*5JOMJOJOHTUSBUFHZUPQEPXOPSEPXOUPQ  ͸JOTUSVDUJPOͷαΠζͳͷͰɺߦ਺ʹ͢Δͱߦະຬ͘Β͍  ฏۉCZUFJOTUSVDUJPO JOTUSVDUJPOMJOFͱԾఆͯ͠dMJOFT  େ͖͍ϝιου͸ύϑΥʔϚϯεͷ؍఺͔Β΋Ϋι ཁ͢Δʹ௕͍ϝιου͸Ϋι 99.BY*OMJOF4J[FTJ[F *OUFHFSTQFDJGZJOHNBYJNVNOVNCFSPGCZUFDPEF JOTUSVDUJPOTJOBNFUIPEXIJDIHFUTJOMJOFE EFGBVMU 99'SFR*OMJOF4J[FTJ[F *OUFHFSTQFDJGZJOHNBYJNVNOVNCFSPGCZUFDPEF JOTUSVDUJPOTJOBGSFRVFOUMZFYFDVUFENFUIPE XIJDIHFUTJOMJOFE EFGBVMU %FQFOETPO&OW PO*OUFM.BD Š+BWB)PU4QPU&RVJWBMFOUTPG&YBDU7.'MBHT
  22. 5JQT#JOBSZTJ[F  +*58BUDIʹ෇ਵ͢Δɺ+*5ίϯύΠϥͷ؍఺͔ΒKBSϑΝΠϧͷதͷϚζ͍࣮૷Λநग़ͯ͘͠Ε Δπʔϧ  NBY.FUIPE4J[FΦϓγϣϯͰΠϯετϥΫγϣϯ͕UISFBTIPMEҎ্ͷϝιουΛநग़Ͱ͖Δ  (SBEMFCVJMEͰ͸ͦͷ··ಈ͔ͳ͍ͷͰNWOͰϏϧυ͢Δ͔εΫϦϓτΛॻ͖׵͑Δඞཁ ͋Γ ཁ͢Δʹ௕͍ϝιου͸Ϋι

    +*58BUDIFS+BS4DBO ❯ cd jitwatch/script ❯ ./jarScan.sh --mode=maxMethodSize --limit=325 ./core/build/libs/core.jar "org.adoptopenjdk.jitwatch.model.bytecode","BytecodeAnnotationBuilder","buildParseTagAnnotations","org.adoptopenjdk.jitwatch.mode l.Tag,org.adoptopenjdk.jitwatch.model.bytecode.BytecodeAnnotations,org.adoptopenjdk.jitwatch.model.IParseDictionary",1314 “org.adoptopenjdk.jitwatch.hotthrow","HotThrowFinder","visitTag","org.adoptopenjdk.jitwatch.model.Tag,org.adoptopenjdk.jitwatch.m odel.IParseDictionary",700 :
  23. 5JQT1PMZNPSQIJTN +*58BUDIFS4BOE#PY public class PolymorphismTest { public interface Coin {

    void deposit();} public static int moneyBox = 0; public class Nickel implements Coin { public void deposit() { moneyBox += 5; }} public class Dime implements Coin { public void deposit() { moneyBox += 10; }} public class Quarter implements Coin { public void deposit() { moneyBox += 25; }} public PolymorphismTest() { Coin nickel = new Nickel(); Coin dime = new Dime(); Coin quarter = new Quarter(); Coin coin = null; // change the variable maxImplementations to control the inlining behaviour // 2 = bimorphic dispatch - the method call will be inlined // 3 = megamorphic dispatch - the method call will not be inlined final int maxImplementations = 2; for (int i = 0; i < 1_000_000; i++) { switch (i % maxImplementations) { case 0: coin = nickel; break; case 1: coin = dime; break; case 2: coin = quarter; break; } coin.deposit(); } System.out.println("moneyBox:" + moneyBox); } public static void main(String[] args) { new PolymorphismTest(); } } 1PMZNPSQIJTN5FTUKBWB  $PJO*OUFSGBDFʹͭͷ࣮૷Λ ΋ͭ؆қͳςετΫϥε  NBY*NQMFNFOUBUJPOTͰར༻ ͢Δ࣮૷ΫϥεΛ੍ޚ͍ͯ͠Δ
  24. 5JQT1PMZNPSQIJTN NBY*NQMFNFOUBUJPOT 0x000000011b27197c: mov 0xb8(%rsi),%r9d ;*getstatic moneyBox {reexecute=0 rethrow=0 return_oop=0}

    ; - PolymorphismTest$Nickel::deposit@0 (line 5) ; - PolymorphismTest::<init>@93 (line 32) 0x000000011b271983: mov %r9d,%r11d 0x000000011b271986: sub %r10d,%r11d 0x000000011b271989: add $0x5,%r9d 0x000000011b27198d: mov %r9d,0xb8(%rsi) ;*iload {reexecute=0 rethrow=0 return_oop=0} ; - PolymorphismTest::<init>@40 (line 22) 0x000000011b271994: add %ebx,%edi 0x000000011b271996: add %r11d,%edi 0x000000011b271999: mov %edi,%r9d 0x000000011b27199c: add $0xa,%r9d ;*iadd {reexecute=0 rethrow=0 return_oop=0} ; - PolymorphismTest$Nickel::deposit@4 (line 5)  - $ ͰϝιουࣗମɺϝιουίʔϧͲͪΒ΋ ΠϯϥΠϯԽ͞Εͨ
  25. 5JQT1PMZNPSQIJTN NBY*NQMFNFOUBUJPOT 0x000000011d7fd837: cmp %rsi,%rcx 0x000000011d7fd83a: jne 0x000000011d7fd872 ;*invokeinterface deposit

    {reexecute=0 rethrow=0 return_oop=0} ; - PolymorphismTest::<init>@93 (line 32) 0x000000011d7fd83c: add $0x5,%r11d : 0x000000011d7fd872: cmp %rax,%rcx 0x000000011d7fd875: jne 0x000000011d7fda1b ;*invokeinterface deposit {reexecute=0 rethrow=0 return_oop=0} ; - PolymorphismTest::<init>@93 (line 32) 0x000000011d7fd87b: add $0xa,%r11d  ΠϯϥΠϯԽ͞Ε͍ͯΔ  ࣮૷͝ͱʹ࣮ߦઌ੍͕ޚ͞Ε͍ͯͦ͏
  26. 5JQT1PMZNPSQIJTN NBY*NQMFNFOUBUJPOT  %FQPTJUϝιουͷத਎͸ΠϯϥΠϯԽ ͞Ε͕ͨɺJOWPLFJOUFSGBDF͸ΠϯϥΠ ϯԽ͞Εͳ͍ʢDBMMRʹΑΔؔ਺ίʔϧʣ 0x0000000121a7180f: mov 0x18(%rsp),%rsi 0x0000000121a71814:

    nop 0x0000000121a71815: movabs $0xffffffffffffffff,%rax 0x0000000121a7181f: callq 0x0000000119ef1c00 ; ImmutableOopMap{[0]=Oop [8]=Oop [16]=Oop [24]=Oop } ;*invokeinterface deposit {reexecute=0 rethrow=0 return_oop=0} ; - PolymorphismTest::<init>@93 (line 32) ; {virtual_call} 0x0000000121a71824: inc %ebp ;*iinc {reexecute=0 rethrow=0 return_oop=0}
  27. 4VN6Q  8IBUJT+*5$PNQJMFS  w %PCJOBSZMFWFMPQUJNJ[BUJPO $PNQJMF +VTU*O5JNF w )PU4QPU7.

     %JWFJOUP+7.+*5$PNQJMFS w $MJFOU4FSWFS$PNQJMFS w 5JFSFE$PNQJMBUJPO w +*58BUDIUPEFFQEJWF  1FSGPSNBODF5JQT w %FFQQJOHXBSNVQ w 5BLF$BSFPG#JOBSZ4J[F w 5BLF$BSFPG1PMZNPSQIJTN
  28. 3FGFSFODFT w +*5ίϯύΠϥͷ࣮ࡍͷಈ࡞+BWB.BHB[JOF w *OUSPEVDUJPOUP+*5$PNQJMBUJPOJO+BWB)PU4QPU7. w 6OEFSTUBOEJOH+BWB+*5$PNQJMBUJPOXJUI+*58BUDI 1BSU w +*58BUDIʹΑΔ+BWB+*5ίϯύΠϧͷௐࠪ+BWB.BHB[JOF

    w +7.+*5DPNQJMFSPWFSWJFX w 0QFO+%,1SJOU"TTFNCMZ w +*58BUDI w )PU4QPUQSP fi MJOHXJUI+*58BUDI w +BWB)PU4QPU&RVJWBMFOUTPG&YBDU7.'MBHT w 3FBEJOHBTTFNCMZGSPNUIF+7. w 1SJOU"TTFNCMZPVUQVUFYQMBJOFE