SlideShare a Scribd company logo
JVM for Dummies
                            (and for the rest of you, as well)




Wednesday, July 27, 2011
Intro
                    •      Charles Oliver Nutter
                           •   “JRuby Guy”
                           •   Sun Microsystems 2006-2009
                           •   Engine Yard 2009-
                    •      Primarily responsible for compiler, perf
                           •   Lots of bytecode generation
                           •   Lots of JIT monitoring


Wednesday, July 27, 2011
Today
                    •      JVM Bytecode
                           •   Inspection
                           •   Generation
                           •   How it works
                    •      JVM JIT
                           •   How it works
                           •   Monitoring
                           •   Assembly (don’t be scared!)


Wednesday, July 27, 2011
Today
                    •      JVM Bytecode
                           •
                           •
                           •
                               Inspection
                               Generation      }   For Dummies




                                               }
                               How it works
                    •      JVM JIT
                           •   How it works        For people who want
                           •   Monitoring          to feel like Dummies
                           •   Assembly


Wednesday, July 27, 2011
Part One:
                           Bytecode


Wednesday, July 27, 2011
Bytecode Definition

                    • “... instruction sets designed for efficient
                           execution by a software interpreter ...”
                    • “... suitable for further compilation into
                           machine code.




Wednesday, July 27, 2011
Byte Code

                    • One-byte instructions
                    • 256 possible “opcodes”
                    • 200 in use on current JVMs
                     • Room for more :-)
                    • Little variation since Java 1.0

Wednesday, July 27, 2011
Microsoft’s CLR

                    • Stack-based, but not interpreted
                    • Two-byte “Wordcodes”
                    • Similar operations to JVM


Wednesday, July 27, 2011
Why Learn It
                    • Know your platform
                     • Full understanding from top to bottom
                    • Bytecode generation is fun and easy
                     • Build your own language?
                    • May need to read bytecode someday
                     • Many libraries generate bytecode
Wednesday, July 27, 2011
Hello World

                   public class HelloWorld {
                       public static void main(String[] args) {
                           System.out.println("Hello, world");
                       }
                   }




Wednesday, July 27, 2011
javap
                    • Java class file disassembler
                    • Basic operation shows class structure
                     • Methods, superclasses, interface, etc
                    • -c flag includes bytecode
                    • -public, -private, -protected
                    • -verbose for stack size, locals, args
Wednesday, July 27, 2011
javap

                    ~/projects/bytecode_for_dummies ➔ javap HelloWorld
                    Compiled from "HelloWorld.java"
                    public class HelloWorld extends java.lang.Object{
                        public HelloWorld();
                        public static void main(java.lang.String[]);
                    }




Wednesday, July 27, 2011
javap -c
  ~/projects/bytecode_for_dummies ➔ javap -c HelloWorld
  Compiled from "HelloWorld.java"
  public class HelloWorld extends java.lang.Object{
  public HelloWorld();
    Code:
     0:! aload_0
     1:! invokespecial!#1; //Method java/lang/Object."<init>":()V
     4:! return

  public static void main(java.lang.String[]);
    Code:
     0:! getstatic! #2; //Field java/lang/System.out:Ljava/io/PrintStream;
     3:! ldc!#3; //String Hello, world
     5:! invokevirtual!#4; //Method java/io/PrintStream.println:
                                                        (Ljava/lang/String;)V
     8:! return

  }



Wednesday, July 27, 2011
javap -verbose
      ~/projects/bytecode_for_dummies ➔ javap -c -verbose HelloWorld
      Compiled from "HelloWorld.java"
      public class HelloWorld extends java.lang.Object
        SourceFile: "HelloWorld.java"
        minor version: 0
        major version: 50
        Constant pool:
      const #1 = Method! #6.#15;!// java/lang/Object."<init>":()V
      const #2 = Field!#16.#17;! / java/lang/System.out:Ljava/io/PrintStream;
                               /
      const #3 = String! #18;! / Hello, world
                               /
      const #4 = Method! #19.#20;! / java/io/PrintStream.println:(Ljava/lang/String;)V
                                   /
      const #5 = class!#21;! / HelloWorld
                           /
      ...

      {




Wednesday, July 27, 2011
javap -verbose

  ...
  public HelloWorld();
    Code:
      Stack=1, Locals=1, Args_size=1
      0:!aload_0
      1:!invokespecial! #1; //Method java/lang/Object."<init>":()V
      4:!return
    LineNumberTable:
      line 1: 0




Wednesday, July 27, 2011
javap -verbose
  public static void main(java.lang.String[]);
    Code:
     Stack=2, Locals=1, Args_size=1
     0:! getstatic!#2; //Field java/lang/System.out:Ljava/io/PrintStream;
     3:! ldc!
            #3; //String Hello, world
     5:! invokevirtual!
                      #4; //Method java/io/PrintStream.println:
                                                    (Ljava/lang/String;)V
     8:! return
    LineNumberTable:
     line 3: 0
     line 4: 8


  }




Wednesday, July 27, 2011
Thank you!



Wednesday, July 27, 2011
Thank you!
                             (Just Kidding)




Wednesday, July 27, 2011
Let’s try something a
                                little easier...


Wednesday, July 27, 2011
BiteScript

                    • (J)Ruby DSL for emitting JVM bytecode
                     • Internal DSL
                     • Primitive “macro” support
                     • Reads like javap -c (but nicer)
                    • http://github.com/headius/bitescript

Wednesday, July 27, 2011
Installation
                    • Download JRuby from http://jruby.org
                    • Unpack, optionally add bin/ to PATH
                     • Ahead of PATH if you have Ruby already
                    • [bin/]jruby -S gem install bitescript
                    • `bite myfile.bs` to run myfile.bs file
                    • `bitec myfile.bs` to compile myfile.bs file
Wednesday, July 27, 2011
BiteScript Users

                    • Mirah
                     • Ruby-like language for writing Java code
                     • BiteScript for JVM bytecode backend
                    • BrainF*ck implementation
                    • Other miscellaneous bytecode experiments

Wednesday, July 27, 2011
javap -c
  ~/projects/bytecode_for_dummies ➔ javap -c HelloWorld
  Compiled from "HelloWorld.java"
  public class HelloWorld extends java.lang.Object{
  public HelloWorld();
    Code:
     0:! aload_0
     1:! invokespecial!#1; //Method java/lang/Object."<init>":()V
     4:! return

  public static void main(java.lang.String[]);
    Code:
     0:! getstatic! #2; //Field java/lang/System.out:Ljava/io/PrintStream;
     3:! ldc!#3; //String Hello, world
     5:! invokevirtual!#4; //Method java/io/PrintStream.println:
                                                        (Ljava/lang/String;)V
     8:! return

  }



Wednesday, July 27, 2011
BiteScript

 main do
   getstatic java.lang.System, "out",
              java.io.PrintStream
   ldc "Hello, world!"
   invokevirtual java.io.PrintStream, "println",
       [java.lang.Void::TYPE, java.lang.Object]
   returnvoid
 end




Wednesday, July 27, 2011
BiteScript

            import java.lang.System          JRuby’s “import”
            import java.io.PrintStream        for Java classes
            main do
              getstatic System, "out", PrintStream
              ldc "Hello, world!"
              invokevirtual PrintStream, "println", [void, object]
              returnvoid
            end
                                                    Shortcuts for
                                                   void, int, string,
                                                     object, etc
Wednesday, July 27, 2011
BiteScript

                           main do
                             ldc "Hello, world!"
                             aprintln
                             returnvoid   A BiteScript “macro”
                           end




Wednesday, July 27, 2011
BiteScript

                           macro :aprintln do
                             getstatic System, "out", PrintStream
                             swap
                             invokevirtual PrintStream, "println",
                                           [void, object]
                           end




Wednesday, July 27, 2011
The Basics

                    • Stack machine
                    • Basic operations
                    • Flow control
                    • Class structures
                    • Exception handling

Wednesday, July 27, 2011
Stack Machine
                    • The “operand stack” holds operands
                    • Operations push and/or pop stack values
                     • Exceptions: nop, wide, goto, jsr/ret
                    • Stack must be consistent
                     • Largest part of bytecode verifier
                    • Stack is explicitly sized per method
Wednesday, July 27, 2011
The JVM Stack
                                                  Depth   Value
        import java.lang.System
        import java.io.PrintStream                 0

        main do
                                                   1
          getstatic System, "out", PrintStream
          ldc "Hello, world!"
          invokevirtual PrintStream, "println",
                                                   2
                                 [void, object]
          returnvoid                               3
        end
                                                   4



Wednesday, July 27, 2011
The JVM Stack
                                                  Depth      Value
        import java.lang.System
        import java.io.PrintStream                 0      out (a PS)

        main do
                                                   1
          getstatic System, "out", PrintStream
          ldc "Hello, world!"
          invokevirtual PrintStream, "println",
                                                   2
                                 [void, object]
          returnvoid                               3
        end
                                                   4



Wednesday, July 27, 2011
The JVM Stack
                                                  Depth        Value
        import java.lang.System
        import java.io.PrintStream                 0      “Hello, world!”

        main do
                                                   1        out (a PS)
          getstatic System, "out", PrintStream
          ldc "Hello, world!"
          invokevirtual PrintStream, "println",
                                                   2
                                 [void, object]
          returnvoid                               3
        end
                                                   4



Wednesday, July 27, 2011
The JVM Stack
                                                  Depth   Value
        import java.lang.System
        import java.io.PrintStream                 0

        main do
                                                   1
          getstatic System, "out", PrintStream
          ldc "Hello, world!"
          invokevirtual PrintStream, "println",
                                                   2
                                 [void, object]
          returnvoid                               3
        end
                                                   4



Wednesday, July 27, 2011
The JVM Stack
                                                  Depth   Value
        import java.lang.System
        import java.io.PrintStream                 0

        main do
                                                   1
          getstatic System, "out", PrintStream
          ldc "Hello, world!"
          invokevirtual PrintStream, "println",
                                                   2
                                 [void, object]
          returnvoid                               3
        end
                                                   4



Wednesday, July 27, 2011
Basic Operations

                    • Stack manipulation
                    • Local variables
                    • Math
                    • Boolean

Wednesday, July 27, 2011
Stack Operations
                           0x00    nop                   Do nothing.
                           0x57    pop           Discard top value from stack
                           0x58    pop2            Discard top two values
                           0x59    dup        Duplicate and push top value again
                           0x5A   dup_x1 Dup and push top value below second value
                           0x5B   dup_x2   Dup and push top value below third value
                           0x5C    dup2          Dup top two values and push
                           0x5D dup2_x1             ...below second value
                           0x5E dup2_x2              ...below third value
                           0x5F    swap              Swap top two values


Wednesday, July 27, 2011
Stack Juggling
                                        Depth    Value
                           dup
                                         0      value_0
                           pop
                           swap          1      value_1
                           dup_x1
                                         2
                           dup2_x2
                                         3

                                         4


Wednesday, July 27, 2011
Stack Juggling
                                        Depth    Value
                           dup
                                         0      value_0
                           pop
                           swap          1      value_0
                           dup_x1
                                         2      value_1
                           dup2_x2
                                         3

                                         4


Wednesday, July 27, 2011
Stack Juggling
                                        Depth    Value
                           dup
                                         0      value_0
                           pop
                           swap          1      value_1
                           dup_x1
                                         2
                           dup2_x2
                                         3

                                         4


Wednesday, July 27, 2011
Stack Juggling
                                        Depth    Value
                           dup
                                         0      value_1
                           pop
                           swap          1      value_0
                           dup_x1
                                         2
                           dup2_x2
                                         3

                                         4


Wednesday, July 27, 2011
Stack Juggling
                                        Depth    Value
                           dup
                                         0      value_1
                           pop
                           swap          1      value_0
                           dup_x1
                                         2      value_1
                           dup2_x2
                                         3

                                         4


Wednesday, July 27, 2011
Stack Juggling
                                        Depth    Value
                           dup
                                         0      value_1
                           pop
                           swap          1      value_0
                           dup_x1
                                         2      value_1
                           dup2_x2
                                         3      value_1

                                         4      value_0


Wednesday, July 27, 2011
Typed Opcodes
                            <type><operation>
                    b        byte             Constant values
                    s       short          Local vars (load, store)
                    c        char
                                       Array operations (aload, astore)
                    i         int
                                        Math ops (add, sub, mul, div)
                    l        long
                                            Boolean and bitwise
                    f        float
                    d       double              Comparisons
                    a      reference            Conversions

Wednesday, July 27, 2011
Where’s boolean?

                    • Boolean is generally int 0 or 1
                    • Boolean operations push int 0 or 1
                    • Boolean branches expect 0 or nonzero
                    • To set a boolean...use int 0 or 1

Wednesday, July 27, 2011
Constant Values
              0x01         aconst_null                  Push null on stack
         0x02-0x08 iload_[m1-5]                   Push integer [-1 to 5] on stack
         0x09-0x0A         lconst_[0,1]             Push long [0 or 1] on stack
        0x0B-0x0D fconst_[0,1,2]                 Push float [0.0, 1.0, 2.0] on stack
         0x0E-0x0F dconst_[0,1]                   Push double [0.0, 1.0] on stack
              0x10           bipush             Push byte value to stack as integer
              0x11           sipush            Push short value to stack as integer
              0x12             ldc        Push 32-bit constant to stack (int, float, string)
              0x14           ldc2_w        Push 64-bit constant to stack (long, double)



Wednesday, July 27, 2011
Why So Many?
                    • Reducing bytecode size
                     • Special iconst_0 and friends take no args
                     • bipush, sipush: only 8, 16 bits arguments
                    • Pre-optimizing JVM
                     • Specialized instructions can be optimized
                     • Doesn’t matter at all now
Wednesday, July 27, 2011
Constant Values
                                            Depth   Value

                            ldc "hello"      0
                            dconst_1
                                             1
                            aconst_null
                            bipush 4         2
                            ldc_float 2.0
                                             3
                                             4
                                             5


Wednesday, July 27, 2011
Constant Values
                                            Depth    Value

                            ldc "hello"      0      “hello”
                            dconst_1
                                             1
                            aconst_null
                            bipush 4         2
                            ldc_float 2.0
                                             3
                                             4
                                             5


Wednesday, July 27, 2011
Constant Values
                                            Depth    Value

                            ldc "hello"      0
                            dconst_1
                                                    1.0d
                                             1
                            aconst_null
                            bipush 4         2      “hello”
                            ldc_float 2.0
                                             3
                                             4
                                             5


Wednesday, July 27, 2011
Woah, Two Slots?

                    • JVM stack slots (and local vars) are 32-bit
                    • 64-bit values take up two slots
                    • “wide” before or “w” suffix
                    • 64-bit field updates not atomic!
                     • Mind those concurrent longs/doubles!

Wednesday, July 27, 2011
Constant Values
                                            Depth    Value

                            ldc "hello"      0       null
                            dconst_1
                                             1
                            aconst_null              1.0d
                            bipush 4         2
                            ldc_float 2.0
                                             3      “hello”
                                             4
                                             5


Wednesday, July 27, 2011
Constant Values
                                            Depth    Value

                            ldc "hello"      0        4
                            dconst_1
                                             1       null
                            aconst_null
                            bipush 4         2
                            ldc_float 2.0            1.0d
                                             3
                                             4      “hello”
                                             5


Wednesday, July 27, 2011
Constant Values
                                            Depth    Value

                            ldc "hello"      0       2.0f
                            dconst_1
                                             1        4
                            aconst_null
                            bipush 4         2       null
                            ldc_float 2.0
                                             3
                                                     1.0
                                             4
                                             5      “hello”


