5790 }
5791 }
5792
5793
5794 // Look up the method for a megamorphic invokeinterface call.
5795 // The target method is determined by <intf_klass, itable_index>.
5796 // The receiver klass is in recv_klass.
5797 // On success, the result will be in method_result, and execution falls through.
5798 // On failure, execution transfers to the given label.
5799 void MacroAssembler::lookup_interface_method(Register recv_klass,
5800 Register intf_klass,
5801 RegisterOrConstant itable_index,
5802 Register method_result,
5803 Register scan_temp,
5804 Label& L_no_such_interface) {
5805 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
5806 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
5807 "caller must use same register for non-constant itable index as for method");
5808
5809 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
5810 int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
5811 int itentry_off = itableMethodEntry::method_offset_in_bytes();
5812 int scan_step = itableOffsetEntry::size() * wordSize;
5813 int vte_size = vtableEntry::size_in_bytes();
5814 Address::ScaleFactor times_vte_scale = Address::times_ptr;
5815 assert(vte_size == wordSize, "else adjust times_vte_scale");
5816
5817 movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset()));
5818
5819 // %%% Could store the aligned, prescaled offset in the klassoop.
5820 lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
5821 if (HeapWordsPerLong > 1) {
5822 // Round up to align_object_offset boundary
5823 // see code for InstanceKlass::start_of_itable!
5824 round_to(scan_temp, BytesPerLong);
5825 }
5826
5827 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
5828 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
5829 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
5830
5831 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
5832 // if (scan->interface() == intf) {
5833 // result = (klass + scan->offset() + itable_index);
5834 // }
5835 // }
5836 Label search, found_method;
5837
5853 // Check that the previous entry is non-null. A null entry means that
5854 // the receiver class doesn't implement the interface, and wasn't the
5855 // same as when the caller was compiled.
5856 testptr(method_result, method_result);
5857 jcc(Assembler::zero, L_no_such_interface);
5858 addptr(scan_temp, scan_step);
5859 }
5860
5861 bind(found_method);
5862
5863 // Got a hit.
5864 movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
5865 movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
5866 }
5867
5868
5869 // virtual method calling
5870 void MacroAssembler::lookup_virtual_method(Register recv_klass,
5871 RegisterOrConstant vtable_index,
5872 Register method_result) {
5873 const int base = in_bytes(InstanceKlass::vtable_start_offset());
5874 assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
5875 Address vtable_entry_addr(recv_klass,
5876 vtable_index, Address::times_ptr,
5877 base + vtableEntry::method_offset_in_bytes());
5878 movptr(method_result, vtable_entry_addr);
5879 }
5880
5881
5882 void MacroAssembler::check_klass_subtype(Register sub_klass,
5883 Register super_klass,
5884 Register temp_reg,
5885 Label& L_success) {
5886 Label L_failure;
5887 check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, &L_success, &L_failure, NULL);
5888 check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, noreg, &L_success, NULL);
5889 bind(L_failure);
5890 }
5891
5892
5893 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
|
5790 }
5791 }
5792
5793
5794 // Look up the method for a megamorphic invokeinterface call.
5795 // The target method is determined by <intf_klass, itable_index>.
5796 // The receiver klass is in recv_klass.
5797 // On success, the result will be in method_result, and execution falls through.
5798 // On failure, execution transfers to the given label.
5799 void MacroAssembler::lookup_interface_method(Register recv_klass,
5800 Register intf_klass,
5801 RegisterOrConstant itable_index,
5802 Register method_result,
5803 Register scan_temp,
5804 Label& L_no_such_interface) {
5805 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
5806 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
5807 "caller must use same register for non-constant itable index as for method");
5808
5809 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
5810 int vtable_base = in_bytes(Klass::vtable_start_offset());
5811 int itentry_off = itableMethodEntry::method_offset_in_bytes();
5812 int scan_step = itableOffsetEntry::size() * wordSize;
5813 int vte_size = vtableEntry::size_in_bytes();
5814 Address::ScaleFactor times_vte_scale = Address::times_ptr;
5815 assert(vte_size == wordSize, "else adjust times_vte_scale");
5816
5817 movl(scan_temp, Address(recv_klass, Klass::vtable_length_offset()));
5818
5819 // %%% Could store the aligned, prescaled offset in the klassoop.
5820 lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
5821 if (HeapWordsPerLong > 1) {
5822 // Round up to align_object_offset boundary
5823 // see code for InstanceKlass::start_of_itable!
5824 round_to(scan_temp, BytesPerLong);
5825 }
5826
5827 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
5828 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
5829 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
5830
5831 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
5832 // if (scan->interface() == intf) {
5833 // result = (klass + scan->offset() + itable_index);
5834 // }
5835 // }
5836 Label search, found_method;
5837
5853 // Check that the previous entry is non-null. A null entry means that
5854 // the receiver class doesn't implement the interface, and wasn't the
5855 // same as when the caller was compiled.
5856 testptr(method_result, method_result);
5857 jcc(Assembler::zero, L_no_such_interface);
5858 addptr(scan_temp, scan_step);
5859 }
5860
5861 bind(found_method);
5862
5863 // Got a hit.
5864 movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
5865 movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
5866 }
5867
5868
5869 // virtual method calling
5870 void MacroAssembler::lookup_virtual_method(Register recv_klass,
5871 RegisterOrConstant vtable_index,
5872 Register method_result) {
5873 const int base = in_bytes(Klass::vtable_start_offset());
5874 assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
5875 Address vtable_entry_addr(recv_klass,
5876 vtable_index, Address::times_ptr,
5877 base + vtableEntry::method_offset_in_bytes());
5878 movptr(method_result, vtable_entry_addr);
5879 }
5880
5881
5882 void MacroAssembler::check_klass_subtype(Register sub_klass,
5883 Register super_klass,
5884 Register temp_reg,
5885 Label& L_success) {
5886 Label L_failure;
5887 check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, &L_success, &L_failure, NULL);
5888 check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, noreg, &L_success, NULL);
5889 bind(L_failure);
5890 }
5891
5892
5893 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
|