I was trying to find some approximization to address on heap , and you guys gave me the function System.IdentityHashCode(Object)
.
The problem is – this function doesn’t fit for primitive types. I’ll explain why.
I’m given as input Java compiled program – class file. My goal is to plot some graphs that will contain some information about variable access between time. I have no idea of how the code looks in advance , and my tactic is instrumentation of my own bytecode for every LOAD and STORE instruction. I’m using ASM Java Bytecode Instrumentation.
Therefore, I can’t do something like:
identityHashCode(Integer.valueOf(...))
because I have no indication whether the type is int, double, long, etc.
I want to be able to determine between different instances of the same class:
For example :
class foo { int a; } foo b; foo c; b.a++; c.a++;
But when it comes to bytecode , there is no relation between the name “b” / “c” and the attribute a. All I “see” is that a is incremented. Both are regarded as a ! if that was Object a
I could have used System.identityHashCode() to distinguish between them. But I can’t.
To make myself clear, look at the following example:
package manipulate; public class Test { int c; public static void main(String[] args) { Test a=new Test(); Test b=new Test(); a.c++; b.c++; } }
which will be translated (main function) to the following bytecode:
L0 LINENUMBER 7 L0 NEW manipulate/Test DUP INVOKESPECIAL manipulate/Test.<init>()V ASTORE 1 L1 LINENUMBER 8 L1 NEW manipulate/Test DUP INVOKESPECIAL manipulate/Test.<init>()V ASTORE 2 L2 LINENUMBER 9 L2 ALOAD 1 DUP GETFIELD manipulate/Test.c : I ICONST_1 IADD PUTFIELD manipulate/Test.c : I L3 LINENUMBER 10 L3 ALOAD 2 DUP GETFIELD manipulate/Test.c : I ICONST_1 IADD PUTFIELD manipulate/Test.c : I L4 LINENUMBER 11 L4 RETURN
And as you can see, what I’ve got on the stack is just the value of the integer c. Therefore, given that code, I can’t determine between these two c’s!
Advertisement
Answer
What i’ve got is java bytecode . I dont have b or c and I’m not aware of them . I only have the value of a on the stack
If you have local variables on the stack, they have variable numbers. These numbers are local to the stack frame, in which the method is executing, and two variables are same if they have the same number.
If you have the two primitive values in your evaluation (argument/operand/result) stack, they are same (in a similar sense as for variables) if they exist at the same time at the same stack index.
In your example, you see that the two GETFIELD manipulate/Test.c : I
instructions operate each on the current value on the stack (which is put there by ALOAD 1
or ALOAD 2
). This current value is the object to which your variable belongs, so you could insert there your counting code for this object (do a DUP first).