New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8331006: [lworld] Support of null markers for nullable flat fields #1078
Conversation
👋 Welcome back fparain! A progress list of the required criteria for merging this PR into |
@fparain This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 302 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
Webrevs
|
test/hotspot/jtreg/runtime/valhalla/inlinetypes/NullableFlatFieldTest.java
Outdated
Show resolved
Hide resolved
test/hotspot/jtreg/runtime/valhalla/inlinetypes/field_layout/NullMarkersTest.java
Show resolved
Hide resolved
test/hotspot/jtreg/runtime/valhalla/inlinetypes/NullableFlatFieldTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good initial runtime implementation to hang the JIT implementation off of, further work for other PRs...good to go !
bool field_is_known_value_class = !fieldinfo.field_flags().is_injected() && _inline_type_field_klasses != nullptr && _inline_type_field_klasses->at(fieldinfo.index()) != nullptr; | ||
bool value_has_oops = field_is_known_value_class ? _inline_type_field_klasses->at(fieldinfo.index())->nonstatic_oop_count() > 0 : true; | ||
bool is_candidate_for_flattening = fieldinfo.field_flags().is_null_free_inline_type() || (EnableNullableFieldFlattening && field_is_known_value_class && !value_has_oops); | ||
// if (!fieldinfo.field_flags().is_null_free_inline_type()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth pulling this into a array_candidate_for_flattening
helper method? It's a complex set of conditions and this is the second occurrence of it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the duplication either, and having a helper method would make the code easier to read. However, this is a section of code under big transformations, with nullable flat field being added, then next the atomic fields, then the nullable atomic fields. Before refactoring, I'd prefer to wait until all the cases are covered, so we know exactly all the parameters the helper method will require, and if the two cases are still identical or if some divergences appeared.
InstanceKlass* ik = InstanceKlass::cast(obj_h()->klass()); | ||
int nm_offset = ik->null_marker_offsets_array()->at(entry->field_index()); | ||
if (val_h() == nullptr) { | ||
obj_h()->byte_field_put(nm_offset, (jbyte)0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a barrier here? When we write the null marker, it is as if we wrote the null marker and then nulled the fields out (which we don't actually do) which makes me think we always need the barrier after writing the null marker to be consistent with the non-null case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, there is a single write from the current thread, so there's no visibility ordering issue like with the non-null case. A concurrently reading thread will check (or has already read) the null marker, and this would be no different than reading a reference field being set to null. So I don't think we need a barrier here, but if you really think there's a potential issue, I can add one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're right here and we don't need the release_byte_field_put
here. Just as we're happy for reads/writes of null references to slowly make their way to other threads, a slow discovery of the null bit is fine given the other value fields are stable before the bit flips.
The barrier you have in place is sufficient for that constraint.
if (entry->has_internal_null_marker()) { | ||
// The interpreter copies values with a bulk operation | ||
// To avoid accidently setting the null marker to "null" during | ||
// the copying, the null marker is set to non zero in the source object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this saying if the null marker is embedded in the value field layout rather than placed separately, we set it to non-null before writing it into the container? This tripped me up a little bit reading the code but I think it makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does that work for our memory barriers then? Do we not need a release here as well given the acquire used to read the null marker?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This particular case cannot currently happen with JEP 401 model implementation (nullable flat field are limited to single field values until we have atomic updates supported). But it involves the tearing issue the interpreter has in some cases. So, even adding a barrier would not make the code correct. I'd prefer to address the issue of this particular code when fixing the wider interpreter tearing issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarifications. This looks good to me.
Mr Simms, Dan, |
/integrate |
Going to push as commit eb1df16.
Your commit was automatically rebased without conflicts. |
This is the first step in supporting nullable flat fields in JEP 401.
Those changes give value fields the optional capability to be associated with a null marker that indicates if the value if the field is null or not. Null markers are integrated in the object layout, and in the field metadata (in both compresses and uncompressed forms).
Field accesses in the x86 and the arch64 interpreter have been extended to check the presence of a null marker when reading a field. If present, the null marker is checked in reads and updated on writes.
The field layout logic is becoming more complex (and the complexity will continue to increase in the future with the addition of atomic flat fields and atomic nullable flat fields). So the changeset includes a test framework able to verify the consistency of fields layout using the output of -XX:+PrintFieldLayout. The format of data printed by PrintFieldLayout has been extended and modified to be easier to parse.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/valhalla.git pull/1078/head:pull/1078
$ git checkout pull/1078
Update a local copy of the PR:
$ git checkout pull/1078
$ git pull https://git.openjdk.org/valhalla.git pull/1078/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1078
View PR using the GUI difftool:
$ git pr show -t 1078
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/valhalla/pull/1078.diff
Webrev
Link to Webrev Comment