I tried to change the klass pointer of an object to point to a different class which has an identical setup. To be precise, for my test I used a copy of the original class with a modified toString()
method, just to print out something else.
Assuming that the JVM orders the attributes in the same way in memory objects of the two classes should look identical.
So in my test I obtained the klass pointer from an object of the new class and set in on an object of the old, original class. After calling toString()
I saw the new output as expected.
When I did this in a loop, however, the JVM crashed. I tried to create new Test()
objects and modified the klass pointer to point to Test2
like this (note: 64bit compressed OOP):
int test2KlassIdentifier = unsafe.getInt(test2Obj, 8L);
unsafe.putInt(testObj, 8L, test2KlassIdentifier);
After creating hundreds of thousands of objects I got a core dump:
# Internal Error (C:\ojdkbuild\lookaside\java-1.8.0-openjdk\hotspot\src\share\vm\opto\memnode.cpp:906), pid=27120, tid=0x0000000000009374
# assert(!(adr_type->isa_oopptr() && adr_type->offset() == oopDesc::klass_offset_in_bytes())) failed: use LoadKlassNode instead
I then reduced the number to only create 100.000 --> no core dump until I created a bunch of new Object()
s afterwards.
So my feeling is that it is a GC related problem and that my change messes up something internally. I would like to understand, however, how my "patched" object is different from a newly created object of type Test2