8353500: [s390x] Intrinsify Unsafe::setMemory

Reviewed-by: lucy, mdoerr
This commit is contained in:
Amit Kumar 2025-05-30 03:50:43 +00:00
parent fd51b03910
commit 20005511e3

View File

@ -1468,11 +1468,120 @@ class StubGenerator: public StubCodeGenerator {
return __ addr_at(start_off);
}
//
// Generate 'unsafe' set memory stub
// Though just as safe as the other stubs, it takes an unscaled
// size_t (# bytes) argument instead of an element count.
//
// Input:
// Z_ARG1 - destination array address
// Z_ARG2 - byte count (size_t)
// Z_ARG3 - byte value
//
address generate_unsafe_setmemory(address unsafe_byte_fill) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, StubGenStubId::unsafe_setmemory_id);
unsigned int start_off = __ offset();
// bump this on entry, not on exit:
// inc_counter_np(SharedRuntime::_unsafe_set_memory_ctr);
const Register dest = Z_ARG1;
const Register size = Z_ARG2;
const Register byteVal = Z_ARG3;
NearLabel tail, finished;
// fill_to_memory_atomic(unsigned char*, unsigned long, unsigned char)
// Mark remaining code as such which performs Unsafe accesses.
UnsafeMemoryAccessMark umam(this, true, false);
__ z_vlvgb(Z_V0, byteVal, 0);
__ z_vrepb(Z_V0, Z_V0, 0);
__ z_aghi(size, -32);
__ z_brl(tail);
{
NearLabel again;
__ bind(again);
__ z_vst(Z_V0, Address(dest, 0));
__ z_vst(Z_V0, Address(dest, 16));
__ z_aghi(dest, 32);
__ z_aghi(size, -32);
__ z_brnl(again);
}
__ bind(tail);
{
NearLabel dont;
__ testbit(size, 4);
__ z_brz(dont);
__ z_vst(Z_V0, Address(dest, 0));
__ z_aghi(dest, 16);
__ bind(dont);
}
{
NearLabel dont;
__ testbit(size, 3);
__ z_brz(dont);
__ z_vsteg(Z_V0, 0, Z_R0, dest, 0);
__ z_aghi(dest, 8);
__ bind(dont);
}
__ z_tmll(size, 7);
__ z_brc(Assembler::bcondAllZero, finished);
{
NearLabel dont;
__ testbit(size, 2);
__ z_brz(dont);
__ z_vstef(Z_V0, 0, Z_R0, dest, 0);
__ z_aghi(dest, 4);
__ bind(dont);
}
{
NearLabel dont;
__ testbit(size, 1);
__ z_brz(dont);
__ z_vsteh(Z_V0, 0, Z_R0, dest, 0);
__ z_aghi(dest, 2);
__ bind(dont);
}
{
NearLabel dont;
__ testbit(size, 0);
__ z_brz(dont);
__ z_vsteb(Z_V0, 0, Z_R0, dest, 0);
__ bind(dont);
}
__ bind(finished);
__ z_br(Z_R14);
return __ addr_at(start_off);
}
// This is common errorexit stub for UnsafeMemoryAccess.
address generate_unsafecopy_common_error_exit() {
unsigned int start_off = __ offset();
__ z_lghi(Z_RET, 0); // return 0
__ z_br(Z_R14);
return __ addr_at(start_off);
}
void generate_arraycopy_stubs() {
// Note: the disjoint stubs must be generated first, some of
// the conjoint stubs use them.
address ucm_common_error_exit = generate_unsafecopy_common_error_exit();
UnsafeMemoryAccess::set_common_exit_stub_pc(ucm_common_error_exit);
StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jbyte_disjoint_arraycopy_id);
StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_nonoop_copy(StubGenStubId::jshort_disjoint_arraycopy_id);
StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jint_disjoint_arraycopy_id);
@ -1500,6 +1609,12 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::arrayof_jlong_arraycopy_id);
StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_id);
StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_uninit_id);
#ifdef COMPILER2
StubRoutines::_unsafe_setmemory =
VM_Version::has_VectorFacility() ? generate_unsafe_setmemory(StubRoutines::_jbyte_fill) : nullptr;
#endif // COMPILER2
}
// Call interface for AES_encryptBlock, AES_decryptBlock stubs.
@ -3184,6 +3299,10 @@ class StubGenerator: public StubCodeGenerator {
//----------------------------------------------------------------------
// Entry points that are platform specific.
if (UnsafeMemoryAccess::_table == nullptr) {
UnsafeMemoryAccess::create_table(4); // 4 for setMemory
}
if (UseCRC32Intrinsics) {
StubRoutines::_crc_table_adr = (address)StubRoutines::zarch::_crc_table;
StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes();