1Monitor inflation and the monitor pool 2-------------------------------------- 3 4Every Java object conceptually has an associated monitor that is used to implement `synchronized` 5blocks as well as `Object.wait()` and related functionality. Initially, the state of this monitor 6is represented by the 32-bit `LockWord` in every object. This same word is also used to represent 7the system hash code if one has been computed for the object. See `lock_word.h` for details. 8 9The `LockWord` suffices for representing the state of unlocked objects with no waiters, whether or 10not they have a system hash code. It can also represent a locked (via a `synchronized` block) 11object that has neither a system hash code, nor an `Object.wait()` waiter. In all other cases, the 12lock must be "inflated". In that case, the `LockWord` contents reflect the "fat lock" state, and 13it contains primarily a `MonitorId`. We also inflate significantly contended locks, since the lock 14word itself does not have space for a wait queue or the like. 15 16(With the Concurrent Copying garbage collector, the `LockWord` supports another "forwarding 17address" state. In that case the above information is instead contained in the `LockWord` for the 18to-space objects referenced by the forwarding address.) 19 20MonitorIds 21---------- 22A `MonitorId` is logically a pointer to a `Monitor` structure. The `Monitor` data structure is 23allocated when needed, and holds all the data needed to support any hashcode or `Object` 24synchronization operation provided by Java. On 32-bit implementations, it is essentially a 25pointer, except for some shifting and masking to avoid collisions with a few bits in the lock word 26required for other purposes. In a 64-bit environment, the situation is more complicated, since we 27don't have enough bits in the lock word to store a 64-bit pointer. 28 29In the 64-bit case, `Monitor`s are stored in "chunks" of 4K bytes. The bottom bits of a 30`MonitorId` are the index of the `Monitor` within its chunk. The remaining bits are used to find 31the correct chunk. 32 33Continuing with the 64-bit case, chunk addresses are stored in the `monitor_chunks_` data 34structure, which is logically a two-dimensional, vaguely triangular, array of pointers to chunks 35Each row is allocated separately, and twice as long as the previous one. (Thus the array is not 36really triangular.) The high bits of a `MonitorId` are interpreted as row- and column-indices into 37this array. Both the second level "rows" of this array, and the chunks themselves are allocated on 38demand. By making the rows grow exponentially in size, and keeping a free list of recycled 39`Monitor` slots, we can accommodate a large number of `Monitor`s, without ever allocating more than 40twice the index size that was actually required. (This doesn't count the top-level index needed 41to find the rows, but exponential growth of the rows makes that tiny.) And there is no need to 42ever move `Monitor` objects, which would significantly complicate the logic. 43 44The above data structure is distinct from the `MonitorList` data structure, which is used simply 45to enumerate all monitors. (It might be possible to save a bit of space in the 64-bit case, and 46have the `monitor_chunks_` data structure handle this as well.) 47 48Monitor inflation 49----------------- 50Monitors are inflated, and `Monitor` structs are allocated on demand, when an operation is 51performed that cannot be accommodated with just the lock word. This normally happens when we need 52to store a hash code in a locked object, when there is lock contention, or when `Object.wait` is 53executed. (Notification on an object with no waiters is trivial and does not require inflation.) 54In the 64-bit case, the `monitor_chunks_` data structure may also need to be extended at this time 55to allow mapping of an additional `MonitorId`. 56 57If we have to inflate a lock that is currently held by another Thread B, we must suspend B while 58updating the data structure representing the lock B holds. When the lock is later released by B, 59it will notice the change and operate on the fat lock representation instead. 60 61Monitor deflation 62----------------- 63Monitors are deflated, and the `Monitor` structs associated with deflated monitors are reclaimed 64as part of `Heap::Trim()` by invoking `SweepMonitorList()` with an `IsMarkedVisitor` that deflates 65unheld monitors with no waiters. This is done with all other threads suspended. 66 67Monitors are also reclaimed, again via `SweepMonitorList()`, in `SweepSystemWeaks()`, if the 68corresponding object was not marked. 69 70(There is one other use of monitor deflation from `ImageWriter`. That does not maintain 71`MonitorList`. It relies on the fact that the dex2oat process is single-threaded, and the heap is 72about to be discarded.) 73 74