Wednesday, July 27, 2011
Local Variable Table

                    • Local variables numbered from 0
                     • Instance methods have “this” at 0
                    • Separate table maps numbers to names
                    • Explicitly sized in method definition

Wednesday, July 27, 2011
Local Variables
              0x15      iload      Load integer from local variable onto stack
            0x16        lload                          ...long...
            0x17        fload                           ...float...
            0x18       dload                         ...double...
            0x19       aload                       ...reference...
         0x1A-0x2D Packed loads                iload_0, aload_3, etc
            0x36       istore      Store integer from stack into local variable
            0x37       lstore                          ...long...
            0x38       fstore                          ...float...
            0x39      dstore                         ...double...
            0x3A      astore                       ...reference...
         0x3B-0x4E Packed stores             fstore_2, dstore_0, etc
            0x84         iinc        Add given amount to int local variable
Wednesday, July 27, 2011
Local Variables
        Var                Value                     Depth   Value
                                       ldc "hello"
          0                            bipush 4       0
                                       istore 3
          1                            dconst_0       1
                                       dstore 1
          2                            astore 0       2
                                       aload 0
          3                            iinc 3, 5
                                                      3

          4                                           4


Wednesday, July 27, 2011
Local Variables
        Var                Value                     Depth    Value
                                       ldc "hello"
          0                            bipush 4       0      “hello”
                                       istore 3
          1                            dconst_0       1
                                       dstore 1
          2                            astore 0       2
                                       aload 0
          3                            iinc 3, 5
                                                      3

          4                                           4


Wednesday, July 27, 2011
Local Variables
        Var                Value                     Depth    Value
                                       ldc "hello"
          0                            bipush 4       0        4
                                       istore 3
          1                            dconst_0       1      “hello”
                                       dstore 1
          2                            astore 0       2
                                       aload 0
          3                            iinc 3, 5
                                                      3

          4                                           4


Wednesday, July 27, 2011
Local Variables
        Var                Value                     Depth    Value
                                       ldc "hello"
          0                            bipush 4       0      “hello”
                                       istore 3
          1                            dconst_0       1
                                       dstore 1
          2                            astore 0       2
                                       aload 0
          3                 4          iinc 3, 5
                                                      3

          4                                           4


Wednesday, July 27, 2011
Local Variables
        Var                Value                     Depth    Value
                                       ldc "hello"
          0                            bipush 4       0
                                       istore 3               0.0
          1                            dconst_0       1
                                       dstore 1
          2                            astore 0       2      “hello”
                                       aload 0
          3                 4          iinc 3, 5
                                                      3

          4                                           4


Wednesday, July 27, 2011
Local Variables
        Var                Value                     Depth    Value
                                       ldc "hello"
          0                            bipush 4       0      “hello”
                                       istore 3
          1                            dconst_0       1
                           0.0         dstore 1
          2                            astore 0       2
                                       aload 0
          3                 4          iinc 3, 5
                                                      3

          4                                           4


Wednesday, July 27, 2011
Local Variables
        Var                 Value                     Depth   Value
                                        ldc "hello"
          0                “hello”      bipush 4       0
                                        istore 3
          1                             dconst_0       1
                             0.0        dstore 1
          2                             astore 0       2
                                        aload 0
          3                   4         iinc 3, 5
                                                       3

          4                                            4


Wednesday, July 27, 2011
Local Variables
        Var                 Value                     Depth    Value
                                        ldc "hello"
          0                “hello”      bipush 4       0      “hello”
                                        istore 3
          1                             dconst_0       1
                            0.0         dstore 1
          2                             astore 0       2
                                        aload 0
          3                  4          iinc 3, 5
                                                       3

          4                                            4


Wednesday, July 27, 2011
Local Variables
        Var                 Value                     Depth    Value
                                        ldc "hello"
          0                “hello”      bipush 4       0      “hello”
                                        istore 3
          1                             dconst_0       1
                            0.0         dstore 1
          2                             astore 0       2
                                        aload 0
          3                  9          iinc 3, 5
                                                       3

          4                                            4


Wednesday, July 27, 2011
Arrays
        0x2E-0x35          [i,l,f,d,a,b,c,d]aload Load [int, long, ...] from array (on stack) to stack

        0x4F-0x56          [i,l,f,d,a,b,c,d]astore Store [int, long, ...] from stack to array (on stack)

            0xBC                newarray                    Construct new primitive array

            0xBD                anewarray                  Construct new reference array

            0xBE               arraylength                          Get array length

            0xC5             multianewarray                Create multi-dimensional array




Wednesday, July 27, 2011
Arrays
                                          Depth   Value
                           iconst_2
                           newarray int    0
                           dup
                           iconst_0        1
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth   Value
                           iconst_2
                           newarray int    0       2
                           dup
                           iconst_0        1
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth       Value
                           iconst_2
                           newarray int    0      int[2] {0,0}
                           dup
                           iconst_0        1
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth       Value
                           iconst_2
                           newarray int    0      int[2] {0,0}
                           dup
                           iconst_0        1      int[2] {0,0}
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth      Value
                           iconst_2
                           newarray int    0           0
                           dup
                           iconst_0        1      int[2] {0,0}
                           iconst_m1
                                           2      int[2] {0,0}
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth      Value
                           iconst_2
                           newarray int    0          -1
                           dup
                           iconst_0        1           0
                           iconst_m1
                                           2      int[2] {0,0}
                           iastore
                           iconst_0        3      int[2] {0,0}
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth       Value
                           iconst_2
                           newarray int    0      int[2] {-1, 0}
                           dup
                           iconst_0        1
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth       Value
                           iconst_2
                           newarray int    0            0
                           dup
                           iconst_0        1      int[2] {-1, 0}
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Arrays
                                          Depth   Value
                           iconst_2
                           newarray int    0      -1
                           dup
                           iconst_0        1
                           iconst_m1
                                           2
                           iastore
                           iconst_0        3
                           iaload
                                           4
                                           5


Wednesday, July 27, 2011
Math Operations
                           add    subtract   multiply   divide   remainder   negate
                            +        -          *          /        %          -()

          int              iadd    isub       imul      idiv       irem      ineg

        long               ladd    lsub       lmul      ldiv       lrem      lneg

        float               fadd    fsub       fmul      fdiv       frem      fneg

     double                dadd    dsub      dmul       ddiv      drem       dneg

Wednesday, July 27, 2011
Boolean and Bitwise

                                                  unsigned
                           shift left shift right               and    or    xor
                                                  shift right

             int             ishl        ishr       iushr       iand   ior   ixor




Wednesday, July 27, 2011
Conversions
                                           To:
                           int    long   float    double   byte   char   short

                   int      -     i2l    i2f      i2d     i2b    i2c    i2s
  From:




                 long      l2i     -     l2f      l2d      -      -       -

                 float      f2i    f2l     -       f2d      -      -       -

              double       d2i    d2l    d2f       -       -      -       -

Wednesday, July 27, 2011
Comparisons
             0x94          lcmp           Compare two longs, push int -1, 0, 1


             0x95          fcmpl    Compare two floats, push in -1, 0, 1 (-1 for NaN)


             0x96          fcmpg    Compare two floats, push in -1, 0, 1 (1 for NaN)


             0x97          dcmpl   Compare two doubles, push in -1, 0, 1 (-1 for NaN)


             0x98          dcmpg   Compare two doubles, push in -1, 0, 1 (1 for NaN)




Wednesday, July 27, 2011
Flow Control

                    • Inspect stack and branch
                     • Or just branch, via goto
                    • Labels mark branch targets
                    • Wide variety of tests

Wednesday, July 27, 2011
Flow Control
              0x99              ifeq                          If zero on stack, branch
              0x9A              ifne                       If nonzero on stack, branch
              0x9B                iflt                If stack value is less than zero, branch
              0x9C               ifge    If stack value is greater than or equal to zero, branch
              0x9D               ifgt             If stack value is greater than zero, branch
              0x9E               ifle        If stack value is less than or equal to zero, branch
              0x9F         if_icmpeq                If two integers on stack are eq, branch
              0xA0         if_icmpne                If two integers on stack are ne, branch
              0xA1           if_icmplt               If two integers on stack are lt, branch
              0xA2          if_icmpge               If two integers on stack are ge, branch
              0xA3          if_icmpgt                                   If tw
                                                    If two integers on stack are gt, branch
              0xA4          if_icmple                If two integers on stack are le, branch
              0xA5         if_acmpeq         If two references on stack are the same, branch
              0xA6         if_acmpne          If two references on stack are different, branch
              0xA7              goto                                  GOTO!

Wednesday, July 27, 2011
Other Flow Control
              0xA8              jsr               Jump to subroutine (deprecated)

              0xA9              ret             Return from subroutine (deprecated)

             0xAA           tableswitch     Branch using an indexed table of jump offsets

              0xAB         lookupswitch   Branch using a lookup-based table of jump offsets

         0xAC-0xB0 [i,l,f,d,a]return       Return (int, long, float, double, reference) value

              0xB1            return         Void return (exit method, return nothing)

              0xC6             ifnull                If reference on stack is null

              0xC7           ifnonnull             If reference on stack is not null


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth     Value
                           ldc "branch"                                String[]
                           invokevirtual string, "equals",    0      {“branch”}
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth         Value
                           ldc "branch"
                           invokevirtual string, "equals",    0              0
                                         [boolean, object]
                           ifne :branch
                                                              1      String[]{“branch”}

                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth    Value
                           ldc "branch"
                           invokevirtual string, "equals",    0      “branch”
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth    Value
                           ldc "branch"
                           invokevirtual string, "equals",    0      “branch”
                                         [boolean, object]
                           ifne :branch
                                                              1      “branch”

                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth   Value
                           ldc "branch"
                           invokevirtual string, "equals",    0       1
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth   Value
                           ldc "branch"
                           invokevirtual string, "equals",    0
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth   Value
                           ldc "branch"
                           invokevirtual string, "equals",    0
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth    Value
                           ldc "branch"
                           invokevirtual string, "equals",    0      “Equal!”
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Flow Control
                           aload 0
                           ldc 0
                           aaload                            Depth   Value
                           ldc "branch"
                           invokevirtual string, "equals",    0
                                         [boolean, object]
                           ifne :branch
                                                              1
                           ldc "Not equal!"
                                                              2
                           aprintln
                           goto :end                          3
                           label :branch
                           ldc "Equal!"                       4
                           aprintln
                           label :end                         5
                           returnvoid


Wednesday, July 27, 2011
Classes and Types

                    • Signatures!!!
                     • Probably the most painful part
                     • ...but not a big deal if you understand


Wednesday, July 27, 2011
Using Classes
              0xB2            getstatic                 Fetch static field from class
              0xB3            putstatic                   Set static field in class
              0xB4            getfield                 Get instance field from object
              0xB5            setfield                   Set instance field in object
              0xB6          invokevirtual           Invoke instance method on object
              0xB7          invokespecial        Invoke constructor or “super” on object
              0xB8          invokestatic               Invoke static method on class
              0xB9         invokeinterface          Invoke interface method on object
              0xBA         invokedynamic       Invoke method dynamically on object (Java 7)
              0xBB              new                  Construct new instance of object
              0xC0           checkcast                Attempt to cast object to type
              0xC1           instanceof      Push nonzero if object is instanceof specified type

Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth        Value
                                         [void]
                                                                         an ArrayList
                           checkcast Collection                  0      (uninitialized)
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth        Value
                                         [void]
                                                                         an ArrayList
                           checkcast Collection                  0      (uninitialized)
                           dup
                                                                           an ArrayList
                           ldc "first element"                   1        (uninitialized)
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                           checkcast Collection                  0      an ArrayList
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                           checkcast Collection                  0      a Collection
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth       Value
                                         [void]
                           checkcast Collection                  0      a Collection
                           dup
                           ldc "first element"                   1       a Collection
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                                                                          “first
                           checkcast Collection                  0      element”
                           dup
                           ldc "first element"                   1      a Collection
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2      a Collection
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                           checkcast Collection                  0       1 (true)
                           dup
                           ldc "first element"                   1      a Collection
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                           checkcast Collection                  0      a Collection
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                           checkcast Collection                  0      an ArrayList
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth      Value
                                         [void]
                           checkcast Collection                  0           0
                           dup
                           ldc "first element"                   1      an ArrayList
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth     Value
                                         [void]
                                                                          “first
                           checkcast Collection                  0      element”
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Using Classes
                           new ArrayList
                           dup
                           invokespecial ArrayList, '<init>',   Depth   Value
                                         [void]
                           checkcast Collection                  0
                           dup
                           ldc "first element"                   1
                           invokeinterface Collection, 'add',
                                           [boolean, object]     2
                           pop
                           checkcast ArrayList                   3
                           ldc 0
                           invokevirtual ArrayList, 'get',       4
                                         [object, int]
                           aprintln                              5
                           returnvoid



Wednesday, July 27, 2011
Exceptions and
                              Synchronization
                                          Table structure for a method indicating start/end of
                 -           trycatch
                                                try/catch and logic to run on exception


              0xC2         monitorenter    Enter synchronized block against object on stack


              0xC3         monitorexit       Exit synchronized block (against same object)




Wednesday, July 27, 2011
More Examples


                    • A simple loop
                    • Fibonacci


Wednesday, July 27, 2011
A Simple Loop
                             main do
                               aload 0
                               push_int 0
                               aaload
                               label :top
                               dup
                               aprintln
                               goto :top
                               returnvoid
                             end
Wednesday, July 27, 2011
Fibonacci
                           public_static_method "fib", [], int, int do
                             iload 0
                             ldc 2
                             if_icmpge :recurse
                             iload 0
                             ireturn
                             label :recurse
                             iload 0
                             ldc 1
                             isub
                             invokestatic this, "fib", [int, int]
                             iload 0
                             ldc 2
                             isub
                             invokestatic this, "fib", [int, int]
                             iadd
                             ireturn
                           end


Wednesday, July 27, 2011
main do
                         load_times
                         istore 1
                                            Fibonacci
                           ldc "Raw bytecode fib(45) performance:"
                           aprintln

                           label :top
                           iload 1
                           ifeq :done
                           iinc 1, -1

                           start_timing 2
                           ldc 45
                           invokestatic this, "fib", [int, int]
                           pop
                           end_timing 2

                           ldc "Time: "
                           aprintln
                           lprintln 2
                           goto :top

                         label :done
                         returnvoid
                       end


Wednesday, July 27, 2011
main do
                         load_times
                         istore 1
                                            Fibonacci
                           ldc "Raw bytecode fib(45) performance:"
                           aprintln

                           label :top
                           iload 1
                           ifeq :done
                           iinc 1, -1

                           start_timing 2
                                                                     Macros
                           ldc 45
                           invokestatic this, "fib", [int, int]
                           pop
                           end_timing 2

                           ldc "Time: "
                           aprintln
                           lprintln 2
                           goto :top

                         label :done
                         returnvoid
                       end


Wednesday, July 27, 2011
Fibonacci

                           macro :load_times do
                             aload 0
                             ldc 0
                             aaload # number of times
                             invokestatic JInteger, 'parseInt',
                                          [int, string]
                           end




Wednesday, July 27, 2011
Fibonacci

                           macro :start_timing do |i|
                             load_time
                             lstore i
                           end




Wednesday, July 27, 2011
Fibonacci

            macro :load_time do
              invokestatic System, "currentTimeMillis", long
            end




Wednesday, July 27, 2011
Fibonacci
                           macro :end_timing do |i|
                             load_time
                             lload i
                             lsub
                             lstore i
                           end




