Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
theaoqi committed Feb 8, 2025
2 parents 613f890 + 4adb459 commit d238041
Show file tree
Hide file tree
Showing 9 changed files with 610 additions and 36 deletions.
2 changes: 1 addition & 1 deletion make/autoconf/version-numbers
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ DEFAULT_VERSION_DATE=2025-01-21
DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
DEFAULT_VERSION_CLASSFILE_MINOR=0
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="10 11"
DEFAULT_PROMOTED_VERSION_PRE=ea
DEFAULT_PROMOTED_VERSION_PRE=

LAUNCHER_NAME=openjdk
PRODUCT_NAME=OpenJDK
Expand Down
90 changes: 66 additions & 24 deletions src/hotspot/share/opto/subnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,44 +1489,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 <u y + 1 is always true if y != -1 (Lemma 2, (uint)(-1 + 1) == (uint)(UINT_MAX + 1) which overflows)
// y <u 0 is always false for any y (Lemma 3, 0 == UINT_MIN and nothing can be smaller than that)
//
// (1a) Always: Change ((x & m) <=u m ) or ((m & x) <=u m ) to always true (true by Lemma 1)
// (1b) If m != -1: Change ((x & m) <u m + 1) or ((m & x) <u m + 1) to always true:
// x & m <=u m is always true // (Lemma 1)
// x & m <=u m <u m + 1 is always true // (Lemma 2: m <u m + 1, if m != -1)
//
// A counter example for (1b), if we allowed m == -1:
// (x & m) <u m + 1
// (x & -1) <u 0
// x <u 0
// which is false for any x (Lemma 3)
if (cop == Op_CmpU &&
cmp1_op == Op_AndI) {
Node* bound = NULL;
Node* m = NULL;
if (_test._test == BoolTest::le) {
bound = cmp2;
// (1a) "((x & m) <=u m)", cmp2 = m
m = cmp2;
} else if (_test._test == BoolTest::lt &&
cmp2->Opcode() == Op_AddI &&
cmp2->in(2)->find_int_con(0) == 1) {
bound = cmp2->in(1);
// (1b) "(x & m) <u m + 1" and "(m & x) <u m + 1", cmp2 = m + 1
Node* rhs_m = cmp2->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 m) or (((m - 1) & x) <u m) to (m >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 m", i.e. "m >u 0 <=> x & (m - 1) <u m"
//
// We use (Lemma 1) and (Lemma 3) from above.
//
// Case "x & (m - 1) <u m => m >u 0":
// We prove this by contradiction:
// Assume m <=u 0 which is equivalent to m == 0:
// and thus
// x & (m - 1) <u m = 0 // m == 0
// y <u 0 // y = x & (m - 1)
// by Lemma 3, this is always false, i.e. a contradiction to our assumption.
//
// Case "m >u 0 => x & (m - 1) <u m":
// x & (m - 1) <=u (m - 1) // (Lemma 1)
// x & (m - 1) <=u (m - 1) <u m // Using assumption m >u 0, no underflow of "m - 1"
//
//
// Note that the signed version of "m > 0":
// m > 0 <=> x & (m - 1) <u m
// does not hold:
// Assume m == -1 and x == -1:
// x & (m - 1) <u m
// -1 & -2 <u -1
// -2 <u -1
// UINT_MAX - 1 <u UINT_MAX // Signed to unsigned numbers
// which is true while
// m > 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);
}
}
}
Expand Down
22 changes: 14 additions & 8 deletions src/java.base/windows/classes/java/lang/ProcessImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,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,
Expand Down Expand Up @@ -332,9 +333,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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/java.desktop/share/native/libawt/java2d/SurfaceData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ void process(Main jartool, String opt, String arg) {
}
},

// Extract options
new Option(false, OptionType.EXTRACT, "--keep-old-files", "-k") {
void process(Main jartool, String opt, String arg) {
jartool.kflag = true;
}
},

