RFC: 8204690: Simplify usage of Access API
Roman Kennke
rkennke at redhat.com
Mon Jun 11 20:10:46 UTC 2018
Hi Kim,
I need to digest all this. But may I throw in another ambiguity:
OOP_IS_NULL is, as far as I can tell, used to decorate an access where
the *value* is known to be not null (for stores), or the value coming
out of a load is known to be not null (for loads). This is useful for
stuff like compressed oops, where a null-check can be elided if we know
it's not null. However, at least when using this in Shenandoah land, it
is also useful to know whether or not a target oop (the object being
written to, or loaded from) is known to be not null, at least in
compiled code. If it's known to be not null, we can elide a null-check
on the read/write barrier around the memor access. I propose to
disambiguate this by splitting the semantics into VALUE_NOT_NULL (or
similar) and TARGET_NOT_NULL (or similar). Suggestions welcome!
I'll dig more into the proposal and probably come up with more comments.
Thanks!!!
Roman
> 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