Request for review (S): 7103665 HeapWord*ParallelScavengeHeap::failed_mem_allocate(unsigned long,bool)+0x97
Bengt Rutisson
bengt.rutisson at oracle.com
Fri Mar 23 12:56:11 UTC 2012
Hi all,
Could I have a couple of reviews for this change? This is on the
critical-watch list for hs23, so it would be great if I could get some
reviews already today.
http://cr.openjdk.java.net/~brutisso/7103665/webrev.00/
Some background:
There are two problems that this fix solves:
(1) When we run with -XX:+UseNUMA we have to make the heap parsable
since we leave some holes in the heap. We do this by faking Integer
arrays in those places. However, on a large heap those holes can be
larger than what can be covered by a single Integer array. The fix is to
allocate several arrays in those cases.
The easy fix would have been to call CollectedHeap::fill_with_objects()
instead of CollectedHeap::fill_with_object(). Note the extra "s" in the
method name. But MutableNUMASpace::ensure_parsability(), where the
change is needed, need to know about all the objects that are allocated
so I saw no better solution than to implement my own loop. Any ideas on
how I could re-use fill_with_objects() instead are welcome.
(2) CollectedHeap::_filler_array_max_size should be the maximum size
that can be covered by a fake Integer array. This value is in words, but
since the word size is different on different platforms but the Integer
size is always the same we need to convert between word and sizeof(jint)
at some point. Unfortunately we do the conversion in the wrong
direction, which means that on 64 bit platforms we end up with a max
size that is 4 times larger than intended. This in turn makes us
overflow an int when we convert from a word size to the length of the
array that we are setting up.
Here is the code that overflows:
328 void
329 CollectedHeap::fill_with_array(HeapWord* start, size_t words, bool
zap)
330 {
331 assert(words >= filler_array_min_size(), "too small for an array");
332 assert(words <= filler_array_max_size(), "too big for a single
object");
333
334 const size_t payload_size = words - filler_array_hdr_size();
335 const size_t len = payload_size * HeapWordSize / sizeof(jint);
336
337 // Set the length first for concurrent GC.
338 ((arrayOop)start)->set_length((int)len);
339 post_allocation_setup_common(Universe::intArrayKlassObj(),
start, words);
340 DEBUG_ONLY(zap_filler_array(start, words, zap);)
341 }
If filler_array_max_size() on line 332, which returns
CollectedHeap::_filler_array_max_size, has a too large value we will
overflow the int conversation on line 338.
Testing:
This fix solves the issue that was found in the reproducer that I could
set up on a Linux x64 machine. I have asked the one who initially
reported the issue to run on their Solaris amd64 setup. I will also try
to set up a reproducer on a Solaris machine.
I also ran the fix through JPRT. It did not fail, but there are no NUMA
tests in there as far as I know. But the change for issue (2) was
hopefully tested.
Thanks,
Bengt
More information about the hotspot-gc-dev
mailing list