1 /* 2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "precompiled.hpp" 27 #include "asm/assembler.hpp" 28 #include "c1/c1_LIRAssembler.hpp" 29 #include "c1/c1_MacroAssembler.hpp" 30 #include "ci/ciArrayKlass.hpp" 31 #include "oops/objArrayKlass.hpp" 32 #include "runtime/stubRoutines.hpp" 33 34 #define __ _masm-> 35 36 37 void LIR_Assembler::generic_arraycopy(Register src, Register src_pos, Register length, 38 Register dst, Register dst_pos, CodeStub *stub) { 39 assert(src == x11 && src_pos == x12, "mismatch in calling convention"); 40 // Save the arguments in case the generic arraycopy fails and we 41 // have to fall back to the JNI stub 42 arraycopy_store_args(src, src_pos, length, dst, dst_pos); 43 44 address copyfunc_addr = StubRoutines::generic_arraycopy(); 45 assert(copyfunc_addr != NULL, "generic arraycopy stub required"); 46 47 // The arguments are in java calling convention so we shift them 48 // to C convention 49 assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); 50 __ mv(c_rarg0, j_rarg0); 51 assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4); 52 __ mv(c_rarg1, j_rarg1); 53 assert_different_registers(c_rarg2, j_rarg3, j_rarg4); 54 __ mv(c_rarg2, j_rarg2); 55 assert_different_registers(c_rarg3, j_rarg4); 56 __ mv(c_rarg3, j_rarg3); 57 __ mv(c_rarg4, j_rarg4); 58 #ifndef PRODUCT 59 if (PrintC1Statistics) { 60 __ add_memory_int32(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt), 1); 61 } 62 #endif 63 __ far_call(RuntimeAddress(copyfunc_addr)); 64 __ beqz(x10, *stub->continuation()); 65 // Reload values from the stack so they are where the stub 66 // expects them. 67 arraycopy_load_args(src, src_pos, length, dst, dst_pos); 68 69 // x10 is -1^K where K == partial copied count 70 __ xori(t0, x10, -1); 71 // adjust length down and src/end pos up by partial copied count 72 __ subw(length, length, t0); 73 __ addw(src_pos, src_pos, t0); 74 __ addw(dst_pos, dst_pos, t0); 75 __ j(*stub->entry()); 76 77 __ bind(*stub->continuation()); 78 } 79 80 void LIR_Assembler::arraycopy_simple_check(Register src, Register src_pos, Register length, 81 Register dst, Register dst_pos, Register tmp, 82 CodeStub *stub, int flags) { 83 // test for NULL 84 if (flags & LIR_OpArrayCopy::src_null_check) { 85 __ beqz(src, *stub->entry(), /* is_far */ true); 86 } 87 if (flags & LIR_OpArrayCopy::dst_null_check) { 88 __ beqz(dst, *stub->entry(), /* is_far */ true); 89 } 90 91 // If the compiler was not able to prove that exact type of the source or the destination 92 // of the arraycopy is an array type, check at runtime if the source or the destination is 93 // an instance type. 94 if (flags & LIR_OpArrayCopy::type_check) { 95 if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) { 96 __ load_klass(tmp, dst); 97 __ lw(t0, Address(tmp, in_bytes(Klass::layout_helper_offset()))); 98 __ li(t1, Klass::_lh_neutral_value); 99 __ bge(t0, t1, *stub->entry(), /* is_far */ true); 100 } 101 102 if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) { 103 __ load_klass(tmp, src); 104 __ lw(t0, Address(tmp, in_bytes(Klass::layout_helper_offset()))); 105 __ li(t1, Klass::_lh_neutral_value); 106 __ bge(t0, t1, *stub->entry(), /* is_far */ true); 107 } 108 } 109 110 // check if negative 111 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { 112 __ bltz(src_pos, *stub->entry(), /* is_far */ true); 113 } 114 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { 115 __ bltz(dst_pos, *stub->entry(), /* is_far */ true); 116 } 117 if (flags & LIR_OpArrayCopy::length_positive_check) { 118 __ bltz(length, *stub->entry(), /* is_far */ true); 119 } 120 121 if (flags & LIR_OpArrayCopy::src_range_check) { 122 __ addw(tmp, src_pos, length); 123 __ lwu(t0, Address(src, arrayOopDesc::length_offset_in_bytes())); 124 __ bgtu(tmp, t0, *stub->entry(), /* is_far */ true); 125 } 126 if (flags & LIR_OpArrayCopy::dst_range_check) { 127 __ addw(tmp, dst_pos, length); 128 __ lwu(t0, Address(dst, arrayOopDesc::length_offset_in_bytes())); 129 __ bgtu(tmp, t0, *stub->entry(), /* is_far */ true); 130 } 131 } 132 133 void LIR_Assembler::arraycopy_checkcast(Register src, Register src_pos, Register length, 134 Register dst, Register dst_pos, Register tmp, 135 CodeStub *stub, BasicType basic_type, 136 address copyfunc_addr, int flags) { 137 // src is not a sub class of dst so we have to do a 138 // per-element check. 139 int mask = LIR_OpArrayCopy::src_objarray | LIR_OpArrayCopy::dst_objarray; 140 if ((flags & mask) != mask) { 141 // Check that at least both of them object arrays. 142 assert(flags & mask, "one of the two should be known to be an object array"); 143 144 if (!(flags & LIR_OpArrayCopy::src_objarray)) { 145 __ load_klass(tmp, src); 146 } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) { 147 __ load_klass(tmp, dst); 148 } 149 int lh_offset = in_bytes(Klass::layout_helper_offset()); 150 Address klass_lh_addr(tmp, lh_offset); 151 jint objArray_lh = Klass::array_layout_helper(T_OBJECT); 152 __ lw(t0, klass_lh_addr); 153 __ mvw(t1, objArray_lh); 154 __ bne(t0, t1, *stub->entry(), /* is_far */ true); 155 } 156 157 // Spill because stubs can use any register they like and it's 158 // easier to restore just those that we care about. 159 arraycopy_store_args(src, src_pos, length, dst, dst_pos); 160 arraycopy_checkcast_prepare_params(src, src_pos, length, dst, dst_pos, basic_type); 161 __ far_call(RuntimeAddress(copyfunc_addr)); 162 163 #ifndef PRODUCT 164 if (PrintC1Statistics) { 165 Label failed; 166 __ bnez(x10, failed); 167 __ add_memory_int32(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_cnt), 1); 168 __ bind(failed); 169 } 170 #endif 171 172 __ beqz(x10, *stub->continuation()); 173 174 #ifndef PRODUCT 175 if (PrintC1Statistics) { 176 __ add_memory_int32(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_attempt_cnt), 1); 177 } 178 #endif 179 assert_different_registers(dst, dst_pos, length, src_pos, src, x10, t0); 180 181 // Restore previously spilled arguments 182 arraycopy_load_args(src, src_pos, length, dst, dst_pos); 183 184 // return value is -1^K where K is partial copied count 185 __ xori(t0, x10, -1); 186 // adjust length down and src/end pos up by partial copied count 187 __ subw(length, length, t0); 188 __ addw(src_pos, src_pos, t0); 189 __ addw(dst_pos, dst_pos, t0); 190 } 191 192 void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Register length, 193 Register dst, Register dst_pos, Register tmp, 194 CodeStub *stub, BasicType basic_type, int flags) { 195 // We don't know the array types are compatible 196 if (basic_type != T_OBJECT) { 197 // Simple test for basic type arrays 198 if (UseCompressedClassPointers) { 199 __ lwu(tmp, Address(src, oopDesc::klass_offset_in_bytes())); 200 __ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes())); 201 } else { 202 __ ld(tmp, Address(src, oopDesc::klass_offset_in_bytes())); 203 __ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes())); 204 } 205 __ bne(tmp, t0, *stub->entry(), /* is_far */ true); 206 } else { 207 // For object arrays, if src is a sub class of dst then we can 208 // safely do the copy. 209 Label cont, slow; 210 211 #define PUSH(r1, r2) \ 212 __ addi(sp, sp, -2 * wordSize); \ 213 __ sd(r1, Address(sp, 1 * wordSize)); \ 214 __ sd(r2, Address(sp, 0)); 215 216 #define POP(r1, r2) \ 217 __ ld(r1, Address(sp, 1 * wordSize)); \ 218 __ ld(r2, Address(sp, 0)); \ 219 __ addi(sp, sp, 2 * wordSize); 220 221 PUSH(src, dst); 222 __ load_klass(src, src); 223 __ load_klass(dst, dst); 224 __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL); 225 226 PUSH(src, dst); 227 __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 228 POP(src, dst); 229 __ bnez(dst, cont); 230 231 __ bind(slow); 232 POP(src, dst); 233 234 address copyfunc_addr = StubRoutines::checkcast_arraycopy(); 235 if (copyfunc_addr != NULL) { // use stub if available 236 arraycopy_checkcast(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, copyfunc_addr, flags); 237 } 238 239 __ j(*stub->entry()); 240 __ bind(cont); 241 POP(src, dst); 242 } 243 } 244 245 void LIR_Assembler::arraycopy_assert(Register src, Register dst, Register tmp, ciArrayKlass *default_type, int flags) { 246 assert(default_type != NULL, "NULL default_type!"); 247 BasicType basic_type = default_type->element_type()->basic_type(); 248 249 if (basic_type == T_ARRAY) { basic_type = T_OBJECT; } 250 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { 251 // Sanity check the known type with the incoming class. For the 252 // primitive case the types must match exactly with src.klass and 253 // dst.klass each exactly matching the default type. For the 254 // object array case, if no type check is needed then either the 255 // dst type is exactly the expected type and the src type is a 256 // subtype which we can't check or src is the same array as dst 257 // but not necessarily exactly of type default_type. 258 Label known_ok, halt; 259 __ mov_metadata(tmp, default_type->constant_encoding()); 260 if (UseCompressedClassPointers) { 261 __ encode_klass_not_null(tmp); 262 } 263 264 if (basic_type != T_OBJECT) { 265 if (UseCompressedClassPointers) { 266 __ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes())); 267 } else { 268 __ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes())); 269 } 270 __ bne(tmp, t0, halt); 271 if (UseCompressedClassPointers) { 272 __ lwu(t0, Address(src, oopDesc::klass_offset_in_bytes())); 273 } else { 274 __ ld(t0, Address(src, oopDesc::klass_offset_in_bytes())); 275 } 276 __ beq(tmp, t0, known_ok); 277 } else { 278 if (UseCompressedClassPointers) { 279 __ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes())); 280 } else { 281 __ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes())); 282 } 283 __ beq(tmp, t0, known_ok); 284 __ beq(src, dst, known_ok); 285 } 286 __ bind(halt); 287 __ stop("incorrect type information in arraycopy"); 288 __ bind(known_ok); 289 } 290 } 291 292 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { 293 ciArrayKlass *default_type = op->expected_type(); 294 Register src = op->src()->as_register(); 295 Register dst = op->dst()->as_register(); 296 Register src_pos = op->src_pos()->as_register(); 297 Register dst_pos = op->dst_pos()->as_register(); 298 Register length = op->length()->as_register(); 299 Register tmp = op->tmp()->as_register(); 300 301 CodeStub* stub = op->stub(); 302 int flags = op->flags(); 303 BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; 304 if (is_reference_type(basic_type)) { basic_type = T_OBJECT; } 305 306 // if we don't know anything, just go through the generic arraycopy 307 if (default_type == NULL) { 308 generic_arraycopy(src, src_pos, length, dst, dst_pos, stub); 309 return; 310 } 311 312 assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), 313 "must be true at this point"); 314 315 arraycopy_simple_check(src, src_pos, length, dst, dst_pos, tmp, stub, flags); 316 317 if (flags & LIR_OpArrayCopy::type_check) { 318 arraycopy_type_check(src, src_pos, length, dst, dst_pos, tmp, stub, basic_type, flags); 319 } 320 321 #ifdef ASSERT 322 arraycopy_assert(src, dst, tmp, default_type, flags); 323 #endif 324 325 #ifndef PRODUCT 326 if (PrintC1Statistics) { 327 __ add_memory_int32(ExternalAddress(Runtime1::arraycopy_count_address(basic_type)), 1); 328 } 329 #endif 330 arraycopy_prepare_params(src, src_pos, length, dst, dst_pos, basic_type); 331 332 bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0; 333 bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0; 334 const char *name = NULL; 335 address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false); 336 337 CodeBlob *cb = CodeCache::find_blob(entry); 338 if (cb != NULL) { 339 __ far_call(RuntimeAddress(entry)); 340 } else { 341 const int args_num = 3; 342 __ call_VM_leaf(entry, args_num); 343 } 344 345 __ bind(*stub->continuation()); 346 } 347 348 349 void LIR_Assembler::arraycopy_prepare_params(Register src, Register src_pos, Register length, 350 Register dst, Register dst_pos, BasicType basic_type) { 351 int scale = array_element_size(basic_type); 352 __ shadd(c_rarg0, src_pos, src, t0, scale); 353 __ add(c_rarg0, c_rarg0, arrayOopDesc::base_offset_in_bytes(basic_type)); 354 assert_different_registers(c_rarg0, dst, dst_pos, length); 355 __ shadd(c_rarg1, dst_pos, dst, t0, scale); 356 __ add(c_rarg1, c_rarg1, arrayOopDesc::base_offset_in_bytes(basic_type)); 357 assert_different_registers(c_rarg1, dst, length); 358 __ mv(c_rarg2, length); 359 assert_different_registers(c_rarg2, dst); 360 } 361 362 void LIR_Assembler::arraycopy_checkcast_prepare_params(Register src, Register src_pos, Register length, 363 Register dst, Register dst_pos, BasicType basic_type) { 364 arraycopy_prepare_params(src, src_pos, length, dst, dst_pos, basic_type); 365 __ load_klass(c_rarg4, dst); 366 __ ld(c_rarg4, Address(c_rarg4, ObjArrayKlass::element_klass_offset())); 367 __ lwu(c_rarg3, Address(c_rarg4, Klass::super_check_offset_offset())); 368 } 369 370 void LIR_Assembler::arraycopy_store_args(Register src, Register src_pos, Register length, 371 Register dst, Register dst_pos) { 372 __ sd(dst_pos, Address(sp, 0)); // 0: dst_pos sp offset 373 __ sd(dst, Address(sp, 1 * BytesPerWord)); // 1: dst sp offset 374 __ sd(length, Address(sp, 2 * BytesPerWord)); // 2: length sp offset 375 __ sd(src_pos, Address(sp, 3 * BytesPerWord)); // 3: src_pos sp offset 376 __ sd(src, Address(sp, 4 * BytesPerWord)); // 4: src sp offset 377 } 378 379 void LIR_Assembler::arraycopy_load_args(Register src, Register src_pos, Register length, 380 Register dst, Register dst_pos) { 381 __ ld(dst_pos, Address(sp, 0)); // 0: dst_pos sp offset 382 __ ld(dst, Address(sp, 1 * BytesPerWord)); // 1: dst sp offset 383 __ ld(length, Address(sp, 2 * BytesPerWord)); // 2: length sp offset 384 __ ld(src_pos, Address(sp, 3 * BytesPerWord)); // 3: src_pos sp offset 385 __ ld(src, Address(sp, 4 * BytesPerWord)); // 4: src sp offset 386 } 387 388 #undef __