mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 03:54:33 +02:00
6578152: fill_region_with_object has usability and safety issues
Reviewed-by: apetrusenko, ysr
This commit is contained in:
parent
26f6b1692a
commit
000b184507
25 changed files with 261 additions and 198 deletions
|
@ -389,7 +389,7 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
|
|||
// full GC.
|
||||
const size_t alignment = old_gen->virtual_space()->alignment();
|
||||
const size_t eden_used = eden_space->used_in_bytes();
|
||||
const size_t promoted = (size_t)(size_policy->avg_promoted()->padded_average());
|
||||
const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average();
|
||||
const size_t absorb_size = align_size_up(eden_used + promoted, alignment);
|
||||
const size_t eden_capacity = eden_space->capacity_in_bytes();
|
||||
|
||||
|
@ -416,16 +416,14 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
|
|||
|
||||
// Fill the unused part of the old gen.
|
||||
MutableSpace* const old_space = old_gen->object_space();
|
||||
MemRegion old_gen_unused(old_space->top(), old_space->end());
|
||||
HeapWord* const unused_start = old_space->top();
|
||||
size_t const unused_words = pointer_delta(old_space->end(), unused_start);
|
||||
|
||||
// If the unused part of the old gen cannot be filled, skip
|
||||
// absorbing eden.
|
||||
if (old_gen_unused.word_size() < SharedHeap::min_fill_size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!old_gen_unused.is_empty()) {
|
||||
SharedHeap::fill_region_with_object(old_gen_unused);
|
||||
if (unused_words > 0) {
|
||||
if (unused_words < CollectedHeap::min_fill_size()) {
|
||||
return false; // If the old gen cannot be filled, must give up.
|
||||
}
|
||||
CollectedHeap::fill_with_objects(unused_start, unused_words);
|
||||
}
|
||||
|
||||
// Take the live data from eden and set both top and end in the old gen to
|
||||
|
@ -441,9 +439,8 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
|
|||
|
||||
// Update the object start array for the filler object and the data from eden.
|
||||
ObjectStartArray* const start_array = old_gen->start_array();
|
||||
HeapWord* const start = old_gen_unused.start();
|
||||
for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
|
||||
start_array->allocate_block(addr);
|
||||
for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) {
|
||||
start_array->allocate_block(p);
|
||||
}
|
||||
|
||||
// Could update the promoted average here, but it is not typically updated at
|
||||
|
|
|
@ -275,22 +275,9 @@ bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
|
|||
HeapWord* q, size_t deadlength) {
|
||||
if (allowed_deadspace_words >= deadlength) {
|
||||
allowed_deadspace_words -= deadlength;
|
||||
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
|
||||
const size_t aligned_min_int_array_size =
|
||||
align_object_size(typeArrayOopDesc::header_size(T_INT));
|
||||
if (deadlength >= aligned_min_int_array_size) {
|
||||
oop(q)->set_klass(Universe::intArrayKlassObj());
|
||||
assert(((deadlength - aligned_min_int_array_size) * (HeapWordSize/sizeof(jint))) < (size_t)max_jint,
|
||||
"deadspace too big for Arrayoop");
|
||||
typeArrayOop(q)->set_length((int)((deadlength - aligned_min_int_array_size)
|
||||
* (HeapWordSize/sizeof(jint))));
|
||||
} else {
|
||||
assert((int) deadlength == instanceOopDesc::header_size(),
|
||||
"size for smallest fake dead object doesn't match");
|
||||
oop(q)->set_klass(SystemDictionary::object_klass());
|
||||
}
|
||||
assert((int) deadlength == oop(q)->size(),
|
||||
"make sure size for fake dead object match");
|
||||
CollectedHeap::fill_with_object(q, deadlength);
|
||||
oop(q)->set_mark(oop(q)->mark()->set_marked());
|
||||
assert((int) deadlength == oop(q)->size(), "bad filler object size");
|
||||
// Recall that we required "q == compaction_top".
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -1308,8 +1308,7 @@ void PSParallelCompact::fill_dense_prefix_end(SpaceId id)
|
|||
}
|
||||
#endif // #ifdef _LP64
|
||||
|
||||
MemRegion region(obj_beg, obj_len);
|
||||
SharedHeap::fill_region_with_object(region);
|
||||
gc_heap()->fill_with_object(obj_beg, obj_len);
|
||||
_mark_bitmap.mark_obj(obj_beg, obj_len);
|
||||
_summary_data.add_obj(obj_beg, obj_len);
|
||||
assert(start_array(id) != NULL, "sanity");
|
||||
|
@ -1807,9 +1806,14 @@ bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_po
|
|||
|
||||
// Fill the unused part of the old gen.
|
||||
MutableSpace* const old_space = old_gen->object_space();
|
||||
MemRegion old_gen_unused(old_space->top(), old_space->end());
|
||||
if (!old_gen_unused.is_empty()) {
|
||||
SharedHeap::fill_region_with_object(old_gen_unused);
|
||||
HeapWord* const unused_start = old_space->top();
|
||||
size_t const unused_words = pointer_delta(old_space->end(), unused_start);
|
||||
|
||||
if (unused_words > 0) {
|
||||
if (unused_words < CollectedHeap::min_fill_size()) {
|
||||
return false; // If the old gen cannot be filled, must give up.
|
||||
}
|
||||
CollectedHeap::fill_with_objects(unused_start, unused_words);
|
||||
}
|
||||
|
||||
// Take the live data from eden and set both top and end in the old gen to
|
||||
|
@ -1825,9 +1829,8 @@ bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_po
|
|||
|
||||
// Update the object start array for the filler object and the data from eden.
|
||||
ObjectStartArray* const start_array = old_gen->start_array();
|
||||
HeapWord* const start = old_gen_unused.start();
|
||||
for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
|
||||
start_array->allocate_block(addr);
|
||||
for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) {
|
||||
start_array->allocate_block(p);
|
||||
}
|
||||
|
||||
// Could update the promoted average here, but it is not typically updated at
|
||||
|
|
|
@ -1324,31 +1324,28 @@ inline void UpdateOnlyClosure::do_addr(HeapWord* addr)
|
|||
oop(addr)->update_contents(compaction_manager());
|
||||
}
|
||||
|
||||
class FillClosure: public ParMarkBitMapClosure {
|
||||
public:
|
||||
class FillClosure: public ParMarkBitMapClosure
|
||||
{
|
||||
public:
|
||||
FillClosure(ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) :
|
||||
ParMarkBitMapClosure(PSParallelCompact::mark_bitmap(), cm),
|
||||
_space_id(space_id),
|
||||
_start_array(PSParallelCompact::start_array(space_id)) {
|
||||
assert(_space_id == PSParallelCompact::perm_space_id ||
|
||||
_space_id == PSParallelCompact::old_space_id,
|
||||
_start_array(PSParallelCompact::start_array(space_id))
|
||||
{
|
||||
assert(space_id == PSParallelCompact::perm_space_id ||
|
||||
space_id == PSParallelCompact::old_space_id,
|
||||
"cannot use FillClosure in the young gen");
|
||||
assert(bitmap() != NULL, "need a bitmap");
|
||||
assert(_start_array != NULL, "need a start array");
|
||||
}
|
||||
|
||||
void fill_region(HeapWord* addr, size_t size) {
|
||||
MemRegion region(addr, size);
|
||||
SharedHeap::fill_region_with_object(region);
|
||||
_start_array->allocate_block(addr);
|
||||
}
|
||||
|
||||
virtual IterationStatus do_addr(HeapWord* addr, size_t size) {
|
||||
fill_region(addr, size);
|
||||
CollectedHeap::fill_with_objects(addr, size);
|
||||
HeapWord* const end = addr + size;
|
||||
do {
|
||||
_start_array->allocate_block(addr);
|
||||
addr += oop(addr)->size();
|
||||
} while (addr < end);
|
||||
return ParMarkBitMap::incomplete;
|
||||
}
|
||||
|
||||
private:
|
||||
const PSParallelCompact::SpaceId _space_id;
|
||||
ObjectStartArray* const _start_array;
|
||||
ObjectStartArray* const _start_array;
|
||||
};
|
||||
|
|
|
@ -499,26 +499,15 @@ oop PSPromotionManager::copy_to_survivor_space(oop o, bool depth_first) {
|
|||
// We lost, someone else "owns" this object
|
||||
guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
|
||||
|
||||
// Unallocate the space used. NOTE! We may have directly allocated
|
||||
// the object. If so, we cannot deallocate it, so we have to test!
|
||||
// Try to deallocate the space. If it was directly allocated we cannot
|
||||
// deallocate it, so we have to test. If the deallocation fails,
|
||||
// overwrite with a filler object.
|
||||
if (new_obj_is_tenured) {
|
||||
if (!_old_lab.unallocate_object(new_obj)) {
|
||||
// The promotion lab failed to unallocate the object.
|
||||
// We need to overwrite the object with a filler that
|
||||
// contains no interior pointers.
|
||||
MemRegion mr((HeapWord*)new_obj, new_obj_size);
|
||||
// Clean this up and move to oopFactory (see bug 4718422)
|
||||
SharedHeap::fill_region_with_object(mr);
|
||||
}
|
||||
} else {
|
||||
if (!_young_lab.unallocate_object(new_obj)) {
|
||||
// The promotion lab failed to unallocate the object.
|
||||
// We need to overwrite the object with a filler that
|
||||
// contains no interior pointers.
|
||||
MemRegion mr((HeapWord*)new_obj, new_obj_size);
|
||||
// Clean this up and move to oopFactory (see bug 4718422)
|
||||
SharedHeap::fill_region_with_object(mr);
|
||||
CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
|
||||
}
|
||||
} else if (!_young_lab.unallocate_object(new_obj)) {
|
||||
CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
|
||||
}
|
||||
|
||||
// don't update this before the unallocation!
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue