8381554: RISC-V: Small refactoring for cmp_klass_compressed macro-assembler routine

Reviewed-by: fyang, gcao, wenanjian
This commit is contained in:
Dingli Zhang 2026-04-03 06:15:19 +00:00
parent 4bb7204fa9
commit f8ca6f6f09
4 changed files with 49 additions and 40 deletions

View File

@ -240,35 +240,6 @@ void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Registe
}
}
void LIR_Assembler::arraycopy_assert(Register src, Register dst, Register tmp, ciArrayKlass *default_type, int flags) {
assert(default_type != nullptr, "null default_type!");
BasicType basic_type = default_type->element_type()->basic_type();
if (basic_type == T_ARRAY) { basic_type = T_OBJECT; }
if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
// Sanity check the known type with the incoming class. For the
// primitive case the types must match exactly with src.klass and
// dst.klass each exactly matching the default type. For the
// object array case, if no type check is needed then either the
// dst type is exactly the expected type and the src type is a
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
__ mov_metadata(tmp, default_type->constant_encoding());
__ encode_klass_not_null(tmp);
if (basic_type != T_OBJECT) {
__ cmp_klass_compressed(dst, tmp, t0, halt, false);
__ cmp_klass_compressed(src, tmp, t0, known_ok, true);
} else {
__ cmp_klass_compressed(dst, tmp, t0, known_ok, true);
__ beq(src, dst, known_ok);
}
__ bind(halt);
__ stop("incorrect type information in arraycopy");
__ bind(known_ok);
}
}
void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
ciArrayKlass *default_type = op->expected_type();
Register src = op->src()->as_register();
@ -299,7 +270,28 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
}
#ifdef ASSERT
arraycopy_assert(src, dst, tmp, default_type, flags);
if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
// Sanity check the known type with the incoming class. For the
// primitive case the types must match exactly with src.klass and
// dst.klass each exactly matching the default type. For the
// object array case, if no type check is needed then either the
// dst type is exactly the expected type and the src type is a
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
__ mov_metadata(tmp, default_type->constant_encoding());
if (basic_type != T_OBJECT) {
__ cmp_klass_bne(dst, tmp, t0, t1, halt);
__ cmp_klass_beq(src, tmp, t0, t1, known_ok);
} else {
__ cmp_klass_beq(dst, tmp, t0, t1, known_ok);
__ beq(src, dst, known_ok);
}
__ bind(halt);
__ stop("incorrect type information in arraycopy");
__ bind(known_ok);
}
#endif
#ifndef PRODUCT

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -39,7 +39,6 @@
void arraycopy_type_check(Register src, Register src_pos, Register length,
Register dst, Register dst_pos, Register tmp,
CodeStub *stub, BasicType basic_type, int flags);
void arraycopy_assert(Register src, Register dst, Register tmp, ciArrayKlass *default_type, int flags);
void arraycopy_prepare_params(Register src, Register src_pos, Register length,
Register dst, Register dst_pos, BasicType basic_type);
void arraycopy_checkcast_prepare_params(Register src, Register src_pos, Register length,

View File

@ -3511,17 +3511,30 @@ void MacroAssembler::orptr(Address adr, RegisterOrConstant src, Register tmp1, R
sd(tmp1, adr);
}
void MacroAssembler::cmp_klass_compressed(Register oop, Register trial_klass, Register tmp, Label &L, bool equal) {
void MacroAssembler::cmp_klass_beq(Register obj, Register klass,
Register tmp1, Register tmp2,
Label &L, bool is_far) {
assert_different_registers(obj, klass, tmp1, tmp2);
if (UseCompactObjectHeaders) {
load_narrow_klass_compact(tmp, oop);
load_narrow_klass_compact(tmp1, obj);
} else {
lwu(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
lwu(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
}
if (equal) {
beq(trial_klass, tmp, L);
decode_klass_not_null(tmp1, tmp2);
beq(klass, tmp1, L, is_far);
}
void MacroAssembler::cmp_klass_bne(Register obj, Register klass,
Register tmp1, Register tmp2,
Label &L, bool is_far) {
assert_different_registers(obj, klass, tmp1, tmp2);
if (UseCompactObjectHeaders) {
load_narrow_klass_compact(tmp1, obj);
} else {
bne(trial_klass, tmp, L);
lwu(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
}
decode_klass_not_null(tmp1, tmp2);
bne(klass, tmp1, L, is_far);
}
// Move an oop into a register.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2024, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -198,7 +198,12 @@ class MacroAssembler: public Assembler {
void load_klass(Register dst, Register src, Register tmp = t0);
void load_narrow_klass_compact(Register dst, Register src);
void store_klass(Register dst, Register src, Register tmp = t0);
void cmp_klass_compressed(Register oop, Register trial_klass, Register tmp, Label &L, bool equal);
void cmp_klass_beq(Register obj, Register klass,
Register tmp1, Register tmp2,
Label &L, bool is_far = false);
void cmp_klass_bne(Register obj, Register klass,
Register tmp1, Register tmp2,
Label &L, bool is_far = false);
void encode_klass_not_null(Register r, Register tmp = t0);
void decode_klass_not_null(Register r, Register tmp = t0);