< prev index next > src/hotspot/share/gc/serial/serialFullGC.cpp
Print this page
#include "gc/shared/gc_globals.hpp"
#include "gc/shared/modRefBarrierSet.hpp"
#include "gc/shared/preservedMarks.inline.hpp"
#include "gc/shared/referencePolicy.hpp"
#include "gc/shared/referenceProcessorPhaseTimes.hpp"
+ #include "gc/shared/slidingForwarding.inline.hpp"
#include "gc/shared/space.hpp"
#include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/weakProcessor.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/universe.hpp"
}
static void forward_obj(oop obj, HeapWord* new_addr) {
prefetch_write_scan(obj);
if (cast_from_oop<HeapWord*>(obj) != new_addr) {
! obj->forward_to(cast_to_oop(new_addr));
} else {
assert(obj->is_gc_marked(), "inv");
// This obj will stay in-place. Fix the markword.
obj->init_mark();
}
}
static void forward_obj(oop obj, HeapWord* new_addr) {
prefetch_write_scan(obj);
if (cast_from_oop<HeapWord*>(obj) != new_addr) {
! SlidingForwarding::forward_to(obj, cast_to_oop(new_addr));
} else {
assert(obj->is_gc_marked(), "inv");
// This obj will stay in-place. Fix the markword.
obj->init_mark();
}
static size_t relocate(HeapWord* addr) {
// Prefetch source and destination
prefetch_read_scan(addr);
oop obj = cast_to_oop(addr);
! oop new_obj = obj->forwardee();
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();
static size_t relocate(HeapWord* addr) {
// Prefetch source and destination
prefetch_read_scan(addr);
oop obj = cast_to_oop(addr);
! oop new_obj = SlidingForwarding::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();
ContiguousSpace* space = get_space(i);
HeapWord* cur_addr = space->bottom();
HeapWord* top = space->top();
// Check if the first obj inside this space is forwarded.
! if (!cast_to_oop(cur_addr)->is_forwarded()) {
// Jump over consecutive (in-place) live-objs-chunk
cur_addr = get_first_dead(i);
}
while (cur_addr < top) {
! if (!cast_to_oop(cur_addr)->is_forwarded()) {
cur_addr = *(HeapWord**) cur_addr;
continue;
}
cur_addr += relocate(cur_addr);
}
ContiguousSpace* space = get_space(i);
HeapWord* cur_addr = space->bottom();
HeapWord* top = space->top();
// Check if the first obj inside this space is forwarded.
! if (SlidingForwarding::is_not_forwarded(cast_to_oop(cur_addr))) {
// Jump over consecutive (in-place) live-objs-chunk
cur_addr = get_first_dead(i);
}
while (cur_addr < top) {
! if (SlidingForwarding::is_not_forwarded(cast_to_oop(cur_addr))) {
cur_addr = *(HeapWord**) cur_addr;
continue;
}
cur_addr += relocate(cur_addr);
}
java_lang_String::is_instance(obj) &&
SerialStringDedup::is_candidate_from_mark(obj)) {
_string_dedup_requests->add(obj);
}
// 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(markWord::prototype().set_marked());
-
- ContinuationGCSupport::transform_stack_chunk(obj);
if (obj->mark_must_be_preserved(mark)) {
preserve_mark(obj, mark);
}
}
java_lang_String::is_instance(obj) &&
SerialStringDedup::is_candidate_from_mark(obj)) {
_string_dedup_requests->add(obj);
}
+ // Do the transform while we still have the header intact,
+ // which might include important class information.
+ ContinuationGCSupport::transform_stack_chunk(obj);
+
// 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());
if (obj->mark_must_be_preserved(mark)) {
preserve_mark(obj, mark);
}
}
T heap_oop = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(heap_oop)) {
oop obj = CompressedOops::decode_not_null(heap_oop);
assert(Universe::heap()->is_in(obj), "should be in heap");
! if (obj->is_forwarded()) {
! oop new_obj = obj->forwardee();
assert(is_object_aligned(new_obj), "oop must be aligned");
RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);
}
}
}
T heap_oop = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(heap_oop)) {
oop obj = CompressedOops::decode_not_null(heap_oop);
assert(Universe::heap()->is_in(obj), "should be in heap");
! if (SlidingForwarding::is_forwarded(obj)) {
! oop new_obj = SlidingForwarding::forwardee(obj);
assert(is_object_aligned(new_obj), "oop must be aligned");
RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);
}
}
}
allocate_stacks();
phase1_mark(clear_all_softrefs);
+ SlidingForwarding::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();
+ SlidingForwarding::end();
+
deallocate_stacks();
SerialFullGC::_string_dedup_requests->flush();
bool is_young_gen_empty = (gch->young_gen()->used() == 0);
< prev index next >