< prev index next > src/hotspot/share/gc/z/zRelocate.cpp
Print this page
static zaddress relocate_object_inner(ZForwarding* forwarding, zaddress from_addr, ZForwardingCursor* cursor) {
assert(ZHeap::heap()->is_object_live(from_addr), "Should be live");
// Allocate object
! const size_t size = ZUtils::object_size(from_addr);
ZAllocatorForRelocation* allocator = ZAllocator::relocation(forwarding->to_age());
const zaddress to_addr = allocator->alloc_object(size);
if (is_null(to_addr)) {
// Allocation failed
return zaddress::null;
}
// Copy object
! ZUtils::object_copy_disjoint(from_addr, to_addr, size);
// Insert forwarding
const zaddress to_addr_final = forwarding->insert(from_addr, to_addr, cursor);
if (to_addr_final != to_addr) {
static zaddress relocate_object_inner(ZForwarding* forwarding, zaddress from_addr, ZForwardingCursor* cursor) {
assert(ZHeap::heap()->is_object_live(from_addr), "Should be live");
// Allocate object
! const size_t old_size = ZUtils::object_size(from_addr);
+ const size_t size = ZUtils::copy_size(from_addr, old_size);
ZAllocatorForRelocation* allocator = ZAllocator::relocation(forwarding->to_age());
const zaddress to_addr = allocator->alloc_object(size);
if (is_null(to_addr)) {
// Allocation failed
return zaddress::null;
}
+ assert(to_addr != from_addr, "addresses must be different");
// Copy object
! ZUtils::object_copy_disjoint(from_addr, to_addr, old_size);
+ ZUtils::initialize_hash_if_necessary(to_addr, from_addr);
// Insert forwarding
const zaddress to_addr_final = forwarding->insert(from_addr, to_addr, cursor);
if (to_addr_final != to_addr) {
} else {
_other_compacted += aligned_size;
}
}
! zaddress try_relocate_object_inner(zaddress from_addr) {
ZForwardingCursor cursor;
-
- const size_t size = ZUtils::object_size(from_addr);
ZPage* const to_page = target(_forwarding->to_age());
// Lookup forwarding
{
const zaddress to_addr = _forwarding->find(from_addr, &cursor);
if (!is_null(to_addr)) {
} else {
_other_compacted += aligned_size;
}
}
! zaddress try_relocate_object_inner(zaddress from_addr, size_t old_size) {
ZForwardingCursor cursor;
ZPage* const to_page = target(_forwarding->to_age());
+ zoffset_end from_offset = to_zoffset_end(ZAddress::offset(from_addr));
+ zoffset_end top = to_page != nullptr ? to_page->top() : to_zoffset_end(0);
+ const size_t new_size = ZUtils::copy_size(from_addr, old_size);
+ const size_t size = top == from_offset ? old_size : new_size;
// Lookup forwarding
{
const zaddress to_addr = _forwarding->find(from_addr, &cursor);
if (!is_null(to_addr)) {
const zaddress allocated_addr = _allocator->alloc_object(to_page, size);
if (is_null(allocated_addr)) {
// Allocation failed
return zaddress::null;
}
// Copy object. Use conjoint copying if we are relocating
// in-place and the new object overlaps with the old object.
! if (_forwarding->in_place_relocation() && allocated_addr + size > from_addr) {
! ZUtils::object_copy_conjoint(from_addr, allocated_addr, size);
} else {
! ZUtils::object_copy_disjoint(from_addr, allocated_addr, size);
}
// Insert forwarding
const zaddress to_addr = _forwarding->insert(from_addr, allocated_addr, &cursor);
if (to_addr != allocated_addr) {
const zaddress allocated_addr = _allocator->alloc_object(to_page, size);
if (is_null(allocated_addr)) {
// Allocation failed
return zaddress::null;
}
+ if (old_size != new_size && ((top == from_offset) != (allocated_addr == from_addr))) {
+ _allocator->undo_alloc_object(to_page, allocated_addr, size);
+ return zaddress::null;
+ }
// Copy object. Use conjoint copying if we are relocating
// in-place and the new object overlaps with the old object.
! if (_forwarding->in_place_relocation() && allocated_addr + old_size > from_addr) {
! ZUtils::object_copy_conjoint(from_addr, allocated_addr, old_size);
} else {
! ZUtils::object_copy_disjoint(from_addr, allocated_addr, old_size);
+ }
+ if (from_addr != allocated_addr) {
+ ZUtils::initialize_hash_if_necessary(allocated_addr, from_addr);
}
// Insert forwarding
const zaddress to_addr = _forwarding->insert(from_addr, allocated_addr, &cursor);
if (to_addr != allocated_addr) {
}
return to_addr;
}
! void update_remset_old_to_old(zaddress from_addr, zaddress to_addr) const {
// Old-to-old relocation - move existing remset bits
// If this is called for an in-place relocated page, then this code has the
// responsibility to clear the old remset bits. Extra care is needed because:
//
}
return to_addr;
}
! void update_remset_old_to_old(zaddress from_addr, zaddress to_addr, size_t size) const {
// Old-to-old relocation - move existing remset bits
// If this is called for an in-place relocated page, then this code has the
// responsibility to clear the old remset bits. Extra care is needed because:
//
// Uses _relaxed version to handle that in-place relocation resets _top
assert(ZHeap::heap()->is_in_page_relaxed(from_page, from_addr), "Must be");
assert(to_page->is_in(to_addr), "Must be");
!
! // Read the size from the to-object, since the from-object
- // could have been overwritten during in-place relocation.
- const size_t size = ZUtils::object_size(to_addr);
// If a young generation collection started while the old generation
// relocated objects, the remember set bits were flipped from "current"
// to "previous".
//
// Uses _relaxed version to handle that in-place relocation resets _top
assert(ZHeap::heap()->is_in_page_relaxed(from_page, from_addr), "Must be");
assert(to_page->is_in(to_addr), "Must be");
! assert(size <= ZUtils::object_size(to_addr), "old size must be <= new size");
! assert(size > 0, "size must be set");
// If a young generation collection started while the old generation
// relocated objects, the remember set bits were flipped from "current"
// to "previous".
//
void update_remset_promoted(zaddress to_addr) const {
ZIterator::basic_oop_iterate(to_oop(to_addr), update_remset_promoted_filter_and_remap_per_field);
}
! void update_remset_for_fields(zaddress from_addr, zaddress to_addr) const {
if (_forwarding->to_age() != ZPageAge::old) {
// No remembered set in young pages
return;
}
// Need to deal with remset when moving objects to the old generation
if (_forwarding->from_age() == ZPageAge::old) {
! update_remset_old_to_old(from_addr, to_addr);
return;
}
// Normal promotion
update_remset_promoted(to_addr);
}
bool try_relocate_object(zaddress from_addr) {
! const zaddress to_addr = try_relocate_object_inner(from_addr);
if (is_null(to_addr)) {
return false;
}
! update_remset_for_fields(from_addr, to_addr);
return true;
}
void start_in_place_relocation_prepare_remset(ZPage* from_page) {
void update_remset_promoted(zaddress to_addr) const {
ZIterator::basic_oop_iterate(to_oop(to_addr), update_remset_promoted_filter_and_remap_per_field);
}
! void update_remset_for_fields(zaddress from_addr, zaddress to_addr, size_t size) const {
if (_forwarding->to_age() != ZPageAge::old) {
// No remembered set in young pages
return;
}
// Need to deal with remset when moving objects to the old generation
if (_forwarding->from_age() == ZPageAge::old) {
! update_remset_old_to_old(from_addr, to_addr, size);
return;
}
// Normal promotion
update_remset_promoted(to_addr);
}
bool try_relocate_object(zaddress from_addr) {
! size_t size = ZUtils::object_size(from_addr);
+ const zaddress to_addr = try_relocate_object_inner(from_addr, size);
if (is_null(to_addr)) {
return false;
}
! update_remset_for_fields(from_addr, to_addr, size);
return true;
}
void start_in_place_relocation_prepare_remset(ZPage* from_page) {
< prev index next >