Wednesday, July 27, 2011
Fibonacci
                      macro :lprintln do |i|
                        getstatic System, "out", PrintStream
                        lload i
                        invokevirtual PrintStream, "println",
                                      [void, long]
                      end




Wednesday, July 27, 2011
ASM

                    • “All purpose bytecode manipulation and
                           analysis framework.”
                    • De facto standard bytecode library
                    • http://asm.ow2.org


Wednesday, July 27, 2011
Basic Process

                    • Construct a ClassWriter
                    • Visit structure
                     • Annotations, methods, fields, inner classes
                    • Write out bytes

Wednesday, July 27, 2011
Blah.java
      public class Blah implements Cloneable {
          private final String fieldName;

                   public Blah() {
                       fieldName = "hello";
                   }

                   public static Blah makeBlah() {
                       return new Blah();
                   }
      }


Wednesday, July 27, 2011
ClassWriter

      ClassWriter cv = new ClassWriter(
              ClassWriter.COMPUTE_MAXS |
              ClassWriter.COMPUTE_FRAMES);




Wednesday, July 27, 2011
COMPUTE...what?
                    • COMPUTE_MAXS
                     • ASM will calculate max stack/local vars
                    • COMPUTE_FRAMES
                     • ASM will calculate Java 6 stack map
                     • Hints to verifier that we’ve pre-validated
                           stack contents (sort of)


Wednesday, July 27, 2011
Visit Class
      cv.visit(
              Opcodes.V1_6,
              Opcodes.ACC_PUBLIC,
              "Blah",
              null,
              "java/lang/Object",
              new String[] {"java/lang/Cloneable"});




Wednesday, July 27, 2011
Opcodes

                    • Interface full of constants
                     • Bytecodes
                     • Visibility modifiers
                     • Java versions
                     • Other stuff

Wednesday, July 27, 2011
ACC_*

                    • Some you know
                     • ACC_PUBLIC, ACC_ABSTRACT, etc
                    • Some you don’t
                     • ACC_BRIDGE, ACC_SYNTHETIC

Wednesday, July 27, 2011
Java Version


                    • V1_1 through V1_7
                     • Sorry 1.0!


Wednesday, July 27, 2011
Class Names
                                 "java/lang/Object"


                           packageClass.replaceAll('.', '/')




Wednesday, July 27, 2011
Visit Source

      cv.visitSource(
              "Blah.java",
              "JSR-45 source map here");




Wednesday, July 27, 2011
Visit Annotation

      AnnotationVisitor av = cv.visitAnnotation("some/Annotation", true);
      av.visitArray("name1", ...);
      av.visitEnum("name2", ...);
      av.visitEnd();




Wednesday, July 27, 2011
Blah.java


                   private final String fieldName;




Wednesday, July 27, 2011
Visit Field
      FieldVisitor fv = cv.visitField(
              Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL,
              "fieldName",
              "Ljava.lang.String;",
              null);
      fv.visitAnnotation(...);
      fv.visitAttribute(...);
      fv.visitEnd();




Wednesday, July 27, 2011
Descriptor
                               "Ljava.lang.String;"
                           "(IF[JLjava.lang.Object;)V"

                    • Primitive types
                     • B,C,S,I,J,F,D,Z,V
                    • Reference types
                     • Lsome/Class;
                    • Array
                     • Prefix with [
Wednesday, July 27, 2011
Blah.java

                   public Blah() {
                       ...
                   }

                   public static Blah makeBlah() {
                       ...
                   }




Wednesday, July 27, 2011
Visit Method
      MethodVisitor construct = cv.visitMethod(
              Opcodes.ACC_PUBLIC,
              "<init>",
              "()V",
              null,
              null);
      MethodVisitor makeBlah = cv.visitMethod(
              Opcodes.ACC_PUBLIC, ACC_STATIC,
              "makeBlah",
              "()LBlah;",
              null,
              null);

Wednesday, July 27, 2011
Special Methods

                    • <init>
                     • Constructor
                    • <clinit>
                     • Static initializer

Wednesday, July 27, 2011
MethodVisitor

                    • Visit annotation stuff
                    • Visit code
                     • Bytecodes, frames, local vars, line nums
                    • Visit maxs
                     • Pass bogus values if COMPUTE_MAXS

Wednesday, July 27, 2011
Blah.java

                   public Blah() {
                       fieldName = "hello";
                   }

                   public static Blah makeBlah() {
                       return new Blah();
                   }




Wednesday, July 27, 2011
Visit Method Body
                           construct.visitCode();
                           construct.visitVarInsn(ALOAD, 0);
                           construct.visitMethodInsn(INVOKESPECIAL,
                                   "java/lang/Object",
                                   "<init>",
                                   "()V");
                           construct.visitVarInsn(ALOAD, 0);
                           construct.visitLdcInsn("hello");
                           construct.visitFieldInsn(PUTFIELD,
                                   "Blah",
                                   "fieldName",
                                   "Ljava/lang/String;");
                           construct.visitInsn(RETURN);
                           construct.visitMaxs(2, 1);
                           construct.visitEnd();

Wednesday, July 27, 2011
ASMifierClassVisitor


                    • Dump ASM visitor calls from .class file
                    • Very raw, but very useful


Wednesday, July 27, 2011
Blah.java
      public class Blah implements Cloneable {
          private final String fieldName;

                   public Blah() {
                       fieldName = "hello";
                   }

                   public static Blah makeBlah() {
                       return new Blah();
                   }
      }


Wednesday, July 27, 2011
~/oscon ➔ java -cp asm-3.3.1.jar:asm-util-3.3.1.jar 
                   org.objectweb.asm.util.ASMifierClassVisitor 
                   Blah.class
  import java.util.*;
  import org.objectweb.asm.*;
  import org.objectweb.asm.attrs.*;
  public class BlahDump implements Opcodes {
  public static byte[] dump () throws Exception {


  ClassWriter cw = new ClassWriter(0);
  FieldVisitor fv;
  MethodVisitor mv;
  AnnotationVisitor av0;


  cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Blah", null, "java/lang/Object", new String[] { "java/lang/Cloneable" });
  {

  fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "fieldName", "Ljava/lang/String;", null, null);
  fv.visitEnd();
  }
  {

  mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  mv.visitCode();
  mv.visitVarInsn(ALOAD, 0);
  mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
  mv.visitVarInsn(ALOAD, 0);
  mv.visitLdcInsn("hello");
  mv.visitFieldInsn(PUTFIELD, "Blah", "fieldName", "Ljava/lang/String;");
  mv.visitInsn(RETURN);
  mv.visitMaxs(2, 1);
  mv.visitEnd();
  }
  {

  mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "makeBlah", "()LBlah;", null, null);
  mv.visitCode();
  mv.visitTypeInsn(NEW, "Blah");
  mv.visitInsn(DUP);
  mv.visitMethodInsn(INVOKESPECIAL, "Blah", "<init>", "()V");
  mv.visitInsn(ARETURN);
  mv.visitMaxs(2, 0);
  mv.visitEnd();
  }
  cw.visitEnd();


  return cw.toByteArray();
  }
  }




Wednesday, July 27, 2011
Real-world Cases
                    • Reflection-free invocation
                     • JRuby, Groovy, other languages
                    • Bytecoded data objects
                     • Hibernate, other data layers
                     • java.lang.reflect.Proxy and others
                    • Language compilers
Wednesday, July 27, 2011
Part Two:
                            JVM JIT


Wednesday, July 27, 2011
JIT

                    • Just-In-Time compilation
                    • Compiled when needed
                     • Maybe immediately before execution
                     • ...or when we decide it’s important
                     • ...or never?

Wednesday, July 27, 2011
Mixed-Mode
                    • Interpreted
                     • Bytecode-walking
                     • Artificial stack
                    • Compiled
                     • Direct native operations
                     • Native registers, memory, etc
Wednesday, July 27, 2011
Profiling

                    • Gather data about code while interpreting
                     • Invariants (types, constants, nulls)
                     • Statistics (branches, calls)
                    • Use that information to optimize
                     • Educated guess?

Wednesday, July 27, 2011
Optimization

                    • Loop unrolling
                    • Lock coarsening
                    • Method inlining
                    • Dead code elimination
                    • Duplicate code elimination

Wednesday, July 27, 2011
The Golden Rule
                           of Optimization

                            Don’t do unnecessary work.




Wednesday, July 27, 2011
Perf Sinks
                    • Memory accesses
                     • By far the biggest expense
                    • Calls
                     • Opaque memory ref + branch
                    • Locks, volatile writes
                     • Kills multi-cpu perf
Wednesday, July 27, 2011
Volatile?
                    • Each CPU maintains a memory cache
                    • Caches may be out of sync
                     • If it doesn’t matter, no problem
                     • If it does matter, threads disagree!
                    • Volatile forces synchronization of cache
                     • Across cores and to main memory
Wednesday, July 27, 2011
Inlining?

                    • Combine caller and callee into one unit
                     • e.g. based on profile
                     • Perhaps with a sanity check
                    • Optimize as a whole

Wednesday, July 27, 2011
Inlining
      int addAll(int max) {
          int accum = 0;
          for (int i = 0; i < max; i++) {
              accum = add(accum, i);
          }
          return accum;
      }

      int add(int a, int b) {
          return a + b;
      }


Wednesday, July 27, 2011
Inlining
      int addAll(int max) {
          int accum = 0;
          for (int i = 0; i < max; i++) {
              accum = add(accum, i);
          }
          return accum;
      }                       Only one target   is ever seen

      int add(int a, int b) {
          return a + b;
      }


Wednesday, July 27, 2011
Inlining

      int addAll(int max) {
          int accum = 0;
          for (int i = 0; i < max; i++) {
              accum = accum + i;
          }
          return accum;
      }                   Don’t bother making   a call



Wednesday, July 27, 2011
Call Site
                    • The place where you make a call
                    • Monomorphic (“one shape”)
                     • Single target class
                    • Bimorphic (“two shapes”)
                    • Polymorphic (“many shapes”)
                    • Megamorphic (“you’re screwed”)
Wednesday, July 27, 2011
Blah.java
      System.currentTimeMillis(); // static, monomorphic

      List list1 = new ArrayList(); // constructor, monomorphic
      List list2 = new LinkedList();

      for (List list : new List[]{ list1, list2 }) {
          list.add("hello"); // bimorphic
      }

      for (Object obj : new Object[]{ 'foo', list1, new Object() }) {
          obj.toString(); // polymorphic
      }




Wednesday, July 27, 2011
Hotspot
                    • -client mode (C1) inlines, less aggressive
                     • Fewer opportunities to optimize
                    • -server mode (C2) profiles, inlines
                     • We’ll focus on this
                    • Tiered mode combines them
                     • -XX:+TieredCompilation
Wednesday, July 27, 2011
Hotspot Inlining

                    • Profile to find “hot spots”
                     • Largely focused around call sites
                     • Profile until 10k calls
                    • Inline mono/bimorphic calls
                    • Other mechanisms for polymorphic calls

Wednesday, July 27, 2011
Now it gets fun!



Wednesday, July 27, 2011
Monitoring the JIT
                    • Dozens of flags
                     • PrintCompilation
                     • PrintInlining
                     • LogCompilation
                     • PrintAssembly
                    • Some in product, some in debug...
Wednesday, July 27, 2011
public class Accumulator {
          public static void main(String[] args) {
              int max = Integer.parseInt(args[0]);
              System.out.println(addAll(max));
          }

                 static int addAll(int max) {
                     int accum = 0;
                     for (int i = 0; i < max; i++) {
                         accum = add(accum, i);
                     }
                     return accum;
                 }

                 static int add(int a, int b) {
                     return a + b;
                 }
      }

Wednesday, July 27, 2011
~/oscon              ➔ java -version
      openjdk              version "1.7.0-internal"
      OpenJDK              Runtime Environment (build 1.7.0-internal-b00)
      OpenJDK              64-Bit Server VM (build 21.0-b17, mixed mode)

      ~/oscon ➔ javac Accumulator.java

      ~/oscon ➔ java Accumulator 1000
      499500




Wednesday, July 27, 2011
PrintCompilation

                    • -XX:+PrintCompilation
                    • Print methods as they are jitted
                     • Class + name + size


Wednesday, July 27, 2011
~/oscon ➔ java -XX:+PrintCompilation Accumulator 1000
        1       java.lang.String::hashCode (64 bytes)
        2       java.math.BigInteger::mulAdd (81 bytes)
        3       java.math.BigInteger::multiplyToLen (219 bytes)
        4       java.math.BigInteger::addOne (77 bytes)
        5       java.math.BigInteger::squareToLen (172 bytes)
        6       java.math.BigInteger::primitiveLeftShift (79 bytes)
        7       java.math.BigInteger::montReduce (99 bytes)
        8       sun.security.provider.SHA::implCompress (491 bytes)
        9       java.lang.String::charAt (33 bytes)
      499500




Wednesday, July 27, 2011
~/oscon ➔ java -XX:+PrintCompilation Accumulator 1000
        1       java.lang.String::hashCode (64 bytes)
        2       java.math.BigInteger::mulAdd (81 bytes)
        3       java.math.BigInteger::multiplyToLen (219 bytes)
        4       java.math.BigInteger::addOne (77 bytes)
        5       java.math.BigInteger::squareToLen (172 bytes)
        6       java.math.BigInteger::primitiveLeftShift (79 bytes)
        7       java.math.BigInteger::montReduce (99 bytes)
        8       sun.security.provider.SHA::implCompress (491 bytes)
        9       java.lang.String::charAt (33 bytes)
      499500
                           Where’s our methods?!



Wednesday, July 27, 2011
~/oscon ➔ java -XX:+PrintCompilation Accumulator 1000
        1       java.lang.String::hashCode (64 bytes)
        2       java.math.BigInteger::mulAdd (81 bytes)
        3       java.math.BigInteger::multiplyToLen (219 bytes)
        4       java.math.BigInteger::addOne (77 bytes)
        5       java.math.BigInteger::squareToLen (172 bytes)
        6       java.math.BigInteger::primitiveLeftShift (79 bytes)
        7       java.math.BigInteger::montReduce (99 bytes)
        8       sun.security.provider.SHA::implCompress (491 bytes)
        9       java.lang.String::charAt (33 bytes)
      499500
                           Where’s our methods?!
                                      ...remember...10k calls

Wednesday, July 27, 2011
10k loop, 10k calls to add

      ~/oscon ➔            java -XX:+PrintCompilation Accumulator 10000
        1                  java.lang.String::hashCode (64 bytes)
        2                  java.math.BigInteger::mulAdd (81 bytes)
        3                  java.math.BigInteger::multiplyToLen (219 bytes)
        4                  java.math.BigInteger::addOne (77 bytes)
        5                  java.math.BigInteger::squareToLen (172 bytes)
        6                  java.math.BigInteger::primitiveLeftShift (79 bytes)
        7                  java.math.BigInteger::montReduce (99 bytes)
        8                  sun.security.provider.SHA::implCompress (491 bytes)
        9                  java.lang.String::charAt (33 bytes)
       10                  Accumulator::add (4 bytes)
      49995000

                                                Hooray!


Wednesday, July 27, 2011
What’s this stuff?
           1               java.lang.String::hashCode (64 bytes)
           2               java.math.BigInteger::mulAdd (81 bytes)
           3               java.math.BigInteger::multiplyToLen (219 bytes)
           4               java.math.BigInteger::addOne (77 bytes)
           5               java.math.BigInteger::squareToLen (172 bytes)
           6               java.math.BigInteger::primitiveLeftShift (79 bytes)
           7               java.math.BigInteger::montReduce (99 bytes)
           8               sun.security.provider.SHA::implCompress (491 bytes)
           9               java.lang.String::charAt (33 bytes)




