< prev index next > src/hotspot/share/gc/shared/space.cpp
Print this page
#include "precompiled.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
+ #include "gc/shared/slidingForwarding.inline.hpp"
#include "gc/shared/space.hpp"
#include "gc/shared/space.inline.hpp"
#include "gc/shared/spaceDecorator.inline.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/universe.hpp"
void ContiguousSpace::mangle_unused_area_complete() {
mangler()->mangle_unused_area_complete();
}
#endif // NOT_PRODUCT
!
HeapWord* ContiguousSpace::forward(oop q, size_t size,
CompactPoint* cp, HeapWord* compact_top) {
// q is alive
// First check if we should switch compaction space
assert(this == cp->space, "'this' should be current compaction space.");
void ContiguousSpace::mangle_unused_area_complete() {
mangler()->mangle_unused_area_complete();
}
#endif // NOT_PRODUCT
! template <bool ALT_FWD>
HeapWord* ContiguousSpace::forward(oop q, size_t size,
CompactPoint* cp, HeapWord* compact_top) {
// q is alive
// First check if we should switch compaction space
assert(this == cp->space, "'this' should be current compaction space.");
compaction_max_size = pointer_delta(cp->space->end(), compact_top);
}
// store the forwarding pointer into the mark word
if (cast_from_oop<HeapWord*>(q) != compact_top) {
! q->forward_to(cast_to_oop(compact_top));
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
} else {
// if the object isn't moving we can just set the mark to the default
// mark and handle it specially later on.
q->init_mark();
! assert(!q->is_forwarded(), "should not be forwarded");
}
compact_top += size;
// We need to update the offset table so that the beginnings of objects can be
compaction_max_size = pointer_delta(cp->space->end(), compact_top);
}
// store the forwarding pointer into the mark word
if (cast_from_oop<HeapWord*>(q) != compact_top) {
! SlidingForwarding::forward_to<ALT_FWD>(q, cast_to_oop(compact_top));
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
} else {
// if the object isn't moving we can just set the mark to the default
// mark and handle it specially later on.
q->init_mark();
! assert(SlidingForwarding::is_not_forwarded(q), "should not be forwarded");
}
compact_top += size;
// We need to update the offset table so that the beginnings of objects can be
return compact_top;
}
#if INCLUDE_SERIALGC
! void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
// Compute the new addresses for the live objects and store it in the mark
// Used by universe::mark_sweep_phase2()
// We're sure to be here before any objects are compacted into this
// space, so this is a good time to initialize this:
return compact_top;
}
#if INCLUDE_SERIALGC
! template <bool ALT_FWD>
+ void ContiguousSpace::prepare_for_compaction_impl(CompactPoint* cp) {
// Compute the new addresses for the live objects and store it in the mark
// Used by universe::mark_sweep_phase2()
// We're sure to be here before any objects are compacted into this
// space, so this is a good time to initialize this:
while (cur_obj < scan_limit) {
if (cast_to_oop(cur_obj)->is_gc_marked()) {
// prefetch beyond cur_obj
Prefetch::write(cur_obj, interval);
size_t size = cast_to_oop(cur_obj)->size();
! compact_top = cp->space->forward(cast_to_oop(cur_obj), size, cp, compact_top);
cur_obj += size;
end_of_live = cur_obj;
} else {
// run over all the contiguous dead objects
HeapWord* end = cur_obj;
while (cur_obj < scan_limit) {
if (cast_to_oop(cur_obj)->is_gc_marked()) {
// prefetch beyond cur_obj
Prefetch::write(cur_obj, interval);
size_t size = cast_to_oop(cur_obj)->size();
! compact_top = cp->space->forward<ALT_FWD>(cast_to_oop(cur_obj), size, cp, compact_top);
cur_obj += size;
end_of_live = cur_obj;
} else {
// run over all the contiguous dead objects
HeapWord* end = cur_obj;
// see if we might want to pretend this object is alive so that
// we don't have to compact quite as often.
if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
oop obj = cast_to_oop(cur_obj);
! compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
end_of_live = end;
} else {
// otherwise, it really is a free region.
// cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
// see if we might want to pretend this object is alive so that
// we don't have to compact quite as often.
if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
oop obj = cast_to_oop(cur_obj);
! compact_top = cp->space->forward<ALT_FWD>(obj, obj->size(), cp, compact_top);
end_of_live = end;
} else {
// otherwise, it really is a free region.
// cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
// save the compaction_top of the compaction space.
cp->space->set_compaction_top(compact_top);
}
! void ContiguousSpace::adjust_pointers() {
// Check first is there is any work to do.
if (used() == 0) {
return; // Nothing to do.
}
// save the compaction_top of the compaction space.
cp->space->set_compaction_top(compact_top);
}
! void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
+ if (UseAltGCForwarding) {
+ prepare_for_compaction_impl<true>(cp);
+ } else {
+ prepare_for_compaction_impl<false>(cp);
+ }
+ }
+
+ template <bool ALT_FWD>
+ void ContiguousSpace::adjust_pointers_impl() {
// Check first is there is any work to do.
if (used() == 0) {
return; // Nothing to do.
}
while (cur_obj < end_of_live) {
Prefetch::write(cur_obj, interval);
if (cur_obj < first_dead || cast_to_oop(cur_obj)->is_gc_marked()) {
// cur_obj is alive
// point all the oops to the new location
! size_t size = MarkSweep::adjust_pointers(cast_to_oop(cur_obj));
debug_only(prev_obj = cur_obj);
cur_obj += size;
} else {
debug_only(prev_obj = cur_obj);
// cur_obj is not a live object, instead it points at the next live object
while (cur_obj < end_of_live) {
Prefetch::write(cur_obj, interval);
if (cur_obj < first_dead || cast_to_oop(cur_obj)->is_gc_marked()) {
// cur_obj is alive
// point all the oops to the new location
! size_t size = MarkSweep::adjust_pointers<ALT_FWD>(cast_to_oop(cur_obj));
debug_only(prev_obj = cur_obj);
cur_obj += size;
} else {
debug_only(prev_obj = cur_obj);
// cur_obj is not a live object, instead it points at the next live object
}
assert(cur_obj == end_of_live, "just checking");
}
! void ContiguousSpace::compact() {
// Copy all live objects to their new location
// Used by MarkSweep::mark_sweep_phase4()
verify_up_to_first_dead(this);
}
assert(cur_obj == end_of_live, "just checking");
}
! void ContiguousSpace::adjust_pointers() {
+ if (UseAltGCForwarding) {
+ adjust_pointers_impl<true>();
+ } else {
+ adjust_pointers_impl<false>();
+ }
+ }
+
+ template <bool ALT_FWD>
+ void ContiguousSpace::compact_impl() {
// Copy all live objects to their new location
// Used by MarkSweep::mark_sweep_phase4()
verify_up_to_first_dead(this);
cur_obj = *(HeapWord**)(_first_dead);
}
debug_only(HeapWord* prev_obj = nullptr);
while (cur_obj < end_of_live) {
! if (!cast_to_oop(cur_obj)->is_forwarded()) {
debug_only(prev_obj = cur_obj);
// The first word of the dead object contains a pointer to the next live object or end of space.
cur_obj = *(HeapWord**)cur_obj;
assert(cur_obj > prev_obj, "we should be moving forward through memory");
} else {
// prefetch beyond q
Prefetch::read(cur_obj, scan_interval);
// size and destination
size_t size = cast_to_oop(cur_obj)->size();
! HeapWord* compaction_top = cast_from_oop<HeapWord*>(cast_to_oop(cur_obj)->forwardee());
// prefetch beyond compaction_top
Prefetch::write(compaction_top, copy_interval);
// copy object and reinit its mark
cur_obj = *(HeapWord**)(_first_dead);
}
debug_only(HeapWord* prev_obj = nullptr);
while (cur_obj < end_of_live) {
! if (SlidingForwarding::is_not_forwarded(cast_to_oop(cur_obj))) {
debug_only(prev_obj = cur_obj);
// The first word of the dead object contains a pointer to the next live object or end of space.
cur_obj = *(HeapWord**)cur_obj;
assert(cur_obj > prev_obj, "we should be moving forward through memory");
} else {
// prefetch beyond q
Prefetch::read(cur_obj, scan_interval);
// size and destination
size_t size = cast_to_oop(cur_obj)->size();
! HeapWord* compaction_top = cast_from_oop<HeapWord*>(SlidingForwarding::forwardee<ALT_FWD>(cast_to_oop(cur_obj)));
// prefetch beyond compaction_top
Prefetch::write(compaction_top, copy_interval);
// copy object and reinit its mark
}
clear_empty_region(this);
}
+ void ContiguousSpace::compact() {
+ if (UseAltGCForwarding) {
+ compact_impl<true>();
+ } else {
+ compact_impl<false>();
+ }
+ }
+
#endif // INCLUDE_SERIALGC
void Space::print_short() const { print_short_on(tty); }
void Space::print_short_on(outputStream* st) const {
< prev index next >