1616 // pseudo-code: 1617 // rax = src_addr - swap_bytes 1618 // rbx = dest_addr 1619 // while (rax >= rbx) *(rax + swap_bytes) = *(rax + 0), rax--; 1620 move_arg_slots_up(_masm, 1621 rbx_destslot, 1622 Address(rax_argslot, 0), 1623 swap_slots, 1624 rax_argslot, rdx_temp); 1625 } else { 1626 // Here is the other direction, rotate < 0: 1627 // (low mem) (high mem) 1628 // | arg: odd_slot | arg+1: more_slots... :dest+1 | 1629 // => 1630 // | arg: more_slots... | dest: odd_slot :dest+1 | 1631 // work argslot up to destslot, copying contiguous data downwards 1632 // pseudo-code: 1633 // rax = src_addr + swap_bytes 1634 // rbx = dest_addr 1635 // while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++; 1636 __ addptr(rbx_destslot, wordSize); 1637 move_arg_slots_down(_masm, 1638 Address(rax_argslot, swap_slots * wordSize), 1639 rbx_destslot, 1640 -swap_slots, 1641 rax_argslot, rdx_temp); 1642 1643 __ subptr(rbx_destslot, wordSize); 1644 } 1645 // pop the original first chunk into the destination slot, now free 1646 for (int i = 0; i < swap_slots; i++) { 1647 if (i == 0) __ movptr(Address(rbx_destslot, i * wordSize), rdi_temp); 1648 else __ popptr(Address(rbx_destslot, i * wordSize)); 1649 } 1650 } 1651 1652 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 1653 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1654 } 1655 break; 1656 1657 case _adapter_dup_args: 1658 { 1659 // 'argslot' is the position of the first argument to duplicate 1660 __ movl(rax_argslot, rcx_amh_vmargslot); 1661 __ lea(rax_argslot, __ argument_address(rax_argslot)); 1662 1663 // 'stack_move' is negative number of words to duplicate | 1616 // pseudo-code: 1617 // rax = src_addr - swap_bytes 1618 // rbx = dest_addr 1619 // while (rax >= rbx) *(rax + swap_bytes) = *(rax + 0), rax--; 1620 move_arg_slots_up(_masm, 1621 rbx_destslot, 1622 Address(rax_argslot, 0), 1623 swap_slots, 1624 rax_argslot, rdx_temp); 1625 } else { 1626 // Here is the other direction, rotate < 0: 1627 // (low mem) (high mem) 1628 // | arg: odd_slot | arg+1: more_slots... :dest+1 | 1629 // => 1630 // | arg: more_slots... | dest: odd_slot :dest+1 | 1631 // work argslot up to destslot, copying contiguous data downwards 1632 // pseudo-code: 1633 // rax = src_addr + swap_bytes 1634 // rbx = dest_addr 1635 // while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++; 1636 // dest_slot denotes an exclusive upper limit 1637 int limit_bias = OP_ROT_ARGS_DOWN_LIMIT_BIAS; 1638 if (limit_bias != 0) 1639 __ addptr(rbx_destslot, - limit_bias * wordSize); 1640 move_arg_slots_down(_masm, 1641 Address(rax_argslot, swap_slots * wordSize), 1642 rbx_destslot, 1643 -swap_slots, 1644 rax_argslot, rdx_temp); 1645 __ subptr(rbx_destslot, swap_slots * wordSize); 1646 } 1647 // pop the original first chunk into the destination slot, now free 1648 for (int i = 0; i < swap_slots; i++) { 1649 if (i == 0) __ movptr(Address(rbx_destslot, i * wordSize), rdi_temp); 1650 else __ popptr(Address(rbx_destslot, i * wordSize)); 1651 } 1652 } 1653 1654 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); 1655 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1656 } 1657 break; 1658 1659 case _adapter_dup_args: 1660 { 1661 // 'argslot' is the position of the first argument to duplicate 1662 __ movl(rax_argslot, rcx_amh_vmargslot); 1663 __ lea(rax_argslot, __ argument_address(rax_argslot)); 1664 1665 // 'stack_move' is negative number of words to duplicate |