Wednesday, July 27, 2011
What’s this stuff?
           1               java.lang.String::hashCode (64 bytes)
           2               java.math.BigInteger::mulAdd (81 bytes)
           3               java.math.BigInteger::multiplyToLen (219 bytes)
           4               java.math.BigInteger::addOne (77 bytes)
           5               java.math.BigInteger::squareToLen (172 bytes)
           6               java.math.BigInteger::primitiveLeftShift (79 bytes)
           7               java.math.BigInteger::montReduce (99 bytes)
           8               sun.security.provider.SHA::implCompress (491 bytes)
           9               java.lang.String::charAt (33 bytes)



                           Class loading, security, other boot logic.


Wednesday, July 27, 2011
What if you see this...
      ~/oscon ➔ java -client -XX:+PrintCompilation Accumulator 1000
        1        java.lang.String::hashCode (64 bytes)
        2        java.math.BigInteger::mulAdd (81 bytes)
        3        java.math.BigInteger::multiplyToLen (219 bytes)
        4        java.math.BigInteger::addOne (77 bytes)
        5        java.math.BigInteger::squareToLen (172 bytes)
        5    made not entrant java.math.BigInteger::squareToLen (172 bytes)
        7        java.math.BigInteger::montReduce (99 bytes)
        6        java.math.BigInteger::primitiveLeftShift (79 bytes)
        8        java.math.BigInteger::squareToLen (172 bytes)
        9        sun.security.provider.SHA::implCompress (491 bytes)
       10        java.lang.String::charAt (33 bytes)
      499500




Wednesday, July 27, 2011
Optimistic Compiler

                    • Assume profile is accurate
                    • Aggressively optimize based on profile
                    • Bail out if we’re wrong
                     • And hope that we’re usually right

Wednesday, July 27, 2011
Deoptimization

                    • Bail out of running code
                    • Monitoring flags describe process
                     • “uncommon trap” - we were wrong
                     • “not entrant” - don’t let anyone enter
                     • “zombie” - on its way to deadness

Wednesday, July 27, 2011
What if you see this...
       20                  java.math.BigInteger::addOne (77 bytes)
       21                  java.math.BigInteger::squareToLen (172 bytes)
       22                  java.math.BigInteger::primitiveLeftShift (79 bytes)
      ---    n             java.lang.System::arraycopy (static)
       24                  sun.security.provider.SHA::implCompress (491 bytes)
       23                  java.math.BigInteger::montReduce (99 bytes)
       25                  java.lang.String$CaseInsensitiveComparator::compare (115
      bytes)
       26                  java.lang.Character::toLowerCase (162 bytes)




Wednesday, July 27, 2011
What if you see this...
       20                  java.math.BigInteger::addOne (77 bytes)
       21                  java.math.BigInteger::squareToLen (172 bytes)
       22                  java.math.BigInteger::primitiveLeftShift (79 bytes)
      ---    n             java.lang.System::arraycopy (static)
       24                  sun.security.provider.SHA::implCompress (491 bytes)
       23                  java.math.BigInteger::montReduce (99 bytes)
       25                  java.lang.String$CaseInsensitiveComparator::compare (115
      bytes)
       26                  java.lang.Character::toLowerCase (162 bytes)

         Native calls don’t compile, may be
         intrinsic. We’ll come back to that.

Wednesday, July 27, 2011
PrintInlining

                    • -XX:+UnlockDiagnosticVMOptions
                           -XX:+PrintInlining
                    • Display hierarchy of inlined methods
                    • Include reasons for not inlining
                    • More, better output on OpenJDK 7

Wednesday, July 27, 2011
~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions 
      >              -XX:+PrintInlining 
      >              Accumulator 10000
      49995000




Wednesday, July 27, 2011
~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions 
      >              -XX:+PrintInlining 
      >              Accumulator 10000
      49995000

                           Um...I don’t see anything inlining...




Wednesday, July 27, 2011
public class Accumulator {
          public static void main(String[] args) {
              int max = Integer.parseInt(args[0]);
              System.out.println(addAll(max));
          }
                                                       Called once
                 static int addAll(int max) {
                     int accum = 0;
                     for (int i = 0; i < max; i++) {
                         accum = add(accum, i);
                     }
                     return accum;       Called 10k      times...
                 }

                 static int add(int a, int b) {
                     return a + b;
                 }                  ...but no calls   to inline!
      }

Wednesday, July 27, 2011
public class Accumulator2 {
          public static void main(String[] args) {
              int max = Integer.parseInt(args[0]);
              System.out.println(
                  new Accumulator2().addAllSqrts(max));
          }

               double addAllSqrts(int max) {
                   double accum = 0;
                   for (int i = 0; i < max; i++) {
                       accum = addSqrt(accum, i);
                   }
                   return accum;
               }

               double addSqrt(double a, int b) {
                   return a + sqrt(b);
               }

               double sqrt(int b) {
                   return Math.sqrt(b);
               }
      }
Wednesday, July 27, 2011
~/oscon ➔ java           -XX:+UnlockDiagnosticVMOptions 
      >                        -XX:+PrintCompilation 
      >
      >
                               -XX:+PrintInlining 
                               Accumulator2 10000                            A hot spot!
      ...
           89    2                      Accumulator2::addSqrt (8 bytes)
                                           @ 3   Accumulator2::sqrt (6 bytes)   inline (hot)
                                             @ 2   java.lang.Math::sqrt (5 bytes)   (intrinsic)
               89          3            Accumulator2::sqrt (6 bytes)
                                           @ 2   java.lang.Math::sqrt (5 bytes)   (intrinsic)
      666616.4591971082

                                                           Calls treated specially by JIT




Wednesday, July 27, 2011
Intrinsic?

                    • Known to the JIT
                     • Don’t inline the bytecode
                     • Do perform a specific native operation
                       • e.g. kernel-level memory operation
                       • e.g. optimized sqrt in machine code

Wednesday, July 27, 2011
Did Someone Say
                           MACHINE CODE?


Wednesday, July 27, 2011
The Red Pill

                    • Knowing code compiles is good
                    • Knowing code inlines is better
                    • Seeing the actual assembly is best!


Wednesday, July 27, 2011
Caveat


                    • I don’t really know assembly.
                    • But I fake it really well.


Wednesday, July 27, 2011
PrintAssembly

                    • -XX:+PrintAssembly
                    • Google “hotspot printassembly”
                    • http://wikis.sun.com/display/
                           HotSpotInternals/PrintAssembly
                    • Assembly dumping plugins

Wednesday, July 27, 2011
~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions 
      >              -XX:+PrintAssembly 
      >              Accumulator 10000
      OpenJDK 64-Bit Server VM warning: PrintAssembly is enabled;
      turning on DebugNonSafepoints to gain additional output
      Loaded disassembler from hsdis-amd64.dylib
      ...




Wednesday, July 27, 2011
Decoding compiled method 11343cbd0:
      Code:
      [Disassembling for mach='i386:x86-64']
      [Entry Point]
      [Verified Entry Point]
      [Constants]
        # {method} 'add' '(II)I' in 'Accumulator'
        # parm0:    rsi        = int
        # parm1:    rdx        = int
        #           [sp+0x20] (sp of caller)
        11343cd00: push   %rbp
        11343cd01: sub    $0x10,%rsp
        11343cd05: nop                              ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq




Wednesday, July 27, 2011
Woah there, buddy.



Wednesday, July 27, 2011
x86_64 Assembly 101
                                  add                Two’s complement add
                                  sub                       ...subtract
                                 mov*                 Move data from a to b
                                  jmp                           goto
                           je, jne, jl, jge, ...      Jump if ==, !=, <, >=, ...
                              push, pop           Push/pop to/from call stack
                              call*, ret*        Call or return from subroutine
                           eax, ebx, esi, ...                Registers
                           rdx, rbx, rsi, ...            64-bit registers


Wednesday, July 27, 2011
Register Machine

                    • Instead of stack moves, we have “slots”
                    • Move data into slots
                    • Call operations that work with slots
                    • Get new data out of slots
                    • JVM stack, locals end up as register ops

Wednesday, July 27, 2011
Stack?
                    • Native code has a stack too
                     • Maintains context from call to call
                    • Calling conventions
                     • Caller preserves registers?
                     • Callee preserves registers?
                     • Many different styles
Wednesday, July 27, 2011
Decoding compiled method 11343cbd0:           <= address of new compiled code
      Code:
      [Disassembling for mach='i386:x86-64']        <= architecture
      [Entry Point]
      [Verified Entry Point]
      [Constants]
        # {method} 'add' '(II)I' in 'Accumulator'   <=   method, signature, class
        # parm0:    rsi       = int                 <=   first parm to method goes in rsi
        # parm1:    rdx       = int                 <=   second parm goes in rdx
        #           [sp+0x20] (sp of caller)        <=   caller’s pointer into native stack




Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



            rbp points at current stack frame, so we save it off.



Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



                    Two args, so we bump stack pointer by 0x10.



Wednesday, July 27, 2011
11343cd00: push       %rbp
         11343cd01: sub        $0x10,%rsp
         11343cd05: nop                                 ;*synchronization entry
                                                        ; - Accumulator::add@-1 (line 16)
         11343cd06: mov        %esi,%eax
         11343cd08: add        %edx,%eax                ;*iadd
                                                        ; - Accumulator::add@2 (line 16)
         11343cd0a: add        $0x10,%rsp
         11343cd0e: pop        %rbp
         11343cd0f: test       %eax,-0x1303fd15(%rip)     # 1003fd000
                                                        ;   {poll_return}
         11343cd15: retq



                           Do nothing, e.g. to memory-align code.



Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq

                   At the “-1” instruction of our add() method...
                                   i.e. here we go!


Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



                                Move parm1 into eax.



Wednesday, July 27, 2011
11343cd00: push         %rbp
         11343cd01: sub          $0x10,%rsp
         11343cd05: nop                                   ;*synchronization entry
                                                          ; - Accumulator::add@-1 (line 16)
         11343cd06: mov          %esi,%eax
         11343cd08: add          %edx,%eax                ;*iadd
                                                          ; - Accumulator::add@2 (line 16)
         11343cd0a: add          $0x10,%rsp
         11343cd0e: pop          %rbp
         11343cd0f: test         %eax,-0x1303fd15(%rip)     # 1003fd000
                                                          ;   {poll_return}
         11343cd15: retq



                           Add parm0 and parm1, store result in eax.



Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



             How nice, Hotspot shows us this is our “iadd” op!



Wednesday, July 27, 2011
11343cd00: push      %rbp
         11343cd01: sub       $0x10,%rsp
         11343cd05: nop                                ;*synchronization entry
                                                       ; - Accumulator::add@-1 (line 16)
         11343cd06: mov       %esi,%eax
         11343cd08: add       %edx,%eax                ;*iadd
                                                       ; - Accumulator::add@2 (line 16)
         11343cd0a: add       $0x10,%rsp
         11343cd0e: pop       %rbp
         11343cd0f: test      %eax,-0x1303fd15(%rip)     # 1003fd000
                                                       ;   {poll_return}
         11343cd15: retq



                           Put stack pointer back where it was.



Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



                              Restore rbp from stack.



Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



               Poll a “safepoint”...give JVM a chance to GC, etc.



Wednesday, July 27, 2011
11343cd00: push   %rbp
         11343cd01: sub    $0x10,%rsp
         11343cd05: nop                             ;*synchronization entry
                                                    ; - Accumulator::add@-1 (line 16)
         11343cd06: mov    %esi,%eax
         11343cd08: add    %edx,%eax                ;*iadd
                                                    ; - Accumulator::add@2 (line 16)
         11343cd0a: add    $0x10,%rsp
         11343cd0e: pop    %rbp
         11343cd0f: test   %eax,-0x1303fd15(%rip)     # 1003fd000
                                                    ;   {poll_return}
         11343cd15: retq



                                          All done!



Wednesday, July 27, 2011
Things to Watch For

                    • CALL operations
                     • Indicate something failed to inline
                    • LOCK operations
                     • Cache-busting, e.g. volatility

Wednesday, July 27, 2011
CALL
         1134858f5: xchg    %ax,%ax
         1134858f7: callq   113414aa0   ; OopMap{off=316}
                                        ;*invokespecial addAsBignum
                                        ; - org.jruby.RubyFixnum::addFixnum@29 (line 348)
                                        ;   {optimized virtual_call}
         1134858fc: jmpq    11348586d




 Ruby integer adds might overflow into Bignum, leading to
 addAsBignum call. In this case, it’s never called, so Hotspot
           emits callq assuming we won’t hit it.


Wednesday, July 27, 2011
LOCK
          Code from a RubyBasicObject’s default constructor.
         11345d823: mov    0x70(%r8),%r9d    ;*getstatic NULL_OBJECT_ARRAY
                                             ; - org.jruby.RubyBasicObject::<init>@5 (line 76)
                                             ; - org.jruby.RubyObject::<init>@2 (line 118)
                                             ; - org.jruby.RubyNumeric::<init>@2 (line 111)
                                             ; - org.jruby.RubyInteger::<init>@2 (line 95)
                                             ; - org.jruby.RubyFixnum::<init>@5 (line 112)
                                             ; - org.jruby.RubyFixnum::newFixnum@25 (line 173)
         11345d827: mov    %r9d,0x14(%rax)
         11345d82b: lock addl $0x0,(%rsp)    ;*putfield varTable
                                             ; - org.jruby.RubyBasicObject::<init>@8 (line 76)
                                             ; - org.jruby.RubyObject::<init>@2 (line 118)
                                             ; - org.jruby.RubyNumeric::<init>@2 (line 111)
                                             ; - org.jruby.RubyInteger::<init>@2 (line 95)
                                             ; - org.jruby.RubyFixnum::<init>@5 (line 112)
                                             ; - org.jruby.RubyFixnum::newFixnum@25 (line 173)


        Why are we doing a volatile write in the constructor?


Wednesday, July 27, 2011
LOCK
      public class RubyBasicObject ... {
          private static final boolean DEBUG = false;
          private static final Object[] NULL_OBJECT_ARRAY = new Object[0];

               // The class of this object
               protected transient RubyClass metaClass;

               // zeroed by jvm
               protected int flags;

               // variable table, lazily allocated as needed (if needed)
               private volatile Object[] varTable = NULL_OBJECT_ARRAY;



         Maybe it’s not such a good idea to pre-init a volatile?
Wednesday, July 27, 2011
LOCK

      ~/projects/jruby ➔ git log 2f935de1e40bfd8b29b3a74eaed699e519571046 -1 | cat
      commit 2f935de1e40bfd8b29b3a74eaed699e519571046
      Author: Charles Oliver Nutter <headius@headius.com>
      Date:   Tue Jun 14 02:59:41 2011 -0500

          Do not eagerly initialize volatile varTable field in RubyBasicObject;
      speeds object creation significantly.




             LEVEL UP!
Wednesday, July 27, 2011
What have we learned?

                    • How to emit bytecode
                    • How to read bytecode
                    • How bytecode execution works
                    • How to monitor the Hotspot JIT
                    • How to find problems from asm code

Wednesday, July 27, 2011
You’re no dummy now.
                             ;-)


Wednesday, July 27, 2011
Thank you!

                    • headius@headius.com, @headius
                    • http://blog.headius.com
                    • http://github.com/headius/bitescript
                    • “java virtual machine specification”
                    • “jvm opcodes”

