1

Assuming I have a method call site in java. What is the equivalent jvm bytecode (apart frm the call which is translated to invokevirtual/static e.t.c)? I'm more interested in the commands that load the receiver on the stack.

-Obviously one command is aload.

-Another could be that another invocation returns a refobject on the stack

-Three, the new instruction. (e.g new A().foo(). It gets dupped. But the dupped is consumed by the constructor)

-four, maybe(??) Dup. (when having a.foo(); a.bar(); Is There a chance the compiler will produce aload then dup instead of aload aload?)

My biggest question is the rest dup commands. Because they kind of shuffle the stack. when does javac produce them? Does it use them when compiling a call site?

I've tried to find documentations without luck. Then found the source code, but it's going to take days to dig into that. I believe the Code.java and Gen.java files are responsible for the translation/compilation process.

Manos Ntoulias
  • 513
  • 1
  • 4
  • 21
  • 2
    You can use the **javap** command to view the jvm byte codes used in your class --- https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html – Ramesh Subramanian Dec 21 '18 at 10:33
  • Yes but it wouldn't cover every possibility. I can't be certain that my examples have covered everything – Manos Ntoulias Dec 21 '18 at 10:45
  • 2
    As you noted yourself, `javac` uses `dup` for constructor invocations. Generally, it does not use `dup` when you are dereferencing the same variable. A variable access will always get compiled to a variable access. But the other way round, it may add synthetic variables not appearing in the source code. Stack manipulations are rather rare. But one example would be `objArray[index] += "string"` which uses `dup2` (in JDK11) to clone array reference and index, as an `aaload` and `aastore` is needed for the update. Another scenario would be `(variable = expression).method()`; – Holger Dec 21 '18 at 16:29

1 Answers1

2

Almost any bytecode instruction that produces a reference can be used by javac to load a receiver.

  • aload, invokeX, new + dup
    Those you already mentioned.
  • getfield, getstatic

    field.method();
    
  • aaload

    arr[index].method();
    
  • anewarray

    (new Object[0]).hashCode();
    
  • multianewarray

    (new byte[5][10]).getClass();
    
  • checkcast

    ((List) obj).size();
    
  • ldc

    MyClass.class.getName();
    
  • aconst_null

    ((Object) null).getClass();
    
  • dup

    IntSupplier s = field::hashCode;
    

    Here dup + invokevirtual are used to emit a tricky null-check:

    getstatic     #2      // Field field:Ljava/lang/String;
    dup
    invokevirtual #3      // Method java/lang/Object.getClass:()Ljava/lang/Class;
    pop
    invokedynamic #4,  0  // InvokeDynamic #0:getAsInt
    
apangin
  • 92,924
  • 10
  • 193
  • 247
  • 2
    Note that starting with JDK 9, the compiler will insert a `Objects.requireNonNull(…)` call instead of `… .getClass()` for the intrinsic `null` check (see also [this answer](https://stackoverflow.com/a/43116722/2711488)) – Holger Jan 07 '19 at 13:11