8299953: Merge ContiguousSpaceDCTOC into DirtyCardToOopClosure
Reviewed-by: tschatzl, iwalulya
This commit is contained in:
parent
a9b8acb643
commit
7725fe845b
@ -49,22 +49,20 @@
|
||||
|
||||
HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top,
|
||||
HeapWord* top_obj) {
|
||||
if (top_obj != NULL) {
|
||||
if (_sp->block_is_obj(top_obj)) {
|
||||
if (cast_to_oop(top_obj)->is_objArray() || cast_to_oop(top_obj)->is_typeArray()) {
|
||||
// An arrayOop is starting on the dirty card - since we do exact
|
||||
// store checks for objArrays we are done.
|
||||
} else {
|
||||
// Otherwise, it is possible that the object starting on the dirty
|
||||
// card spans the entire card, and that the store happened on a
|
||||
// later card. Figure out where the object ends.
|
||||
top = top_obj + cast_to_oop(top_obj)->size();
|
||||
}
|
||||
if (top_obj != NULL && top_obj < (_sp->toContiguousSpace())->top()) {
|
||||
if (cast_to_oop(top_obj)->is_objArray() || cast_to_oop(top_obj)->is_typeArray()) {
|
||||
// An arrayOop is starting on the dirty card - since we do exact
|
||||
// store checks for objArrays we are done.
|
||||
} else {
|
||||
top = top_obj;
|
||||
// Otherwise, it is possible that the object starting on the dirty
|
||||
// card spans the entire card, and that the store happened on a
|
||||
// later card. Figure out where the object ends.
|
||||
assert(_sp->block_size(top_obj) == cast_to_oop(top_obj)->size(),
|
||||
"Block size and object size mismatch");
|
||||
top = top_obj + cast_to_oop(top_obj)->size();
|
||||
}
|
||||
} else {
|
||||
assert(top == _sp->end(), "only case where top_obj == NULL");
|
||||
top = (_sp->toContiguousSpace())->top();
|
||||
}
|
||||
return top;
|
||||
}
|
||||
@ -72,25 +70,21 @@ HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top,
|
||||
void DirtyCardToOopClosure::walk_mem_region(MemRegion mr,
|
||||
HeapWord* bottom,
|
||||
HeapWord* top) {
|
||||
// 1. Blocks may or may not be objects.
|
||||
// 2. Even when a block_is_obj(), it may not entirely
|
||||
// occupy the block if the block quantum is larger than
|
||||
// the object size.
|
||||
// We can and should try to optimize by calling the non-MemRegion
|
||||
// version of oop_iterate() for all but the extremal objects
|
||||
// (for which we need to call the MemRegion version of
|
||||
// oop_iterate()) To be done post-beta XXX
|
||||
for (; bottom < top; bottom += _sp->block_size(bottom)) {
|
||||
// As in the case of contiguous space above, we'd like to
|
||||
// just use the value returned by oop_iterate to increment the
|
||||
// current pointer; unfortunately, that won't work in CMS because
|
||||
// we'd need an interface change (it seems) to have the space
|
||||
// "adjust the object size" (for instance pad it up to its
|
||||
// block alignment or minimum block size restrictions. XXX
|
||||
if (_sp->block_is_obj(bottom) &&
|
||||
!_sp->obj_allocated_since_save_marks(cast_to_oop(bottom))) {
|
||||
cast_to_oop(bottom)->oop_iterate(_cl, mr);
|
||||
}
|
||||
// Note that this assumption won't hold if we have a concurrent
|
||||
// collector in this space, which may have freed up objects after
|
||||
// they were dirtied and before the stop-the-world GC that is
|
||||
// examining cards here.
|
||||
assert(bottom < top, "ought to be at least one obj on a dirty card.");
|
||||
|
||||
if (_boundary != NULL) {
|
||||
// We have a boundary outside of which we don't want to look
|
||||
// at objects, so create a filtering closure around the
|
||||
// oop closure before walking the region.
|
||||
FilteringClosure filter(_boundary, _cl);
|
||||
walk_mem_region_with_cl(mr, bottom, top, &filter);
|
||||
} else {
|
||||
// No boundary, simply walk the heap with the oop closure.
|
||||
walk_mem_region_with_cl(mr, bottom, top, _cl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,80 +140,38 @@ void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
|
||||
_min_done = bottom;
|
||||
}
|
||||
|
||||
HeapWord* ContiguousSpaceDCTOC::get_actual_top(HeapWord* top,
|
||||
HeapWord* top_obj) {
|
||||
if (top_obj != NULL && top_obj < (_sp->toContiguousSpace())->top()) {
|
||||
if (cast_to_oop(top_obj)->is_objArray() || cast_to_oop(top_obj)->is_typeArray()) {
|
||||
// An arrayOop is starting on the dirty card - since we do exact
|
||||
// store checks for objArrays we are done.
|
||||
} else {
|
||||
// Otherwise, it is possible that the object starting on the dirty
|
||||
// card spans the entire card, and that the store happened on a
|
||||
// later card. Figure out where the object ends.
|
||||
assert(_sp->block_size(top_obj) == cast_to_oop(top_obj)->size(),
|
||||
"Block size and object size mismatch");
|
||||
top = top_obj + cast_to_oop(top_obj)->size();
|
||||
}
|
||||
} else {
|
||||
top = (_sp->toContiguousSpace())->top();
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
void ContiguousSpaceDCTOC::walk_mem_region(MemRegion mr,
|
||||
HeapWord* bottom,
|
||||
HeapWord* top) {
|
||||
// Note that this assumption won't hold if we have a concurrent
|
||||
// collector in this space, which may have freed up objects after
|
||||
// they were dirtied and before the stop-the-world GC that is
|
||||
// examining cards here.
|
||||
assert(bottom < top, "ought to be at least one obj on a dirty card.");
|
||||
|
||||
if (_boundary != NULL) {
|
||||
// We have a boundary outside of which we don't want to look
|
||||
// at objects, so create a filtering closure around the
|
||||
// oop closure before walking the region.
|
||||
FilteringClosure filter(_boundary, _cl);
|
||||
walk_mem_region_with_cl(mr, bottom, top, &filter);
|
||||
} else {
|
||||
// No boundary, simply walk the heap with the oop closure.
|
||||
walk_mem_region_with_cl(mr, bottom, top, _cl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We must replicate this so that the static type of "FilteringClosure"
|
||||
// (see above) is apparent at the oop_iterate calls.
|
||||
#define ContiguousSpaceDCTOC__walk_mem_region_with_cl_DEFN(ClosureType) \
|
||||
void ContiguousSpaceDCTOC::walk_mem_region_with_cl(MemRegion mr, \
|
||||
HeapWord* bottom, \
|
||||
HeapWord* top, \
|
||||
ClosureType* cl) { \
|
||||
bottom += cast_to_oop(bottom)->oop_iterate_size(cl, mr); \
|
||||
if (bottom < top) { \
|
||||
HeapWord* next_obj = bottom + cast_to_oop(bottom)->size(); \
|
||||
while (next_obj < top) { \
|
||||
/* Bottom lies entirely below top, so we can call the */ \
|
||||
/* non-memRegion version of oop_iterate below. */ \
|
||||
cast_to_oop(bottom)->oop_iterate(cl); \
|
||||
bottom = next_obj; \
|
||||
next_obj = bottom + cast_to_oop(bottom)->size(); \
|
||||
} \
|
||||
/* Last object. */ \
|
||||
cast_to_oop(bottom)->oop_iterate(cl, mr); \
|
||||
} \
|
||||
#define DirtyCardToOopClosure__walk_mem_region_with_cl_DEFN(ClosureType) \
|
||||
void DirtyCardToOopClosure::walk_mem_region_with_cl(MemRegion mr, \
|
||||
HeapWord* bottom, \
|
||||
HeapWord* top, \
|
||||
ClosureType* cl) { \
|
||||
bottom += cast_to_oop(bottom)->oop_iterate_size(cl, mr); \
|
||||
if (bottom < top) { \
|
||||
HeapWord* next_obj = bottom + cast_to_oop(bottom)->size(); \
|
||||
while (next_obj < top) { \
|
||||
/* Bottom lies entirely below top, so we can call the */ \
|
||||
/* non-memRegion version of oop_iterate below. */ \
|
||||
cast_to_oop(bottom)->oop_iterate(cl); \
|
||||
bottom = next_obj; \
|
||||
next_obj = bottom + cast_to_oop(bottom)->size(); \
|
||||
} \
|
||||
/* Last object. */ \
|
||||
cast_to_oop(bottom)->oop_iterate(cl, mr); \
|
||||
} \
|
||||
}
|
||||
|
||||
// (There are only two of these, rather than N, because the split is due
|
||||
// only to the introduction of the FilteringClosure, a local part of the
|
||||
// impl of this abstraction.)
|
||||
ContiguousSpaceDCTOC__walk_mem_region_with_cl_DEFN(OopIterateClosure)
|
||||
ContiguousSpaceDCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
|
||||
DirtyCardToOopClosure__walk_mem_region_with_cl_DEFN(OopIterateClosure)
|
||||
DirtyCardToOopClosure__walk_mem_region_with_cl_DEFN(FilteringClosure)
|
||||
|
||||
DirtyCardToOopClosure*
|
||||
ContiguousSpace::new_dcto_cl(OopIterateClosure* cl,
|
||||
HeapWord* boundary) {
|
||||
return new ContiguousSpaceDCTOC(this, cl, boundary);
|
||||
return new DirtyCardToOopClosure(this, cl, boundary);
|
||||
}
|
||||
|
||||
void Space::initialize(MemRegion mr,
|
||||
|
@ -226,15 +226,18 @@ class Space: public CHeapObj<mtGC> {
|
||||
virtual void verify() const = 0;
|
||||
};
|
||||
|
||||
// A MemRegionClosure (ResourceObj) whose "do_MemRegion" function applies an
|
||||
// OopClosure to (the addresses of) all the ref-containing fields that could
|
||||
// be modified by virtue of the given MemRegion being dirty. (Note that
|
||||
// because of the imprecise nature of the write barrier, this may iterate
|
||||
// over oops beyond the region.)
|
||||
// This base type for dirty card to oop closures handles memory regions
|
||||
// in non-contiguous spaces with no boundaries, and should be sub-classed
|
||||
// to support other space types. See ContiguousDCTOC for a sub-class
|
||||
// that works with ContiguousSpaces.
|
||||
// A dirty card to oop closure for contiguous spaces (ContiguousSpace and
|
||||
// sub-classes). It knows how to filter out objects that are outside of the
|
||||
// _boundary.
|
||||
// (Note that because of the imprecise nature of the write barrier, this may
|
||||
// iterate over oops beyond the region.)
|
||||
//
|
||||
// Assumptions:
|
||||
// 1. That the actual top of any area in a memory region
|
||||
// contained by the space is bounded by the end of the contiguous
|
||||
// region of the space.
|
||||
// 2. That the space is really made up of objects and not just
|
||||
// blocks.
|
||||
|
||||
class DirtyCardToOopClosure: public MemRegionClosureRO {
|
||||
protected:
|
||||
@ -255,7 +258,7 @@ protected:
|
||||
// at the top is assumed to start. For example, an object may
|
||||
// start at the top but actually extend past the assumed top,
|
||||
// in which case the top becomes the end of the object.
|
||||
virtual HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj);
|
||||
HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj);
|
||||
|
||||
// Walk the given memory region from bottom to (actual) top
|
||||
// looking for objects and applying the oop closure (_cl) to
|
||||
@ -263,7 +266,21 @@ protected:
|
||||
// blocks, where a block may or may not be an object. Sub-
|
||||
// classes should override this to provide more accurate
|
||||
// or possibly more efficient walking.
|
||||
virtual void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
|
||||
void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
|
||||
|
||||
// Walk the given memory region, from bottom to top, applying
|
||||
// the given oop closure to (possibly) all objects found. The
|
||||
// given oop closure may or may not be the same as the oop
|
||||
// closure with which this closure was created, as it may
|
||||
// be a filtering closure which makes use of the _boundary.
|
||||
// We offer two signatures, so the FilteringClosure static type is
|
||||
// apparent.
|
||||
void walk_mem_region_with_cl(MemRegion mr,
|
||||
HeapWord* bottom, HeapWord* top,
|
||||
OopIterateClosure* cl);
|
||||
void walk_mem_region_with_cl(MemRegion mr,
|
||||
HeapWord* bottom, HeapWord* top,
|
||||
FilteringClosure* cl);
|
||||
|
||||
public:
|
||||
DirtyCardToOopClosure(Space* sp, OopIterateClosure* cl,
|
||||
@ -508,45 +525,6 @@ class ContiguousSpace: public CompactibleSpace {
|
||||
void verify() const override;
|
||||
};
|
||||
|
||||
// A dirty card to oop closure for contiguous spaces (ContiguousSpace and
|
||||
// sub-classes). It knows how to filter out objects that are outside of the
|
||||
// _boundary.
|
||||
//
|
||||
// Assumptions:
|
||||
// 1. That the actual top of any area in a memory region
|
||||
// contained by the space is bounded by the end of the contiguous
|
||||
// region of the space.
|
||||
// 2. That the space is really made up of objects and not just
|
||||
// blocks.
|
||||
class ContiguousSpaceDCTOC : public DirtyCardToOopClosure {
|
||||
// Overrides.
|
||||
void walk_mem_region(MemRegion mr,
|
||||
HeapWord* bottom, HeapWord* top) override;
|
||||
|
||||
HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj) override;
|
||||
|
||||
// Walk the given memory region, from bottom to top, applying
|
||||
// the given oop closure to (possibly) all objects found. The
|
||||
// given oop closure may or may not be the same as the oop
|
||||
// closure with which this closure was created, as it may
|
||||
// be a filtering closure which makes use of the _boundary.
|
||||
// We offer two signatures, so the FilteringClosure static type is
|
||||
// apparent.
|
||||
void walk_mem_region_with_cl(MemRegion mr,
|
||||
HeapWord* bottom, HeapWord* top,
|
||||
OopIterateClosure* cl);
|
||||
void walk_mem_region_with_cl(MemRegion mr,
|
||||
HeapWord* bottom, HeapWord* top,
|
||||
FilteringClosure* cl);
|
||||
|
||||
public:
|
||||
ContiguousSpaceDCTOC(ContiguousSpace* sp, OopIterateClosure* cl,
|
||||
HeapWord* boundary) :
|
||||
DirtyCardToOopClosure(sp, cl, boundary)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
#if INCLUDE_SERIALGC
|
||||
|
||||
// Class TenuredSpace is used by TenuredGeneration; it supports an efficient
|
||||
|
Loading…
Reference in New Issue
Block a user