< prev index next >

src/cpu/sparc/vm/macroAssembler_sparc.cpp

Print this page




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) {


< prev index next >