8331935: Add support for primitive array C1 clone intrinsic in PPC
Reviewed-by: mdoerr, amitkumar
This commit is contained in:
parent
a2030fff98
commit
6968770b1e
@ -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());
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user