574 void set_target(ZPageAge age, ZPage* page) {
575 _target[static_cast<uint>(age) - 1] = page;
576 }
577
578 size_t object_alignment() const {
579 return (size_t)1 << _forwarding->object_alignment_shift();
580 }
581
582 void increase_other_forwarded(size_t unaligned_object_size) {
583 const size_t aligned_size = align_up(unaligned_object_size, object_alignment());
584 if (_forwarding->is_promotion()) {
585 _other_promoted += aligned_size;
586 } else {
587 _other_compacted += aligned_size;
588 }
589 }
590
591 zaddress try_relocate_object_inner(zaddress from_addr) {
592 ZForwardingCursor cursor;
593
594 const size_t size = ZUtils::object_size(from_addr);
595 ZPage* const to_page = target(_forwarding->to_age());
596
597 // Lookup forwarding
598 {
599 const zaddress to_addr = _forwarding->find(from_addr, &cursor);
600 if (!is_null(to_addr)) {
601 // Already relocated
602 increase_other_forwarded(size);
603 return to_addr;
604 }
605 }
606
607 // Allocate object
608 const zaddress allocated_addr = _allocator->alloc_object(to_page, size);
609 if (is_null(allocated_addr)) {
610 // Allocation failed
611 return zaddress::null;
612 }
613
614 // Copy object. Use conjoint copying if we are relocating
615 // in-place and the new object overlaps with the old object.
616 if (_forwarding->in_place_relocation() && allocated_addr + size > from_addr) {
617 ZUtils::object_copy_conjoint(from_addr, allocated_addr, size);
618 } else {
619 ZUtils::object_copy_disjoint(from_addr, allocated_addr, size);
620 }
621
622 // Insert forwarding
623 const zaddress to_addr = _forwarding->insert(from_addr, allocated_addr, &cursor);
624 if (to_addr != allocated_addr) {
625 // Already relocated, undo allocation
626 _allocator->undo_alloc_object(to_page, to_addr, size);
627 increase_other_forwarded(size);
|
574 void set_target(ZPageAge age, ZPage* page) {
575 _target[static_cast<uint>(age) - 1] = page;
576 }
577
578 size_t object_alignment() const {
579 return (size_t)1 << _forwarding->object_alignment_shift();
580 }
581
582 void increase_other_forwarded(size_t unaligned_object_size) {
583 const size_t aligned_size = align_up(unaligned_object_size, object_alignment());
584 if (_forwarding->is_promotion()) {
585 _other_promoted += aligned_size;
586 } else {
587 _other_compacted += aligned_size;
588 }
589 }
590
591 zaddress try_relocate_object_inner(zaddress from_addr) {
592 ZForwardingCursor cursor;
593
594 ZPage* const to_page = target(_forwarding->to_age());
595
596 // Lookup forwarding
597 {
598 const zaddress to_addr = _forwarding->find(from_addr, &cursor);
599 if (!is_null(to_addr)) {
600 // Already relocated
601 const size_t size = ZUtils::object_size(to_addr);
602 increase_other_forwarded(size);
603 return to_addr;
604 }
605 }
606
607 // Allocate object
608 const size_t size = ZUtils::object_size(from_addr);
609 const zaddress allocated_addr = _allocator->alloc_object(to_page, size);
610 if (is_null(allocated_addr)) {
611 // Allocation failed
612 return zaddress::null;
613 }
614
615 // Copy object. Use conjoint copying if we are relocating
616 // in-place and the new object overlaps with the old object.
617 if (_forwarding->in_place_relocation() && allocated_addr + size > from_addr) {
618 ZUtils::object_copy_conjoint(from_addr, allocated_addr, size);
619 } else {
620 ZUtils::object_copy_disjoint(from_addr, allocated_addr, size);
621 }
622
623 // Insert forwarding
624 const zaddress to_addr = _forwarding->insert(from_addr, allocated_addr, &cursor);
625 if (to_addr != allocated_addr) {
626 // Already relocated, undo allocation
627 _allocator->undo_alloc_object(to_page, to_addr, size);
628 increase_other_forwarded(size);
|