C2 memory analysis divides the memory into slices. These slices need to be mutually exclusive (e.g. writing to Integer.value will not affect an element of int[]). However, this is violated in many cases.
One such case is when you have an array of bottoms (e.g. a Phi of an int[] and a byte[]). When C2 tries to reason about this memory, it receives a distinct slice from every other array, this means that C2 thinks the array aliases with no other kind of arrays, while in reality it should alias with all kinds of arrays.
The same potential issue can be encountered with TypeOopPtr::BOTTOM, we also give it a distinct memory slice, when in reality we should have something that aliases all other oop slices.
My proposal is that we should do similar to Valhalla, in which we have all flat array accesses sharing the same slice, then we divide that slice into smaller ones after we know all the slices that are present. For this issue, we should have all oop accesses share the same slice, then we divide that slice after all inlining. This approach also has multiple benefits:
- Currently, all oop array accesses share the same slice, if we divide the slices after we know all the present slices, we can divide this slice further if we know that there is no access into Object[] in this method.
- Mismatched accesses currently work poorly. We cannot assign them a slice, hence we wrap them in a pair of MemBar to prevent them floating in a nasty manner. This, however, introduces a barrier which prevents memory accesses from floating across it, which is detrimental to multiple optimizations.
- Memory of fields can also be divided better. For example, given classes B and C both inherit the field v from class A, then B.v and C.v can be separate slices if we don't do A.v anywhere inside the compilation unit.
One such case is when you have an array of bottoms (e.g. a Phi of an int[] and a byte[]). When C2 tries to reason about this memory, it receives a distinct slice from every other array, this means that C2 thinks the array aliases with no other kind of arrays, while in reality it should alias with all kinds of arrays.
The same potential issue can be encountered with TypeOopPtr::BOTTOM, we also give it a distinct memory slice, when in reality we should have something that aliases all other oop slices.
My proposal is that we should do similar to Valhalla, in which we have all flat array accesses sharing the same slice, then we divide that slice into smaller ones after we know all the slices that are present. For this issue, we should have all oop accesses share the same slice, then we divide that slice after all inlining. This approach also has multiple benefits:
- Currently, all oop array accesses share the same slice, if we divide the slices after we know all the present slices, we can divide this slice further if we know that there is no access into Object[] in this method.
- Mismatched accesses currently work poorly. We cannot assign them a slice, hence we wrap them in a pair of MemBar to prevent them floating in a nasty manner. This, however, introduces a barrier which prevents memory accesses from floating across it, which is detrimental to multiple optimizations.
- Memory of fields can also be divided better. For example, given classes B and C both inherit the field v from class A, then B.v and C.v can be separate slices if we don't do A.v anywhere inside the compilation unit.
- duplicates
-
JDK-8331133 C2: wrong result - broken memory graph - arrays with bottom element type
-
- In Progress
-