Skip to content

Commit

Permalink
8331935: Add support for primitive array C1 clone intrinsic in PPC
Browse files Browse the repository at this point in the history
Reviewed-by: mdoerr, amitkumar
  • Loading branch information
Varada M authored and offamitkumar committed Jun 7, 2024
1 parent a2030ff commit 6968770
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 37 deletions.
28 changes: 17 additions & 11 deletions src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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());
}
}


Expand Down Expand Up @@ -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());
}
Expand Down
24 changes: 19 additions & 5 deletions src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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.
Expand Down
37 changes: 20 additions & 17 deletions src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -346,22 +347,24 @@ 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

// 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.
}
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.
}

initialize_body(base, index);
initialize_body(base, index);
}

if (CURRENT_ENV->dtrace_alloc_probes()) {
Unimplemented();
Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.hpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/c1/c1_Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/c1/c1_LIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

1 comment on commit 6968770

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.