From 419cc4624891e5775847f8acaf92fa8c42a9719c Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Tue, 16 Jul 2024 12:48:06 +0000 Subject: [PATCH 01/19] 8335533: OutOfMemoryError: Metaspace observed again on AIX in test RedefineLeakThrowable.java after JDK-8294960 Reviewed-by: mbaesken, stuefe --- .../jvmti/RedefineClasses/RedefineLeakThrowable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineLeakThrowable.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineLeakThrowable.java index bf5105f2674..8d008e1d6aa 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineLeakThrowable.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineLeakThrowable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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 @@ -33,7 +33,7 @@ * @modules java.instrument * java.compiler * @run main RedefineClassHelper - * @run main/othervm/timeout=6000 -javaagent:redefineagent.jar -XX:MetaspaceSize=23m -XX:MaxMetaspaceSize=23m RedefineLeakThrowable + * @run main/othervm/timeout=6000 -javaagent:redefineagent.jar -XX:MetaspaceSize=25m -XX:MaxMetaspaceSize=25m RedefineLeakThrowable */ /* From c99be357c9ff3b4f7edd8673beefeab54aa4ee90 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 16 Jul 2024 15:23:55 +0000 Subject: [PATCH 02/19] 8336474: Problemlist compiler/interpreter/Test6833129 on x86_32 Reviewed-by: thartmann, stuefe --- test/hotspot/jtreg/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 76dc9f6f033..000a2908561 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -71,6 +71,8 @@ compiler/codecache/CodeCacheFullCountTest.java 8332954 generic-all compiler/vectorization/TestFloat16VectorConvChain.java 8335860 generic-all +compiler/interpreter/Test6833129.java 8335266 generic-i586 + ############################################################################# # :hotspot_gc From 88eff4c3054b7d9d6486ff418bbecca8f0388117 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 16 Jul 2024 16:11:00 +0000 Subject: [PATCH 03/19] 8336421: ciMethod() constructor should use ConditionalMutexLocker(Compile_lock) Reviewed-by: jwaters, thartmann, shade --- src/hotspot/share/ci/ciMethod.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp index 844ef0a0c03..bc95f322d0d 100644 --- a/src/hotspot/share/ci/ciMethod.cpp +++ b/src/hotspot/share/ci/ciMethod.cpp @@ -109,7 +109,8 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) : ciEnv *env = CURRENT_ENV; if (env->jvmti_can_hotswap_or_post_breakpoint()) { // 6328518 check hotswap conditions under the right lock. - MutexLocker locker(Compile_lock); + bool should_take_Compile_lock = !Compile_lock->owned_by_self(); + ConditionalMutexLocker locker(Compile_lock, should_take_Compile_lock, Mutex::_safepoint_check_flag); if (Dependencies::check_evol_method(h_m()) != nullptr) { _is_c1_compilable = false; _is_c2_compilable = false; From 59bf3d77aa96dfdc199f5a6893c76c8a379e9fba Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 16 Jul 2024 17:53:08 +0000 Subject: [PATCH 04/19] 8336080: Fix -Wzero-as-null-pointer-constant warnings in ClassLoaderStats ctor Reviewed-by: dholmes, iwalulya --- src/hotspot/share/classfile/classLoaderStats.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/classfile/classLoaderStats.hpp b/src/hotspot/share/classfile/classLoaderStats.hpp index 8296c6ee25f..4818ddff609 100644 --- a/src/hotspot/share/classfile/classLoaderStats.hpp +++ b/src/hotspot/share/classfile/classLoaderStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, 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 @@ -82,9 +82,9 @@ class ClassLoaderStats : public ResourceObj { uintx _hidden_classes_count; ClassLoaderStats() : - _cld(0), - _class_loader(0), - _parent(0), + _cld(nullptr), + _class_loader(), + _parent(), _chunk_sz(0), _block_sz(0), _classes_count(0), From a60608e7a35aeeed57bcce641d4957de1e4b4def Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Tue, 16 Jul 2024 18:10:47 +0000 Subject: [PATCH 05/19] 8334169: Long arguments of attach operation are silently truncated on Windows Reviewed-by: sspitsyn, cjplummer --- .../native/libattach/VirtualMachineImpl.c | 48 +++-- .../serviceability/attach/LongArgTest.java | 179 ++++++++++++++++++ 2 files changed, 212 insertions(+), 15 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/attach/LongArgTest.java diff --git a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c index 3e3118c327f..a8b17c22d83 100644 --- a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -54,8 +54,8 @@ typedef jint (WINAPI* EnqueueOperationFunc) static HANDLE doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); -/* convert jstring to C string */ -static void jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, int len); +/* Converts jstring to C string, returns JNI_FALSE if the string has been truncated. */ +static jboolean jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, size_t cstr_buf_size); /* @@ -75,9 +75,9 @@ typedef struct { char jvmLib[MAX_LIBNAME_LENGTH]; /* "jvm.dll" */ char func1[MAX_FUNC_LENGTH]; char func2[MAX_FUNC_LENGTH]; - char cmd[MAX_CMD_LENGTH]; /* "load", "dump", ... */ - char arg[MAX_ARGS][MAX_ARG_LENGTH]; /* arguments to command */ - char pipename[MAX_PIPE_NAME_LENGTH]; + char cmd[MAX_CMD_LENGTH + 1]; /* "load", "dump", ... */ + char arg[MAX_ARGS][MAX_ARG_LENGTH + 1]; /* arguments to command */ + char pipename[MAX_PIPE_NAME_LENGTH + 1]; } DataBlock; /* @@ -377,7 +377,6 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_readPipe return (jint)nread; } - /* * Class: sun_tools_attach_VirtualMachineImpl * Method: enqueue @@ -410,7 +409,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue /* * Command and arguments */ - jstring_to_cstring(env, cmd, data.cmd, MAX_CMD_LENGTH); + if (!jstring_to_cstring(env, cmd, data.cmd, sizeof(data.cmd))) { + JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException", + "command is too long"); + return; + } argsLen = (*env)->GetArrayLength(env, args); if (argsLen > 0) { @@ -423,7 +426,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue if (obj == NULL) { data.arg[i][0] = '\0'; } else { - jstring_to_cstring(env, obj, data.arg[i], MAX_ARG_LENGTH); + if (!jstring_to_cstring(env, obj, data.arg[i], sizeof(data.arg[i]))) { + JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException", + "argument is too long"); + return; + } } if ((*env)->ExceptionOccurred(env)) return; } @@ -433,7 +440,11 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue } /* pipe name */ - jstring_to_cstring(env, pipename, data.pipename, MAX_PIPE_NAME_LENGTH); + if (!jstring_to_cstring(env, pipename, data.pipename, sizeof(data.pipename))) { + JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException", + "pipe name is too long"); + return; + } /* * Allocate memory in target process for data and code stub @@ -615,21 +626,28 @@ doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProc return hProcess; } -/* convert jstring to C string */ -static void jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, int len) { +/* Converts jstring to C string, returns JNI_FALSE if the string has been truncated. */ +static jboolean jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, size_t cstr_buf_size) { jboolean isCopy; const char* str; + jboolean result = JNI_TRUE; if (jstr == NULL) { cstr[0] = '\0'; } else { str = JNU_GetStringPlatformChars(env, jstr, &isCopy); - if ((*env)->ExceptionOccurred(env)) return; + if ((*env)->ExceptionOccurred(env)) { + return result; + } + if (strlen(str) >= cstr_buf_size) { + result = JNI_FALSE; + } - strncpy(cstr, str, len); - cstr[len-1] = '\0'; + strncpy(cstr, str, cstr_buf_size); + cstr[cstr_buf_size - 1] = '\0'; if (isCopy) { JNU_ReleaseStringPlatformChars(env, jstr, str); } } + return result; } diff --git a/test/hotspot/jtreg/serviceability/attach/LongArgTest.java b/test/hotspot/jtreg/serviceability/attach/LongArgTest.java new file mode 100644 index 00000000000..f7d8a330a6b --- /dev/null +++ b/test/hotspot/jtreg/serviceability/attach/LongArgTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2024, 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 + * @summary Tests that long arguments of attach operation are not truncated + * @bug 8334168 + * @library /test/lib + * @modules jdk.attach/sun.tools.attach + * @run main LongArgTest + */ + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.InputStream; +import java.io.IOException; + +import com.sun.tools.attach.VirtualMachine; +import sun.tools.attach.HotSpotVirtualMachine; + +import jdk.test.lib.apps.LingeredApp; + +public class LongArgTest { + + // current restriction: max arg size is 1024 + private static int MAX_ARG_SIZE = 1024; + + public static void main(String[] args) throws Exception { + LingeredApp app = null; + try { + app = LingeredApp.startApp(); + + // sanity + test(app) + .mustSucceed() + .run(); + + test(app) + .valueLength(MAX_ARG_SIZE) + .mustSucceed() + .run(); + + test(app) + .valueLength(MAX_ARG_SIZE + 1) + .run(); + + // more than max args (3) with MAX_ARG_SIZE + test(app) + .valueLength(3 * MAX_ARG_SIZE + 1) + .run(); + + } finally { + LingeredApp.stopApp(app); + } + } + + private static Test test(LingeredApp app) { + return new Test(app); + } + + // For simplicity, the test uses internal HotSpotVirtualMachine, + // sets/gets "HeapDumpPath" flag value (string flag, not validated by JVM). + private static class Test { + private LingeredApp app; + private String flagName = "HeapDumpPath"; + private String flagValue = generateValue(5); + private boolean setFlagMustSucceed = false; + + Test(LingeredApp app) { + this.app = app; + } + + Test valueLength(int len) { + flagValue = generateValue(len); + return this; + } + + Test mustSucceed() { + setFlagMustSucceed = true; + return this; + } + + void run() throws Exception { + System.out.println("======== Start ========"); + System.out.println("Arg size = " + flagValue.length()); + + HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(String.valueOf(app.getPid())); + + if (setFlag(vm)) { + String actualValue = getFlag(vm); + + if (!flagValue.equals(actualValue)) { + String msg = "Actual value is different: "; + if (actualValue == null) { + msg += "null"; + } else if (flagValue.startsWith(actualValue)) { + msg += "truncated from " + flagValue.length() + " to " + actualValue.length(); + } else { + msg += actualValue + ", expected value: " + flagValue; + } + System.out.println(msg); + vm.detach(); + throw new RuntimeException(msg); + } else { + System.out.println("Actual value matches: " + actualValue); + } + } + + vm.detach(); + + System.out.println("======== End ========"); + System.out.println(); + } + + // Sets the flag value, return true on success. + private boolean setFlag(HotSpotVirtualMachine vm) throws Exception { + BufferedReader replyReader = null; + try { + replyReader = new BufferedReader(new InputStreamReader( + vm.setFlag(flagName, flagValue))); + } catch (IOException ex) { + if (setFlagMustSucceed) { + throw ex; + } + System.out.println("OK: setFlag() thrown exception:"); + ex.printStackTrace(System.out); + return false; + } + + String line; + while ((line = replyReader.readLine()) != null) { + System.out.println("setFlag: " + line); + } + replyReader.close(); + return true; + } + + private String getFlag(HotSpotVirtualMachine vm) throws Exception { + // Then read and make sure we get back the same value. + BufferedReader replyReader = new BufferedReader(new InputStreamReader(vm.printFlag(flagName))); + + String prefix = "-XX:" + flagName + "="; + String value = null; + String line; + while((line = replyReader.readLine()) != null) { + System.out.println("getFlag: " + line); + if (line.startsWith(prefix)) { + value = line.substring(prefix.length()); + } + } + return value; + } + + private String generateValue(int len) { + return "X" + "A".repeat(len - 2) + "X"; + } + } + +} From 005fb67e99370ef2bd15dae621a3924e1cf00124 Mon Sep 17 00:00:00 2001 From: Cesar Soares Lucas Date: Tue, 16 Jul 2024 20:47:42 +0000 Subject: [PATCH 06/19] 8331194: NPE in ArrayCreationTree.java with -XX:-UseCompressedOops Reviewed-by: kvn --- src/hotspot/share/opto/machnode.hpp | 4 + src/hotspot/share/opto/output.cpp | 26 +++++- src/hotspot/share/opto/output.hpp | 3 + ...stReduceAllocationAndNestedScalarized.java | 80 +++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndNestedScalarized.java diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 4d7b9c62aaa..6fcbabdab90 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -867,6 +867,10 @@ class MachSafePointNode : public MachReturnNode { assert(verify_jvms(jvms), "jvms must match"); return in(_jvmadj + jvms->monitor_box_offset(idx)); } + Node* scalarized_obj(const JVMState* jvms, uint idx) const { + assert(verify_jvms(jvms), "jvms must match"); + return in(_jvmadj + jvms->scloff() + idx); + } void set_local(const JVMState* jvms, uint idx, Node *c) { assert(verify_jvms(jvms), "jvms must match"); set_req(_jvmadj + jvms->locoff() + idx, c); diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 9631f40b67e..fd7d0eaf171 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -974,6 +974,27 @@ bool PhaseOutput::contains_as_owner(GrowableArray *monarray, Obje return false; } +// Determine if there is a scalar replaced object description represented by 'ov'. +bool PhaseOutput::contains_as_scalarized_obj(JVMState* jvms, MachSafePointNode* sfn, + GrowableArray* objs, + ObjectValue* ov) const { + for (int i = 0; i < jvms->scl_size(); i++) { + Node* n = sfn->scalarized_obj(jvms, i); + // Other kinds of nodes that we may encounter here, for instance constants + // representing values of fields of objects scalarized, aren't relevant for + // us, since they don't map to ObjectValue. + if (!n->is_SafePointScalarObject()) { + continue; + } + + ObjectValue* other = (ObjectValue*) sv_for_node_id(objs, n->_idx); + if (ov == other) { + return true; + } + } + return false; +} + //--------------------------Process_OopMap_Node-------------------------------- void PhaseOutput::Process_OopMap_Node(MachNode *mach, int current_offset) { // Handle special safepoint nodes for synchronization @@ -1137,7 +1158,10 @@ void PhaseOutput::Process_OopMap_Node(MachNode *mach, int current_offset) { for (int j = 0; j< merge->possible_objects()->length(); j++) { ObjectValue* ov = merge->possible_objects()->at(j)->as_ObjectValue(); - bool is_root = locarray->contains(ov) || exparray->contains(ov) || contains_as_owner(monarray, ov); + bool is_root = locarray->contains(ov) || + exparray->contains(ov) || + contains_as_owner(monarray, ov) || + contains_as_scalarized_obj(jvms, sfn, objs, ov); ov->set_root(is_root); } } diff --git a/src/hotspot/share/opto/output.hpp b/src/hotspot/share/opto/output.hpp index 9431ef3d508..503f5414dc4 100644 --- a/src/hotspot/share/opto/output.hpp +++ b/src/hotspot/share/opto/output.hpp @@ -208,6 +208,9 @@ class PhaseOutput : public Phase { bool starts_bundle(const Node *n) const; bool contains_as_owner(GrowableArray *monarray, ObjectValue *ov) const; + bool contains_as_scalarized_obj(JVMState* jvms, MachSafePointNode* sfn, + GrowableArray* objs, + ObjectValue* ov) const; // Dump formatted assembly #if defined(SUPPORT_OPTO_ASSEMBLY) diff --git a/test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndNestedScalarized.java b/test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndNestedScalarized.java new file mode 100644 index 00000000000..5916490a02c --- /dev/null +++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndNestedScalarized.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024, 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 + * @bug 8331194 + * @summary Check that Reduce Allocation Merges doesn't crash when an input + * of the Phi is not the _current_ output of the Phi but said input + * needs to be rematerialized because it's used regardless of the + * Phi output. + * @run main/othervm -XX:CompileCommand=dontinline,*TestReduceAllocationAndNestedScalarized*::test + * -XX:CompileCommand=compileonly,*TestReduceAllocationAndNestedScalarized*::test + * -XX:CompileCommand=compileonly,*Picture*::*init* + * -XX:CompileCommand=compileonly,*Point*::*init* + * -XX:CompileCommand=exclude,*Unloaded*::* + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-TieredCompilation + * -XX:-UseCompressedOops + * -Xcomp + * -server + * compiler.escapeAnalysis.TestReduceAllocationAndNestedScalarized + * @run main compiler.escapeAnalysis.TestReduceAllocationAndNestedScalarized + */ + +package compiler.escapeAnalysis; + +public class TestReduceAllocationAndNestedScalarized { + static class Picture { + public Point first; + public Point second; + } + + static class Point { + int x; + } + + static class Unloaded { + } + + static int test(boolean cond) { + Picture p = new Picture(); + p.first = new Point(); + Point p2 = p.first; + + if (cond) p2 = new Point(); + + p.second = p2; + + new Unloaded(); + + return p.first.x; + } + + public static void main(String[] args) { + Picture pic = new Picture(); + Point pnt = new Point(); + int res = test(true); + System.out.println("Result is: " + res); + } +} From f3e7063e26cefb6643e4150b7fcbdc9a1fdaebed Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Tue, 16 Jul 2024 23:27:32 +0000 Subject: [PATCH 07/19] 8336420: Add JVMTI setfldw001 and setfmodw001 tests to Xcomp problem list Reviewed-by: dcubed --- test/hotspot/jtreg/ProblemList-Xcomp.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index 9a52a731039..5617ea0efa6 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -28,6 +28,12 @@ ############################################################################# vmTestbase/nsk/jvmti/AttachOnDemand/attach020/TestDescription.java 8287324 generic-all + +vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java#id0 8205957 generic-all +vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java#logging 8205957 generic-all +vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw001/TestDescription.java#id0 8205957 generic-all +vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw001/TestDescription.java#logging 8205957 generic-all + vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8245680 windows-x64 vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64 From 69baa7d2850fafbd89978db12eec683c286eb921 Mon Sep 17 00:00:00 2001 From: Harshitha Onkar Date: Tue, 16 Jul 2024 23:46:41 +0000 Subject: [PATCH 08/19] 8336413: gtk headers : Fix typedef redeclaration of GMainContext and GdkPixbuf Reviewed-by: prr, dnguyen --- src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h | 4 +--- src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h b/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h index 4a9773d333a..8075d4f419f 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -55,13 +55,11 @@ typedef enum } GParamFlags; /* We define all structure pointers to be void* */ -typedef void GMainContext; typedef void GVfs; typedef void GdkColormap; typedef void GdkDrawable; typedef void GdkGC; -typedef void GdkPixbuf; typedef void GdkPixmap; typedef void GtkFixed; diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h index ed5997cb0cd..054510d488b 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -180,8 +180,6 @@ typedef enum _cairo_status { } cairo_status_t; /* We define all structure pointers to be void* */ -typedef void GdkPixbuf; -typedef void GMainContext; typedef void GVfs; typedef void GdkColormap; From 5f365d44be9c1f3413c9ccde970e2745090a516a Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Tue, 23 Jan 2024 08:25:53 +0000 Subject: [PATCH 09/19] 8323231: Improve array management Co-authored-by: Martin Balao Reviewed-by: iveresov, rhalade, mschoene, dlong, kvn --- src/hotspot/share/c1/c1_RangeCheckElimination.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp index 256f8190b50..c2397d4a399 100644 --- a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp +++ b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -483,14 +483,14 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList if (c) { jint value = c->type()->as_IntConstant()->value(); - if (value != min_jint) { - if (ao->op() == Bytecodes::_isub) { - value = -value; - } + if (ao->op() == Bytecodes::_iadd) { base = java_add(base, value); - last_integer = base; - last_instruction = other; + } else { + assert(ao->op() == Bytecodes::_isub, "unexpected bytecode"); + base = java_subtract(base, value); } + last_integer = base; + last_instruction = other; index = other; } else { break; From 46c37686454321011541499a79c776f774ff2b57 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Thu, 25 Jan 2024 14:47:13 +0000 Subject: [PATCH 10/19] 8320548: Improved loop handling Reviewed-by: mschoene, rhalade, thartmann, chagedorn --- src/hotspot/share/opto/superword.cpp | 42 +++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 5721f7bcd54..0e1328a4485 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -2954,27 +2954,55 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { TRACE_ALIGN_VECTOR_NODE(mask_AW); TRACE_ALIGN_VECTOR_NODE(adjust_pre_iter); - // 4: Compute (3a, b): + // 4: The computation of the new pre-loop limit could overflow (for 3a) or + // underflow (for 3b) the int range. This is problematic in combination + // with Range Check Elimination (RCE), which determines a "safe" range + // where a RangeCheck will always succeed. RCE adjusts the pre-loop limit + // such that we only enter the main-loop once we have reached the "safe" + // range, and adjusts the main-loop limit so that we exit the main-loop + // before we leave the "safe" range. After RCE, the range of the main-loop + // can only be safely narrowed, and should never be widened. Hence, the + // pre-loop limit can only be increased (for stride > 0), but an add + // overflow might decrease it, or decreased (for stride < 0), but a sub + // underflow might increase it. To prevent that, we perform the Sub / Add + // and Max / Min with long operations. + old_limit = new ConvI2LNode(old_limit); + orig_limit = new ConvI2LNode(orig_limit); + adjust_pre_iter = new ConvI2LNode(adjust_pre_iter); + phase()->register_new_node(old_limit, pre_ctrl); + phase()->register_new_node(orig_limit, pre_ctrl); + phase()->register_new_node(adjust_pre_iter, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(old_limit); + TRACE_ALIGN_VECTOR_NODE(orig_limit); + TRACE_ALIGN_VECTOR_NODE(adjust_pre_iter); + + // 5: Compute (3a, b): // new_limit = old_limit + adjust_pre_iter (stride > 0) // new_limit = old_limit - adjust_pre_iter (stride < 0) + // Node* new_limit = nullptr; if (stride < 0) { - new_limit = new SubINode(old_limit, adjust_pre_iter); + new_limit = new SubLNode(old_limit, adjust_pre_iter); } else { - new_limit = new AddINode(old_limit, adjust_pre_iter); + new_limit = new AddLNode(old_limit, adjust_pre_iter); } phase()->register_new_node(new_limit, pre_ctrl); TRACE_ALIGN_VECTOR_NODE(new_limit); - // 5: Compute (15a, b): + // 6: Compute (15a, b): // Prevent pre-loop from going past the original limit of the loop. Node* constrained_limit = - (stride > 0) ? (Node*) new MinINode(new_limit, orig_limit) - : (Node*) new MaxINode(new_limit, orig_limit); + (stride > 0) ? (Node*) new MinLNode(phase()->C, new_limit, orig_limit) + : (Node*) new MaxLNode(phase()->C, new_limit, orig_limit); + phase()->register_new_node(constrained_limit, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(constrained_limit); + + // 7: We know that the result is in the int range, there is never truncation + constrained_limit = new ConvL2INode(constrained_limit); phase()->register_new_node(constrained_limit, pre_ctrl); TRACE_ALIGN_VECTOR_NODE(constrained_limit); - // 6: Hack the pre-loop limit + // 8: Hack the pre-loop limit igvn().replace_input_of(pre_opaq, 1, constrained_limit); } From 227fc5e591da0ea7540a7f25451240401ead3495 Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Mon, 29 Jan 2024 21:40:21 +0000 Subject: [PATCH 11/19] 8314794: Improve UTF8 String supports Reviewed-by: dholmes, coleenp, rhalade --- src/hotspot/share/utilities/exceptions.cpp | 29 +++++++++++++--------- src/hotspot/share/utilities/utf8.cpp | 11 +++++--- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index 78147ea4089..c8f458dfa31 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -44,6 +44,9 @@ #include "utilities/events.hpp" #include "utilities/exceptions.hpp" +// Limit exception message components to 64K (the same max as Symbols) +#define MAX_LEN 65535 + // Implementation of ThreadShadow void check_ThreadShadow() { const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception); @@ -114,10 +117,11 @@ bool Exceptions::special_exception(JavaThread* thread, const char* file, int lin if (h_exception.is_null() && !thread->can_call_java()) { ResourceMark rm(thread); const char* exc_value = h_name != nullptr ? h_name->as_C_string() : "null"; - log_info(exceptions)("Thread cannot call Java so instead of throwing exception <%s%s%s> (" PTR_FORMAT ") \n" + log_info(exceptions)("Thread cannot call Java so instead of throwing exception <%.*s%s%.*s> (" PTR_FORMAT ") \n" "at [%s, line %d]\nfor thread " PTR_FORMAT ",\n" "throwing pre-allocated exception: %s", - exc_value, message ? ": " : "", message ? message : "", + MAX_LEN, exc_value, message ? ": " : "", + MAX_LEN, message ? message : "", p2i(h_exception()), file, line, p2i(thread), Universe::vm_exception()->print_value_string()); // We do not care what kind of exception we get for a thread which @@ -143,10 +147,11 @@ void Exceptions::_throw(JavaThread* thread, const char* file, int line, Handle h // tracing (do this up front - so it works during boot strapping) // Note, the print_value_string() argument is not called unless logging is enabled! - log_info(exceptions)("Exception <%s%s%s> (" PTR_FORMAT ") \n" + log_info(exceptions)("Exception <%.*s%s%.*s> (" PTR_FORMAT ") \n" "thrown [%s, line %d]\nfor thread " PTR_FORMAT, - h_exception->print_value_string(), - message ? ": " : "", message ? message : "", + MAX_LEN, h_exception->print_value_string(), + message ? ": " : "", + MAX_LEN, message ? message : "", p2i(h_exception()), file, line, p2i(thread)); // for AbortVMOnException flag @@ -566,13 +571,13 @@ void Exceptions::log_exception(Handle exception, const char* message) { ResourceMark rm; const char* detail_message = java_lang_Throwable::message_as_utf8(exception()); if (detail_message != nullptr) { - log_info(exceptions)("Exception <%s: %s>\n thrown in %s", - exception->print_value_string(), - detail_message, - message); + log_info(exceptions)("Exception <%.*s: %.*s>\n thrown in %.*s", + MAX_LEN, exception->print_value_string(), + MAX_LEN, detail_message, + MAX_LEN, message); } else { - log_info(exceptions)("Exception <%s>\n thrown in %s", - exception->print_value_string(), - message); + log_info(exceptions)("Exception <%.*s>\n thrown in %.*s", + MAX_LEN, exception->print_value_string(), + MAX_LEN, message); } } diff --git a/src/hotspot/share/utilities/utf8.cpp b/src/hotspot/share/utilities/utf8.cpp index d7798778b2c..6fd877120df 100644 --- a/src/hotspot/share/utilities/utf8.cpp +++ b/src/hotspot/share/utilities/utf8.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "memory/allocation.hpp" +#include "utilities/checkedCast.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/utf8.hpp" @@ -431,12 +432,16 @@ int UNICODE::utf8_size(jbyte c) { template int UNICODE::utf8_length(const T* base, int length) { - int result = 0; + size_t result = 0; for (int index = 0; index < length; index++) { T c = base[index]; - result += utf8_size(c); + int sz = utf8_size(c); + if (result + sz > INT_MAX-1) { + break; + } + result += sz; } - return result; + return checked_cast(result); } template From aea9a08bebb6555ef6f00daba24afec394dd245b Mon Sep 17 00:00:00 2001 From: David Holmes Date: Sun, 11 Feb 2024 21:54:51 +0000 Subject: [PATCH 12/19] 8319859: Better symbol storage Reviewed-by: rhalade, coleenp, matsaave, iklam --- src/hotspot/share/classfile/symbolTable.cpp | 15 ++++++++++++++- src/hotspot/share/oops/symbol.cpp | 1 + src/hotspot/share/oops/symbol.hpp | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index f680939682a..9483c6715b4 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -344,8 +344,19 @@ Symbol* SymbolTable::lookup_common(const char* name, return sym; } +// Symbols should represent entities from the constant pool that are +// limited to 64K in length, but usage errors creep in allowing Symbols +// to be used for arbitrary strings. For debug builds we will assert if +// a string is too long, whereas product builds will truncate it. Symbol* SymbolTable::new_symbol(const char* name, int len) { - assert(len <= Symbol::max_length(), "sanity"); + assert(len <= Symbol::max_length(), + "String length %d exceeds the maximum Symbol length of %d", len, Symbol::max_length()); + if (len > Symbol::max_length()) { + warning("A string \"%.80s ... %.80s\" exceeds the maximum Symbol " + "length of %d and has been truncated", name, (name + len - 80), Symbol::max_length()); + len = Symbol::max_length(); + } + unsigned int hash = hash_symbol(name, len, _alt_hash); Symbol* sym = lookup_common(name, len, hash); if (sym == nullptr) { @@ -485,6 +496,7 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa for (int i = 0; i < names_count; i++) { const char *name = names[i]; int len = lengths[i]; + assert(len <= Symbol::max_length(), "must be - these come from the constant pool"); unsigned int hash = hashValues[i]; assert(lookup_shared(name, len, hash) == nullptr, "must have checked already"); Symbol* sym = do_add_if_needed(name, len, hash, is_permanent); @@ -494,6 +506,7 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa } Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool is_permanent) { + assert(len <= Symbol::max_length(), "caller should have ensured this"); SymbolTableLookup lookup(name, len, hash); SymbolTableGet stg; bool clean_hint = false; diff --git a/src/hotspot/share/oops/symbol.cpp b/src/hotspot/share/oops/symbol.cpp index 4deae372061..8fe7c2aadbf 100644 --- a/src/hotspot/share/oops/symbol.cpp +++ b/src/hotspot/share/oops/symbol.cpp @@ -54,6 +54,7 @@ uint32_t Symbol::pack_hash_and_refcount(short hash, int refcount) { } Symbol::Symbol(const u1* name, int length, int refcount) { + assert(length <= max_length(), "SymbolTable should have caught this!"); _hash_and_refcount = pack_hash_and_refcount((short)os::random(), refcount); _length = (u2)length; // _body[0..1] are allocated in the header just by coincidence in the current diff --git a/src/hotspot/share/oops/symbol.hpp b/src/hotspot/share/oops/symbol.hpp index 3b3f1366203..045332c7a84 100644 --- a/src/hotspot/share/oops/symbol.hpp +++ b/src/hotspot/share/oops/symbol.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, 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 @@ -130,6 +130,7 @@ class Symbol : public MetaspaceObj { return (int)heap_word_size(byte_size(length)); } + // Constructor is private for use only by SymbolTable. Symbol(const u1* name, int length, int refcount); static short extract_hash(uint32_t value) { return (short)(value >> 16); } From c5a8c8a0b6d51c33679efb02514f7a44e93ad290 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Tue, 13 Feb 2024 21:15:08 +0000 Subject: [PATCH 13/19] 8325600: Better symbol storage Reviewed-by: coleenp, rhalade, matsaave --- src/hotspot/share/classfile/symbolTable.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index 9483c6715b4..ddbf180a4a1 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -345,10 +345,10 @@ Symbol* SymbolTable::lookup_common(const char* name, } // Symbols should represent entities from the constant pool that are -// limited to 64K in length, but usage errors creep in allowing Symbols +// limited to <64K in length, but usage errors creep in allowing Symbols // to be used for arbitrary strings. For debug builds we will assert if // a string is too long, whereas product builds will truncate it. -Symbol* SymbolTable::new_symbol(const char* name, int len) { +static int check_length(const char* name, int len) { assert(len <= Symbol::max_length(), "String length %d exceeds the maximum Symbol length of %d", len, Symbol::max_length()); if (len > Symbol::max_length()) { @@ -356,7 +356,11 @@ Symbol* SymbolTable::new_symbol(const char* name, int len) { "length of %d and has been truncated", name, (name + len - 80), Symbol::max_length()); len = Symbol::max_length(); } + return len; +} +Symbol* SymbolTable::new_symbol(const char* name, int len) { + len = check_length(name, len); unsigned int hash = hash_symbol(name, len, _alt_hash); Symbol* sym = lookup_common(name, len, hash); if (sym == nullptr) { @@ -555,7 +559,7 @@ Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, boo Symbol* SymbolTable::new_permanent_symbol(const char* name) { unsigned int hash = 0; - int len = (int)strlen(name); + int len = check_length(name, (int)strlen(name)); Symbol* sym = SymbolTable::lookup_only(name, len, hash); if (sym == nullptr) { sym = do_add_if_needed(name, len, hash, /* is_permanent */ true); From e636325510e882afa703752c6d37c183d111565c Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Fri, 15 Mar 2024 10:28:00 +0000 Subject: [PATCH 14/19] 8324559: Improve 2D image handling Reviewed-by: rhalade, mschoene, psadhukhan, prr --- .../share/native/libawt/java2d/loops/MaskFill.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/java.desktop/share/native/libawt/java2d/loops/MaskFill.c b/src/java.desktop/share/native/libawt/java2d/loops/MaskFill.c index 354934069c0..fe0bc406860 100644 --- a/src/java.desktop/share/native/libawt/java2d/loops/MaskFill.c +++ b/src/java.desktop/share/native/libawt/java2d/loops/MaskFill.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, 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 @@ -467,7 +467,7 @@ storePgram(EdgeInfo *pLeftEdge, EdgeInfo *pRightEdge, #define INSERT_ACCUM(pACCUM, IMIN, IMAX, X0, Y0, X1, Y1, CX1, CX2, MULT) \ do { \ jdouble xmid = ((X0) + (X1)) * 0.5; \ - if (xmid <= (CX2)) { \ + if (xmid < (CX2)) { \ jdouble sliceh = ((Y1) - (Y0)); \ jdouble slicearea; \ jint i; \ @@ -556,7 +556,7 @@ fillAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo, jint cy2 = pRasInfo->bounds.y2; jint width = cx2 - cx1; EdgeInfo edges[4]; - jfloat localaccum[MASK_BUF_LEN + 1]; + jfloat localaccum[MASK_BUF_LEN + 2]; jfloat *pAccum; if (!storePgram(edges + 0, edges + 2, @@ -568,12 +568,12 @@ fillAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo, } pAccum = ((width > MASK_BUF_LEN) - ? malloc((width + 1) * sizeof(jfloat)) + ? malloc((width + 2) * sizeof(jfloat)) : localaccum); if (pAccum == NULL) { return; } - memset(pAccum, 0, (width+1) * sizeof(jfloat)); + memset(pAccum, 0, (width + 2) * sizeof(jfloat)); while (cy1 < cy2) { jint lmin, lmax, rmin, rmax; @@ -794,7 +794,7 @@ drawAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo, jint cy2 = pRasInfo->bounds.y2; jint width = cx2 - cx1; EdgeInfo edges[8]; - jfloat localaccum[MASK_BUF_LEN + 1]; + jfloat localaccum[MASK_BUF_LEN + 2]; jfloat *pAccum; if (!storePgram(edges + 0, edges + 6, @@ -815,12 +815,12 @@ drawAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo, JNI_TRUE); pAccum = ((width > MASK_BUF_LEN) - ? malloc((width + 1) * sizeof(jfloat)) + ? malloc((width + 2) * sizeof(jfloat)) : localaccum); if (pAccum == NULL) { return; } - memset(pAccum, 0, (width+1) * sizeof(jfloat)); + memset(pAccum, 0, (width + 2) * sizeof(jfloat)); while (cy1 < cy2) { jint lmin, lmax, rmin, rmax; From 553f21ae5324029eef3c934d69be40f5d4266457 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 26 Mar 2024 11:43:35 +0000 Subject: [PATCH 15/19] 8327413: Enhance compilation efficiency Co-authored-by: Roland Westrelin Reviewed-by: ahgross, rhalade, thartmann, epeter, mbalao, fferrari --- src/hotspot/share/opto/ifnode.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index a5722c45a5e..cedbc66bbb4 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp @@ -773,6 +773,7 @@ bool IfNode::cmpi_folds(PhaseIterGVN* igvn, bool fold_ne) { bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) { return ctrl != nullptr && ctrl->is_Proj() && + ctrl->outcnt() == 1 && // No side-effects ctrl->in(0) != nullptr && ctrl->in(0)->Opcode() == Op_If && ctrl->in(0)->outcnt() == 2 && @@ -1346,7 +1347,7 @@ Node* IfNode::fold_compares(PhaseIterGVN* igvn) { if (cmpi_folds(igvn)) { Node* ctrl = in(0); - if (is_ctrl_folds(ctrl, igvn) && ctrl->outcnt() == 1) { + if (is_ctrl_folds(ctrl, igvn)) { // A integer comparison immediately dominated by another integer // comparison ProjNode* success = nullptr; From 8cc84bf71e42bb72755a9f2d8532cbdbd428c2a5 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 29 Mar 2024 17:40:00 +0000 Subject: [PATCH 16/19] 8320097: Improve Image transformations Reviewed-by: jdv, psadhukhan, aivanov, rhalade --- .../share/classes/sun/java2d/pipe/DrawImage.java | 9 ++++++++- .../share/native/libawt/java2d/loops/TransformHelper.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java b/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java index 7275a01ce06..00563a84ecf 100644 --- a/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java +++ b/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, 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 @@ -369,6 +369,13 @@ protected void renderImageXform(SunGraphics2D sg, Image img, final AffineTransform itx; try { itx = tx.createInverse(); + double[] mat = new double[6]; + itx.getMatrix(mat); + for (double d : mat) { + if (!Double.isFinite(d)) { + return; + } + } } catch (final NoninvertibleTransformException ignored) { // Non-invertible transform means no output return; diff --git a/src/java.desktop/share/native/libawt/java2d/loops/TransformHelper.c b/src/java.desktop/share/native/libawt/java2d/loops/TransformHelper.c index 4d7442d7aef..02c99ea9ada 100644 --- a/src/java.desktop/share/native/libawt/java2d/loops/TransformHelper.c +++ b/src/java.desktop/share/native/libawt/java2d/loops/TransformHelper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, 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 @@ -120,7 +120,7 @@ TransformInterpFunc *pBicubicFunc = BicubicInterp; /* We reject coordinates not less than 1<<30 so that the distance between */ /* any 2 of them is less than 1<<31 which would overflow into the sign */ /* bit of a signed long value used to represent fixed point coordinates. */ -#define TX_FIXED_UNSAFE(v) (fabs(v) >= (1<<30)) +#define TX_FIXED_UNSAFE(v) (isinf(v) || isnan(v) || fabs(v) >= (1<<30)) static jboolean checkOverflow(jint dxoff, jint dyoff, SurfaceDataBounds *pBounds, From 13341ca70276c891add2e4652b6e1e8020610988 Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Tue, 2 Apr 2024 06:02:01 +0000 Subject: [PATCH 17/19] 8323390: Enhance mask blit functionality Reviewed-by: prr, rhalade, psadhukhan --- .../classes/sun/java2d/SunGraphics2D.java | 42 +++++++++++-------- .../share/native/libawt/java2d/SurfaceData.h | 11 ++++- .../native/libawt/java2d/loops/MaskBlit.c | 16 ++++++- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java index 86666b1f894..c27e4c6ebe0 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, 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 @@ -2150,27 +2150,33 @@ private void doCopyArea(int x, int y, int w, int h, int dx, int dy) { } Blit ob = lastCAblit; - if (dy == 0 && dx > 0 && dx < w) { - while (w > 0) { - int partW = Math.min(w, dx); - w -= partW; - int sx = x + w; - ob.Blit(theData, theData, comp, clip, - sx, y, sx+dx, y+dy, partW, h); + try { + if (dy == 0 && dx > 0 && dx < w) { + while (w > 0) { + int partW = Math.min(w, dx); + w -= partW; + int sx = Math.addExact(x, w); + ob.Blit(theData, theData, comp, clip, + sx, y, sx+dx, y+dy, partW, h); + } + return; } - return; - } - if (dy > 0 && dy < h && dx > -w && dx < w) { - while (h > 0) { - int partH = Math.min(h, dy); - h -= partH; - int sy = y + h; - ob.Blit(theData, theData, comp, clip, - x, sy, x+dx, sy+dy, w, partH); + if (dy > 0 && dy < h && dx > -w && dx < w) { + while (h > 0) { + int partH = Math.min(h, dy); + h -= partH; + int sy = Math.addExact(y, h); + ob.Blit(theData, theData, comp, clip, + x, sy, Math.addExact(x, dx), sy+dy, w, partH); + } + return; } + ob.Blit(theData, theData, comp, clip, x, y, + Math.addExact(x, dx), Math.addExact(y, dy), w, h); + } catch (ArithmeticException ex) { + // We are hitting integer overflow in Math.addExact() return; } - ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h); } /* diff --git a/src/java.desktop/share/native/libawt/java2d/SurfaceData.h b/src/java.desktop/share/native/libawt/java2d/SurfaceData.h index c4eae3c19aa..8975f8d4a9d 100644 --- a/src/java.desktop/share/native/libawt/java2d/SurfaceData.h +++ b/src/java.desktop/share/native/libawt/java2d/SurfaceData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, 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 @@ -32,6 +32,7 @@ #define _Included_SurfaceData #include +#include #ifdef __cplusplus extern "C" { @@ -53,6 +54,14 @@ typedef struct { #define SD_RASINFO_PRIVATE_SIZE 64 +#define UNSAFE_TO_ADD(a, b) \ + (((a >= 0) && (b >= 0) && (a > (INT_MAX - b))) || \ + ((a < 0) && (b < 0) && (a < (INT_MIN - b)))) \ + +#define UNSAFE_TO_SUB(a, b) \ + (((b >= 0) && (a < 0) && (a < (INT_MIN + b))) || \ + ((b < 0) && (a >= 0) && (-b > (INT_MAX - a)))) \ + /* * The SurfaceDataRasInfo structure is used to pass in and return various * pieces of information about the destination drawable. In particular: diff --git a/src/java.desktop/share/native/libawt/java2d/loops/MaskBlit.c b/src/java.desktop/share/native/libawt/java2d/loops/MaskBlit.c index 21b716e3bcd..e8c8765dd2c 100644 --- a/src/java.desktop/share/native/libawt/java2d/loops/MaskBlit.c +++ b/src/java.desktop/share/native/libawt/java2d/loops/MaskBlit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, 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 @@ -68,14 +68,28 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit return; } + if (width <= 0 || height <= 0) { + return; + } + srcInfo.bounds.x1 = srcx; srcInfo.bounds.y1 = srcy; + if (UNSAFE_TO_ADD(srcx, width) || + UNSAFE_TO_ADD(srcy, height) || + UNSAFE_TO_ADD(dstx, width) || + UNSAFE_TO_ADD(dsty, height)) { + return; + } srcInfo.bounds.x2 = srcx + width; srcInfo.bounds.y2 = srcy + height; dstInfo.bounds.x1 = dstx; dstInfo.bounds.y1 = dsty; dstInfo.bounds.x2 = dstx + width; dstInfo.bounds.y2 = dsty + height; + if (UNSAFE_TO_SUB(srcx, dstx) || + UNSAFE_TO_SUB(srcy, dsty)) { + return; + } srcx -= dstx; srcy -= dsty; SurfaceData_IntersectBounds(&dstInfo.bounds, &clipInfo.bounds); From 3babffd4002be62f9f75a1a773c9561804612fad Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Wed, 17 Jul 2024 06:12:01 +0000 Subject: [PATCH 18/19] 8334167: Test java/lang/instrument/NativeMethodPrefixApp.java timed out Reviewed-by: dholmes, sspitsyn, alanb --- .../instrument/NativeMethodPrefixAgent.java | 85 +++++++++---------- .../instrument/NativeMethodPrefixApp.java | 53 ++++++------ .../lang/instrument/libNativeMethodPrefix.c | 39 +++++++++ 3 files changed, 105 insertions(+), 72 deletions(-) create mode 100644 test/jdk/java/lang/instrument/libNativeMethodPrefix.c diff --git a/test/jdk/java/lang/instrument/NativeMethodPrefixAgent.java b/test/jdk/java/lang/instrument/NativeMethodPrefixAgent.java index 5ddede39959..5107f122ba3 100644 --- a/test/jdk/java/lang/instrument/NativeMethodPrefixAgent.java +++ b/test/jdk/java/lang/instrument/NativeMethodPrefixAgent.java @@ -35,70 +35,69 @@ class NativeMethodPrefixAgent { static ClassFileTransformer t0, t1, t2; static Instrumentation inst; - private static Throwable agentError; + private static Throwable agentError; // to be accessed/updated in a synchronized block - public static void checkErrors() { + private static final String CLASS_TO_TRANSFORM = "NativeMethodPrefixApp$Dummy"; + + public static synchronized void checkErrors() { if (agentError != null) { throw new RuntimeException("Agent error", agentError); } } + private static synchronized void trackError(final Throwable t) { + if (agentError == null) { + agentError = t; + return; + } + if (agentError != t) { + agentError.addSuppressed(t); + } + } + static class Tr implements ClassFileTransformer { private static final ClassDesc CD_StringIdCallbackReporter = ClassDesc.ofInternalName("bootreporter/StringIdCallbackReporter"); private static final MethodTypeDesc MTD_void_String_int = MethodTypeDesc.of(CD_void, CD_String, CD_int); final String trname; final int transformId; + private final String nativeMethodPrefix; Tr(int transformId) { this.trname = "tr" + transformId; this.transformId = transformId; + this.nativeMethodPrefix = "wrapped_" + trname + "_"; } - public byte[] - transform( - ClassLoader loader, - String className, - Class classBeingRedefined, - ProtectionDomain protectionDomain, - byte[] classfileBuffer) { - boolean redef = classBeingRedefined != null; - System.out.println(trname + ": " + - (redef? "Retransforming " : "Loading ") + className); - if (className != null) { - try { - byte[] newcf = Instrumentor.instrFor(classfileBuffer) - .addNativeMethodTrackingInjection( - "wrapped_" + trname + "_", (name, h) -> { - h.loadConstant(name); - h.loadConstant(transformId); - h.invokestatic( - CD_StringIdCallbackReporter, - "tracker", - MTD_void_String_int); - }) - .apply(); - /*** debugging ... - if (newcf != null) { - String fname = trname + (redef?"_redef" : "") + "/" + className; - System.err.println("dumping to: " + fname); - write_buffer(fname + "_before.class", classfileBuffer); - write_buffer(fname + "_instr.class", newcf); - } - ***/ - - return redef? null : newcf; - } catch (Throwable ex) { - if (agentError == null) { - agentError = ex; - } - System.err.println("ERROR: Injection failure: " + ex); - ex.printStackTrace(); + @Override + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) { + + try { + // we only transform a specific application class + if (!className.equals(CLASS_TO_TRANSFORM)) { + return null; + } + if (classBeingRedefined != null) { return null; } + // use a byte code generator which creates wrapper methods, + // with a configured native method prefix, for each native method on the + // class being transformed + final Instrumentor byteCodeGenerator = Instrumentor.instrFor(classfileBuffer) + .addNativeMethodTrackingInjection(nativeMethodPrefix, + (name, cb) -> { + cb.loadConstant(name); + cb.loadConstant(transformId); + cb.invokestatic(CD_StringIdCallbackReporter, + "tracker", MTD_void_String_int); + }); + // generate the bytecode + return byteCodeGenerator.apply(); + } catch (Throwable t) { + trackError(t); + return null; } - return null; } - } // for debugging diff --git a/test/jdk/java/lang/instrument/NativeMethodPrefixApp.java b/test/jdk/java/lang/instrument/NativeMethodPrefixApp.java index 65cc54793cb..97cf4fde2f1 100644 --- a/test/jdk/java/lang/instrument/NativeMethodPrefixApp.java +++ b/test/jdk/java/lang/instrument/NativeMethodPrefixApp.java @@ -22,10 +22,7 @@ */ -import java.io.File; import java.nio.file.Path; -import java.lang.management.*; -import java.util.zip.CRC32; import bootreporter.*; import jdk.test.lib.helpers.ClassFileInstaller; @@ -34,27 +31,24 @@ /* * @test - * @bug 6263319 + * @bug 6263319 8334167 * @summary test setNativeMethodPrefix * @requires ((vm.opt.StartFlightRecording == null) | (vm.opt.StartFlightRecording == false)) & ((vm.opt.FlightRecorder == null) | (vm.opt.FlightRecorder == false)) - * @modules java.management - * java.instrument + * @modules java.instrument * @library /test/lib * @build bootreporter.StringIdCallback bootreporter.StringIdCallbackReporter * asmlib.Instrumentor NativeMethodPrefixAgent * @enablePreview * @comment The test uses asmlib/Instrumentor.java which relies on ClassFile API PreviewFeature. - * @run driver/timeout=240 NativeMethodPrefixApp roleDriver - * @comment The test uses a higher timeout to prevent test timeouts noted in JDK-6528548 + * @run main/native NativeMethodPrefixApp roleDriver */ public class NativeMethodPrefixApp implements StringIdCallback { - // This test is fragile like a golden file test. - // It assumes that a specific non-native library method will call a specific - // native method. The below may need to be updated based on library changes. - static String goldenNativeMethodName = "getStartupTime"; - + // we expect this native method, which is part of this test's application, + // to be instrumented and invoked + static String goldenNativeMethodName = "fooBarNativeMethod"; static boolean[] gotIt = {false, false, false}; + private static final String testLibraryPath = System.getProperty("test.nativepath"); public static void main(String[] args) throws Exception { if (args.length == 1) { @@ -69,21 +63,19 @@ public static void main(String[] args) throws Exception { launchApp(agentJar); } else { System.err.println("running app"); + System.loadLibrary("NativeMethodPrefix"); // load the native library new NativeMethodPrefixApp().run(); } } private static Path createAgentJar() throws Exception { - final String testClassesDir = System.getProperty("test.classes"); final Path agentJar = Path.of("NativeMethodPrefixAgent.jar"); final String manifest = """ Manifest-Version: 1.0 Premain-Class: NativeMethodPrefixAgent Can-Retransform-Classes: true Can-Set-Native-Method-Prefix: true - """ - + "Boot-Class-Path: " + testClassesDir.replace(File.separatorChar, '/') + "/" - + "\n"; + """; System.out.println("Manifest is:\n" + manifest); // create the agent jar ClassFileInstaller.writeJar(agentJar.getFileName().toString(), @@ -97,10 +89,7 @@ private static void launchApp(final Path agentJar) throws Exception { final OutputAnalyzer oa = ProcessTools.executeTestJava( "--enable-preview", // due to usage of ClassFile API PreviewFeature in the agent "-javaagent:" + agentJar.toString(), - // We disable CheckIntrinsic because the NativeMethodPrefixAgent modifies - // the native method names, which then causes a failure in the VM check - // for the presence of an intrinsic on a @IntrinsicCandidate native method. - "-XX:+UnlockDiagnosticVMOptions", "-XX:-CheckIntrinsics", + "-Djava.library.path=" + testLibraryPath, NativeMethodPrefixApp.class.getName()); oa.shouldHaveExitValue(0); // make available stdout/stderr in the logs, even in case of successful completion @@ -110,14 +99,11 @@ private static void launchApp(final Path agentJar) throws Exception { private void run() throws Exception { StringIdCallbackReporter.registerCallback(this); System.err.println("start"); - - java.lang.reflect.Array.getLength(new short[5]); - RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean(); - System.err.println(mxbean.getVmVendor()); - // Simply load a class containing an @IntrinsicCandidate on a native method - // to exercise the VM code which verifies the presence of the intrinsic - // implementation for that method. - System.err.println(new CRC32()); + final long val = new Dummy().callSomeNativeMethod(); + if (val != 42) { + throw new RuntimeException("unexpected return value " + val + + " from native method, expected 42"); + } NativeMethodPrefixAgent.checkErrors(); @@ -137,4 +123,13 @@ public void tracker(String name, int id) { System.err.println("Tracked #" + id + ": " + name); } } + + private static class Dummy { + + private long callSomeNativeMethod() { + return fooBarNativeMethod(); + } + + private native long fooBarNativeMethod(); + } } diff --git a/test/jdk/java/lang/instrument/libNativeMethodPrefix.c b/test/jdk/java/lang/instrument/libNativeMethodPrefix.c new file mode 100644 index 00000000000..39dd7edbf23 --- /dev/null +++ b/test/jdk/java/lang/instrument/libNativeMethodPrefix.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024, 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. + */ + +#include +#include "jni.h" + +JNIEXPORT jlong JNICALL +Java_NativeMethodPrefixApp_00024Dummy_fooBarNativeMethod(JNIEnv *env, jclass clazz) +{ + fprintf(stderr, "native method called\n"); + return 42; +} + +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved) +{ + fprintf(stderr, "native library loaded\n"); + return JNI_VERSION_1_1; // this native library needs the very basic JNI support +} From b9b0b8504ec989ad0687188de4bccfe2c04e5d64 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 17 Jul 2024 06:46:34 +0000 Subject: [PATCH 19/19] 8336375: Crash on paste to JShell Reviewed-by: jvernee --- .../jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java index 0c485819f57..4e7adbe3355 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java @@ -236,7 +236,7 @@ public static int ScrollConsoleScreenBuffer( MethodHandle mh$ = requireNonNull(ScrollConsoleScreenBufferW$MH, "ScrollConsoleScreenBuffer"); try { return (int) - mh$.invokeExact(hConsoleOutput, lpScrollRectangle, lpClipRectangle, dwDestinationOrigin, lpFill); + mh$.invokeExact(hConsoleOutput, lpScrollRectangle.seg, lpClipRectangle.seg, dwDestinationOrigin.seg, lpFill.seg); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); }