diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 710539bc0d7..0462cf6548a 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="16 17" DEFAULT_JDK_SOURCE_TARGET_VERSION=17 -DEFAULT_PROMOTED_VERSION_PRE=ea +DEFAULT_PROMOTED_VERSION_PRE= diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index 98e0f5f2ed3..478c6a315bf 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -1483,44 +1483,86 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { return new BoolNode( ncmp, _test.negate() ); } - // Change ((x & m) u<= m) or ((m & x) u<= m) to always true - // Same with ((x & m) u< m+1) and ((m & x) u< m+1) + // We use the following Lemmas/insights for the following two transformations (1) and (2): + // x & y <=u y, for any x and y (Lemma 1, masking always results in a smaller unsigned number) + // y Opcode() == Op_AddI && cmp2->in(2)->find_int_con(0) == 1) { - bound = cmp2->in(1); + // (1b) "(x & m) in(1); + const TypeInt* rhs_m_type = phase->type(rhs_m)->isa_int(); + if (rhs_m_type->_lo > -1 || rhs_m_type->_hi < -1) { + // Exclude any case where m == -1 is possible. + m = rhs_m; + } } - if (cmp1->in(2) == bound || cmp1->in(1) == bound) { + if (cmp1->in(2) == m || cmp1->in(1) == m) { return ConINode::make(1); } } - // Change ((x & (m - 1)) u< m) into (m > 0) - // This is the off-by-one variant of the above + // (2) Change ((x & (m - 1)) u 0) + // This is the off-by-one variant of the above. + // + // We now prove that this replacement is correct. This is the same as proving + // "m >u 0" if and only if "x & (m - 1) u 0 <=> x & (m - 1) m >u 0": + // We prove this by contradiction: + // Assume m <=u 0 which is equivalent to m == 0: + // and thus + // x & (m - 1) u 0 => x & (m - 1) u 0, no underflow of "m - 1" + // + // + // Note that the signed version of "m > 0": + // m > 0 <=> x & (m - 1) 0 + // is false which is a contradiction. if (cop == Op_CmpU && _test._test == BoolTest::lt && cmp1_op == Op_AndI) { - Node* l = cmp1->in(1); - Node* r = cmp1->in(2); - for (int repeat = 0; repeat < 2; repeat++) { - bool match = r->Opcode() == Op_AddI && r->in(2)->find_int_con(0) == -1 && - r->in(1) == cmp2; - if (match) { - // arraylength known to be non-negative, so a (arraylength != 0) is sufficient, - // but to be compatible with the array range check pattern, use (arraylength u> 0) - Node* ncmp = cmp2->Opcode() == Op_LoadRange - ? phase->transform(new CmpUNode(cmp2, phase->intcon(0))) - : phase->transform(new CmpINode(cmp2, phase->intcon(0))); - return new BoolNode(ncmp, BoolTest::gt); - } else { - // commute and try again - l = cmp1->in(2); - r = cmp1->in(1); + Node* m = cmp2; // RHS: m + for (int add_idx = 1; add_idx <= 2; add_idx++) { // LHS: "(m + (-1)) & x" or "x & (m + (-1))"? + Node* maybe_m_minus_1 = cmp1->in(add_idx); + if (maybe_m_minus_1->Opcode() == Op_AddI && + maybe_m_minus_1->in(2)->find_int_con(0) == -1 && + maybe_m_minus_1->in(1) == m) { + Node* m_cmpu_0 = phase->transform(new CmpUNode(m, phase->intcon(0))); + return new BoolNode(m_cmpu_0, BoolTest::gt); } } } diff --git a/src/java.base/windows/classes/java/lang/ProcessImpl.java b/src/java.base/windows/classes/java/lang/ProcessImpl.java index 536f2a27cf7..f46c5ea777a 100644 --- a/src/java.base/windows/classes/java/lang/ProcessImpl.java +++ b/src/java.base/windows/classes/java/lang/ProcessImpl.java @@ -216,13 +216,14 @@ private static String[] getTokensFromCommand(String command) { private static final int VERIFICATION_LEGACY = 3; // See Command shell overview for documentation of special characters. // https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490954(v=technet.10) - private static final char ESCAPE_VERIFICATION[][] = { + private static final String ESCAPE_VERIFICATION[] = { // We guarantee the only command file execution for implicit [cmd.exe] run. // http://technet.microsoft.com/en-us/library/bb490954.aspx - {' ', '\t', '\"', '<', '>', '&', '|', '^'}, - {' ', '\t', '\"', '<', '>'}, - {' ', '\t', '\"', '<', '>'}, - {' ', '\t'} + // All space characters require quoting are checked in needsEscaping(). + "\"<>&|^", + "\"<>", + "\"<>", + "" }; private static String createCommandLine(int verificationType, @@ -337,9 +338,14 @@ private static boolean needsEscaping(int verificationType, String arg) { } if (!argIsQuoted) { - char testEscape[] = ESCAPE_VERIFICATION[verificationType]; - for (int i = 0; i < testEscape.length; ++i) { - if (arg.indexOf(testEscape[i]) >= 0) { + for (int i = 0; i < arg.length(); i++) { + char ch = arg.charAt(i); + if (Character.isLetterOrDigit(ch)) + continue; // skip over common characters + // All space chars require quotes and other mode specific characters + if (Character.isSpaceChar(ch) || + Character.isWhitespace(ch) || + ESCAPE_VERIFICATION[verificationType].indexOf(ch) >= 0) { return true; } } diff --git a/src/java.desktop/share/native/libawt/java2d/SurfaceData.h b/src/java.desktop/share/native/libawt/java2d/SurfaceData.h index f8fd8e62a82..ca2e985fa7a 100644 --- a/src/java.desktop/share/native/libawt/java2d/SurfaceData.h +++ b/src/java.desktop/share/native/libawt/java2d/SurfaceData.h @@ -60,7 +60,7 @@ typedef struct { #define UNSAFE_TO_SUB(a, b) \ (((b >= 0) && (a < 0) && (a < (INT_MIN + b))) || \ - ((b < 0) && (a >= 0) && (-b > (INT_MAX - a)))) \ + ((b < 0) && (a >= 0) && (a > (INT_MAX + b)))) \ /* * The SurfaceDataRasInfo structure is used to pass in and return various