RFR 8042668: GC Support for shared heap ranges in CDS (RE: JDK-8059092)
Thomas Schatzl
thomas.schatzl at oracle.com
Wed Jun 10 12:23:47 UTC 2015
Hi again,
one additional note, because I just stumbled across it: the new
G1CollectedHeap::fill_with_non_humongous_objects() could be replaced by
using CollectedHeap::fill_with_objects() and properly setting up
CollectedHeap::_filler_array_max_size for G1.
Thanks,
Thomas
On Tue, 2015-06-09 at 22:57 +0200, Thomas Schatzl wrote:
> Hi Tom,
>
> I am answering this email based on my re-review of the latest changes
> at http://cr.openjdk.java.net/~tbenson/8042668/webrev.02/ because it
> covers most responses.
>
> First, I appreciate for considering the suggestions. I would have even
> more appreciated it for re-review, if there were a diff changeset :)
>
> On Thu, 2015-06-04 at 16:09 -0400, Tom Benson wrote:
> > Hi Thomas,
> > Thanks for the review. I've made many of the changes, except where noted.
> > I want to look a little more at options for re-factoring the code that
> > walks the
> > heap region array. I'll post a separate reply about that.
> >
> > > - Comments about that humongous regions are never added to the collection
> > > set in collectionSetChooser.hpp need to be updated. While it is still
> > > true, that humongous regions are never added, we actually never want to
> > > add pinned regions, which are a superset.
> > > E.g. collectionsetChooser.hpp:106
> >
> > This comment was, in fact, updated to include archive regions, but perhaps
> > the parenthetical note made it hard to notice. The review version says:
> >
> > 106 // not. Currently, we skip humongous regions (we never add them to
> > 107 // the CSet, we only reclaim them during cleanup) and archive
> > regions,
> > 108 // which are both "pinned", and regions whose live bytes are
> > over the
> > 109 // threshold.
> >
> > So, I've now re-ordered it to make it more obvious.
>
> The main part, and that is what the code does, is that we do not add
> pinned regions. It is incidental that all humongous regions and archived
> regions are pinned at the moment. Not the other way around; in that
> sentence the the actual relevant information for deciding to add a
> region is in a sub-clause.
>
> E.g. there are some ideas to allow limited copying of humongous regions
> in the future to fight region-level fragmentation.
>
> The comment now is somewhat better. I am okay with the current version
> though.
>
> > > - In general it would be nice if the asserts gave more information than
> > > just some "this failed" message. E.g. it would be nice to at least
> > > print the
> > > index of the HeapRegion or the base address to be able to find out more
> > > information about it just using the hs_err file.
> > >
> > > All changed asserts have that problem, so I am not mentioning them
> > > explicitly.
> >
> > OK. I focused on the ones I have added, rather than existing ones where
> > I may
> > have changed "is_humongous" to "is_pinned", for example. But I did
> > change the
> > existing one in g1EvacFailure where the previous message was just "sanity".
> >
> > I had already changed some in g1Allocator at Bengt's suggestion since
> > the version
> > you reviewed. Now I've changed others where I think it makes sense.
>
> If others think this is okay, then I won't object to it any more. To me,
> having as much as possible useful information about what is wrong in the
> assert message seems very useful.
>
> E.g. with the existing comment in the first assert in
> G1CollectedHeap::check_archive_addresses() (and other similar cases) I
> would not be able to rule out one or the other condition failing.
>
> As for the part about not fixing existing bad comments, we also agree to
> disagree that this is not useful. :)
>
> - extra newline in g1Allocator.cpp:174
>
> - g1Allocator.cpp:299: // MemRegions to the growable array provided by
> the caller.
>
> I would prefer using "GrowableArray" the class name in the comment
> instead of "growable array" to avoid confusion
>
> - G1ArchiveAllocator::complete_archive: could the method verify that
> "ranges" at least contains one element, and that it's not NULL?
>
> - G1ArchiveAllocator class definition: please provide a summary what the
> class is intended to do.
>
> - G1ArchiveAllocator::~G1ArchiveAllocator: I recommend making
> destructors virtual by default unless there is some particular concern
> (like avoiding the increase in object size). Otherwise, when subclassing
> (and adding virtual methods) the virtual is just forgotten. But the code
> is not wrong, so keep it if you want.
>
> - G1CollectedHeap::alloc_archive_regions: please give the "commits"
> variable an unsigned type, as it is a count.
>
> - G1CollectedHeap::end_archive_alloc_range(): is there a reason why the
> destructor of _archive_allocator is directly called instead of
> delete'ing the instance?
>
> - g1CollectedHeap.cpp: extra newline at 1134, 3137, 3161
>
> - it would be really great if the asserts in the verification closures
> in g1collectedheap.cpp printed the offending object address and what it
> points to. This would save you looking for the addresses in the
> debugger, and works even if something is optimized away (i.e. in
> fastdebug mode). :)
>
> - in g1CollectedHeap.cpp: line 6385, could the reason why archive
> regions are ignored be added here? The additional condition seems
> superfluous since they are part of the old, and we should not get here
> (imo).
>
> - g1Collectedheap.cpp: line 6444, there is a new extra space at the end
> of the line (assuming that I did not accidentally added it).
>
> - g1Collectedheap.cpp: line 6450-6455: why is it required to not set
> archive regions old? Apart from that they are already old, setting them
> old again does not seem to hurt. (It has been done that way before)
>
> - g1CollectedHeap.cpp: line 6639: the code specifically calls out
> (asserts on) non-pinned regions, while the next line is a
> ShouldNotReachHere(). It seems to be some debugging code leftover -
> otherwise I would prefer to print the kind of region at this point
> unconditionally.
>
> - G1CollectedHeap::alloc_highest_free_region() should not be public, it
> seems to purely be a helper function.
>
> - g1CollectedHeap.hpp:741: wouild -> would
>
> - g1MarkSweep.cpp:281/386: I would prefer if the "if" part of an "else
> if" is on the same line as the "else", not opening an unnecessary block.
> Feel free to ignore.
>
> - heapRegion.cpp:723: I am not sure that excluding pinned regions here
> is what is expected. This code verifies that the to-region has a correct
> remembered set entry. As far as I know, at the moment we still manage
> remembered sets for the pinned (and archived) regions. It seems to me
> that also the original code is wrong. I may be overlooking something.
>
> - HeapRegionManager::find_highest_free(): there is a potential overflow
> for curr in the code: int's cannot hold uints (i.e. the result of
> max_length()).
>
> - HeapRegionManager::allocate_containing_regions() uses an int to return
> the number of committed regions in commit_count. Please use size_t.
>
> - HeapRegionManager::allocate_containing_regions: I am somewhat
> concerned about the use of uints to hold size_t arguments, ie.
>
> uint start_index = _regions.get_index_by_address(range.start());
> uint last_index = _regions.get_index_by_address(range.last());
>
> Does no compiler complain about this?
>
> - why is the "|| hr->is_archive()" clause needed in
> HeapRegionManager::verify()? Imo it would be preferable (but just
> minimally so), like for humongous starts regions to use the orig_end()
> member for prev_end (i.e. add to the "if (starts_humongous..." in line
> 498).
> The current code basically tries to verify that between regions there
> are no holes, i.e. the heap is contiguous.
> Now archive regions potentially (i.e. the last one) have their end() not
> at the end of the complete region, so I understand why this would fail
> without specially handling them.
> As mentioned, I would prefer to extend the existing workaround for
> humongous starts regions, instead of disabling the assert.
>
> - HeapRegionSetBase::verify_region(): I thought below you mentioned that
> there can be no completely empty/free region, so why could this fail
> with archive regions in the mix?
>
> > > - I think the code in line 225-231 may cause crashes/asserts.
> > >
> > > 225 if ((new_top > _max) ||
> > > 226 ((new_top < _max) && (remainder <
> > CollectedHeap::min_fill_size()))) {
> > > 227 if (old_top != _max) {
> > > 228 size_t fill_size = _max - old_top;
> > > 229 CollectedHeap::fill_with_object(old_top, fill_size);
> > > 230 _summary_bytes_used += fill_size * HeapWordSize;
> > > 231 }
> > >
> > > i.e. consider the situation exactly when the remaining space is too
> > small to
> > > fit a filler object, i.e. old_top == _max - remainder
> > > (where remainder == (G1CollectedHeap::min_fill_size() - 1)). In this
> > case,
> > > the condition in line 226 holds (new_top < _max), and the remainder
> > is too
> > > small to fit. So the predicate in 227 is trivially true, and we call
> > > CollectedHeap::fill_with_object(). Am I overlooking something here?
> >
> > I think what you're overlooking is that "remainder" is not the remaining
> > space in the region's current state, but what the remainder WOULD BE
> > after the
> > requested allocation. If the remainder will be too small, we don't do the
> > current allocation, and instead fill from the old_top to _max. That
> > size will
> > always be greater than min_fill_size.
>
> Okay.
>
> > > - I would prefer if the method did not preemptively allocate a new
> > > region, but only if requested. Now it can happen that we end up with a
> > > completely empty region after the last string just filled up the
> > > previous one. (If I understand correctly)
> >
> > That shouldn't happen. There are 2 calls to alloc_new_region - one is at the
> > start of archive_mem_allocate, if there is no current
> > _allocation_region. The other
> > is in the code that decides that the current requested allocation
> > doesn't fit in
> > the current region. In either case, we will do an allocation in the region
> > immediately, so it isn't "preemptive".
>
> Okay. So why is there the change in HeapRegionSetBase::verify_region()
> to allow empty archive regions?
>
> > > In G1RecordingAllocator::alloc_new_region():
> > >
> > > - In Hotspot-code memory ranges are typically right-open, i.e. do not
> > > include the last address. G1MarkSweep::mark_range_archive() neither does
> > > that, nor is it documented. (Or use a base address + size, or MemRegion).
> >
> > OK. It now takes (HeapWord*, size_t) .
> >
>
> Thanks.
>
> > > - Possibly put G1RecordingAllocator into its own files. I am not
> > insisting
> > > on that.
> >
> > OK, I'll take you up on your offer to not insist. 8^)
>
> Okay.
>
> > > - I think the method still returns two memory ranges even if the
> > > space is actually contiguous. I would not expect that.
> >
> > Of course we've tested this change, and that doesn't happen. You get 1
> > MemRegion
> > for ranges that are truly contiguous. Normally the last G1 region
> > allocated will
> > not be full, however, and since it is below the previously allocated ones,
> > there will be a gap. I considered 'filling' the gap if it is smaller than
> > some threshold and just returning 1, but since CDS must be prepared to
> > receive 2 anyway, it doesn't seem worthwhile.
>
> Okay, good.
>
> > > g1BiasedArray.hpp:
> > > - the change should not add specialized methods returning data of a
> > > particular type to the G1BiasedMappedArray base class that is used only
> > > useful for a single instance.
> > > G1BiasedMappedArray is basically an abstraction of an array, and indexes
> > > should always be of type idx_t (size_t), not uint.
> > > It is very dangerous if other users start using this method and
> > > potentially get a truncated value out of it (by not looking at the
> > > signature in detail).
> > > The change should either cast the value in the user, or add its own
> > > getter (if possible).
> >
> > OK. I had been swayed by region array indices being uint throughout
> > heapRegionManager. Now changed to idx_t.
>
> We do not support more than uint regions in the heap, and there is
> actually a lot of code depending on that. So if you want a larger heap
> than 2^25*(2^32-1) bytes you are out of luck. :)
>
> > > G1CollectedHeap::is_record_alloc_too_large():
> > > - I would prefer if the comments were talking about the "why" for
> > > a given statement instead of just repeating the statement. I.e.
> > > instead of "Check whether the size would be considered humongous for
> > > a minimum-sized region.", it would be much more useful to write
> > > "We do not support humongous sized strings" or similar. Actually,
> > > it would be perfectly good if the method had a single description
> > > in the header file instead of putting almost the same comment
> > > twice here and in line 926f. Same with the comment at 939, which
> > > is more about "what" is done, not why.
> >
> > Yes, I agree 'why' is better here. It's a rather long story in this case,
> > but I've summarized it to:
> > // Allocations in archive regions cannot be of a size that would be
> > considered
> > // humongous even for a minimum-sized region, because G1 region
> > sizes/boundaries
> > // may be different at archive-restore time.
> >
> > RE: line 939, I think the "what" here is useful, that the MemRegion array
> > will be filled in by complete_archive. But I don't feel strongly about it,
> > and will remove it if you do.
>
> Okay.
>
> > > g1CollectedHeap::fill_with_non_humongous_objects()
> > > - any reason why the increment is half the humonguous threshold
> > > and not humongous threshold-1 words?
> >
> > It was because I didn't want to have to worry about the increment
> > plus min_fill_size being humongous, for the last fill after exiting the
> > loop. Using (humongous_threshold - (min_fill_size+1)) for the increment
> > would
> > probably also work, but honestly, I don't think it matters much.
>
> I agree.
>
> > > G1CollectedHeap::check_archive_addresses()
> > > - not sure why it uses an uint for a size specification. It seems
> > > okay, but if there is no particular reason, I would prefer to use
> > > size_t for sizes.
> >
> > I don't recall a compelling reason. I'll change it.
> >
> >
> > > - is that method actually used anywhere? Grepping the sources I
> > > could not find any use for this method.
> >
> > This is used in the CDS code, so that the error of having mismatched heap
> > addresses can be reported separately from a general allocation failure.
> >
> >
> > > G1CollectedHeap::end_record_alloc_range():
> > > - why is end_alignment a uint, and not a size_t? Most if not all
> > > other alignments for various purposes are size_t.
> >
> > OK.
> >
> >
> > > G1CollectedHeap::alloc_archive_regions():
> > > - if the given count is zero, there is some wasted work, and we
> > > enable the slow path. Maybe guarantee that count > 0 and ranges
> > > != NULL?
> >
> > I added asserts to the check/alloc/fill entries.
> >
> >
> > > - I think this is the method where check_archive_addresses should
> > > be called?
> >
> > It's called by CDS before calling this. However, I have added 'guarantees'
> > to alloc_archive_regions that check the addresses against heap boundaries
> > and that they are in ascending order.
> >
> >
> > > - I would prefer if more guarantee()'s are used in that code
> > > instead of assert. It does not seem harmful in a performance
> > > point of view, but at least gives the fuzzy feeling that we
> > > get an immediate crash for invalid input data.
> >
> > The existing and new checks in alloc_archive_region are now 'guarantee.'
> > The same checks are in fill_archive_region, but those are left as asserts.
> > The reason being that in the event the archive was corrupt, there could be
> > a bad range that would be handed to alloc_. But once it has succesfully
> > gotten through alloc_, it will be ok for fill_, unless CDS init does
> > something
> > wrong internally. I just like to avoid needless code bloat in the
> > release version.
> >
> >
> > > - the count parameter should be size_t imo, just because it
> > > is a size of the given array.
> > > - 994: the comment should probably read "... in ascending
> > > (start) address order..."
> >
> > OK to both.
> >
> >
> > > - I think the code is buggy if the first region of the given
> > > memory range is region zero (which might happen). In that case,
> > > the code does not reserve region zero it seems, because line 1013
> > > increments the start_index.
> >
> > Region zero can't be part of the range, in this use. We start allocating
> > at the high end of heap, right after JVM init. However, it would also
> > work to initialize prev_end_index to something which is not a valid index,
> > like the last valid index + 1 , so I've changed the code to do that.
>
> Thanks.
>
> > > - in line 1017, I think the comment needs to be fixed: "available"
> > > already has a distinct meaning in heap region management (in this
> > > code). See below.
> >
> > OK.
> >
> >
> > > - please avoid assignment and check in the condition if not
> > > necessary for some reason (the "if ((curr_region = ...) == NULL)").
> > > The current code is just hard to read, particularly because it
> > > does not save any code size, ie.
> > >
> > > 1020 HeapRegion* curr_region;
> > > 1021 if ((curr_region = _hrm.at_or_null(curr_index)) == NULL) {
> > >
> > > seems much worse to read than
> > >
> > > 1020 HeapRegion* curr_region = _hrm.at_or_null(curr_index);
> > > 1021 if (curr_region == NULL) {
> > >
> > > Since curr_region is needed in the outer scope anyway (in the
> > > else-part), I do not see a good reason to put the assignment in
> > > the if-statement.
> >
> > I don't either. I think it wound up that way through evolution of different
> > versions. I've changed it.
>
> Thanks.
>
> > > - the code from 1017 to 1035 seems to be best placed as some
> > > utility method in HeapRegionManager. HeapRegionManager::at_or_null()
> > > leaks details about internal region organization to G1CollectedHeap.
> > > It would also allow iteration over the "heap region array", which is
> > > an implementation detail of HeapRegionManager (which is, what the
> > > most recent huge changes to region management explicitly tried to
> > > make impossible).
> > > - HeapRegionManager::addr_to_index(): the code should use the
> > > HeapRegion*'s hrm_index() getter to retrieve the region's index if
> > > required. The HeapRegionManager should expose as little as possible
> > > details, including that the regions are consecutive. Not sure about
> > > this. I mean it's nice to have, but not necessary at all.
> > > Removing it would (I think) also remove the need for the ugly change
> > > in G1BiasedMappedArray.
> >
> > I think the re-factoring suggested here will take a little more thought.
> > Part of it could be done entirely in HeapRegionManager, but I think some
> > needs to be in G1CollectHeap. I think this may generate more discussion,
> > so I'll post a separate reply.
>
> It seems good to me now.
>
> >
> >
> > > G1CollectedHeap::fill_archive_regions():
> > > - the code should check the passed ranges for minimal validity,
> > > e.g. use check_archive_addresses(). That method might also check
> > > for ascending addresses in the list - at least fill_archive_regions()
> > > seems to miss it. Please also put such requirements in the parameter
> > > description.
> >
> > As noted above, I added checks.
> >
> >
> > > - (also for other methods): please make sure to use the exact
> > > terminology for variable names that is used elsewhere, i.e. for
> > > start/top/end/last/bottom. Several variables are called "end_XYZ",
> > > but contain the "last" address. Making the naming uniform improves
> > > readability and avoids constant lookup up of their exact meaning.
> > > Please also try to avoid new words like "base" for no apparent
> > > reason. Also, the code might be slightly less complicated (as in
> > > less characters to be parsed and understood) if "end" were used
> > > instead of "last", which would save some "+1" calculations and
> > > "<=" in comparisons (using "<" for the latter).
> >
> > OK, I tried to make that more consistent.
> >
> >
> > > - please rename "mr" to "reserved", as this is more specific.
> >
> > OK.
> >
> >
> > > - line 1068 // that contain the address range. The address
> > > range actually within the : I think the "actually" is misplaced,
> > > maybe should go at the beginning of the sentence.
> >
> > No, I meant that the address range which is actually represented by
> > the MemRegion will not be modified. Filler objects might be added
> > in the G1 region that contains that address range, if necessary, to make
> > it parseable.
> >
> >
> > > - I personally would prefer if "word_size" were defined more
> > > closely to its use. I.e. in this case, there are 30 lines
> > > between definition and use.
> >
> > OK. Removed the local.
>
> It's still there, but the change may keep it.
>
> > > - I think fill_archive_regions() has the same bug as
> > > alloc_archive_regions is the first region in the memory range is
> > > region zero.
> >
> > Not a bug, but I made the same change.
> >
> >
> > > - fill_with_non_humongous_objects() should not be called if
> > > fill_size is < min_fill_size(), as it asserts in debug mode.
> >
> > Since the archive allocator won't leave a space smaller than min_fill_size
> > at the top of an allocation region, this won't arise.
> >
> >
> > > VerifyArchiveOopClosure::do_oop_work():
> > > - "Archive object references a non-pinned object" - isn't it that
> > > archived objects can only reference other archived objects, not
> > > just pinned? I might be wrong...
> > > - same in the comment for VerifyArchiveRegionClosure::do_object(),
> > > and VerifyRegionClosure::doHeapRegion()
> >
> > Yes, text strings are wrong, code is right. Fixed.
> >
> >
> > > G1CollectedHeap::is_obj_dead_cond():
> > > - not sure if it is performance critical, but the changed code
> > > now always evaluates the region type.
> >
> > Yes, but these are only used in heap verification. I could have
> > used G1MarkSweep::in_archive_range(obj) instead, but the
> > HeapRegion* was already at hand.
>
> Okay.
>
> > > G1CollectedHeap::rebuild_region_sets():
> > > - the code clears the summary_used field of the recording_allocator
> > > here. Where is its value recreated? I actually do not think this is
> > > required: the contents of the archive regions never change anyway.
> > > It should be doable to create a test that first creates a shared
> > > archive, then uses it in the next VM invocation, and checks whether
> > > summary bytes are okay after full gc/evacuation failure (see below)?
> > >
> > > G1CollectedHeap::do_collection_pause_at_safepoint(), line 4101:
> > > - why clear the used bytes for the recording allocator since my
> > > understanding is that archive regions will never be collected?
> >
> > The _allocator->set_used calls at both of the above points 'inherit' the
> > space allocated by the ArchiveAllocator. EG, recalculate_used walks the
> > regions and adds up the used size. It seemed best to me not to perturb
> > the _allocator's idea of how much heap was in use, even if some of it
> > had originally been allocated by the ArchiveAllocator. If the
> > ArchiveAllocator's total is not cleared, verification fails because the
> > space is double counted.
> >
> > I think this is really moot at present, since the G1ArchiveAllocator
> > is created and and destroyed in a single safepoint, after which the JVM
> > exits. But I tested scenarios where it was allowed to stay around.
>
> Okay.
>
> > > g1CollectedHeap.cpp:
> > > - please avoid the double-spaces between sentences in comments. At
> > > least in this file, the majority of comments do not use two spaces
> > > after a full stop.
> > > - line 3368: extra spaces before the brace
> >
> > OK.
> >
> >
> > > G1CollectedHeap.hpp:
> > > - I would prefer if methods were commented separately about what
> > > they do and what they expect instead of one big blob of comments
> > > before a group of methods. This leads to unnecessary searching if just
> > > wanting to find out about parameter usage. Also this increases the
> > > likelihood if one method is changed, the developer does not update
> > > the corresponding comment lots of lines above. Do not misunderstand,
> > > I am fine with an introductory/summary comment about a group of methods,
> > > just not that it contains the descriptions of the method signatures,
> > > like in the comment in line 735 and 748. Please do not abbreviate
> > > method names in comments.
> >
> > OK. I personally find it more readable and more strongly connecting
> > the routines the way it is, but I'll change it to your preferred form.
> >
> >
> > > - line " 737 // end address and returns the allocated ranges as
> > > an ascending array" - what is an ascending array?
> > > 738 // of MemRegions. This can be used to create and archive a heap
> > > 739 // region which can be mapped at the same fixed addresses in a
> > future
> > > 740 // VM instance.
> > >
> > > I think it should read ... create and archive a set of heap regions
> > > which...
> > >
> > > Maybe it could be clarified what a "future VM instance" is.
> >
> > OK.
> >
> >
> > > g1MarkSweep.cpp
> > > - line 61: extra space between G1ArchiveRegionMap and G1MarkSweep::
> > > - extra newlines in line 330,331
> >
> > OK.
> >
> >
> > > G1SpaceCompactClosure::doHeapRegion(): I think any pinned regions should
> > > be skipped for compaction, not only archived.
> >
> > I used is_archive because Humongous regions are already conditionalized
> > out above,
> > so using "!is_pinned" could be misleading. Same thing for
> > G1AdjustPointersClosure
> > and G1AdjustPointersClosure. However, I don't feel strongly about it,
> > so have
> > changed them.
> >
> >
> > > G1MarkSweep::enable_archive_object_check():
> > > - indentation in the call to initialize()
> > > - the cast in front of HeapRegion::Grainbytes is superfluous
> > >
> > > 321 _archive_region_map.set_by_index(index++, true);
> > >
> > > using the ++ operator within the argument seems unnecessary here, just
> > > makes the statement harder to read.
> >
> > OK to all.
> >
> >
> > > G1PrepareCompactClosure::doHeapRegion():
> > > - again I think any pinned regions should be skipped here.
> >
> > Answered above.
> >
> >
> > > g1MarkSweep.hpp:
> > >
> > > Please add a comment to what G1ArchiveRegionMap does/is supposed to do.
> > >
> > > 58 // Support for 'archive' objects, to prevent objects in
> > archive regions
> > > 59 // from being marked by full GCs.
> > >
> > > "Support for XYZ" seems a bit too sparse.
> > >
> > > Please at least document the parameters for mark_range_archive(),
> > > whether the parameters are inclusive/exclusive, etc. Or pass a
> > > MemRegion, because it has defined semantics.
> >
> > OK, I've bulked up the comments. The mark_range_archive arguments are an
> > address and length, not 2 addresses, so I don't think 'exclusive' is really
> > necessary.
> >
> >
> > > G1VerifyLiveClosure::do_oop_work()
> > > - why is the remembered set for pinned regions not checked? We do need
> > > the remembered set if it gets unpinned.
> >
> > This conditional was already there for Humongous regions. For archive
> > regions, there is no way for them to become 'unpinned.' If that
> > is a future goal, I think a follow-on project/testing is called for.
>
> See above, I am not sure that the exclusion of humongous objects here is
> valid in the first place. I may overlook something though. E.g. in the
> eager reclaim code we depend on the remembered set for humongous regions
> being correct too...
>
> > > heapRegion.hpp:421:
> > > - please add a little comment about what pinned/archive means and the
> > > difference.
> >
> > OK.
> >
> >
> > > heapRegionManager.cpp:
> > >
> > > HeapRegionManager::find_highest_available():
> > > - the code will never return or consider the region zero for use. I am
> > > not sure this is intended.
> >
> > Yes, it was not viewed as an issue, knowing the usage. But it's easily
> > changed,
> > and I did so.
> >
> >
> > > - please document that the method will automatically commit any
> > > previously uncommitted regions in the header file, not in the cpp file.
> > > I mean, the comment in the cpp file would be very good start (except for
> > > the "loop downwards", and comments below) for the documentation of the
> > > interface.
> > > At least from the method name it would not have occurred to me that it
> > > also commits the region. Also, "available" has a specific meaning in the
> > > context of HeapRegionManager, i.e. that the region can be allocated into
> > > (either empty or already allocated into).
> > > Also, the documentation does not say anything about what happens when
> > > there is no suitable region.
> >
> > OK. I changed the comments and renamed it find_highest_free().
> >
> >
> > > HeapRegionManager.hpp:
> > > - HeapRegionManager::addr_to_index(): please use the HeapRegion*'s
> > > hrm_index() getter to retrieve the region's index. It is an
> > implementation
> > > detail that the index in the _regions table of HeapRegionManager
> > > corresponds to the HeapRegion's index.
> > > - HeapRegionmanager::at_or_null(uint index) const; should be removed,
> > > see above.
> >
> > I'll defer this to the 'how to traverse regions' message I said
> > I would send separately.
>
> Okay :)
>
> > > - HeapRegionManager::find_highest_available() method: please put input
> > > parameter descriptions in the header file, not in the implementation.
> >
> > OK.
> >
> >
> > > heapRegionManager.inline.hpp.
> > > - HeapRegionManager::addr_to_index(): not sure if there is a point to
> > > remind you that the lower levels already do the asserting, and have two
> > > levels of brackets with a more cryptic than explaining comment ("which
> > > might be outside the current heap") here.
> >
> > The comment was there to tell the reader that the address range is indeed
> > being checked for validity, a question I would expect. But I'll remove it.
> >
> > > > Performance: The GC changes had no significant impact on SpecJBB,
> > >
> > > For Specjbb2005, did you check object copy/young gc times specifically?
> > > They do not do a lot of GCs in the first place, so an overall performance
> > > regression would require a very large performance regression in young gc
> > > times to be noticed.
> >
> > I only specifically checked full GC times for the reasons I mentioned,
> > relying
> > on impact to benchmarks to show other impact. I can look at that as
> > well with
> > the new version.
>
> In the other email you answered that, thanks.
>
> Thanks,
> Thomas
>
>
More information about the hotspot-gc-dev
mailing list