1523 // (flag == eq) => (dest_current_value == compare_value), ( swapped)
1524 }
1525
1526 // Look up the method for a megamorphic invokeinterface call.
1527 // The target method is determined by <intf_klass, itable_index>.
1528 // The receiver klass is in recv_klass.
1529 // On success, the result will be in method_result, and execution falls through.
1530 // On failure, execution transfers to the given label.
1531 void MacroAssembler::lookup_interface_method(Register recv_klass,
1532 Register intf_klass,
1533 RegisterOrConstant itable_index,
1534 Register method_result,
1535 Register scan_temp,
1536 Register sethi_temp,
1537 Label& L_no_such_interface) {
1538 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
1539 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
1540 "caller must use same register for non-constant itable index as for method");
1541
1542 // Compute start of first itableOffsetEntry (which is at the end of the vtable).
1543 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
1544 int itentry_off = itableMethodEntry::method_offset_in_bytes();
1545 int logMEsize = exact_log2(itableMethodEntry::size() * wordSize);
1546 int scan_step = itableOffsetEntry::size() * wordSize;
1547 int log_vte_size= exact_log2(vtableEntry::size() * wordSize);
1548
1549 lwz(scan_temp, InstanceKlass::vtable_length_offset() * wordSize, recv_klass);
1550 // %%% We should store the aligned, prescaled offset in the klassoop.
1551 // Then the next several instructions would fold away.
1552
1553 sldi(scan_temp, scan_temp, log_vte_size);
1554 addi(scan_temp, scan_temp, vtable_base);
1555 add(scan_temp, recv_klass, scan_temp);
1556
1557 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
1558 if (itable_index.is_register()) {
1559 Register itable_offset = itable_index.as_register();
1560 sldi(itable_offset, itable_offset, logMEsize);
1561 if (itentry_off) addi(itable_offset, itable_offset, itentry_off);
1562 add(recv_klass, itable_offset, recv_klass);
1563 } else {
1564 long itable_offset = (long)itable_index.as_constant();
1565 load_const_optimized(sethi_temp, (itable_offset<<logMEsize)+itentry_off); // static address, no relocation
1566 add(recv_klass, sethi_temp, recv_klass);
1567 }
1568
1569 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
1597 cmpdi(CCR0, method_result, 0);
1598 beq(CCR0, L_no_such_interface);
1599 addi(scan_temp, scan_temp, scan_step);
1600 }
1601
1602 bind(found_method);
1603
1604 // Got a hit.
1605 int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
1606 lwz(scan_temp, ito_offset, scan_temp);
1607 ldx(method_result, scan_temp, recv_klass);
1608 }
1609
1610 // virtual method calling
1611 void MacroAssembler::lookup_virtual_method(Register recv_klass,
1612 RegisterOrConstant vtable_index,
1613 Register method_result) {
1614
1615 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
1616
1617 const int base = InstanceKlass::vtable_start_offset() * wordSize;
1618 assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
1619
1620 if (vtable_index.is_register()) {
1621 sldi(vtable_index.as_register(), vtable_index.as_register(), LogBytesPerWord);
1622 add(recv_klass, vtable_index.as_register(), recv_klass);
1623 } else {
1624 addi(recv_klass, recv_klass, vtable_index.as_constant() << LogBytesPerWord);
1625 }
1626 ld(R19_method, base + vtableEntry::method_offset_in_bytes(), recv_klass);
1627 }
1628
1629 /////////////////////////////////////////// subtype checking ////////////////////////////////////////////
1630
1631 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
1632 Register super_klass,
1633 Register temp1_reg,
1634 Register temp2_reg,
1635 Label& L_success,
1636 Label& L_failure) {
1637
|
1523 // (flag == eq) => (dest_current_value == compare_value), ( swapped)
1524 }
1525
1526 // Look up the method for a megamorphic invokeinterface call.
1527 // The target method is determined by <intf_klass, itable_index>.
1528 // The receiver klass is in recv_klass.
1529 // On success, the result will be in method_result, and execution falls through.
1530 // On failure, execution transfers to the given label.
1531 void MacroAssembler::lookup_interface_method(Register recv_klass,
1532 Register intf_klass,
1533 RegisterOrConstant itable_index,
1534 Register method_result,
1535 Register scan_temp,
1536 Register sethi_temp,
1537 Label& L_no_such_interface) {
1538 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
1539 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
1540 "caller must use same register for non-constant itable index as for method");
1541
1542 // Compute start of first itableOffsetEntry (which is at the end of the vtable).
1543 int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
1544 int itentry_off = itableMethodEntry::method_offset_in_bytes();
1545 int logMEsize = exact_log2(itableMethodEntry::size() * wordSize);
1546 int scan_step = itableOffsetEntry::size() * wordSize;
1547 int log_vte_size= exact_log2(vtableEntry::size_in_bytes());
1548
1549 lwz(scan_temp, in_bytes(InstanceKlass::vtable_length_offset()), recv_klass);
1550 // %%% We should store the aligned, prescaled offset in the klassoop.
1551 // Then the next several instructions would fold away.
1552
1553 sldi(scan_temp, scan_temp, log_vte_size);
1554 addi(scan_temp, scan_temp, vtable_base);
1555 add(scan_temp, recv_klass, scan_temp);
1556
1557 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
1558 if (itable_index.is_register()) {
1559 Register itable_offset = itable_index.as_register();
1560 sldi(itable_offset, itable_offset, logMEsize);
1561 if (itentry_off) addi(itable_offset, itable_offset, itentry_off);
1562 add(recv_klass, itable_offset, recv_klass);
1563 } else {
1564 long itable_offset = (long)itable_index.as_constant();
1565 load_const_optimized(sethi_temp, (itable_offset<<logMEsize)+itentry_off); // static address, no relocation
1566 add(recv_klass, sethi_temp, recv_klass);
1567 }
1568
1569 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
1597 cmpdi(CCR0, method_result, 0);
1598 beq(CCR0, L_no_such_interface);
1599 addi(scan_temp, scan_temp, scan_step);
1600 }
1601
1602 bind(found_method);
1603
1604 // Got a hit.
1605 int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
1606 lwz(scan_temp, ito_offset, scan_temp);
1607 ldx(method_result, scan_temp, recv_klass);
1608 }
1609
1610 // virtual method calling
1611 void MacroAssembler::lookup_virtual_method(Register recv_klass,
1612 RegisterOrConstant vtable_index,
1613 Register method_result) {
1614
1615 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
1616
1617 const int base = in_bytes(InstanceKlass::vtable_start_offset());
1618 assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
1619
1620 if (vtable_index.is_register()) {
1621 sldi(vtable_index.as_register(), vtable_index.as_register(), LogBytesPerWord);
1622 add(recv_klass, vtable_index.as_register(), recv_klass);
1623 } else {
1624 addi(recv_klass, recv_klass, vtable_index.as_constant() << LogBytesPerWord);
1625 }
1626 ld(R19_method, base + vtableEntry::method_offset_in_bytes(), recv_klass);
1627 }
1628
1629 /////////////////////////////////////////// subtype checking ////////////////////////////////////////////
1630
1631 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
1632 Register super_klass,
1633 Register temp1_reg,
1634 Register temp2_reg,
1635 Label& L_success,
1636 Label& L_failure) {
1637
|