- A Concurrent Affair - https://www.concurrentaffair.org -

Object ID Update

A while ago I analyzed problems with assigning object IDs [1]. Back then, I had the following symptoms:

  1. java.lang.Object: always -1, can’t hold a field
  2. java.lang.String: always -1, can’t hold a field
  3. java.lang.Class: always 0, $$$objectID$$$ field doesn’t get initialized
  4. arrays: always -1

Since then, I have changed the base class implementation to use the identity hashcode instead of -1 to signal if an object ID isn’t available. To distinguish object IDs and identity hashcodes, object IDs are now negative. Let’s look at what the same code generates now:

0 3 // 000030e4 0003 0018   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 1 // 000030e4 0003 0018   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 2 // 000030e4 0003 006c   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 3 // 000031d7 0002 001a   18262862 ObjectIDTest.main
0 1 // 000031d7 0002 001a   18262862 ObjectIDTest.main
0 2 // 000031d7 0002 0047   18262862 ObjectIDTest.main
0 3 // 000030e4 0003 0018   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 1 // 000030e4 0003 0018   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 2 // 000030e4 0003 006c   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 3 // 000031d7 0002 0085   21539363 ObjectIDTest.main
0 1 // 000031d7 0002 0085   21539363 ObjectIDTest.main
0 2 // 000031d7 0002 00b2   21539363 ObjectIDTest.main
0 3 // 000031d7 0002 00ed    2570525 ObjectIDTest.main
0 1 // 000031d7 0002 00ed    2570525 ObjectIDTest.main
0 2 // 000031d7 0002 011a    2570525 ObjectIDTest.main
0 3 // 000031d7 0002 015d   26867996 ObjectIDTest.main
0 1 // 000031d7 0002 015d   26867996 ObjectIDTest.main
0 2 // 000031d7 0002 018a   26867996 ObjectIDTest.main
0 3 // 000030e4 0003 0018   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 1 // 000030e4 0003 0018   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 2 // 000030e4 0003 006c   22413802 sun.misc.Launcher$AppClassLoader.loadClass
0 8 // 00003188 0001 0016          0 java.lang.Character.
0 6 // 00003188 0001 0016          0 java.lang.Character.
0 7 // 00003188 0001 005b       -443 java.lang.Character.
0 8 // 00003188 0001 0016          0 java.lang.Character.
0 6 // 00003188 0001 0016          0 java.lang.Character.
0 7 // 00003188 0001 005b       -444 java.lang.Character.
0 3 // 000031d7 0002 01db       -443 ObjectIDTest.main
0 1 // 000031d7 0002 01db       -443 ObjectIDTest.main
0 3 // 000031d7 0002 020d       -444 ObjectIDTest.main
0 1 // 000031d7 0002 020d       -444 ObjectIDTest.main
0 2 // 000031d7 0002 023b       -444 ObjectIDTest.main
0 2 // 000031d7 0002 0275       -443 ObjectIDTest.main
0 5 // 000031aa 0015 0032          0 java.lang.Thread.exit

Now all locks are distinguishable, though not always by using object IDs. The only zeros here in this recording occur when object IDs are just being assigned. I can probably still fine-tune this and let a few more classes have object IDs, but this is a major improvement already.

As the occurrence of of sync points with codes 6, 7 and 8 may already suggest, assigning object and thread IDs now generate different sync points for their monitorenter and monitorexit opcodes (6 through 8 for object IDs, 9 through 11 for thread IDs) , as previously suggested [2]. Another difference is the presence of the TRYMONITORENTER sync point before the monitorenter instruction, which makes deadlock detection possible again, but that has been there for a while.

[3] [4]Share [5]