--- old/src/hotspot/share/prims/jni.cpp 2019-10-24 11:07:44.000000000 -0400 +++ new/src/hotspot/share/prims/jni.cpp 2019-10-24 11:07:43.000000000 -0400 @@ -1228,13 +1228,26 @@ jobject obj = NULL; DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj); - instanceOop i = alloc_object(clazz, CHECK_NULL); - obj = JNIHandles::make_local(env, i); - JavaValue jvalue(T_VOID); - JNI_ArgumentPusherArray ap(methodID, args); - jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); + Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); + if (k == NULL) { + ResourceMark rm(THREAD); + THROW_(vmSymbols::java_lang_InstantiationException(), NULL); + } + + if (!k->is_value()) { + instanceOop i = alloc_object(clazz, CHECK_NULL); + obj = JNIHandles::make_local(env, i); + JavaValue jvalue(T_VOID); + JNI_ArgumentPusherArray ap(methodID, args); + jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); + } else { + JavaValue jvalue(T_VALUETYPE); + JNI_ArgumentPusherArray ap(methodID, args); + jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL); + obj = jvalue.get_jobject(); + } return obj; -JNI_END + JNI_END DT_RETURN_MARK_DECL(NewObjectV, jobject @@ -1248,11 +1261,24 @@ jobject obj = NULL; DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj); - instanceOop i = alloc_object(clazz, CHECK_NULL); - obj = JNIHandles::make_local(env, i); - JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(methodID, args); - jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); + Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); + if (k == NULL) { + ResourceMark rm(THREAD); + THROW_(vmSymbols::java_lang_InstantiationException(), NULL); + } + + if (!k->is_value()) { + instanceOop i = alloc_object(clazz, CHECK_NULL); + obj = JNIHandles::make_local(env, i); + JavaValue jvalue(T_VOID); + JNI_ArgumentPusherVaArg ap(methodID, args); + jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); + } else { + JavaValue jvalue(T_VALUETYPE); + JNI_ArgumentPusherVaArg ap(methodID, args); + jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL); + obj = jvalue.get_jobject(); + } return obj; JNI_END @@ -1268,14 +1294,30 @@ jobject obj = NULL; DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj); - instanceOop i = alloc_object(clazz, CHECK_NULL); - obj = JNIHandles::make_local(env, i); - va_list args; - va_start(args, methodID); - JavaValue jvalue(T_VOID); - JNI_ArgumentPusherVaArg ap(methodID, args); - jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); - va_end(args); + Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); + if (k == NULL) { + ResourceMark rm(THREAD); + THROW_(vmSymbols::java_lang_InstantiationException(), NULL); + } + + if (!k->is_value()) { + instanceOop i = alloc_object(clazz, CHECK_NULL); + obj = JNIHandles::make_local(env, i); + va_list args; + va_start(args, methodID); + JavaValue jvalue(T_VOID); + JNI_ArgumentPusherVaArg ap(methodID, args); + jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL); + va_end(args); + } else { + va_list args; + va_start(args, methodID); + JavaValue jvalue(T_VALUETYPE); + JNI_ArgumentPusherVaArg ap(methodID, args); + jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL); + va_end(args); + obj = jvalue.get_jobject(); + } return obj; JNI_END --- old/src/jdk.jdi/share/classes/com/sun/tools/jdi/JNITypeParser.java 2019-10-24 11:07:46.000000000 -0400 +++ new/src/jdk.jdi/share/classes/com/sun/tools/jdi/JNITypeParser.java 2019-10-24 11:07:45.000000000 -0400 @@ -43,6 +43,30 @@ this.signature = signature; } + static String inlineTypeNameToSignature(String signature) { + StringBuilder sb = new StringBuilder(); + int firstIndex = signature.indexOf('['); + int index = firstIndex; + while (index != -1) { + sb.append('['); + index = signature.indexOf('[', index + 1); + } + + if (signature.equals("boolean") || signature.equals("byte") + || signature.equals("char") || signature.equals("short") + || signature.equals("int") ||signature.equals("long") + || signature.equals("float") || signature.equals("double")) { + throw new IllegalArgumentException("Not an inline type signature '" + + signature + "'"); + } else { + sb.append('Q'); + sb.append(signature.replace('.', '/')); + sb.append(';'); + } + + return sb.toString(); + } + static String typeNameToSignature(String signature) { StringBuilder sb = new StringBuilder(); int firstIndex = signature.indexOf('['); --- old/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java 2019-10-24 11:07:47.000000000 -0400 +++ new/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java 2019-10-24 11:07:47.000000000 -0400 @@ -326,6 +326,14 @@ return Collections.unmodifiableList(list); } + private static boolean isReferenceArray(String signature) { + int i = signature.lastIndexOf('['); + if (i > -1 && signature.charAt(i+1) == 'L') { + return true; + } + return false; + } + public List classesByName(String className) { validateVM(); String signature = JNITypeParser.typeNameToSignature(className); @@ -335,6 +343,24 @@ } else { list = retrieveClassesBySignature(signature); } + // HACK: add second request to cover the case where className + // is the name of an inline type. This is done only if the + // first signature is either a reference type or an array + // of a reference type. + if (signature.length() > 1 && + (signature.charAt(0) == 'L' || isReferenceArray((signature)))) { + List listInlineTypes; + signature = JNITypeParser.inlineTypeNameToSignature(className); + if (retrievedAllTypes) { + listInlineTypes = findReferenceTypes(signature); + } else { + listInlineTypes = retrieveClassesBySignature(signature); + } + if (!listInlineTypes.isEmpty()) { + list.addAll(listInlineTypes); + } + } + return Collections.unmodifiableList(list); } --- old/test/jdk/com/sun/jdi/JdbInlineTypesTest.java 2019-10-24 11:07:49.000000000 -0400 +++ new/test/jdk/com/sun/jdi/JdbInlineTypesTest.java 2019-10-24 11:07:48.000000000 -0400 @@ -154,5 +154,8 @@ // Testing substitutability test execCommand(JdbCommand.print("v == v2")).shouldContain(" = true"); execCommand(JdbCommand.print("v == v3")).shouldContain(" = false"); + + // Testing inline type instance creation + execCommand(JdbCommand.print("new JdbInlineTypesTestTarg$SmallValue(42,64)")).shouldContain(" = \"[JdbInlineTypesTestTarg$SmallValue b0=42 b1=64]\""); } }