RFR: 8064721: The card tables only ever need two covering regions
Erik Helin
erik.helin at oracle.com
Wed Nov 12 18:57:37 UTC 2014
Hi all,
this patch removes the max_covering_regions argument from the BarrierSet
constructor, since all the code using a BarrierSet only needs two
covering regions. Having the maximum number of covering regions as a
constant is desirable because it makes it much easier to reason about
the code in all the various card tables (CardTableRS, CardTableModRefBS,
G1SATBCardTableModRefBS, CardTableExtension).
The only way a covering region can be added is via a call to
CardTableModRefBS::find_covering_region_by_base.
find_covering_region_by_base adds a region if there is no covering
region already having its argument `base` as start address. The only
caller to find_covering_region_by_base is
CardTableModRefBS::resize_covered_region.
To show that two covering regions are enough, one has to show that
callers of CardTableModRefBS::resize_covered_region in different
generations always pass an MemRegion argument with a start address that
is always the same. This way, we only need one covering region per
generation, and we only ever have two generations.
There calls to CardTableModRefBS::resize_covering_region comes from
(found via grep, filtered declarations, definitions and forwarding):
- psYoungGen.cpp
- psOldGen.cpp
- asPSYoungGen.cpp
- concurrentMarkSweepGeneration.cpp
- generation.cpp
- defNewGeneration.cpp
The calls in defNewGeneration.cpp always uses _virtual_space.low() as
the start address of the MemRegion argument, and _virtual_space.low()
never changes.
In generation.cpp, the calls from the class OneContigSpaceCardGeneration
always use _the_space->bottom() as start and that won't change. The call
from CardGeneration uses `start`, which is the same as rs.base(), which
is the same as _virtual_space.low(), which (by looking in
tenuredGeneration.cpp) is the same _the_space->bottom(). So both
CardGeneration and OneContigSpaceCardGeneration use the same start address.
The calls in concurrentMarkSweepGeneration.cpp uses _cmsSpace->bottom()
as the start of the MemRegion and that won't change.
The calls in asPSYoungGen.cpp, psOldGen.cpp and psYoungGen.cpp all uses
virtual_space()->low() as the start address for the MemRegion. This
address might change, but the calls from these files will reach
CardTableExtension::resize_covered_region, which explicitly handles the
case when the start address has changed and ensures now new covering
region is added (see comments and code in cardTableExtension.cpp).
The only GC that specified 2 as max_covering_regions was G1. ParallelGC
specified 3, most likely because each generation needed one and PermGen
needed one and this was not updated when PermGen was removed. The
generation collectors specified 4, because each generation wanted one
each and PermGen wanted two (one one for the main space and one for the
shared spaces).
The other variable that was made static const is
CardTableRS::_regions_to_iterate. This was previously set to
max_covered_regions - 1 by the framework collectors, so 4 - 1 = 3. I
also added a comment explaining why it needs to be 3 and not 2.
Webrev:
http://cr.openjdk.java.net/~ehelin/8064721/webrev.00/
Bug:
https://bugs.openjdk.java.net/browse/JDK-8064721
Testing:
- JPRT
- Running all JTReg tests locally
- Ad-hoc (Window 32/64, Linux 32/64, OS X 64, Solaris x86-64/SPARC):
- Dacapo, Kitchensink, Weblogic+medrec, runThese
- nsk.regression, vm.gc, vm.oom, vm.parallel_class_loading,
vm.regression, vm.runtime, vm.compiler, vm.runtime, vm.signal,
vm.debug, nsk.sysdict + some others
- nashorn regression tests
- jruby quick + slow
- JTReg:
- hotspot
- jdk_core, jdk_svc
Thanks,
Erik
More information about the hotspot-gc-dev
mailing list