Search code examples
javathiscallstackcalling-convention

Is 'this' reference stored on call stack in Java?


We already knew that when we calling a method in Java, parameters and local variables will be stored on the stack.

For example the following code:

public class Test
{
    int x = 10;
    int y = 20;

    void test(int y)
    {
        int z = y;
        this.x = y; // How JVM knows where is our current object?
    }

    public static void main(String [] args)
    {
        Test obj = new Test();
        obj.test(3);
    }
} 

Will produce a call stack like the following when we called obj.test():

|             |
+-------------+
|     z       |
|     y       |  obj.test()
+-------------+
|    obj      |  main()
+-------------+

But I'm wondering where does this reference in the method stored? Is it also stored on the stack like the following:

|             |
+-------------+
|   this      |
|     z       |
|     y       |  obj.test()
+-------------+
|    obj      |  main()
+-------------+

Or it is stored on other area in memory? Or is it calculate by the JVM at runtime?

Finally, I'm also curious about does the order of parameters / variable of obj.test() in the stack has a specific order, just like C has calling convention, or it is depend on the implementation of VM?

Update:

I know this is a keyword instead of a normal reference variable, but my primary concern about this example, is how JVM knows where does object laid in the heap?

Or in other words, how can JVM knows what is the current object of a member method at runtime, so they can get access to those instance variable?


Solution

  • Most languages that are built around a stackmachine model will work exactly like you described. This includes Java, .NET and C++.

    Think about it this way: The code for instance methods is most likely shared across all instances of a class, it wouldn't make much sense to copy anything more than the data for each instance, if that common part (the code for methiod implementations, remember its all just memory to the computer) is the same across all instances anyway.

    So what differentiates instance methods from static (in Java and .NET speak) methods is an implicit this parameter that is added to each method signature. The implicit this parameters denotes the instance that the method should operate on. And since parameter passing to method most likely happens over the stack, yes the this parameter will be stored on the stack. (see http://zeroturnaround.com/articles/java-bytecode-fundamentals-using-objects-and-calling-methods/#objects for Java, it's pretty mich the same thing in .NET). The this parameter is pushed as the first parameter onto the stack before calling the method, followed by all other parameters.

    Now, that describes the model of the Virtual Machine. If the JITed machine code will really pass the this parameter over the stack or in a register (or in any other way) is entirely implementation specific and transparent to the VM.

    One additional thing to beware of in your example code is that you used the variable name 'y' twice, thus in the method the local variable 'y' will shadow the instance variable, except if you explcitily qualify it with 'this'.