< prev index next >

src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp

Print this page

223 
224     PUSH(src, dst);
225     __ far_call(RuntimeAddress(Runtime1::entry_for(StubId::c1_slow_subtype_check_id)));
226     POP(src, dst);
227     __ bnez(dst, cont);
228 
229     __ bind(slow);
230     POP(src, dst);
231 
232     address copyfunc_addr = StubRoutines::checkcast_arraycopy();
233     if (copyfunc_addr != nullptr) { // use stub if available
234       arraycopy_checkcast(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, copyfunc_addr, flags);
235     }
236 
237     __ j(*stub->entry());
238     __ bind(cont);
239     POP(src, dst);
240   }
241 }
242 












243 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
244   ciArrayKlass *default_type = op->expected_type();
245   Register src = op->src()->as_register();
246   Register dst = op->dst()->as_register();
247   Register src_pos = op->src_pos()->as_register();
248   Register dst_pos = op->dst_pos()->as_register();
249   Register length = op->length()->as_register();
250   Register tmp = op->tmp()->as_register();
251 
252   CodeStub* stub = op->stub();
253   int flags = op->flags();
254   BasicType basic_type = default_type != nullptr ? default_type->element_type()->basic_type() : T_ILLEGAL;
255   if (is_reference_type(basic_type)) { basic_type = T_OBJECT; }
256 






257   // if we don't know anything, just go through the generic arraycopy
258   if (default_type == nullptr) {
259     generic_arraycopy(src, src_pos, length, dst, dst_pos, stub);
260     return;
261   }
262 







263   assert(default_type != nullptr && default_type->is_array_klass() && default_type->is_loaded(),
264          "must be true at this point");
265 
266   arraycopy_simple_check(src, src_pos, length, dst, dst_pos, tmp, stub, flags);
267 
268   if (flags & LIR_OpArrayCopy::type_check) {
269     arraycopy_type_check(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, flags);
270   }
271 
272 #ifdef ASSERT
273   if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
274     // Sanity check the known type with the incoming class.  For the
275     // primitive case the types must match exactly with src.klass and
276     // dst.klass each exactly matching the default type.  For the
277     // object array case, if no type check is needed then either the
278     // dst type is exactly the expected type and the src type is a
279     // subtype which we can't check or src is the same array as dst
280     // but not necessarily exactly of type default_type.
281     Label known_ok, halt;
282     __ mov_metadata(tmp, default_type->constant_encoding());

223 
224     PUSH(src, dst);
225     __ far_call(RuntimeAddress(Runtime1::entry_for(StubId::c1_slow_subtype_check_id)));
226     POP(src, dst);
227     __ bnez(dst, cont);
228 
229     __ bind(slow);
230     POP(src, dst);
231 
232     address copyfunc_addr = StubRoutines::checkcast_arraycopy();
233     if (copyfunc_addr != nullptr) { // use stub if available
234       arraycopy_checkcast(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, copyfunc_addr, flags);
235     }
236 
237     __ j(*stub->entry());
238     __ bind(cont);
239     POP(src, dst);
240   }
241 }
242 
243 void LIR_Assembler::arraycopy_inlinetype_check(Register obj, Register tmp, CodeStub* slow_path, bool is_dest, bool null_check) {
244   if (null_check) {
245     __ beqz(obj, *slow_path->entry(), /* is_far */ true);
246   }
247   if (is_dest) {
248     __ test_null_free_array_oop(obj, tmp, *slow_path->entry());
249     __ test_flat_array_oop(obj, tmp, *slow_path->entry());
250   } else {
251     __ test_flat_array_oop(obj, tmp, *slow_path->entry());
252   }
253 }
254 
255 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
256   ciArrayKlass *default_type = op->expected_type();
257   Register src = op->src()->as_register();
258   Register dst = op->dst()->as_register();
259   Register src_pos = op->src_pos()->as_register();
260   Register dst_pos = op->dst_pos()->as_register();
261   Register length = op->length()->as_register();
262   Register tmp = op->tmp()->as_register();
263 
264   CodeStub* stub = op->stub();
265   int flags = op->flags();
266   BasicType basic_type = default_type != nullptr ? default_type->element_type()->basic_type() : T_ILLEGAL;
267   if (is_reference_type(basic_type)) { basic_type = T_OBJECT; }
268 
269   if (flags & LIR_OpArrayCopy::always_slow_path) {
270     __ j(*stub->entry());
271     __ bind(*stub->continuation());
272     return;
273   }
274 
275   // if we don't know anything, just go through the generic arraycopy
276   if (default_type == nullptr) {
277     generic_arraycopy(src, src_pos, length, dst, dst_pos, stub);
278     return;
279   }
280 
281   if (flags & LIR_OpArrayCopy::src_inlinetype_check) {
282     arraycopy_inlinetype_check(src, tmp, stub, false, (flags & LIR_OpArrayCopy::src_null_check));
283   }
284   if (flags & LIR_OpArrayCopy::dst_inlinetype_check) {
285     arraycopy_inlinetype_check(dst, tmp, stub, true, (flags & LIR_OpArrayCopy::dst_null_check));
286   }
287 
288   assert(default_type != nullptr && default_type->is_array_klass() && default_type->is_loaded(),
289          "must be true at this point");
290 
291   arraycopy_simple_check(src, src_pos, length, dst, dst_pos, tmp, stub, flags);
292 
293   if (flags & LIR_OpArrayCopy::type_check) {
294     arraycopy_type_check(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, flags);
295   }
296 
297 #ifdef ASSERT
298   if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
299     // Sanity check the known type with the incoming class.  For the
300     // primitive case the types must match exactly with src.klass and
301     // dst.klass each exactly matching the default type.  For the
302     // object array case, if no type check is needed then either the
303     // dst type is exactly the expected type and the src type is a
304     // subtype which we can't check or src is the same array as dst
305     // but not necessarily exactly of type default_type.
306     Label known_ok, halt;
307     __ mov_metadata(tmp, default_type->constant_encoding());
< prev index next >