8205908: Unnecessarily strong memory barriers in ParNewGeneration::copy_to_survivor_space
Doerr, Martin
martin.doerr at sap.com
Tue Jul 3 13:51:18 UTC 2018
Hi Michihiro,
I think oopDesc::forward_to should not be changed with this change because it is used by many GCs.
If you want to add a StoreStore barrier, you could add “OrderAccess::storestore();” before “old->forward_to(new_obj);” for example.
It would be nice to have a comment for your new case in oopDesc::forward_to_atomic.
Best regards,
Martin
From: Michihiro Horie [mailto:HORIE at jp.ibm.com]
Sent: Dienstag, 3. Juli 2018 10:26
To: Doerr, Martin <martin.doerr at sap.com>
Cc: hotspot-gc-dev at openjdk.java.net; Kim Barrett <kim.barrett at oracle.com>; Gustavo Romero <gromero at linux.vnet.ibm.com>
Subject: RE: 8205908: Unnecessarily strong memory barriers in ParNewGeneration::copy_to_survivor_space
Hi Martin,
Thanks a lot for your review. Sure, we need an OK from a CMS expert. Following is the new webrev:
http://cr.openjdk.java.net/~mhorie/8205908/webrev.01/
>Seems like a user of the forwardee needs to rely on memory_order_consume in the current implementation. I guess it will be appreciated that you’re fixing this.
Thank you for pointing out this issue in the original implementation. I newly inserted a release at "2.4. Set new_obj as forwardee [L1142]".
Improvement of critical-jOPS in SPECjbb2015 was 10%, which is still a big number.
Best regards,
--
Michihiro,
IBM Research - Tokyo
[Inactive hide details for "Doerr, Martin" ---2018/07/02 16:56:03---Hi Michihiro, thanks for addressing this issue.]"Doerr, Martin" ---2018/07/02 16:56:03---Hi Michihiro, thanks for addressing this issue.
From: "Doerr, Martin" <martin.doerr at sap.com<mailto:martin.doerr at sap.com>>
To: Michihiro Horie <HORIE at jp.ibm.com<mailto:HORIE at jp.ibm.com>>, "hotspot-gc-dev at openjdk.java.net<mailto:hotspot-gc-dev at openjdk.java.net>" <hotspot-gc-dev at openjdk.java.net<mailto:hotspot-gc-dev at openjdk.java.net>>
Cc: Kim Barrett <kim.barrett at oracle.com<mailto:kim.barrett at oracle.com>>, Gustavo Romero <gromero at linux.vnet.ibm.com<mailto:gromero at linux.vnet.ibm.com>>
Date: 2018/07/02 16:56
Subject: RE: 8205908: Unnecessarily strong memory barriers in ParNewGeneration::copy_to_survivor_space
________________________________
Hi Michihiro,
thanks for addressing this issue.
The change looks good to me. I only have a comment on the coding style (oop.inline.hpp): “if ()” should be followed by braces “{ … }”.
Seems like a user of the forwardee needs to rely on memory_order_consume in the current implementation. I guess it will be appreciated that you’re fixing this.
Please note that SAP still supports CMS in the commercial VM so this change is still relevant and we’d like to push it to jdk11 if possible.
But we definitely need an OK from a CMS expert (which I’m not).
Best regards,
Martin
From: Michihiro Horie [mailto:HORIE at jp.ibm.com]
Sent: Mittwoch, 27. Juni 2018 02:23
To: hotspot-gc-dev at openjdk.java.net<mailto:hotspot-gc-dev at openjdk.java.net>
Cc: Doerr, Martin <martin.doerr at sap.com<mailto:martin.doerr at sap.com>>; Kim Barrett <kim.barrett at oracle.com<mailto:kim.barrett at oracle.com>>; Gustavo Romero <gromero at linux.vnet.ibm.com<mailto:gromero at linux.vnet.ibm.com>>
Subject: RFR: 8205908: Unnecessarily strong memory barriers in ParNewGeneration::copy_to_survivor_space
Dear all,
Would you please review the following change?
Bug: https://bugs.openjdk.java.net/browse/JDK-8205908
Webrev: http://cr.openjdk.java.net/~mhorie/8205908/webrev.00/
[Current implementation]
ParNewGeneration::copy_to_survivor_space tries to move live objects to a different location. There are two patterns on how to copy an object depending on whether there is space to allocate new_obj in to-space or not. If a thread cannot find space to allocate new_obj in to-space, the thread first executes the CAS with a dummy forwarding pointer "ClaimedForwardPtr", which is a sentinel to mark an object as claimed. After succeeding in the CAS, a thread can copy the new_obj in the old space. Here, suppose thread A succeeds in the CAS, while thread B fails in the CAS. When thread A finishes the copy, it replaces the dummy forwarding pointer with a real forwarding pointer. After thread B fails in the CAS, thread B returns the forwardee after waiting for the copy of the forwardee is completed. This is observable by checking the dummy forwarding pointer is replaced with a real forwarding pointer by thread A. In contrast, if a thread can find space to allocate new_obj in to-space, the thread first copies the new_obj and then executes the CAS with the new_obj. If a thread fails in the CAS, it deallocates the copied new_obj and returns the forwardee.
Procedure of ParNewGeneration::copy_to_survivor_space : ([L****] represents the line number in src/hotspot/share/gc/cms/parNewGeneration.cpp)
1. Try to each allocate space for new_obj in to-space [L.1110]
2. If fail in the allocation in to-space [L1117]
2.1. Execute the CAS with the dummy forwarding pointer [L1122] ——— (A)
2.2. If fail in the CAS, return the forwardee via real_forwardee() [L1123]
2.3. If succeed in the CAS [L1128]
2.3.1. If promotion is allowed, copy new_obj in the old area [L1129]
2.3.2. If promotion is not allowed, forward to obj itself [L1133]
2.4. Set new_obj as forwardee [L1142]
3. If succeed in the allocation in to-space [L1144]
3.1. Copy new_obj [L1146]
3.2. Execute the CAS with new_obj [L1148] ——— (B)
4. Dereference the new_obj for logging. Each new_obj copied by each thread at step 3.1 is used instead of forwardee() [L1159]
5. If succeed in either CAS (A) or CAS (B), return new_obj [L1163]
6. If fail in CAS (B), get the forwardee via real_forwardee(). Unallocate new_obj in to-space [L1193]
7. Return forwardee [L1203]
For reference, real_forwardee() is as shown below:
oop ParNewGeneration::real_forwardee(oop obj) {
oop forward_ptr = obj->forwardee();
if (forward_ptr != ClaimedForwardPtr) {
return forward_ptr;
} else {
// manually inlined for readability.
oop forward_ptr = obj->forwardee();
while (forward_ptr == ClaimedForwardPtr) {
waste_some_time();
forward_ptr = obj->forwardee();
}
return forward_ptr;
}
}
Regarding the CAS (A),
There is no copy before the CAS.
Dereferencing the forwardee must be allowed after obtaining the forwardee.
Regarding the CAS (B),
There is a copy before the CAS.
Dereferencing the forwardee must be allowed after obtaining the forwardee.
[Observation on the current implementation]
No fence is necessary before and after the CAS (A).
Release barrier is necessary before the CAS (B).
The forwardee_acquire() must be used instead of forwardee() in real_forwardee().
[Performance measurement]
The critical-jOPS of SPECjbb2015 improved by 12% with this change.
Best regards,
--
Michihiro,
IBM Research - Tokyo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20180703/2996127f/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.gif
Type: image/gif
Size: 105 bytes
Desc: image001.gif
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20180703/2996127f/image001.gif>
More information about the hotspot-gc-dev
mailing list