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.
Almost any bytecode instruction that produces a reference can be used by javac to load a receiver.
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