public final class FirstObjectTable extends Object
The card table is a summary of pointer stores into a region of the heap. The card table is linear with the region it summarizes, but smaller than the region. Each card table entry records that a pointer has been stored in the address range summarized by the entry.
During a young generation collection, all the pointers on dirty cards must be examined to see if they reference objects in the young generation, since those objects are reachable and must be scavenged (and any pointers to them must be updated). In order to find the pointers within objects I have to find the header of each object that has pointers in the covered region, so that I can use the class to get to any interior pointers. Once I find the header for the first object in a region I can stride by the size of the object to find the next object. But finding the first header is hard because objects can cross the boundaries between the cards. The first object table solves this problem by saying where is the start of the object that crosses onto the memory covered by a card.
The table is linear with the memory it covers, so the table can be indexed by scaling an index into the memory region, and the memory region can be indexed by scaling an index into the table. In the code here, an entry is one byte for each memory region covered by an entry.
Entries come in two flavors. A memory offset entry gives an offset into the *previous* memory region to the start of the object that crosses onto this entry. If all objects were tiny, then the one byte entry could hold the memory offset back to the header for the object that crosses onto this card. A memory offset entry can be scaled, because objects are 8-byte aligned in memory so the entries can be in units of 8 bytes, which gives them larger range. Thus, if a table entry covers 512 bytes of memory, the offsets into the previous card can have magnitudes in the range [0..(512/8)], or [0..64]. In the code here, offsets into memory are represented by negative or zero values: the number of 8-byte units before the start of the memory covered by this entry. For example, an entry of -17 would indicate that the object in the memory corresponding to the beginning of this entry starts (17 * 8 =) 136 bytes before the memory covered by this entry. (An offset of 0 means the first object starts at the beginning of the memory covered by this entry.)
If an object is larger than can be represented by one byte of offset, the first entry contains the memory offset to the start of the object, as above. Entries corresponding to the rest of the object the object hold values that are index offsets to that first memory offset entry. In the code here, such index offset entries are strictly positive values. Index offset entries come in two flavors. Small positive values give a simple offset to the memory offset entry for the object. Larger positive values give an exponent of a logarithmic offset to an entry closer to the memory offset entry. Thus a small value, say 3, would say that 3 entries towards the beginning of the object is the entry holding the memory offset to the start of the object. But a larger value, say 42, would say that 2^17 entries towards the beginning of the object is an entry that either holds the memory offset entry (as a negative value), or a table offset entry that gets us closer to the memory offset entry (as a positive value). In order not to confuse small positive entry offsets and small positive entry offset exponents, the exponents are biased by adding a value that make then larger than any small entry offsets. To summarize, and using the values of the various tunable constants used in the code here, first object table entries come in several ranges:
A first object table entry is initialized when an object is allocated that crosses on to the memory corresponding to a new entry.
Entry Value Interpretation [-128..0] A memory offset in 8-byte units from the address corresponding to the start of this entry to the header of the object that crosses onto the memory corresponding to this entry. [1..63] A linear entry offset to the entry N entries to the left. [64..126] An exponential entry offset to the entry 2^(6+N-64) entries to the left. 127 An otherwise uninitialized entry.
Implementation note: Table entries are bytes but converted to and from ints with bounds checks.