< prev index next > src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp
Print this page
#include "compiler/oopMap.hpp"
#include "gc/shared/continuationGCSupport.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/preservedMarks.inline.hpp"
+ #include "gc/shared/gcForwarding.inline.hpp"
#include "gc/shared/tlab_globals.hpp"
#include "gc/shared/workerThread.hpp"
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahConcurrentGC.hpp"
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
{
// The rest of code performs region moves, where region status is undefined
// until all phases run together.
ShenandoahHeapLocker lock(heap->lock());
+ GCForwarding::begin();
phase2_calculate_target_addresses(worker_slices);
OrderAccess::fence();
phase3_update_references();
phase4_compact_objects(worker_slices);
}
{
// Epilogue
+ GCForwarding::end();
_preserved_marks->restore(heap->workers());
_preserved_marks->reclaim();
}
// Resize metaspace
// Object fits into current region, record new location:
assert(_compact_point + obj_size <= _to_region->end(), "must fit");
shenandoah_assert_not_forwarded(nullptr, p);
_preserved_marks->push_if_necessary(p, p->mark());
! p->forward_to(cast_to_oop(_compact_point));
_compact_point += obj_size;
}
};
class ShenandoahPrepareForCompactionTask : public WorkerTask {
// Object fits into current region, record new location:
assert(_compact_point + obj_size <= _to_region->end(), "must fit");
shenandoah_assert_not_forwarded(nullptr, p);
_preserved_marks->push_if_necessary(p, p->mark());
! GCForwarding::forward_to(p, cast_to_oop(_compact_point));
_compact_point += obj_size;
}
};
class ShenandoahPrepareForCompactionTask : public WorkerTask {
while (from_region != nullptr) {
assert(is_candidate_region(from_region), "Sanity");
cl.set_from_region(from_region);
if (from_region->has_live()) {
+ size_t num_marked = _heap->complete_marking_context()->count_marked(MemRegion(from_region->bottom(), from_region->top()));
_heap->marked_object_iterate(from_region, &cl);
}
// Compacted the region to somewhere else? From-region is empty then.
if (!cl.is_compact_same_region()) {
size_t start = to_end - num_regions;
if (start >= to_begin && start != r->index()) {
// Fits into current window, and the move is non-trivial. Record the move then, and continue scan.
_preserved_marks->get(0)->push_if_necessary(old_obj, old_obj->mark());
! old_obj->forward_to(cast_to_oop(heap->get_region(start)->bottom()));
to_end = start;
continue;
}
}
size_t start = to_end - num_regions;
if (start >= to_begin && start != r->index()) {
// Fits into current window, and the move is non-trivial. Record the move then, and continue scan.
_preserved_marks->get(0)->push_if_necessary(old_obj, old_obj->mark());
! GCForwarding::forward_to(old_obj, cast_to_oop(heap->get_region(start)->bottom()));
to_end = start;
continue;
}
}
inline void do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
assert(_ctx->is_marked(obj), "must be marked");
! if (obj->is_forwarded()) {
! oop forw = obj->forwardee();
RawAccess<IS_NOT_NULL>::oop_store(p, forw);
}
}
}
inline void do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
assert(_ctx->is_marked(obj), "must be marked");
! if (GCForwarding::is_forwarded(obj)) {
! oop forw = GCForwarding::forwardee(obj);
RawAccess<IS_NOT_NULL>::oop_store(p, forw);
}
}
}
_heap(ShenandoahHeap::heap()), _worker_id(worker_id) {}
void do_object(oop p) {
assert(_heap->complete_marking_context()->is_marked(p), "must be marked");
size_t size = p->size();
! if (p->is_forwarded()) {
HeapWord* compact_from = cast_from_oop<HeapWord*>(p);
! HeapWord* compact_to = cast_from_oop<HeapWord*>(p->forwardee());
Copy::aligned_conjoint_words(compact_from, compact_to, size);
oop new_obj = cast_to_oop(compact_to);
ContinuationGCSupport::relativize_stack_chunk(new_obj);
new_obj->init_mark();
_heap(ShenandoahHeap::heap()), _worker_id(worker_id) {}
void do_object(oop p) {
assert(_heap->complete_marking_context()->is_marked(p), "must be marked");
size_t size = p->size();
! if (GCForwarding::is_forwarded(p)) {
HeapWord* compact_from = cast_from_oop<HeapWord*>(p);
! HeapWord* compact_to = cast_from_oop<HeapWord*>(GCForwarding::forwardee(p));
Copy::aligned_conjoint_words(compact_from, compact_to, size);
oop new_obj = cast_to_oop(compact_to);
ContinuationGCSupport::relativize_stack_chunk(new_obj);
new_obj->init_mark();
for (size_t c = heap->num_regions(); c > 0; c--) {
ShenandoahHeapRegion* r = heap->get_region(c - 1);
if (r->is_humongous_start()) {
oop old_obj = cast_to_oop(r->bottom());
! if (!old_obj->is_forwarded()) {
// No need to move the object, it stays at the same slot
continue;
}
size_t words_size = old_obj->size();
size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize);
size_t old_start = r->index();
size_t old_end = old_start + num_regions - 1;
! size_t new_start = heap->heap_region_index_containing(old_obj->forwardee());
size_t new_end = new_start + num_regions - 1;
assert(old_start != new_start, "must be real move");
assert(r->is_stw_move_allowed(), "Region " SIZE_FORMAT " should be movable", r->index());
Copy::aligned_conjoint_words(r->bottom(), heap->get_region(new_start)->bottom(), words_size);
for (size_t c = heap->num_regions(); c > 0; c--) {
ShenandoahHeapRegion* r = heap->get_region(c - 1);
if (r->is_humongous_start()) {
oop old_obj = cast_to_oop(r->bottom());
! if (GCForwarding::is_not_forwarded(old_obj)) {
// No need to move the object, it stays at the same slot
continue;
}
size_t words_size = old_obj->size();
size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize);
size_t old_start = r->index();
size_t old_end = old_start + num_regions - 1;
! size_t new_start = heap->heap_region_index_containing(GCForwarding::forwardee(old_obj));
size_t new_end = new_start + num_regions - 1;
assert(old_start != new_start, "must be real move");
assert(r->is_stw_move_allowed(), "Region " SIZE_FORMAT " should be movable", r->index());
Copy::aligned_conjoint_words(r->bottom(), heap->get_region(new_start)->bottom(), words_size);
< prev index next >