2185 Label& L_no_such_interface) { 2186 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); 2187 assert(itable_index.is_constant() || itable_index.as_register() == method_result, 2188 "caller must use same register for non-constant itable index as for method"); 2189 2190 Label L_no_such_interface_restore; 2191 bool did_save = false; 2192 if (scan_temp == noreg || sethi_temp == noreg) { 2193 Register recv_2 = recv_klass->is_global() ? recv_klass : L0; 2194 Register intf_2 = intf_klass->is_global() ? intf_klass : L1; 2195 assert(method_result->is_global(), "must be able to return value"); 2196 scan_temp = L2; 2197 sethi_temp = L3; 2198 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2); 2199 recv_klass = recv_2; 2200 intf_klass = intf_2; 2201 did_save = true; 2202 } 2203 2204 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 2205 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; 2206 int scan_step = itableOffsetEntry::size() * wordSize; 2207 int vte_size = vtableEntry::size() * wordSize; 2208 2209 lduw(recv_klass, InstanceKlass::vtable_length_offset() * wordSize, scan_temp); 2210 // %%% We should store the aligned, prescaled offset in the klassoop. 2211 // Then the next several instructions would fold away. 2212 2213 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0); 2214 int itb_offset = vtable_base; 2215 if (round_to_unit != 0) { 2216 // hoist first instruction of round_to(scan_temp, BytesPerLong): 2217 itb_offset += round_to_unit - wordSize; 2218 } 2219 int itb_scale = exact_log2(vtableEntry::size() * wordSize); 2220 sll(scan_temp, itb_scale, scan_temp); 2221 add(scan_temp, itb_offset, scan_temp); 2222 if (round_to_unit != 0) { 2223 // Round up to align_object_offset boundary 2224 // see code for InstanceKlass::start_of_itable! 2225 // Was: round_to(scan_temp, BytesPerLong); 2226 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); 2227 and3(scan_temp, -round_to_unit, scan_temp); 2228 } 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); 2277 if (did_save) { 2278 Label L_done; 2279 ba(L_done); 2280 delayed()->restore(); 2281 2282 bind(L_no_such_interface_restore); 2283 ba(L_no_such_interface); 2284 delayed()->restore(); 2285 2286 bind(L_done); 2287 } 2288 } 2289 2290 2291 // virtual method calling 2292 void MacroAssembler::lookup_virtual_method(Register recv_klass, 2293 RegisterOrConstant vtable_index, 2294 Register method_result) { 2295 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg()); 2296 Register sethi_temp = method_result; 2297 const int base = (InstanceKlass::vtable_start_offset() * wordSize + 2298 // method pointer offset within the vtable entry: 2299 vtableEntry::method_offset_in_bytes()); 2300 RegisterOrConstant vtable_offset = vtable_index; 2301 // Each of the following three lines potentially generates an instruction. 2302 // But the total number of address formation instructions will always be 2303 // at most two, and will often be zero. In any case, it will be optimal. 2304 // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x). 2305 // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t). 2306 vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size() * wordSize), vtable_offset); 2307 vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp); 2308 Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp)); 2309 ld_ptr(vtable_entry_addr, method_result); 2310 } 2311 2312 2313 void MacroAssembler::check_klass_subtype(Register sub_klass, 2314 Register super_klass, 2315 Register temp_reg, 2316 Register temp2_reg, 2317 Label& L_success) { 2318 Register sub_2 = sub_klass; 2319 Register sup_2 = super_klass; 2320 if (!sub_2->is_global()) sub_2 = L0; 2321 if (!sup_2->is_global()) sup_2 = L1; 2322 bool did_save = false; 2323 if (temp_reg == noreg || temp2_reg == noreg) { 2324 temp_reg = L2; 2325 temp2_reg = L3; 2326 save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2); | 2185 Label& L_no_such_interface) { 2186 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); 2187 assert(itable_index.is_constant() || itable_index.as_register() == method_result, 2188 "caller must use same register for non-constant itable index as for method"); 2189 2190 Label L_no_such_interface_restore; 2191 bool did_save = false; 2192 if (scan_temp == noreg || sethi_temp == noreg) { 2193 Register recv_2 = recv_klass->is_global() ? recv_klass : L0; 2194 Register intf_2 = intf_klass->is_global() ? intf_klass : L1; 2195 assert(method_result->is_global(), "must be able to return value"); 2196 scan_temp = L2; 2197 sethi_temp = L3; 2198 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2); 2199 recv_klass = recv_2; 2200 intf_klass = intf_2; 2201 did_save = true; 2202 } 2203 2204 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 2205 int vtable_base = in_bytes(InstanceKlass::vtable_start_offset()); 2206 int scan_step = itableOffsetEntry::size() * wordSize; 2207 int vte_size = vtableEntry::size_in_bytes(); 2208 2209 lduw(recv_klass, in_bytes(InstanceKlass::vtable_length_offset()), scan_temp); 2210 // %%% We should store the aligned, prescaled offset in the klassoop. 2211 // Then the next several instructions would fold away. 2212 2213 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0); 2214 int itb_offset = vtable_base; 2215 if (round_to_unit != 0) { 2216 // hoist first instruction of round_to(scan_temp, BytesPerLong): 2217 itb_offset += round_to_unit - wordSize; 2218 } 2219 int itb_scale = exact_log2(vtableEntry::size_in_bytes()); 2220 sll(scan_temp, itb_scale, scan_temp); 2221 add(scan_temp, itb_offset, scan_temp); 2222 if (round_to_unit != 0) { 2223 // Round up to align_object_offset boundary 2224 // see code for InstanceKlass::start_of_itable! 2225 // Was: round_to(scan_temp, BytesPerLong); 2226 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); 2227 and3(scan_temp, -round_to_unit, scan_temp); 2228 } 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); 2277 if (did_save) { 2278 Label L_done; 2279 ba(L_done); 2280 delayed()->restore(); 2281 2282 bind(L_no_such_interface_restore); 2283 ba(L_no_such_interface); 2284 delayed()->restore(); 2285 2286 bind(L_done); 2287 } 2288 } 2289 2290 2291 // virtual method calling 2292 void MacroAssembler::lookup_virtual_method(Register recv_klass, 2293 RegisterOrConstant vtable_index, 2294 Register method_result) { 2295 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg()); 2296 Register sethi_temp = method_result; 2297 const int base = in_bytes(InstanceKlass::vtable_start_offset()) + 2298 // method pointer offset within the vtable entry: 2299 vtableEntry::method_offset_in_bytes(); 2300 RegisterOrConstant vtable_offset = vtable_index; 2301 // Each of the following three lines potentially generates an instruction. 2302 // But the total number of address formation instructions will always be 2303 // at most two, and will often be zero. In any case, it will be optimal. 2304 // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x). 2305 // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t). 2306 vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size_in_bytes()), vtable_offset); 2307 vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp); 2308 Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp)); 2309 ld_ptr(vtable_entry_addr, method_result); 2310 } 2311 2312 2313 void MacroAssembler::check_klass_subtype(Register sub_klass, 2314 Register super_klass, 2315 Register temp_reg, 2316 Register temp2_reg, 2317 Label& L_success) { 2318 Register sub_2 = sub_klass; 2319 Register sup_2 = super_klass; 2320 if (!sub_2->is_global()) sub_2 = L0; 2321 if (!sup_2->is_global()) sup_2 = L1; 2322 bool did_save = false; 2323 if (temp_reg == noreg || temp2_reg == noreg) { 2324 temp_reg = L2; 2325 temp2_reg = L3; 2326 save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2); |