2171 Label& L_no_such_interface) {
2172 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
2173 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
2174 "caller must use same register for non-constant itable index as for method");
2175
2176 Label L_no_such_interface_restore;
2177 bool did_save = false;
2178 if (scan_temp == noreg || sethi_temp == noreg) {
2179 Register recv_2 = recv_klass->is_global() ? recv_klass : L0;
2180 Register intf_2 = intf_klass->is_global() ? intf_klass : L1;
2181 assert(method_result->is_global(), "must be able to return value");
2182 scan_temp = L2;
2183 sethi_temp = L3;
2184 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2);
2185 recv_klass = recv_2;
2186 intf_klass = intf_2;
2187 did_save = true;
2188 }
2189
2190 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
2191 int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
2192 int scan_step = itableOffsetEntry::size() * wordSize;
2193 int vte_size = vtableEntry::size_in_bytes();
2194
2195 lduw(recv_klass, in_bytes(InstanceKlass::vtable_length_offset()), scan_temp);
2196 // %%% We should store the aligned, prescaled offset in the klassoop.
2197 // Then the next several instructions would fold away.
2198
2199 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0);
2200 int itb_offset = vtable_base;
2201 if (round_to_unit != 0) {
2202 // hoist first instruction of round_to(scan_temp, BytesPerLong):
2203 itb_offset += round_to_unit - wordSize;
2204 }
2205 int itb_scale = exact_log2(vtableEntry::size_in_bytes());
2206 sll(scan_temp, itb_scale, scan_temp);
2207 add(scan_temp, itb_offset, scan_temp);
2208 if (round_to_unit != 0) {
2209 // Round up to align_object_offset boundary
2210 // see code for InstanceKlass::start_of_itable!
2211 // Was: round_to(scan_temp, BytesPerLong);
2212 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp);
2213 and3(scan_temp, -round_to_unit, scan_temp);
2214 }
2215 add(recv_klass, scan_temp, scan_temp);
2263 if (did_save) {
2264 Label L_done;
2265 ba(L_done);
2266 delayed()->restore();
2267
2268 bind(L_no_such_interface_restore);
2269 ba(L_no_such_interface);
2270 delayed()->restore();
2271
2272 bind(L_done);
2273 }
2274 }
2275
2276
2277 // virtual method calling
2278 void MacroAssembler::lookup_virtual_method(Register recv_klass,
2279 RegisterOrConstant vtable_index,
2280 Register method_result) {
2281 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
2282 Register sethi_temp = method_result;
2283 const int base = in_bytes(InstanceKlass::vtable_start_offset()) +
2284 // method pointer offset within the vtable entry:
2285 vtableEntry::method_offset_in_bytes();
2286 RegisterOrConstant vtable_offset = vtable_index;
2287 // Each of the following three lines potentially generates an instruction.
2288 // But the total number of address formation instructions will always be
2289 // at most two, and will often be zero. In any case, it will be optimal.
2290 // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x).
2291 // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t).
2292 vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size_in_bytes()), vtable_offset);
2293 vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp);
2294 Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp));
2295 ld_ptr(vtable_entry_addr, method_result);
2296 }
2297
2298
2299 void MacroAssembler::check_klass_subtype(Register sub_klass,
2300 Register super_klass,
2301 Register temp_reg,
2302 Register temp2_reg,
2303 Label& L_success) {
|
2171 Label& L_no_such_interface) {
2172 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
2173 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
2174 "caller must use same register for non-constant itable index as for method");
2175
2176 Label L_no_such_interface_restore;
2177 bool did_save = false;
2178 if (scan_temp == noreg || sethi_temp == noreg) {
2179 Register recv_2 = recv_klass->is_global() ? recv_klass : L0;
2180 Register intf_2 = intf_klass->is_global() ? intf_klass : L1;
2181 assert(method_result->is_global(), "must be able to return value");
2182 scan_temp = L2;
2183 sethi_temp = L3;
2184 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2);
2185 recv_klass = recv_2;
2186 intf_klass = intf_2;
2187 did_save = true;
2188 }
2189
2190 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
2191 int vtable_base = in_bytes(Klass::vtable_start_offset());
2192 int scan_step = itableOffsetEntry::size() * wordSize;
2193 int vte_size = vtableEntry::size_in_bytes();
2194
2195 lduw(recv_klass, in_bytes(Klass::vtable_length_offset()), scan_temp);
2196 // %%% We should store the aligned, prescaled offset in the klassoop.
2197 // Then the next several instructions would fold away.
2198
2199 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0);
2200 int itb_offset = vtable_base;
2201 if (round_to_unit != 0) {
2202 // hoist first instruction of round_to(scan_temp, BytesPerLong):
2203 itb_offset += round_to_unit - wordSize;
2204 }
2205 int itb_scale = exact_log2(vtableEntry::size_in_bytes());
2206 sll(scan_temp, itb_scale, scan_temp);
2207 add(scan_temp, itb_offset, scan_temp);
2208 if (round_to_unit != 0) {
2209 // Round up to align_object_offset boundary
2210 // see code for InstanceKlass::start_of_itable!
2211 // Was: round_to(scan_temp, BytesPerLong);
2212 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp);
2213 and3(scan_temp, -round_to_unit, scan_temp);
2214 }
2215 add(recv_klass, scan_temp, scan_temp);
2263 if (did_save) {
2264 Label L_done;
2265 ba(L_done);
2266 delayed()->restore();
2267
2268 bind(L_no_such_interface_restore);
2269 ba(L_no_such_interface);
2270 delayed()->restore();
2271
2272 bind(L_done);
2273 }
2274 }
2275
2276
2277 // virtual method calling
2278 void MacroAssembler::lookup_virtual_method(Register recv_klass,
2279 RegisterOrConstant vtable_index,
2280 Register method_result) {
2281 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
2282 Register sethi_temp = method_result;
2283 const int base = in_bytes(Klass::vtable_start_offset()) +
2284 // method pointer offset within the vtable entry:
2285 vtableEntry::method_offset_in_bytes();
2286 RegisterOrConstant vtable_offset = vtable_index;
2287 // Each of the following three lines potentially generates an instruction.
2288 // But the total number of address formation instructions will always be
2289 // at most two, and will often be zero. In any case, it will be optimal.
2290 // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x).
2291 // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t).
2292 vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size_in_bytes()), vtable_offset);
2293 vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp);
2294 Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp));
2295 ld_ptr(vtable_entry_addr, method_result);
2296 }
2297
2298
2299 void MacroAssembler::check_klass_subtype(Register sub_klass,
2300 Register super_klass,
2301 Register temp_reg,
2302 Register temp2_reg,
2303 Label& L_success) {
|