RFC: 8204690: Simplify usage of Access API

Kim Barrett kim.barrett at oracle.com
Mon Jun 11 19:36:31 UTC 2018


JDK-8204690 is an enhancement request for simplifing the usage of the
Access API.  This RFE comes out of some discussions within the Oracle
runtime and GC teams about difficulties encountered when using the
Access API.  We now have a concrete set of changes to propose (rather
than just vague complaints), described in that RFE, which I'm
duplicating below for further discussion.

Most of the proposed changes are technically straight-forward; many
are just changes of nomenclature. However, because they are name
changes, they end up touching a bunch of files, including various
platform-specific files.  So we'll be asking for help with testing.

We want to move ahead with these changes ASAP, because of the impact
they will have to backporting to JDK 11 if not included in that
release. However, a few of the changes significantly intersect other
changes that are soon to be pushed to JDK 11, so some amount of
scheduling will be needed to minimize overall work.

Here's the description from the RFE:

----------

Simplify usage of Access API

With 6+ months of usage of the Access API, some usage issues have been
noted. In particular, there are some issues around decorator names and
semantics which have caused confusion and led to some long discussions.
While the underlying strategy is sound, there are some changes that would
simplify usage. This proposal is in part the result of attempting to create
a guide for choosing the decorators for some use of the Access API.

We currently have several categories of decorators, with some categories
having entries with overlapping semantics. We'd like to have a set of
categories from which one chooses exactly one entry, and it should be
"obvious" which one to choose for a given access.

The first step is to determine where the operand is located. We presently
have the following decorators to indicate the Access location: IN_HEAP,
IN_HEAP_ARRAY, IN_ROOT, IN_CONCURRENT_ROOT, and IN_ARCHIVE_ROOT. Some of
these overlap with or imply others; the goal is to have a disjoint set.

IN_CONCURRENT_ROOT has generated much discussion about when and how it
should be used. This might be better modelled as a Barrier Strength
decorator, e.g. in the AS_ category. It was placed among the location
decorators with the idea that some Access-roots would be identified as being
fully processed during a safe-point (and so would not require GC barriers),
while others (the "concurrent" roots) would require GC barriers. There was a
question of whether we needed more fine-grained decorators, or whether just
two categories that are the same for all collectors would be sufficient. So
far, we've gotten along without introducing further granularity. But we've
also found no significant need for the distinction at all.

Proposal 1: IN_CONCURRENT_ROOT should be eliminated, and the corresponding
behavior should be the default.

Proposal 2: IN_ARCHIVE_ROOT should be eliminated; see JDK-8204585.

IN_HEAP_ARRAY is effectively an additional orthogonal property layered over
IN_HEAP. It would be better to actually make it an orthogonal property.

Proposal 3: Remove IN_HEAP_ARRAY and add IS_ARRAY with similar semantics.
(IS_ARRAY might only be valid in conjunction with IN_HEAP.)

The use of "root" here differs from how that term is usually used in the
context of GC. In particular, while GC-roots are Access-roots, not all
Access-roots are GC-roots. This is a frequent source of confusion.

Proposal 4: The use of "root" by Access should be replaced by "native". So
IN_ROOT => IN_NATIVE, and RootAccess<> => NativeAccess<>.

The second step is to determine the reference strength. The current API has
been working well here. We have ON_STRONG_OOP_REF, ON_WEAK_OOP_REF,
ON_PHANTOM_OOP_REF, and ON_UNKNOWN_OOP_REF, with ON_STRONG_OOP_REF being the
default. No changes are being proposed in this area.

Another step is to determine the barrier strength. We presently have the
following decorators for this: AS_RAW, AS_DEST_NOT_INITIALIZED,
AS_NO_KEEPALIVE, and AS_NORMAL. AS_DEST_NOT_INITIALIZED is somewhat out of
place here, describing a property of the value rather than the access. It
would be better to make it an orthogonal property. The existing name is also
a little awkward, especially when turned into a variable and logically
negated, e.g.

  bool is_dest_not_initialized = ...;
  ... !is_dest_not_initialized ...

Proposal 5: Rename AS_DEST_NOT_INITIALIZED to IS_DEST_UNINITIALIZED.

The fourth step is to determine the memory order. The current API has been
working well here. We have MO_UNORDERED, MO_VOLATILE, MO_RELAXED,
MO_ACQUIRE, MO_RELEASE, MO_SEQ_CST. No changes are being proposed in this
area.

In addition, we presently have OOP_NOT_NULL, all on its own in a separate
category. There's no need for this separate category, and this can be
renamed to be similar to other orthogonal properties proposed above.

Proposal 6: Rename OOP_NOT_NULL to IS_NOT_NULL.  Remove OOP_DECORATOR_MASK.

Proposal 7: Add IS_DECORATOR_MASK, containing the values for IS_ARRAY,
IS_NOT_NULL, and IS_DEST_UNINITIALIZED.

There are also decorators for annotating arraycopy. These are highly tied in
to the code, and are not discussed here.

With these changes, the process of selecting the decorators for an access
consists of first selecting one decorator in each of the following
categories:

(1) Operand location: IN_NATIVE, IN_HEAP. There is no default; one or the
other must be explicitly specified. However, rather than using the
decorators directly, use the NativeAccess<> and HeapAccess<> classes.

(2) Access strength: AS_NORMAL, AS_RAW, AS_NO_KEEPALIVE. The default
is AS_NORMAL.  When accessing a primitive (non-object) value, use
AS_RAW.

(3) Reference strength (if not raw access): ON_STRONG_OOP_REF,
ON_WEAK_OOP_REF, ON_PHANTOM_OOP_REF, ON_UNKNOWN_OOP_REF. The default is
ON_STRONG_OOP_REF. This decorator is ignored and should be left empty if the
access strength is AS_RAW.

