src/cpu/sparc/vm/macroAssembler_sparc.cpp

Print this page




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