Wednesday, July 27, 2011
Ad

More Related Content

What's hot (20)

Hibernate tutorial
Hibernate tutorialHibernate tutorial
Hibernate tutorial
Mumbai Academisc
 
Java Garbage Collection - How it works
Java Garbage Collection - How it worksJava Garbage Collection - How it works
Java Garbage Collection - How it works
Mindfire Solutions
 
Multithreading In Java
Multithreading In JavaMultithreading In Java
Multithreading In Java
parag
 
Java Exception handling
Java Exception handlingJava Exception handling
Java Exception handling
kamal kotecha
 
Collections In Java
Collections In JavaCollections In Java
Collections In Java
Binoj T E
 
Django forms
Django formsDjango forms
Django forms
Rubin Damian
 
Java multi threading
Java multi threadingJava multi threading
Java multi threading
Raja Sekhar
 
Introduction to java
Introduction to javaIntroduction to java
Introduction to java
Ajay Sharma
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
Jeevesh Pandey
 
Python GC
Python GCPython GC
Python GC
delimitry
 
Presentation swagger
Presentation swaggerPresentation swagger
Presentation swagger
François Robert
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
José Paumard
 
SQL Injection Defense in Python
SQL Injection Defense in PythonSQL Injection Defense in Python
SQL Injection Defense in Python
Public Broadcasting Service
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
Jonathan Holloway
 
Jvm Architecture
Jvm ArchitectureJvm Architecture
Jvm Architecture
ThirupathiReddy Vajjala
 
Computer Science:Java jdbc
Computer Science:Java jdbcComputer Science:Java jdbc
Computer Science:Java jdbc
St Mary's College,Thrissur,Kerala
 
Java(Polymorphism)
Java(Polymorphism)Java(Polymorphism)
Java(Polymorphism)
harsh kothari
 
JAVA Polymorphism
JAVA PolymorphismJAVA Polymorphism
JAVA Polymorphism
Mahi Mca
 
Java beans
Java beansJava beans
Java beans
sptatslide
 
MULTI THREADING IN JAVA
MULTI THREADING IN JAVAMULTI THREADING IN JAVA
MULTI THREADING IN JAVA
VINOTH R
 

Similar to JVM for Dummies - OSCON 2011 (20)

JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
Charles Nutter
 
Introduction to Java 7 (OSCON 2012)
Introduction to Java 7 (OSCON 2012)Introduction to Java 7 (OSCON 2012)
Introduction to Java 7 (OSCON 2012)
Martijn Verburg
 
JRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyJRuby - The Best of Java and Ruby
JRuby - The Best of Java and Ruby
Evgeny Rahman
 
java basics concepts and the keywords needed
java basics concepts and the keywords neededjava basics concepts and the keywords needed
java basics concepts and the keywords needed
PriyadharshiniG41
 
The Evolution of Java
The Evolution of JavaThe Evolution of Java
The Evolution of Java
Fu Cheng
 
Presentation on java
Presentation  on  javaPresentation  on  java
Presentation on java
shashi shekhar
 
Java Introduction
Java IntroductionJava Introduction
Java Introduction
sunmitraeducation
 
JAVA PROGRAM CONSTRUCTS OR LANGUAGE BASICS.pptx
JAVA PROGRAM CONSTRUCTS OR LANGUAGE BASICS.pptxJAVA PROGRAM CONSTRUCTS OR LANGUAGE BASICS.pptx
JAVA PROGRAM CONSTRUCTS OR LANGUAGE BASICS.pptx
AALIM MUHAMMED SALEGH COLLEGE OF ENGINEERING
 
JAVAPart1_BasicIntroduction.pptx
JAVAPart1_BasicIntroduction.pptxJAVAPart1_BasicIntroduction.pptx
JAVAPart1_BasicIntroduction.pptx
Murugesh33
 
JAVA_Day1_BasicIntroduction.pptx
JAVA_Day1_BasicIntroduction.pptxJAVA_Day1_BasicIntroduction.pptx
JAVA_Day1_BasicIntroduction.pptx
Murugesh33
 
Java (1)
Java (1)Java (1)
Java (1)
Samraiz Tejani
 
T4T Training day - NodeJS
T4T Training day - NodeJST4T Training day - NodeJS
T4T Training day - NodeJS
Tim Sommer
 
every-day-automation
every-day-automationevery-day-automation
every-day-automation
Amir Barylko
 
Object Oriented Programming Part 1 of Unit 1
Object Oriented Programming Part 1 of Unit 1Object Oriented Programming Part 1 of Unit 1
Object Oriented Programming Part 1 of Unit 1
VigneshkumarPonnusam1
 
Java: Rumours of my demise are greatly exaggerated
Java: Rumours of my demise are greatly exaggeratedJava: Rumours of my demise are greatly exaggerated
Java: Rumours of my demise are greatly exaggerated
Steve Dalton
 
1.Intro--Why Java.pptx
1.Intro--Why Java.pptx1.Intro--Why Java.pptx
1.Intro--Why Java.pptx
YounasKhan542109
 
Java 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureJava 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the future
Sander Mak (@Sander_Mak)
 
1 Module 1 Introduction.pptx
1 Module 1 Introduction.pptx1 Module 1 Introduction.pptx
1 Module 1 Introduction.pptx
BhargaviDalal3
 
Java Presentation
Java PresentationJava Presentation
Java Presentation
Amr Salah
 
2011 JavaOne Apache TomEE Java EE 6 Web Profile
2011 JavaOne Apache TomEE Java EE 6 Web Profile2011 JavaOne Apache TomEE Java EE 6 Web Profile
2011 JavaOne Apache TomEE Java EE 6 Web Profile
David Blevins
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
Charles Nutter
 
Introduction to Java 7 (OSCON 2012)
Introduction to Java 7 (OSCON 2012)Introduction to Java 7 (OSCON 2012)
Introduction to Java 7 (OSCON 2012)
Martijn Verburg
 
JRuby - The Best of Java and Ruby
JRuby - The Best of Java and RubyJRuby - The Best of Java and Ruby
JRuby - The Best of Java and Ruby
Evgeny Rahman
 
java basics concepts and the keywords needed
java basics concepts and the keywords neededjava basics concepts and the keywords needed
java basics concepts and the keywords needed
PriyadharshiniG41
 
The Evolution of Java
The Evolution of JavaThe Evolution of Java
The Evolution of Java
Fu Cheng
 
JAVAPart1_BasicIntroduction.pptx
JAVAPart1_BasicIntroduction.pptxJAVAPart1_BasicIntroduction.pptx
JAVAPart1_BasicIntroduction.pptx
Murugesh33
 
JAVA_Day1_BasicIntroduction.pptx
JAVA_Day1_BasicIntroduction.pptxJAVA_Day1_BasicIntroduction.pptx
JAVA_Day1_BasicIntroduction.pptx
Murugesh33
 
T4T Training day - NodeJS
T4T Training day - NodeJST4T Training day - NodeJS
T4T Training day - NodeJS
Tim Sommer
 
every-day-automation
every-day-automationevery-day-automation
every-day-automation
Amir Barylko
 
Object Oriented Programming Part 1 of Unit 1
Object Oriented Programming Part 1 of Unit 1Object Oriented Programming Part 1 of Unit 1
Object Oriented Programming Part 1 of Unit 1
VigneshkumarPonnusam1
 
Java: Rumours of my demise are greatly exaggerated
Java: Rumours of my demise are greatly exaggeratedJava: Rumours of my demise are greatly exaggerated
Java: Rumours of my demise are greatly exaggerated
Steve Dalton
 
Java 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureJava 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the future
Sander Mak (@Sander_Mak)
 
1 Module 1 Introduction.pptx
1 Module 1 Introduction.pptx1 Module 1 Introduction.pptx
1 Module 1 Introduction.pptx
BhargaviDalal3
 
Java Presentation
Java PresentationJava Presentation
Java Presentation
Amr Salah
 
2011 JavaOne Apache TomEE Java EE 6 Web Profile
2011 JavaOne Apache TomEE Java EE 6 Web Profile2011 JavaOne Apache TomEE Java EE 6 Web Profile
2011 JavaOne Apache TomEE Java EE 6 Web Profile
David Blevins
 
Ad

More from Charles Nutter (20)

The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
Charles Nutter
 
Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM Wonderland
Charles Nutter
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016
Charles Nutter
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
Charles Nutter
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015
Charles Nutter
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
Charles Nutter
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
Charles Nutter
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!
Charles Nutter
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method Handles
Charles Nutter
 
Over 9000: JRuby in 2015
Over 9000: JRuby in 2015Over 9000: JRuby in 2015
Over 9000: JRuby in 2015
Charles Nutter
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right Way
Charles Nutter
 
JRuby: The Hard Parts
JRuby: The Hard PartsJRuby: The Hard Parts
JRuby: The Hard Parts
Charles Nutter
 
Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014
Charles Nutter
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
Charles Nutter
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013
Charles Nutter
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
Charles Nutter
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
Charles Nutter
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
Charles Nutter
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
Charles Nutter
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 Minutes
Charles Nutter
 
The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018The Year of JRuby - RubyC 2018
The Year of JRuby - RubyC 2018
Charles Nutter
 
Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM Wonderland
Charles Nutter
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016
Charles Nutter
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
Charles Nutter
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015
Charles Nutter
 
JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
Charles Nutter
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
Charles Nutter
 
Open Source Software Needs You!
Open Source Software Needs You!Open Source Software Needs You!
Open Source Software Needs You!
Charles Nutter
 
InvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method HandlesInvokeBinder: Fluent Programming for Method Handles
InvokeBinder: Fluent Programming for Method Handles
Charles Nutter
 
Over 9000: JRuby in 2015
Over 9000: JRuby in 2015Over 9000: JRuby in 2015
Over 9000: JRuby in 2015
Charles Nutter
 
Doing Open Source the Right Way
Doing Open Source the Right WayDoing Open Source the Right Way
Doing Open Source the Right Way
Charles Nutter
 
Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014Bringing Concurrency to Ruby - RubyConf India 2014
Bringing Concurrency to Ruby - RubyConf India 2014
Charles Nutter
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
Charles Nutter
 
Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013Beyond JVM - YOW! Brisbane 2013
Beyond JVM - YOW! Brisbane 2013
Charles Nutter
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
Charles Nutter
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
Charles Nutter
 
High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013High Performance Ruby - E4E Conference 2013
High Performance Ruby - E4E Conference 2013
Charles Nutter
 
Invokedynamic in 45 Minutes
Invokedynamic in 45 MinutesInvokedynamic in 45 Minutes
Invokedynamic in 45 Minutes
Charles Nutter
 
Ad

Recently uploaded (20)

The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...
The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...
The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...
SOFTTECHHUB
 
UiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer OpportunitiesUiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer Opportunities
DianaGray10
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Viam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdfViam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdf
camilalamoratta
 
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
James Anderson
 
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptxReimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
John Moore
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
AI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdfAI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdf
Precisely
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Play It Safe: Manage Security Risks - Google Certificate
Play It Safe: Manage Security Risks - Google CertificatePlay It Safe: Manage Security Risks - Google Certificate
Play It Safe: Manage Security Risks - Google Certificate
VICTOR MAESTRE RAMIREZ
 
Webinar - Top 5 Backup Mistakes MSPs and Businesses Make .pptx
Webinar - Top 5 Backup Mistakes MSPs and Businesses Make   .pptxWebinar - Top 5 Backup Mistakes MSPs and Businesses Make   .pptx
Webinar - Top 5 Backup Mistakes MSPs and Businesses Make .pptx
MSP360
 
Q1 2025 Dropbox Earnings and Investor Presentation
Q1 2025 Dropbox Earnings and Investor PresentationQ1 2025 Dropbox Earnings and Investor Presentation
Q1 2025 Dropbox Earnings and Investor Presentation
Dropbox
 
Web and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in RajpuraWeb and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in Rajpura
Erginous Technology
 
Foundations of Cybersecurity - Google Certificate
Foundations of Cybersecurity - Google CertificateFoundations of Cybersecurity - Google Certificate
Foundations of Cybersecurity - Google Certificate
VICTOR MAESTRE RAMIREZ
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
AI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of DocumentsAI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of Documents
UiPathCommunity
 
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and MLGyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
Gyrus AI
 
TrsLabs Consultants - DeFi, WEb3, Token Listing
TrsLabs Consultants - DeFi, WEb3, Token ListingTrsLabs Consultants - DeFi, WEb3, Token Listing
TrsLabs Consultants - DeFi, WEb3, Token Listing
Trs Labs
 
fennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solutionfennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solution
shallal2
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...
The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...
The No-Code Way to Build a Marketing Team with One AI Agent (Download the n8n...
SOFTTECHHUB
 
UiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer OpportunitiesUiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer Opportunities
DianaGray10
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Viam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdfViam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdf
camilalamoratta
 
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
James Anderson
 
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptxReimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
John Moore
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
AI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdfAI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdf
Precisely
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Play It Safe: Manage Security Risks - Google Certificate
Play It Safe: Manage Security Risks - Google CertificatePlay It Safe: Manage Security Risks - Google Certificate
Play It Safe: Manage Security Risks - Google Certificate
VICTOR MAESTRE RAMIREZ
 
Webinar - Top 5 Backup Mistakes MSPs and Businesses Make .pptx
Webinar - Top 5 Backup Mistakes MSPs and Businesses Make   .pptxWebinar - Top 5 Backup Mistakes MSPs and Businesses Make   .pptx
Webinar - Top 5 Backup Mistakes MSPs and Businesses Make .pptx
MSP360
 
Q1 2025 Dropbox Earnings and Investor Presentation
Q1 2025 Dropbox Earnings and Investor PresentationQ1 2025 Dropbox Earnings and Investor Presentation
Q1 2025 Dropbox Earnings and Investor Presentation
Dropbox
 
Web and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in RajpuraWeb and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in Rajpura
Erginous Technology
 
Foundations of Cybersecurity - Google Certificate
Foundations of Cybersecurity - Google CertificateFoundations of Cybersecurity - Google Certificate
Foundations of Cybersecurity - Google Certificate
VICTOR MAESTRE RAMIREZ
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
AI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of DocumentsAI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of Documents
UiPathCommunity
 
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and MLGyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
Gyrus AI
 
TrsLabs Consultants - DeFi, WEb3, Token Listing
TrsLabs Consultants - DeFi, WEb3, Token ListingTrsLabs Consultants - DeFi, WEb3, Token Listing
TrsLabs Consultants - DeFi, WEb3, Token Listing
Trs Labs
 
fennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solutionfennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solution
shallal2
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 

JVM for Dummies - OSCON 2011

  • 1. JVM for Dummies (and for the rest of you, as well) Wednesday, July 27, 2011
  • 2. Intro • Charles Oliver Nutter • “JRuby Guy” • Sun Microsystems 2006-2009 • Engine Yard 2009- • Primarily responsible for compiler, perf • Lots of bytecode generation • Lots of JIT monitoring Wednesday, July 27, 2011
  • 3. Today • JVM Bytecode • Inspection • Generation • How it works • JVM JIT • How it works • Monitoring • Assembly (don’t be scared!) Wednesday, July 27, 2011
  • 4. Today • JVM Bytecode • • • Inspection Generation } For Dummies } How it works • JVM JIT • How it works For people who want • Monitoring to feel like Dummies • Assembly Wednesday, July 27, 2011
  • 5. Part One: Bytecode Wednesday, July 27, 2011
  • 6. Bytecode Definition • “... instruction sets designed for efficient execution by a software interpreter ...” • “... suitable for further compilation into machine code. Wednesday, July 27, 2011
  • 7. Byte Code • One-byte instructions • 256 possible “opcodes” • 200 in use on current JVMs • Room for more :-) • Little variation since Java 1.0 Wednesday, July 27, 2011
  • 8. Microsoft’s CLR • Stack-based, but not interpreted • Two-byte “Wordcodes” • Similar operations to JVM Wednesday, July 27, 2011
  • 9. Why Learn It • Know your platform • Full understanding from top to bottom • Bytecode generation is fun and easy • Build your own language? • May need to read bytecode someday • Many libraries generate bytecode Wednesday, July 27, 2011
  • 10. Hello World public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, world"); } } Wednesday, July 27, 2011
  • 11. javap • Java class file disassembler • Basic operation shows class structure • Methods, superclasses, interface, etc • -c flag includes bytecode • -public, -private, -protected • -verbose for stack size, locals, args Wednesday, July 27, 2011
  • 12. javap ~/projects/bytecode_for_dummies ➔ javap HelloWorld Compiled from "HelloWorld.java" public class HelloWorld extends java.lang.Object{ public HelloWorld(); public static void main(java.lang.String[]); } Wednesday, July 27, 2011
  • 13. javap -c ~/projects/bytecode_for_dummies ➔ javap -c HelloWorld Compiled from "HelloWorld.java" public class HelloWorld extends java.lang.Object{ public HelloWorld(); Code: 0:! aload_0 1:! invokespecial!#1; //Method java/lang/Object."<init>":()V 4:! return public static void main(java.lang.String[]); Code: 0:! getstatic! #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3:! ldc!#3; //String Hello, world 5:! invokevirtual!#4; //Method java/io/PrintStream.println: (Ljava/lang/String;)V 8:! return } Wednesday, July 27, 2011
  • 14. javap -verbose ~/projects/bytecode_for_dummies ➔ javap -c -verbose HelloWorld Compiled from "HelloWorld.java" public class HelloWorld extends java.lang.Object SourceFile: "HelloWorld.java" minor version: 0 major version: 50 Constant pool: const #1 = Method! #6.#15;!// java/lang/Object."<init>":()V const #2 = Field!#16.#17;! / java/lang/System.out:Ljava/io/PrintStream; / const #3 = String! #18;! / Hello, world / const #4 = Method! #19.#20;! / java/io/PrintStream.println:(Ljava/lang/String;)V / const #5 = class!#21;! / HelloWorld / ... { Wednesday, July 27, 2011
  • 15. javap -verbose ... public HelloWorld(); Code: Stack=1, Locals=1, Args_size=1 0:!aload_0 1:!invokespecial! #1; //Method java/lang/Object."<init>":()V 4:!return LineNumberTable: line 1: 0 Wednesday, July 27, 2011
  • 16. javap -verbose public static void main(java.lang.String[]); Code: Stack=2, Locals=1, Args_size=1 0:! getstatic!#2; //Field java/lang/System.out:Ljava/io/PrintStream; 3:! ldc! #3; //String Hello, world 5:! invokevirtual! #4; //Method java/io/PrintStream.println: (Ljava/lang/String;)V 8:! return LineNumberTable: line 3: 0 line 4: 8 } Wednesday, July 27, 2011
  • 18. Thank you! (Just Kidding) Wednesday, July 27, 2011
  • 19. Let’s try something a little easier... Wednesday, July 27, 2011
  • 20. BiteScript • (J)Ruby DSL for emitting JVM bytecode • Internal DSL • Primitive “macro” support • Reads like javap -c (but nicer) • http://github.com/headius/bitescript Wednesday, July 27, 2011
  • 21. Installation • Download JRuby from http://jruby.org • Unpack, optionally add bin/ to PATH • Ahead of PATH if you have Ruby already • [bin/]jruby -S gem install bitescript • `bite myfile.bs` to run myfile.bs file • `bitec myfile.bs` to compile myfile.bs file Wednesday, July 27, 2011
  • 22. BiteScript Users • Mirah • Ruby-like language for writing Java code • BiteScript for JVM bytecode backend • BrainF*ck implementation • Other miscellaneous bytecode experiments Wednesday, July 27, 2011
  • 23. javap -c ~/projects/bytecode_for_dummies ➔ javap -c HelloWorld Compiled from "HelloWorld.java" public class HelloWorld extends java.lang.Object{ public HelloWorld(); Code: 0:! aload_0 1:! invokespecial!#1; //Method java/lang/Object."<init>":()V 4:! return public static void main(java.lang.String[]); Code: 0:! getstatic! #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3:! ldc!#3; //String Hello, world 5:! invokevirtual!#4; //Method java/io/PrintStream.println: (Ljava/lang/String;)V 8:! return } Wednesday, July 27, 2011
  • 24. BiteScript main do getstatic java.lang.System, "out", java.io.PrintStream ldc "Hello, world!" invokevirtual java.io.PrintStream, "println", [java.lang.Void::TYPE, java.lang.Object] returnvoid end Wednesday, July 27, 2011
  • 25. BiteScript import java.lang.System JRuby’s “import” import java.io.PrintStream for Java classes main do getstatic System, "out", PrintStream ldc "Hello, world!" invokevirtual PrintStream, "println", [void, object] returnvoid end Shortcuts for void, int, string, object, etc Wednesday, July 27, 2011
  • 26. BiteScript main do ldc "Hello, world!" aprintln returnvoid A BiteScript “macro” end Wednesday, July 27, 2011
  • 27. BiteScript macro :aprintln do getstatic System, "out", PrintStream swap invokevirtual PrintStream, "println", [void, object] end Wednesday, July 27, 2011
  • 28. The Basics • Stack machine • Basic operations • Flow control • Class structures • Exception handling Wednesday, July 27, 2011
  • 29. Stack Machine • The “operand stack” holds operands • Operations push and/or pop stack values • Exceptions: nop, wide, goto, jsr/ret • Stack must be consistent • Largest part of bytecode verifier • Stack is explicitly sized per method Wednesday, July 27, 2011
  • 30. The JVM Stack Depth Value import java.lang.System import java.io.PrintStream 0 main do 1 getstatic System, "out", PrintStream ldc "Hello, world!" invokevirtual PrintStream, "println", 2 [void, object] returnvoid 3 end 4 Wednesday, July 27, 2011
  • 31. The JVM Stack Depth Value import java.lang.System import java.io.PrintStream 0 out (a PS) main do 1 getstatic System, "out", PrintStream ldc "Hello, world!" invokevirtual PrintStream, "println", 2 [void, object] returnvoid 3 end 4 Wednesday, July 27, 2011
  • 32. The JVM Stack Depth Value import java.lang.System import java.io.PrintStream 0 “Hello, world!” main do 1 out (a PS) getstatic System, "out", PrintStream ldc "Hello, world!" invokevirtual PrintStream, "println", 2 [void, object] returnvoid 3 end 4 Wednesday, July 27, 2011
  • 33. The JVM Stack Depth Value import java.lang.System import java.io.PrintStream 0 main do 1 getstatic System, "out", PrintStream ldc "Hello, world!" invokevirtual PrintStream, "println", 2 [void, object] returnvoid 3 end 4 Wednesday, July 27, 2011
  • 34. The JVM Stack Depth Value import java.lang.System import java.io.PrintStream 0 main do 1 getstatic System, "out", PrintStream ldc "Hello, world!" invokevirtual PrintStream, "println", 2 [void, object] returnvoid 3 end 4 Wednesday, July 27, 2011
  • 35. Basic Operations • Stack manipulation • Local variables • Math • Boolean Wednesday, July 27, 2011
  • 36. Stack Operations 0x00 nop Do nothing. 0x57 pop Discard top value from stack 0x58 pop2 Discard top two values 0x59 dup Duplicate and push top value again 0x5A dup_x1 Dup and push top value below second value 0x5B dup_x2 Dup and push top value below third value 0x5C dup2 Dup top two values and push 0x5D dup2_x1 ...below second value 0x5E dup2_x2 ...below third value 0x5F swap Swap top two values Wednesday, July 27, 2011
  • 37. Stack Juggling Depth Value dup 0 value_0 pop swap 1 value_1 dup_x1 2 dup2_x2 3 4 Wednesday, July 27, 2011
  • 38. Stack Juggling Depth Value dup 0 value_0 pop swap 1 value_0 dup_x1 2 value_1 dup2_x2 3 4 Wednesday, July 27, 2011
  • 39. Stack Juggling Depth Value dup 0 value_0 pop swap 1 value_1 dup_x1 2 dup2_x2 3 4 Wednesday, July 27, 2011
  • 40. Stack Juggling Depth Value dup 0 value_1 pop swap 1 value_0 dup_x1 2 dup2_x2 3 4 Wednesday, July 27, 2011
  • 41. Stack Juggling Depth Value dup 0 value_1 pop swap 1 value_0 dup_x1 2 value_1 dup2_x2 3 4 Wednesday, July 27, 2011
  • 42. Stack Juggling Depth Value dup 0 value_1 pop swap 1 value_0 dup_x1 2 value_1 dup2_x2 3 value_1 4 value_0 Wednesday, July 27, 2011
  • 43. Typed Opcodes <type><operation> b byte Constant values s short Local vars (load, store) c char Array operations (aload, astore) i int Math ops (add, sub, mul, div) l long Boolean and bitwise f float d double Comparisons a reference Conversions Wednesday, July 27, 2011
  • 44. Where’s boolean? • Boolean is generally int 0 or 1 • Boolean operations push int 0 or 1 • Boolean branches expect 0 or nonzero • To set a boolean...use int 0 or 1 Wednesday, July 27, 2011
  • 45. Constant Values 0x01 aconst_null Push null on stack 0x02-0x08 iload_[m1-5] Push integer [-1 to 5] on stack 0x09-0x0A lconst_[0,1] Push long [0 or 1] on stack 0x0B-0x0D fconst_[0,1,2] Push float [0.0, 1.0, 2.0] on stack 0x0E-0x0F dconst_[0,1] Push double [0.0, 1.0] on stack 0x10 bipush Push byte value to stack as integer 0x11 sipush Push short value to stack as integer 0x12 ldc Push 32-bit constant to stack (int, float, string) 0x14 ldc2_w Push 64-bit constant to stack (long, double) Wednesday, July 27, 2011
  • 46. Why So Many? • Reducing bytecode size • Special iconst_0 and friends take no args • bipush, sipush: only 8, 16 bits arguments • Pre-optimizing JVM • Specialized instructions can be optimized • Doesn’t matter at all now Wednesday, July 27, 2011
  • 47. Constant Values Depth Value ldc "hello" 0 dconst_1 1 aconst_null bipush 4 2 ldc_float 2.0 3 4 5 Wednesday, July 27, 2011
  • 48. Constant Values Depth Value ldc "hello" 0 “hello” dconst_1 1 aconst_null bipush 4 2 ldc_float 2.0 3 4 5 Wednesday, July 27, 2011
  • 49. Constant Values Depth Value ldc "hello" 0 dconst_1 1.0d 1 aconst_null bipush 4 2 “hello” ldc_float 2.0 3 4 5 Wednesday, July 27, 2011
  • 50. Woah, Two Slots? • JVM stack slots (and local vars) are 32-bit • 64-bit values take up two slots • “wide” before or “w” suffix • 64-bit field updates not atomic! • Mind those concurrent longs/doubles! Wednesday, July 27, 2011
  • 51. Constant Values Depth Value ldc "hello" 0 null dconst_1 1 aconst_null 1.0d bipush 4 2 ldc_float 2.0 3 “hello” 4 5 Wednesday, July 27, 2011
  • 52. Constant Values Depth Value ldc "hello" 0 4 dconst_1 1 null aconst_null bipush 4 2 ldc_float 2.0 1.0d 3 4 “hello” 5 Wednesday, July 27, 2011
  • 53. Constant Values Depth Value ldc "hello" 0 2.0f dconst_1 1 4 aconst_null bipush 4 2 null ldc_float 2.0 3 1.0 4 5 “hello” Wednesday, July 27, 2011
  • 54. Local Variable Table • Local variables numbered from 0 • Instance methods have “this” at 0 • Separate table maps numbers to names • Explicitly sized in method definition Wednesday, July 27, 2011
  • 55. Local Variables 0x15 iload Load integer from local variable onto stack 0x16 lload ...long... 0x17 fload ...float... 0x18 dload ...double... 0x19 aload ...reference... 0x1A-0x2D Packed loads iload_0, aload_3, etc 0x36 istore Store integer from stack into local variable 0x37 lstore ...long... 0x38 fstore ...float... 0x39 dstore ...double... 0x3A astore ...reference... 0x3B-0x4E Packed stores fstore_2, dstore_0, etc 0x84 iinc Add given amount to int local variable Wednesday, July 27, 2011
  • 56. Local Variables Var Value Depth Value ldc "hello" 0 bipush 4 0 istore 3 1 dconst_0 1 dstore 1 2 astore 0 2 aload 0 3 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 57. Local Variables Var Value Depth Value ldc "hello" 0 bipush 4 0 “hello” istore 3 1 dconst_0 1 dstore 1 2 astore 0 2 aload 0 3 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 58. Local Variables Var Value Depth Value ldc "hello" 0 bipush 4 0 4 istore 3 1 dconst_0 1 “hello” dstore 1 2 astore 0 2 aload 0 3 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 59. Local Variables Var Value Depth Value ldc "hello" 0 bipush 4 0 “hello” istore 3 1 dconst_0 1 dstore 1 2 astore 0 2 aload 0 3 4 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 60. Local Variables Var Value Depth Value ldc "hello" 0 bipush 4 0 istore 3 0.0 1 dconst_0 1 dstore 1 2 astore 0 2 “hello” aload 0 3 4 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 61. Local Variables Var Value Depth Value ldc "hello" 0 bipush 4 0 “hello” istore 3 1 dconst_0 1 0.0 dstore 1 2 astore 0 2 aload 0 3 4 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 62. Local Variables Var Value Depth Value ldc "hello" 0 “hello” bipush 4 0 istore 3 1 dconst_0 1 0.0 dstore 1 2 astore 0 2 aload 0 3 4 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 63. Local Variables Var Value Depth Value ldc "hello" 0 “hello” bipush 4 0 “hello” istore 3 1 dconst_0 1 0.0 dstore 1 2 astore 0 2 aload 0 3 4 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 64. Local Variables Var Value Depth Value ldc "hello" 0 “hello” bipush 4 0 “hello” istore 3 1 dconst_0 1 0.0 dstore 1 2 astore 0 2 aload 0 3 9 iinc 3, 5 3 4 4 Wednesday, July 27, 2011
  • 65. Arrays 0x2E-0x35 [i,l,f,d,a,b,c,d]aload Load [int, long, ...] from array (on stack) to stack 0x4F-0x56 [i,l,f,d,a,b,c,d]astore Store [int, long, ...] from stack to array (on stack) 0xBC newarray Construct new primitive array 0xBD anewarray Construct new reference array 0xBE arraylength Get array length 0xC5 multianewarray Create multi-dimensional array Wednesday, July 27, 2011
  • 66. Arrays Depth Value iconst_2 newarray int 0 dup iconst_0 1 iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 67. Arrays Depth Value iconst_2 newarray int 0 2 dup iconst_0 1 iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 68. Arrays Depth Value iconst_2 newarray int 0 int[2] {0,0} dup iconst_0 1 iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 69. Arrays Depth Value iconst_2 newarray int 0 int[2] {0,0} dup iconst_0 1 int[2] {0,0} iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 70. Arrays Depth Value iconst_2 newarray int 0 0 dup iconst_0 1 int[2] {0,0} iconst_m1 2 int[2] {0,0} iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 71. Arrays Depth Value iconst_2 newarray int 0 -1 dup iconst_0 1 0 iconst_m1 2 int[2] {0,0} iastore iconst_0 3 int[2] {0,0} iaload 4 5 Wednesday, July 27, 2011
  • 72. Arrays Depth Value iconst_2 newarray int 0 int[2] {-1, 0} dup iconst_0 1 iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 73. Arrays Depth Value iconst_2 newarray int 0 0 dup iconst_0 1 int[2] {-1, 0} iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 74. Arrays Depth Value iconst_2 newarray int 0 -1 dup iconst_0 1 iconst_m1 2 iastore iconst_0 3 iaload 4 5 Wednesday, July 27, 2011
  • 75. Math Operations add subtract multiply divide remainder negate + - * / % -() int iadd isub imul idiv irem ineg long ladd lsub lmul ldiv lrem lneg float fadd fsub fmul fdiv frem fneg double dadd dsub dmul ddiv drem dneg Wednesday, July 27, 2011
  • 76. Boolean and Bitwise unsigned shift left shift right and or xor shift right int ishl ishr iushr iand ior ixor Wednesday, July 27, 2011
  • 77. Conversions To: int long float double byte char short int - i2l i2f i2d i2b i2c i2s From: long l2i - l2f l2d - - - float f2i f2l - f2d - - - double d2i d2l d2f - - - - Wednesday, July 27, 2011
  • 78. Comparisons 0x94 lcmp Compare two longs, push int -1, 0, 1 0x95 fcmpl Compare two floats, push in -1, 0, 1 (-1 for NaN) 0x96 fcmpg Compare two floats, push in -1, 0, 1 (1 for NaN) 0x97 dcmpl Compare two doubles, push in -1, 0, 1 (-1 for NaN) 0x98 dcmpg Compare two doubles, push in -1, 0, 1 (1 for NaN) Wednesday, July 27, 2011
  • 79. Flow Control • Inspect stack and branch • Or just branch, via goto • Labels mark branch targets • Wide variety of tests Wednesday, July 27, 2011
  • 80. Flow Control 0x99 ifeq If zero on stack, branch 0x9A ifne If nonzero on stack, branch 0x9B iflt If stack value is less than zero, branch 0x9C ifge If stack value is greater than or equal to zero, branch 0x9D ifgt If stack value is greater than zero, branch 0x9E ifle If stack value is less than or equal to zero, branch 0x9F if_icmpeq If two integers on stack are eq, branch 0xA0 if_icmpne If two integers on stack are ne, branch 0xA1 if_icmplt If two integers on stack are lt, branch 0xA2 if_icmpge If two integers on stack are ge, branch 0xA3 if_icmpgt If tw If two integers on stack are gt, branch 0xA4 if_icmple If two integers on stack are le, branch 0xA5 if_acmpeq If two references on stack are the same, branch 0xA6 if_acmpne If two references on stack are different, branch 0xA7 goto GOTO! Wednesday, July 27, 2011
  • 81. Other Flow Control 0xA8 jsr Jump to subroutine (deprecated) 0xA9 ret Return from subroutine (deprecated) 0xAA tableswitch Branch using an indexed table of jump offsets 0xAB lookupswitch Branch using a lookup-based table of jump offsets 0xAC-0xB0 [i,l,f,d,a]return Return (int, long, float, double, reference) value 0xB1 return Void return (exit method, return nothing) 0xC6 ifnull If reference on stack is null 0xC7 ifnonnull If reference on stack is not null Wednesday, July 27, 2011
  • 82. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" String[] invokevirtual string, "equals", 0 {“branch”} [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 83. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 0 [boolean, object] ifne :branch 1 String[]{“branch”} ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 84. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 “branch” [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 85. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 “branch” [boolean, object] ifne :branch 1 “branch” ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 86. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 1 [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 87. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 88. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 89. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 “Equal!” [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 90. Flow Control aload 0 ldc 0 aaload Depth Value ldc "branch" invokevirtual string, "equals", 0 [boolean, object] ifne :branch 1 ldc "Not equal!" 2 aprintln goto :end 3 label :branch ldc "Equal!" 4 aprintln label :end 5 returnvoid Wednesday, July 27, 2011
  • 91. Classes and Types • Signatures!!! • Probably the most painful part • ...but not a big deal if you understand Wednesday, July 27, 2011
  • 92. Using Classes 0xB2 getstatic Fetch static field from class 0xB3 putstatic Set static field in class 0xB4 getfield Get instance field from object 0xB5 setfield Set instance field in object 0xB6 invokevirtual Invoke instance method on object 0xB7 invokespecial Invoke constructor or “super” on object 0xB8 invokestatic Invoke static method on class 0xB9 invokeinterface Invoke interface method on object 0xBA invokedynamic Invoke method dynamically on object (Java 7) 0xBB new Construct new instance of object 0xC0 checkcast Attempt to cast object to type 0xC1 instanceof Push nonzero if object is instanceof specified type Wednesday, July 27, 2011
  • 93. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] an ArrayList checkcast Collection 0 (uninitialized) dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 94. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] an ArrayList checkcast Collection 0 (uninitialized) dup an ArrayList ldc "first element" 1 (uninitialized) invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 95. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 an ArrayList dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 96. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 a Collection dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 97. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 a Collection dup ldc "first element" 1 a Collection invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 98. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] “first checkcast Collection 0 element” dup ldc "first element" 1 a Collection invokeinterface Collection, 'add', [boolean, object] 2 a Collection pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 99. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 1 (true) dup ldc "first element" 1 a Collection invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 100. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 a Collection dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 101. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 an ArrayList dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 102. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 0 dup ldc "first element" 1 an ArrayList invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 103. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] “first checkcast Collection 0 element” dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 104. Using Classes new ArrayList dup invokespecial ArrayList, '<init>', Depth Value [void] checkcast Collection 0 dup ldc "first element" 1 invokeinterface Collection, 'add', [boolean, object] 2 pop checkcast ArrayList 3 ldc 0 invokevirtual ArrayList, 'get', 4 [object, int] aprintln 5 returnvoid Wednesday, July 27, 2011
  • 105. Exceptions and Synchronization Table structure for a method indicating start/end of - trycatch try/catch and logic to run on exception 0xC2 monitorenter Enter synchronized block against object on stack 0xC3 monitorexit Exit synchronized block (against same object) Wednesday, July 27, 2011
  • 106. More Examples • A simple loop • Fibonacci Wednesday, July 27, 2011
  • 107. A Simple Loop main do aload 0 push_int 0 aaload label :top dup aprintln goto :top returnvoid end Wednesday, July 27, 2011
  • 108. Fibonacci public_static_method "fib", [], int, int do iload 0 ldc 2 if_icmpge :recurse iload 0 ireturn label :recurse iload 0 ldc 1 isub invokestatic this, "fib", [int, int] iload 0 ldc 2 isub invokestatic this, "fib", [int, int] iadd ireturn end Wednesday, July 27, 2011
  • 109. main do load_times istore 1 Fibonacci ldc "Raw bytecode fib(45) performance:" aprintln label :top iload 1 ifeq :done iinc 1, -1 start_timing 2 ldc 45 invokestatic this, "fib", [int, int] pop end_timing 2 ldc "Time: " aprintln lprintln 2 goto :top label :done returnvoid end Wednesday, July 27, 2011
  • 110. main do load_times istore 1 Fibonacci ldc "Raw bytecode fib(45) performance:" aprintln label :top iload 1 ifeq :done iinc 1, -1 start_timing 2 Macros ldc 45 invokestatic this, "fib", [int, int] pop end_timing 2 ldc "Time: " aprintln lprintln 2 goto :top label :done returnvoid end Wednesday, July 27, 2011
  • 111. Fibonacci macro :load_times do aload 0 ldc 0 aaload # number of times invokestatic JInteger, 'parseInt', [int, string] end Wednesday, July 27, 2011
  • 112. Fibonacci macro :start_timing do |i| load_time lstore i end Wednesday, July 27, 2011
  • 113. Fibonacci macro :load_time do invokestatic System, "currentTimeMillis", long end Wednesday, July 27, 2011
  • 114. Fibonacci macro :end_timing do |i| load_time lload i lsub lstore i end Wednesday, July 27, 2011
  • 115. Fibonacci macro :lprintln do |i| getstatic System, "out", PrintStream lload i invokevirtual PrintStream, "println", [void, long] end Wednesday, July 27, 2011
  • 116. ASM • “All purpose bytecode manipulation and analysis framework.” • De facto standard bytecode library • http://asm.ow2.org Wednesday, July 27, 2011
  • 117. Basic Process • Construct a ClassWriter • Visit structure • Annotations, methods, fields, inner classes • Write out bytes Wednesday, July 27, 2011
  • 118. Blah.java public class Blah implements Cloneable { private final String fieldName; public Blah() { fieldName = "hello"; } public static Blah makeBlah() { return new Blah(); } } Wednesday, July 27, 2011
  • 119. ClassWriter ClassWriter cv = new ClassWriter( ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); Wednesday, July 27, 2011
  • 120. COMPUTE...what? • COMPUTE_MAXS • ASM will calculate max stack/local vars • COMPUTE_FRAMES • ASM will calculate Java 6 stack map • Hints to verifier that we’ve pre-validated stack contents (sort of) Wednesday, July 27, 2011
  • 121. Visit Class cv.visit( Opcodes.V1_6, Opcodes.ACC_PUBLIC, "Blah", null, "java/lang/Object", new String[] {"java/lang/Cloneable"}); Wednesday, July 27, 2011
  • 122. Opcodes • Interface full of constants • Bytecodes • Visibility modifiers • Java versions • Other stuff Wednesday, July 27, 2011
  • 123. ACC_* • Some you know • ACC_PUBLIC, ACC_ABSTRACT, etc • Some you don’t • ACC_BRIDGE, ACC_SYNTHETIC Wednesday, July 27, 2011
  • 124. Java Version • V1_1 through V1_7 • Sorry 1.0! Wednesday, July 27, 2011
  • 125. Class Names "java/lang/Object" packageClass.replaceAll('.', '/') Wednesday, July 27, 2011
  • 126. Visit Source cv.visitSource( "Blah.java", "JSR-45 source map here"); Wednesday, July 27, 2011
  • 127. Visit Annotation AnnotationVisitor av = cv.visitAnnotation("some/Annotation", true); av.visitArray("name1", ...); av.visitEnum("name2", ...); av.visitEnd(); Wednesday, July 27, 2011
  • 128. Blah.java private final String fieldName; Wednesday, July 27, 2011
  • 129. Visit Field FieldVisitor fv = cv.visitField( Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "fieldName", "Ljava.lang.String;", null); fv.visitAnnotation(...); fv.visitAttribute(...); fv.visitEnd(); Wednesday, July 27, 2011
  • 130. Descriptor "Ljava.lang.String;" "(IF[JLjava.lang.Object;)V" • Primitive types • B,C,S,I,J,F,D,Z,V • Reference types • Lsome/Class; • Array • Prefix with [ Wednesday, July 27, 2011
  • 131. Blah.java public Blah() { ... } public static Blah makeBlah() { ... } Wednesday, July 27, 2011
  • 132. Visit Method MethodVisitor construct = cv.visitMethod( Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); MethodVisitor makeBlah = cv.visitMethod( Opcodes.ACC_PUBLIC, ACC_STATIC, "makeBlah", "()LBlah;", null, null); Wednesday, July 27, 2011
  • 133. Special Methods • <init> • Constructor • <clinit> • Static initializer Wednesday, July 27, 2011
  • 134. MethodVisitor • Visit annotation stuff • Visit code • Bytecodes, frames, local vars, line nums • Visit maxs • Pass bogus values if COMPUTE_MAXS Wednesday, July 27, 2011
  • 135. Blah.java public Blah() { fieldName = "hello"; } public static Blah makeBlah() { return new Blah(); } Wednesday, July 27, 2011
  • 136. Visit Method Body construct.visitCode(); construct.visitVarInsn(ALOAD, 0); construct.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); construct.visitVarInsn(ALOAD, 0); construct.visitLdcInsn("hello"); construct.visitFieldInsn(PUTFIELD, "Blah", "fieldName", "Ljava/lang/String;"); construct.visitInsn(RETURN); construct.visitMaxs(2, 1); construct.visitEnd(); Wednesday, July 27, 2011
  • 137. ASMifierClassVisitor • Dump ASM visitor calls from .class file • Very raw, but very useful Wednesday, July 27, 2011
  • 138. Blah.java public class Blah implements Cloneable { private final String fieldName; public Blah() { fieldName = "hello"; } public static Blah makeBlah() { return new Blah(); } } Wednesday, July 27, 2011
  • 139. ~/oscon ➔ java -cp asm-3.3.1.jar:asm-util-3.3.1.jar org.objectweb.asm.util.ASMifierClassVisitor Blah.class import java.util.*; import org.objectweb.asm.*; import org.objectweb.asm.attrs.*; public class BlahDump implements Opcodes { public static byte[] dump () throws Exception { ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0; cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Blah", null, "java/lang/Object", new String[] { "java/lang/Cloneable" }); { fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "fieldName", "Ljava/lang/String;", null, null); fv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn("hello"); mv.visitFieldInsn(PUTFIELD, "Blah", "fieldName", "Ljava/lang/String;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "makeBlah", "()LBlah;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "Blah"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "Blah", "<init>", "()V"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 0); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } } Wednesday, July 27, 2011
  • 140. Real-world Cases • Reflection-free invocation • JRuby, Groovy, other languages • Bytecoded data objects • Hibernate, other data layers • java.lang.reflect.Proxy and others • Language compilers Wednesday, July 27, 2011
  • 141. Part Two: JVM JIT Wednesday, July 27, 2011
  • 142. JIT • Just-In-Time compilation • Compiled when needed • Maybe immediately before execution • ...or when we decide it’s important • ...or never? Wednesday, July 27, 2011
  • 143. Mixed-Mode • Interpreted • Bytecode-walking • Artificial stack • Compiled • Direct native operations • Native registers, memory, etc Wednesday, July 27, 2011
  • 144. Profiling • Gather data about code while interpreting • Invariants (types, constants, nulls) • Statistics (branches, calls) • Use that information to optimize • Educated guess? Wednesday, July 27, 2011
  • 145. Optimization • Loop unrolling • Lock coarsening • Method inlining • Dead code elimination • Duplicate code elimination Wednesday, July 27, 2011
  • 146. The Golden Rule of Optimization Don’t do unnecessary work. Wednesday, July 27, 2011
  • 147. Perf Sinks • Memory accesses • By far the biggest expense • Calls • Opaque memory ref + branch • Locks, volatile writes • Kills multi-cpu perf Wednesday, July 27, 2011
  • 148. Volatile? • Each CPU maintains a memory cache • Caches may be out of sync • If it doesn’t matter, no problem • If it does matter, threads disagree! • Volatile forces synchronization of cache • Across cores and to main memory Wednesday, July 27, 2011
  • 149. Inlining? • Combine caller and callee into one unit • e.g. based on profile • Perhaps with a sanity check • Optimize as a whole Wednesday, July 27, 2011
  • 150. Inlining int addAll(int max) { int accum = 0; for (int i = 0; i < max; i++) { accum = add(accum, i); } return accum; } int add(int a, int b) { return a + b; } Wednesday, July 27, 2011
  • 151. Inlining int addAll(int max) { int accum = 0; for (int i = 0; i < max; i++) { accum = add(accum, i); } return accum; } Only one target is ever seen int add(int a, int b) { return a + b; } Wednesday, July 27, 2011
  • 152. Inlining int addAll(int max) { int accum = 0; for (int i = 0; i < max; i++) { accum = accum + i; } return accum; } Don’t bother making a call Wednesday, July 27, 2011
  • 153. Call Site • The place where you make a call • Monomorphic (“one shape”) • Single target class • Bimorphic (“two shapes”) • Polymorphic (“many shapes”) • Megamorphic (“you’re screwed”) Wednesday, July 27, 2011
  • 154. Blah.java System.currentTimeMillis(); // static, monomorphic List list1 = new ArrayList(); // constructor, monomorphic List list2 = new LinkedList(); for (List list : new List[]{ list1, list2 }) { list.add("hello"); // bimorphic } for (Object obj : new Object[]{ 'foo', list1, new Object() }) { obj.toString(); // polymorphic } Wednesday, July 27, 2011
  • 155. Hotspot • -client mode (C1) inlines, less aggressive • Fewer opportunities to optimize • -server mode (C2) profiles, inlines • We’ll focus on this • Tiered mode combines them • -XX:+TieredCompilation Wednesday, July 27, 2011
  • 156. Hotspot Inlining • Profile to find “hot spots” • Largely focused around call sites • Profile until 10k calls • Inline mono/bimorphic calls • Other mechanisms for polymorphic calls Wednesday, July 27, 2011
  • 157. Now it gets fun! Wednesday, July 27, 2011
  • 158. Monitoring the JIT • Dozens of flags • PrintCompilation • PrintInlining • LogCompilation • PrintAssembly • Some in product, some in debug... Wednesday, July 27, 2011
  • 159. public class Accumulator { public static void main(String[] args) { int max = Integer.parseInt(args[0]); System.out.println(addAll(max)); } static int addAll(int max) { int accum = 0; for (int i = 0; i < max; i++) { accum = add(accum, i); } return accum; } static int add(int a, int b) { return a + b; } } Wednesday, July 27, 2011
  • 160. ~/oscon ➔ java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-b00) OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode) ~/oscon ➔ javac Accumulator.java ~/oscon ➔ java Accumulator 1000 499500 Wednesday, July 27, 2011
  • 161. PrintCompilation • -XX:+PrintCompilation • Print methods as they are jitted • Class + name + size Wednesday, July 27, 2011
  • 162. ~/oscon ➔ java -XX:+PrintCompilation Accumulator 1000 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 8 sun.security.provider.SHA::implCompress (491 bytes) 9 java.lang.String::charAt (33 bytes) 499500 Wednesday, July 27, 2011
  • 163. ~/oscon ➔ java -XX:+PrintCompilation Accumulator 1000 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 8 sun.security.provider.SHA::implCompress (491 bytes) 9 java.lang.String::charAt (33 bytes) 499500 Where’s our methods?! Wednesday, July 27, 2011
  • 164. ~/oscon ➔ java -XX:+PrintCompilation Accumulator 1000 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 8 sun.security.provider.SHA::implCompress (491 bytes) 9 java.lang.String::charAt (33 bytes) 499500 Where’s our methods?! ...remember...10k calls Wednesday, July 27, 2011
  • 165. 10k loop, 10k calls to add ~/oscon ➔ java -XX:+PrintCompilation Accumulator 10000 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 8 sun.security.provider.SHA::implCompress (491 bytes) 9 java.lang.String::charAt (33 bytes) 10 Accumulator::add (4 bytes) 49995000 Hooray! Wednesday, July 27, 2011
  • 166. What’s this stuff? 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 8 sun.security.provider.SHA::implCompress (491 bytes) 9 java.lang.String::charAt (33 bytes) Wednesday, July 27, 2011
  • 167. What’s this stuff? 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 8 sun.security.provider.SHA::implCompress (491 bytes) 9 java.lang.String::charAt (33 bytes) Class loading, security, other boot logic. Wednesday, July 27, 2011
  • 168. What if you see this... ~/oscon ➔ java -client -XX:+PrintCompilation Accumulator 1000 1 java.lang.String::hashCode (64 bytes) 2 java.math.BigInteger::mulAdd (81 bytes) 3 java.math.BigInteger::multiplyToLen (219 bytes) 4 java.math.BigInteger::addOne (77 bytes) 5 java.math.BigInteger::squareToLen (172 bytes) 5 made not entrant java.math.BigInteger::squareToLen (172 bytes) 7 java.math.BigInteger::montReduce (99 bytes) 6 java.math.BigInteger::primitiveLeftShift (79 bytes) 8 java.math.BigInteger::squareToLen (172 bytes) 9 sun.security.provider.SHA::implCompress (491 bytes) 10 java.lang.String::charAt (33 bytes) 499500 Wednesday, July 27, 2011
  • 169. Optimistic Compiler • Assume profile is accurate • Aggressively optimize based on profile • Bail out if we’re wrong • And hope that we’re usually right Wednesday, July 27, 2011
  • 170. Deoptimization • Bail out of running code • Monitoring flags describe process • “uncommon trap” - we were wrong • “not entrant” - don’t let anyone enter • “zombie” - on its way to deadness Wednesday, July 27, 2011
  • 171. What if you see this... 20 java.math.BigInteger::addOne (77 bytes) 21 java.math.BigInteger::squareToLen (172 bytes) 22 java.math.BigInteger::primitiveLeftShift (79 bytes) --- n java.lang.System::arraycopy (static) 24 sun.security.provider.SHA::implCompress (491 bytes) 23 java.math.BigInteger::montReduce (99 bytes) 25 java.lang.String$CaseInsensitiveComparator::compare (115 bytes) 26 java.lang.Character::toLowerCase (162 bytes) Wednesday, July 27, 2011
  • 172. What if you see this... 20 java.math.BigInteger::addOne (77 bytes) 21 java.math.BigInteger::squareToLen (172 bytes) 22 java.math.BigInteger::primitiveLeftShift (79 bytes) --- n java.lang.System::arraycopy (static) 24 sun.security.provider.SHA::implCompress (491 bytes) 23 java.math.BigInteger::montReduce (99 bytes) 25 java.lang.String$CaseInsensitiveComparator::compare (115 bytes) 26 java.lang.Character::toLowerCase (162 bytes) Native calls don’t compile, may be intrinsic. We’ll come back to that. Wednesday, July 27, 2011
  • 173. PrintInlining • -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining • Display hierarchy of inlined methods • Include reasons for not inlining • More, better output on OpenJDK 7 Wednesday, July 27, 2011
  • 174. ~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions > -XX:+PrintInlining > Accumulator 10000 49995000 Wednesday, July 27, 2011
  • 175. ~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions > -XX:+PrintInlining > Accumulator 10000 49995000 Um...I don’t see anything inlining... Wednesday, July 27, 2011
  • 176. public class Accumulator { public static void main(String[] args) { int max = Integer.parseInt(args[0]); System.out.println(addAll(max)); } Called once static int addAll(int max) { int accum = 0; for (int i = 0; i < max; i++) { accum = add(accum, i); } return accum; Called 10k times... } static int add(int a, int b) { return a + b; } ...but no calls to inline! } Wednesday, July 27, 2011
  • 177. public class Accumulator2 { public static void main(String[] args) { int max = Integer.parseInt(args[0]); System.out.println( new Accumulator2().addAllSqrts(max)); } double addAllSqrts(int max) { double accum = 0; for (int i = 0; i < max; i++) { accum = addSqrt(accum, i); } return accum; } double addSqrt(double a, int b) { return a + sqrt(b); } double sqrt(int b) { return Math.sqrt(b); } } Wednesday, July 27, 2011
  • 178. ~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions > -XX:+PrintCompilation > > -XX:+PrintInlining Accumulator2 10000 A hot spot! ... 89 2 Accumulator2::addSqrt (8 bytes) @ 3 Accumulator2::sqrt (6 bytes) inline (hot) @ 2 java.lang.Math::sqrt (5 bytes) (intrinsic) 89 3 Accumulator2::sqrt (6 bytes) @ 2 java.lang.Math::sqrt (5 bytes) (intrinsic) 666616.4591971082 Calls treated specially by JIT Wednesday, July 27, 2011
  • 179. Intrinsic? • Known to the JIT • Don’t inline the bytecode • Do perform a specific native operation • e.g. kernel-level memory operation • e.g. optimized sqrt in machine code Wednesday, July 27, 2011
  • 180. Did Someone Say MACHINE CODE? Wednesday, July 27, 2011
  • 181. The Red Pill • Knowing code compiles is good • Knowing code inlines is better • Seeing the actual assembly is best! Wednesday, July 27, 2011
  • 182. Caveat • I don’t really know assembly. • But I fake it really well. Wednesday, July 27, 2011
  • 183. PrintAssembly • -XX:+PrintAssembly • Google “hotspot printassembly” • http://wikis.sun.com/display/ HotSpotInternals/PrintAssembly • Assembly dumping plugins Wednesday, July 27, 2011
  • 184. ~/oscon ➔ java -XX:+UnlockDiagnosticVMOptions > -XX:+PrintAssembly > Accumulator 10000 OpenJDK 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output Loaded disassembler from hsdis-amd64.dylib ... Wednesday, July 27, 2011
  • 185. Decoding compiled method 11343cbd0: Code: [Disassembling for mach='i386:x86-64'] [Entry Point] [Verified Entry Point] [Constants] # {method} 'add' '(II)I' in 'Accumulator' # parm0: rsi = int # parm1: rdx = int # [sp+0x20] (sp of caller) 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Wednesday, July 27, 2011
  • 187. x86_64 Assembly 101 add Two’s complement add sub ...subtract mov* Move data from a to b jmp goto je, jne, jl, jge, ... Jump if ==, !=, <, >=, ... push, pop Push/pop to/from call stack call*, ret* Call or return from subroutine eax, ebx, esi, ... Registers rdx, rbx, rsi, ... 64-bit registers Wednesday, July 27, 2011
  • 188. Register Machine • Instead of stack moves, we have “slots” • Move data into slots • Call operations that work with slots • Get new data out of slots • JVM stack, locals end up as register ops Wednesday, July 27, 2011
  • 189. Stack? • Native code has a stack too • Maintains context from call to call • Calling conventions • Caller preserves registers? • Callee preserves registers? • Many different styles Wednesday, July 27, 2011
  • 190. Decoding compiled method 11343cbd0: <= address of new compiled code Code: [Disassembling for mach='i386:x86-64'] <= architecture [Entry Point] [Verified Entry Point] [Constants] # {method} 'add' '(II)I' in 'Accumulator' <= method, signature, class # parm0: rsi = int <= first parm to method goes in rsi # parm1: rdx = int <= second parm goes in rdx # [sp+0x20] (sp of caller) <= caller’s pointer into native stack Wednesday, July 27, 2011
  • 191. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq rbp points at current stack frame, so we save it off. Wednesday, July 27, 2011
  • 192. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Two args, so we bump stack pointer by 0x10. Wednesday, July 27, 2011
  • 193. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Do nothing, e.g. to memory-align code. Wednesday, July 27, 2011
  • 194. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq At the “-1” instruction of our add() method... i.e. here we go! Wednesday, July 27, 2011
  • 195. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Move parm1 into eax. Wednesday, July 27, 2011
  • 196. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Add parm0 and parm1, store result in eax. Wednesday, July 27, 2011
  • 197. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq How nice, Hotspot shows us this is our “iadd” op! Wednesday, July 27, 2011
  • 198. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Put stack pointer back where it was. Wednesday, July 27, 2011
  • 199. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Restore rbp from stack. Wednesday, July 27, 2011
  • 200. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq Poll a “safepoint”...give JVM a chance to GC, etc. Wednesday, July 27, 2011
  • 201. 11343cd00: push %rbp 11343cd01: sub $0x10,%rsp 11343cd05: nop ;*synchronization entry ; - Accumulator::add@-1 (line 16) 11343cd06: mov %esi,%eax 11343cd08: add %edx,%eax ;*iadd ; - Accumulator::add@2 (line 16) 11343cd0a: add $0x10,%rsp 11343cd0e: pop %rbp 11343cd0f: test %eax,-0x1303fd15(%rip) # 1003fd000 ; {poll_return} 11343cd15: retq All done! Wednesday, July 27, 2011
  • 202. Things to Watch For • CALL operations • Indicate something failed to inline • LOCK operations • Cache-busting, e.g. volatility Wednesday, July 27, 2011
  • 203. CALL 1134858f5: xchg %ax,%ax 1134858f7: callq 113414aa0 ; OopMap{off=316} ;*invokespecial addAsBignum ; - org.jruby.RubyFixnum::addFixnum@29 (line 348) ; {optimized virtual_call} 1134858fc: jmpq 11348586d Ruby integer adds might overflow into Bignum, leading to addAsBignum call. In this case, it’s never called, so Hotspot emits callq assuming we won’t hit it. Wednesday, July 27, 2011
  • 204. LOCK Code from a RubyBasicObject’s default constructor. 11345d823: mov 0x70(%r8),%r9d ;*getstatic NULL_OBJECT_ARRAY ; - org.jruby.RubyBasicObject::<init>@5 (line 76) ; - org.jruby.RubyObject::<init>@2 (line 118) ; - org.jruby.RubyNumeric::<init>@2 (line 111) ; - org.jruby.RubyInteger::<init>@2 (line 95) ; - org.jruby.RubyFixnum::<init>@5 (line 112) ; - org.jruby.RubyFixnum::newFixnum@25 (line 173) 11345d827: mov %r9d,0x14(%rax) 11345d82b: lock addl $0x0,(%rsp) ;*putfield varTable ; - org.jruby.RubyBasicObject::<init>@8 (line 76) ; - org.jruby.RubyObject::<init>@2 (line 118) ; - org.jruby.RubyNumeric::<init>@2 (line 111) ; - org.jruby.RubyInteger::<init>@2 (line 95) ; - org.jruby.RubyFixnum::<init>@5 (line 112) ; - org.jruby.RubyFixnum::newFixnum@25 (line 173) Why are we doing a volatile write in the constructor? Wednesday, July 27, 2011
  • 205. LOCK public class RubyBasicObject ... { private static final boolean DEBUG = false; private static final Object[] NULL_OBJECT_ARRAY = new Object[0]; // The class of this object protected transient RubyClass metaClass; // zeroed by jvm protected int flags; // variable table, lazily allocated as needed (if needed) private volatile Object[] varTable = NULL_OBJECT_ARRAY; Maybe it’s not such a good idea to pre-init a volatile? Wednesday, July 27, 2011
  • 206. LOCK ~/projects/jruby ➔ git log 2f935de1e40bfd8b29b3a74eaed699e519571046 -1 | cat commit 2f935de1e40bfd8b29b3a74eaed699e519571046 Author: Charles Oliver Nutter <[email protected]> Date: Tue Jun 14 02:59:41 2011 -0500 Do not eagerly initialize volatile varTable field in RubyBasicObject; speeds object creation significantly. LEVEL UP! Wednesday, July 27, 2011
  • 207. What have we learned? • How to emit bytecode • How to read bytecode • How bytecode execution works • How to monitor the Hotspot JIT • How to find problems from asm code Wednesday, July 27, 2011
  • 208. You’re no dummy now. ;-) Wednesday, July 27, 2011
  • 209. Thank you! [email protected], @headius • http://blog.headius.com • http://github.com/headius/bitescript • “java virtual machine specification” • “jvm opcodes” Wednesday, July 27, 2011

Editor's Notes