JDK-8022853 : add ability to load uncompressed object and Klass references in a compressed environment to Unsafe
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P5
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2013-08-12
  • Updated: 2016-05-09
  • Resolved: 2015-04-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b64Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
In some native data structures of the VM oops are stored uncompressed even if compressed oops are turned on, for example Klass::_java_mirror.  Java code which is tightly coupled with the VM should have the ability to read and write such fields.

This additional Unsafe API make the implementation of JEP 243: Java-Level JVM Compiler Interface simpler.
Comments
I've changed the Summary to only talk about loading since the change will not support storing.
13-04-2015

Any solution for this vexed problem that Chris and Coleen can agree on is fine with me. So let me see if I get it: - getKlassPointer(o) pulls a metaspace pointer out of an object reference, decoding/decompressing as needed to get a Real Address. Comment: If we ever do near classes, that should be a near class, and the user is responsible for getting the far class (if needed). - getJavaMirror(k) pulls a java.lang.Class out of the address of a metadata class (far class, if applicable). This may use an unknown number of indirections to track down its quarry, so its opacity is like Unsafe.monitorEnter. This primitive is good for only one thing. - getUncompressedObject(o+off) loads an object pointer from metaspace, taking into account the characteristics of how oops are stored in metaspace. Here is some new data about Unsafe API patterns. We just accepted a patch (JDK-8026049) adding new degrees of freedom to the primitive gets and sets. There are two new options: allow unaligned access, and specify byte order. The pattern settled on uses new method names to encode the unaligned option, and an optional boolean to specify byte order. The boolean defaults to a reasonable value (platform byte order). Note that these API enhancements do not say anything about where the "funny" data formats are stored. We could have made these intrinsics specific to byte buffers (which is what the RFE is for), but primitives in Unsafe make better sense (to me at least) if they do not make too many claims about where the data locations are. They make the (super-)user responsible for applying the right format to the right location. Some of the API patterns with primitives may be applicable to oop loading and storing. Unlike primitives, oops are never stored unaligned or in non-native byte order; but, they are stored with or without compression, and the they are stored with or without card marking. If we control these options with an explicit boolean like "bigEndian" (or explicit mode in the name like "Unaligned"), we get a context free API. As an overstated example: Object getManagedPointer(Object o, long offset [, boolean isCompressed, int barrierType]). As Coleen points out, the trend in metaspace is to isolate oops as much as possible, into a handles array. Assuming that trend is quite robust, it can make sense to have API points in Unsafe which are bound to particular contexts, such as the handles array, something like getObjectFromMetaspaceHandleArray(Object o, long offset). Then the "isCompressed" option is naturally set to agree with the context, and doesn't need or want a separate argument.
07-04-2015

[~coleenp] said regarding Unsafe.getUncompressedObject: "Your comment could say that the object is coming from metadata (either C heap allocated or in metaspace) so that the object doesn���t follow the compression chosen by the jvm."
07-04-2015

After some discussion with [~coleenp] we have agreed on a path forward. The agreed on interface will probably look something like this: Class<?> Unsafe.getJavaMirror(long metaspaceKlass) Object Unsafe.getUncompressedObject(Object o, long offset) long Unsafe.getKlassPointer(Object o) This enables us to read all the values we need.
07-04-2015

To add some fuel to the fire before it goes out... now that Unsafe will be non-accessible in the modules world, could we talk again about adding this?
23-02-2015

Is there any chance we can get this into 9?
10-04-2014

Here is a link to the review thread that ultimately led to the withdrawal of the patch: http://mail.openjdk.java.net/pipermail/hotspot-dev/2013-August/010554.html
04-09-2013