In java bytecode why is the receiver is pushed onto the stack first followed by all the parameters? I seem to remember it being something to do with efficiency.
This is true for both method calls and setting fields.
Method Call
class X {
int p(int a) {
//Do something
}
int main() {
int ret = p(1);
}
}
Main method compiles to:
aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
invokevirtual <int p(int)> from class X
Setting a field:
class X {
int x;
int main() {
x = 1;
}
}
Main method compiles to:
aload_0 // Load this onto the stack
iconst_1 // Load constant 1 onto the stack
putfield <int x> from class X
Being pushed first has advantages in that
if it were much later in the parameter list and had to use a
parametric version of the aload bytecode. Because “this” is often referenced in methods for both field and method access, it leads to a real code density improvement.
the future “this” for .baz() is magically already in the right place on the
stack if you arrange things as was done in Java.