< prev index next > src/hotspot/share/gc/serial/serialFullGC.cpp
Print this page
void record_first_dead(uint index, HeapWord* first_dead) {
assert(_spaces[index]._first_dead == nullptr, "should write only once");
_spaces[index]._first_dead = first_dead;
}
- HeapWord* alloc(size_t words) {
+ HeapWord* alloc(size_t old_size, size_t new_size, HeapWord* old_obj) {
+ size_t words = (old_obj == _spaces[_index]._compaction_top) ? old_size : new_size;
while (true) {
if (words <= pointer_delta(_spaces[_index]._space->end(),
_spaces[_index]._compaction_top)) {
HeapWord* result = _spaces[_index]._compaction_top;
_spaces[_index]._compaction_top += words;
}
// out-of-memory in this space
_index++;
assert(_index < max_num_spaces - 1, "the last space should not be used");
+ words = (old_obj == _spaces[_index]._compaction_top) ? old_size : new_size;
}
}
static void prefetch_read_scan(void* p) {
if (PrefetchScanIntervalInBytes >= 0) {
prefetch_read_scan(addr);
oop obj = cast_to_oop(addr);
oop new_obj = FullGCForwarding::forwardee(obj);
HeapWord* new_addr = cast_from_oop<HeapWord*>(new_obj);
- assert(addr != new_addr, "inv");
- prefetch_write_copy(new_addr);
size_t obj_size = obj->size();
- Copy::aligned_conjoint_words(addr, new_addr, obj_size);
+ if (addr != new_addr) {
+ prefetch_write_copy(new_addr);
+ Copy::aligned_conjoint_words(addr, new_addr, obj_size);
+ }
new_obj->init_mark();
+ if (addr != new_addr) {
+ new_obj->initialize_hash_if_necessary(obj);
+ }
return obj_size;
}
public:
DeadSpacer dead_spacer(space);
while (cur_addr < top) {
oop obj = cast_to_oop(cur_addr);
size_t obj_size = obj->size();
+ size_t new_size = obj->copy_size(obj_size, obj->mark());
if (obj->is_gc_marked()) {
- HeapWord* new_addr = alloc(obj_size);
+ HeapWord* new_addr = alloc(obj_size, new_size, cur_addr);
forward_obj(obj, new_addr);
+ assert(obj->size() == obj_size, "size must not change after forwarding");
cur_addr += obj_size;
} else {
// Skipping the current known-unmarked obj
HeapWord* next_live_addr = find_next_live_addr(cur_addr + obj_size, top);
if (dead_spacer.insert_deadspace(cur_addr, next_live_addr)) {
// Register space for the filler obj
- alloc(pointer_delta(next_live_addr, cur_addr));
+ size_t size = pointer_delta(next_live_addr, cur_addr);
+ alloc(size, size, cur_addr);
} else {
if (!record_first_dead_done) {
record_first_dead(i, cur_addr);
record_first_dead_done = true;
}
}
// some marks may contain information we need to preserve so we store them away
// and overwrite the mark. We'll restore it at the end of serial full GC.
markWord mark = obj->mark();
- obj->set_mark(obj->prototype_mark().set_marked());
+ obj->set_mark(mark.set_marked());
ContinuationGCSupport::transform_stack_chunk(obj);
if (obj->mark_must_be_preserved(mark)) {
preserve_mark(obj, mark);
allocate_stacks();
phase1_mark(clear_all_softrefs);
+ FullGCForwarding::begin();
+
Compacter compacter{gch};
{
// Now all live objects are marked, compute the new object addresses.
GCTraceTime(Info, gc, phases) tm("Phase 2: Compute new object addresses", _gc_timer);
compacter.phase4_compact();
}
restore_marks();
+ FullGCForwarding::end();
+
deallocate_stacks();
SerialFullGC::_string_dedup_requests->flush();
bool is_young_gen_empty = (gch->young_gen()->used() == 0);
< prev index next >