RFR: JDK-8061259: ParNew promotion failed is serialized on a lock
Kim Barrett
kim.barrett at oracle.com
Thu Nov 6 01:50:30 UTC 2014
On Oct 30, 2014, at 1:24 PM, Jungwoo Ha <jwha at google.com> wrote:
>
> PTAL
> http://cr.openjdk.java.net/~rasbold/8061259/webrev.02/
------------------------------------------------------------------------------
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
271 // Support for CMSFastPromotionFailure
272 reset_promotion_failed();
Why this and not just initialize the data member in the constructor
initializer list?
------------------------------------------------------------------------------
[All of code discussed here is in par_promote().]
The tests of CMSFastPromotionFailure && has_promotion_failed() that
are outside the lock have a sort of DCLP (double checked locking
pattern) feel to them. The goal here is to avoid the locked region
and go do something else, instead of waiting for the current lock
holder to complete the work the checker would be doing if only they
could get the lock.
I think I would like it better if the outside the lock tests were
moved closer to the lock entries, to emphasize that relationship, and
to reduce the code affected by the introduction of this set of
changes. That might result in the thread that gives up doing a little
more work before giving up. I'm particularly thinking of
1358 if (CMSFastPromotionFailure && has_promotion_failed()) {
1359 return NULL;
1360 }
removal of which would let execution proceed to
1373 if (!expand_and_ensure_spooling_space(promoInfo)) {
1374 return NULL;
and give up because the moved test caused expand_xxx to return false.
I don't know if the placement of the test at line 1358 rather than
inside expand_and_ensure_spooling_space() would be significant. I
suspect not, but without measurements I don't have a lot of confidence
in that supposition. But I think that change would improve the
understandability of the code.
In the other case,
1381 if (CMSFastPromotionFailure && has_promotion_failed()) {
1382 return NULL;
1383 }
1384 obj_ptr = expand_and_par_lab_allocate(ps, alloc_sz);
I would definitely prefer that test be moved into
expand_and_par_lab_allocate(). This is the only call to that
function, and the first thing it does is lock the mutex and re-perform
the test.
------------------------------------------------------------------------------
I'm suspicious of the during-review change to make
_has_promotion_failed non-atomic.
I see the argument for the interaction between set and test; the set
occurs in lock context so gets released on the way out of the lock,
while the first time each core gets a stale false value it will
acquire the lock and acquire the updated set value, so that future
tests on the same core will avoid the code in question, until the
reset finally happens.
However, I think the present interaction between reset and test is not
safe. A test seeing a stale true value leads to an inappropriate skip
of the protected code, with nothing obvious to prevent that from
occurring "forever".
------------------------------------------------------------------------------
More information about the hotspot-gc-dev
mailing list