-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
8305898: Alternative self-forwarding mechanism #20603
Conversation
👋 Welcome back rkennke! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
5eb66f6
to
86239af
Compare
/label remove hotspot |
@rkennke |
@rkennke |
Webrevs
|
@@ -706,32 +700,27 @@ void DefNewGeneration::remove_forwarding_pointers() { | |||
// starts. (The mark word is overloaded: `is_marked()` == `is_forwarded()`.) | |||
struct ResetForwardedMarkWord : ObjectClosure { | |||
void do_object(oop obj) override { | |||
if (obj->is_forwarded()) { | |||
if (obj->is_self_forwarded()) { |
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.
Why is is_self_forwarded
treated specially? I'd expect the is_forwarded
case alone to be enough here.
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.
Because I'd like self-forwarded marks not to be init-ed. Otherwise we'd have to preserve/restore them. Simply unset_self_forwarded() is enough to get them back to the original state.
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.
Otherwise we'd have to preserve/restore them.
OK, then it's incorrect to use init_mark()
for self-fwd objs.
This method is for self-fwd objs only. Can we remove the else if
part? The non-self-fwd objs are essentially dead, right?
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 wasn't sure about this. What happens to successfully-promoted objects? Are we sure that no references point to their from-space parts? If yes, then I'd remove the else-if part and place an assert there instead.
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.
The else if part is needed when we later turn on UseCompactObjectHeaders, because the "normal" forwarding pointers then destroy the klass pointers, causing the object_iterate to fail to read the size of the objects.
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.
What happens to successfully-promoted objects? ...
Successfully-forwarded objs are don't live in eden/from spaces, which are the spaces this closure is applied on. One can't have assert here, because as we iterate over eden/from spaces, we will encounter successfully-forwarded objs, but they should just be skipped.
The else if part is needed when we later turn on UseCompactObjectHeaders...
I believe so, but it should be in the UseCompactObjectHeaders PR, not this 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.
Ok, thanks for the explanation!
I don't think it's needed for the UCOH part - the iterator fetched Klass*/size from forwardee if it encounters forwarded objects.
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.
You didn't change the iterators for the Serial GC, only for Parallel. But, yes, we can deal with this in the UCOH PR.
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.
It might not be clear to reviewers, but the suggested change forces the usage of Lightweight locking on 32-bit JVMs. I think that is OK, especially given that Legacy locking is deprecated. However, before approving this PR it would be good to know if this has been communicated to the maintainers of the affected platforms?
And with that said, I couldn't find anything in this patch that prevented 32-bit JVMs from starting with Legacy. There's only these asserts:
NOT_LP64(assert(LockingMode != LM_LEGACY, "incorrect with LM_LEGACY on 32 bit");)
Right, with this change, we cannot use legacy locking on 32bit platforms anymore, because 1. the self-fwd bit would conflict with stack-locks because stack-locks are only 4-byte aligned on those platforms and 2. we no longer preserve headers around self-forwarding. No I haven't communicated this, yet. |
I'm fine with handling it here in this PR. |
Superseding by #20677 |
Currently, the Serial, Parallel and G1 GCs store a pointer to self into object headers, when promotion fails, to indicate that the object has been looked at, but failed promotion. This is problematic for compact object headers (JDK-8294992) because it would (temporarily) over-write the crucial class information, which we need for heap parsing. I would like to propose an alternative: use the bit #3 (previously biased-locking bit) to indicate that an object is 'self-forwarded'. That preserves the crucial class information in the upper bits of the header until the full header gets restored.
A side-effect of this is that we can get rid of the machinery to preserve headers across promotion failures in Serial and G1. (Parallel GC [ab]uses the preserved-headers structure to also find all the forwarded objects for header restoration. This could be changed, I suppose, but it is not trivial.) If you prefer, I could break-out the removal of the preserved-headers stuff into a separate PR.
This is in preparation of upstreaming compact object headers, and I intend to push it only once all the parts have been approved.
Testing:
Progress
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/20603/head:pull/20603
$ git checkout pull/20603
Update a local copy of the PR:
$ git checkout pull/20603
$ git pull https://git.openjdk.org/jdk.git pull/20603/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 20603
View PR using the GUI difftool:
$ git pr show -t 20603
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/20603.diff
Webrev
Link to Webrev Comment