604 void set_target(ZPageAge age, ZPage* page) {
605 _target[static_cast<uint>(age) - 1] = page;
606 }
607
608 size_t object_alignment() const {
609 return (size_t)1 << _forwarding->object_alignment_shift();
610 }
611
612 void increase_other_forwarded(size_t unaligned_object_size) {
613 const size_t aligned_size = align_up(unaligned_object_size, object_alignment());
614 if (_forwarding->is_promotion()) {
615 _other_promoted += aligned_size;
616 } else {
617 _other_compacted += aligned_size;
618 }
619 }
620
621 zaddress try_relocate_object_inner(zaddress from_addr) {
622 ZForwardingCursor cursor;
623
624 const size_t size = ZUtils::object_size(from_addr);
625 ZPage* const to_page = target(_forwarding->to_age());
626
627 // Lookup forwarding
628 {
629 const zaddress to_addr = forwarding_find(_forwarding, from_addr, &cursor);
630 if (!is_null(to_addr)) {
631 // Already relocated
632 increase_other_forwarded(size);
633 return to_addr;
634 }
635 }
636
637 // Allocate object
638 const zaddress allocated_addr = _allocator->alloc_object(to_page, size);
639 if (is_null(allocated_addr)) {
640 // Allocation failed
641 return zaddress::null;
642 }
643
644 // Copy object. Use conjoint copying if we are relocating
645 // in-place and the new object overlaps with the old object.
646 if (_forwarding->in_place_relocation() && allocated_addr + size > from_addr) {
647 ZUtils::object_copy_conjoint(from_addr, allocated_addr, size);
648 } else {
649 ZUtils::object_copy_disjoint(from_addr, allocated_addr, size);
650 }
651
652 // Insert forwarding
653 const zaddress to_addr = forwarding_insert(_forwarding, from_addr, allocated_addr, &cursor);
654 if (to_addr != allocated_addr) {
655 // Already relocated, undo allocation
656 _allocator->undo_alloc_object(to_page, to_addr, size);
657 increase_other_forwarded(size);
|
604 void set_target(ZPageAge age, ZPage* page) {
605 _target[static_cast<uint>(age) - 1] = page;
606 }
607
608 size_t object_alignment() const {
609 return (size_t)1 << _forwarding->object_alignment_shift();
610 }
611
612 void increase_other_forwarded(size_t unaligned_object_size) {
613 const size_t aligned_size = align_up(unaligned_object_size, object_alignment());
614 if (_forwarding->is_promotion()) {
615 _other_promoted += aligned_size;
616 } else {
617 _other_compacted += aligned_size;
618 }
619 }
620
621 zaddress try_relocate_object_inner(zaddress from_addr) {
622 ZForwardingCursor cursor;
623
624 ZPage* const to_page = target(_forwarding->to_age());
625
626 // Lookup forwarding
627 {
628 const zaddress to_addr = forwarding_find(_forwarding, from_addr, &cursor);
629 if (!is_null(to_addr)) {
630 // Already relocated
631 const size_t size = ZUtils::object_size(to_addr);
632 increase_other_forwarded(size);
633 return to_addr;
634 }
635 }
636
637 // Allocate object
638 const size_t size = ZUtils::object_size(from_addr);
639 const zaddress allocated_addr = _allocator->alloc_object(to_page, size);
640 if (is_null(allocated_addr)) {
641 // Allocation failed
642 return zaddress::null;
643 }
644
645 // Copy object. Use conjoint copying if we are relocating
646 // in-place and the new object overlaps with the old object.
647 if (_forwarding->in_place_relocation() && allocated_addr + size > from_addr) {
648 ZUtils::object_copy_conjoint(from_addr, allocated_addr, size);
649 } else {
650 ZUtils::object_copy_disjoint(from_addr, allocated_addr, size);
651 }
652
653 // Insert forwarding
654 const zaddress to_addr = forwarding_insert(_forwarding, from_addr, allocated_addr, &cursor);
655 if (to_addr != allocated_addr) {
656 // Already relocated, undo allocation
657 _allocator->undo_alloc_object(to_page, to_addr, size);
658 increase_other_forwarded(size);
|