2205 Register recv_2 = recv_klass->is_global() ? recv_klass : L0; 2206 Register intf_2 = intf_klass->is_global() ? intf_klass : L1; 2207 assert(method_result->is_global(), "must be able to return value"); 2208 scan_temp = L2; 2209 sethi_temp = L3; 2210 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2); 2211 recv_klass = recv_2; 2212 intf_klass = intf_2; 2213 did_save = true; 2214 } 2215 2216 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 2217 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; 2218 int scan_step = itableOffsetEntry::size() * wordSize; 2219 int vte_size = vtableEntry::size() * wordSize; 2220 2221 lduw(recv_klass, InstanceKlass::vtable_length_offset() * wordSize, scan_temp); 2222 // %%% We should store the aligned, prescaled offset in the klassoop. 2223 // Then the next several instructions would fold away. 2224 2225 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0); 2226 int itb_offset = vtable_base; 2227 if (round_to_unit != 0) { 2228 // hoist first instruction of round_to(scan_temp, BytesPerLong): 2229 itb_offset += round_to_unit - wordSize; 2230 } 2231 int itb_scale = exact_log2(vtableEntry::size() * wordSize); 2232 sll(scan_temp, itb_scale, scan_temp); 2233 add(scan_temp, itb_offset, scan_temp); 2234 if (round_to_unit != 0) { 2235 // Round up to align_object_offset boundary 2236 // see code for InstanceKlass::start_of_itable! 2237 // Was: round_to(scan_temp, BytesPerLong); 2238 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); 2239 and3(scan_temp, -round_to_unit, scan_temp); 2240 } 2241 add(recv_klass, scan_temp, scan_temp); 2242 2243 // Adjust recv_klass by scaled itable_index, so we can free itable_index. 2244 RegisterOrConstant itable_offset = itable_index; 2245 itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset); 2246 itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset); 2247 add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass); 2248 2249 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { 2250 // if (scan->interface() == intf) { 2251 // result = (klass + scan->offset() + itable_index); 2252 // } 2253 // } 2254 Label L_search, L_found_method; 2255 2256 for (int peel = 1; peel >= 0; peel--) { 2257 // %%%% Could load both offset and interface in one ldx, if they were 2258 // in the opposite order. This would save a load. 2259 ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result); 2260 | 2205 Register recv_2 = recv_klass->is_global() ? recv_klass : L0; 2206 Register intf_2 = intf_klass->is_global() ? intf_klass : L1; 2207 assert(method_result->is_global(), "must be able to return value"); 2208 scan_temp = L2; 2209 sethi_temp = L3; 2210 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2); 2211 recv_klass = recv_2; 2212 intf_klass = intf_2; 2213 did_save = true; 2214 } 2215 2216 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 2217 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; 2218 int scan_step = itableOffsetEntry::size() * wordSize; 2219 int vte_size = vtableEntry::size() * wordSize; 2220 2221 lduw(recv_klass, InstanceKlass::vtable_length_offset() * wordSize, scan_temp); 2222 // %%% We should store the aligned, prescaled offset in the klassoop. 2223 // Then the next several instructions would fold away. 2224 2225 int itb_offset = vtable_base; 2226 int itb_scale = exact_log2(vtableEntry::size() * wordSize); 2227 sll(scan_temp, itb_scale, scan_temp); 2228 add(scan_temp, itb_offset, scan_temp); 2229 add(recv_klass, scan_temp, scan_temp); 2230 2231 // Adjust recv_klass by scaled itable_index, so we can free itable_index. 2232 RegisterOrConstant itable_offset = itable_index; 2233 itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset); 2234 itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset); 2235 add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass); 2236 2237 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { 2238 // if (scan->interface() == intf) { 2239 // result = (klass + scan->offset() + itable_index); 2240 // } 2241 // } 2242 Label L_search, L_found_method; 2243 2244 for (int peel = 1; peel >= 0; peel--) { 2245 // %%%% Could load both offset and interface in one ldx, if they were 2246 // in the opposite order. This would save a load. 2247 ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result); 2248 |