G1BlockOffsetTablePart is currently aware of block starts (i.e. the block offset table field), and for various operations the size of the blocks.
The size of a block seems unnecessary information; it's always gathered via the associated HeapRegion. At the same time G1BlockOffsetTablePart is a part of HeapRegion, so there typically is a back-and-forth between HeapRegion and G1BlockOffsetTablePart when calling methods.
I.e. calls are often of the type HeapRegion->G1BlockOffsetTablePart->HeapRegion which seems unnecessary, as the only user of its associated G1BlockOffsetTablePart is the HeapRegion anyway.
Instead of this call sequence, HeapRegion could always ask G1BlockOffsetTablePart for the start of the block spanning into the card, and then do the rest of the operations within HeapRegion.