Collections are frequently used in classes and they are part of standard library. This additional layer between the business object and the array causes memory loads. Inlining reduces this overhead by placing the objects and arrays together in the heap and by replacing the memory accesses with offset address arithmetic. Object and array have headers and these are used for inlining. Dynamic arrays are given additional header fields and values. This might increase heap usage but it definitely reduces the execution time.
For example, a Polygon class can be defined as having a java.util.ArrayList of objects which corresponds to a dynamic list of Points. When the new elements are added and the size of the array does not suffice, the array is resized. The array elements reference the points that store the coordinates. There are two lookups for access to a point, first the loading of the field points and second the loading of the elementData. These two loads and one array access are unnecessary. Inlining combines the objects into a larger group such that a point can be loaded with a single access.
The points reference is initialized once and the elementData can be resized many times. An intelligent technique can handle this inlining which goes above and beyond the regular inlining of fixed value objects.
Objects and array inlining operate on a group of objects and arrays in the heap that are in a parent-child relationship. These nest levels allow the reference of a child to be directly in the parent even if a parent has multiple children. There can be a hierarchy of such levels but the difference is only between object fields and array fields.
The bytecode is the same between array and object fields but the inlining is different between the two. The size of the object is known beforehand. The size of an array is not known until allocation. Hot fields are worth more for optimizing. The Just-in-time compiler is leveraged for this purpose which inserts read barriers that increment field access counters per field and class.
The inlining works when the following two conditions are met. First, the parent and child objects must be allocated together and the field store that places the reference of the parent in the child must happen immediately afterwards so that it remains true for the lifetime of the data structures that are collocated this way. Second, the field stores must not overwrite the field with a new value.
No comments:
Post a Comment