diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 37266259ef2..63ce4fe97be 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -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/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java index 15db79d69d2..6aefbe401ce 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, 2020, 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 @@ -2151,27 +2151,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/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/SurfaceData.h b/src/java.desktop/share/native/libawt/java2d/SurfaceData.h index 48504629703..f8fd8e62a82 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); 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; 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, diff --git a/test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java b/test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java new file mode 100644 index 00000000000..18a58aa7ae5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, 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 id=test1 + * @bug 8298935 + * @summary CMoveI for underflow protection of the limit did not compute a type that was precise enough. + * This lead to dead data but zero-trip-guard control did not die -> "malformed control flow". + * @requires vm.compiler2.enabled + * @run main/othervm + * -XX:CompileCommand=compileonly,compiler.loopopts.TestUnrollLimitPreciseType::test1 + * -XX:CompileCommand=dontinline,compiler.loopopts.TestUnrollLimitPreciseType::* + * -XX:MaxVectorSize=64 + * -Xcomp + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=0 -XX:PerMethodTrapLimit=0 + * compiler.loopopts.TestUnrollLimitPreciseType test1 + */ + +/* + * @test id=test2 + * @bug 8298935 + * @summary CMoveI for underflow protection of the limit did not compute a type that was precise enough. + * This lead to dead data but zero-trip-guard control did not die -> "malformed control flow". + * @requires vm.compiler2.enabled + * @run main/othervm + * -XX:CompileCommand=compileonly,compiler.loopopts.TestUnrollLimitPreciseType::* + * -Xcomp + * compiler.loopopts.TestUnrollLimitPreciseType test2 + */ + + +package compiler.loopopts; + +public class TestUnrollLimitPreciseType { + static final int RANGE = 512; + + public static void main(String args[]) { + if (args.length != 1) { + throw new RuntimeException("Need exactly one argument."); + } + if (args[0].equals("test1")) { + byte[] data = new byte[RANGE]; + test1(data); + } else if (args[0].equals("test2")) { + test2(); + } else { + throw new RuntimeException("Do not have: " + args[0]); + } + } + + public static void test1(byte[] data) { + // Did not fully analyze this. But it is also unrolled, SuperWorded, + // and further unrolled with vectorlized post loop. + // Only seems to reproduce with avx512, and not with avx2. + for (int j = 192; j < RANGE; j++) { + data[j - 192] = (byte)(data[j] * 11); + } + } + + static void test2() { + // Loop is SuperWord'ed. + // We unroll more afterwards, and so add vectorized post loop. + // But it turns out that the vectorized post loop is never entered. + // This lead to assert, because the zero-trip-guard did not collaspse, + // but the CastII with the trip count did die. + // Only seems to reproduce with avx512, and not with avx2. + double dArr[][] = new double[100][100]; + for (int i = 2, j = 2; j < 68; j++) { + dArr[i][j] = 8; + } + } +}