From 4709e337f1f5ece5d75448264b9d1c0508bc7b8a Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 9 Jul 2025 17:54:36 +0000 Subject: [PATCH] Remove ensure_objArray and copying code and write a test. --- src/hotspot/share/memory/oopFactory.cpp | 17 ---- src/hotspot/share/memory/oopFactory.hpp | 4 - src/hotspot/share/prims/jvm.cpp | 7 +- .../inlinetypes/DirectMethodTest.java | 92 +++++++++++++++++++ 4 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/valhalla/inlinetypes/DirectMethodTest.java diff --git a/src/hotspot/share/memory/oopFactory.cpp b/src/hotspot/share/memory/oopFactory.cpp index fccb9a44185..d71473072f2 100644 --- a/src/hotspot/share/memory/oopFactory.cpp +++ b/src/hotspot/share/memory/oopFactory.cpp @@ -147,23 +147,6 @@ flatArrayOop oopFactory::new_flatArray(Klass* k, int length, LayoutKind lk, TRAP return oop; } -objArrayHandle oopFactory::copy_flatArray_to_objArray(flatArrayHandle array, TRAPS) { - int len = array->length(); - FlatArrayKlass* vak = FlatArrayKlass::cast(array->klass()); - objArrayOop oarray = new_objectArray(array->length(), CHECK_(objArrayHandle())); - objArrayHandle oarrayh(THREAD, oarray); - vak->copy_array(array(), 0, oarrayh(), 0, len, CHECK_(objArrayHandle())); - return oarrayh; -} - -objArrayHandle oopFactory::ensure_objArray(oop array, TRAPS) { - if (array != nullptr && array->is_flatArray()) { - return copy_flatArray_to_objArray(flatArrayHandle(THREAD, flatArrayOop(array)), THREAD); - } else { - return objArrayHandle(THREAD, objArrayOop(array)); - } -} - objArrayHandle oopFactory::new_objArray_handle(Klass* klass, int length, TRAPS) { objArrayOop obj = new_objArray(klass, length, CHECK_(objArrayHandle())); return objArrayHandle(THREAD, obj); diff --git a/src/hotspot/share/memory/oopFactory.hpp b/src/hotspot/share/memory/oopFactory.hpp index 7676f1016f3..643555baee3 100644 --- a/src/hotspot/share/memory/oopFactory.hpp +++ b/src/hotspot/share/memory/oopFactory.hpp @@ -66,10 +66,6 @@ class oopFactory: AllStatic { static flatArrayOop new_flatArray(Klass* klass, int length, LayoutKind lk, TRAPS); static objArrayOop new_null_free_objArray(Klass* klass, int length, TRAPS); - // Helper conversions from value to obj array... - static objArrayHandle copy_flatArray_to_objArray(flatArrayHandle array, TRAPS); - static objArrayHandle ensure_objArray(oop array, TRAPS); // copy into new objArray if not already an objArray - // Helper that returns a Handle static objArrayHandle new_objArray_handle(Klass* klass, int length, TRAPS); }; diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 85787087a46..0a3d7eaac21 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -3526,7 +3526,9 @@ JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jo if (thread->stack_overflow_state()->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) { method_handle = Handle(THREAD, JNIHandles::resolve(method)); Handle receiver(THREAD, JNIHandles::resolve(obj)); - objArrayHandle args = oopFactory::ensure_objArray(JNIHandles::resolve(args0), CHECK_NULL); + objArrayHandle args(THREAD, (objArrayOop)JNIHandles::resolve(args0)); + assert(args() == nullptr || !args->is_flatArray(), "args are never flat or are they???"); + oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL); jobject res = JNIHandles::make_local(THREAD, result); if (JvmtiExport::should_post_vm_object_alloc()) { @@ -3546,7 +3548,8 @@ JVM_END JVM_ENTRY(jobject, JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0)) - objArrayHandle args = oopFactory::ensure_objArray(JNIHandles::resolve(args0), CHECK_NULL); + objArrayHandle args(THREAD, (objArrayOop)JNIHandles::resolve(args0)); + assert(args() == nullptr || !args->is_flatArray(), "args are never flat or are they???"); oop constructor_mirror = JNIHandles::resolve(c); oop result = Reflection::invoke_constructor(constructor_mirror, args, CHECK_NULL); jobject res = JNIHandles::make_local(THREAD, result); diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/DirectMethodTest.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/DirectMethodTest.java new file mode 100644 index 00000000000..c47460238c7 --- /dev/null +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/DirectMethodTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test DirectMethodTest + * @summary Test arguments to JVM_InvokeMethod not flattened into an args array. + * @requires vm.flagless + * @modules java.base/jdk.internal.value + * java.base/jdk.internal.vm.annotation + * java.base/jdk.internal.misc + * @library /test/lib + * @enablePreview + * @compile --source 25 DirectMethodTest.java + * @run main/othervm -Djdk.reflect.useNativeAccessorOnly=true -XX:+UseArrayFlattening -XX:+UseFieldFlattening -XX:+UseAtomicValueFlattening -XX:+UseNullableValueFlattening DirectMethodTest + * @run main/othervm -Djdk.reflect.useNativeAccessorOnly=true -XX:-UseArrayFlattening -XX:+UseAtomicValueFlattening -XX:+UseNullableValueFlattening DirectMethodTest + + */ + +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import jdk.internal.value.ValueClass; + +public class DirectMethodTest { + + public int method1(int i, int j, int k) { + System.out.println("i = " + i + " j = " + j + " k = " + k); + return i + j * k; + } + + public static void printFlat(Object[] array) { + if (!ValueClass.isFlatArray(array)) { + System.out.println("not flat " + array); + } else { + System.out.println("yay flat " + array); + } + } + + static value class SmallValue { + byte b; + short s; + + SmallValue(short i) { b = 0; s = i; } + } + + public int method2(SmallValue i, SmallValue j, SmallValue k) { + System.out.println("i = " + i + " j = " + j + " k = " + k); + return i.s + j.s * k.s; + } + + static final int ARRAY_SIZE = 3; + + public static void main(java.lang.String[] unused) throws Exception { + DirectMethodTest d = new DirectMethodTest(); + + Method m = DirectMethodTest.class.getMethod("method1", int.class, int.class, int.class); + Integer[] intarray = new Integer[]{1, 2, 3}; // is this flattened? + printFlat(intarray); + Object[] array = (Object[])Array.newInstance(Integer.class, 3); + printFlat(array); + array = ValueClass.newNullableAtomicArray(Integer.class, ARRAY_SIZE); + printFlat(array); + System.out.println("value is " + m.invoke(d, 1, 2, 3)); + + Method m2 = DirectMethodTest.class.getMethod("method2", SmallValue.class, SmallValue.class, SmallValue.class); + Object[] smallValueArray = (Object[])Array.newInstance(SmallValue.class, ARRAY_SIZE); + printFlat(smallValueArray); + smallValueArray = ValueClass.newNullableAtomicArray(SmallValue.class, ARRAY_SIZE); + printFlat(smallValueArray); + System.out.println("value is " + m2.invoke(d, new SmallValue((short)1), new SmallValue((short)2), new SmallValue((short)3))); + } +} +