(4) Memory ordering: MO_UNORDERED, MO_VOLATILE, MO_RELAXED, MO_ACQUIRE,
MO_RELEASE, MO_SEQ_CST. The default is MO_UNORDERED.

Then, add any of the following "flag" decorators that are appropriate:
IS_ARRAY, IS_NOT_NULL, IS_DEST_UNINITIALIZED. The default for these is that
the flag is unset.
 Simplify usage of Access API

With 6+ months of usage of the Access API, some usage issues have been
noted. In particular, there are some issues around decorator names and
semantics which have caused confusion and led to some long discussions.
While the underlying strategy is sound, there are some changes that would
simplify usage. This proposal is in part the result of attempting to create
a guide for choosing the decorators for some use of the Access API.

We currently have several categories of decorators, with some categories
having entries with overlapping semantics. We'd like to have a set of
categories from which one chooses exactly one entry, and it should be
"obvious" which one to choose for a given access.

The first step is to determine where the operand is located. We presently
have the following decorators to indicate the Access location: IN_HEAP,
IN_HEAP_ARRAY, IN_ROOT, IN_CONCURRENT_ROOT, and IN_ARCHIVE_ROOT. Some of
these overlap with or imply others; the goal is to have a disjoint set.

IN_CONCURRENT_ROOT has generated much discussion about when and how it
should be used. This might be better modelled as a Barrier Strength
decorator, e.g. in the AS_ category. It was placed among the location
decorators with the idea that some Access-roots would be identified as being
fully processed during a safe-point (and so would not require GC barriers),
while others (the "concurrent" roots) would require GC barriers. There was a
question of whether we needed more fine-grained decorators, or whether just
two categories that are the same for all collectors would be sufficient. So
far, we've gotten along without introducing further granularity. But we've
also found no significant need for the distinction at all.

Proposal 1: IN_CONCURRENT_ROOT should be eliminated, and the corresponding
behavior should be the default.

Proposal 2: IN_ARCHIVE_ROOT should be eliminated; see JDK-8204585.

IN_HEAP_ARRAY is effectively an additional orthogonal property layered over
IN_HEAP. It would be better to actually make it an orthogonal property.

Proposal 3: Remove IN_HEAP_ARRAY and add IS_ARRAY with similar semantics.
(IS_ARRAY might only be valid in conjunction with IN_HEAP.)

The use of "root" here differs from how that term is usually used in the
context of GC. In particular, while GC-roots are Access-roots, not all
Access-roots are GC-roots. This is a frequent source of confusion.

Proposal 4: The use of "root" by Access should be replaced by "native". So
IN_ROOT => IN_NATIVE, and RootAccess<> => NativeAccess<>.

The second step is to determine the reference strength. The current API has
been working well here. We have ON_STRONG_OOP_REF, ON_WEAK_OOP_REF,
ON_PHANTOM_OOP_REF, and ON_UNKNOWN_OOP_REF, with ON_STRONG_OOP_REF being the
default. No changes are being proposed in this area.

Another step is to determine the barrier strength. We presently have the
following decorators for this: AS_RAW, AS_DEST_NOT_INITIALIZED,
AS_NO_KEEPALIVE, and AS_NORMAL. AS_DEST_NOT_INITIALIZED is somewhat out of
place here, describing a property of the value rather than the access. It
would be better to make it an orthogonal property. The existing name is also
a little awkward, especially when turned into a variable and logically
negated, e.g.

  bool is_dest_not_initialized = ...;
  ... !is_dest_not_initialized ...

Proposal 5: Rename AS_DEST_NOT_INITIALIZED to IS_DEST_UNINITIALIZED.

The fourth step is to determine the memory order. The current API has been
working well here. We have MO_UNORDERED, MO_VOLATILE, MO_RELAXED,
MO_ACQUIRE, MO_RELEASE, MO_SEQ_CST. No changes are being proposed in this
area.

In addition, we presently have OOP_NOT_NULL, all on its own in a separate
category. There's no need for this separate category, and this can be
renamed to be similar to other orthogonal properties proposed above.

Proposal 6: Rename OOP_NOT_NULL to IS_NOT_NULL.  Remove OOP_DECORATOR_MASK.

Proposal 7: Add IS_DECORATOR_MASK, containing the values for IS_ARRAY,
IS_NOT_NULL, and IS_DEST_UNINITIALIZED.

There are also decorators for annotating arraycopy. These are highly tied in
to the code, and are not discussed here.

With these changes, the process of selecting the decorators for an access
consists of first selecting one decorator in each of the following
categories:

(1) Operand location: IN_NATIVE, IN_HEAP. There is no default; one or the
other must be explicitly specified. However, rather than using the
decorators directly, use the NativeAccess<> and HeapAccess<> classes.

(2) Access strength: AS_NORMAL, AS_RAW, AS_NO_KEEPALIVE. The default is AS_NORMAL.  When accessing a primitive (non-object) value, use AS_RAW.

(3) Reference strength (if not raw access): ON_STRONG_OOP_REF,
ON_WEAK_OOP_REF, ON_PHANTOM_OOP_REF, ON_UNKNOWN_OOP_REF. The default is
ON_STRONG_OOP_REF. This decorator is ignored and should be left empty if the
access strength is AS_RAW.

(4) Memory ordering: MO_UNORDERED, MO_VOLATILE, MO_RELAXED, MO_ACQUIRE,
MO_RELEASE, MO_SEQ_CST. The default is MO_UNORDERED.

Then, add any of the following "flag" decorators that are appropriate:
IS_ARRAY, IS_NOT_NULL, IS_DEST_UNINITIALIZED. The default for these is that
the flag is unset.



More information about the hotspot-dev mailing list