6035 RegisterOrConstant itable_index, 6036 Register method_result, 6037 Register scan_temp, 6038 Label& L_no_such_interface) { 6039 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); 6040 assert(itable_index.is_constant() || itable_index.as_register() == method_result, 6041 "caller must use same register for non-constant itable index as for method"); 6042 6043 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 6044 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; 6045 int itentry_off = itableMethodEntry::method_offset_in_bytes(); 6046 int scan_step = itableOffsetEntry::size() * wordSize; 6047 int vte_size = vtableEntry::size() * wordSize; 6048 Address::ScaleFactor times_vte_scale = Address::times_ptr; 6049 assert(vte_size == wordSize, "else adjust times_vte_scale"); 6050 6051 movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize)); 6052 6053 // %%% Could store the aligned, prescaled offset in the klassoop. 6054 lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base)); 6055 if (HeapWordsPerLong > 1) { 6056 // Round up to align_object_offset boundary 6057 // see code for InstanceKlass::start_of_itable! 6058 round_to(scan_temp, BytesPerLong); 6059 } 6060 6061 // Adjust recv_klass by scaled itable_index, so we can free itable_index. 6062 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); 6063 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off)); 6064 6065 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { 6066 // if (scan->interface() == intf) { 6067 // result = (klass + scan->offset() + itable_index); 6068 // } 6069 // } 6070 Label search, found_method; 6071 6072 for (int peel = 1; peel >= 0; peel--) { 6073 movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes())); 6074 cmpptr(intf_klass, method_result); 6075 6076 if (peel) { 6077 jccb(Assembler::equal, found_method); 6078 } else { 6079 jccb(Assembler::notEqual, search); | 6035 RegisterOrConstant itable_index, 6036 Register method_result, 6037 Register scan_temp, 6038 Label& L_no_such_interface) { 6039 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); 6040 assert(itable_index.is_constant() || itable_index.as_register() == method_result, 6041 "caller must use same register for non-constant itable index as for method"); 6042 6043 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 6044 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; 6045 int itentry_off = itableMethodEntry::method_offset_in_bytes(); 6046 int scan_step = itableOffsetEntry::size() * wordSize; 6047 int vte_size = vtableEntry::size() * wordSize; 6048 Address::ScaleFactor times_vte_scale = Address::times_ptr; 6049 assert(vte_size == wordSize, "else adjust times_vte_scale"); 6050 6051 movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize)); 6052 6053 // %%% Could store the aligned, prescaled offset in the klassoop. 6054 lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base)); 6055 6056 // Adjust recv_klass by scaled itable_index, so we can free itable_index. 6057 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); 6058 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off)); 6059 6060 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { 6061 // if (scan->interface() == intf) { 6062 // result = (klass + scan->offset() + itable_index); 6063 // } 6064 // } 6065 Label search, found_method; 6066 6067 for (int peel = 1; peel >= 0; peel--) { 6068 movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes())); 6069 cmpptr(intf_klass, method_result); 6070 6071 if (peel) { 6072 jccb(Assembler::equal, found_method); 6073 } else { 6074 jccb(Assembler::notEqual, search); |