// Hidden options
new Option(false, OptionType.OTHER, "-P") {
void process(Main jartool, String opt, String arg) {
Expand Down Expand Up @@ -230,6 +237,7 @@ enum OptionType {
CREATE("create"),
CREATE_UPDATE("create.update"),
CREATE_UPDATE_INDEX("create.update.index"),
EXTRACT("extract"),
OTHER("other");

/** Resource lookup section prefix. */
Expand Down
15 changes: 14 additions & 1 deletion src/jdk.jartool/share/classes/sun/tools/jar/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,9 @@ public int hashCode() {
* nflag: Perform jar normalization at the end
* pflag: preserve/don't strip leading slash and .. component from file name
* dflag: print module descriptor
* kflag: keep existing file
*/
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, dflag;
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, dflag, kflag;

boolean suppressDeprecateMsg = false;

Expand Down Expand Up @@ -584,6 +585,9 @@ boolean parseArgs(String args[]) {
case '0':
flag0 = true;
break;
case 'k':
kflag = true;
break;
case 'i':
if (cflag || uflag || xflag || tflag) {
usageError(getMsg("error.multiple.main.operations"));
Expand Down Expand Up @@ -617,6 +621,9 @@ boolean parseArgs(String args[]) {
usageError(getMsg("error.bad.option"));
return false;
}
if (kflag && !xflag) {
warn(formatMsg("warn.option.is.ignored", "--keep-old-files/-k/k"));
}

/* parse file arguments */
int n = args.length - count;
Expand Down Expand Up @@ -1448,6 +1455,12 @@ ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
output(formatMsg("out.create", name));
}
} else {
if (f.exists() && kflag) {
if (vflag) {
output(formatMsg("out.kept", name));
}
return rc;
}
if (f.getParent() != null) {
File d = new File(f.getParent());
if (!d.exists() && !d.mkdirs() || !d.isDirectory()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ warn.release.unexpected.versioned.entry=\
unexpected versioned entry {0}
warn.flag.is.deprecated=\
Warning: The {0} option is deprecated, and is planned for removal in a future JDK release\n
warn.option.is.ignored=\
Warning: The {0} option is not valid with current usage, will be ignored.
out.added.manifest=\
added manifest
out.added.module-info=\
Expand All @@ -155,6 +157,8 @@ out.create=\
\ \ created: {0}
out.extracted=\
extracted: {0}
out.kept=\
\ \ skipped: {0} exists
out.inflated=\
\ inflated: {0}
out.size=\
Expand Down Expand Up @@ -234,7 +238,10 @@ main.help.opt.main.list=\
main.help.opt.main.update=\
\ -u, --update Update an existing jar archive
main.help.opt.main.extract=\
\ -x, --extract Extract named (or all) files from the archive
\ -x, --extract Extract named (or all) files from the archive.\n\
\ If a file with the same name appears more than once in\n\
\ the archive, each copy will be extracted, with later copies\n\
\ overwriting (replacing) earlier copies unless -k is specified.
main.help.opt.main.describe-module=\
\ -d, --describe-module Print the module descriptor, or automatic module name
main.help.opt.any=\
Expand Down Expand Up @@ -287,6 +294,15 @@ main.help.opt.create.update.index=\
\ Operation modifiers valid only in create, update, and generate-index mode:\n
main.help.opt.create.update.index.no-compress=\
\ -0, --no-compress Store only; use no ZIP compression
main.help.opt.extract=\
\ Operation modifiers valid only in extract mode:\n
main.help.opt.extract.keep-old-files=\
\ -k, --keep-old-files Do not overwrite existing files.\n\
\ If a Jar file entry with the same name exists in the target\n\
\ directory, the existing file will not be overwritten.\n\
\ As a result, if a file appears more than once in an\n\
\ archive, later copies will not overwrite earlier copies.\n\
\ Also note that some file system can be case insensitive.
main.help.opt.other=\
\ Other options:\n
main.help.opt.other.help=\
Expand Down
Loading

0 comments on commit d238041

Please sign in to comment.