8331935: Add support for primitive array C1 clone intrinsic in PPC

Reviewed-by: mdoerr, amitkumar
This commit is contained in:
Varada M 2024-06-07 08:24:15 +00:00 committed by Amit Kumar
parent a2030fff98
commit 6968770b1e
6 changed files with 60 additions and 36 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1827,18 +1827,17 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
int flags = op->flags();
ciArrayKlass* default_type = op->expected_type();
BasicType basic_type = default_type != nullptr ? default_type->element_type()->basic_type() : T_ILLEGAL;
BasicType basic_type = (default_type != nullptr) ? default_type->element_type()->basic_type() : T_ILLEGAL;
if (basic_type == T_ARRAY) basic_type = T_OBJECT;
// Set up the arraycopy stub information.
ArrayCopyStub* stub = op->stub();
const int frame_resize = frame::native_abi_reg_args_size - sizeof(frame::java_abi); // C calls need larger frame.
// Always do stub if no type information is available. It's ok if
// the known type isn't loaded since the code sanity checks
// in debug mode and the type isn't required when we know the exact type
// also check that the type is an array type.
if (op->expected_type() == nullptr) {
if (default_type == nullptr) {
assert(src->is_nonvolatile() && src_pos->is_nonvolatile() && dst->is_nonvolatile() && dst_pos->is_nonvolatile() &&
length->is_nonvolatile(), "must preserve");
address copyfunc_addr = StubRoutines::generic_arraycopy();
@ -1873,7 +1872,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
return;
}
assert(default_type != nullptr && default_type->is_array_klass(), "must be true at this point");
assert(default_type != nullptr && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point");
Label cont, slow, copyfunc;
bool simple_check_flag_set = flags & (LIR_OpArrayCopy::src_null_check |
@ -1968,7 +1967,11 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
int shift = shift_amount(basic_type);
if (!(flags & LIR_OpArrayCopy::type_check)) {
__ b(cont);
if (stub != nullptr) {
__ b(cont);
__ bind(slow);
__ b(*stub->entry());
}
} else {
// We don't know the array types are compatible.
if (basic_type != T_OBJECT) {
@ -2089,9 +2092,9 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ add(dst_pos, tmp, dst_pos);
}
}
__ bind(slow);
__ b(*stub->entry());
}
__ bind(slow);
__ b(*stub->entry());
__ bind(cont);
#ifdef ASSERT
@ -2104,7 +2107,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// 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;
metadata2reg(op->expected_type()->constant_encoding(), tmp);
metadata2reg(default_type->constant_encoding(), tmp);
if (UseCompressedClassPointers) {
// Tmp holds the default type. It currently comes uncompressed after the
// load of a constant, so encode it.
@ -2180,7 +2183,9 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ mr(len, length);
__ call_c_with_frame_resize(entry, /*stub does not need resized frame*/ 0);
__ bind(*stub->continuation());
if (stub != nullptr) {
__ bind(*stub->continuation());
}
}
@ -2301,7 +2306,8 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
arrayOopDesc::base_offset_in_bytes(op->type()),
type2aelembytes(op->type()),
op->klass()->as_register(),
*op->stub()->entry());
*op->stub()->entry(),
op->zero_array());
}
__ bind(*op->stub()->continuation());
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -758,7 +758,13 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
assert(x->number_of_arguments() == 5, "wrong type");
// Make all state_for calls early since they can emit code.
CodeEmitInfo* info = state_for(x, x->state());
CodeEmitInfo* info = nullptr;
if (x->state_before() != nullptr && x->state_before()->force_reexecute()) {
info = state_for(x, x->state_before());
info->set_force_reexecute();
} else {
info = state_for(x, x->state());
}
LIRItem src (x->argument_at(0), this);
LIRItem src_pos (x->argument_at(1), this);
@ -778,7 +784,9 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
int flags;
ciArrayKlass* expected_type;
arraycopy_helper(x, &flags, &expected_type);
if (x->check_flag(Instruction::OmitChecksFlag)) {
flags = 0;
}
__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),
length.result(), tmp,
expected_type, flags, info);
@ -903,7 +911,13 @@ void LIRGenerator::do_NewInstance(NewInstance* x) {
void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
// Evaluate state_for early since it may emit code.
CodeEmitInfo* info = state_for(x, x->state());
CodeEmitInfo* info = nullptr;
if (x->state_before() != nullptr && x->state_before()->force_reexecute()) {
info = state_for(x, x->state_before());
info->set_force_reexecute();
} else {
info = state_for(x, x->state());
}
LIRItem length(x->length(), this);
length.load_item();
@ -921,7 +935,7 @@ void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
__ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path, x->zero_array());
// Must prevent reordering of stores for object initialization
// with stores that publish the new object.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -310,7 +310,8 @@ void C1_MacroAssembler::allocate_array(
int base_offset_in_bytes, // elements offset in bytes
int elt_size, // element size in bytes
Register klass, // object klass
Label& slow_case // continuation point if fast allocation fails
Label& slow_case, // continuation point if fast allocation fails
bool zero_array // zero the allocated array or not
) {
assert_different_registers(obj, len, t1, t2, t3, klass);
@ -346,23 +347,25 @@ void C1_MacroAssembler::allocate_array(
try_allocate(obj, arr_size, 0, t2, t3, slow_case);
initialize_header(obj, klass, len, t2, t3);
// Initialize body.
const Register base = t2;
const Register index = t3;
addi(base, obj, base_offset_in_bytes); // compute address of first element
addi(index, arr_size, -(base_offset_in_bytes)); // compute index = number of bytes to clear
if (zero_array) {
// Initialize body.
const Register base = t2;
const Register index = t3;
addi(base, obj, base_offset_in_bytes); // compute address of first element
addi(index, arr_size, -(base_offset_in_bytes)); // compute index = number of bytes to clear
// Zero first 4 bytes, if start offset is not word aligned.
if (!is_aligned(base_offset_in_bytes, BytesPerWord)) {
assert(is_aligned(base_offset_in_bytes, BytesPerInt), "must be 4-byte aligned");
li(t1, 0);
stw(t1, 0, base);
addi(base, base, BytesPerInt);
// Note: initialize_body will align index down, no need to correct it here.
// Zero first 4 bytes, if start offset is not word aligned.
if (!is_aligned(base_offset_in_bytes, BytesPerWord)) {
assert(is_aligned(base_offset_in_bytes, BytesPerInt), "must be 4-byte aligned");
li(t1, 0);
stw(t1, 0, base);
addi(base, base, BytesPerInt);
// Note: initialize_body will align index down, no need to correct it here.
}
initialize_body(base, index);
}
initialize_body(base, index);
if (CURRENT_ENV->dtrace_alloc_probes()) {
Unimplemented();
//assert(obj == O0, "must be");

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -83,7 +83,8 @@
int base_offset_in_bytes, // elements offset in bytes
int elt_size, // element size in bytes
Register klass, // object klass
Label& slow_case // continuation point if fast allocation fails
Label& slow_case, // continuation point if fast allocation fails
bool zero_array // zero the allocated array or not
);
void null_check(Register r, Label *Lnull = nullptr);

View File

@ -235,7 +235,7 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_counterTime:
#endif
case vmIntrinsics::_getObjectSize:
#if defined(X86) || defined(AARCH64) || defined(S390) || defined(RISCV)
#if defined(X86) || defined(AARCH64) || defined(S390) || defined(RISCV) || defined(PPC64)
case vmIntrinsics::_clone:
#endif
break;

View File

@ -351,7 +351,7 @@ LIR_OpArrayCopy::LIR_OpArrayCopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_
, _tmp(tmp)
, _expected_type(expected_type)
, _flags(flags) {
#if defined(X86) || defined(AARCH64) || defined(S390) || defined(RISCV)
#if defined(X86) || defined(AARCH64) || defined(S390) || defined(RISCV) || defined(PPC64)
if (expected_type != nullptr && flags == 0) {
_stub = nullptr;
} else {