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