RFR: JDK-8205549 JDK-8205698 Support of flattened values in Unsafe
mandy chung
mandy.chung at oracle.com
Fri Jun 29 03:26:40 UTC 2018
On 6/28/18 5:54 PM, John Rose wrote:
> I read this patch and I like what you are doing; thanks for pushing on
this problem.
>
> I guess the underlying theory is that any object field whose type is
> a value type can be flattened, but the decision to flatten must be
> queried for the metadata *for that field*. The query returns a
> boolean: If false, the field is formatted as a regular oop pointer
> (though there might be a restriction against nulls on it). If true,
> then the field is formatted in a layout which is permanently
> assigned to the value type. Two flattened fields of the same value
> type *always* have the same layout; thus, flattened fields have no
> variance or polymorphism.
Yes that's the underlying theory from my understanding of the current
implementation. Frederic and Karen can double confirm.
> This allows you to statically query whether a given field is
> flattened, and thereafter just use the value type (Class mirror) to
> control how the field is correctly accessed. This all makes sense to
> me, and we want to be clear that this is how we are going to do
> things. For example, we won't pack two value type fields in one
> container by mixing their fields together according to alignment
> restrictions, even though that would pack the containing object
> tighter in memory. I have ideas how to do this in the long run, but
> it would complicate the logic for U.getValue.
Frederic - does that align with what you are thinking?
> Once a field (with its base offset) has been determined to be a flat
> value, then loading or storing it is a fixed procedure to copy into
> TLVB or out of TLVB/HB, which the JIT can easily "see through" and
> optimize down to individual memory operations. There will be one
> such procedure for each U.get/put operation. Maybe {get,put} x
> {normal,volatile,acquire, release,opaque}. In addition to teaching
> the JIT how to optimize those, I wonder if we will want to make them
> into quasi-virtual methods on java.lang.Class or ValueKlass, and call
> them out-of-line from codes which cannot determine the value type
> Class as a JIT-time constant. Probably not, but it's interesting to
> imagine this protocol, a sort of type-dependent access API for
> flattened fields.
>
> In your code, the extra check in unsafe.cpp (check_putfield_access)
> seems to promise that the unsafe access is taking responsibility for
> preventing certain mismatched accesses. The more "unsafe-y" way to
> handle this is to require the caller of the access to perform the
> check. In this way the primitive can do the simplest possible thing,
> even if that would crash the VM if the access is mismatched.
Thanks. Paul also pointed that out.
> This reasoning applies to almost every path you might find in
> unsafe.cpp which throws an exception. It doesn't apply to "large
> scale" ops like loadClass or allocateMemory, but it does apply to
> every op we hope the JIT will optimize as an intrinsic.
>
> As a service to the user we can sometimes make simple checks in
> unsafe.cpp, but if we put complicated ones in, then we are putting
> the optimizations at risk, since the JIT will then have the burden to
> reproduce the complicated checks.
>
> Making the unsafe.cpp code using the 'guarantee' macro is less
> friendly to the user, but more honest than throwing an exception that
> the JIT won't be able to produce.
>
> Dealing with the layers of required checking will be easier, I think,
> if we put most or all of the checks (for flattening, for value type
> mismatches, etc.) in Java code. So if we *do* decide that getObject
> should have a special value-type check (as a service to the user,
> even though the user should drive more carefully) then that check
> would be better reified as a subroutine method call inside a
> Java-coded version of U.getObject, rather than hardwired C++ code in
> unsafe.cpp. In that case, the logic of the Java-coded check can
> itself be made into an intrinsic, so the JIT can separately optimize
> it.
Thanks for this. I'll move the extra check in unsafe to Java code where
appropriate.
Status update: I have got the MethodHandle, VarHandle, core reflection
working with flattened fields (webrev [1] updated in place). Array
access via VarHandles would need more investigation.
Mandy
[1]
http://cr.openjdk.java.net/~mchung/valhalla/webrevs/unsafe-flat-fields-webrev/
More information about the valhalla-dev
mailing list