< prev index next >

src/cpu/ppc/vm/macroAssembler_ppc.cpp

Print this page




1566   // (flag == eq) => (dest_current_value == compare_value), ( swapped)
1567 }
1568 
1569 // Look up the method for a megamorphic invokeinterface call.
1570 // The target method is determined by <intf_klass, itable_index>.
1571 // The receiver klass is in recv_klass.
1572 // On success, the result will be in method_result, and execution falls through.
1573 // On failure, execution transfers to the given label.
1574 void MacroAssembler::lookup_interface_method(Register recv_klass,
1575                                              Register intf_klass,
1576                                              RegisterOrConstant itable_index,
1577                                              Register method_result,
1578                                              Register scan_temp,
1579                                              Register sethi_temp,
1580                                              Label& L_no_such_interface) {
1581   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
1582   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
1583          "caller must use same register for non-constant itable index as for method");
1584 
1585   // Compute start of first itableOffsetEntry (which is at the end of the vtable).
1586   int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
1587   int itentry_off = itableMethodEntry::method_offset_in_bytes();
1588   int logMEsize   = exact_log2(itableMethodEntry::size() * wordSize);
1589   int scan_step   = itableOffsetEntry::size() * wordSize;
1590   int log_vte_size= exact_log2(vtableEntry::size_in_bytes());
1591 
1592   lwz(scan_temp, in_bytes(InstanceKlass::vtable_length_offset()), recv_klass);
1593   // %%% We should store the aligned, prescaled offset in the klassoop.
1594   // Then the next several instructions would fold away.
1595 
1596   sldi(scan_temp, scan_temp, log_vte_size);
1597   addi(scan_temp, scan_temp, vtable_base);
1598   add(scan_temp, recv_klass, scan_temp);
1599 
1600   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
1601   if (itable_index.is_register()) {
1602     Register itable_offset = itable_index.as_register();
1603     sldi(itable_offset, itable_offset, logMEsize);
1604     if (itentry_off) addi(itable_offset, itable_offset, itentry_off);
1605     add(recv_klass, itable_offset, recv_klass);
1606   } else {
1607     long itable_offset = (long)itable_index.as_constant();
1608     load_const_optimized(sethi_temp, (itable_offset<<logMEsize)+itentry_off); // static address, no relocation
1609     add(recv_klass, sethi_temp, recv_klass);
1610   }
1611 
1612   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {


1640     cmpdi(CCR0, method_result, 0);
1641     beq(CCR0, L_no_such_interface);
1642     addi(scan_temp, scan_temp, scan_step);
1643   }
1644 
1645   bind(found_method);
1646 
1647   // Got a hit.
1648   int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
1649   lwz(scan_temp, ito_offset, scan_temp);
1650   ldx(method_result, scan_temp, recv_klass);
1651 }
1652 
1653 // virtual method calling
1654 void MacroAssembler::lookup_virtual_method(Register recv_klass,
1655                                            RegisterOrConstant vtable_index,
1656                                            Register method_result) {
1657 
1658   assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
1659 
1660   const int base = in_bytes(InstanceKlass::vtable_start_offset());
1661   assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
1662 
1663   if (vtable_index.is_register()) {
1664     sldi(vtable_index.as_register(), vtable_index.as_register(), LogBytesPerWord);
1665     add(recv_klass, vtable_index.as_register(), recv_klass);
1666   } else {
1667     addi(recv_klass, recv_klass, vtable_index.as_constant() << LogBytesPerWord);
1668   }
1669   ld(R19_method, base + vtableEntry::method_offset_in_bytes(), recv_klass);
1670 }
1671 
1672 /////////////////////////////////////////// subtype checking ////////////////////////////////////////////
1673 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
1674                                                    Register super_klass,
1675                                                    Register temp1_reg,
1676                                                    Register temp2_reg,
1677                                                    Label* L_success,
1678                                                    Label* L_failure,
1679                                                    Label* L_slow_path,
1680                                                    RegisterOrConstant super_check_offset) {




1566   // (flag == eq) => (dest_current_value == compare_value), ( swapped)
1567 }
1568 
1569 // Look up the method for a megamorphic invokeinterface call.
1570 // The target method is determined by <intf_klass, itable_index>.
1571 // The receiver klass is in recv_klass.
1572 // On success, the result will be in method_result, and execution falls through.
1573 // On failure, execution transfers to the given label.
1574 void MacroAssembler::lookup_interface_method(Register recv_klass,
1575                                              Register intf_klass,
1576                                              RegisterOrConstant itable_index,
1577                                              Register method_result,
1578                                              Register scan_temp,
1579                                              Register sethi_temp,
1580                                              Label& L_no_such_interface) {
1581   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
1582   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
1583          "caller must use same register for non-constant itable index as for method");
1584 
1585   // Compute start of first itableOffsetEntry (which is at the end of the vtable).
1586   int vtable_base = in_bytes(Klass::vtable_start_offset());
1587   int itentry_off = itableMethodEntry::method_offset_in_bytes();
1588   int logMEsize   = exact_log2(itableMethodEntry::size() * wordSize);
1589   int scan_step   = itableOffsetEntry::size() * wordSize;
1590   int log_vte_size= exact_log2(vtableEntry::size_in_bytes());
1591 
1592   lwz(scan_temp, in_bytes(Klass::vtable_length_offset()), recv_klass);
1593   // %%% We should store the aligned, prescaled offset in the klassoop.
1594   // Then the next several instructions would fold away.
1595 
1596   sldi(scan_temp, scan_temp, log_vte_size);
1597   addi(scan_temp, scan_temp, vtable_base);
1598   add(scan_temp, recv_klass, scan_temp);
1599 
1600   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
1601   if (itable_index.is_register()) {
1602     Register itable_offset = itable_index.as_register();
1603     sldi(itable_offset, itable_offset, logMEsize);
1604     if (itentry_off) addi(itable_offset, itable_offset, itentry_off);
1605     add(recv_klass, itable_offset, recv_klass);
1606   } else {
1607     long itable_offset = (long)itable_index.as_constant();
1608     load_const_optimized(sethi_temp, (itable_offset<<logMEsize)+itentry_off); // static address, no relocation
1609     add(recv_klass, sethi_temp, recv_klass);
1610   }
1611 
1612   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {


1640     cmpdi(CCR0, method_result, 0);
1641     beq(CCR0, L_no_such_interface);
1642     addi(scan_temp, scan_temp, scan_step);
1643   }
1644 
1645   bind(found_method);
1646 
1647   // Got a hit.
1648   int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
1649   lwz(scan_temp, ito_offset, scan_temp);
1650   ldx(method_result, scan_temp, recv_klass);
1651 }
1652 
1653 // virtual method calling
1654 void MacroAssembler::lookup_virtual_method(Register recv_klass,
1655                                            RegisterOrConstant vtable_index,
1656                                            Register method_result) {
1657 
1658   assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
1659 
1660   const int base = in_bytes(Klass::vtable_start_offset());
1661   assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
1662 
1663   if (vtable_index.is_register()) {
1664     sldi(vtable_index.as_register(), vtable_index.as_register(), LogBytesPerWord);
1665     add(recv_klass, vtable_index.as_register(), recv_klass);
1666   } else {
1667     addi(recv_klass, recv_klass, vtable_index.as_constant() << LogBytesPerWord);
1668   }
1669   ld(R19_method, base + vtableEntry::method_offset_in_bytes(), recv_klass);
1670 }
1671 
1672 /////////////////////////////////////////// subtype checking ////////////////////////////////////////////
1673 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
1674                                                    Register super_klass,
1675                                                    Register temp1_reg,
1676                                                    Register temp2_reg,
1677                                                    Label* L_success,
1678                                                    Label* L_failure,
1679                                                    Label* L_slow_path,
1680                                                    RegisterOrConstant super_check_offset) {


< prev index next >