diff a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -1,8 +1,8 @@ /* * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2025 SAP SE. All rights reserved. + * Copyright (c) 2012, 2026 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. @@ -337,12 +337,25 @@ // default: __ stw(R3_RET, 0, r_arg_result_addr); __ blr(); // return to caller // case T_OBJECT: - // case T_LONG: __ bind(ret_is_object); + if (InlineTypeReturnedAsFields) { + // Check for scalarized return value + __ cmpdi(CR0, R3_RET, 0); + __ beq(CR0, ret_is_long); + // Load pack handler address + __ untested("call stub InlineTypeReturnedAsFields"); // TODO: check return registers usage + __ andi(R12_scratch2, R3_RET, -2); + __ ld(R12_scratch2, InlineKlass::adr_members_offset(), R12_scratch2); + __ ld(R12_scratch2, InlineKlass::pack_handler_jobject_offset(), R12_scratch2); + __ mtctr(R12_scratch2); + __ bctr(); // tail call + } // else fall through + + // case T_LONG: __ bind(ret_is_long); __ std(R3_RET, 0, r_arg_result_addr); __ blr(); // return to caller // case T_FLOAT: @@ -2604,14 +2617,20 @@ __ load_const_optimized(temp, objArray_lh, R0); __ cmpw(CR0, lh, temp); __ beq(CR0, L_objArray); __ cmpd(CR5, src_klass, dst_klass); // if (src->klass() != dst->klass()) return -1; - __ cmpwi(CR6, lh, Klass::_lh_neutral_value); // if (!src->is_Array()) return -1; + __ bne(CR5, L_failed); - __ crnand(CR5, Assembler::equal, CR6, Assembler::less); - __ beq(CR5, L_failed); + // Check for flat inline type array -> return -1 + __ test_flat_array_oop(src, temp, L_failed); + + // Check for null-free (non-flat) inline type array -> handle as object array + __ test_null_free_array_oop(src, temp, L_objArray); + + __ cmpwi(CR6, lh, Klass::_lh_neutral_value); // if (!src->is_Array()) return -1; + __ bge(CR6, L_failed); // At this point, it is known to be a typeArray (array_tag 0x3). #ifdef ASSERT { Label L; jint lh_prim_tag_in_place = (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift); @@ -4799,10 +4818,11 @@ if (kind == Continuation::thaw_top) { __ clobber_nonvolatile_registers(); // Except R16_thread and R29_TOC } if (return_barrier) { + assert(!InlineTypeReturnedAsFields, "unsupported"); __ mr(nvtmp, R3_RET); __ fmr(nvftmp, F1_RET); // preserve possible return value from a method returning to the return barrier DEBUG_ONLY(__ ld_ptr(tmp1, _abi0(callers_sp), R1_SP);) __ ld_ptr(R1_SP, JavaThread::cont_entry_offset(), R16_thread); #ifdef ASSERT __ ld_ptr(tmp2, _abi0(callers_sp), R1_SP); @@ -4843,10 +4863,11 @@ __ li(R4_ARG2, kind); __ call_VM_leaf(Continuation::thaw_entry(), R16_thread, R4_ARG2); __ mr(R1_SP, R3_RET); // R3_RET contains the SP of the thawed top frame if (return_barrier) { + assert(!InlineTypeReturnedAsFields, "unsupported"); // we're now in the caller of the frame that returned to the barrier __ mr(R3_RET, nvtmp); __ fmr(F1_RET, nvftmp); // restore return value (no safepoint in the call to thaw, so even an oop return value should be OK) } else { // we're now on the yield frame (which is in an address above us b/c rsp has been pushed down) __ li(R3_RET, 0); // return 0 (success) from doYield